commit 6849d33cf1d363709f0db3e1cc38ddfc866979af Author: deadinside Date: Fri Sep 25 10:20:27 2026 +0300 Native Bloodborne loader with HLE runtime, shadPS4 video core and performance work Includes FPS unlock patches, AudioOut pacing fix, rwlock memory table, threaded Vulkan command recording and front-end caches. Co-Authored-By: Claude Opus 5.5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cec6ab1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +out/ +__pycache__/ +user/ +*.mp4 diff --git a/README.md b/README.md new file mode 100644 index 0000000..fc8f422 --- /dev/null +++ b/README.md @@ -0,0 +1,428 @@ +# Bloodborne: первый эксперимент нативного запуска + +## Частота кадров, звук, диагностика (2026-09-25) + +- **FPS**: `BB_FPS=uncap` (по умолчанию) применяет патч «Uncap FPS++» + (Lance McDonald, Kyo) из `patches/Bloodborne.xml`: интервал флипа 1 и + шаги симуляции от реального дельтатайма кадра. Vblank при этом следует за + частотой монитора (`BB_VBLANK_HZ=0`). `BB_FPS=60`/`90` — патчи с + фиксированным шагом, `BB_FPS=30` — без патчей. Дополнительные патчи из XML: + `BB_PATCHES="Skip Intro;Disable Motion Blur (perf increase)"`. + `patches.py` компилирует их в `out/patches.bin`; адреса в XML — это + виртуальные адреса PS4 (база eboot 0x400000), загрузчик пишет их по + смещению `адрес-0x400000` после релокаций (`--patches`). +- **Звук**: `sceAudioOutOutput` теперь возвращает управление строго раз в + период буфера (как железо). Раньше вызовы шли пачками раз в квант PipeWire + (21 мс), поток вывода FMOD обгонял микшер и проигрывал незаписанные половины + 512-кадровых блоков — щелчок каждые 10.7 мс. +- **Производительность потока GPU** (`shadPS4:GpuCommandProcessor` — узкое + место: ~97% одного ядра). Замер в одной сцене: 26.5 → 47 FPS. + - `runtime_memory.c`: таблица регионов под rwlock вместо рекурсивного + мьютекса (18% времени поток GPU ждал его), плюс потоковый кеш регионов, + проверяемый по счётчику поколений таблицы, — запросы видеоядра на каждый + draw идут без блокировки. + - `vk_scheduler.cpp`: `PopPendingOperations` на каждом draw делал ioctl + опроса timeline-семафора; теперь только при непустой очереди и не чаще + раза в 250 мкс. + - `fetch_shader.cpp`: разбор fetch-шейдера кешируется по адресу кода с + проверкой копии кода. + - `region_manager.h`: без изменённых страниц в диапазоне защита не + пересчитывается. + Профилирование без perf: загрузчик по SIGUSR2 печатает RIP, `rdi` (адрес + мьютекса при ожидании futex) и цепочку кадров потока; GPU-библиотека + собирается с `-fno-omit-frame-pointer`. +- **Диагностика**: `BB_FRAME_STATS=1` — FPS, худший кадр и время компиляции + шейдеров/пайплайнов раз в 5 с; `BB_AUDIO_STATS=1` — ритм и заполнение + очереди звука; `BB_AUDIO_DUMP=путь` — сырой PCM каждого порта. + +## Текущее состояние (2026-09-25) + +Оригинальный x86-64 код `eboot.bin` выполняется напрямую на Linux и проходит +глобальные конструкторы, инициализацию памяти и запуск собственной системы +потоков игры: создано 13 гостевых потоков (`FD4JobWorker:0`, `EzWorkPool_*` ×9, +`MOMainThread`, логгер). Игра выделяет ~4.8 ГиБ direct- и ~337 МиБ +flexible-памяти. Текущая остановка — `sceAjmInitialize` (аудиокодек ATRAC9), +caller `0xd18a6a`. + +Изменения этого этапа: + +- `runtime_memory.c` переписан: единый sparse memfd на весь direct-пул + (5056 МиБ, как `sceKernelGetDirectMemorySize` на PS4), таблица регионов + с разбиением, flexible memory (448 МиБ), `ReserveVirtualRange`, `Mprotect`, + `QueryMemoryProtection`, `VirtualQuery`, `GetDirectMemoryType`, `BatchMap(2)`, + частичные unmap/release, `MAP_FIXED`/`NO_OVERWRITE`, GPU-биты защиты. +- **Все видимые гостю адреса размещаются ниже 1 ТиБ**: образ, стеки потоков, + главный стек, трамплины (`runtime_low_map`), гостевая память + (`0x10_0000_0000..0xfc_0000_0000`), кучи host-объектов (non-PIE + `mallopt`). + Игра упаковывает указатели в 40 бит: например, lock по адресу `0x20368c0` + хранит владельца как `scePthreadSelf() & 0xffffffffff` и сравнивает с полным + значением. С хэндлами `0x7f…` это давало вечную взаимоблокировку. +- Watchdog (`--timeout`) печатает RIP и цепочку кадров всех потоков + (смещения относительно образа и `bb-probe` для `addr2line`). + `BB_TRACE_SEMA=1` печатает блокирующие ожидания семафоров. + `got_import.py <адрес GOT>` называет импорт за PLT-заглушкой. +- Сеть в режиме «кабель отключён»: HTTP-шаблоны/соединения/запросы создаются, + отправка возвращает сетевую ошибку; NpWebApi/Matching2/Signaling/Score — + «не в PSN»; голосовой чат — порты без звука. + +Следующие подсистемы по порядку появления: Ajm (ATRAC9 через ffmpeg), +Fios2, SaveData, Rtc, Pad, AudioOut, AvPlayer, VideoOut и GnmDriver. + +## Предыдущее описание + + +**Оригинальный x86-64 код `eboot.bin` выполняется непосредственно процессором +Linux и проходит начальный участок конструкторов.** Теперь он возвращается из +`_init_env`, регистрирует три обработчика `atexit` и 279 C++-деструкторов, +проходит 1416 guard инициализации, создаёт 1422 mutex, один rwlock и 17 семафоров, +выделяет/отображает 116 МиБ для игрового аллокатора. +Оригинальная `libc.prx` загружается вместе с eboot, её инициализатор возвращает 0, +конструктор `std::ios_base::Init` пройден. Следующая контролируемая остановка — +`sceSysmoduleLoadModule(0xb4)` (`g8cM39EUZ6o#M#N`, caller `0x2026149`). +Отдельный тест Vulkan выполняет команду заполнения буфера и проверяет +возвращённые 4096 байт. shadPS4 в этом эксперименте не запускается. + +**Это ещё не рекомпиляция всей игры и не играбельный порт.** Нет окна игры, +меню, отрисовки игровых ресурсов или работающего игрового цикла. Vulkan пока +не соединён с графическими командами игры. Контролируемая остановка на очередном +неподдерживаемом импорте — измеримая граница прототипа; запуск игры не завершён. + +## Запуск в текущем окружении + +Из `game_files`: + +```bash +bash native_probe/run.sh --software +``` + +Скрипт находит локальные Python, GCC и Vulkan SDK, подготавливает образ, +собирает загрузчик и запускает его. На этой машине инструменты найдены +в `/nix/store`; ничего скачивать или устанавливать не понадобилось. +`--software` выбирает Lavapipe и отключает неявные Vulkan layers для теста. +В проверенном окружении `/dev/dri` отсутствует, поэтому реальный GPU не проверен. + +Ожидаемый результат: + +```text +Vulkan: llvmpipe (LLVM 21.1.8, 256 bits); command submission + 4096-byte readback PASS +Mapped 91973152 bytes, 4 segments; applied 237083 relocations +Starting native libc.prx at image offset 0x56e0000; fallback exports=202 +Runtime: application heap API registered +Native libc module initializer returned 0 +Entering original x86-64 code at guest offset 0xa0 +Runtime: _init_env returned (verified libc implementation: RET) +Runtime: direct allocation offset=0x0, size=121634816 bytes +Runtime: mapped direct memory, size=121634816, alignment=0x200000 +Runtime: semaphore id=1, attr=2, initial=0, max=1 +Runtime: semaphore id=2, attr=2, initial=0, max=1 +Runtime: semaphore id=3, attr=2, initial=0, max=1 +Runtime: semaphore id=4, attr=2, initial=0, max=1 +Runtime: semaphore id=5, attr=2, initial=0, max=1 +Runtime: semaphore id=6, attr=2, initial=0, max=1 +Runtime: semaphore id=7, attr=2, initial=0, max=1 +Runtime: semaphore id=8, attr=2, initial=0, max=1 +Runtime: semaphore id=9, attr=2, initial=0, max=1 +Runtime: semaphore id=10, attr=2, initial=0, max=1 +Runtime: semaphore id=11, attr=2, initial=0, max=1 +Runtime: semaphore id=12, attr=2, initial=0, max=1 +Runtime: semaphore id=13, attr=2, initial=0, max=1 +Runtime: semaphore id=14, attr=2, initial=0, max=1 +Runtime: semaphore id=15, attr=2, initial=0, max=1 +Runtime: semaphore id=16, attr=2, initial=0, max=1 +Runtime: semaphore id=17, attr=2, initial=0, max=1 +STOP: first unsupported PS4 import: g8cM39EUZ6o#M#N (index 249) +API: sceSysmoduleLoadModule +Caller return offset: 0x2026149; first argument: 0xb4 +Runtime: _init_env=1, atexit=3, __cxa_atexit=279, registered handlers=282 +Runtime: static guards acquired=1416, released=1416 +Runtime: mutexes created=1422, locks=3208, unlocks=3208 +Runtime: rwlocks created=1, reads=21, writes=1, unlocks=22 +Runtime: semaphores created=17, deleted=0, acquired=0, signals=0, timeouts=0 +Runtime: direct memory allocations=1, maps=1, live=121634816, budget=536870912 +Runtime: memory operations=9884 +Original guest entry instructions executed; game initialization is incomplete. +``` + +**Код завершения 20 означает ожидаемую остановку на отсутствующей реализации +PS4 API.** Он намеренно отличается от 0. Ошибки загрузки возвращают 1; +явно неподдерживаемые режимы runtime — 21, срабатывание stack protector — 22. +Linux-сигналы — 128 + номер сигнала. На выполнение гостевого кода в Linux +установлен таймер 10 секунд. + +На системе с доступным GPU можно попробовать `bash native_probe/run.sh`. +Это использует обычный выбор устройства Vulkan; аппаратный результат здесь +не проверен. Для повторного запуска уже собранных файлов: + +```bash +native_probe/out/bb-probe native_probe/out/boot-libc.bin --cpu-only +native_probe/out/bb-probe --vulkan-only +``` + +Базовый образ без нативной libc сохраняется в `out/boot.bin` для сравнения +с прежней остановкой на `std::ios_base::Init`. + +Из каталога `native_probe` команда остаётся прежней: `bash run.sh --software`. +Для воспроизведения самой ранней остановки на `_init_env` используйте +`out/bb-probe out/boot.bin --cpu-only --strict-imports` из этого каталога. + +Последняя команда использует обычные настройки Vulkan. Для программного +драйвера задайте `VK_DRIVER_FILES` на его JSON и +`VK_LOADER_LAYERS_DISABLE='~implicit~'`, как делает `run.sh --software`. + +## Что найдено в файлах + +| Параметр | Результат | +|---|---| +| Игра | Bloodborne, CUSA03173 | +| Версия из `param.sfo` | APP_VER 01.09, VERSION 01.00 | +| Контейнер | SELF, 8 записей сегментов | +| CPU | x86-64, ELF64 little-endian, PS4/FreeBSD ABI | +| Тип ELF | ET_SCE_DYNEXEC (`0xfe10`) | +| Точка входа | `0xa0` относительно базы загрузки | +| Загружаемые сегменты | 2: код/данные только для чтения и изменяемые данные/BSS | +| Образ в памяти | 91 042 036 байт | +| Импорты | 686 уникальных импортированных символов | +| Зависимости DT_NEEDED | 42 модуля | +| Перемещения адресов | 231 478 RELATIVE, 2 838 ABS64, 23 GLOB_DAT, 661 JUMP_SLOT | +| Ресурсы `dvdroot_ps4` | 31 322 968 005 байт | + +Среди зависимостей: libc, libkernel, GnmDriver, VideoOut, Pad, Fios2, +AudioOut, SaveData, Sysmodule, сетевые и диалоговые API. В `sce_module` +имеются только семь файлов; наличие файлов модулей не заменяет поддержку их ABI. + +Используемые сегменты SELF доступны открытым текстом. Извлечение не выполняет +расшифровку. Неподдерживаемые сжатые/зашифрованные сегменты отклоняются. +Один незагружаемый сегмент метаданных (`program header 9`, тип `0x6fffff01`) +не представлен в доступных SELF-сегментах. В диагностическом `eboot.elf` его +диапазон заполнен нулями: **это не побайтово полное восстановление ELF**. +Все сегменты, нужные этому эксперименту, проверены на наличие. + +Подробности, SHA-256 исходного eboot, список зависимостей, NID, сегментов +и количество ресурсов по каталогам находятся в `out/analysis.json`. +Имена нескольких импортов проверены вычислением NID из предполагаемых имён; +результаты записаны в `import_name_hints`. Для первого вызова `_init_env` +получен NID `bzQExy189ZI`, следующий вызов соответствует `atexit`. + +## Как устроен прототип + +`prepare.py` читает SELF и SFO, проверяет границы, восстанавливает доступные +сегменты, разбирает PS4 dynamic/symbol/RELA-таблицы и формирует `out/boot.bin`. +Исходные файлы открываются только для чтения. Все результаты — в `out/`. + +Дополнительно проверяется фактический экспорт `_init_env` в `sce_module/libc.prx`: +NID `bzQExy189ZI`, адрес `0x5fef0`, размер 1, байт `c3` (RET). +SHA-256 libc и доказательство записываются в `analysis.json/libc_evidence`. +Первоначальное предположение о сложной инициализации внутри `_init_env` +для этого дампа не подтвердилось. Возврат соответствует реальному коду функции. +Формат `BBPROBE2` содержит флаг этой проверки; без флага runtime отключён. +Старые образы `BBPROBE1` читаются с отключённым runtime. + +`link_libc.py` создаёт отдельный `out/boot-libc.bin` формата `BBPROBE3`: +добавляет два сегмента оригинальной libc, её перемещения адресов и 202 +резервные привязки экспортов. Сопоставляет NID вместе с именами и версиями +библиотеки/модуля: локальные суффиксы libc `#C#A` и eboot `#q#q` различаются. +Реализованные host-контракты имеют приоритет. Остальные совпавшие импорты +ссылаются на настоящий код/данные libc, включая объекты и таблицы C++. +Исходные файлы игры не изменяются; сведения о привязках и SHA-256 libc +записываются в `out/libc-link.json`. + +Перед входом в eboot выполняется `DT_INIT` libc. Поддержан TLS этой библиотеки: +модуль 2, шаблон 544 байта, блок 1184 байта на host-поток, обнулённый остаток; +14 перемещений `DTPMOD64` записывают номер модуля, а не указатель на образ. +`__tls_get_addr` проверяет модуль и границы. Полный TLS всех модулей PS4, +его освобождение при завершении гостевых потоков и прямой доступ через FS +не реализованы. Для текущего одного гостевого потока блок живёт до выхода. +`sceKernelGetProcParam` возвращает исходный перемещённый procparam eboot; +`_sceKernelRtldSetApplicationHeapAPI` сохраняет таблицу callbacks аллокатора. + +`runtime_thread.c` реализует self и запросы init/get/getaffinity/destroy +атрибутов текущего гостевого потока. Для этого прототипа существует один +виртуальный CPU (маска 1); это не маска host CPU и не настройка его affinity. +Создание гостевых потоков и изменение атрибутов остаются неподдержанными. + +`probe.c` выделяет память, копирует сегменты и применяет перемещения адресов. +Неизвестные функции направляются в исполняемые перехватчики, печатающие NID +и завершающие процесс. Неподдерживаемые импортированные данные направляются в недоступные +страницы: их использование вызывает ошибку, а не возвращает фиктивные данные. +После загрузки устанавливаются права страниц по ELF, код получает права RX. +Затем выполняется прямой вызов оригинальной точки входа по SysV ABI. +Подготовки аргументов достаточно для наблюдаемого участка; полноценный стек +запуска ядра PS4, исключения и общий механизм загрузки зависимых модулей +не реализованы; пока специально подключена только libc. + +`runtime.c` реализует проверенный возврат из `_init_env`, реестр `atexit`/ +`__cxa_atexit` с обратным порядком и фильтрацией DSO, `__cxa_finalize`, +`exit`, guard acquire/release/abort, случайный process-local stack canary, +аварийный обработчик повреждения стека, четыре функции работы с памятью и `strlen`. +Сопоставление выполняется по полному NID с library/module suffix именно +этого eboot, без автоматического «вернуть 0» для неизвестных импортов. +Реестр завершения и guards рассчитаны на текущий один гостевой поток; +рекурсивная/конкурентная инициализация guard останавливает выполнение с кодом 21. + +`runtime_mutex.c` связывает PS4 mutex/атрибуты с Linux pthread, преобразует +типы и коды ошибок, поддерживает рекурсивные и статически созданные mutex. +Приоритетные протоколы, PS4-планировщик и гостевые потоки не реализованы. +Opaque handles предназначены для реализованных API; двоичный layout +внутренних PS4 mutex не воспроизводится. Наблюдаемый участок libc работает +через эти API; прямой доступ к внутренностям mutex потребует отдельной реализации. + +POSIX-импорты mutex из `libScePosix` используют тот же backend через +отдельные wrappers: возвращают положительные PS4 errno, а не отрицательные +коды `scePthread`. Двухаргументный `pthread_mutex_init` не читает отсутствующий +третий аргумент. Linux errno не передаётся гостю напрямую. + +`runtime_sema.c` реализует kernel create/delete, wait/poll, signal/cancel. +Handles — уникальные 32-битные ID; удалённые ID не переиспользуются. +Проверены счётчики и переполнение, таймаут в микросекундах с монотонными +часами, резервирование токенов до пробуждения, отмена и удаление с ожидающими +host-потоками. Объект освобождается после возврата всех ожидающих вызовов. +В режиме FIFO обслуживаются подходящие запросы в порядке очереди; запрос +меньшего размера может пройти ожидающий запрос, для которого токенов ещё нет. +Это соответствует использованной справочной модели shadPS4; сопоставление +на реальной PS4 пока не выполнено. +Атрибуты 0/2 допускают создание и неблокирующие операции, но блокирующее +ожидание явно останавливает прототип (21): приоритетный PS4-планировщик ещё +отсутствует. Ненулевые option parameters также не реализованы. В текущем +запуске игра создала 17 семафоров с attr=2, initial=0, max=1, но пока не +выполняла wait/signal; эти операции проверены отдельными C-тестами. + +`runtime_time.c` поддерживает POSIX `gettimeofday`: время берётся у host, +поля копируются в явные PS4 timeval/timezone. Проверены границы полей и +диапазон микросекунд. Неожиданная ошибка host API останавливает прототип: +полный POSIX errno/TLS bridge ещё не реализован. + +`runtime_rwlock.c` поддерживает init/destroy, read/write, try-read/try-write, +timed-read/timed-write и unlock поверх Linux pthread. Реестр синхронизирует +инициализацию статических handles, отслеживает владельцев, читателей и +ожидающие вызовы: уничтожение занятой блокировки возвращает EBUSY, +чужой unlock — EPERM, таймаут — Orbis ETIMEDOUT. Ожидание не удерживает +mutex реестра. Проверена одновременная работа нескольких host-потоков, +но создание гостевых потоков пока отсутствует. Поддержаны только атрибуты +по умолчанию; нестандартные атрибуты останавливают прототип с кодом 21. + +`runtime_memory.c` даёт **ограниченный CPU-пул 512 МиБ для исследования**. +Это выбранный бюджет прототипа, не объём RAM PS4. Выделение возвращает +виртуальный физический offset; Linux memfd обеспечивает реальное общее +хранилище для нескольких отображений и выравнивание 16 КиБ/2 МиБ. +Реализованы allocate/map, полное unmap и полное release. Поддержаны типы +памяти 0/3 для CPU, permissions read/write, flags=0, автоматический адрес; +иной режим останавливается с диагностикой. Частичные release/unmap пока +возвращают EINVAL. GPU coherency, резервирование фиксированных адресов, +полное адресное пространство PS4 и подключение этого пула к Vulkan отсутствуют. + +`vulkan_smoke.c` создаёт instance/device/queue, отправляет `vkCmdFillBuffer`, +ставит барьер для чтения CPU, ожидает завершения и сравнивает все слова буфера. +Это проверка будущего графического backend, не переводчик GNM. + +## Сборка на других системах + +Linux x86-64: Python 3, GCC/Clang, Vulkan headers и loader. Обычно достаточно: + +```bash +python3 native_probe/prepare.py CUSA03173 +python3 native_probe/link_libc.py CUSA03173 +bash native_probe/build.sh +``` + +Скрипт поддерживает `CC`, `VULKAN_INCLUDE`, `VULKAN_LIB`; +при наличии `pkg-config vulkan` использует его настройки. + +Для Windows в исходнике есть ветка `VirtualAlloc`/`VirtualProtect` и явный +SysV ABI. Предполагается **MinGW-w64 GCC/Clang x86-64**, не MSVC. +Эта ветка **не собрана и не проверена** в текущем Linux-окружении. +Пример ручной сборки в окружении MinGW с установленным Vulkan SDK: + +```text +python native_probe/prepare.py CUSA03173 +gcc -std=c11 -O2 -Wall -Wextra native_probe/probe.c native_probe/runtime.c native_probe/runtime_mutex.c native_probe/runtime_thread.c native_probe/runtime_rwlock.c native_probe/runtime_sema.c native_probe/runtime_time.c native_probe/runtime_memory.c native_probe/vulkan_smoke.c -I/Include -L/Lib -lvulkan-1 -o native_probe/out/bb-probe.exe +native_probe/out/bb-probe.exe native_probe/out/boot.bin +``` + +Пути SDK заменяются фактическими; бинарник Linux непереносим на Windows. +Диагностика сигналов и таймер в текущем исходнике реализованы только для Linux. +Новые mutex/rwlock/semaphore/time/direct-memory backends также реализованы только для Linux; +Windows дойдёт до более раннего неподдерживаемого импорта. + +## Проверки + +```bash +bash native_probe/build.sh --test +python3 -m unittest discover -s native_probe -v +``` + +Пройдено 35 Python-тестов, включая запуск набора C-проверок runtime: +границы SELF/образа, проверка инструкции `_init_env`, прямое исполнение +x86-64, перемещения адресов, режим strict, отключение неподтверждённого runtime, +диагностика сбоев. C-проверки охватывают обратный порядок деструкторов, +DSO и повторную финализацию, регистрацию при финализации и рост реестра, +guard acquire/abort/release, ошибки и рекурсивность mutex, выравнивание, +непересечение физических выделений, shared aliasing и повторное выделение +очищенной памяти. Stack protector и рекурсивный guard проверены в subprocess. +Дополнительно проверены жизненный цикл rwlock, повторные read-захваты, +чужой unlock, занятое уничтожение, несколько одновременных читателей, +ожидающий writer, преобразование таймаутов и `strlen` с NUL внутри строки. +Добавлены проверки нативного инициализатора/экспорта, приоритета host API, +отключения libc в strict-режиме, прав исполнения и границ новых metadata, +совпадения идентичности при разных локальных ID, отказа при другой версии +библиотеки и обработки TLS-релокаций. C-тест проверяет отдельные TLS-блоки +в host-потоках, шаблон/BSS, запросы атрибутов и регистрацию heap API. +Отдельный `sema-test` проверяет 32-битную запись handle без порчи соседнего +поля, устаревшие ID, переполнение, таймаут, очередь из нескольких host-потоков, +резервирование токенов, отмену/удаление с ожидающими и явный отказ от +приоритетного блокирующего ожидания. Проверены положительные ошибки POSIX +mutex, рекурсивный захват и выходные структуры `gettimeofday`. +Linux-сборка выполнена с `-Wall -Wextra -Werror`. +Актуальный интеграционный запуск настоящего eboot записан в `out/run.log`; +результат старого режима — в `out/strict-run.log`. + +## Следующие этапы настоящего порта + +1. Реализовать загрузку/реестр системных модулей и необходимые контракты + AppContent. Игра вызвала `sceSysmoduleLoadModule(0xb4)` из `0x2026149`; + по справочной таблице этот ID означает `libSceAppContent`. Такого файла + среди семи локальных `sce_module/*.prx` нет. Потребуется реализация + используемых API и состояния модуля; простой возврат успеха не добавлен. +2. Продолжить конструкторы, дополнить память/синхронизацию, затем реализовать + TLS остальных модулей, запуск потоков и загрузку необходимых модулей. +3. Дойти до `main`, добавить файловую систему (`/app0` → каталог ресурсов) + и фиксировать каждый следующий неподдерживаемый контракт. +4. Перевести GNM/PM4-команды, форматы ресурсов и AMD GCN-шейдеры в Vulkan/SPIR-V; + затем связать VideoOut с окном и swapchain. Наличие Vulkan само по себе + не делает графический код PS4 совместимым. +5. Для статической рекомпиляции восстанавливать функции и контрольный поток, + таблицы виртуальных вызовов, исключения и ABI; проверять поведение сравнением + с исходным машинным кодом. На x86-64 прямое исполнение с совместимым runtime + уже позволяет исследовать запуск без предварительного перевода всего CPU-кода. + +Приоритет следующего изменения — Sysmodule/AppContent и следующие конструкторы. + +## Справочные источники + +Формат SELF и правила соотнесения сегментов сверены с +[заголовками загрузчика shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/loader/elf.h) +и [загрузкой сегментов](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/loader/elf.cpp). +PS4 dynamic-таблицы и вычисление NID сверены с +[module.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/module.cpp), +контекст запуска — с [linker.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/linker.cpp). +Сигнатуры mutex и значения типов сверены с +[mutex.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/threads/mutex.cpp) +и [pthread.h](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/threads/pthread.h), +rwlock — с [rwlock.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/threads/rwlock.cpp), +сигнатуры direct memory — с +[memory.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/memory.cpp). +Семафоры сверены с +[semaphore.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/threads/semaphore.cpp), +структуры времени — с +[time.h](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/time.h). +Идентификатор AppContent — с +[sysmodule_table.h](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/sysmodule/sysmodule_table.h). +Новые контракты регистрации heap API и procparam сверены с +[linker.h](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/linker.h) +и [process.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/process.cpp), +атрибуты потоков — с +[pthread_attr.cpp](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/kernel/threads/pthread_attr.cpp). +Тело `_init_env` и устройство guards проверены дизассемблированием локальной libc. +Реализация прототипа написана отдельно; зависимости на исполняемый shadPS4 нет. + +Каталог `out/` содержит производные данные игры, имеет `.gitignore` и не нужен +для распространения исходников инструмента. diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..2ebe8bf --- /dev/null +++ b/build.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -euo pipefail +cd -- "$(dirname -- "$0")" +mkdir -p out +if [[ -z ${CC:-} ]]; then + CC=$(command -v cc || command -v gcc || true) + if [[ -z $CC ]]; then + for candidate in /nix/store/*-gcc-wrapper-*/bin/gcc; do + if [[ -x $candidate ]]; then CC=$candidate; break; fi + done + fi +fi +if [[ -z ${CC:-} ]]; then echo 'Install GCC/Clang or set CC.' >&2; exit 1; fi +# Dependencies come from pkg-config (Vulkan loader/headers, SDL3). On NixOS the +# environment is provided by shell.nix; re-enter it automatically if needed. +if ! { command -v pkg-config >/dev/null && pkg-config --exists vulkan sdl3 && command -v cmake >/dev/null && command -v ninja >/dev/null; }; then + if [[ -z ${BB_IN_NIX_SHELL:-} ]] && command -v nix-shell >/dev/null; then + exec env BB_IN_NIX_SHELL=1 nix-shell shell.nix --run "bash build.sh $*" + fi + echo 'Need pkg-config with vulkan and sdl3, cmake and ninja (see shell.nix).' >&2; exit 1 +fi +read -r -a includes <<< "$(pkg-config --cflags vulkan sdl3)" +read -r -a libraries <<< "$(pkg-config --libs vulkan sdl3)" +# GPU library (shadPS4 video core + drivers), built by CMake into out/gpu/libbbgpu.so. +cmake -S gpu -B out/gpu -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo >/dev/null +# A failed GPU build must stop here: an older libbbgpu.so would otherwise be used silently. +if ! ninja -C out/gpu bbgpu > out/gpu-build.log 2>&1; then + grep -v '^\[' out/gpu-build.log | tail -40 >&2 + echo 'GPU library build failed (full log: out/gpu-build.log)' >&2; exit 1 +fi +gpu=(-Lout/gpu -lbbgpu -Wl,-rpath,"$PWD/out/gpu" -rdynamic) +runtime=(runtime*.c) +# Third-party decoders: compiled once, without this project's -Werror policy. +atrac9=(third_party/LibAtrac9/C/src/*.c) +if [[ ! -f out/libatrac9.a || -n $(find third_party/LibAtrac9/C/src -newer out/libatrac9.a -name '*.c') ]]; then + rm -rf out/atrac9 && mkdir -p out/atrac9 + for source in "${atrac9[@]}"; do "$CC" -std=c99 -O2 -g -w -c "$source" -o "out/atrac9/$(basename "${source%.c}").o"; done + ar rcs out/libatrac9.a out/atrac9/*.o +fi +"$CC" -std=c11 -O2 -g -Wall -Wextra -Werror -pthread -no-pie "${includes[@]}" probe.c "${runtime[@]}" vulkan_smoke.c out/libatrac9.a -lm "${gpu[@]}" "${libraries[@]}" -o out/bb-probe +echo "Built $PWD/out/bb-probe" +if [[ ${1:-} == --test ]]; then + "$CC" -std=c11 -O2 -g -Wall -Wextra -Werror -pthread test_runtime.c "${runtime[@]}" out/libatrac9.a -lm "${gpu[@]}" "${libraries[@]}" -o out/runtime-test + out/runtime-test + "$CC" -std=c11 -O2 -g -Wall -Wextra -Werror -pthread test_sema.c "${runtime[@]}" out/libatrac9.a -lm "${gpu[@]}" "${libraries[@]}" -o out/sema-test + out/sema-test + "$CC" -std=c11 -O2 -g -Wall -Wextra -Werror test_content.c runtime_content.c -o out/content-test + out/content-test +fi diff --git a/content_profile.py b/content_profile.py new file mode 100644 index 0000000..9fb9a81 --- /dev/null +++ b/content_profile.py @@ -0,0 +1,26 @@ +"""Prepare explicit offline AppContent metadata; SKU is a probe setting, not a license check.""" +import argparse +import json +import struct +from pathlib import Path +from prepare import sfo + + +def prepare(game, out, sku='full'): + values=sfo((game/'sce_sys/param.sfo').read_bytes()) + params=[values.get(f'USER_DEFINED_PARAM_{i}',0) for i in range(1,5)] + if any(type(v) is not int or not 0<=v<=0xffffffff for v in params): + raise ValueError('invalid user-defined parameter') + profile=dict(title_id=values.get('TITLE_ID'),sku=sku,sku_source='explicit probe setting', + user_params=params, mounted_addons=[],boot_attr=0) + out.mkdir(parents=True,exist_ok=True) + (out/'content.bin').write_bytes(struct.pack('<8s5I',b'BBCONT01',{'full':3,'trial':1}[sku],*params)) + (out/'content-profile.json').write_text(json.dumps(profile,indent=2)+'\n') + print(f'AppContent profile: SKU={sku} (probe setting), user params={params}, mounted add-ons=0') + +if __name__=='__main__': + p=argparse.ArgumentParser(description=__doc__) + p.add_argument('game',type=Path) + p.add_argument('--out',type=Path,default=Path(__file__).parent/'out') + p.add_argument('--sku',choices=['full','trial'],default='full') + a=p.parse_args();prepare(a.game,a.out,a.sku) diff --git a/got_import.py b/got_import.py new file mode 100644 index 0000000..4ae5b7a --- /dev/null +++ b/got_import.py @@ -0,0 +1,18 @@ +"""Diagnostic: name the import bound to a GOT slot (guest offsets) in out/boot.bin.""" +import re, struct, sys +from pathlib import Path +here = Path(__file__).parent +data = (here / 'out/boot.bin').read_bytes() +size, entry, ns, nr, ni, caps = struct.unpack_from(' headers (same scheme as shadPS4's host_shaders/CMakeLists.txt). +set(SHADER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/shadps4/video_core/host_shaders) +set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) +set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) +set(SHADER_HEADERS "") +function(add_host_shader FILENAME SHADER_NAME) + set(OUT ${SHADER_DIR}/${SHADER_NAME}.h) + string(TOUPPER ${SHADER_NAME} SYMBOL) + set(DEFINES ${ARGN}) + list(TRANSFORM DEFINES PREPEND "-D") + add_custom_command(OUTPUT ${OUT} + COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADER_DIR} + COMMAND ${GLSLANG_COMPILER} --target-env vulkan1.3 -o ${OUT} --vn ${SYMBOL} ${DEFINES} ${SHADER_SRC}/${FILENAME} + COMMAND ${CMAKE_COMMAND} "-DHEADER_FILE=${OUT}" -P ${SHADER_SRC}/AddShaderHeaderInclude.cmake + DEPENDS ${SHADER_SRC}/${FILENAME} VERBATIM) + set(SHADER_HEADERS ${SHADER_HEADERS} ${OUT} PARENT_SCOPE) +endfunction() +add_host_shader(color_to_ms_depth.frag color_to_ms_depth_frag) +add_host_shader(ms_image_blit.frag ms_image_blit_frag) +add_host_shader(ms_image_blit.frag ms_image_blit_msaa_frag SRC_MSAA=1) +add_host_shader(fault_buffer_process.comp fault_buffer_process_comp) +add_host_shader(fs_tri.vert fs_tri_vert) +add_host_shader(fsr.comp fsr_easu_comp SAMPLE_EASU=1) +add_host_shader(fsr.comp fsr_rcas_comp SAMPLE_RCAS=1) +add_host_shader(post_process.frag post_process_frag) +foreach(BPP IN ITEMS 8 16 32 64 96 128) + add_host_shader(tiling.comp tiling_micro_${BPP}_comp BITS_PER_PIXEL=${BPP} IS_MACRO_TILED=0) + add_host_shader(tiling.comp tiling_macro_${BPP}_comp BITS_PER_PIXEL=${BPP} IS_MACRO_TILED=1) +endforeach() +add_custom_target(host_shaders DEPENDS ${SHADER_HEADERS}) + +file(GLOB_RECURSE VIDEO_CORE CONFIGURE_DEPENDS shadps4/video_core/*.cpp) +file(GLOB_RECURSE RECOMPILER CONFIGURE_DEPENDS shadps4/shader_recompiler/*.cpp) +list(FILTER VIDEO_CORE EXCLUDE REGEX "renderdoc\\.cpp$") +set(COMMON + shadps4/common/decoder.cpp shadps4/common/error.cpp + shadps4/common/io_file.cpp shadps4/common/native_clock.cpp shadps4/common/number_utils.cpp + shadps4/common/path_util.cpp shadps4/common/rdtsc.cpp shadps4/common/spin_lock.cpp shadps4/common/recursive_lock.cpp + shadps4/common/string_util.cpp shadps4/common/thread.cpp shadps4/common/signal_context.cpp + shim/common/logging/log.cpp) +file(GLOB AVPLAYER CONFIGURE_DEPENDS shadps4/core/libraries/avplayer/*.cpp) +pkg_check_modules(FFMPEG REQUIRED IMPORTED_TARGET libavformat libavcodec libavutil libswscale libswresample) +file(GLOB SHIM_SOURCES CONFIGURE_DEPENDS shim/*.cpp shim/*/*.cpp) +add_library(bbgpu SHARED ${VIDEO_CORE} ${RECOMPILER} ${COMMON} ${SHIM_SOURCES} + shadps4/core/libraries/gnmdriver/gnmdriver.cpp + shadps4/core/libraries/videoout/driver.cpp shadps4/core/libraries/videoout/video_out.cpp + shadps4/core/libraries/kernel/equeue.cpp ${AVPLAYER} + shadps4/core/libraries/videodec/video_utils.cpp) +add_dependencies(bbgpu host_shaders) +target_include_directories(bbgpu PRIVATE shim shadps4 ${SHADER_INCLUDE} third_party/gcn/include third_party/half/include) +target_compile_definitions(bbgpu PRIVATE BOOST_ASIO_STANDALONE NDEBUG) +target_compile_options(bbgpu PRIVATE -Wno-deprecated-declarations -Wno-missing-field-initializers) +# Runtime symbols (runtime_memory_*, runtime_process_*) resolve against bb-probe. +target_link_options(bbgpu PRIVATE -Wl,--allow-shlib-undefined) +target_link_libraries(bbgpu PUBLIC Vulkan::Headers fmt::fmt Boost::headers magic_enum::magic_enum + tsl::robin_map GPUOpen::VulkanMemoryAllocator PkgConfig::XXHASH PkgConfig::SDL3 PkgConfig::X11 PkgConfig::FFMPEG miniz::miniz Zydis::Zydis sirit) diff --git a/gpu/VENDOR.txt b/gpu/VENDOR.txt new file mode 100644 index 0000000..bec9cad --- /dev/null +++ b/gpu/VENDOR.txt @@ -0,0 +1,5 @@ +Vendored from https://github.com/shadps4-emu/shadPS4 commit b4e7ae776071ceb1dd35004577a8719481e1d258 (GPL-2.0-or-later). +Directories: src/video_core, src/shader_recompiler, src/common, src/core/libraries/{gnmdriver,videoout}, externals/gcn, externals/sirit, externals/half. +Also: src/core/libraries/kernel/{orbis_error,posix_error,time,process,equeue}.h, equeue.cpp, src/core/libraries/error_codes.h, src/core/platform.h, src/core/libraries/system/{userservice,systemservice}.h. +Also: src/core/libraries/avplayer (without the handle streamer), src/core/libraries/videodec/video_utils.{h,cpp}. +Local changes are marked with "bbport:" comments. diff --git a/gpu/bbgpu.h b/gpu/bbgpu.h new file mode 100644 index 0000000..de9ca00 --- /dev/null +++ b/gpu/bbgpu.h @@ -0,0 +1,34 @@ +/* C interface of the GPU library (gpu/): shadPS4's Liverpool/Vulkan video core, + * GnmDriver, VideoOut and kernel event queues, adapted to the native loader. */ +#ifndef BBGPU_H +#define BBGPU_H +#include +#ifdef __cplusplus +extern "C" { +#endif +typedef struct { + const char *title; /* window title */ + const char *serial; /* CUSA id, names the pipeline cache */ + const char *user_dir; /* pipeline cache/logs directory */ + uint32_t sdk_version; /* from the eboot's procparam */ + uint32_t psf_attributes; /* param.sfo ATTRIBUTE */ + int32_t width, height; /* initial window size */ +} BbGpuConfig; +/* Registers kernel event queues (needed with or without graphics). */ +void bbgpu_register_kernel(void); +/* Creates window, Vulkan device, presenter and GPU command processor. */ +int bbgpu_init(const BbGpuConfig *config); +/* Function for an imported NID ("NID#lib#mod"), or 0 when the GPU library does not provide it. */ +uintptr_t bbgpu_resolve(const char *scoped_nid); +/* Called first by the loader's SIGSEGV handler: 1 when a GPU page-tracking fault was handled. */ +int bbgpu_handle_fault(void *ucontext, void *address); +/* Keyboard text entry through the game window (IME dialog). begin returns 0 when + * no window exists; poll returns 0 typing, 1 confirmed, 2 cancelled (UTF-8 text). */ +int bbgpu_text_input_begin(const char *initial_utf8, const char *prompt_utf8); +int bbgpu_text_input_poll(char *out_utf8, uint64_t size); +/* Number of symbols registered by the vendored libraries (diagnostics). */ +unsigned bbgpu_symbol_count(void); +#ifdef __cplusplus +} +#endif +#endif diff --git a/gpu/shadps4/LICENSE b/gpu/shadps4/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/gpu/shadps4/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/gpu/shadps4/common/adaptive_mutex.h b/gpu/shadps4/common/adaptive_mutex.h new file mode 100644 index 0000000..bdc10b9 --- /dev/null +++ b/gpu/shadps4/common/adaptive_mutex.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#if __unix__ +#include +#endif + +namespace Common { + +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +class AdaptiveMutex { +public: + AdaptiveMutex() = default; + ~AdaptiveMutex() { + pthread_mutex_destroy(&mutex); + } + AdaptiveMutex(const AdaptiveMutex&) = delete; + AdaptiveMutex& operator=(const AdaptiveMutex&) = delete; + + void lock() { + pthread_mutex_lock(&mutex); + } + void unlock() { + pthread_mutex_unlock(&mutex); + } + [[nodiscard]] bool try_lock() { + return pthread_mutex_trylock(&mutex) == 0; + } + +private: + pthread_mutex_t mutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP; +}; +#endif // PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP + +} // namespace Common diff --git a/gpu/shadps4/common/aes.h b/gpu/shadps4/common/aes.h new file mode 100644 index 0000000..5ca0096 --- /dev/null +++ b/gpu/shadps4/common/aes.h @@ -0,0 +1,1195 @@ +// SPDX-FileCopyrightText: 2015 kkAyataka +// SPDX-License-Identifier: BSL-1.0 + +#pragma once + +#include +#include +#include +#include +#include +#include + +/** AES cipher APIs */ +namespace aes { +namespace detail { + +const int kWordSize = 4; +typedef unsigned int Word; + +const int kBlockSize = 4; +/** @private */ +struct State { + Word w[4]; + Word& operator[](const int index) { + return w[index]; + } + const Word& operator[](const int index) const { + return w[index]; + } +}; + +const int kStateSize = 16; // Word * BlockSize +typedef State RoundKey; +typedef std::vector RoundKeys; + +inline void add_round_key(const RoundKey& key, State& state) { + for (int i = 0; i < kBlockSize; ++i) { + state[i] ^= key[i]; + } +} + +const unsigned char kSbox[] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + +const unsigned char kInvSbox[] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; + +inline Word sub_word(const Word w) { + return kSbox[(w >> 0) & 0xFF] << 0 | kSbox[(w >> 8) & 0xFF] << 8 | + kSbox[(w >> 16) & 0xFF] << 16 | kSbox[(w >> 24) & 0xFF] << 24; +} + +inline Word inv_sub_word(const Word w) { + return kInvSbox[(w >> 0) & 0xFF] << 0 | kInvSbox[(w >> 8) & 0xFF] << 8 | + kInvSbox[(w >> 16) & 0xFF] << 16 | kInvSbox[(w >> 24) & 0xFF] << 24; +} + +inline void sub_bytes(State& state) { + for (int i = 0; i < kBlockSize; ++i) { + state[i] = sub_word(state[i]); + } +} + +inline void inv_sub_bytes(State& state) { + for (int i = 0; i < kBlockSize; ++i) { + state[i] = inv_sub_word(state[i]); + } +} + +inline void shift_rows(State& state) { + const State ori = {state[0], state[1], state[2], state[3]}; + for (int r = 1; r < kWordSize; ++r) { + const Word m2 = 0xFF << (r * 8); + const Word m1 = ~m2; + for (int c = 0; c < kBlockSize; ++c) { + state[c] = (state[c] & m1) | (ori[(c + r) % kBlockSize] & m2); + } + } +} + +inline void inv_shift_rows(State& state) { + const State ori = {state[0], state[1], state[2], state[3]}; + for (int r = 1; r < kWordSize; ++r) { + const Word m2 = 0xFF << (r * 8); + const Word m1 = ~m2; + for (int c = 0; c < kBlockSize; ++c) { + state[c] = (state[c] & m1) | (ori[(c + kBlockSize - r) % kWordSize] & m2); + } + } +} + +inline unsigned char mul2(const unsigned char b) { + unsigned char m2 = b << 1; + if (b & 0x80) { + m2 ^= 0x011B; + } + + return m2; +} + +inline unsigned char mul(const unsigned char b, const unsigned char m) { + unsigned char v = 0; + unsigned char t = b; + for (int i = 0; i < 8; ++i) { // 8-bits + if ((m >> i) & 0x01) { + v ^= t; + } + + t = mul2(t); + } + + return v; +} + +inline void mix_columns(State& state) { + for (int i = 0; i < kBlockSize; ++i) { + const unsigned char v0_1 = (state[i] >> 0) & 0xFF; + const unsigned char v1_1 = (state[i] >> 8) & 0xFF; + const unsigned char v2_1 = (state[i] >> 16) & 0xFF; + const unsigned char v3_1 = (state[i] >> 24) & 0xFF; + + const unsigned char v0_2 = mul2(v0_1); + const unsigned char v1_2 = mul2(v1_1); + const unsigned char v2_2 = mul2(v2_1); + const unsigned char v3_2 = mul2(v3_1); + + const unsigned char v0_3 = v0_2 ^ v0_1; + const unsigned char v1_3 = v1_2 ^ v1_1; + const unsigned char v2_3 = v2_2 ^ v2_1; + const unsigned char v3_3 = v3_2 ^ v3_1; + + state[i] = (v0_2 ^ v1_3 ^ v2_1 ^ v3_1) << 0 | (v0_1 ^ v1_2 ^ v2_3 ^ v3_1) << 8 | + (v0_1 ^ v1_1 ^ v2_2 ^ v3_3) << 16 | (v0_3 ^ v1_1 ^ v2_1 ^ v3_2) << 24; + } +} + +inline void inv_mix_columns(State& state) { + for (int i = 0; i < kBlockSize; ++i) { + const unsigned char v0 = (state[i] >> 0) & 0xFF; + const unsigned char v1 = (state[i] >> 8) & 0xFF; + const unsigned char v2 = (state[i] >> 16) & 0xFF; + const unsigned char v3 = (state[i] >> 24) & 0xFF; + + state[i] = (mul(v0, 0x0E) ^ mul(v1, 0x0B) ^ mul(v2, 0x0D) ^ mul(v3, 0x09)) << 0 | + (mul(v0, 0x09) ^ mul(v1, 0x0E) ^ mul(v2, 0x0B) ^ mul(v3, 0x0D)) << 8 | + (mul(v0, 0x0D) ^ mul(v1, 0x09) ^ mul(v2, 0x0E) ^ mul(v3, 0x0B)) << 16 | + (mul(v0, 0x0B) ^ mul(v1, 0x0D) ^ mul(v2, 0x09) ^ mul(v3, 0x0E)) << 24; + } +} + +inline Word rot_word(const Word v) { + return ((v >> 8) & 0x00FFFFFF) | ((v & 0xFF) << 24); +} + +/** + * @private + * @throws std::invalid_argument + */ +inline unsigned int get_round_count(const int key_size) { + switch (key_size) { + case 16: + return 10; + case 24: + return 12; + case 32: + return 14; + default: + throw std::invalid_argument("Invalid key size"); + } +} + +/** + * @private + * @throws std::invalid_argument + */ +inline RoundKeys expand_key(const unsigned char* key, const int key_size) { + if (key_size != 16 && key_size != 24 && key_size != 32) { + throw std::invalid_argument("Invalid key size"); + } + + const Word rcon[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + + const int nb = kBlockSize; + const int nk = key_size / nb; + const int nr = get_round_count(key_size); + + std::vector w(nb * (nr + 1)); + for (int i = 0; i < nk; ++i) { + memcpy(&w[i], key + (i * kWordSize), kWordSize); + } + + for (int i = nk; i < nb * (nr + 1); ++i) { + Word t = w[i - 1]; + if (i % nk == 0) { + t = sub_word(rot_word(t)) ^ rcon[i / nk]; + } else if (nk > 6 && i % nk == 4) { + t = sub_word(t); + } + + w[i] = t ^ w[i - nk]; + } + + RoundKeys keys(nr + 1); + memcpy(&keys[0], &w[0], w.size() * kWordSize); + + return keys; +} + +inline void copy_bytes_to_state(const unsigned char data[16], State& state) { + memcpy(&state[0], data + 0, kWordSize); + memcpy(&state[1], data + 4, kWordSize); + memcpy(&state[2], data + 8, kWordSize); + memcpy(&state[3], data + 12, kWordSize); +} + +inline void copy_state_to_bytes(const State& state, unsigned char buf[16]) { + memcpy(buf + 0, &state[0], kWordSize); + memcpy(buf + 4, &state[1], kWordSize); + memcpy(buf + 8, &state[2], kWordSize); + memcpy(buf + 12, &state[3], kWordSize); +} + +inline void xor_data(unsigned char data[kStateSize], const unsigned char v[kStateSize]) { + for (int i = 0; i < kStateSize; ++i) { + data[i] ^= v[i]; + } +} + +/** increment counter (128-bit int) by 1 */ +inline void incr_counter(unsigned char counter[kStateSize]) { + unsigned n = kStateSize, c = 1; + do { + --n; + c += counter[n]; + counter[n] = c; + c >>= 8; + } while (n); +} + +inline void encrypt_state(const RoundKeys& rkeys, const unsigned char data[16], + unsigned char encrypted[16]) { + State s; + copy_bytes_to_state(data, s); + + add_round_key(rkeys[0], s); + + for (unsigned int i = 1; i < rkeys.size() - 1; ++i) { + sub_bytes(s); + shift_rows(s); + mix_columns(s); + add_round_key(rkeys[i], s); + } + + sub_bytes(s); + shift_rows(s); + add_round_key(rkeys.back(), s); + + copy_state_to_bytes(s, encrypted); +} + +inline void decrypt_state(const RoundKeys& rkeys, const unsigned char data[16], + unsigned char decrypted[16]) { + State s; + copy_bytes_to_state(data, s); + + add_round_key(rkeys.back(), s); + inv_shift_rows(s); + inv_sub_bytes(s); + + for (std::size_t i = rkeys.size() - 2; i > 0; --i) { + add_round_key(rkeys[i], s); + inv_mix_columns(s); + inv_shift_rows(s); + inv_sub_bytes(s); + } + + add_round_key(rkeys[0], s); + + copy_state_to_bytes(s, decrypted); +} + +template +std::vector key_from_string(const char (*key_str)[KeyLen]) { + std::vector key(KeyLen - 1); + memcpy(&key[0], *key_str, KeyLen - 1); + return key; +} + +inline bool is_valid_key_size(const std::size_t key_size) { + if (key_size != 16 && key_size != 24 && key_size != 32) { + return false; + } else { + return true; + } +} + +namespace gcm { + +const int kBlockBitSize = 128; +const int kBlockByteSize = kBlockBitSize / 8; + +/** + * @private + * GCM operation unit as bit. + * This library handles 128 bit little endian bit array. + * e.g. 0^127 || 1 == "000...0001" (bit string) == 1 + */ +typedef std::bitset bitset128; + +/** + * @private + * GCM operation unit. + * Little endian byte array + * + * If bitset128 is 1: 0^127 || 1 == "000...0001" (bit string) == 1 + * byte array is 0x00, 0x00, 0x00 ... 0x01 (low -> high). + * Byte array is NOT 0x01, 0x00 ... 0x00. + * + * This library handles GCM bit string in two ways. + * One is an array of bitset, which is a little endian 128-bit array's array. + * + * <- first byte + * bitset128 || bitset128 || bitset128... + * + * The other one is a byte array. + * <- first byte + * byte || byte || byte... + */ +class Block { +public: + Block() { + init_v(0, 0); + } + + Block(const unsigned char* bytes, const unsigned long bytes_size) { + init_v(bytes, bytes_size); + } + + Block(const std::vector& bytes) { + init_v(&bytes[0], bytes.size()); + } + + Block(const std::bitset<128>& bits); // implementation below + + inline unsigned char* data() { + return v_; + } + + inline const unsigned char* data() const { + return v_; + } + + inline std::bitset<128> to_bits() const { + std::bitset<128> bits; + for (int i = 0; i < 16; ++i) { + bits <<= 8; + bits |= v_[i]; + } + + return bits; + } + + inline Block operator^(const Block& b) const { + Block r; + for (int i = 0; i < 16; ++i) { + r.data()[i] = data()[i] ^ b.data()[i]; + } + return r; + } + +private: + unsigned char v_[16]; + + inline void init_v(const unsigned char* bytes, const std::size_t bytes_size) { + memset(v_, 0, sizeof(v_)); + + const std::size_t cs = (std::min)(bytes_size, static_cast(16)); + for (std::size_t i = 0; i < cs; ++i) { + v_[i] = bytes[i]; + } + } +}; + +// Workaround for clang optimization in 32-bit build via Visual Studio producing incorrect results +// (https://github.com/kkAyataka/plusaes/issues/43) +#if defined(__clang__) && defined(_WIN32) && !defined(_WIN64) +#pragma optimize("", off) +#endif +inline Block::Block(const std::bitset<128>& bits) { + init_v(0, 0); + const std::bitset<128> mask(0xFF); // 1 byte mask + for (std::size_t i = 0; i < 16; ++i) { + v_[15 - i] = static_cast(((bits >> (i * 8)) & mask).to_ulong()); + } +} +#if defined(__clang__) && defined(_WIN32) && !defined(_WIN64) +#pragma optimize("", on) +#endif + +template +unsigned long ceil(const T v) { + return static_cast(std::ceil(v) + 0.5); +} + +template +std::bitset operator||(const std::bitset& v1, const std::bitset& v2) { + std::bitset ret(v1.to_string() + v2.to_string()); + return ret; +} + +template +std::bitset lsb(const std::bitset& X) { + std::bitset r; + for (std::size_t i = 0; i < S; ++i) { + r[i] = X[i]; + } + return r; +} + +template +std::bitset msb(const std::bitset& X) { + std::bitset r; + for (std::size_t i = 0; i < S; ++i) { + r[S - 1 - i] = X[X.size() - 1 - i]; + } + return r; +} + +template +std::bitset inc32(const std::bitset X) { + const std::size_t S = 32; + + const auto a = msb(X); + const std::bitset b( + (lsb(X).to_ulong() + 1)); // % (2^32); + // lsb<32> is low 32-bit value + // Spec.'s "mod 2^S" is not necessary when S is 32 (inc32). + // ...and 2^32 is over 32-bit integer. + + return a || b; +} + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wself-assign" +#endif // __clang__ + +/** Algorithm 1 @private */ +inline Block mul_blocks(const Block X, const Block Y) { + const bitset128 R = (std::bitset<8>("11100001") || std::bitset<120>()); + + bitset128 X_bits = X.to_bits(); + bitset128 Z; + bitset128 V = Y.to_bits(); + for (int i = 127; i >= 0; --i) { + // Z + if (X_bits[i] == false) { + Z = Z; + } else { + Z = Z ^ V; + } + + // V + if (V[0] == false) { + V = V >> 1; + } else { + V = (V >> 1) ^ R; + } + } + + return Z; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif // __clang__ + +/** Algorithm 2 @private */ +inline Block ghash(const Block& H, const std::vector& X) { + const std::size_t m = X.size() / kBlockByteSize; + Block Ym; + for (std::size_t i = 0; i < m; ++i) { + const Block Xi(&X[i * kBlockByteSize], kBlockByteSize); + Ym = mul_blocks((Ym ^ Xi), H); + } + + return Ym; +} + +template +std::bitset make_bitset(const unsigned char* bytes, const std::size_t bytes_size) { + std::bitset bits; + for (auto i = 0u; i < bytes_size; ++i) { + bits <<= 8; + bits |= bytes[i]; + } + return bits; +} + +/** Algorithm 3 @private */ +inline std::vector gctr(const detail::RoundKeys& rkeys, const Block& ICB, + const unsigned char* X, const std::size_t X_size) { + if (!X || X_size == 0) { + return std::vector(); + } else { + const unsigned long n = ceil(X_size * 8.0 / kBlockBitSize); + std::vector Y(X_size); + + Block CB; + for (std::size_t i = 0; i < n; ++i) { + // CB + if (i == 0) { // first + CB = ICB; + } else { + CB = inc32(CB.to_bits()); + } + + // CIPH + Block eCB; + encrypt_state(rkeys, CB.data(), eCB.data()); + + // Y + int op_size = 0; + if (i < n - 1) { + op_size = kBlockByteSize; + } else { // last + op_size = (X_size % kBlockByteSize) ? (X_size % kBlockByteSize) : kBlockByteSize; + } + const Block Yi = Block(X + i * kBlockBitSize / 8, op_size) ^ eCB; + memcpy(&Y[i * kBlockByteSize], Yi.data(), op_size); + } + + return Y; + } +} + +inline void push_back(std::vector& bytes, const unsigned char* data, + const std::size_t data_size) { + bytes.insert(bytes.end(), data, data + data_size); +} + +inline void push_back(std::vector& bytes, const std::bitset<64>& bits) { + const std::bitset<64> mask(0xFF); // 1 byte mask + for (std::size_t i = 0; i < 8; ++i) { + bytes.push_back(static_cast(((bits >> ((7 - i) * 8)) & mask).to_ulong())); + } +} + +inline void push_back_zero_bits(std::vector& bytes, + const std::size_t zero_bits_size) { + const std::vector zero_bytes(zero_bits_size / 8); + bytes.insert(bytes.end(), zero_bytes.begin(), zero_bytes.end()); +} + +inline Block calc_H(const RoundKeys& rkeys) { + std::vector H_raw(gcm::kBlockByteSize); + encrypt_state(rkeys, &H_raw[0], &H_raw[0]); + return gcm::Block(H_raw); +} + +inline Block calc_J0(const Block& H, const unsigned char* iv, const std::size_t iv_size) { + if (iv_size == 12) { + const std::bitset<96> iv_bits = gcm::make_bitset<96>(iv, iv_size); + return iv_bits || std::bitset<31>() || std::bitset<1>(1); + } else { + const auto len_iv = iv_size * 8; + const auto s = 128 * gcm::ceil(len_iv / 128.0) - len_iv; + std::vector ghash_in; + gcm::push_back(ghash_in, iv, iv_size); + gcm::push_back_zero_bits(ghash_in, s + 64); + gcm::push_back(ghash_in, std::bitset<64>(len_iv)); + + return gcm::ghash(H, ghash_in); + } +} + +inline void calc_gcm_tag(const unsigned char* data, const std::size_t data_size, + const unsigned char* aadata, const std::size_t aadata_size, + const unsigned char* key, const std::size_t key_size, + const unsigned char* iv, const std::size_t iv_size, unsigned char* tag, + const std::size_t tag_size) { + const detail::RoundKeys rkeys = detail::expand_key(key, static_cast(key_size)); + const gcm::Block H = gcm::calc_H(rkeys); + const gcm::Block J0 = gcm::calc_J0(H, iv, iv_size); + + const auto lenC = data_size * 8; + const auto lenA = aadata_size * 8; + const std::size_t u = 128 * gcm::ceil(lenC / 128.0) - lenC; + const std::size_t v = 128 * gcm::ceil(lenA / 128.0) - lenA; + + std::vector ghash_in; + ghash_in.reserve((aadata_size + v / 8) + (data_size + u / 8) + 8 + 8); + gcm::push_back(ghash_in, aadata, aadata_size); + gcm::push_back_zero_bits(ghash_in, v); + gcm::push_back(ghash_in, data, data_size); + gcm::push_back_zero_bits(ghash_in, u); + gcm::push_back(ghash_in, std::bitset<64>(lenA)); + gcm::push_back(ghash_in, std::bitset<64>(lenC)); + const gcm::Block S = gcm::ghash(H, ghash_in); + const std::vector T = gcm::gctr(rkeys, J0, S.data(), gcm::kBlockByteSize); + + // return + memcpy(tag, &T[0], (std::min)(tag_size, static_cast(16))); +} + +/** Algorithm 4 and 5 @private */ +inline void crypt_gcm(const unsigned char* data, const std::size_t data_size, + const unsigned char* key, const std::size_t key_size, const unsigned char* iv, + const std::size_t iv_size, unsigned char* crypted) { + const detail::RoundKeys rkeys = detail::expand_key(key, static_cast(key_size)); + const gcm::Block H = gcm::calc_H(rkeys); + const gcm::Block J0 = gcm::calc_J0(H, iv, iv_size); + + const std::vector C = + gcm::gctr(rkeys, gcm::inc32(J0.to_bits()), data, data_size); + + if (crypted) { + memcpy(crypted, &C[0], data_size); + } +} + +} // namespace gcm + +} // namespace detail + +/** @defgroup Base Base + * Base definitions and convenient functions + * @{ */ + +/** Create 128-bit key from string. */ +inline std::vector key_from_string(const char (*key_str)[17]) { + return detail::key_from_string<17>(key_str); +} + +/** Create 192-bit key from string. */ +inline std::vector key_from_string(const char (*key_str)[25]) { + return detail::key_from_string<25>(key_str); +} + +/** Create 256-bit key from string. */ +inline std::vector key_from_string(const char (*key_str)[33]) { + return detail::key_from_string<33>(key_str); +} + +/** Calculates encrypted data size when padding is enabled. */ +inline unsigned long get_padded_encrypted_size(const unsigned long data_size) { + return data_size + detail::kStateSize - (data_size % detail::kStateSize); +} + +/** Error code */ +typedef enum { + kErrorOk = 0, + kErrorInvalidDataSize = 1, + kErrorInvalidKeySize, + kErrorInvalidBufferSize, + kErrorInvalidKey, + kErrorDeprecated, // kErrorInvalidNonceSize + kErrorInvalidIvSize, + kErrorInvalidTagSize, + kErrorInvalidTag +} Error; + +/** @} */ + +namespace detail { + +inline Error check_encrypt_cond(const unsigned long data_size, const unsigned long key_size, + const unsigned long encrypted_size, const bool pads) { + // check data size + if (!pads && (data_size % kStateSize != 0)) { + return kErrorInvalidDataSize; + } + + // check key size + if (!detail::is_valid_key_size(key_size)) { + return kErrorInvalidKeySize; + } + + // check encrypted buffer size + if (pads) { + const unsigned long required_size = get_padded_encrypted_size(data_size); + if (encrypted_size < required_size) { + return kErrorInvalidBufferSize; + } + } else { + if (encrypted_size < data_size) { + return kErrorInvalidBufferSize; + } + } + return kErrorOk; +} + +inline Error check_decrypt_cond(const unsigned long data_size, const unsigned long key_size, + const unsigned long decrypted_size, + const unsigned long* padded_size) { + // check data size + if (data_size % 16 != 0) { + return kErrorInvalidDataSize; + } + + // check key size + if (!detail::is_valid_key_size(key_size)) { + return kErrorInvalidKeySize; + } + + // check decrypted buffer size + if (!padded_size) { + if (decrypted_size < data_size) { + return kErrorInvalidBufferSize; + } + } else { + if (decrypted_size < (data_size - kStateSize)) { + return kErrorInvalidBufferSize; + } + } + + return kErrorOk; +} + +inline bool check_padding(const unsigned long padding, const unsigned char data[kStateSize]) { + if (padding > kStateSize) { + return false; + } + + for (unsigned long i = 0; i < padding; ++i) { + if (data[kStateSize - 1 - i] != padding) { + return false; + } + } + + return true; +} + +inline Error check_gcm_cond(const std::size_t key_size, const std::size_t iv_size, + const std::size_t tag_size) { + // check key size + if (!detail::is_valid_key_size(key_size)) { + return kErrorInvalidKeySize; + } + + if (iv_size < 1) { + return kErrorInvalidIvSize; + } + + // check tag size + if ((tag_size < 12 || 16 < tag_size) && (tag_size != 8) && (tag_size != 4)) { + return kErrorInvalidTagSize; + } + + return kErrorOk; +} + +} // namespace detail + +/** @defgroup ECB ECB + * ECB mode functions + * @{ */ + +/** + * Encrypts data with ECB mode. + * @param [in] data Data. + * @param [in] data_size Data size. + * If the pads is false, data size must be multiple of 16. + * @param [in] key key bytes. The key length must be 16 (128-bit), 24 (192-bit) or 32 (256-bit). + * @param [in] key_size key size. + * @param [out] encrypted Encrypted data buffer. + * @param [in] encrypted_size Encrypted data buffer size. + * @param [in] pads If this value is true, encrypted data is padded by PKCS. + * Encrypted data size must be multiple of 16. + * If the pads is true, encrypted data is padded with PKCS. + * So the data is multiple of 16, encrypted data size needs additonal 16 bytes. + * @since 1.0.0 + */ +inline Error encrypt_ecb(const unsigned char* data, const unsigned long data_size, + const unsigned char* key, const unsigned long key_size, + unsigned char* encrypted, const unsigned long encrypted_size, + const bool pads) { + const Error e = detail::check_encrypt_cond(data_size, key_size, encrypted_size, pads); + if (e != kErrorOk) { + return e; + } + + const detail::RoundKeys rkeys = detail::expand_key(key, static_cast(key_size)); + + const unsigned long bc = data_size / detail::kStateSize; + for (unsigned long i = 0; i < bc; ++i) { + detail::encrypt_state(rkeys, data + (i * detail::kStateSize), + encrypted + (i * detail::kStateSize)); + } + + if (pads) { + const int rem = data_size % detail::kStateSize; + const char pad_v = detail::kStateSize - rem; + + std::vector ib(detail::kStateSize, pad_v), ob(detail::kStateSize); + memcpy(&ib[0], data + data_size - rem, rem); + + detail::encrypt_state(rkeys, &ib[0], &ob[0]); + memcpy(encrypted + (data_size - rem), &ob[0], detail::kStateSize); + } + + return kErrorOk; +} + +/** + * Decrypts data with ECB mode. + * @param [in] data Data bytes. + * @param [in] data_size Data size. + * @param [in] key Key bytes. + * @param [in] key_size Key size. + * @param [out] decrypted Decrypted data buffer. + * @param [in] decrypted_size Decrypted data buffer size. + * @param [out] padded_size If this value is NULL, this function does not remove padding. + * If this value is not NULL, this function removes padding by PKCS + * and returns padded size using padded_size. + * @since 1.0.0 + */ +inline Error decrypt_ecb(const unsigned char* data, const unsigned long data_size, + const unsigned char* key, const unsigned long key_size, + unsigned char* decrypted, const unsigned long decrypted_size, + unsigned long* padded_size) { + const Error e = detail::check_decrypt_cond(data_size, key_size, decrypted_size, padded_size); + if (e != kErrorOk) { + return e; + } + + const detail::RoundKeys rkeys = detail::expand_key(key, static_cast(key_size)); + + const unsigned long bc = data_size / detail::kStateSize - 1; + for (unsigned long i = 0; i < bc; ++i) { + detail::decrypt_state(rkeys, data + (i * detail::kStateSize), + decrypted + (i * detail::kStateSize)); + } + + unsigned char last[detail::kStateSize] = {}; + detail::decrypt_state(rkeys, data + (bc * detail::kStateSize), last); + + if (padded_size) { + *padded_size = last[detail::kStateSize - 1]; + const unsigned long cs = detail::kStateSize - *padded_size; + + if (!detail::check_padding(*padded_size, last)) { + return kErrorInvalidKey; + } else if (decrypted_size >= (bc * detail::kStateSize) + cs) { + memcpy(decrypted + (bc * detail::kStateSize), last, cs); + } else { + return kErrorInvalidBufferSize; + } + } else { + memcpy(decrypted + (bc * detail::kStateSize), last, sizeof(last)); + } + + return kErrorOk; +} + +/** @} */ + +/** @defgroup CBC CBC + * CBC mode functions + * @{ */ + +/** + * Encrypt data with CBC mode. + * @param [in] data Data. + * @param [in] data_size Data size. + * If the pads is false, data size must be multiple of 16. + * @param [in] key key bytes. The key length must be 16 (128-bit), 24 (192-bit) or 32 (256-bit). + * @param [in] key_size key size. + * @param [in] iv Initialize vector. + * @param [out] encrypted Encrypted data buffer. + * @param [in] encrypted_size Encrypted data buffer size. + * @param [in] pads If this value is true, encrypted data is padded by PKCS. + * Encrypted data size must be multiple of 16. + * If the pads is true, encrypted data is padded with PKCS. + * So the data is multiple of 16, encrypted data size needs additonal 16 bytes. + * @since 1.0.0 + */ +inline Error encrypt_cbc(const unsigned char* data, const unsigned long data_size, + const unsigned char* key, const unsigned long key_size, + const unsigned char iv[16], unsigned char* encrypted, + const unsigned long encrypted_size, const bool pads) { + const Error e = detail::check_encrypt_cond(data_size, key_size, encrypted_size, pads); + if (e != kErrorOk) { + return e; + } + + const detail::RoundKeys rkeys = detail::expand_key(key, static_cast(key_size)); + + unsigned char s[detail::kStateSize] = {}; // encrypting data + + // calculate padding value + const bool ge16 = (data_size >= detail::kStateSize); + const int rem = data_size % detail::kStateSize; + const unsigned char pad_v = detail::kStateSize - rem; + + // encrypt 1st state + if (ge16) { + memcpy(s, data, detail::kStateSize); + } else { + memset(s, pad_v, detail::kStateSize); + memcpy(s, data, data_size); + } + if (iv) { + detail::xor_data(s, iv); + } + detail::encrypt_state(rkeys, s, encrypted); + + // encrypt mid + const unsigned long bc = data_size / detail::kStateSize; + for (unsigned long i = 1; i < bc; ++i) { + const long offset = i * detail::kStateSize; + memcpy(s, data + offset, detail::kStateSize); + detail::xor_data(s, encrypted + offset - detail::kStateSize); + + detail::encrypt_state(rkeys, s, encrypted + offset); + } + + // enctypt last + if (pads && ge16) { + std::vector ib(detail::kStateSize, pad_v), ob(detail::kStateSize); + memcpy(&ib[0], data + data_size - rem, rem); + + detail::xor_data(&ib[0], encrypted + (bc - 1) * detail::kStateSize); + + detail::encrypt_state(rkeys, &ib[0], &ob[0]); + memcpy(encrypted + (data_size - rem), &ob[0], detail::kStateSize); + } + + return kErrorOk; +} + +/** + * Decrypt data with CBC mode. + * @param [in] data Data bytes. + * @param [in] data_size Data size. + * @param [in] key Key bytes. + * @param [in] key_size Key size. + * @param [in] iv Initialize vector. + * @param [out] decrypted Decrypted data buffer. + * @param [in] decrypted_size Decrypted data buffer size. + * @param [out] padded_size If this value is NULL, this function does not remove padding. + * If this value is not NULL, this function removes padding by PKCS + * and returns padded size using padded_size. + * @since 1.0.0 + */ +inline Error decrypt_cbc(const unsigned char* data, const unsigned long data_size, + const unsigned char* key, const unsigned long key_size, + const unsigned char iv[16], unsigned char* decrypted, + const unsigned long decrypted_size, unsigned long* padded_size) { + const Error e = detail::check_decrypt_cond(data_size, key_size, decrypted_size, padded_size); + if (e != kErrorOk) { + return e; + } + + const detail::RoundKeys rkeys = detail::expand_key(key, static_cast(key_size)); + + // decrypt 1st state + detail::decrypt_state(rkeys, data, decrypted); + if (iv) { + detail::xor_data(decrypted, iv); + } + + // decrypt mid + const unsigned long bc = data_size / detail::kStateSize - 1; + for (unsigned long i = 1; i < bc; ++i) { + const long offset = i * detail::kStateSize; + detail::decrypt_state(rkeys, data + offset, decrypted + offset); + detail::xor_data(decrypted + offset, data + offset - detail::kStateSize); + } + + // decrypt last + unsigned char last[detail::kStateSize] = {}; + if (data_size > detail::kStateSize) { + detail::decrypt_state(rkeys, data + (bc * detail::kStateSize), last); + detail::xor_data(last, data + (bc * detail::kStateSize - detail::kStateSize)); + } else { + memcpy(last, decrypted, data_size); + memset(decrypted, 0, decrypted_size); + } + + if (padded_size) { + *padded_size = last[detail::kStateSize - 1]; + const unsigned long cs = detail::kStateSize - *padded_size; + + if (!detail::check_padding(*padded_size, last)) { + return kErrorInvalidKey; + } else if (decrypted_size >= (bc * detail::kStateSize) + cs) { + memcpy(decrypted + (bc * detail::kStateSize), last, cs); + } else { + return kErrorInvalidBufferSize; + } + } else { + memcpy(decrypted + (bc * detail::kStateSize), last, sizeof(last)); + } + + return kErrorOk; +} + +/** @} */ + +/** @defgroup GCM GCM + * GCM mode functions + * @{ */ + +/** + * Encrypts data with GCM mode and gets an authentication tag. + * + * You can specify iv size and tag size. + * But usually you should use the other overloaded function whose iv and tag size is fixed. + * + * @returns kErrorOk + * @returns kErrorInvalidKeySize + * @returns kErrorInvalidIvSize + * @returns kErrorInvalidTagSize + */ +inline Error encrypt_gcm(unsigned char* data, const std::size_t data_size, + const unsigned char* aadata, const std::size_t aadata_size, + const unsigned char* key, const std::size_t key_size, + const unsigned char* iv, const std::size_t iv_size, unsigned char* tag, + const std::size_t tag_size) { + const Error err = detail::check_gcm_cond(key_size, iv_size, tag_size); + if (err != kErrorOk) { + return err; + } + + detail::gcm::crypt_gcm(data, data_size, key, key_size, iv, iv_size, data); + detail::gcm::calc_gcm_tag(data, data_size, aadata, aadata_size, key, key_size, iv, iv_size, tag, + tag_size); + + return kErrorOk; +} + +/** + * Encrypts data with GCM mode and gets an authentication tag. + * + * @param [in,out] data Input data and output buffer. + * This buffer is replaced with encrypted data. + * @param [in] data_size data size + * @param [in] aadata Additional Authenticated data + * @param [in] aadata_size aadata size + * @param [in] key Cipher key + * @param [in] key_size Cipher key size. This value must be 16 (128-bit), 24 (192-bit), or 32 + * (256-bit). + * @param [in] iv Initialization vector + * @param [out] tag Calculated authentication tag data + * + * @returns kErrorOk + * @returns kErrorInvalidKeySize + */ +inline Error encrypt_gcm(unsigned char* data, const std::size_t data_size, + const unsigned char* aadata, const std::size_t aadata_size, + const unsigned char* key, const std::size_t key_size, + const unsigned char (*iv)[12], unsigned char (*tag)[16]) { + return encrypt_gcm(data, data_size, aadata, aadata_size, key, key_size, *iv, 12, *tag, 16); +} + +/** + * Decrypts data with GCM mode and checks an authentication tag. + * + * You can specify iv size and tag size. + * But usually you should use the other overloaded function whose iv and tag size is fixed. + * + * @returns kErrorOk + * @returns kErrorInvalidKeySize + * @returns kErrorInvalidIvSize + * @returns kErrorInvalidTagSize + * @returns kErrorInvalidTag + */ +inline Error decrypt_gcm(unsigned char* data, const std::size_t data_size, + const unsigned char* aadata, const std::size_t aadata_size, + const unsigned char* key, const std::size_t key_size, + const unsigned char* iv, const std::size_t iv_size, + const unsigned char* tag, const std::size_t tag_size) { + const Error err = detail::check_gcm_cond(key_size, iv_size, tag_size); + if (err != kErrorOk) { + return err; + } + + unsigned char* C = data; + const auto C_size = data_size; + unsigned char tagd[16] = {}; + detail::gcm::calc_gcm_tag(C, C_size, aadata, aadata_size, key, key_size, iv, iv_size, tagd, 16); + + if (memcmp(tag, tagd, tag_size) != 0) { + return kErrorInvalidTag; + } else { + detail::gcm::crypt_gcm(C, C_size, key, key_size, iv, iv_size, C); + + return kErrorOk; + } +} + +/** + * Decrypts data with GCM mode and checks an authentication tag. + * + * @param [in,out] data Input data and output buffer. + * This buffer is replaced with decrypted data. + * @param [in] data_size data size + * @param [in] aadata Additional Authenticated data + * @param [in] aadata_size aadata size + * @param [in] key Cipher key + * @param [in] key_size Cipher key size. This value must be 16 (128-bit), 24 (192-bit), or 32 + * (256-bit). + * @param [in] iv Initialization vector + * @param [in] tag Authentication tag data + * + * @returns kErrorOk + * @returns kErrorInvalidKeySize + * @returns kErrorInvalidTag + */ +inline Error decrypt_gcm(unsigned char* data, const std::size_t data_size, + const unsigned char* aadata, const std::size_t aadata_size, + const unsigned char* key, const std::size_t key_size, + const unsigned char (*iv)[12], const unsigned char (*tag)[16]) { + return decrypt_gcm(data, data_size, aadata, aadata_size, key, key_size, *iv, 12, *tag, 16); +} + +/** @} */ + +/** @defgroup CTR CTR + * CTR mode function + * @{ */ + +/** + * Encrypts or decrypt data in-place with CTR mode. + * + * @param [in,out] data Input data and output buffer. + * This buffer is replaced with encrypted / decrypted data. + * @param [in] data_size Data size. + * @param [in] key Cipher key + * @param [in] key_size Cipher key size. This value must be 16 (128-bit), 24 (192-bit), or 32 + * (256-bit). + * @param [in] nonce Nonce of the counter initialization. + * + * @returns kErrorOk + * @returns kErrorInvalidKeySize + * @since 1.0.0 + */ +inline Error crypt_ctr(unsigned char* data, const std::size_t data_size, const unsigned char* key, + const std::size_t key_size, const unsigned char (*nonce)[16]) { + if (!detail::is_valid_key_size(key_size)) + return kErrorInvalidKeySize; + const detail::RoundKeys rkeys = detail::expand_key(key, static_cast(key_size)); + + unsigned long pos = 0; + unsigned long blkpos = detail::kStateSize; + unsigned char blk[detail::kStateSize] = {}; + unsigned char counter[detail::kStateSize] = {}; + memcpy(counter, nonce, 16); + + while (pos < data_size) { + if (blkpos == detail::kStateSize) { + detail::encrypt_state(rkeys, counter, blk); + detail::incr_counter(counter); + blkpos = 0; + } + data[pos++] ^= blk[blkpos++]; + } + + return kErrorOk; +} + +/** @} */ + +} // namespace aes diff --git a/gpu/shadps4/common/alignment.h b/gpu/shadps4/common/alignment.h new file mode 100644 index 0000000..22c3390 --- /dev/null +++ b/gpu/shadps4/common/alignment.h @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2014 Jannik Vogel +// SPDX-License-Identifier: CC0-1.0 + +#pragma once + +#include +#include + +namespace Common { + +template +[[nodiscard]] constexpr T AlignUp(T value, std::size_t size) { + static_assert(std::is_unsigned_v, "T must be an unsigned value."); + auto mod{static_cast(value % size)}; + value -= mod; + return static_cast(mod == T{0} ? value : value + size); +} + +template +[[nodiscard]] constexpr T AlignDown(T value, std::size_t size) { + static_assert(std::is_unsigned_v, "T must be an unsigned value."); + return static_cast(value - value % size); +} + +template +[[nodiscard]] constexpr T AlignUpPow2(T value, T size) { + return static_cast(value + (size - 1) & ~(size - 1)); +} + +template +[[nodiscard]] constexpr T AlignDownPow2(T value, T size) { + return static_cast(value & ~(size - 1)); +} + +template + requires std::is_integral_v +[[nodiscard]] constexpr bool IsAligned(T value, std::size_t alignment) { + return (value & (alignment - 1)) == 0; +} + +template + requires std::is_integral_v +[[nodiscard]] constexpr bool Is16KBAligned(T value) { + return (value & 0x3FFF) == 0; +} + +template + requires std::is_integral_v +[[nodiscard]] constexpr bool Is64KBAligned(T value) { + return (value & 0xFFFF) == 0; +} + +template + requires std::is_integral_v +[[nodiscard]] constexpr bool Is2MBAligned(T value) { + return (value & 0x1FFFFF) == 0; +} + +} // namespace Common diff --git a/gpu/shadps4/common/arch.h b/gpu/shadps4/common/arch.h new file mode 100644 index 0000000..b22366c --- /dev/null +++ b/gpu/shadps4/common/arch.h @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#if defined(__x86_64__) || defined(_M_X64) +#define ARCH_X86_64 1 +#elif defined(__aarch64__) || defined(_M_ARM64) +#define ARCH_ARM64 1 +#endif diff --git a/gpu/shadps4/common/assert.cpp b/gpu/shadps4/common/assert.cpp new file mode 100644 index 0000000..a2b941a --- /dev/null +++ b/gpu/shadps4/common/assert.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/arch.h" +#include "common/assert.h" +#include "core/signals.h" +#include "emulator.h" + +#if defined(ARCH_X86_64) +#define Crash() __asm__ __volatile__("int $3") +#elif defined(ARCH_ARM64) +#define Crash() __asm__ __volatile__("brk 0") +#else +#error "Missing Crash() implementation for target CPU architecture." +#endif + +void assert_fail_impl() { + Core::Signals::Instance()->RemoveHandlers(); + Common::Singleton::Instance()->Shutdown(); + Crash(); +} + +[[noreturn]] void unreachable_impl() { + assert_fail_impl(); + throw std::runtime_error("Unreachable code"); +} + +void assert_fail_debug_msg(const char* msg) { + LOG_CRITICAL(Debug, "Assertion Failed!\n{}", msg); + assert_fail_impl(); +} diff --git a/gpu/shadps4/common/assert.h b/gpu/shadps4/common/assert.h new file mode 100644 index 0000000..63bd125 --- /dev/null +++ b/gpu/shadps4/common/assert.h @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/logging/log.h" + +// Sometimes we want to try to continue even after hitting an assert. +// However touching this file yields a global recompilation as this header is included almost +// everywhere. So let's just move the handling of the failed assert to a single cpp file. + +void assert_fail_impl(); +[[noreturn]] void unreachable_impl(); + +#ifdef _MSC_VER +#define SHAD_NO_INLINE __declspec(noinline) +#else +#define SHAD_NO_INLINE __attribute__((noinline)) +#endif + +#define ASSERT(_a_) \ + do { \ + if (!(_a_)) [[unlikely]] { \ + LOG_CRITICAL(Debug, "Assertion Failed!"); \ + assert_fail_impl(); \ + } \ + } while (false) + +#define ASSERT_MSG(_a_, ...) \ + do { \ + if (!(_a_)) [[unlikely]] { \ + LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \ + assert_fail_impl(); \ + } \ + } while (false) + +#define UNREACHABLE() \ + do { \ + LOG_CRITICAL(Debug, "Unreachable code!"); \ + unreachable_impl(); \ + } while (0) + +#define UNREACHABLE_MSG(...) \ + do { \ + LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); \ + unreachable_impl(); \ + } while (0) + +#ifdef _DEBUG +#define DEBUG_ASSERT(_a_) ASSERT(_a_) +#define DEBUG_ASSERT_MSG(_a_, ...) ASSERT_MSG(_a_, __VA_ARGS__) +#else // not debug +#define DEBUG_ASSERT(_a_) \ + do { \ + } while (0) +#define DEBUG_ASSERT_MSG(_a_, _desc_, ...) \ + do { \ + } while (0) +#endif + +#define UNIMPLEMENTED() ASSERT_MSG(false, "Unimplemented code!") +#define UNIMPLEMENTED_MSG(...) ASSERT_MSG(false, __VA_ARGS__) + +#define UNIMPLEMENTED_IF(cond) ASSERT_MSG(!(cond), "Unimplemented code!") +#define UNIMPLEMENTED_IF_MSG(cond, ...) ASSERT_MSG(!(cond), __VA_ARGS__) + +// If the assert is ignored, execute _b_ +#define ASSERT_OR_EXECUTE(_a_, _b_) \ + do { \ + ASSERT(_a_); \ + if (!(_a_)) [[unlikely]] { \ + _b_ \ + } \ + } while (0) + +// If the assert is ignored, execute _b_ +#define ASSERT_OR_EXECUTE_MSG(_a_, _b_, ...) \ + do { \ + ASSERT_MSG(_a_, __VA_ARGS__); \ + if (!(_a_)) [[unlikely]] { \ + _b_ \ + } \ + } while (0) diff --git a/gpu/shadps4/common/bit_array.h b/gpu/shadps4/common/bit_array.h new file mode 100644 index 0000000..e2d111a --- /dev/null +++ b/gpu/shadps4/common/bit_array.h @@ -0,0 +1,432 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" + +#ifdef __AVX2__ +#define BIT_ARRAY_USE_AVX +#include +#endif + +namespace Common { + +template +class BitArray { + static_assert(N % 64 == 0, "BitArray size must be a multiple of 64 bits."); + + static constexpr size_t BITS_PER_WORD = 64; + static constexpr size_t WORD_COUNT = N / BITS_PER_WORD; + static constexpr size_t WORDS_PER_AVX = 4; + static constexpr size_t AVX_WORD_COUNT = WORD_COUNT / WORDS_PER_AVX; + +public: + using Range = std::pair; + + class Iterator { + public: + explicit Iterator(const BitArray& bit_array_, u64 start) : bit_array(bit_array_) { + range = bit_array.FirstRangeFrom(start); + } + + Iterator& operator++() { + range = bit_array.FirstRangeFrom(range.second); + return *this; + } + + bool operator==(const Iterator& other) const { + return range == other.range; + } + + bool operator!=(const Iterator& other) const { + return !(*this == other); + } + + const Range& operator*() const { + return range; + } + + const Range* operator->() const { + return ⦥ + } + + private: + const BitArray& bit_array; + Range range; + }; + + using const_iterator = Iterator; + using iterator_category = std::forward_iterator_tag; + using value_type = Range; + using difference_type = std::ptrdiff_t; + using pointer = const Range*; + using reference = const Range&; + + BitArray() = default; + BitArray(const BitArray& other) = default; + BitArray& operator=(const BitArray& other) = default; + BitArray(BitArray&& other) noexcept = default; + BitArray& operator=(BitArray&& other) noexcept = default; + ~BitArray() = default; + + BitArray(const BitArray& other, size_t start, size_t end) { + if (start >= end || end > N) { + return; + } + const size_t first_word = start / BITS_PER_WORD; + const size_t last_word = (end - 1) / BITS_PER_WORD; + const size_t start_bit = start % BITS_PER_WORD; + const size_t end_bit = (end - 1) % BITS_PER_WORD; + const u64 start_mask = ~((1ULL << start_bit) - 1); + const u64 end_mask = end_bit == BITS_PER_WORD - 1 ? ~0ULL : (1ULL << (end_bit + 1)) - 1; + if (first_word == last_word) { + data[first_word] = other.data[first_word] & (start_mask & end_mask); + } else { + data[first_word] = other.data[first_word] & start_mask; + size_t i = first_word + 1; +#ifdef BIT_ARRAY_USE_AVX + for (; i + WORDS_PER_AVX <= last_word; i += WORDS_PER_AVX) { + const __m256i current = + _mm256_loadu_si256(reinterpret_cast(&other.data[i])); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&data[i]), current); + } +#endif + for (; i < last_word; ++i) { + data[i] = other.data[i]; + } + data[last_word] = other.data[last_word] & end_mask; + } + } + + BitArray(const BitArray& other, const Range& range) + : BitArray(other, range.first, range.second) {} + + const_iterator begin() const { + return Iterator(*this, 0); + } + const_iterator end() const { + return Iterator(*this, N); + } + + inline constexpr void Set(size_t idx) { + data[idx / BITS_PER_WORD] |= (1ULL << (idx % BITS_PER_WORD)); + } + + inline constexpr void Unset(size_t idx) { + data[idx / BITS_PER_WORD] &= ~(1ULL << (idx % BITS_PER_WORD)); + } + + inline constexpr bool Get(size_t idx) const { + return (data[idx / BITS_PER_WORD] & (1ULL << (idx % BITS_PER_WORD))) != 0; + } + + inline void SetRange(size_t start, size_t end) { + if (start >= end || end > N) { + return; + } + const size_t first_word = start / BITS_PER_WORD; + const size_t last_word = (end - 1) / BITS_PER_WORD; + const size_t start_bit = start % BITS_PER_WORD; + const size_t end_bit = (end - 1) % BITS_PER_WORD; + const u64 start_mask = ~((1ULL << start_bit) - 1); + const u64 end_mask = end_bit == BITS_PER_WORD - 1 ? ~0ULL : (1ULL << (end_bit + 1)) - 1; + if (first_word == last_word) { + data[first_word] |= start_mask & end_mask; + } else { + data[first_word] |= start_mask; + size_t i = first_word + 1; +#ifdef BIT_ARRAY_USE_AVX + const __m256i value = _mm256_set1_epi64x(-1); + for (; i + WORDS_PER_AVX <= last_word; i += WORDS_PER_AVX) { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&data[i]), value); + } +#endif + for (; i < last_word; ++i) { + data[i] = ~0ULL; + } + data[last_word] |= end_mask; + } + } + + inline void UnsetRange(size_t start, size_t end) { + if (start >= end || end > N) { + return; + } + size_t first_word = start / BITS_PER_WORD; + const size_t last_word = (end - 1) / BITS_PER_WORD; + const size_t start_bit = start % BITS_PER_WORD; + const size_t end_bit = (end - 1) % BITS_PER_WORD; + const u64 start_mask = (1ULL << start_bit) - 1; + const u64 end_mask = end_bit == BITS_PER_WORD - 1 ? 0ULL : ~((1ULL << (end_bit + 1)) - 1); + if (first_word == last_word) { + data[first_word] &= start_mask | end_mask; + } else { + data[first_word] &= start_mask; + size_t i = first_word + 1; +#ifdef BIT_ARRAY_USE_AVX + const __m256i value = _mm256_setzero_si256(); + for (; i + WORDS_PER_AVX <= last_word; i += WORDS_PER_AVX) { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&data[i]), value); + } +#endif + for (; i < last_word; ++i) { + data[i] = 0ULL; + } + data[last_word] &= end_mask; + } + } + + inline constexpr void SetRange(const Range& range) { + SetRange(range.first, range.second); + } + + inline constexpr void UnsetRange(const Range& range) { + UnsetRange(range.first, range.second); + } + + inline constexpr void Clear() { + data.fill(0); + } + + inline constexpr void Fill() { + data.fill(~0ULL); + } + + inline constexpr bool None() const { + u64 result = 0; + for (const auto& word : data) { + result |= word; + } + return result == 0; + } + + inline constexpr bool Any() const { + return !None(); + } + + inline constexpr bool AnyInRange(size_t start, size_t end) const { + const size_t first_word = start / BITS_PER_WORD; + const size_t last_word = (end - 1) / BITS_PER_WORD; + const size_t start_bit = start % BITS_PER_WORD; + const size_t end_bit = (end - 1) % BITS_PER_WORD; + const u64 start_mask = ~((1ULL << start_bit) - 1); + const u64 end_mask = end_bit == BITS_PER_WORD - 1 ? ~0ULL : (1ULL << (end_bit + 1)) - 1; + if (first_word == last_word) { + return data[first_word] & (start_mask & end_mask); + } else { + if (data[first_word] & start_mask) { + return true; + } + size_t i = first_word + 1; + for (; i < last_word; ++i) { + if (data[i]) { + return true; + } + } + if (data[last_word] & end_mask) { + return true; + } + } + return false; + } + + Range FirstRangeFrom(size_t start) const { + if (start >= N) { + return {N, N}; + } + const auto find_end_bit = [&](size_t word) { +#ifdef BIT_ARRAY_USE_AVX + const __m256i all_one = _mm256_set1_epi64x(-1); + for (; word + WORDS_PER_AVX <= WORD_COUNT; word += WORDS_PER_AVX) { + const __m256i current = + _mm256_loadu_si256(reinterpret_cast(&data[word])); + const __m256i cmp = _mm256_cmpeq_epi64(current, all_one); + if (_mm256_movemask_epi8(cmp) != 0xFFFFFFFF) { + break; + } + } +#endif + for (; word < WORD_COUNT; ++word) { + if (data[word] != ~0ULL) { + return (word * BITS_PER_WORD) + std::countr_one(data[word]); + } + } + return N; + }; + + const auto word_bits = [&](size_t index, u64 word) { + const int empty_bits = std::countr_zero(word); + const int ones_count = std::countr_one(word >> empty_bits); + const size_t start_bit = index * BITS_PER_WORD + empty_bits; + if (ones_count + empty_bits < BITS_PER_WORD) { + return Range{start_bit, start_bit + ones_count}; + } + return Range{start_bit, find_end_bit(index + 1)}; + }; + + const size_t start_word = start / BITS_PER_WORD; + const size_t start_bit = start % BITS_PER_WORD; + const u64 masked_first = data[start_word] & (~((1ULL << start_bit) - 1)); + if (masked_first) { + return word_bits(start_word, masked_first); + } + + size_t word = start_word + 1; +#ifdef BIT_ARRAY_USE_AVX + for (; word + WORDS_PER_AVX <= WORD_COUNT; word += WORDS_PER_AVX) { + const __m256i current = + _mm256_loadu_si256(reinterpret_cast(&data[word])); + if (!_mm256_testz_si256(current, current)) { + break; + } + } +#endif + for (; word < WORD_COUNT; ++word) { + if (data[word] != 0) { + return word_bits(word, data[word]); + } + } + return {N, N}; + } + + inline constexpr Range FirstRange() const { + return FirstRangeFrom(0); + } + + Range LastRangeFrom(size_t end) const { + if (end == 0) { + return {0, 0}; + } + if (end > N) { + end = N; + } + const auto find_start_bit = [&](size_t word) { +#ifdef BIT_ARRAY_USE_AVX + const __m256i all_zero = _mm256_setzero_si256(); + for (; word >= WORDS_PER_AVX; word -= WORDS_PER_AVX) { + const __m256i current = _mm256_loadu_si256( + reinterpret_cast(&data[word - WORDS_PER_AVX])); + const __m256i cmp = _mm256_cmpeq_epi64(current, all_zero); + if (_mm256_movemask_epi8(cmp) != 0xFFFFFFFF) { + break; + } + } +#endif + for (; word > 0; --word) { + if (data[word - 1] != ~0ULL) { + return word * BITS_PER_WORD - std::countl_one(data[word - 1]); + } + } + return size_t(0); + }; + const auto word_bits = [&](size_t index, u64 word) { + const int empty_bits = std::countl_zero(word); + const int ones_count = std::countl_one(word << empty_bits); + const size_t end_bit = index * BITS_PER_WORD - empty_bits; + if (empty_bits + ones_count < BITS_PER_WORD) { + return Range{end_bit - ones_count, end_bit}; + } + return Range{find_start_bit(index - 1), end_bit}; + }; + const size_t end_word = ((end - 1) / BITS_PER_WORD) + 1; + const size_t end_bit = (end - 1) % BITS_PER_WORD; + u64 masked_last = data[end_word - 1]; + if (end_bit < BITS_PER_WORD - 1) { + masked_last &= (1ULL << (end_bit + 1)) - 1; + } + if (masked_last) { + return word_bits(end_word, masked_last); + } + size_t word = end_word - 1; +#ifdef BIT_ARRAY_USE_AVX + for (; word >= WORDS_PER_AVX; word -= WORDS_PER_AVX) { + const __m256i current = + _mm256_loadu_si256(reinterpret_cast(&data[word - WORDS_PER_AVX])); + if (!_mm256_testz_si256(current, current)) { + break; + } + } +#endif + for (; word > 0; --word) { + if (data[word - 1] != 0) { + return word_bits(word, data[word - 1]); + } + } + return {0, 0}; + } + + inline constexpr Range LastRange() const { + return LastRangeFrom(N); + } + + inline constexpr size_t Size() const { + return N; + } + + inline constexpr BitArray& operator|=(const BitArray& other) { + for (size_t i = 0; i < WORD_COUNT; ++i) { + data[i] |= other.data[i]; + } + return *this; + } + + inline constexpr BitArray& operator&=(const BitArray& other) { + for (size_t i = 0; i < WORD_COUNT; ++i) { + data[i] &= other.data[i]; + } + return *this; + } + + inline constexpr BitArray& operator^=(const BitArray& other) { + for (size_t i = 0; i < WORD_COUNT; ++i) { + data[i] ^= other.data[i]; + } + return *this; + } + + inline constexpr BitArray operator|(const BitArray& other) const { + BitArray result = *this; + result |= other; + return result; + } + + inline constexpr BitArray operator&(const BitArray& other) const { + BitArray result = *this; + result &= other; + return result; + } + + inline constexpr BitArray operator^(const BitArray& other) const { + BitArray result = *this; + result ^= other; + return result; + } + + inline constexpr BitArray operator~() const { + BitArray result = *this; + for (size_t i = 0; i < WORD_COUNT; ++i) { + result.data[i] = ~result.data[i]; + } + return result; + } + + inline constexpr bool operator==(const BitArray& other) const { + u64 result = 0; + for (size_t i = 0; i < WORD_COUNT; ++i) { + result |= data[i] ^ other.data[i]; + } + return result == 0; + } + + inline constexpr bool operator!=(const BitArray& other) const { + return !(*this == other); + } + +private: + std::array data{}; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/bit_field.h b/gpu/shadps4/common/bit_field.h new file mode 100644 index 0000000..bc8a276 --- /dev/null +++ b/gpu/shadps4/common/bit_field.h @@ -0,0 +1,167 @@ +// SPDX-FileCopyrightText: 2014 Tony Wasserka +// SPDX-FileCopyrightText: 2014 Dolphin Emulator Project +// SPDX-License-Identifier: BSD-3-Clause AND GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +/* + * Abstract bitfield class + * + * Allows endianness-independent access to individual bitfields within some raw + * integer value. The assembly generated by this class is identical to the + * usage of raw bitfields, so it's a perfectly fine replacement. + * + * For BitField, X is the distance of the bitfield to the LSB of the + * raw value, Y is the length in bits of the bitfield. Z is an integer type + * which determines the sign of the bitfield. Z must have the same size as the + * raw integer. + * + * + * General usage: + * + * Create a new union with the raw integer value as a member. + * Then for each bitfield you want to expose, add a BitField member + * in the union. The template parameters are the bit offset and the number + * of desired bits. + * + * Changes in the bitfield members will then get reflected in the raw integer + * value and vice-versa. + * + * + * Sample usage: + * + * union SomeRegister + * { + * u32 hex; + * + * BitField<0,7,u32> first_seven_bits; // unsigned + * BitField<7,8,u32> next_eight_bits; // unsigned + * BitField<3,15,s32> some_signed_fields; // signed + * }; + * + * This is equivalent to the little-endian specific code: + * + * union SomeRegister + * { + * u32 hex; + * + * struct + * { + * u32 first_seven_bits : 7; + * u32 next_eight_bits : 8; + * }; + * struct + * { + * u32 : 3; // padding + * s32 some_signed_fields : 15; + * }; + * }; + * + * + * Caveats: + * + * 1) + * BitField provides automatic casting from and to the storage type where + * appropriate. However, when using non-typesafe functions like printf, an + * explicit cast must be performed on the BitField object to make sure it gets + * passed correctly, e.g.: + * printf("Value: %d", (s32)some_register.some_signed_fields); + * + * 2) + * Not really a caveat, but potentially irritating: This class is used in some + * packed structures that do not guarantee proper alignment. Therefore we have + * to use #pragma pack here not to pack the members of the class, but instead + * to break GCC's assumption that the members of the class are aligned on + * sizeof(StorageType). + */ +#pragma pack(1) +template +struct BitField { + + using Type = T; + + // UnderlyingType is T for non-enum types and the underlying type of T if + // T is an enumeration. Note that T is wrapped within an enable_if in the + // former case to workaround compile errors which arise when using + // std::underlying_type::type directly. + using UnderlyingType = typename std::conditional_t, std::underlying_type, + std::enable_if>::type; + + // We store the value as the unsigned type to avoid undefined behaviour on value shifting + using StorageType = std::make_unsigned_t; + + /// Constants to allow limited introspection of fields if needed + static constexpr std::size_t position = Position; + static constexpr std::size_t bits = Bits; + static constexpr StorageType mask = (((StorageType)~0) >> (8 * sizeof(T) - bits)) << position; + + /** + * Formats a value by masking and shifting it according to the field parameters. A value + * containing several bitfields can be assembled by formatting each of their values and ORing + * the results together. + */ + [[nodiscard]] static constexpr StorageType FormatValue(const T& value) { + return (static_cast(value) << position) & mask; + } + + /** + * Extracts a value from the passed storage. In most situations prefer use the member functions + * (such as Value() or operator T), but this can be used to extract a value from a bitfield + * union in a constexpr context. + */ + [[nodiscard]] static constexpr T ExtractValue(const StorageType& storage) { + if constexpr (std::numeric_limits::is_signed) { + std::size_t shift = 8 * sizeof(T) - bits; + return static_cast(static_cast(storage << (shift - position)) >> + shift); + } else { + return static_cast((storage & mask) >> position); + } + } + + // This constructor and assignment operator might be considered ambiguous: + // Would they initialize the storage or just the bitfield? + // Hence, delete them. Use the Assign method to set bitfield values! + BitField(T val) = delete; + BitField& operator=(T val) = delete; + + constexpr BitField() noexcept = default; + + constexpr BitField(const BitField&) noexcept = default; + constexpr BitField& operator=(const BitField&) noexcept = default; + + constexpr BitField(BitField&&) noexcept = default; + constexpr BitField& operator=(BitField&&) noexcept = default; + + [[nodiscard]] constexpr operator T() const { + return Value(); + } + + constexpr void Assign(const T& value) { + storage = (static_cast(storage) & ~mask) | FormatValue(value); + } + + [[nodiscard]] constexpr T Value() const { + return ExtractValue(storage); + } + + [[nodiscard]] constexpr explicit operator bool() const { + return Value() != 0; + } + +private: + StorageType storage; + + static_assert(bits + position <= 8 * sizeof(T), "Bitfield out of range"); + + // And, you know, just in case people specify something stupid like bits=position=0x80000000 + static_assert(position < 8 * sizeof(T), "Invalid position"); + static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); + static_assert(bits > 0, "Invalid number of bits"); + static_assert(std::is_trivially_copyable_v, "T must be trivially copyable in a BitField"); +}; +#pragma pack() diff --git a/gpu/shadps4/common/bounded_threadsafe_queue.h b/gpu/shadps4/common/bounded_threadsafe_queue.h new file mode 100644 index 0000000..5d15872 --- /dev/null +++ b/gpu/shadps4/common/bounded_threadsafe_queue.h @@ -0,0 +1,248 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include "common/polyfill_thread.h" + +namespace Common { + +namespace detail { +constexpr std::size_t DefaultCapacity = 0x1000; +} // namespace detail + +template +class SPSCQueue { + static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be a power of two."); + +public: + template + bool TryEmplace(Args&&... args) { + return Emplace(std::forward(args)...); + } + + template + void EmplaceWait(Args&&... args) { + Emplace(std::forward(args)...); + } + + bool TryPop(T& t) { + return Pop(t); + } + + void PopWait(T& t) { + Pop(t); + } + + void PopWait(T& t, std::stop_token stop_token) { + Pop(t, stop_token); + } + + T PopWait() { + T t; + Pop(t); + return t; + } + + T PopWait(std::stop_token stop_token) { + T t; + Pop(t, stop_token); + return t; + } + +private: + enum class PushMode { + Try, + Wait, + Count, + }; + + enum class PopMode { + Try, + Wait, + WaitWithStopToken, + Count, + }; + + template + bool Emplace(Args&&... args) { + const std::size_t write_index = m_write_index.load(std::memory_order::relaxed); + + if constexpr (Mode == PushMode::Try) { + // Check if we have free slots to write to. + if ((write_index - m_read_index.load(std::memory_order::acquire)) == Capacity) { + return false; + } + } else if constexpr (Mode == PushMode::Wait) { + // Wait until we have free slots to write to. + std::unique_lock lock{producer_cv_mutex}; + producer_cv.wait(lock, [this, write_index] { + return (write_index - m_read_index.load(std::memory_order::acquire)) < Capacity; + }); + } else { + static_assert(Mode < PushMode::Count, "Invalid PushMode."); + } + + // Determine the position to write to. + const std::size_t pos = write_index % Capacity; + + // Emplace into the queue. + new (std::addressof(m_data[pos])) T(std::forward(args)...); + + // Increment the write index. + ++m_write_index; + + // Notify the consumer that we have pushed into the queue. + std::scoped_lock lock{consumer_cv_mutex}; + consumer_cv.notify_one(); + + return true; + } + + template + bool Pop(T& t, [[maybe_unused]] std::stop_token stop_token = {}) { + const std::size_t read_index = m_read_index.load(std::memory_order::relaxed); + + if constexpr (Mode == PopMode::Try) { + // Check if the queue is empty. + if (read_index == m_write_index.load(std::memory_order::acquire)) { + return false; + } + } else if constexpr (Mode == PopMode::Wait) { + // Wait until the queue is not empty. + std::unique_lock lock{consumer_cv_mutex}; + consumer_cv.wait(lock, [this, read_index] { + return read_index != m_write_index.load(std::memory_order::acquire); + }); + } else if constexpr (Mode == PopMode::WaitWithStopToken) { + // Wait until the queue is not empty. + std::unique_lock lock{consumer_cv_mutex}; + Common::CondvarWait(consumer_cv, lock, stop_token, [this, read_index] { + return read_index != m_write_index.load(std::memory_order::acquire); + }); + if (stop_token.stop_requested()) { + return false; + } + } else { + static_assert(Mode < PopMode::Count, "Invalid PopMode."); + } + + // Determine the position to read from. + const std::size_t pos = read_index % Capacity; + + // Pop the data off the queue, moving it. + t = std::move(m_data[pos]); + + // Increment the read index. + ++m_read_index; + + // Notify the producer that we have popped off the queue. + std::scoped_lock lock{producer_cv_mutex}; + producer_cv.notify_one(); + + return true; + } + + alignas(128) std::atomic_size_t m_read_index{0}; + alignas(128) std::atomic_size_t m_write_index{0}; + + std::array m_data; + + std::condition_variable_any producer_cv; + std::mutex producer_cv_mutex; + std::condition_variable_any consumer_cv; + std::mutex consumer_cv_mutex; +}; + +template +class MPSCQueue { +public: + template + bool TryEmplace(Args&&... args) { + std::scoped_lock lock{write_mutex}; + return spsc_queue.TryEmplace(std::forward(args)...); + } + + template + void EmplaceWait(Args&&... args) { + std::scoped_lock lock{write_mutex}; + spsc_queue.EmplaceWait(std::forward(args)...); + } + + bool TryPop(T& t) { + return spsc_queue.TryPop(t); + } + + void PopWait(T& t) { + spsc_queue.PopWait(t); + } + + void PopWait(T& t, std::stop_token stop_token) { + spsc_queue.PopWait(t, stop_token); + } + + T PopWait() { + return spsc_queue.PopWait(); + } + + T PopWait(std::stop_token stop_token) { + return spsc_queue.PopWait(stop_token); + } + +private: + SPSCQueue spsc_queue; + std::mutex write_mutex; +}; + +template +class MPMCQueue { +public: + template + bool TryEmplace(Args&&... args) { + std::scoped_lock lock{write_mutex}; + return spsc_queue.TryEmplace(std::forward(args)...); + } + + template + void EmplaceWait(Args&&... args) { + std::scoped_lock lock{write_mutex}; + spsc_queue.EmplaceWait(std::forward(args)...); + } + + bool TryPop(T& t) { + std::scoped_lock lock{read_mutex}; + return spsc_queue.TryPop(t); + } + + void PopWait(T& t) { + std::scoped_lock lock{read_mutex}; + spsc_queue.PopWait(t); + } + + void PopWait(T& t, std::stop_token stop_token) { + std::scoped_lock lock{read_mutex}; + spsc_queue.PopWait(t, stop_token); + } + + T PopWait() { + std::scoped_lock lock{read_mutex}; + return spsc_queue.PopWait(); + } + + T PopWait(std::stop_token stop_token) { + std::scoped_lock lock{read_mutex}; + return spsc_queue.PopWait(stop_token); + } + +private: + SPSCQueue spsc_queue; + std::mutex write_mutex; + std::mutex read_mutex; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/concepts.h b/gpu/shadps4/common/concepts.h new file mode 100644 index 0000000..a61add7 --- /dev/null +++ b/gpu/shadps4/common/concepts.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +namespace Common { + +// Check if type satisfies the ContiguousContainer named requirement. +template +concept IsContiguousContainer = std::contiguous_iterator; + +template +concept DerivedFrom = std::derived_from; + +// TODO: Replace with std::convertible_to when libc++ implements it. +template +concept ConvertibleTo = std::is_convertible_v; + +// No equivalents in the stdlib + +template +concept IsArithmetic = std::is_arithmetic_v; + +template +concept IsIntegral = std::is_integral_v; + +} // namespace Common diff --git a/gpu/shadps4/common/cstring.h b/gpu/shadps4/common/cstring.h new file mode 100644 index 0000000..14c508f --- /dev/null +++ b/gpu/shadps4/common/cstring.h @@ -0,0 +1,173 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "assert.h" + +namespace Common { + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wtautological-undefined-compare" + +/** + * @brief A null-terminated string with a fixed maximum length + * This class is not meant to be used as a general-purpose string class + * It is meant to be used as `char[N]` where memory layout is fixed + * @tparam N Maximum length of the string + * @tparam T Type of character + */ +template +class CString { + T data[N]{}; + +public: + class Iterator; + + CString() = default; + + template + explicit CString(const CString& other) + requires(M <= N) + { + if (this == nullptr) { + return; + } + std::ranges::copy(other.begin(), other.end(), data); + } + + void FromString(const std::basic_string_view& str) { + if (this == nullptr) { + return; + } + size_t p = str.copy(data, N - 1); + data[p] = '\0'; + } + + void Zero() { + if (this == nullptr) { + return; + } + std::ranges::fill(data, 0); + } + + explicit(false) operator std::basic_string_view() const { + if (this == nullptr) { + return {}; + } + return std::basic_string_view{data}; + } + + explicit operator std::basic_string() const { + if (this == nullptr) { + return {}; + } + return std::basic_string{data}; + } + + std::basic_string to_string() const { + if (this == nullptr) { + return {}; + } + return std::basic_string{data}; + } + + std::basic_string_view to_view() const { + if (this == nullptr) { + return {}; + } + return std::basic_string_view{data}; + } + + T* begin() { + if (this == nullptr) { + return nullptr; + } + return data; + } + + const T* begin() const { + if (this == nullptr) { + return nullptr; + } + return data; + } + + T* end() { + if (this == nullptr) { + return nullptr; + } + return data + N; + } + + const T* end() const { + if (this == nullptr) { + return nullptr; + } + return data + N; + } + + constexpr std::size_t capacity() const { + return N; + } + + std::size_t size() const { + return std::char_traits::length(data); + } + + T& operator[](size_t idx) { + return data[idx]; + } + + const T& operator[](size_t idx) const { + return data[idx]; + } + + class Iterator { + T* ptr; + T* end; + + public: + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = T*; + using reference = T&; + using iterator_category = std::random_access_iterator_tag; + + Iterator() = default; + explicit Iterator(T* ptr) : ptr(ptr), end(ptr + N) {} + + Iterator& operator++() { + ++ptr; + return *this; + } + + Iterator operator++(int) { + Iterator tmp = *this; + ++ptr; + return tmp; + } + + operator T*() { + ASSERT_MSG(ptr >= end, "CString iterator out of bounds"); + return ptr; + } + }; +}; + +static_assert(sizeof(CString<13>) == sizeof(char[13])); // Ensure size still matches a simple array +static_assert(std::weakly_incrementable::Iterator>); + +template +using CWString = CString; + +template +using CU16String = CString; + +#pragma clang diagnostic pop + +} // namespace Common \ No newline at end of file diff --git a/gpu/shadps4/common/debug.h b/gpu/shadps4/common/debug.h new file mode 100644 index 0000000..92bf725 --- /dev/null +++ b/gpu/shadps4/common/debug.h @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#ifdef _MSC_VER +#define BREAKPOINT __debugbreak +#elif defined(__GNUC__) +#define BREAKPOINT __builtin_trap +#else +#error What the fuck is this compiler +#endif + +#include + +static inline bool IsProfilerConnected() { +#if TRACY_ENABLE + return tracy::GetProfiler().IsConnected(); +#else + return false; +#endif +} + +#define TRACY_GPU_ENABLED 0 + +#define CUSTOM_LOCK(type, varname) \ + tracy::LockableCtx varname { \ + []() -> const tracy::SourceLocationData* { \ + static constexpr tracy::SourceLocationData srcloc{nullptr, #type " " #varname, \ + TracyFile, TracyLine, 0}; \ + return &srcloc; \ + }() \ + } + +#define TRACK_ALLOC(ptr, size, pool) TracyAllocN(std::bit_cast(ptr), (size), (pool)) +#define TRACK_FREE(ptr, pool) TracyFreeN(std::bit_cast(ptr), (pool)) + +enum MarkersPalette : int { + EmulatorMarkerColor = 0x264653, + RendererMarkerColor = 0x2a9d8f, + HleMarkerColor = 0xe9c46a, + GpuMarkerColor = 0xf4a261, + Reserved1 = 0xe76f51, +}; + +#define EMULATOR_TRACE ZoneScopedC(EmulatorMarkerColor) +#define RENDERER_TRACE ZoneScopedC(RendererMarkerColor) +#define HLE_TRACE ZoneScopedC(HleMarkerColor) + +#define TRACE_HINT(str) ZoneText(str.data(), str.size()) + +#define TRACE_WARN(msg) \ + [](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::DarkOrange); }(msg); +#define TRACE_ERROR(msg) \ + [](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::Red); }(msg) +#define TRACE_CRIT(msg) \ + [](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::HotPink); }(msg) + +#define GPU_SCOPE_LOCATION(name, color) \ + tracy::SourceLocationData{name, TracyFunction, TracyFile, (uint32_t)TracyLine, color}; + +#define MUTEX_LOCATION(name) \ + tracy::SourceLocationData{nullptr, name, TracyFile, (uint32_t)TracyLine, 0}; + +#define FRAME_END FrameMark + +#ifdef TRACY_FIBERS +#define FIBER_ENTER(name) TracyFiberEnter(name) +#define FIBER_EXIT TracyFiberLeave +#else +#define FIBER_ENTER(name) +#define FIBER_EXIT +#endif diff --git a/gpu/shadps4/common/decoder.cpp b/gpu/shadps4/common/decoder.cpp new file mode 100644 index 0000000..011e195 --- /dev/null +++ b/gpu/shadps4/common/decoder.cpp @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/decoder.h" + +namespace Common { + +DecoderImpl::DecoderImpl() { + ZydisDecoderInit(&m_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); + ZydisFormatterInit(&m_formatter, ZYDIS_FORMATTER_STYLE_INTEL); +} + +DecoderImpl::~DecoderImpl() = default; + +std::string DecoderImpl::disassembleInst(ZydisDecodedInstruction& inst, + ZydisDecodedOperand* operands, u64 address) { + const int bufLen = 256; + char szBuffer[bufLen]; + ZydisFormatterFormatInstruction(&m_formatter, &inst, operands, inst.operand_count_visible, + szBuffer, sizeof(szBuffer), address, ZYAN_NULL); + return szBuffer; +} + +ZyanStatus DecoderImpl::decodeInstruction(ZydisDecodedInstruction& inst, + ZydisDecodedOperand* operands, void* data, u64 size) { + return ZydisDecoderDecodeFull(&m_decoder, data, size, &inst, operands); +} + +} // namespace Common diff --git a/gpu/shadps4/common/decoder.h b/gpu/shadps4/common/decoder.h new file mode 100644 index 0000000..c8085a7 --- /dev/null +++ b/gpu/shadps4/common/decoder.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/singleton.h" +#include "common/types.h" + +namespace Common { + +class DecoderImpl { +public: + DecoderImpl(); + ~DecoderImpl(); + + std::string disassembleInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, + u64 address); + ZyanStatus decodeInstruction(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, + void* data, u64 size = 15); + +private: + ZydisDecoder m_decoder; + ZydisFormatter m_formatter; +}; + +using Decoder = Common::Singleton; + +} // namespace Common diff --git a/gpu/shadps4/common/discord_rpc_handler.cpp b/gpu/shadps4/common/discord_rpc_handler.cpp new file mode 100644 index 0000000..448cb4a --- /dev/null +++ b/gpu/shadps4/common/discord_rpc_handler.cpp @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "discord_rpc_handler.h" + +namespace DiscordRPCHandler { + +void RPC::init() { + DiscordEventHandlers handlers{}; + + Discord_Initialize("1139939140494971051", &handlers, 1, nullptr); + startTimestamp = time(nullptr); + rpcEnabled = true; +} + +void RPC::setStatusIdling() { + DiscordRichPresence rpc{}; + rpc.largeImageKey = "https://cdn.jsdelivr.net/gh/shadps4-emu/shadPS4@main/.github/shadps4.png"; + rpc.largeImageText = "shadPS4 is a PS4 emulator"; + rpc.startTimestamp = startTimestamp; + rpc.details = "Idle"; + + status = RPCStatus::Idling; + Discord_UpdatePresence(&rpc); +} + +void RPC::setStatusPlaying(const std::string& game_name, const std::string& game_id) { + DiscordRichPresence rpc{}; + + rpc.details = "Playing"; + rpc.state = game_name.c_str(); + std::string largeImageUrl = + "https://store.playstation.com/store/api/chihiro/00_09_000/titlecontainer/US/en/999/" + + game_id + "_00/image"; + rpc.largeImageKey = largeImageUrl.c_str(); + rpc.largeImageText = game_name.c_str(); + rpc.startTimestamp = startTimestamp; + + status = RPCStatus::Playing; + Discord_UpdatePresence(&rpc); +} + +void RPC::shutdown() { + if (rpcEnabled) { + rpcEnabled = false; + Discord_ClearPresence(); + Discord_Shutdown(); + } +} + +bool RPC::getRPCEnabled() { + return rpcEnabled; +} + +} // namespace DiscordRPCHandler diff --git a/gpu/shadps4/common/discord_rpc_handler.h b/gpu/shadps4/common/discord_rpc_handler.h new file mode 100644 index 0000000..1e451e1 --- /dev/null +++ b/gpu/shadps4/common/discord_rpc_handler.h @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +namespace DiscordRPCHandler { + +enum class RPCStatus { + Idling, + Playing, +}; + +class RPC { + std::uint64_t startTimestamp; + bool rpcEnabled = false; + RPCStatus status; + +public: + void init(); + void setStatusIdling(); + void setStatusPlaying(const std::string& game_name, const std::string& game_id); + void shutdown(); + bool getRPCEnabled(); +}; + +} // namespace DiscordRPCHandler diff --git a/gpu/shadps4/common/div_ceil.h b/gpu/shadps4/common/div_ceil.h new file mode 100755 index 0000000..c12477d --- /dev/null +++ b/gpu/shadps4/common/div_ceil.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +namespace Common { + +/// Ceiled integer division. +template + requires std::is_integral_v && std::is_unsigned_v +[[nodiscard]] constexpr N DivCeil(N number, D divisor) { + return static_cast((static_cast(number) + divisor - 1) / divisor); +} + +/// Ceiled integer division with logarithmic divisor in base 2 +template + requires std::is_integral_v && std::is_unsigned_v +[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) { + return static_cast((static_cast(value) + (D(1) << alignment_log2) - 1) >> alignment_log2); +} + +} // namespace Common diff --git a/gpu/shadps4/common/elf_info.h b/gpu/shadps4/common/elf_info.h new file mode 100644 index 0000000..69c2163 --- /dev/null +++ b/gpu/shadps4/common/elf_info.h @@ -0,0 +1,162 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include +#include "assert.h" +#include "bit_field.h" +#include "singleton.h" +#include "types.h" + +namespace Core { +class Emulator; +} + +namespace Common { + +union PSFAttributes { + /// Supports initial user's logout + BitField<0, 1, u32> support_initial_user_logout; + /// Enter button for the common dialog is cross. + BitField<1, 1, u32> enter_button_cross; + /// Warning dialog for PS Move is displayed in the options menu. + BitField<2, 1, u32> ps_move_warning; + /// Supports stereoscopic 3D. + BitField<3, 1, u32> support_stereoscopic_3d; + /// Suspends when PS button is pressed. + BitField<4, 1, u32> ps_button_suspend; + /// Enter button for the common dialog is assigned by the system software. + BitField<5, 1, u32> enter_button_system; + /// Overrides share menu behavior. + BitField<6, 1, u32> override_share_menu; + /// Suspends when PS button is pressed and special output resolution is set. + BitField<8, 1, u32> special_res_ps_button_suspend; + /// Enable HDCP. + BitField<9, 1, u32> enable_hdcp; + /// Disable HDCP for non-game. + BitField<10, 1, u32> disable_hdcp_non_game; + /// Supports PS VR. + BitField<14, 1, u32> support_ps_vr; + /// CPU mode (6 CPU) + BitField<15, 1, u32> six_cpu_mode; + /// CPU mode (7 CPU) + BitField<16, 1, u32> seven_cpu_mode; + /// Supports PS4 Pro (Neo) mode. + BitField<23, 1, u32> support_neo_mode; + /// Requires PS VR. + BitField<26, 1, u32> require_ps_vr; + /// Supports HDR. + BitField<29, 1, u32> support_hdr; + /// Display location. + BitField<31, 1, u32> display_location; + + u32 raw{}; +}; +static_assert(sizeof(PSFAttributes) == 4); + +class ElfInfo { + friend class Core::Emulator; + + bool initialized = false; + + std::string game_serial{}; + std::string title{}; + std::string app_ver{}; + u32 firmware_ver = 0; + u32 raw_firmware_ver = 0; + u32 sdk_ver = 0; + PSFAttributes psf_attributes{}; + + std::vector splash_data{}; + std::filesystem::path game_folder{}; + std::vector npCommIds{}; + std::map trophy_index_map{}; + +public: + static constexpr u32 FW_100 = 0x1000000; + static constexpr u32 FW_150 = 0x1500000; + static constexpr u32 FW_160 = 0x1600000; + static constexpr u32 FW_170 = 0x1700000; + static constexpr u32 FW_200 = 0x2000000; + static constexpr u32 FW_250 = 0x2500000; + static constexpr u32 FW_300 = 0x3000000; + static constexpr u32 FW_350 = 0x3500000; + static constexpr u32 FW_400 = 0x4000000; + static constexpr u32 FW_450 = 0x4500000; + static constexpr u32 FW_500 = 0x5000000; + static constexpr u32 FW_550 = 0x5500000; + static constexpr u32 FW_600 = 0x6000000; + static constexpr u32 FW_700 = 0x7000000; + static constexpr u32 FW_750 = 0x7500000; + static constexpr u32 FW_800 = 0x8000000; + static constexpr u32 FW_900 = 0x9000000; + static constexpr u32 FW_1000 = 0x10000000; + static constexpr u32 FW_1150 = 0x11500000; + + static ElfInfo& Instance() { + return *Singleton::Instance(); + } + + [[nodiscard]] std::string_view GameSerial() const { + ASSERT(initialized); + return Instance().game_serial; + } + + [[nodiscard]] std::string_view Title() const { + ASSERT(initialized); + return title; + } + + [[nodiscard]] std::string_view AppVer() const { + ASSERT(initialized); + return app_ver; + } + + [[nodiscard]] u32 FirmwareVer() const { + ASSERT(initialized); + return firmware_ver; + } + + [[nodiscard]] u32 RawFirmwareVer() const { + ASSERT(initialized); + return raw_firmware_ver; + } + + [[nodiscard]] u32 CompiledSdkVer() const { + ASSERT(initialized); + return sdk_ver; + } + + [[nodiscard]] const PSFAttributes& GetPSFAttributes() const { + ASSERT(initialized); + return psf_attributes; + } + + [[nodiscard]] const std::vector& GetSplashData() const { + return splash_data; + } + + [[nodiscard]] const std::filesystem::path& GetGameFolder() const { + return game_folder; + } + + [[nodiscard]] const std::map& GetTrophyIndexMap() const { + return trophy_index_map; + } + + [[nodiscard]] const std::vector& GetNpCommIds() const { + return npCommIds; + } + + void SetNpCommIds(std::vector ids) { + npCommIds = std::move(ids); + } +}; + +} // namespace Common diff --git a/gpu/shadps4/common/endian.h b/gpu/shadps4/common/endian.h new file mode 100644 index 0000000..4b0b70c --- /dev/null +++ b/gpu/shadps4/common/endian.h @@ -0,0 +1,242 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +/** + * (c) 2014-2016 Alexandro Sanchez Bach. All rights reserved. + * Released under GPL v2 license. Read LICENSE for more details. + * Some modifications for using with shadps4 by georgemoralis + */ + +#pragma once + +#include +#include +#include "common/types.h" + +namespace Common { + +/** + * Native endianness + */ +template +using NativeEndian = T; + +template +class SwappedEndian { +public: + const T& Raw() const { + return data; + } + + T Swap() const { + return std::byteswap(data); + } + + void FromRaw(const T& value) { + data = value; + } + + void FromSwap(const T& value) { + data = std::byteswap(value); + } + + operator const T() const { + return Swap(); + } + + template + explicit operator const SwappedEndian() const { + SwappedEndian res; + if (sizeof(T1) < sizeof(T)) { + res.FromRaw(Raw() >> ((sizeof(T) - sizeof(T1)) * 8)); + } else if (sizeof(T1) > sizeof(T)) { + res.FromSwap(Swap()); + } else { + res.FromRaw(Raw()); + } + return res; + } + + SwappedEndian& operator=(const T& right) { + FromSwap(right); + return *this; + } + SwappedEndian& operator=(const SwappedEndian& right) = default; + + template + SwappedEndian& operator+=(T1 right) { + return *this = T(*this) + right; + } + template + SwappedEndian& operator-=(T1 right) { + return *this = T(*this) - right; + } + template + SwappedEndian& operator*=(T1 right) { + return *this = T(*this) * right; + } + template + SwappedEndian& operator/=(T1 right) { + return *this = T(*this) / right; + } + template + SwappedEndian& operator%=(T1 right) { + return *this = T(*this) % right; + } + template + SwappedEndian& operator&=(T1 right) { + return *this = T(*this) & right; + } + template + SwappedEndian& operator|=(T1 right) { + return *this = T(*this) | right; + } + template + SwappedEndian& operator^=(T1 right) { + return *this = T(*this) ^ right; + } + template + SwappedEndian& operator<<=(T1 right) { + return *this = T(*this) << right; + } + template + SwappedEndian& operator>>=(T1 right) { + return *this = T(*this) >> right; + } + + template + SwappedEndian& operator+=(const SwappedEndian& right) { + return *this = Swap() + right.Swap(); + } + template + SwappedEndian& operator-=(const SwappedEndian& right) { + return *this = Swap() - right.Swap(); + } + template + SwappedEndian& operator*=(const SwappedEndian& right) { + return *this = Swap() * right.Swap(); + } + template + SwappedEndian& operator/=(const SwappedEndian& right) { + return *this = Swap() / right.Swap(); + } + template + SwappedEndian& operator%=(const SwappedEndian& right) { + return *this = Swap() % right.Swap(); + } + template + SwappedEndian& operator&=(const SwappedEndian& right) { + return *this = Raw() & right.Raw(); + } + template + SwappedEndian& operator|=(const SwappedEndian& right) { + return *this = Raw() | right.Raw(); + } + template + SwappedEndian& operator^=(const SwappedEndian& right) { + return *this = Raw() ^ right.Raw(); + } + + template + SwappedEndian operator&(const SwappedEndian& right) const { + return SwappedEndian{Raw() & right.Raw()}; + } + template + SwappedEndian operator|(const SwappedEndian& right) const { + return SwappedEndian{Raw() | right.Raw()}; + } + template + SwappedEndian operator^(const SwappedEndian& right) const { + return SwappedEndian{Raw() ^ right.Raw()}; + } + + template + bool operator==(T1 right) const { + return (T1)Swap() == right; + } + template + bool operator!=(T1 right) const { + return !(*this == right); + } + template + bool operator>(T1 right) const { + return (T1)Swap() > right; + } + template + bool operator<(T1 right) const { + return (T1)Swap() < right; + } + template + bool operator>=(T1 right) const { + return (T1)Swap() >= right; + } + template + bool operator<=(T1 right) const { + return (T1)Swap() <= right; + } + + template + bool operator==(const SwappedEndian& right) const { + return Raw() == right.Raw(); + } + template + bool operator!=(const SwappedEndian& right) const { + return !(*this == right); + } + template + bool operator>(const SwappedEndian& right) const { + return (T1)Swap() > right.Swap(); + } + template + bool operator<(const SwappedEndian& right) const { + return (T1)Swap() < right.Swap(); + } + template + bool operator>=(const SwappedEndian& right) const { + return (T1)Swap() >= right.Swap(); + } + template + bool operator<=(const SwappedEndian& right) const { + return (T1)Swap() <= right.Swap(); + } + + SwappedEndian operator++(int) { + SwappedEndian res = *this; + *this += 1; + return res; + } + SwappedEndian operator--(int) { + SwappedEndian res = *this; + *this -= 1; + return res; + } + SwappedEndian& operator++() { + *this += 1; + return *this; + } + SwappedEndian& operator--() { + *this -= 1; + return *this; + } + +private: + T data; +}; + +template +using LittleEndian = std::conditional_t, + SwappedEndian>; + +template +using BigEndian = + std::conditional_t, SwappedEndian>; + +} // namespace Common + +using u16_be = Common::BigEndian; +using u32_be = Common::BigEndian; +using u64_be = Common::BigEndian; + +using u16_le = Common::LittleEndian; +using u32_le = Common::LittleEndian; +using u64_le = Common::LittleEndian; diff --git a/gpu/shadps4/common/enum.h b/gpu/shadps4/common/enum.h new file mode 100644 index 0000000..a2f0877 --- /dev/null +++ b/gpu/shadps4/common/enum.h @@ -0,0 +1,161 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +#define DECLARE_ENUM_FLAG_OPERATORS(type) \ + [[nodiscard]] constexpr type operator|(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) | static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator&(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) & static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator^(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) ^ static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) << static_cast(b)); \ + } \ + [[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(static_cast(a) >> static_cast(b)); \ + } \ + constexpr type& operator|=(type& a, type b) noexcept { \ + a = a | b; \ + return a; \ + } \ + constexpr type& operator&=(type& a, type b) noexcept { \ + a = a & b; \ + return a; \ + } \ + constexpr type& operator^=(type& a, type b) noexcept { \ + a = a ^ b; \ + return a; \ + } \ + constexpr type& operator<<=(type& a, type b) noexcept { \ + a = a << b; \ + return a; \ + } \ + constexpr type& operator>>=(type& a, type b) noexcept { \ + a = a >> b; \ + return a; \ + } \ + [[nodiscard]] constexpr type operator~(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(~static_cast(key)); \ + } \ + [[nodiscard]] constexpr bool True(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(key) != 0; \ + } \ + [[nodiscard]] constexpr bool False(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(key) == 0; \ + } + +namespace Common { + +template +class Flags { +public: + using IntType = std::underlying_type_t; + + Flags() {} + + Flags(IntType t) : m_bits(t) {} + + template + Flags(T f, Tx... fx) { + this->set(f, fx...); + } + + template + void set(Tx... fx) { + m_bits |= bits(fx...); + } + + void set(Flags flags) { + m_bits |= flags.m_bits; + } + + template + void clr(Tx... fx) { + m_bits &= ~bits(fx...); + } + + void clr(Flags flags) { + m_bits &= ~flags.m_bits; + } + + template + bool any(Tx... fx) const { + return (m_bits & bits(fx...)) != 0; + } + + template + bool all(Tx... fx) const { + const IntType mask = bits(fx...); + return (m_bits & mask) == mask; + } + + bool test(T f) const { + return this->any(f); + } + + bool isClear() const { + return m_bits == 0; + } + + void clrAll() { + m_bits = 0; + } + + u32 raw() const { + return m_bits; + } + + Flags operator&(const Flags& other) const { + return Flags(m_bits & other.m_bits); + } + + Flags operator|(const Flags& other) const { + return Flags(m_bits | other.m_bits); + } + + Flags operator^(const Flags& other) const { + return Flags(m_bits ^ other.m_bits); + } + + bool operator==(const Flags& other) const { + return m_bits == other.m_bits; + } + + bool operator!=(const Flags& other) const { + return m_bits != other.m_bits; + } + +private: + IntType m_bits = 0; + + static IntType bit(T f) { + return IntType(1) << static_cast(f); + } + + template + static IntType bits(T f, Tx... fx) { + return bit(f) | bits(fx...); + } + + static IntType bits() { + return 0; + } +}; + +} // namespace Common diff --git a/gpu/shadps4/common/error.cpp b/gpu/shadps4/common/error.cpp new file mode 100644 index 0000000..972a342 --- /dev/null +++ b/gpu/shadps4/common/error.cpp @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +#include "common/error.h" + +namespace Common { + +std::string NativeErrorToString(int e) { +#ifdef _WIN32 + LPSTR err_str; + + DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, e, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + reinterpret_cast(&err_str), 1, nullptr); + if (!res) { + return "(FormatMessageA failed to format error)"; + } + std::string ret(err_str); + LocalFree(err_str); + return ret; +#else + char err_str[255]; +#if defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) || \ + defined(ANDROID) + // Thread safe (GNU-specific) + const char* str = strerror_r(e, err_str, sizeof(err_str)); + return std::string(str); +#else + // Thread safe (XSI-compliant) + int second_err = strerror_r(e, err_str, sizeof(err_str)); + if (second_err != 0) { + return "(strerror_r failed to format error)"; + } + return std::string(err_str); +#endif // GLIBC etc. +#endif // _WIN32 +} + +std::string GetLastErrorMsg() { +#ifdef _WIN32 + return NativeErrorToString(GetLastError()); +#else + return NativeErrorToString(errno); +#endif +} + +} // namespace Common diff --git a/gpu/shadps4/common/error.h b/gpu/shadps4/common/error.h new file mode 100644 index 0000000..62a3bd8 --- /dev/null +++ b/gpu/shadps4/common/error.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Common { + +// Generic function to get last error message. +// Call directly after the command or use the error num. +// This function might change the error code. +// Defined in error.cpp. +[[nodiscard]] std::string GetLastErrorMsg(); + +// Like GetLastErrorMsg(), but passing an explicit error code. +// Defined in error.cpp. +[[nodiscard]] std::string NativeErrorToString(int e); + +} // namespace Common diff --git a/gpu/shadps4/common/fixed_value.h b/gpu/shadps4/common/fixed_value.h new file mode 100644 index 0000000..e32a795 --- /dev/null +++ b/gpu/shadps4/common/fixed_value.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +/** + * @brief A template class that encapsulates a fixed, compile-time constant value. + * + * @tparam T The type of the value. + * @tparam Value The fixed value of type T. + * + * This class provides a way to encapsulate a value that is constant and known at compile-time. + * The value is stored as a private member and cannot be changed. Any attempt to assign a new + * value to an object of this class will reset it to the fixed value. + */ +template +class FixedValue { + T m_value{Value}; + +public: + constexpr FixedValue() = default; + + constexpr explicit(false) operator T() const { + return m_value; + } + + FixedValue& operator=(const T&) { + m_value = Value; + return *this; + } + FixedValue& operator=(T&&) noexcept { + m_value = {Value}; + return *this; + } +}; diff --git a/gpu/shadps4/common/func_traits.h b/gpu/shadps4/common/func_traits.h new file mode 100644 index 0000000..407b2db --- /dev/null +++ b/gpu/shadps4/common/func_traits.h @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Common { + +template +struct FuncTraits {}; + +template +struct FuncTraits { + using ReturnType = ReturnType_; + + static constexpr size_t NUM_ARGS = sizeof...(Args); + + template + using ArgType = std::tuple_element_t>; +}; + +template +struct LambdaTraits : LambdaTraits::operator())> {}; + +template +struct LambdaTraits { + template + using ArgType = std::tuple_element_t>; + + static constexpr size_t NUM_ARGS{sizeof...(Args)}; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/hash.h b/gpu/shadps4/common/hash.h new file mode 100644 index 0000000..d5caced --- /dev/null +++ b/gpu/shadps4/common/hash.h @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +[[nodiscard]] inline u64 HashCombine(const u64 seed, const u64 hash) { + return seed ^ (hash + 0x9e3779b9 + (seed << 12) + (seed >> 4)); +} + +[[nodiscard]] inline u32 HashCombine(const u32 seed, const u32 hash) { + return seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2)); +} \ No newline at end of file diff --git a/gpu/shadps4/common/incremental_id.h b/gpu/shadps4/common/incremental_id.h new file mode 100644 index 0000000..1891bfe --- /dev/null +++ b/gpu/shadps4/common/incremental_id.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once +#include + +namespace Common { +template +class IncrementalIdProvider { +public: + IncrementalIdProvider() : counter(0) {} + ~IncrementalIdProvider() = default; + + CounterType Next() { + return counter.fetch_add(1, std::memory_order_relaxed) + 1; + } + +private: + std::atomic counter; +}; + +} // namespace Common \ No newline at end of file diff --git a/gpu/shadps4/common/interval_set.h b/gpu/shadps4/common/interval_set.h new file mode 100644 index 0000000..3568431 --- /dev/null +++ b/gpu/shadps4/common/interval_set.h @@ -0,0 +1,205 @@ +// SPDX-FileCopyrightText: 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include "common/types.h" + +struct Interval { + u64 start; + u64 end; + + constexpr bool CanMergeWith(const Interval&) const noexcept { + return true; + } + constexpr Interval SubRange(u64 a, u64 b) const noexcept { + return {a, b}; + } +}; + +template +concept IsInterval = std::derived_from && std::is_trivially_copyable_v && + requires(const IV& a, const IV& b, u64 x) { + { a.CanMergeWith(b) } -> std::same_as; + { a.SubRange(x, x) } -> std::same_as; + }; + +template + requires IsInterval +class IntervalList { +public: + using List = std::vector; + using const_iterator = typename List::const_iterator; + using iterator = typename List::iterator; + + const_iterator begin() const { + return intervals.begin(); + } + const_iterator end() const { + return intervals.end(); + } + + void Clear() { + intervals.clear(); + } + bool Empty() const { + return intervals.empty(); + } + std::size_t Size() const { + return intervals.size(); + } + void Reserve(std::size_t n) { + intervals.reserve(n); + } + + /// Adds a range to the interval set. + void Add(IV value) { + if (value.start >= value.end) [[unlikely]] { + return; + } + + IV out[3]; + std::size_t m = 0; + + auto [first, last] = OverlapRun(value.start, value.end); + if (first != last) { + if (first->start < value.start) { + out[m++] = first->SubRange(first->start, value.start); + } + out[m++] = value; + auto prev = std::prev(last); + if (prev->end > value.end) { + out[m++] = prev->SubRange(value.end, prev->end); + } + } else { + out[m++] = value; + } + + const auto at = std::distance(intervals.begin(), first); + Splice(first, last, out, m); + Coalesce(at, m); + } + + /// Returns immutable iterator to an interval that contains provided address. + const_iterator Find(u64 addr) const { + auto it = std::ranges::upper_bound(intervals, addr, {}, &IV::start); + if (it == intervals.begin()) { + return intervals.end(); + } + --it; + return (it->start <= addr && addr < it->end) ? it : intervals.end(); + } + + /// Returns true if address if contained inside an interval. + bool Contains(u64 addr) const { + return Find(addr) != intervals.end(); + } + + /// Returns true if range is fully contained in the interval set. + bool Contains(u64 start, u64 end) const { + if (start >= end) [[unlikely]] { + return false; + } + auto it = std::ranges::upper_bound(intervals, start, {}, &IV::end); + u64 cur = start; + while (it != intervals.end() && it->start <= cur && cur < end) { + cur = it->end; + ++it; + } + return cur >= end; + } + + /// Returns true if range partially overlaps an interval. + bool Overlaps(u64 start, u64 end) const { + if (start >= end) [[unlikely]] { + return false; + } + auto it = std::ranges::upper_bound(intervals, start, {}, &IV::end); + return it != intervals.end() && it->start < end; + } + + /// Calls 'func' for each gap in provided range. + void ForEachGap(u64 start, u64 end, auto&& func) const { + if (start >= end) [[unlikely]] { + return; + } + auto it = std::ranges::upper_bound(intervals, start, {}, &IV::end); + u64 cur = start; + for (; it != intervals.end() && it->start < end; ++it) { + if (it->start > cur) { + func(cur, it->start); + } + cur = std::max(cur, it->end); + } + if (cur < end) { + func(cur, end); + } + } + + /// Calls 'func' for each interval that partially overlaps provided range. + void ForEachInRange(u64 start, u64 end, auto&& func) const { + if (start >= end) [[unlikely]] { + return; + } + auto it = std::ranges::upper_bound(intervals, start, {}, &IV::end); + if (it == intervals.end()) { + return; + } + while (it != intervals.end() && it->start < end) { + func(*it); + ++it; + } + } + +protected: + /// Returns first interval that overlaps range and first interval after range. + std::pair OverlapRun(u64 start, u64 end) noexcept { + auto first = std::ranges::upper_bound(intervals, start, {}, &IV::end); + auto last = first; + while (last != intervals.end() && last->start <= end) { + ++last; + } + return {first, last}; + } + + /// Inserts intervals from first until last + void Splice(iterator first, iterator last, const IV* src, std::size_t m) noexcept { + if (first == last) { + intervals.insert(first, src, src + m); + return; + } + const auto slots = std::distance(first, last); + if (m <= slots) { + std::copy(src, src + m, first); + if (m < slots) { + intervals.erase(first + m, last); + } + } else { + std::copy(src, src + slots, first); + intervals.insert(last, src + slots, src + m); + } + } + + /// Merges compatible adjacent intervals. + void Coalesce(std::size_t start, std::size_t count) { + auto stop = std::min(start + count + 1, intervals.size()); + for (auto i = start ? start - 1 : start; i + 1 < stop;) { + IV& a = intervals[i]; + IV& b = intervals[i + 1]; + if (a.end == b.start && a.CanMergeWith(b)) { + a.end = b.end; + intervals.erase(intervals.begin() + i + 1); + --stop; + } else { + ++i; + } + } + } + + List intervals; +}; diff --git a/gpu/shadps4/common/io_file.cpp b/gpu/shadps4/common/io_file.cpp new file mode 100644 index 0000000..249d0e0 --- /dev/null +++ b/gpu/shadps4/common/io_file.cpp @@ -0,0 +1,423 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/alignment.h" +#include "common/assert.h" +#include "common/error.h" +#include "common/io_file.h" +#include "common/logging/log.h" +#include "common/path_util.h" + +#ifdef _WIN32 +#include "common/ntapi.h" + +#include +#include +#include +#else +#include +#endif + +#ifdef _MSC_VER +#define fileno _fileno +#define fseeko _fseeki64 +#define ftello _ftelli64 +#endif + +namespace Common::FS { + +namespace fs = std::filesystem; + +namespace { + +#ifdef _WIN32 + +[[nodiscard]] constexpr const wchar_t* AccessModeToWStr(FileAccessMode mode, FileType type) { + switch (type) { + case FileType::BinaryFile: + switch (mode) { + case FileAccessMode::Read: + return L"rb"; + case FileAccessMode::Append: + return L"ab"; + case FileAccessMode::Write: + case FileAccessMode::ReadWrite: + return L"r+b"; + case FileAccessMode::ReadAppend: + return L"a+b"; + case FileAccessMode::Create: + return L"wb"; + } + break; + case FileType::TextFile: + switch (mode) { + case FileAccessMode::Read: + return L"r"; + case FileAccessMode::Append: + return L"a"; + case FileAccessMode::Write: + case FileAccessMode::ReadWrite: + return L"r+"; + case FileAccessMode::ReadAppend: + return L"a+"; + case FileAccessMode::Create: + return L"w"; + } + break; + } + + return L""; +} + +[[nodiscard]] constexpr int ToWindowsFileShareFlag(FileShareFlag flag) { + switch (flag) { + case FileShareFlag::ShareNone: + default: + return _SH_DENYRW; + case FileShareFlag::ShareReadOnly: + return _SH_DENYWR; + case FileShareFlag::ShareWriteOnly: + return _SH_DENYRD; + case FileShareFlag::ShareReadWrite: + return _SH_DENYNO; + } +} + +#else + +[[nodiscard]] constexpr const char* AccessModeToStr(FileAccessMode mode, FileType type) { + switch (type) { + case FileType::BinaryFile: + switch (mode) { + case FileAccessMode::Read: + return "rb"; + case FileAccessMode::Append: + return "ab"; + case FileAccessMode::Write: + case FileAccessMode::ReadWrite: + return "r+b"; + case FileAccessMode::ReadAppend: + return "a+b"; + case FileAccessMode::Create: + return "wb"; + } + break; + case FileType::TextFile: + switch (mode) { + case FileAccessMode::Read: + return "r"; + case FileAccessMode::Append: + return "a"; + case FileAccessMode::Write: + case FileAccessMode::ReadWrite: + return "r+"; + case FileAccessMode::ReadAppend: + return "a+"; + case FileAccessMode::Create: + return "w"; + } + break; + } + + return ""; +} + +#endif + +[[nodiscard]] constexpr int ToSeekOrigin(SeekOrigin origin) { + switch (origin) { + case SeekOrigin::SetOrigin: + return SEEK_SET; + case SeekOrigin::CurrentPosition: + return SEEK_CUR; + case SeekOrigin::End: + return SEEK_END; + default: + UNREACHABLE_MSG("Impossible SeekOrigin {}", static_cast(origin)); + } +} + +} // Anonymous namespace + +IOFile::IOFile() = default; + +IOFile::IOFile(const std::string& path, FileAccessMode mode, FileType type, FileShareFlag flag) { + Open(path, mode, type, flag); +} + +IOFile::IOFile(std::string_view path, FileAccessMode mode, FileType type, FileShareFlag flag) { + Open(path, mode, type, flag); +} + +IOFile::IOFile(const fs::path& path, FileAccessMode mode, FileType type, FileShareFlag flag) { + Open(path, mode, type, flag); +} + +IOFile::~IOFile() { + Close(); +} + +IOFile::IOFile(IOFile&& other) noexcept { + std::swap(file_path, other.file_path); + std::swap(file_access_mode, other.file_access_mode); + std::swap(file_type, other.file_type); + std::swap(file, other.file); +} + +IOFile& IOFile::operator=(IOFile&& other) noexcept { + std::swap(file_path, other.file_path); + std::swap(file_access_mode, other.file_access_mode); + std::swap(file_type, other.file_type); + std::swap(file, other.file); + return *this; +} + +int IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, FileShareFlag flag) { + Close(); + + file_path = path; + file_access_mode = mode; + file_type = type; + + errno = 0; + int result = 0; + +#ifdef _WIN32 + if (flag != FileShareFlag::ShareNone) { + file = _wfsopen(path.c_str(), AccessModeToWStr(mode, type), ToWindowsFileShareFlag(flag)); + result = errno; + } else { + result = _wfopen_s(&file, path.c_str(), AccessModeToWStr(mode, type)); + } +#else + file = std::fopen(path.c_str(), AccessModeToStr(mode, type)); + result = errno; +#endif + + if (!IsOpen()) { + const auto ec = std::error_code{result, std::generic_category()}; + LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, error_message={}", + PathToUTF8String(file_path), ec.message()); + } + + return result; +} + +void IOFile::Close() { + if (!IsOpen()) { + return; + } + + errno = 0; + + const auto close_result = std::fclose(file) == 0; + + if (!close_result) { + const auto ec = std::error_code{errno, std::generic_category()}; + LOG_ERROR(Common_Filesystem, "Failed to close the file at path={}, ec_message={}", + PathToUTF8String(file_path), ec.message()); + } + + file = nullptr; + +#ifdef _WIN64 + if (file_mapping && file_access_mode == FileAccessMode::ReadWrite) { + CloseHandle(std::bit_cast(file_mapping)); + } +#endif +} + +void IOFile::Unlink() { + if (!IsOpen()) { + return; + } + + // Mark the file for deletion + // TODO: Also remove the file path? +#ifdef _WIN64 + FILE_DISPOSITION_INFORMATION disposition; + IO_STATUS_BLOCK iosb; + + const int fd = fileno(file); + HANDLE hfile = reinterpret_cast(_get_osfhandle(fd)); + + disposition.DeleteFile = TRUE; + NtSetInformationFile(hfile, &iosb, &disposition, sizeof(disposition), + FileDispositionInformation); +#else + if (unlink(file_path.c_str()) != 0) { + const auto ec = std::error_code{errno, std::generic_category()}; + LOG_ERROR(Common_Filesystem, "Failed to unlink the file at path={}, ec_message={}", + PathToUTF8String(file_path), ec.message()); + } +#endif +} + +uintptr_t IOFile::GetFileMapping() { + if (file_mapping) { + return file_mapping; + } +#ifdef _WIN64 + const int fd = fileno(file); + + HANDLE hfile = reinterpret_cast(_get_osfhandle(fd)); + HANDLE mapping = nullptr; + + if (file_access_mode == FileAccessMode::ReadWrite) { + mapping = CreateFileMapping2(hfile, NULL, FILE_MAP_WRITE, PAGE_READWRITE, SEC_COMMIT, 0, + NULL, NULL, 0); + } else { + mapping = hfile; + } + + file_mapping = std::bit_cast(mapping); + ASSERT_MSG(file_mapping, "{}", Common::GetLastErrorMsg()); + return file_mapping; +#else + file_mapping = fileno(file); + return file_mapping; +#endif +} + +std::string IOFile::ReadString(size_t length) const { + std::vector string_buffer(length); + + const auto chars_read = ReadSpan(string_buffer); + const auto string_size = chars_read != length ? chars_read : length; + + return std::string{string_buffer.data(), string_size}; +} + +bool IOFile::Flush() const { + if (!IsOpen()) { + return false; + } + + errno = 0; + +#ifdef _WIN32 + const auto flush_result = std::fflush(file) == 0; +#else + const auto flush_result = std::fflush(file) == 0; +#endif + + if (!flush_result) { + const auto ec = std::error_code{errno, std::generic_category()}; + LOG_ERROR(Common_Filesystem, "Failed to flush the file at path={}, ec_message={}", + PathToUTF8String(file_path), ec.message()); + } + + return flush_result; +} + +bool IOFile::Commit() const { + if (!IsOpen()) { + return false; + } + + errno = 0; + +#ifdef _WIN32 + const auto commit_result = std::fflush(file) == 0 && _commit(fileno(file)) == 0; +#else + const auto commit_result = std::fflush(file) == 0 && fsync(fileno(file)) == 0; +#endif + + if (!commit_result) { + const auto ec = std::error_code{errno, std::generic_category()}; + LOG_ERROR(Common_Filesystem, "Failed to commit the file at path={}, ec_message={}", + PathToUTF8String(file_path), ec.message()); + } + + return commit_result; +} + +bool IOFile::SetSize(u64 size) const { + if (!IsOpen()) { + return false; + } + + errno = 0; + +#ifdef _WIN32 + const auto set_size_result = _chsize_s(fileno(file), static_cast(size)) == 0; +#else + const auto set_size_result = ftruncate(fileno(file), static_cast(size)) == 0; +#endif + + if (!set_size_result) { + const auto ec = std::error_code{errno, std::generic_category()}; + LOG_ERROR(Common_Filesystem, "Failed to resize the file at path={}, size={}, ec_message={}", + PathToUTF8String(file_path), size, ec.message()); + } + + return set_size_result; +} + +u64 IOFile::GetSize() const { + if (!IsOpen()) { + return 0; + } + + // Flush any unwritten buffered data into the file prior to retrieving the file size. + std::fflush(file); + + std::error_code ec; + + const auto file_size = fs::file_size(file_path, ec); + + if (ec) { + LOG_ERROR(Common_Filesystem, "Failed to retrieve the file size of path={}, ec_message={}", + PathToUTF8String(file_path), ec.message()); + return 0; + } + + return file_size; +} + +bool IOFile::Seek(s64 offset, SeekOrigin origin) const { + if (!IsOpen()) { + return false; + } + + errno = 0; + + const auto seek_result = fseeko(file, offset, ToSeekOrigin(origin)) == 0; + + if (!seek_result) { + const auto ec = std::error_code{errno, std::generic_category()}; + LOG_ERROR(Common_Filesystem, + "Failed to seek the file at path={}, offset={}, origin={}, ec_message={}", + PathToUTF8String(file_path), offset, static_cast(origin), ec.message()); + } + + return seek_result; +} + +s64 IOFile::Tell() const { + if (!IsOpen()) { + return 0; + } + + errno = 0; + + return ftello(file); +} + +u64 GetDirectorySize(const std::filesystem::path& path) { + if (!fs::exists(path)) { + return 0; + } + + u64 total = 0; + for (const auto& entry : fs::recursive_directory_iterator(path)) { + if (fs::is_regular_file(entry.path())) { + total += fs::file_size(entry.path()); + } + } + return total; +} + +} // namespace Common::FS diff --git a/gpu/shadps4/common/io_file.h b/gpu/shadps4/common/io_file.h new file mode 100644 index 0000000..937d6dc --- /dev/null +++ b/gpu/shadps4/common/io_file.h @@ -0,0 +1,252 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/concepts.h" +#include "common/types.h" +#include "enum.h" + +namespace Common::FS { + +enum class FileAccessMode { + /** + * If the file at path exists, it opens the file for reading. + * If the file at path does not exist, it fails to open the file. + */ + Read = 1 << 0, + /** + * If the file at path exists, it opens the file for writing. + * If the file at path does not exist, it fails to open the file. + */ + Write = 1 << 1, + /** + * If the file at path exists, it opens the file for reading and writing. + * If the file at path does not exist, it fails to open the file. + */ + ReadWrite = Read | Write, + /** + * If the file at path exists, it opens the file for appending. + * If the file at path does not exist, it creates and opens a new empty file for appending. + */ + Append = 1 << 2, + /** + * If the file at path exists, it opens the file for both reading and appending. + * If the file at path does not exist, it creates and opens a new empty file for both + * reading and appending. + */ + ReadAppend = Read | Append, + /** + * If the file at path exists, the existing contents of the file are erased. + * The empty file is then opened for writing. + * If the file at path does not exist, it creates and opens a new empty file for writing. + */ + Create = 1 << 3, +}; +DECLARE_ENUM_FLAG_OPERATORS(FileAccessMode); + +enum class FileType { + BinaryFile, + TextFile, +}; + +enum class FileShareFlag { + ShareNone, // Provides exclusive access to the file. + ShareReadOnly, // Provides read only shared access to the file. + ShareWriteOnly, // Provides write only shared access to the file. + ShareReadWrite, // Provides read and write shared access to the file. +}; + +enum class SeekOrigin : u32 { + SetOrigin, // Seeks from the start of the file. + CurrentPosition, // Seeks from the current file pointer position. + End, // Seeks from the end of the file. +}; + +class IOFile final { +public: + IOFile(); + + explicit IOFile(const std::string& path, FileAccessMode mode, + FileType type = FileType::BinaryFile, + FileShareFlag flag = FileShareFlag::ShareReadOnly); + + explicit IOFile(std::string_view path, FileAccessMode mode, + FileType type = FileType::BinaryFile, + FileShareFlag flag = FileShareFlag::ShareReadOnly); + explicit IOFile(const std::filesystem::path& path, FileAccessMode mode, + FileType type = FileType::BinaryFile, + FileShareFlag flag = FileShareFlag::ShareReadOnly); + + ~IOFile(); + + IOFile(const IOFile&) = delete; + IOFile& operator=(const IOFile&) = delete; + + IOFile(IOFile&& other) noexcept; + IOFile& operator=(IOFile&& other) noexcept; + + std::filesystem::path GetPath() const { + return file_path; + } + + FileAccessMode GetAccessMode() const { + return file_access_mode; + } + + FileType GetType() const { + return file_type; + } + + bool IsOpen() const { + return file != nullptr; + } + + bool IsWriteOnly() const { + return file_access_mode == FileAccessMode::Append || + file_access_mode == FileAccessMode::Write; + } + + uintptr_t GetFileMapping(); + + int Open(const std::filesystem::path& path, FileAccessMode mode, + FileType type = FileType::BinaryFile, + FileShareFlag flag = FileShareFlag::ShareReadOnly); + void Close(); + + void Unlink(); + + bool Flush() const; + bool Commit() const; + + bool SetSize(u64 size) const; + u64 GetSize() const; + + bool Seek(s64 offset, SeekOrigin origin = SeekOrigin::SetOrigin) const; + s64 Tell() const; + + template + size_t Read(T& data) const { + if constexpr (IsContiguousContainer) { + using ContiguousType = typename T::value_type; + static_assert(std::is_trivially_copyable_v, + "Data type must be trivially copyable."); + return ReadSpan(data); + } else { + return ReadObject(data) ? 1 : 0; + } + } + + template + size_t Write(const T& data) const { + if constexpr (IsContiguousContainer) { + using ContiguousType = typename T::value_type; + static_assert(std::is_trivially_copyable_v, + "Data type must be trivially copyable."); + return WriteSpan(data); + } else { + static_assert(std::is_trivially_copyable_v, "Data type must be trivially copyable."); + return WriteObject(data) ? 1 : 0; + } + } + + template + size_t ReadSpan(std::span data) const { + static_assert(std::is_trivially_copyable_v, "Data type must be trivially copyable."); + + if (!IsOpen()) { + return 0; + } + + return ReadRaw(data.data(), data.size()); + } + + template + size_t ReadRaw(void* data, size_t size) const { + u64 read = std::fread(data, sizeof(T), size, file); + ASSERT_MSG(std::ferror(file) == 0, "Failed to read file, error = {}", std::strerror(errno)); + return read; + } + + template + size_t WriteSpan(std::span data) const { + static_assert(std::is_trivially_copyable_v, "Data type must be trivially copyable."); + + if (!IsOpen()) { + return 0; + } + + u64 written = std::fwrite(data.data(), sizeof(T), data.size(), file); + ASSERT_MSG(std::ferror(file) == 0, "Failed to write to file, error = {}", + std::strerror(errno)); + std::fflush(file); + return written; + } + + template + bool ReadObject(T& object) const { + static_assert(std::is_trivially_copyable_v, "Data type must be trivially copyable."); + static_assert(!std::is_pointer_v, "T must not be a pointer to an object."); + + if (!IsOpen()) { + return false; + } + + bool success = std::fread(&object, sizeof(T), 1, file) == 1; + ASSERT_MSG(std::ferror(file) == 0, "Failed to read file, error = {}", std::strerror(errno)); + return success; + } + + template + size_t WriteRaw(const void* data, size_t size) const { + u64 bytes = std::fwrite(data, sizeof(T), size, file); + ASSERT_MSG(std::ferror(file) == 0, "Failed to write to file, error = {}", + std::strerror(errno)); + std::fflush(file); + return bytes; + } + + template + bool WriteObject(const T& object) const { + static_assert(std::is_trivially_copyable_v, "Data type must be trivially copyable."); + static_assert(!std::is_pointer_v, "T must not be a pointer to an object."); + + if (!IsOpen()) { + return false; + } + + u64 bytes = std::fwrite(&object, sizeof(T), 1, file) == 1; + ASSERT_MSG(std::ferror(file) == 0, "Failed to read file, error = {}", std::strerror(errno)); + std::fflush(file); + return bytes; + } + + std::string ReadString(size_t length) const; + + size_t WriteString(std::span string) const { + return WriteSpan(string); + } + + static size_t WriteBytes(const std::filesystem::path path, const auto& data) { + IOFile out(path, FileAccessMode::Create); + return out.Write(data); + } + std::FILE* file = nullptr; + +private: + std::filesystem::path file_path; + FileAccessMode file_access_mode{}; + FileType file_type{}; + + uintptr_t file_mapping = 0; +}; + +u64 GetDirectorySize(const std::filesystem::path& path); + +} // namespace Common::FS diff --git a/gpu/shadps4/common/key_manager.cpp b/gpu/shadps4/common/key_manager.cpp new file mode 100644 index 0000000..3497ec8 --- /dev/null +++ b/gpu/shadps4/common/key_manager.cpp @@ -0,0 +1,202 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadLauncher4 Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include "common/logging/formatter.h" +#include "common/logging/log.h" +#include "key_manager.h" +#include "path_util.h" + +std::shared_ptr KeyManager::s_instance = nullptr; +std::mutex KeyManager::s_mutex; + +// ------------------- Constructor & Singleton ------------------- +KeyManager::KeyManager() { + SetDefaultKeys(); +} +KeyManager::~KeyManager() { + SaveToFile(); +} + +std::shared_ptr KeyManager::GetInstance() { + std::lock_guard lock(s_mutex); + if (!s_instance) + s_instance = std::make_shared(); + return s_instance; +} + +void KeyManager::SetInstance(std::shared_ptr instance) { + std::lock_guard lock(s_mutex); + s_instance = instance; +} + +// ------------------- Load / Save ------------------- +bool KeyManager::TransferTrophyKey() { + try { + auto path = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml"; + if (!std::filesystem::exists(path)) { + return false; + } + + // Parse the old config + std::ifstream ifs; + ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); + ifs.open(path, std::ios_base::binary); + toml::value og_data = + toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data}); + + // Retrieve old trophy key and store it. + if (og_data.contains("Keys")) { + const auto& keys = og_data.at("Keys").as_table(); + auto it = keys.find("TrophyKey"); + if (it == keys.end()) { + return false; + } + + std::string old_key = toml::get(it->second); + if (!old_key.empty()) { + m_keys.TrophyKeySet.ReleaseTrophyKey = KeyManager::HexStringToBytes(old_key); + return true; + } + } + } catch (std::exception& ex) { + fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); + } + return false; +} + +bool KeyManager::LoadFromFile() { + try { + const auto userDir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); + const auto keysPath = userDir / "keys.json"; + + if (!std::filesystem::exists(keysPath)) { + SetDefaultKeys(); + TransferTrophyKey(); + SaveToFile(); + return true; + } + + std::ifstream file(keysPath); + if (!file.is_open()) { + LOG_ERROR(KeyManager, "Could not open key file: {}", keysPath.string()); + return false; + } + + json j; + file >> j; + + SetDefaultKeys(); // start from defaults + + if (j.contains("TrophyKeySet")) { + j.at("TrophyKeySet").get_to(m_keys.TrophyKeySet); + } + + if (m_keys.TrophyKeySet.ReleaseTrophyKey.empty()) { + // No key, try to transfer it from the old configs + if (TransferTrophyKey()) { + // If we did transfer something, make sure to save it. + SaveToFile(); + } + } + return true; + + } catch (const std::exception& e) { + LOG_ERROR(KeyManager, "Error loading keys, using defaults: {}", e.what()); + SetDefaultKeys(); + return false; + } +} + +bool KeyManager::SaveToFile() { + try { + const auto userDir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); + const auto keysPath = userDir / "keys.json"; + + json j; + KeysToJson(j); + + std::ofstream file(keysPath); + if (!file.is_open()) { + LOG_ERROR(KeyManager, "Could not open key file for writing: {}", keysPath.string()); + return false; + } + + file << std::setw(4) << j; + file.flush(); + + if (file.fail()) { + LOG_ERROR(KeyManager, "Failed to write keys to: {}", keysPath.string()); + return false; + } + return true; + + } catch (const std::exception& e) { + LOG_ERROR(KeyManager, "Error saving keys: {}", e.what()); + return false; + } +} + +// ------------------- JSON conversion ------------------- +void KeyManager::KeysToJson(json& j) const { + j = m_keys; +} +void KeyManager::JsonToKeys(const json& j) { + json current = m_keys; // serialize current defaults + current.update(j); // merge only fields present in file + m_keys = current.get(); // deserialize back +} + +// ------------------- Defaults / Checks ------------------- +void KeyManager::SetDefaultKeys() { + m_keys = AllKeys{}; +} + +bool KeyManager::HasKeys() const { + return !m_keys.TrophyKeySet.ReleaseTrophyKey.empty(); +} + +// ------------------- Hex conversion ------------------- +std::vector KeyManager::HexStringToBytes(const std::string& hexStr) { + std::vector bytes; + if (hexStr.empty()) + return bytes; + + if (hexStr.size() % 2 != 0) + throw std::runtime_error("Invalid hex string length"); + + bytes.reserve(hexStr.size() / 2); + + auto hexCharToInt = [](char c) -> u8 { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + throw std::runtime_error("Invalid hex character"); + }; + + for (size_t i = 0; i < hexStr.size(); i += 2) { + u8 high = hexCharToInt(hexStr[i]); + u8 low = hexCharToInt(hexStr[i + 1]); + bytes.push_back((high << 4) | low); + } + + return bytes; +} + +std::string KeyManager::BytesToHexString(const std::vector& bytes) { + static const char hexDigits[] = "0123456789ABCDEF"; + std::string hexStr; + hexStr.reserve(bytes.size() * 2); + for (u8 b : bytes) { + hexStr.push_back(hexDigits[(b >> 4) & 0xF]); + hexStr.push_back(hexDigits[b & 0xF]); + } + return hexStr; +} \ No newline at end of file diff --git a/gpu/shadps4/common/key_manager.h b/gpu/shadps4/common/key_manager.h new file mode 100644 index 0000000..f71765f --- /dev/null +++ b/gpu/shadps4/common/key_manager.h @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadLauncher4 Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "common/types.h" +#include "nlohmann/json.hpp" + +using json = nlohmann::json; + +class KeyManager { +public: + // ------------------- Nested keysets ------------------- + struct TrophyKeySet { + std::vector ReleaseTrophyKey; + }; + + struct AllKeys { + KeyManager::TrophyKeySet TrophyKeySet; + }; + + // ------------------- Construction ------------------- + KeyManager(); + ~KeyManager(); + + // ------------------- Singleton ------------------- + static std::shared_ptr GetInstance(); + static void SetInstance(std::shared_ptr instance); + + // ------------------- File operations ------------------- + bool TransferTrophyKey(); + bool LoadFromFile(); + bool SaveToFile(); + + // ------------------- Key operations ------------------- + void SetDefaultKeys(); + bool HasKeys() const; + + // ------------------- Getters / Setters ------------------- + const AllKeys& GetAllKeys() const { + return m_keys; + } + void SetAllKeys(const AllKeys& keys) { + m_keys = keys; + } + + static std::vector HexStringToBytes(const std::string& hexStr); + static std::string BytesToHexString(const std::vector& bytes); + +private: + void KeysToJson(json& j) const; + void JsonToKeys(const json& j); + + AllKeys m_keys{}; + + static std::shared_ptr s_instance; + static std::mutex s_mutex; +}; + +// ------------------- NLOHMANN macros ------------------- +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(KeyManager::TrophyKeySet, ReleaseTrophyKey) +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(KeyManager::AllKeys, TrophyKeySet) + +namespace nlohmann { +template <> +struct adl_serializer> { + static void to_json(json& j, const std::vector& vec) { + j = KeyManager::BytesToHexString(vec); + } + static void from_json(const json& j, std::vector& vec) { + vec = KeyManager::HexStringToBytes(j.get()); + } +}; +} // namespace nlohmann diff --git a/gpu/shadps4/common/logging/classes.h b/gpu/shadps4/common/logging/classes.h new file mode 100644 index 0000000..dbd30ee --- /dev/null +++ b/gpu/shadps4/common/logging/classes.h @@ -0,0 +1,120 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Common::Log::Class { +// clang-format off +/// Listing all log classes, if you add here, dont forget ALL_LOGGERS +constexpr auto Common = "Common"; ///< Library routines +constexpr auto Common_Filesystem = "Common.Filesystem"; ///< Filesystem interface library +constexpr auto Common_Memory = "Common.Memory"; ///< Memory mapping and management functions +constexpr auto Config = "Config"; ///< Emulator configuration (including commandline) +constexpr auto Core = "Core"; ///< LLE emulation core +constexpr auto Core_Devices = "Core.Devices"; ///< Devices emulation +constexpr auto Core_Linker = "Core.Linker"; ///< The module linker +constexpr auto Debug = "Debug"; ///< Debugging tools +constexpr auto Frontend = "Frontend"; ///< Emulator UI +constexpr auto IPC = "IPC"; ///< IPC +constexpr auto ImGui = "ImGui"; ///< ImGui +constexpr auto Input = "Input"; ///< Input emulation +constexpr auto Kernel = "Kernel"; ///< The HLE implementation of the PS4 kernel. +constexpr auto Kernel_Event = "Kernel.Event"; ///< The event management implementation of the kernel. +constexpr auto Kernel_Fs = "Kernel.Fs"; ///< The filesystem implementation of the kernel. +constexpr auto Kernel_Pthread = "Kernel.Pthread"; ///< The pthread implementation of the kernel. +constexpr auto Kernel_Sce = "Kernel.Sce"; ///< The Sony-specific interfaces provided by the kernel. +constexpr auto Kernel_Vmm = "Kernel.Vmm"; ///< The virtual memory implementation of the kernel. +constexpr auto KeyManager = "KeyManager"; ///< Key management system +constexpr auto Lib = "Lib"; ///< HLE implementation of system library. Each major library should have its own subclass. +constexpr auto Lib_Ajm = "Lib.Ajm"; ///< The LibSceAjm implementation. +constexpr auto Lib_AppContent = "Lib.AppContent"; ///< The LibSceAppContent implementation. +constexpr auto Lib_Audio3d = "Lib.Audio3d"; ///< The LibSceAudio3d implementation. +constexpr auto Lib_AudioIn = "Lib.AudioIn"; ///< The LibSceAudioIn implementation. +constexpr auto Lib_AudioOut = "Lib.AudioOut"; ///< The LibSceAudioOut implementation. +constexpr auto Lib_AvPlayer = "Lib.AvPlayer"; ///< The LibSceAvPlayer implementation. +constexpr auto Lib_Camera = "Lib.Camera"; ///< The LibSceCamera implementation. +constexpr auto Lib_CommonDlg = "Lib.CommonDlg"; ///< The LibSceCommonDialog implementation. +constexpr auto Lib_CompanionHttpd = "Lib.CompanionHttpd"; ///< The LibSceCompanionHttpd implementation. +constexpr auto Lib_CompanionUtil = "Lib.CompanionUtil"; ///< The LibSceCompanionUtil implementation. +constexpr auto Lib_ContentExport = "Lib.ContentExport"; ///< The LibSceContentExport implementation. +constexpr auto Lib_DiscMap = "Lib.DiscMap"; ///< The LibSceDiscMap implementation. +constexpr auto Lib_ErrorDialog = "Lib.ErrorDialog"; ///< The LibSceErrorDialog implementation. +constexpr auto Lib_Fiber = "Lib.Fiber"; ///< The LibSceFiber implementation. +constexpr auto Lib_Font = "Lib.Font"; ///< The libSceFont implementation. +constexpr auto Lib_FontFt = "Lib.FontFt"; ///< The libSceFontFt implementation. +constexpr auto Lib_GameLiveStreaming = "Lib.GameLiveStreaming"; ///< The LibSceGameLiveStreaming implementation +constexpr auto Lib_GnmDriver = "Lib.GnmDriver"; ///< The LibSceGnmDriver implementation. +constexpr auto Lib_Hmd = "Lib.Hmd"; ///< The LibSceHmd implementation. +constexpr auto Lib_HmdSetupDialog = "Lib.HmdSetupDialog"; ///< The LibSceHmdSetupDialog implementation. +constexpr auto Lib_Http = "Lib.Http"; ///< The LibSceHttp implementation. +constexpr auto Lib_Http2 = "Lib.Http2"; ///< The LibSceHttp2 implementation. +constexpr auto Lib_Ime = "Lib.Ime"; ///< The LibSceIme implementation +constexpr auto Lib_ImeDialog = "Lib.ImeDialog"; ///< The LibSceImeDialog implementation. +constexpr auto Lib_InvitationDialog="Lib.InvitationDialog"; ///< The LibSceInvitationDialog implementation. +constexpr auto Lib_Jpeg = "Lib.Jpeg"; ///< The LibSceJpeg implementation. +constexpr auto Lib_Kernel = "Lib.Kernel"; ///< The LibKernel implementation. +constexpr auto Lib_LibcInternal = "Lib.LibcInternal"; ///< The LibSceLibcInternal implementation. +constexpr auto Lib_Mouse = "Lib.Mouse"; ///< The LibSceMouse implementation +constexpr auto Lib_Move = "Lib.Move"; ///< The LibSceMove implementation. +constexpr auto Lib_MsgDlg = "Lib.MsgDlg"; ///< The LibSceMsgDialog implementation. +constexpr auto Lib_Net = "Lib.Net"; ///< The LibSceNet implementation. +constexpr auto Lib_NetCtl = "Lib.NetCtl"; ///< The LibSceNetCtl implementation. +constexpr auto Lib_Ngs2 = "Lib.Ngs2"; ///< The LibSceNgs2 implementation. +constexpr auto Lib_NpAuth = "Lib.NpAuth"; ///< The LibSceNpAuth implementation +constexpr auto Lib_NpCommerce = "Lib.NpCommerce"; ///< The LibSceNpCommerce implementation +constexpr auto Lib_NpCommon = "Lib.NpCommon"; ///< The LibSceNpCommon implementation +constexpr auto Lib_NpManager = "Lib.NpManager"; ///< The LibSceNpManager implementation +constexpr auto Lib_NpMatching2 = "Lib.NpMatching2"; ///< The LibSceNpMatching2 implementation +constexpr auto Lib_NpSignaling = "Lib.NpSignaling"; ///< The LibSceNpSignaling implementation +constexpr auto Lib_NpPartner = "Lib.NpPartner"; ///< The LibSceNpPartner implementation +constexpr auto Lib_NpParty = "Lib.NpParty"; ///< The LibSceNpParty implementation +constexpr auto Lib_NpProfileDialog = "Lib.NpProfileDialog"; ///< The LibSceNpProfileDialog implementation +constexpr auto Lib_NpScore = "Lib.NpScore"; ///< The LibSceNpScore implementation +constexpr auto Lib_NpSnsFacebookDialog = "Lib.NpSnsFacebookDialog"; ///< The LibSceNpSnsFacebookDialog implementation +constexpr auto Lib_NpTrophy = "Lib.NpTrophy"; ///< The LibSceNpTrophy implementation +constexpr auto Lib_NpTus = "Lib.NpTus"; ///< The LibSceNpTus implementation +constexpr auto Lib_NpUtility = "Lib.NpUtility"; ///< The LibSceNpUtility implementation +constexpr auto Lib_NpWebApi = "Lib.NpWebApi"; ///< The LibSceWebApi implementation +constexpr auto Lib_NpWebApi2 = "Lib.NpWebApi2"; ///< The LibSceWebApi2 implementation +constexpr auto Lib_Pad = "Lib.Pad"; ///< The LibScePad implementation. +constexpr auto Lib_PlayGo = "Lib.PlayGo"; ///< The LibScePlayGo implementation. +constexpr auto Lib_PlayGoDialog = "Lib.PlayGoDialog"; ///< The LibScePlayGoDialog implementation. +constexpr auto Lib_Png = "Lib.Png"; ///< The LibScePng implementation. +constexpr auto Lib_Random = "Lib.Random"; ///< The LibSceRandom implementation. +constexpr auto Lib_RazorCpu = "Lib.RazorCpu"; ///< The LibRazorCpu implementation. +constexpr auto Lib_Remoteplay = "Lib.Remoteplay"; ///< The LibSceRemotePlay implementation +constexpr auto Lib_Rtc = "Lib.Rtc"; ///< The LibSceRtc implementation. +constexpr auto Lib_Rudp = "Lib.Rudp"; ///< The LibSceRudp implementation. +constexpr auto Lib_SaveData = "Lib.SaveData"; ///< The LibSceSaveData implementation. +constexpr auto Lib_SaveDataDialog = "Lib.SaveDataDialog"; ///< The LibSceSaveDataDialog implementation. +constexpr auto Lib_Screenshot = "Lib.Screenshot"; ///< The LibSceScreenshot implementation +constexpr auto Lib_SharePlay = "Lib.SharePlay"; ///< The LibSceSharePlay implemenation +constexpr auto Lib_SigninDialog = "Lib.SigninDialog"; ///< The LibSigninDialog implementation. +constexpr auto Lib_Ssl = "Lib.Ssl"; ///< The LibSceSsl implementation. +constexpr auto Lib_Ssl2 = "Lib.Ssl2"; ///< The LibSceSsl2 implementation. +constexpr auto Lib_SysModule = "Lib.SysModule"; ///< The LibSceSysModule implementation +constexpr auto Lib_SystemGesture = "Lib.SystemGesture"; ///< The LibSceSystemGesture implementation. +constexpr auto Lib_SystemService = "Lib.SystemService"; ///< The LibSceSystemService implementation. +constexpr auto Lib_Usbd = "Lib.Usbd"; ///< The LibSceUsbd implementation. +constexpr auto Lib_UserService = "Lib.UserService"; ///< The LibSceUserService implementation. +constexpr auto Lib_Vdec2 = "Lib.Vdec2"; ///< The LibSceVideodec2 implementation. +constexpr auto Lib_Vdecsw = "Lib.Vdecsw"; ///< The LibSceVdecsw implementation. +constexpr auto Lib_VideoOut = "Lib.VideoOut"; ///< The LibSceVideoOut implementation. +constexpr auto Lib_Videodec = "Lib.Videodec"; ///< The LibSceVideodec implementation. +constexpr auto Lib_VideoRecording = "Lib.VideoRecording"; ///< The LibSceVideoRecording implementation. +constexpr auto Lib_Voice = "Lib.Voice"; ///< The LibSceVoice implementation. +constexpr auto Lib_VrTracker = "Lib.VrTracker"; ///< The LibSceVrTracker implementation. +constexpr auto Lib_WebBrowserDialog = "Lib.WebBrowserDialog"; ///< The LibSceWebBrowserDialog implementation +constexpr auto Lib_Zlib = "Lib.Zlib"; ///< The LibSceZlib implementation. +constexpr auto Loader = "Loader"; ///< ROM loader +constexpr auto Log = "Log"; ///< Messages about the log system itself +constexpr auto NpHandler = "NpHandler"; ///< NpHandler shadNet manager +constexpr auto Render = "Render"; ///< Video Core +constexpr auto Render_Recompiler = "Render.Recompiler"; ///< Shader recompiler +constexpr auto Render_Vulkan = "Render.Vulkan"; ///< Vulkan backend +constexpr auto ShadNet = "ShadNet"; ///< shadNet binary protocol client +constexpr auto Tty = "Tty"; ///< Debug output from emu +// clang-format on +} // namespace Common::Log::Class diff --git a/gpu/shadps4/common/logging/formatter.h b/gpu/shadps4/common/logging/formatter.h new file mode 100644 index 0000000..fad8451 --- /dev/null +++ b/gpu/shadps4/common/logging/formatter.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +// Adapted from https://github.com/fmtlib/fmt/issues/2704 +// a generic formatter for enum classes +#if FMT_VERSION >= 80100 +template +struct fmt::formatter, char>> + : formatter> { + template + auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) { + return fmt::formatter>::format( + static_cast>(value), ctx); + } +}; +#endif + +namespace fmt { +template +struct UTF { + T data; + + explicit UTF(const std::u8string_view view) { + data = view.empty() ? T{} : T{(const char*)&view.front(), (const char*)&view.back() + 1}; + } + + explicit UTF(const std::u8string& str) : UTF(std::u8string_view{str}) {} +}; +} // namespace fmt + +template <> +struct fmt::formatter, char> : formatter { + template + auto format(const UTF& wrapper, FormatContext& ctx) const { + return formatter::format(wrapper.data, ctx); + } +}; \ No newline at end of file diff --git a/gpu/shadps4/common/logging/log.cpp b/gpu/shadps4/common/logging/log.cpp new file mode 100644 index 0000000..7b40935 --- /dev/null +++ b/gpu/shadps4/common/logging/log.cpp @@ -0,0 +1,302 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#include "common/assert.h" +#include "common/logging/log.h" +#include "common/logging/log_file_sink.h" +#include "common/types.h" +#include "core/emulator_settings.h" + +namespace Common::Log { +bool g_should_append = false; + +static std::shared_ptr g_console_sink; +static std::shared_ptr g_shad_file_sink; + +std::unordered_map> ALL_LOGGERS{ + {Class::Common, nullptr}, + {Class::Common_Filesystem, nullptr}, + {Class::Common_Memory, nullptr}, + {Class::Config, nullptr}, + {Class::Core, nullptr}, + {Class::Core_Devices, nullptr}, + {Class::Core_Linker, nullptr}, + {Class::Debug, nullptr}, + {Class::Frontend, nullptr}, + {Class::IPC, nullptr}, + {Class::ImGui, nullptr}, + {Class::Input, nullptr}, + {Class::Kernel, nullptr}, + {Class::Kernel_Event, nullptr}, + {Class::Kernel_Fs, nullptr}, + {Class::Kernel_Pthread, nullptr}, + {Class::Kernel_Sce, nullptr}, + {Class::Kernel_Vmm, nullptr}, + {Class::KeyManager, nullptr}, + {Class::Lib, nullptr}, + {Class::Lib_Ajm, nullptr}, + {Class::Lib_AppContent, nullptr}, + {Class::Lib_Audio3d, nullptr}, + {Class::Lib_AudioIn, nullptr}, + {Class::Lib_AudioOut, nullptr}, + {Class::Lib_AvPlayer, nullptr}, + {Class::Lib_Camera, nullptr}, + {Class::Lib_CommonDlg, nullptr}, + {Class::Lib_CompanionHttpd, nullptr}, + {Class::Lib_CompanionUtil, nullptr}, + {Class::Lib_ContentExport, nullptr}, + {Class::Lib_DiscMap, nullptr}, + {Class::Lib_ErrorDialog, nullptr}, + {Class::Lib_Fiber, nullptr}, + {Class::Lib_Font, nullptr}, + {Class::Lib_FontFt, nullptr}, + {Class::Lib_GameLiveStreaming, nullptr}, + {Class::Lib_GnmDriver, nullptr}, + {Class::Lib_Hmd, nullptr}, + {Class::Lib_HmdSetupDialog, nullptr}, + {Class::Lib_Http, nullptr}, + {Class::Lib_Http2, nullptr}, + {Class::Lib_Ime, nullptr}, + {Class::Lib_ImeDialog, nullptr}, + {Class::Lib_InvitationDialog, nullptr}, + {Class::Lib_Jpeg, nullptr}, + {Class::Lib_Kernel, nullptr}, + {Class::Lib_LibcInternal, nullptr}, + {Class::Lib_Mouse, nullptr}, + {Class::Lib_Move, nullptr}, + {Class::Lib_MsgDlg, nullptr}, + {Class::Lib_Net, nullptr}, + {Class::Lib_NetCtl, nullptr}, + {Class::Lib_Ngs2, nullptr}, + {Class::Lib_NpAuth, nullptr}, + {Class::Lib_NpCommerce, nullptr}, + {Class::Lib_NpCommon, nullptr}, + {Class::Lib_NpManager, nullptr}, + {Class::Lib_NpMatching2, nullptr}, + {Class::Lib_NpSignaling, nullptr}, + {Class::Lib_NpPartner, nullptr}, + {Class::Lib_NpParty, nullptr}, + {Class::Lib_NpProfileDialog, nullptr}, + {Class::Lib_NpScore, nullptr}, + {Class::Lib_NpSnsFacebookDialog, nullptr}, + {Class::Lib_NpTrophy, nullptr}, + {Class::Lib_NpTus, nullptr}, + {Class::Lib_NpUtility, nullptr}, + {Class::Lib_NpWebApi, nullptr}, + {Class::Lib_NpWebApi2, nullptr}, + {Class::Lib_Pad, nullptr}, + {Class::Lib_PlayGo, nullptr}, + {Class::Lib_PlayGoDialog, nullptr}, + {Class::Lib_Png, nullptr}, + {Class::Lib_Random, nullptr}, + {Class::Lib_RazorCpu, nullptr}, + {Class::Lib_Remoteplay, nullptr}, + {Class::Lib_Rtc, nullptr}, + {Class::Lib_Rudp, nullptr}, + {Class::Lib_SaveData, nullptr}, + {Class::Lib_SaveDataDialog, nullptr}, + {Class::Lib_Screenshot, nullptr}, + {Class::Lib_SharePlay, nullptr}, + {Class::Lib_SigninDialog, nullptr}, + {Class::Lib_Ssl, nullptr}, + {Class::Lib_Ssl2, nullptr}, + {Class::Lib_SysModule, nullptr}, + {Class::Lib_SystemGesture, nullptr}, + {Class::Lib_SystemService, nullptr}, + {Class::Lib_Usbd, nullptr}, + {Class::Lib_UserService, nullptr}, + {Class::Lib_Vdec2, nullptr}, + {Class::Lib_Vdecsw, nullptr}, + {Class::Lib_VideoOut, nullptr}, + {Class::Lib_Videodec, nullptr}, + {Class::Lib_VideoRecording, nullptr}, + {Class::Lib_Voice, nullptr}, + {Class::Lib_VrTracker, nullptr}, + {Class::Lib_WebBrowserDialog, nullptr}, + {Class::Lib_Zlib, nullptr}, + {Class::Loader, nullptr}, + {Class::Log, nullptr}, + {Class::NpHandler, nullptr}, + {Class::Render, nullptr}, + {Class::Render_Recompiler, nullptr}, + {Class::Render_Vulkan, nullptr}, + {Class::ShadNet, nullptr}, + {Class::Tty, nullptr}, +}; + +template +static auto UpdateColorLevels(T sink) { +#ifdef _WIN32 + using LogColor = std::uint16_t; + + const auto Grey = FOREGROUND_INTENSITY; + const auto Cyan = FOREGROUND_GREEN | FOREGROUND_BLUE; + const auto Bright_gray = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + const auto Bright_yellow = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; + const auto Bright_red = FOREGROUND_RED | FOREGROUND_INTENSITY; + const auto Bright_magenta = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; +#else + using LogColor = std::string_view; + +#define ESC "\x1b" + const auto Grey = ESC "[1;30m"; + const auto Cyan = ESC "[0;36m"; + const auto Bright_gray = ESC "[0;37m"; + const auto Bright_yellow = ESC "[1;33m"; + const auto Bright_red = ESC "[1;31m"; + const auto Bright_magenta = ESC "[1;35m"; +#undef ESC +#endif + + const std::unordered_map colors{ + {spdlog::level::trace, Grey}, {spdlog::level::debug, Cyan}, + {spdlog::level::info, Bright_gray}, {spdlog::level::warn, Bright_yellow}, + {spdlog::level::err, Bright_red}, {spdlog::level::critical, Bright_magenta}}; + + for (const auto& [level, color] : colors) { + sink->set_color(level, color); + } + + return sink; +} + +void Setup(std::string_view shadps4_filename) { + static std::once_flag already_registered; + + std::call_once(already_registered, []() { + std::atexit(Shutdown); + std::at_quick_exit(Flush); + }); + + for (auto& [name, logger] : ALL_LOGGERS) { + logger = std::make_shared(std::string(name)); + logger->set_level(spdlog::level::trace); + } + + // Setup console + +#ifdef _WIN32 + if (EmulatorSettings.GetLogType() == "wincolor") { + g_console_sink = std::make_shared(); + } else { + g_console_sink = std::make_shared(); + } + +#else + g_console_sink = UpdateColorLevels(std::make_shared(spdlog::color_mode::always)); +#endif + + g_console_sink->set_pattern("%^%v%$"); + + // Setup file + + g_shad_file_sink = std::make_shared( + (GetUserPath(Common::FS::PathType::LogDir) / shadps4_filename).string(), false, + EmulatorSettings.GetLogSizeLimit()); + g_shad_file_sink->set_pattern("%^%v%$"); + + UpdateSinks(); +} + +void Switch(std::string_view game_filename) { + UpdateSinks(); + UpdateLogLevels(EmulatorSettings.GetLogFilter()); + UpdateLogFlushLevel(EmulatorSettings.GetLogFlushLevel()); + + g_shad_file_sink->_size_limit = EmulatorSettings.GetLogSizeLimit(); + g_shad_file_sink->session_file_helper_.open( + (GetUserPath(Common::FS::PathType::LogDir) / game_filename).string(), !g_should_append); +} + +void Shutdown() { + for (auto& logger : ALL_LOGGERS | std::views::values) { + logger.reset(); + } + + g_shad_file_sink.reset(); + g_console_sink.reset(); +} + +void Flush() { + if (g_shad_file_sink != nullptr) { + g_shad_file_sink->flush(); + } + + if (g_console_sink != nullptr) { + g_console_sink->flush(); + } +} + +void UpdateSinks() { + std::initializer_list sinks{g_console_sink, g_shad_file_sink}; + + std::initializer_list async_sink{std::make_shared( + spdlog::sinks::async_sink::config{.sinks = sinks})}; + + std::initializer_list dup_filter{ + std::make_shared( + std::chrono::milliseconds(EmulatorSettings.GetLogMaxSkipDuration()), + EmulatorSettings.IsLogSync() ? sinks : async_sink)}; + + for (auto& [name, logger] : ALL_LOGGERS) { + logger->sinks() = EmulatorSettings.IsLogSkipDuplicate() + ? dup_filter + : (EmulatorSettings.IsLogSync() ? sinks : async_sink); + } +} + +void UpdateLogLevels(std::string_view log_filter) { + spdlog::level default_log_level = spdlog::level::info; + std::unordered_map log_level_per_class; + + if (EmulatorSettings.IsLogEnable()) { + for (const auto class_level : std::views::split(log_filter, ' ')) { + const auto class_level_pair = + std::views::split(class_level, ':') | std::ranges::to>(); + + if (class_level_pair.size() != 2) { + LOG_ERROR(Config, "bad log filter provided"); + continue; + } + + if (class_level_pair.front()[0] == '*') { + default_log_level = spdlog::level_from_str(class_level_pair.back() | + std::ranges::to()); + } else { + log_level_per_class[class_level_pair.front() | std::ranges::to()] = + spdlog::level_from_str(class_level_pair.back() | + std::ranges::to()); + } + } + } + + for (auto& [name, logger] : ALL_LOGGERS) { + if (EmulatorSettings.IsLogEnable()) { + const auto level_it = log_level_per_class.find(std::string(name)); + + logger->set_level(level_it != log_level_per_class.end() ? level_it->second + : default_log_level); + } else { + logger->set_level(spdlog::level::off); + } + } +} + +void UpdateLogFlushLevel(std::string_view log_flush_level) { + if (!log_flush_level.empty()) { + for (auto& [name, logger] : ALL_LOGGERS) { + logger->flush_on(spdlog::level_from_str(log_flush_level.data())); + } + } +} +} // namespace Common::Log diff --git a/gpu/shadps4/common/logging/log.h b/gpu/shadps4/common/logging/log.h new file mode 100644 index 0000000..8fa3096 --- /dev/null +++ b/gpu/shadps4/common/logging/log.h @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +using spdlog_stdout = spdlog::sinks::sink; +#else +using spdlog_stdout = spdlog::sinks::stdout_color_sink_mt; +#endif +#include + +#include "common/logging/classes.h" +#include "common/path_util.h" +#include "common/thread.h" + +namespace Common::Log { +extern bool g_should_append; +extern std::unordered_map> ALL_LOGGERS; + +void Setup(std::string_view shadps4_filename); + +void Switch(std::string_view game_filename); + +void Shutdown(); + +void Flush(); + +void Terminate(); + +void UpdateSinks(); + +void UpdateLogLevels(std::string_view log_filter); +void UpdateLogFlushLevel(std::string_view log_flush_level); + +static constexpr std::array level_string_views{"Trace", "Debug", "Info", "Warning", + "Error", "Critical", "Off"}; + +[[nodiscard]] static constexpr std::string_view to_string_view(spdlog::level lvl) noexcept { + return level_string_views.at(level_to_number(lvl)); +} +} // namespace Common::Log + +// Define the fmt lib macros +#define LOG_GENERIC(log_class, log_level, format, ...) \ + do { \ + if (auto logger = Common::Log::ALL_LOGGERS[log_class]; \ + logger && logger->should_log(log_level)) { \ + logger->log(log_level, "[{}] <{}> ({}) {}:{} {}: " format, log_class, \ + Common::Log::to_string_view(log_level), Common::GetCurrentThreadName(), \ + spdlog::source_loc::basename(__FILE__), __LINE__, \ + std::string_view(__func__) == "operator()" ? "lambda" : __func__, \ + ##__VA_ARGS__); \ + } \ + } while (false) + +#ifdef NDEBUG +#define LOG_TRACE(log_class, ...) (void(0)) +#else +#define LOG_TRACE(log_class, ...) \ + LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::trace, __VA_ARGS__) +#endif + +#define LOG_DEBUG(log_class, ...) \ + LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::debug, __VA_ARGS__) +#define LOG_INFO(log_class, ...) \ + LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::info, __VA_ARGS__) +#define LOG_WARNING(log_class, ...) \ + LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::warn, __VA_ARGS__) +#define LOG_ERROR(log_class, ...) \ + LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::err, __VA_ARGS__) +#define LOG_CRITICAL(log_class, ...) \ + LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::critical, __VA_ARGS__) diff --git a/gpu/shadps4/common/logging/log_file_sink.h b/gpu/shadps4/common/logging/log_file_sink.h new file mode 100644 index 0000000..5d6505a --- /dev/null +++ b/gpu/shadps4/common/logging/log_file_sink.h @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Common::Log { +static constexpr unsigned long long UNLIMITED_SIZE = 0; + +/* + * Trivial file sink with two files as target : main and session + */ +class LogFileSink final : public spdlog::sinks::base_sink { +public: + explicit LogFileSink(const spdlog::filename_t& main_filename, bool truncate = false, + unsigned long long size_limit = UNLIMITED_SIZE) + : _size_limit{size_limit} { + main_file_helper_.open(main_filename, truncate); + } + + spdlog::details::file_helper main_file_helper_; + spdlog::details::file_helper session_file_helper_; + + unsigned long long _size_limit; + +protected: + void sink_it_(const spdlog::details::log_msg& msg) override { + spdlog::memory_buf_t formatted; + this->formatter_->format(msg, formatted); + + if (session_file_helper_.filename().empty()) { + // always log in the main file, it shouldnt be too big + main_file_helper_.write(formatted); + } else if (_current_size < _size_limit || msg.log_level == spdlog::level::critical) { + session_file_helper_.write(formatted); + _current_size += formatted.size(); + } + } + + void flush_() override { + main_file_helper_.flush(); + session_file_helper_.flush(); + } + + unsigned long long _current_size = 0; +}; +} // namespace Common::Log diff --git a/gpu/shadps4/common/lru_cache.h b/gpu/shadps4/common/lru_cache.h new file mode 100644 index 0000000..4204fad --- /dev/null +++ b/gpu/shadps4/common/lru_cache.h @@ -0,0 +1,135 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/types.h" + +namespace Common { + +template +class LeastRecentlyUsedCache { + struct Item { + ObjectType obj; + TickType tick; + Item* next{}; + Item* prev{}; + }; + +public: + LeastRecentlyUsedCache() : first_item{}, last_item{} {} + ~LeastRecentlyUsedCache() = default; + + size_t Insert(ObjectType obj, TickType tick) { + const auto new_id = Build(); + auto& item = item_pool[new_id]; + item.obj = obj; + item.tick = tick; + Attach(item); + return new_id; + } + + void Touch(size_t id, TickType tick) { + auto& item = item_pool[id]; + if (item.tick >= tick) { + return; + } + item.tick = tick; + if (&item == last_item) { + return; + } + Detach(item); + Attach(item); + } + + void Free(size_t id) { + auto& item = item_pool[id]; + Detach(item); + item.prev = nullptr; + item.next = nullptr; + free_items.push_back(id); + } + + template + void ForEachItemBelow(TickType tick, Func&& func) { + static constexpr bool RETURNS_BOOL = + std::is_same_v, bool>; + Item* iterator = first_item; + while (iterator) { + if (static_cast(tick) - static_cast(iterator->tick) < 0) { + return; + } + Item* next = iterator->next; + if constexpr (RETURNS_BOOL) { + if (func(iterator->obj)) { + return; + } + } else { + func(iterator->obj); + } + iterator = next; + } + } + +private: + size_t Build() { + if (free_items.empty()) { + const size_t item_id = item_pool.size(); + auto& item = item_pool.emplace_back(); + item.next = nullptr; + item.prev = nullptr; + return item_id; + } + const size_t item_id = free_items.front(); + free_items.pop_front(); + auto& item = item_pool[item_id]; + item.next = nullptr; + item.prev = nullptr; + return item_id; + } + + void Attach(Item& item) { + if (!first_item) { + first_item = &item; + } + if (!last_item) { + last_item = &item; + } else { + item.prev = last_item; + last_item->next = &item; + item.next = nullptr; + last_item = &item; + } + } + + void Detach(Item& item) { + if (item.prev) { + item.prev->next = item.next; + } + if (item.next) { + item.next->prev = item.prev; + } + if (&item == first_item) { + first_item = item.next; + if (first_item) { + first_item->prev = nullptr; + } + } + if (&item == last_item) { + last_item = item.prev; + if (last_item) { + last_item->next = nullptr; + } + } + } + + std::deque item_pool; + std::deque free_items; + Item* first_item{}; + Item* last_item{}; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/memory_patcher.cpp b/gpu/shadps4/common/memory_patcher.cpp new file mode 100644 index 0000000..862fd6b --- /dev/null +++ b/gpu/shadps4/common/memory_patcher.cpp @@ -0,0 +1,460 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include +#include +#include "common/elf_info.h" +#include "common/logging/log.h" +#include "common/path_util.h" +#include "core/emulator_state.h" +#include "core/file_format/psf.h" +#include "memory_patcher.h" + +namespace MemoryPatcher { + +EXPORT uintptr_t g_eboot_address; +uint64_t g_eboot_image_size; +std::string g_game_serial; +std::string patch_file; +bool patches_applied = false; +std::vector pending_patches; + +std::string toHex(u64 value, size_t byteSize) { + std::stringstream ss; + ss << std::hex << std::setfill('0') << std::setw(byteSize * 2) << value; + return ss.str(); +} + +static bool isHexSym(const std::string& s) { + return (s.size() >= 2 && (s[0] == '$' || s[0] == '#')); +} + +static bool isHex0x(const std::string& s) { + return (s.size() >= 3 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')); +} + +// possible prefixes == (s == `0x` || s == `#` || s == `$`) will be interpet as hex value, else is +// decimal +static int convertNumBase(const std::string& s) { + return (isHex0x(s) || isHexSym(s)) ? 16 : 10; +} + +std::string convertValueToHex(const std::string type, const std::string valueStr) { + std::string result; + + if (type == "byte") { + const u32 value = std::stoul(valueStr, nullptr, convertNumBase(valueStr)); + result = toHex(value, 1); + } else if (type == "bytes16") { + const u32 value = std::stoul(valueStr, nullptr, convertNumBase(valueStr)); + result = toHex(value, 2); + } else if (type == "bytes32") { + const u32 value = std::stoul(valueStr, nullptr, convertNumBase(valueStr)); + result = toHex(value, 4); + } else if (type == "bytes64") { + const u64 value = std::stoull(valueStr, nullptr, convertNumBase(valueStr)); + result = toHex(value, 8); + } else if (type == "float32") { + union { + float f; + uint32_t i; + } floatUnion; + floatUnion.f = std::stof(valueStr); + result = toHex(std::byteswap(floatUnion.i), sizeof(floatUnion.i)); + } else if (type == "float64") { + union { + double d; + uint64_t i; + } doubleUnion; + doubleUnion.d = std::stod(valueStr); + result = toHex(std::byteswap(doubleUnion.i), sizeof(doubleUnion.i)); + } else if (type == "utf8") { + std::vector byteArray = + std::vector(valueStr.begin(), valueStr.end()); + byteArray.push_back('\0'); + std::stringstream ss; + for (unsigned char c : byteArray) { + ss << std::hex << std::setfill('0') << std::setw(2) << static_cast(c); + } + result = ss.str(); + } else if (type == "utf16") { + std::wstring wide_str(valueStr.size(), L'\0'); + std::mbstowcs(&wide_str[0], valueStr.c_str(), valueStr.size()); + wide_str.resize(std::wcslen(wide_str.c_str())); + + std::u16string valueStringU16; + + for (wchar_t wc : wide_str) { + if (wc <= 0xFFFF) { + valueStringU16.push_back(static_cast(wc)); + } else { + wc -= 0x10000; + valueStringU16.push_back(static_cast(0xD800 | (wc >> 10))); + valueStringU16.push_back(static_cast(0xDC00 | (wc & 0x3FF))); + } + } + + std::vector byteArray; + // convert to little endian + for (char16_t ch : valueStringU16) { + unsigned char low_byte = static_cast(ch & 0x00FF); + unsigned char high_byte = static_cast((ch >> 8) & 0x00FF); + + byteArray.push_back(low_byte); + byteArray.push_back(high_byte); + } + byteArray.push_back('\0'); + byteArray.push_back('\0'); + std::stringstream ss; + + for (unsigned char ch : byteArray) { + ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(ch); + } + result = ss.str(); + } else if (type == "bytes") { + result = valueStr; + } else if (type == "mask" || type == "mask_jump32") { + result = valueStr; + } else { + LOG_INFO(Loader, "Error applying Patch, unknown type: {}", type); + } + return result; +} + +void ApplyPendingPatches(); + +void ApplyPatchesFromXML(std::filesystem::path path) { + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(path.c_str()); + + auto* param_sfo = Common::Singleton::Instance(); + auto app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); + + if (result) { + auto patchXML = doc.child("Patch"); + for (pugi::xml_node_iterator it = patchXML.children().begin(); + it != patchXML.children().end(); ++it) { + + if (std::string(it->name()) == "Metadata") { + if (std::string(it->attribute("isEnabled").value()) == "true") { + std::string currentPatchName = it->attribute("Name").value(); + std::string metadataAppVer = it->attribute("AppVer").value(); + bool versionMatches = metadataAppVer == app_version; + + auto patchList = it->first_child(); + for (pugi::xml_node_iterator patchLineIt = patchList.children().begin(); + patchLineIt != patchList.children().end(); ++patchLineIt) { + + std::string type = patchLineIt->attribute("Type").value(); + if (!versionMatches && type != "mask" && type != "mask_jump32") + continue; + + std::string address = patchLineIt->attribute("Address").value(); + std::string patchValue = patchLineIt->attribute("Value").value(); + std::string maskOffsetStr = patchLineIt->attribute("Offset").value(); + std::string targetStr = ""; + std::string sizeStr = ""; + if (type == "mask_jump32") { + targetStr = patchLineIt->attribute("Target").value(); + sizeStr = patchLineIt->attribute("Size").value(); + } else { + try { + patchValue = convertValueToHex(type, patchValue); + } catch (std::exception& e) { + ASSERT_MSG(false, + "Failed to parse patch value \"{}\" for \"{}\" in " + "patch \"{}\", error: \"{}\"\n" + "If the patch was working on earlier versions, then it " + "was using a format that shadPS4 handled incorrectly, " + "and the patch should instead be fixed.", + patchValue, address, currentPatchName, e.what()); + } + } + + bool littleEndian = false; + if (type == "bytes16" || type == "bytes32" || type == "bytes64") { + littleEndian = true; + } + + MemoryPatcher::PatchMask patchMask = MemoryPatcher::PatchMask::None; + int maskOffsetValue = 0; + + if (type == "mask") + patchMask = MemoryPatcher::PatchMask::Mask; + + if (type == "mask_jump32") + patchMask = MemoryPatcher::PatchMask::Mask_Jump32; + + if ((type == "mask" || type == "mask_jump32") && !maskOffsetStr.empty()) { + maskOffsetValue = std::stoi(maskOffsetStr, 0, 10); + } + + const patchInfo patch = { + .gameSerial = "*", + .modNameStr = currentPatchName, + .offsetStr = address, + .valueStr = patchValue, + .targetStr = targetStr, + .sizeStr = sizeStr, + .littleEndian = littleEndian, + .patchMask = patchMask, + .maskOffset = maskOffsetValue, + }; + MemoryPatcher::PatchMemory(patch); + } + } + } + } + } else { + LOG_ERROR(Loader, "Could not parse patch XML: {}", result.description()); + } +} + +void OnGameLoaded() { + std::filesystem::path patch_dir = Common::FS::GetUserPath(Common::FS::PathType::PatchesDir); + if (!patch_file.empty()) { + + auto file_path = (patch_dir / patch_file).native(); + if (std::filesystem::exists(patch_file)) { + ApplyPatchesFromXML(patch_file); + } else { + ApplyPatchesFromXML(file_path); + } + } else if (EmulatorState::GetInstance()->IsAutoPatchesLoadEnabled()) { + for (auto const& repo : std::filesystem::directory_iterator(patch_dir)) { + if (!repo.is_directory()) { + continue; + } + + const auto files_json_path = repo.path() / "files.json"; + + if (!std::filesystem::is_regular_file(files_json_path)) { + LOG_ERROR(Loader, "The folder '{}' does not contain the files.json file.", + repo.path().filename().string()); + continue; + } + + std::ifstream json_file{files_json_path}; + nlohmann::json available_patches; + + if (!json_file.is_open()) { + LOG_ERROR(Loader, "Could not open patch index: {}", files_json_path.string()); + continue; + } + + try { + available_patches = nlohmann::json::parse(json_file); + } catch (const nlohmann::json::parse_error& e) { + LOG_ERROR(Loader, "Could not parse patch index {}: {}", files_json_path.string(), + e.what()); + continue; + } + + std::filesystem::path game_patch_file; + for (auto const& [filename, serials] : available_patches.items()) { + if (std::find(serials.begin(), serials.end(), g_game_serial) != serials.end()) { + game_patch_file = repo.path() / filename; + break; + } + } + if (std::filesystem::exists(game_patch_file)) { + ApplyPatchesFromXML(game_patch_file); + } + } + } + ApplyPendingPatches(); +} + +void AddPatchToQueue(const patchInfo& patchToAdd) { + if (patches_applied) { + PatchMemory(patchToAdd); + return; + } + pending_patches.push_back(patchToAdd); +} + +void ApplyPendingPatches() { + patches_applied = true; + for (size_t i = 0; i < pending_patches.size(); ++i) { + const patchInfo& currentPatch = pending_patches[i]; + + if (currentPatch.gameSerial != "*" && currentPatch.gameSerial != g_game_serial) + continue; + + PatchMemory(currentPatch); + } + + pending_patches.clear(); +} + +void PatchMemory(const patchInfo& patch) { + // Send a request to modify the process memory. + void* cheatAddress = nullptr; + + if (patch.patchMask == PatchMask::None) { + if (patch.isOffset) { + cheatAddress = + reinterpret_cast(g_eboot_address + std::stoi(patch.offsetStr, 0, 16)); + } else { + cheatAddress = reinterpret_cast(g_eboot_address + + (std::stoi(patch.offsetStr, 0, 16) - 0x400000)); + } + } + + if (patch.patchMask == PatchMask::Mask) { + cheatAddress = reinterpret_cast(PatternScan(patch.offsetStr) + patch.maskOffset); + } + + if (patch.patchMask == PatchMask::Mask_Jump32) { + int jumpSize = std::stoi(patch.sizeStr); + + constexpr int MAX_PATTERN_LENGTH = 256; + if (jumpSize < 5) { + LOG_ERROR(Loader, "Jump size must be at least 5 bytes"); + return; + } + if (jumpSize > MAX_PATTERN_LENGTH) { + LOG_ERROR(Loader, "Jump size must be no more than {} bytes.", MAX_PATTERN_LENGTH); + return; + } + + // Find the base address using "Address" + uintptr_t baseAddress = PatternScan(patch.offsetStr); + if (baseAddress == 0) { + LOG_ERROR(Loader, "PatternScan failed for mask_jump32 with pattern: {}", + patch.offsetStr); + return; + } + uintptr_t patchAddress = baseAddress + patch.maskOffset; + + // Fills the original region (jumpSize bytes) with NOPs + std::vector nopBytes(jumpSize, 0x90); + std::memcpy(reinterpret_cast(patchAddress), nopBytes.data(), nopBytes.size()); + + // Use "Target" to locate the start of the code cave + uintptr_t jump_target = PatternScan(patch.targetStr); + if (jump_target == 0) { + LOG_ERROR(Loader, "PatternScan failed to Target with pattern: {}", patch.targetStr); + return; + } + + // Converts the Value attribute to a byte array (payload) + std::vector payload; + for (size_t i = 0; i < patch.valueStr.length(); i += 2) { + std::string tempStr = patch.valueStr.substr(i, 2); + const char* byteStr = tempStr.c_str(); + char* endPtr; + unsigned int byteVal = std::strtoul(byteStr, &endPtr, 16); + + if (endPtr != byteStr + 2) { + LOG_ERROR(Loader, "Invalid byte in Value: {}", patch.valueStr.substr(i, 2)); + return; + } + payload.push_back(static_cast(byteVal)); + } + + // Calculates the end of the code cave (where the return jump will be inserted) + uintptr_t code_cave_end = jump_target + payload.size(); + + // Write the payload to the code cave, from jump_target + std::memcpy(reinterpret_cast(jump_target), payload.data(), payload.size()); + + // Inserts the initial jump in the original region to divert to the code cave + u8 jumpInstruction[5]; + jumpInstruction[0] = 0xE9; + s32 relJump = static_cast(jump_target - patchAddress - 5); + std::memcpy(&jumpInstruction[1], &relJump, sizeof(relJump)); + std::memcpy(reinterpret_cast(patchAddress), jumpInstruction, + sizeof(jumpInstruction)); + + // Inserts jump back at the end of the code cave to resume execution after patching + u8 jumpBack[5]; + jumpBack[0] = 0xE9; + // Calculates the relative offset to return to the instruction immediately following the + // overwritten region + s32 target_return = static_cast((patchAddress + jumpSize) - (code_cave_end + 5)); + std::memcpy(&jumpBack[1], &target_return, sizeof(target_return)); + std::memcpy(reinterpret_cast(code_cave_end), jumpBack, sizeof(jumpBack)); + + LOG_INFO(Loader, + "Applied Patch mask_jump32: {}, PatchAddress: {:#x}, JumpTarget: {:#x}, " + "CodeCaveEnd: {:#x}, JumpSize: {}", + patch.modNameStr, patchAddress, jump_target, code_cave_end, jumpSize); + return; + } + + if (cheatAddress == nullptr) { + LOG_ERROR(Loader, "Failed to get address for patch {}", patch.modNameStr); + return; + } + + std::vector bytePatch; + + for (size_t i = 0; i < patch.valueStr.length(); i += 2) { + unsigned char byte = static_cast( + std::strtol(patch.valueStr.substr(i, 2).c_str(), nullptr, 16)); + + bytePatch.push_back(byte); + } + + if (patch.littleEndian) { + std::reverse(bytePatch.begin(), bytePatch.end()); + } + + std::memcpy(cheatAddress, bytePatch.data(), bytePatch.size()); + + LOG_INFO(Loader, "Applied patch: {}, Offset: {:#x}, Value: {}", patch.modNameStr, + (uintptr_t)cheatAddress, patch.valueStr); +} + +static std::vector PatternToByte(const std::string& pattern) { + std::vector bytes; + const char* start = pattern.data(); + const char* end = start + pattern.size(); + + for (const char* current = start; current < end; ++current) { + if (*current == '?') { + ++current; + if (*current == '?') + ++current; + bytes.push_back(-1); + } else { + bytes.push_back(strtoul(current, const_cast(¤t), 16)); + } + } + + return bytes; +} + +uintptr_t PatternScan(const std::string& signature) { + std::vector patternBytes = PatternToByte(signature); + const auto scanBytes = static_cast((void*)g_eboot_address); + + const int32_t* sigPtr = patternBytes.data(); + const size_t sigSize = patternBytes.size(); + + uint32_t foundResults = 0; + for (uint32_t i = 0; i < g_eboot_image_size - sigSize; ++i) { + bool found = true; + for (uint32_t j = 0; j < sigSize; ++j) { + if (scanBytes[i + j] != sigPtr[j] && sigPtr[j] != -1) { + found = false; + break; + } + } + + if (found) { + foundResults++; + return reinterpret_cast(&scanBytes[i]); + } + } + + return 0; +} + +} // namespace MemoryPatcher diff --git a/gpu/shadps4/common/memory_patcher.h b/gpu/shadps4/common/memory_patcher.h new file mode 100644 index 0000000..352bce4 --- /dev/null +++ b/gpu/shadps4/common/memory_patcher.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once +#include +#include +#include + +#if defined(WIN32) +#define EXPORT __declspec(dllexport) +#else +#define EXPORT __attribute__((visibility("default"))) +#endif + +namespace MemoryPatcher { + +extern EXPORT uintptr_t g_eboot_address; +extern uint64_t g_eboot_image_size; +extern std::string g_game_serial; +extern std::string patch_file; + +enum PatchMask : uint8_t { + None, + Mask, + Mask_Jump32, +}; + +struct patchInfo { + std::string gameSerial; + std::string modNameStr; + std::string offsetStr; + std::string valueStr; + std::string targetStr; + std::string sizeStr; + bool isOffset; + bool littleEndian; + PatchMask patchMask; + int maskOffset; +}; + +std::string convertValueToHex(const std::string type, const std::string valueStr); + +void OnGameLoaded(); +void AddPatchToQueue(const patchInfo& patchToAdd); + +void PatchMemory(const patchInfo& patch); + +static std::vector PatternToByte(const std::string& pattern); +uintptr_t PatternScan(const std::string& signature); + +} // namespace MemoryPatcher \ No newline at end of file diff --git a/gpu/shadps4/common/native_clock.cpp b/gpu/shadps4/common/native_clock.cpp new file mode 100644 index 0000000..0c05dbe --- /dev/null +++ b/gpu/shadps4/common/native_clock.cpp @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/native_clock.h" +#include "common/rdtsc.h" +#include "common/uint128.h" + +namespace Common { + +NativeClock::NativeClock() + : rdtsc_frequency{EstimateRDTSCFrequency()}, + ns_rdtsc_factor{GetFixedPoint64Factor(std::nano::den, rdtsc_frequency)}, + us_rdtsc_factor{GetFixedPoint64Factor(std::micro::den, rdtsc_frequency)}, + ms_rdtsc_factor{GetFixedPoint64Factor(std::milli::den, rdtsc_frequency)} {} + +u64 NativeClock::GetTimeNS(u64 base_ptc /*= 0*/) const { + return MultiplyHigh(GetUptime() - base_ptc, ns_rdtsc_factor); +} + +u64 NativeClock::GetTimeUS(u64 base_ptc /*= 0*/) const { + return MultiplyHigh(GetUptime() - base_ptc, us_rdtsc_factor); +} + +u64 NativeClock::GetTimeMS(u64 base_ptc /*= 0*/) const { + return MultiplyHigh(GetUptime() - base_ptc, ms_rdtsc_factor); +} + +u64 NativeClock::GetUptime() const { + return FencedRDTSC(); +} + +} // namespace Common diff --git a/gpu/shadps4/common/native_clock.h b/gpu/shadps4/common/native_clock.h new file mode 100644 index 0000000..1542c2f --- /dev/null +++ b/gpu/shadps4/common/native_clock.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace Common { + +class NativeClock final { +public: + explicit NativeClock(); + + u64 GetTscFrequency() const { + return rdtsc_frequency; + } + + u64 GetTimeNS(u64 base_ptc = 0) const; + u64 GetTimeUS(u64 base_ptc = 0) const; + u64 GetTimeMS(u64 base_ptc = 0) const; + u64 GetUptime() const; + +private: + u64 rdtsc_frequency; + u64 ns_rdtsc_factor; + u64 us_rdtsc_factor; + u64 ms_rdtsc_factor; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/ntapi.cpp b/gpu/shadps4/common/ntapi.cpp new file mode 100644 index 0000000..46ec57e --- /dev/null +++ b/gpu/shadps4/common/ntapi.cpp @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifdef _WIN32 + +#include "ntapi.h" + +NtClose_t NtClose = nullptr; +NtSetInformationFile_t NtSetInformationFile = nullptr; +NtCreateThread_t NtCreateThread = nullptr; +NtTerminateThread_t NtTerminateThread = nullptr; +NtQueueApcThreadEx_t NtQueueApcThreadEx = nullptr; + +namespace Common::NtApi { + +void Initialize() { + HMODULE nt_handle = GetModuleHandleA("ntdll.dll"); + + // http://stackoverflow.com/a/31411628/4725495 + NtClose = (NtClose_t)GetProcAddress(nt_handle, "NtClose"); + NtSetInformationFile = + (NtSetInformationFile_t)GetProcAddress(nt_handle, "NtSetInformationFile"); + NtCreateThread = (NtCreateThread_t)GetProcAddress(nt_handle, "NtCreateThread"); + NtTerminateThread = (NtTerminateThread_t)GetProcAddress(nt_handle, "NtTerminateThread"); + NtQueueApcThreadEx = (NtQueueApcThreadEx_t)GetProcAddress(nt_handle, "NtQueueApcThreadEx"); +} + +} // namespace Common::NtApi + +#endif diff --git a/gpu/shadps4/common/ntapi.h b/gpu/shadps4/common/ntapi.h new file mode 100644 index 0000000..c876af5 --- /dev/null +++ b/gpu/shadps4/common/ntapi.h @@ -0,0 +1,554 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#ifdef _WIN32 + +#include +#include "common/types.h" + +typedef enum _FILE_INFORMATION_CLASS { + FileDirectoryInformation = 1, + FileFullDirectoryInformation = 2, + FileBothDirectoryInformation = 3, + FileBasicInformation = 4, + FileStandardInformation = 5, + FileInternalInformation = 6, + FileEaInformation = 7, + FileAccessInformation = 8, + FileNameInformation = 9, + FileRenameInformation = 10, + FileLinkInformation = 11, + FileNamesInformation = 12, + FileDispositionInformation = 13, + FilePositionInformation = 14, + FileFullEaInformation = 15, + FileModeInformation = 16, + FileAlignmentInformation = 17, + FileAllInformation = 18, + FileAllocationInformation = 19, + FileEndOfFileInformation = 20, + FileAlternateNameInformation = 21, + FileStreamInformation = 22, + FilePipeInformation = 23, + FilePipeLocalInformation = 24, + FilePipeRemoteInformation = 25, + FileMailslotQueryInformation = 26, + FileMailslotSetInformation = 27, + FileCompressionInformation = 28, + FileObjectIdInformation = 29, + FileCompletionInformation = 30, + FileMoveClusterInformation = 31, + FileQuotaInformation = 32, + FileReparsePointInformation = 33, + FileNetworkOpenInformation = 34, + FileAttributeTagInformation = 35, + FileTrackingInformation = 36, + FileIdBothDirectoryInformation = 37, + FileIdFullDirectoryInformation = 38, + FileValidDataLengthInformation = 39, + FileShortNameInformation = 40, + FileIoCompletionNotificationInformation = 41, + FileIoStatusBlockRangeInformation = 42, + FileIoPriorityHintInformation = 43, + FileSfioReserveInformation = 44, + FileSfioVolumeInformation = 45, + FileHardLinkInformation = 46, + FileProcessIdsUsingFileInformation = 47, + FileNormalizedNameInformation = 48, + FileNetworkPhysicalNameInformation = 49, + FileIdGlobalTxDirectoryInformation = 50, + FileIsRemoteDeviceInformation = 51, + FileUnusedInformation = 52, + FileNumaNodeInformation = 53, + FileStandardLinkInformation = 54, + FileRemoteProtocolInformation = 55, + FileRenameInformationBypassAccessCheck = 56, + FileLinkInformationBypassAccessCheck = 57, + FileVolumeNameInformation = 58, + FileIdInformation = 59, + FileIdExtdDirectoryInformation = 60, + FileReplaceCompletionInformation = 61, + FileHardLinkFullIdInformation = 62, + FileIdExtdBothDirectoryInformation = 63, + FileDispositionInformationEx = 64, + FileRenameInformationEx = 65, + FileRenameInformationExBypassAccessCheck = 66, + FileDesiredStorageClassInformation = 67, + FileStatInformation = 68, + FileMemoryPartitionInformation = 69, + FileStatLxInformation = 70, + FileCaseSensitiveInformation = 71, + FileLinkInformationEx = 72, + FileLinkInformationExBypassAccessCheck = 73, + FileStorageReserveIdInformation = 74, + FileCaseSensitiveInformationForceAccessCheck = 75, + FileKnownFolderInformation = 76, + FileStatBasicInformation = 77, + FileId64ExtdDirectoryInformation = 78, + FileId64ExtdBothDirectoryInformation = 79, + FileIdAllExtdDirectoryInformation = 80, + FileIdAllExtdBothDirectoryInformation = 81, + FileStreamReservationInformation, + FileMupProviderInfo, + FileMaximumInformation +} FILE_INFORMATION_CLASS, + *PFILE_INFORMATION_CLASS; + +typedef struct _IO_STATUS_BLOCK { + union { + u32 Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +typedef struct _FILE_DISPOSITION_INFORMATION { + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWCH Buffer; +} UNICODE_STRING, *PUNICODE_STRING; + +typedef const UNICODE_STRING* PCUNICODE_STRING; + +typedef struct _OBJECT_ATTRIBUTES { + ULONG Length; + HANDLE RootDirectory; + PCUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR; + PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE +} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; + +typedef const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES; + +typedef struct _CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, *PCLIENT_ID; + +typedef struct _INITIAL_TEB { + struct { + PVOID OldStackBase; + PVOID OldStackLimit; + } OldInitialTeb; + PVOID StackBase; + PVOID StackLimit; + PVOID StackAllocationBase; +} INITIAL_TEB, *PINITIAL_TEB; + +typedef struct _PEB_LDR_DATA { + ULONG Length; + BOOLEAN Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID EntryInProgress; + BOOLEAN ShutdownInProgress; + HANDLE ShutdownThreadId; +} PEB_LDR_DATA, *PPEB_LDR_DATA; + +typedef struct _CURDIR { + UNICODE_STRING DosPath; + PVOID Handle; +} CURDIR, *PCURDIR; + +typedef struct RTL_DRIVE_LETTER_CURDIR { + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + UNICODE_STRING DosPath; +} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; + +typedef struct _RTL_USER_PROCESS_PARAMETERS { + ULONG AllocationSize; + ULONG Size; + ULONG Flags; + ULONG DebugFlags; + HANDLE ConsoleHandle; + ULONG ConsoleFlags; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + CURDIR CurrentDirectory; + UNICODE_STRING DllPath; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; + PWSTR Environment; + ULONG dwX; + ULONG dwY; + ULONG dwXSize; + ULONG dwYSize; + ULONG dwXCountChars; + ULONG dwYCountChars; + ULONG dwFillAttribute; + ULONG dwFlags; + ULONG wShowWindow; + UNICODE_STRING WindowTitle; + UNICODE_STRING Desktop; + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeInfo; + RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; + ULONG_PTR EnvironmentSize; + ULONG_PTR EnvironmentVersion; + PVOID PackageDependencyData; + ULONG ProcessGroupId; + ULONG LoaderThreads; +} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; + +typedef struct tagRTL_BITMAP { + ULONG SizeOfBitMap; + PULONG Buffer; +} RTL_BITMAP, *PRTL_BITMAP; + +typedef struct { + UINT next; + UINT id; + ULONGLONG addr; + ULONGLONG size; + UINT args[4]; +} CROSS_PROCESS_WORK_ENTRY; + +typedef union { + struct { + UINT first; + UINT counter; + }; + volatile LONGLONG hdr; +} CROSS_PROCESS_WORK_HDR; + +typedef struct { + CROSS_PROCESS_WORK_HDR free_list; + CROSS_PROCESS_WORK_HDR work_list; + ULONGLONG unknown[4]; + CROSS_PROCESS_WORK_ENTRY entries[1]; +} CROSS_PROCESS_WORK_LIST; + +typedef struct _CHPEV2_PROCESS_INFO { + ULONG Wow64ExecuteFlags; /* 000 */ + USHORT NativeMachineType; /* 004 */ + USHORT EmulatedMachineType; /* 006 */ + HANDLE SectionHandle; /* 008 */ + CROSS_PROCESS_WORK_LIST* CrossProcessWorkList; /* 010 */ + void* unknown; /* 018 */ +} CHPEV2_PROCESS_INFO, *PCHPEV2_PROCESS_INFO; + +typedef u64(__stdcall* KERNEL_CALLBACK_PROC)(void*, ULONG); + +typedef struct _PEB { /* win32/win64 */ + BOOLEAN InheritedAddressSpace; /* 000/000 */ + BOOLEAN ReadImageFileExecOptions; /* 001/001 */ + BOOLEAN BeingDebugged; /* 002/002 */ + UCHAR ImageUsedLargePages : 1; /* 003/003 */ + UCHAR IsProtectedProcess : 1; + UCHAR IsImageDynamicallyRelocated : 1; + UCHAR SkipPatchingUser32Forwarders : 1; + UCHAR IsPackagedProcess : 1; + UCHAR IsAppContainer : 1; + UCHAR IsProtectedProcessLight : 1; + UCHAR IsLongPathAwareProcess : 1; + HANDLE Mutant; /* 004/008 */ + HMODULE ImageBaseAddress; /* 008/010 */ + PPEB_LDR_DATA LdrData; /* 00c/018 */ + RTL_USER_PROCESS_PARAMETERS* ProcessParameters; /* 010/020 */ + PVOID SubSystemData; /* 014/028 */ + HANDLE ProcessHeap; /* 018/030 */ + PRTL_CRITICAL_SECTION FastPebLock; /* 01c/038 */ + PVOID AtlThunkSListPtr; /* 020/040 */ + PVOID IFEOKey; /* 024/048 */ + ULONG ProcessInJob : 1; /* 028/050 */ + ULONG ProcessInitializing : 1; + ULONG ProcessUsingVEH : 1; + ULONG ProcessUsingVCH : 1; + ULONG ProcessUsingFTH : 1; + ULONG ProcessPreviouslyThrottled : 1; + ULONG ProcessCurrentlyThrottled : 1; + ULONG ProcessImagesHotPatched : 1; + ULONG ReservedBits0 : 24; + KERNEL_CALLBACK_PROC* KernelCallbackTable; /* 02c/058 */ + ULONG Reserved; /* 030/060 */ + ULONG AtlThunkSListPtr32; /* 034/064 */ + PVOID ApiSetMap; /* 038/068 */ + ULONG TlsExpansionCounter; /* 03c/070 */ + PRTL_BITMAP TlsBitmap; /* 040/078 */ + ULONG TlsBitmapBits[2]; /* 044/080 */ + PVOID ReadOnlySharedMemoryBase; /* 04c/088 */ + PVOID SharedData; /* 050/090 */ + PVOID* ReadOnlyStaticServerData; /* 054/098 */ + PVOID AnsiCodePageData; /* 058/0a0 */ + PVOID OemCodePageData; /* 05c/0a8 */ + PVOID UnicodeCaseTableData; /* 060/0b0 */ + ULONG NumberOfProcessors; /* 064/0b8 */ + ULONG NtGlobalFlag; /* 068/0bc */ + LARGE_INTEGER CriticalSectionTimeout; /* 070/0c0 */ + SIZE_T HeapSegmentReserve; /* 078/0c8 */ + SIZE_T HeapSegmentCommit; /* 07c/0d0 */ + SIZE_T HeapDeCommitTotalFreeThreshold; /* 080/0d8 */ + SIZE_T HeapDeCommitFreeBlockThreshold; /* 084/0e0 */ + ULONG NumberOfHeaps; /* 088/0e8 */ + ULONG MaximumNumberOfHeaps; /* 08c/0ec */ + PVOID* ProcessHeaps; /* 090/0f0 */ + PVOID GdiSharedHandleTable; /* 094/0f8 */ + PVOID ProcessStarterHelper; /* 098/100 */ + PVOID GdiDCAttributeList; /* 09c/108 */ + PVOID LoaderLock; /* 0a0/110 */ + ULONG OSMajorVersion; /* 0a4/118 */ + ULONG OSMinorVersion; /* 0a8/11c */ + ULONG OSBuildNumber; /* 0ac/120 */ + ULONG OSPlatformId; /* 0b0/124 */ + ULONG ImageSubSystem; /* 0b4/128 */ + ULONG ImageSubSystemMajorVersion; /* 0b8/12c */ + ULONG ImageSubSystemMinorVersion; /* 0bc/130 */ + KAFFINITY ActiveProcessAffinityMask; /* 0c0/138 */ +#ifdef _WIN64 + ULONG GdiHandleBuffer[60]; /* /140 */ +#else + ULONG GdiHandleBuffer[34]; /* 0c4/ */ +#endif + PVOID PostProcessInitRoutine; /* 14c/230 */ + PRTL_BITMAP TlsExpansionBitmap; /* 150/238 */ + ULONG TlsExpansionBitmapBits[32]; /* 154/240 */ + ULONG SessionId; /* 1d4/2c0 */ + ULARGE_INTEGER AppCompatFlags; /* 1d8/2c8 */ + ULARGE_INTEGER AppCompatFlagsUser; /* 1e0/2d0 */ + PVOID ShimData; /* 1e8/2d8 */ + PVOID AppCompatInfo; /* 1ec/2e0 */ + UNICODE_STRING CSDVersion; /* 1f0/2e8 */ + PVOID ActivationContextData; /* 1f8/2f8 */ + PVOID ProcessAssemblyStorageMap; /* 1fc/300 */ + PVOID SystemDefaultActivationData; /* 200/308 */ + PVOID SystemAssemblyStorageMap; /* 204/310 */ + SIZE_T MinimumStackCommit; /* 208/318 */ + PVOID* FlsCallback; /* 20c/320 */ + LIST_ENTRY FlsListHead; /* 210/328 */ + union { + PRTL_BITMAP FlsBitmap; /* 218/338 */ +#ifdef _WIN64 + CHPEV2_PROCESS_INFO* ChpeV2ProcessInfo; /* /338 */ +#endif + }; + ULONG FlsBitmapBits[4]; /* 21c/340 */ + ULONG FlsHighIndex; /* 22c/350 */ + PVOID WerRegistrationData; /* 230/358 */ + PVOID WerShipAssertPtr; /* 234/360 */ + PVOID EcCodeBitMap; /* 238/368 */ + PVOID pImageHeaderHash; /* 23c/370 */ + ULONG HeapTracingEnabled : 1; /* 240/378 */ + ULONG CritSecTracingEnabled : 1; + ULONG LibLoaderTracingEnabled : 1; + ULONG SpareTracingBits : 29; + ULONGLONG CsrServerReadOnlySharedMemoryBase; /* 248/380 */ + ULONG TppWorkerpListLock; /* 250/388 */ + LIST_ENTRY TppWorkerpList; /* 254/390 */ + PVOID WaitOnAddressHashTable[0x80]; /* 25c/3a0 */ + PVOID TelemetryCoverageHeader; /* 45c/7a0 */ + ULONG CloudFileFlags; /* 460/7a8 */ + ULONG CloudFileDiagFlags; /* 464/7ac */ + CHAR PlaceholderCompatibilityMode; /* 468/7b0 */ + CHAR PlaceholderCompatibilityModeReserved[7]; /* 469/7b1 */ + PVOID LeapSecondData; /* 470/7b8 */ + ULONG LeapSecondFlags; /* 474/7c0 */ + ULONG NtGlobalFlag2; /* 478/7c4 */ +} PEB, *PPEB; + +typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME { + struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous; + struct _ACTIVATION_CONTEXT* ActivationContext; + ULONG Flags; +} RTL_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME; + +typedef struct _ACTIVATION_CONTEXT_STACK { + RTL_ACTIVATION_CONTEXT_STACK_FRAME* ActiveFrame; + LIST_ENTRY FrameListCache; + ULONG Flags; + ULONG NextCookieSequenceNumber; + ULONG_PTR StackId; +} ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK; + +typedef struct _GDI_TEB_BATCH { + ULONG Offset; + HANDLE HDC; + ULONG Buffer[0x136]; +} GDI_TEB_BATCH; + +typedef struct _TEB_ACTIVE_FRAME_CONTEXT { + ULONG Flags; + const char* FrameName; +} TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT; + +typedef struct _TEB_ACTIVE_FRAME { + ULONG Flags; + struct _TEB_ACTIVE_FRAME* Previous; + TEB_ACTIVE_FRAME_CONTEXT* Context; +} TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME; + +typedef struct _TEB { /* win32/win64 */ + NT_TIB Tib; /* 000/0000 */ + PVOID EnvironmentPointer; /* 01c/0038 */ + CLIENT_ID ClientId; /* 020/0040 */ + PVOID ActiveRpcHandle; /* 028/0050 */ + PVOID ThreadLocalStoragePointer; /* 02c/0058 */ + PPEB Peb; /* 030/0060 */ + ULONG LastErrorValue; /* 034/0068 */ + ULONG CountOfOwnedCriticalSections; /* 038/006c */ + PVOID CsrClientThread; /* 03c/0070 */ + PVOID Win32ThreadInfo; /* 040/0078 */ + ULONG User32Reserved[26]; /* 044/0080 */ + ULONG UserReserved[5]; /* 0ac/00e8 */ + PVOID WOW32Reserved; /* 0c0/0100 */ + ULONG CurrentLocale; /* 0c4/0108 */ + ULONG FpSoftwareStatusRegister; /* 0c8/010c */ + PVOID ReservedForDebuggerInstrumentation[16]; /* 0cc/0110 */ +#ifdef _WIN64 + PVOID SystemReserved1[30]; /* /0190 */ +#else + PVOID SystemReserved1[26]; /* 10c/ */ +#endif + char PlaceholderCompatibilityMode; /* 174/0280 */ + BOOLEAN PlaceholderHydrationAlwaysExplicit; /* 175/0281 */ + char PlaceholderReserved[10]; /* 176/0282 */ + DWORD ProxiedProcessId; /* 180/028c */ + ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 184/0290 */ + UCHAR WorkingOnBehalfOfTicket[8]; /* 19c/02b8 */ + LONG ExceptionCode; /* 1a4/02c0 */ + ACTIVATION_CONTEXT_STACK* ActivationContextStackPointer; /* 1a8/02c8 */ + ULONG_PTR InstrumentationCallbackSp; /* 1ac/02d0 */ + ULONG_PTR InstrumentationCallbackPreviousPc; /* 1b0/02d8 */ + ULONG_PTR InstrumentationCallbackPreviousSp; /* 1b4/02e0 */ +#ifdef _WIN64 + ULONG TxFsContext; /* /02e8 */ + BOOLEAN InstrumentationCallbackDisabled; /* /02ec */ + BOOLEAN UnalignedLoadStoreExceptions; /* /02ed */ +#else + BOOLEAN InstrumentationCallbackDisabled; /* 1b8/ */ + BYTE SpareBytes1[23]; /* 1b9/ */ + ULONG TxFsContext; /* 1d0/ */ +#endif + GDI_TEB_BATCH GdiTebBatch; /* 1d4/02f0 */ + CLIENT_ID RealClientId; /* 6b4/07d8 */ + HANDLE GdiCachedProcessHandle; /* 6bc/07e8 */ + ULONG GdiClientPID; /* 6c0/07f0 */ + ULONG GdiClientTID; /* 6c4/07f4 */ + PVOID GdiThreadLocaleInfo; /* 6c8/07f8 */ + ULONG_PTR Win32ClientInfo[62]; /* 6cc/0800 */ + PVOID glDispatchTable[233]; /* 7c4/09f0 */ + PVOID glReserved1[29]; /* b68/1138 */ + PVOID glReserved2; /* bdc/1220 */ + PVOID glSectionInfo; /* be0/1228 */ + PVOID glSection; /* be4/1230 */ + PVOID glTable; /* be8/1238 */ + PVOID glCurrentRC; /* bec/1240 */ + PVOID glContext; /* bf0/1248 */ + ULONG LastStatusValue; /* bf4/1250 */ + UNICODE_STRING StaticUnicodeString; /* bf8/1258 */ + WCHAR StaticUnicodeBuffer[261]; /* c00/1268 */ + PVOID DeallocationStack; /* e0c/1478 */ + PVOID TlsSlots[64]; /* e10/1480 */ + LIST_ENTRY TlsLinks; /* f10/1680 */ + PVOID Vdm; /* f18/1690 */ + PVOID ReservedForNtRpc; /* f1c/1698 */ + PVOID DbgSsReserved[2]; /* f20/16a0 */ + ULONG HardErrorMode; /* f28/16b0 */ +#ifdef _WIN64 + PVOID Instrumentation[11]; /* /16b8 */ +#else + PVOID Instrumentation[9]; /* f2c/ */ +#endif + GUID ActivityId; /* f50/1710 */ + PVOID SubProcessTag; /* f60/1720 */ + PVOID PerflibData; /* f64/1728 */ + PVOID EtwTraceData; /* f68/1730 */ + PVOID WinSockData; /* f6c/1738 */ + ULONG GdiBatchCount; /* f70/1740 */ + ULONG IdealProcessorValue; /* f74/1744 */ + ULONG GuaranteedStackBytes; /* f78/1748 */ + PVOID ReservedForPerf; /* f7c/1750 */ + PVOID ReservedForOle; /* f80/1758 */ + ULONG WaitingOnLoaderLock; /* f84/1760 */ + PVOID SavedPriorityState; /* f88/1768 */ + ULONG_PTR ReservedForCodeCoverage; /* f8c/1770 */ + PVOID ThreadPoolData; /* f90/1778 */ + PVOID* TlsExpansionSlots; /* f94/1780 */ +#ifdef _WIN64 + union { + PVOID DeallocationBStore; /* /1788 */ + PVOID* ChpeV2CpuAreaInfo; /* /1788 */ + } DUMMYUNIONNAME; + PVOID BStoreLimit; /* /1790 */ +#endif + ULONG MuiGeneration; /* f98/1798 */ + ULONG IsImpersonating; /* f9c/179c */ + PVOID NlsCache; /* fa0/17a0 */ + PVOID ShimData; /* fa4/17a8 */ + ULONG HeapVirtualAffinity; /* fa8/17b0 */ + PVOID CurrentTransactionHandle; /* fac/17b8 */ + TEB_ACTIVE_FRAME* ActiveFrame; /* fb0/17c0 */ + PVOID* FlsSlots; /* fb4/17c8 */ + PVOID PreferredLanguages; /* fb8/17d0 */ + PVOID UserPrefLanguages; /* fbc/17d8 */ + PVOID MergedPrefLanguages; /* fc0/17e0 */ + ULONG MuiImpersonation; /* fc4/17e8 */ + USHORT CrossTebFlags; /* fc8/17ec */ + USHORT SameTebFlags; /* fca/17ee */ + PVOID TxnScopeEnterCallback; /* fcc/17f0 */ + PVOID TxnScopeExitCallback; /* fd0/17f8 */ + PVOID TxnScopeContext; /* fd4/1800 */ + ULONG LockCount; /* fd8/1808 */ + LONG WowTebOffset; /* fdc/180c */ + PVOID ResourceRetValue; /* fe0/1810 */ + PVOID ReservedForWdf; /* fe4/1818 */ + ULONGLONG ReservedForCrt; /* fe8/1820 */ + GUID EffectiveContainerId; /* ff0/1828 */ +} TEB, *PTEB; +static_assert(offsetof(TEB, DeallocationStack) == + 0x1478); /* The only member we care about at the moment */ + +typedef enum _QUEUE_USER_APC_FLAGS { + QueueUserApcFlagsNone, + QueueUserApcFlagsSpecialUserApc, + QueueUserApcFlagsMaxValue +} QUEUE_USER_APC_FLAGS; + +typedef union _USER_APC_OPTION { + ULONG_PTR UserApcFlags; + HANDLE MemoryReserveHandle; +} USER_APC_OPTION, *PUSER_APC_OPTION; + +using PPS_APC_ROUTINE = void (*)(PVOID ApcArgument1, PVOID ApcArgument2, PVOID ApcArgument3, + PCONTEXT Context); + +typedef u64(__stdcall* NtClose_t)(HANDLE Handle); + +typedef u64(__stdcall* NtSetInformationFile_t)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass); + +typedef u64(__stdcall* NtCreateThread_t)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, + PCOBJECT_ATTRIBUTES ObjectAttributes, HANDLE ProcessHandle, + PCLIENT_ID ClientId, PCONTEXT ThreadContext, + PINITIAL_TEB InitialTeb, BOOLEAN CreateSuspended); + +typedef u64(__stdcall* NtTerminateThread_t)(HANDLE ThreadHandle, u64 ExitStatus); + +typedef u64(__stdcall* NtQueueApcThreadEx_t)(HANDLE ThreadHandle, + USER_APC_OPTION UserApcReserveHandle, + PPS_APC_ROUTINE ApcRoutine, PVOID ApcArgument1, + PVOID ApcArgument2, PVOID ApcArgument3); + +extern NtClose_t NtClose; +extern NtSetInformationFile_t NtSetInformationFile; +extern NtCreateThread_t NtCreateThread; +extern NtTerminateThread_t NtTerminateThread; +extern NtQueueApcThreadEx_t NtQueueApcThreadEx; + +namespace Common::NtApi { +void Initialize(); +} + +#endif diff --git a/gpu/shadps4/common/number_utils.cpp b/gpu/shadps4/common/number_utils.cpp new file mode 100644 index 0000000..121437a --- /dev/null +++ b/gpu/shadps4/common/number_utils.cpp @@ -0,0 +1,155 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/number_utils.h" + +constexpr u32 UF11_EXPONENT_SHIFT = 6; +constexpr u32 UF10_EXPONENT_SHIFT = 5; +constexpr u32 RGB9E5_MANTISSA_BITS = 9; +constexpr u32 RGB9E5_EXP_BIAS = 1; +constexpr u32 F32_INFINITY = 0x7f800000; + +namespace NumberUtils { + +float Uf11ToF32(u16 val) { + union { + float f; + u32 ui; + } f32; + + int exponent = (val & 0x07c0) >> UF11_EXPONENT_SHIFT; + int mantissa = (val & 0x003f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 20); + f32.f = scale * mantissa; + } + } else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0f / (1 << -exponent); + } else { + scale = (float)(1 << exponent); + } + decimal = 1.0f + (float)mantissa / 64; + f32.f = scale * decimal; + } + + return f32.f; +} + +float Uf10ToF32(u16 val) { + union { + float f; + u32 ui; + } f32; + + int exponent = (val & 0x03e0) >> UF10_EXPONENT_SHIFT; + int mantissa = (val & 0x001f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 19); + f32.f = scale * mantissa; + } + } else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0f / (1 << -exponent); + } else { + scale = (float)(1 << exponent); + } + decimal = 1.0f + (float)mantissa / 32; + f32.f = scale * decimal; + } + + return f32.f; +} + +float Uf16ToF32(u16 val) { + return half_float::half_cast(reinterpret_cast(val)); +} + +float U2ToUnorm(u8 val) { + static constexpr auto c = 1.0f / 3.0f; + return float(val * c); +} + +float S2ToSnorm(s8 val) { + static constexpr auto c = 1.0f / 1.0f; + return float(val * c); +} + +float U4ToUnorm(u8 val) { + static constexpr auto c = 1.0f / 15.0f; + return float(val * c); +} + +float S4ToSnorm(s8 val) { + static constexpr auto c = 1.0f / 7.0f; + return float(val * c); +} + +float U5ToUnorm(u8 val) { + static constexpr auto c = 1.0f / 31.0f; + return float(val * c); +} + +float S5ToSnorm(s8 val) { + static constexpr auto c = 1.0f / 15.0f; + return float(val * c); +} + +float U6ToUnorm(u8 val) { + static constexpr auto c = 1.0f / 63.0f; + return float(val * c); +} + +float S6ToSnorm(s8 val) { + static constexpr auto c = 1.0f / 31.0f; + return float(val * c); +} + +float U8ToUnorm(u8 val) { + static constexpr auto c = 1.0f / 255.0f; + return float(val * c); +} + +float S8ToSnorm(s8 val) { + static constexpr auto c = 1.0f / 127.0f; + return float(val * c); +} + +float U10ToUnorm(u16 val) { + static constexpr auto c = 1.0f / 1023.0f; + return float(val * c); +} + +float S10ToSnorm(s16 val) { + static constexpr auto c = 1.0f / 511.0f; + return float(val * c); +} + +float U16ToUnorm(u16 val) { + static constexpr auto c = 1.0f / 65535.0f; + return float(val * c); +} + +float S16ToSnorm(s16 val) { + static constexpr auto c = 1.0f / 32767.0f; + return float(val * c); +} + +} // namespace NumberUtils diff --git a/gpu/shadps4/common/number_utils.h b/gpu/shadps4/common/number_utils.h new file mode 100644 index 0000000..05c62a1 --- /dev/null +++ b/gpu/shadps4/common/number_utils.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace NumberUtils { + +float Uf11ToF32(u16 val); +float Uf10ToF32(u16 val); +float Uf16ToF32(u16 val); +float U2ToUnorm(u8 val); +float S2ToSnorm(s8 val); +float U4ToUnorm(u8 val); +float S4ToSnorm(s8 val); +float U5ToUnorm(u8 val); +float S5ToSnorm(s8 val); +float U6ToUnorm(u8 val); +float S6ToSnorm(s8 val); +float U8ToUnorm(u8 val); +float S8ToSnorm(s8 val); +float U10ToUnorm(u16 val); +float S10ToSnorm(s16 val); +float U16ToUnorm(u16 val); +float S16ToSnorm(s16 val); + +} // namespace NumberUtils diff --git a/gpu/shadps4/common/object_pool.h b/gpu/shadps4/common/object_pool.h new file mode 100644 index 0000000..3a0df7b --- /dev/null +++ b/gpu/shadps4/common/object_pool.h @@ -0,0 +1,109 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +namespace Common { + +template + requires std::is_destructible_v +class ObjectPool { +public: + explicit ObjectPool(size_t chunk_size = 1024) : new_chunk_size{chunk_size} { + node = &chunks.emplace_back(new_chunk_size); + } + + template + requires std::is_constructible_v + [[nodiscard]] T* Create(Args&&... args) { + return std::construct_at(Memory(), std::forward(args)...); + } + + void ReleaseContents() { + if (chunks.empty()) { + return; + } + Chunk& root{chunks.front()}; + if (root.used_objects == root.num_objects) { + // Root chunk has been filled, squash allocations into it + const size_t total_objects{root.num_objects + new_chunk_size * (chunks.size() - 1)}; + chunks.clear(); + chunks.emplace_back(total_objects); + } else { + root.Release(); + chunks.resize(1); + } + chunks.shrink_to_fit(); + node = &chunks.front(); + } + +private: + struct NonTrivialDummy { + NonTrivialDummy() noexcept {} + }; + + union Storage { + Storage() noexcept {} + ~Storage() noexcept {} + + NonTrivialDummy dummy{}; + T object; + }; + + struct Chunk { + explicit Chunk() = default; + explicit Chunk(size_t size) + : num_objects{size}, storage{std::make_unique(size)} {} + + Chunk& operator=(Chunk&& rhs) noexcept { + Release(); + used_objects = std::exchange(rhs.used_objects, 0); + num_objects = std::exchange(rhs.num_objects, 0); + storage = std::move(rhs.storage); + return *this; + } + + Chunk(Chunk&& rhs) noexcept + : used_objects{std::exchange(rhs.used_objects, 0)}, + num_objects{std::exchange(rhs.num_objects, 0)}, storage{std::move(rhs.storage)} {} + + ~Chunk() { + Release(); + } + + void Release() { + for (size_t i = 0; i < used_objects; i++) { + storage[i].object.~T(); + } + used_objects = 0; + } + + size_t used_objects{}; + size_t num_objects{}; + std::unique_ptr storage; + }; + + [[nodiscard]] T* Memory() { + Chunk* const chunk{FreeChunk()}; + return &chunk->storage[chunk->used_objects++].object; + } + + [[nodiscard]] Chunk* FreeChunk() { + if (node->used_objects != node->num_objects) { + return node; + } + node = &chunks.emplace_back(new_chunk_size); + return node; + } + + Chunk* node{}; + std::vector chunks; + size_t new_chunk_size{}; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/path_util.cpp b/gpu/shadps4/common/path_util.cpp new file mode 100644 index 0000000..f6c2aed --- /dev/null +++ b/gpu/shadps4/common/path_util.cpp @@ -0,0 +1,250 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "common/logging/log.h" +#include "common/path_util.h" +#include "common/scope_exit.h" +#include "common/types.h" + +#ifdef __APPLE__ +#include +#include +#include +#endif + +#ifndef MAX_PATH +#ifdef _WIN32 +// This is the maximum number of UTF-16 code units permissible in Windows file paths +#define MAX_PATH 260 +#include +#include +#else +// This is the maximum number of UTF-8 code units permissible in all other OSes' file paths +#define MAX_PATH 1024 +#endif +#endif + +namespace Common::FS { + +namespace fs = std::filesystem; + +#ifdef __APPLE__ +using IsTranslocatedURLFunc = Boolean (*)(CFURLRef path, bool* isTranslocated, + CFErrorRef* __nullable error); +using CreateOriginalPathForURLFunc = CFURLRef __nullable (*)(CFURLRef translocatedPath, + CFErrorRef* __nullable error); + +static CFURLRef UntranslocateBundlePath(const CFURLRef bundle_path) { + if (void* security_handle = + dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY)) { + SCOPE_EXIT { + dlclose(security_handle); + }; + + const auto IsTranslocatedURL = reinterpret_cast( + dlsym(security_handle, "SecTranslocateIsTranslocatedURL")); + const auto CreateOriginalPathForURL = reinterpret_cast( + dlsym(security_handle, "SecTranslocateCreateOriginalPathForURL")); + + bool is_translocated = false; + if (IsTranslocatedURL && CreateOriginalPathForURL && + IsTranslocatedURL(bundle_path, &is_translocated, nullptr) && is_translocated) { + return CreateOriginalPathForURL(bundle_path, nullptr); + } + } + return nullptr; +} + +static std::optional GetBundleParentDirectory() { + if (CFBundleRef bundle_ref = CFBundleGetMainBundle()) { + if (CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref)) { + SCOPE_EXIT { + CFRelease(bundle_url_ref); + }; + + CFURLRef untranslocated_url_ref = UntranslocateBundlePath(bundle_url_ref); + SCOPE_EXIT { + if (untranslocated_url_ref) { + CFRelease(untranslocated_url_ref); + } + }; + + char app_bundle_path[MAXPATHLEN]; + if (CFURLGetFileSystemRepresentation( + untranslocated_url_ref ? untranslocated_url_ref : bundle_url_ref, true, + reinterpret_cast(app_bundle_path), sizeof(app_bundle_path))) { + std::filesystem::path bundle_path{app_bundle_path}; + return bundle_path.parent_path(); + } + } + } + return std::nullopt; +} +#endif + +static auto UserPaths = [] { + // bbport: the port keeps GPU caches where BB_GPU_USER_DIR points. + const char* port_dir = std::getenv("BB_GPU_USER_DIR"); + auto user_dir = port_dir ? std::filesystem::path(port_dir) : std::filesystem::current_path() / PORTABLE_DIR; + if (!std::filesystem::exists(user_dir)) { + // If it doesn't exist, use the standard path for the platform instead. + // NOTE: On Windows we currently just create the portable directory instead. +#ifdef __APPLE__ + user_dir = + std::filesystem::path(getenv("HOME")) / "Library" / "Application Support" / "shadPS4"; +#elif defined(__linux__) + const char* xdg_data_home = getenv("XDG_DATA_HOME"); + if (xdg_data_home != nullptr && strlen(xdg_data_home) > 0) { + user_dir = std::filesystem::path(xdg_data_home) / "shadPS4"; + } else { + user_dir = std::filesystem::path(getenv("HOME")) / ".local" / "share" / "shadPS4"; + } +#elif _WIN32 + TCHAR appdata[MAX_PATH] = {0}; + SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, appdata); + user_dir = std::filesystem::path(appdata) / "shadPS4"; +#endif + } + + std::unordered_map paths; + + const auto create_path = [&](PathType shad_path, const fs::path& new_path) { + std::filesystem::create_directory(new_path); + paths.insert_or_assign(shad_path, new_path); + }; + + create_path(PathType::UserDir, user_dir); + create_path(PathType::LogDir, user_dir / LOG_DIR); + create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR); + create_path(PathType::ShaderDir, user_dir / SHADER_DIR); + create_path(PathType::GameDataDir, user_dir / GAMEDATA_DIR); + create_path(PathType::TempDataDir, user_dir / TEMPDATA_DIR); + create_path(PathType::SysModuleDir, user_dir / SYSMODULES_DIR); + create_path(PathType::DownloadDir, user_dir / DOWNLOAD_DIR); + create_path(PathType::CapturesDir, user_dir / CAPTURES_DIR); + create_path(PathType::CheatsDir, user_dir / CHEATS_DIR); + create_path(PathType::PatchesDir, user_dir / PATCHES_DIR); + create_path(PathType::MetaDataDir, user_dir / METADATA_DIR); + create_path(PathType::CustomTrophy, user_dir / CUSTOM_TROPHY); + create_path(PathType::CustomConfigs, user_dir / CUSTOM_CONFIGS); + create_path(PathType::CacheDir, user_dir / CACHE_DIR); + create_path(PathType::FontsDir, user_dir / FONTS_DIR); + create_path(PathType::TrophyDir, user_dir / TROPHY_DIR); + create_path(PathType::HomeDir, user_dir / HOME_DIR); + create_path(PathType::CustomModulesDir, user_dir / CUSTOM_MODULES_DIR); + + std::ofstream notice_file(user_dir / CUSTOM_TROPHY / "Notice.txt"); + if (notice_file.is_open()) { + notice_file + << "++++++++++++++++++++++++++++++++\n+ Custom Trophy Images / Sound " + "+\n++++++++++++++++++++++++++++++++\n\nYou can add custom images to the " + "trophies.\n*We recommend a square resolution image, for example 200x200, 500x500, " + "the same size as the height and width.\nIn this folder ('user\\custom_trophy'), " + "add the files with the following " + "names:\n\nbronze.png\nsilver.png\ngold.png\nplatinum.png\n\nYou can add a custom " + "sound for trophy notifications.\n*By default, no audio is played unless it is in " + "this folder and you are using the QT version.\nIn this folder " + "('user\\custom_trophy'), add the files with the following names:\n\ntrophy.mp3"; + notice_file.close(); + } + + return paths; +}(); + +bool ValidatePath(const fs::path& path) { + if (path.empty()) { + LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path)); + return false; + } + +#ifdef _WIN32 + if (path.u16string().size() >= MAX_PATH) { + LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path)); + return false; + } +#else + if (path.u8string().size() >= MAX_PATH) { + LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path)); + return false; + } +#endif + + return true; +} + +std::string PathToUTF8String(const std::filesystem::path& path) { + const auto u8_string = path.u8string(); + return std::string{u8_string.begin(), u8_string.end()}; +} + +const fs::path& GetUserPath(PathType shad_path) { + return UserPaths.at(shad_path); +} + +std::string GetUserPathString(PathType shad_path) { + return PathToUTF8String(GetUserPath(shad_path)); +} + +void SetUserPath(PathType shad_path, const fs::path& new_path) { + if (!std::filesystem::is_directory(new_path)) { + LOG_ERROR(Common_Filesystem, "Filesystem object at new_path={} is not a directory", + PathToUTF8String(new_path)); + return; + } + + UserPaths.insert_or_assign(shad_path, new_path); +} + +std::optional FindGameByID(const fs::path& dir, const std::string& game_id, + int max_depth) { + if (max_depth < 0) { + return std::nullopt; + } + + const auto boot_path_for = [](const fs::path& root) -> std::optional { + std::error_code ec; + if (fs::is_directory(root, ec) && !ec) { + if (!fs::exists(root / "sce_sys" / "param.sfo")) { + return std::nullopt; + } + if (auto eboot_path = root / "eboot.bin"; fs::exists(eboot_path)) { + return eboot_path; + } + return std::nullopt; + } + // bbport: packed (ZArchive) game images are not supported by the port. + return std::nullopt; + }; + + // Check if this is the game we're looking for + if (dir.filename() == game_id) { + if (auto found = boot_path_for(dir)) { + return found; + } + } + + if (auto found = boot_path_for(dir / game_id)) { + return found; + } + if (auto found = boot_path_for(dir / (game_id + ".zar"))) { + return found; + } + + // Recursively search subdirectories + std::error_code ec; + for (const auto& entry : fs::directory_iterator(dir, ec)) { + std::error_code entry_ec; + if (!entry.is_directory(entry_ec) || entry_ec) { + continue; + } + if (auto found = FindGameByID(entry.path(), game_id, max_depth - 1)) { + return found; + } + } + + return std::nullopt; +} + +} // namespace Common::FS diff --git a/gpu/shadps4/common/path_util.h b/gpu/shadps4/common/path_util.h new file mode 100644 index 0000000..922e75f --- /dev/null +++ b/gpu/shadps4/common/path_util.h @@ -0,0 +1,123 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +namespace Common::FS { + +enum class PathType { + UserDir, // Where shadPS4 stores its data. + LogDir, // Where log files are stored. + ScreenshotsDir, // Where screenshots are stored. + ShaderDir, // Where shaders are stored. + TempDataDir, // Where game temp data is stored. + GameDataDir, // Where game data is stored. + SysModuleDir, // Where system modules are stored. + DownloadDir, // Where downloads/temp files are stored. + CapturesDir, // Where rdoc captures are stored. + CheatsDir, // Where cheats are stored. + PatchesDir, // Where patches are stored. + MetaDataDir, // Where game metadata (e.g. trophies and menu backgrounds) is stored. + CustomTrophy, // Where custom files for trophies are stored. + CustomConfigs, // Where custom files for different games are stored. + CacheDir, // Where pipeline and shader cache is stored. + FontsDir, // Where dumped system fonts are stored. + TrophyDir, // Where general trophy metadata is stored. + HomeDir, // PS4 home directory + CustomModulesDir // Where custom modules are stored. +}; + +constexpr auto PORTABLE_DIR = "user"; + +// Sub-directories contained within a user data directory +constexpr auto LOG_DIR = "log"; +constexpr auto SCREENSHOTS_DIR = "screenshots"; +constexpr auto SHADER_DIR = "shader"; +constexpr auto GAMEDATA_DIR = "data"; +constexpr auto TEMPDATA_DIR = "temp"; +constexpr auto SYSMODULES_DIR = "sys_modules"; +constexpr auto DOWNLOAD_DIR = "download"; +constexpr auto CAPTURES_DIR = "captures"; +constexpr auto CHEATS_DIR = "cheats"; +constexpr auto PATCHES_DIR = "patches"; +constexpr auto METADATA_DIR = "game_data"; +constexpr auto CUSTOM_TROPHY = "custom_trophy"; +constexpr auto CUSTOM_CONFIGS = "custom_configs"; +constexpr auto CACHE_DIR = "cache"; +constexpr auto FONTS_DIR = "fonts"; +constexpr auto TROPHY_DIR = "trophy"; +constexpr auto HOME_DIR = "home"; +constexpr auto CUSTOM_MODULES_DIR = "custom_modules"; + +// Filenames +constexpr auto LOG_FILE = "shad_log.txt"; + +/** + * Validates a given path. + * + * A given path is valid if it meets these conditions: + * - The path is not empty + * - The path is not too long + * + * @param path Filesystem path + * + * @returns True if the path is valid, false otherwise. + */ +[[nodiscard]] bool ValidatePath(const std::filesystem::path& path); + +/** + * Converts a filesystem path to a UTF-8 encoded std::string. + * + * @param path Filesystem path + * + * @returns UTF-8 encoded std::string. + */ +[[nodiscard]] std::string PathToUTF8String(const std::filesystem::path& path); + +/** + * Gets the filesystem path associated with the PathType enum. + * + * @param user_path PathType enum + * + * @returns The filesystem path associated with the PathType enum. + */ +[[nodiscard]] const std::filesystem::path& GetUserPath(PathType user_path); + +/** + * Gets the filesystem path associated with the PathType enum as a UTF-8 encoded std::string. + * + * @param user_path PathType enum + * + * @returns The filesystem path associated with the PathType enum as a UTF-8 encoded std::string. + */ +[[nodiscard]] std::string GetUserPathString(PathType user_path); + +/** + * Sets a new filesystem path associated with the PathType enum. + * If the filesystem object at new_path is not a directory, this function will not do anything. + * + * @param user_path PathType enum + * @param new_path New filesystem path + */ +void SetUserPath(PathType user_path, const std::filesystem::path& new_path); + +/** + * Recursively searches for an installed game by its ID. + * Limits search depth to prevent excessive filesystem traversal. + * + * @param dir Base directory to start the search from + * @param game_id The game ID to search for + * @param max_depth Maximum directory depth to search + * + * @returns A path to eboot.bin for an unpacked game, or the ".zar" archive itself for a + * packed one. std::nullopt if the game isn't found. + */ +[[nodiscard]] std::optional FindGameByID(const std::filesystem::path& dir, + const std::string& game_id, + int max_depth); + +} // namespace Common::FS diff --git a/gpu/shadps4/common/polyfill_thread.h b/gpu/shadps4/common/polyfill_thread.h new file mode 100644 index 0000000..ca04810 --- /dev/null +++ b/gpu/shadps4/common/polyfill_thread.h @@ -0,0 +1,377 @@ +// SPDX-FileCopyrightText: 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// +// TODO: remove this file when jthread is supported by all compilation targets +// + +#pragma once + +#include + +#ifdef __cpp_lib_jthread + +#include +#include +#include +#include +#include + +namespace Common { + +template +void CondvarWait(Condvar& cv, std::unique_lock& lk, std::stop_token token, Pred&& pred) { + cv.wait(lk, token, std::forward(pred)); +} + +template +bool StoppableTimedWait(std::stop_token token, const std::chrono::duration& rel_time) { + std::condition_variable_any cv; + std::mutex m; + + // Perform the timed wait. + std::unique_lock lk{m}; + return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); }); +} + +} // namespace Common + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace std { +namespace polyfill { + +using stop_state_callback = size_t; + +class stop_state { +public: + stop_state() = default; + ~stop_state() = default; + + bool request_stop() { + unique_lock lk{m_lock}; + + if (m_stop_requested) { + // Already set, nothing to do. + return false; + } + + // Mark stop requested. + m_stop_requested = true; + + while (!m_callbacks.empty()) { + // Get an iterator to the first element. + const auto it = m_callbacks.begin(); + + // Move the callback function out of the map. + function f; + swap(it->second, f); + + // Erase the now-empty map element. + m_callbacks.erase(it); + + // Run the callback. + if (f) { + f(); + } + } + + return true; + } + + bool stop_requested() const { + unique_lock lk{m_lock}; + return m_stop_requested; + } + + stop_state_callback insert_callback(function f) { + unique_lock lk{m_lock}; + + if (m_stop_requested) { + // Stop already requested. Don't insert anything, + // just run the callback synchronously. + if (f) { + f(); + } + return 0; + } + + // Insert the callback. + stop_state_callback ret = ++m_next_callback; + m_callbacks.emplace(ret, std::move(f)); + return ret; + } + + void remove_callback(stop_state_callback cb) { + unique_lock lk{m_lock}; + m_callbacks.erase(cb); + } + +private: + mutable recursive_mutex m_lock; + map> m_callbacks; + stop_state_callback m_next_callback{0}; + bool m_stop_requested{false}; +}; + +} // namespace polyfill + +class stop_token; +class stop_source; +struct nostopstate_t { + explicit nostopstate_t() = default; +}; +inline constexpr nostopstate_t nostopstate{}; + +template +class stop_callback; + +class stop_token { +public: + stop_token() noexcept = default; + + stop_token(const stop_token&) noexcept = default; + stop_token(stop_token&&) noexcept = default; + stop_token& operator=(const stop_token&) noexcept = default; + stop_token& operator=(stop_token&&) noexcept = default; + ~stop_token() = default; + + void swap(stop_token& other) noexcept { + m_stop_state.swap(other.m_stop_state); + } + + [[nodiscard]] bool stop_requested() const noexcept { + return m_stop_state && m_stop_state->stop_requested(); + } + [[nodiscard]] bool stop_possible() const noexcept { + return m_stop_state != nullptr; + } + +private: + friend class stop_source; + template + friend class stop_callback; + stop_token(shared_ptr stop_state) : m_stop_state(std::move(stop_state)) {} + +private: + shared_ptr m_stop_state; +}; + +class stop_source { +public: + stop_source() : m_stop_state(make_shared()) {} + explicit stop_source(nostopstate_t) noexcept {} + + stop_source(const stop_source&) noexcept = default; + stop_source(stop_source&&) noexcept = default; + stop_source& operator=(const stop_source&) noexcept = default; + stop_source& operator=(stop_source&&) noexcept = default; + ~stop_source() = default; + void swap(stop_source& other) noexcept { + m_stop_state.swap(other.m_stop_state); + } + + [[nodiscard]] stop_token get_token() const noexcept { + return stop_token(m_stop_state); + } + [[nodiscard]] bool stop_possible() const noexcept { + return m_stop_state != nullptr; + } + [[nodiscard]] bool stop_requested() const noexcept { + return m_stop_state && m_stop_state->stop_requested(); + } + bool request_stop() noexcept { + return m_stop_state && m_stop_state->request_stop(); + } + +private: + friend class jthread; + explicit stop_source(shared_ptr stop_state) + : m_stop_state(std::move(stop_state)) {} + +private: + shared_ptr m_stop_state; +}; + +template +class stop_callback { + static_assert(is_nothrow_destructible_v); + static_assert(is_invocable_v); + +public: + using callback_type = Callback; + + template + requires constructible_from + explicit stop_callback(const stop_token& st, + C&& cb) noexcept(is_nothrow_constructible_v) + : m_stop_state(st.m_stop_state) { + if (m_stop_state) { + m_callback = m_stop_state->insert_callback(std::move(cb)); + } + } + template + requires constructible_from + explicit stop_callback(stop_token&& st, + C&& cb) noexcept(is_nothrow_constructible_v) + : m_stop_state(std::move(st.m_stop_state)) { + if (m_stop_state) { + m_callback = m_stop_state->insert_callback(std::move(cb)); + } + } + ~stop_callback() { + if (m_stop_state && m_callback) { + m_stop_state->remove_callback(m_callback); + } + } + + stop_callback(const stop_callback&) = delete; + stop_callback(stop_callback&&) = delete; + stop_callback& operator=(const stop_callback&) = delete; + stop_callback& operator=(stop_callback&&) = delete; + +private: + shared_ptr m_stop_state; + polyfill::stop_state_callback m_callback; +}; + +template +stop_callback(stop_token, Callback) -> stop_callback; + +class jthread { +public: + using id = thread::id; + using native_handle_type = thread::native_handle_type; + + jthread() noexcept = default; + + template , jthread>>> + explicit jthread(F&& f, Args&&... args) + : m_stop_state(make_shared()), + m_thread(make_thread(std::forward(f), std::forward(args)...)) {} + + ~jthread() { + if (joinable()) { + request_stop(); + join(); + } + } + + jthread(const jthread&) = delete; + jthread(jthread&&) noexcept = default; + jthread& operator=(const jthread&) = delete; + + jthread& operator=(jthread&& other) noexcept { + m_thread.swap(other.m_thread); + m_stop_state.swap(other.m_stop_state); + return *this; + } + + void swap(jthread& other) noexcept { + m_thread.swap(other.m_thread); + m_stop_state.swap(other.m_stop_state); + } + [[nodiscard]] bool joinable() const noexcept { + return m_thread.joinable(); + } + void join() { + m_thread.join(); + } + void detach() { + m_thread.detach(); + m_stop_state.reset(); + } + + [[nodiscard]] id get_id() const noexcept { + return m_thread.get_id(); + } + [[nodiscard]] native_handle_type native_handle() { + return m_thread.native_handle(); + } + [[nodiscard]] stop_source get_stop_source() noexcept { + return stop_source(m_stop_state); + } + [[nodiscard]] stop_token get_stop_token() const noexcept { + return stop_source(m_stop_state).get_token(); + } + bool request_stop() noexcept { + return get_stop_source().request_stop(); + } + [[nodiscard]] static unsigned int hardware_concurrency() noexcept { + return thread::hardware_concurrency(); + } + +private: + template + thread make_thread(F&& f, Args&&... args) { + if constexpr (is_invocable_v, stop_token, decay_t...>) { + return thread(std::forward(f), get_stop_token(), std::forward(args)...); + } else { + return thread(std::forward(f), std::forward(args)...); + } + } + + shared_ptr m_stop_state; + thread m_thread; +}; + +} // namespace std + +namespace Common { + +template +void CondvarWait(Condvar& cv, std::unique_lock& lk, std::stop_token token, Pred pred) { + if (token.stop_requested()) { + return; + } + + std::stop_callback callback(token, [&] { + { + std::scoped_lock lk2{*lk.mutex()}; + } + cv.notify_all(); + }); + + cv.wait(lk, [&] { return pred() || token.stop_requested(); }); +} + +template +bool StoppableTimedWait(std::stop_token token, const std::chrono::duration& rel_time) { + if (token.stop_requested()) { + return false; + } + + bool stop_requested = false; + std::condition_variable cv; + std::mutex m; + + std::stop_callback cb(token, [&] { + // Wake up the waiting thread. + { + std::scoped_lock lk{m}; + stop_requested = true; + } + cv.notify_one(); + }); + + // Perform the timed wait. + std::unique_lock lk{m}; + return !cv.wait_for(lk, rel_time, [&] { return stop_requested; }); +} + +} // namespace Common + +#endif diff --git a/gpu/shadps4/common/range_lock.h b/gpu/shadps4/common/range_lock.h new file mode 100644 index 0000000..efe6eb5 --- /dev/null +++ b/gpu/shadps4/common/range_lock.h @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +namespace Common { + +// From boost thread locking + +template +struct RangeLockGuard { + Iterator begin; + Iterator end; + + RangeLockGuard(Iterator begin_, Iterator end_) : begin(begin_), end(end_) { + LockRange(begin, end); + } + + void release() { + begin = end; + } + + ~RangeLockGuard() { + for (; begin != end; ++begin) { + begin->unlock(); + } + } +}; + +template +Iterator TryLockRange(Iterator begin, Iterator end) { + using LockType = typename std::iterator_traits::value_type; + + if (begin == end) { + return end; + } + + std::unique_lock guard(*begin, std::try_to_lock); + if (!guard.owns_lock()) { + return begin; + } + + Iterator failed = TryLockRange(++begin, end); + if (failed == end) { + guard.release(); + } + + return failed; +} + +template +void LockRange(Iterator begin, Iterator end) { + using LockType = typename std::iterator_traits::value_type; + + if (begin == end) { + return; + } + + bool start_with_begin = true; + Iterator second = begin; + ++second; + Iterator next = second; + + while (true) { + std::unique_lock begin_lock(*begin, std::defer_lock); + if (start_with_begin) { + begin_lock.lock(); + + const Iterator failed_lock = TryLockRange(next, end); + if (failed_lock == end) { + begin_lock.release(); + return; + } + + start_with_begin = false; + next = failed_lock; + } else { + RangeLockGuard guard(next, end); + + if (begin_lock.try_lock()) { + const Iterator failed_lock = TryLockRange(second, next); + if (failed_lock == next) { + begin_lock.release(); + guard.release(); + return; + } + + start_with_begin = false; + next = failed_lock; + } else { + start_with_begin = true; + next = second; + } + } + } +} + +} // namespace Common \ No newline at end of file diff --git a/gpu/shadps4/common/rdtsc.cpp b/gpu/shadps4/common/rdtsc.cpp new file mode 100644 index 0000000..48d1b7a --- /dev/null +++ b/gpu/shadps4/common/rdtsc.cpp @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/rdtsc.h" +#include "common/uint128.h" + +#ifdef _WIN64 +#include +#endif + +namespace Common { + +static constexpr size_t SecondToNanoseconds = 1000000000ULL; + +template +static u64 RoundToNearest(u64 value) { + const auto mod = value % Nearest; + return mod >= (Nearest / 2) ? (value - mod + Nearest) : (value - mod); +} + +static u64 GetTimeNs() { +#ifdef _WIN64 + // GetSystemTimePreciseAsFileTime returns the file time in 100ns units. + static constexpr u64 Multiplier = 100; + // Convert Windows epoch to Unix epoch. + static constexpr u64 WindowsEpochToUnixEpoch = 0x19DB1DED53E8000LL; + FILETIME filetime; + GetSystemTimePreciseAsFileTime(&filetime); + return Multiplier * ((static_cast(filetime.dwHighDateTime) << 32) + + static_cast(filetime.dwLowDateTime) - WindowsEpochToUnixEpoch); +#elif defined(__APPLE__) + return clock_gettime_nsec_np(CLOCK_REALTIME); +#else + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return ts.tv_sec * SecondToNanoseconds + ts.tv_nsec; +#endif +} + +u64 EstimateRDTSCFrequency() { + // Discard the first result measuring the rdtsc. + FencedRDTSC(); + std::this_thread::sleep_for(std::chrono::milliseconds{1}); + FencedRDTSC(); + + // Get the current time. + const auto start_time = GetTimeNs(); + const u64 tsc_start = FencedRDTSC(); + // Wait for 100 milliseconds. + std::this_thread::sleep_for(std::chrono::milliseconds{100}); + const auto end_time = GetTimeNs(); + const u64 tsc_end = FencedRDTSC(); + // Calculate differences. + const u64 tsc_diff = tsc_end - tsc_start; + const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, end_time - start_time); + return RoundToNearest<100'000>(tsc_freq); +} + +} // namespace Common diff --git a/gpu/shadps4/common/rdtsc.h b/gpu/shadps4/common/rdtsc.h new file mode 100644 index 0000000..4e4d584 --- /dev/null +++ b/gpu/shadps4/common/rdtsc.h @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/arch.h" + +#ifdef _MSC_VER +#include +#endif + +#include "common/types.h" + +namespace Common { + +#ifdef _MSC_VER +__forceinline static u64 FencedRDTSC() { +#ifdef ARCH_X86_64 + _mm_lfence(); + _ReadWriteBarrier(); + const u64 result = __rdtsc(); + _mm_lfence(); + _ReadWriteBarrier(); + return result; +#else +#error "Missing FencedRDTSC() implementation for target CPU architecture." +#endif +} +#else +static inline u64 FencedRDTSC() { +#ifdef ARCH_X86_64 + u64 eax; + u64 edx; + asm volatile("lfence\n\t" + "rdtsc\n\t" + "lfence\n\t" + : "=a"(eax), "=d"(edx)); + return (edx << 32) | eax; +#elif defined(ARCH_ARM64) + u64 ret; + asm volatile("isb\n\t" + "mrs %0, cntvct_el0\n\t" + "isb\n\t" + : "=r"(ret)::"memory"); + return ret; +#else +#error "Missing FencedRDTSC() implementation for target CPU architecture." +#endif +} +#endif + +u64 EstimateRDTSCFrequency(); + +} // namespace Common diff --git a/gpu/shadps4/common/recursive_lock.cpp b/gpu/shadps4/common/recursive_lock.cpp new file mode 100644 index 0000000..2471a2e --- /dev/null +++ b/gpu/shadps4/common/recursive_lock.cpp @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "common/recursive_lock.h" + +namespace Common::Detail { + +struct RecursiveLockState { + RecursiveLockType type; + int count; +}; + +thread_local std::unordered_map g_recursive_locks; + +bool IncrementRecursiveLock(void* mutex, RecursiveLockType type) { + auto& state = g_recursive_locks[mutex]; + if (state.count == 0) { + ASSERT(state.type == RecursiveLockType::None); + state.type = type; + } + ASSERT(state.type == type); + return state.count++ == 0; +} + +bool DecrementRecursiveLock(void* mutex, RecursiveLockType type) { + auto& state = g_recursive_locks[mutex]; + ASSERT(state.type == type && state.count > 0); + if (--state.count == 0) { + g_recursive_locks.erase(mutex); + return true; + } + return false; +} + +} // namespace Common::Detail diff --git a/gpu/shadps4/common/recursive_lock.h b/gpu/shadps4/common/recursive_lock.h new file mode 100644 index 0000000..5a5fc66 --- /dev/null +++ b/gpu/shadps4/common/recursive_lock.h @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +namespace Common { + +namespace Detail { + +enum class RecursiveLockType { None, Shared, Exclusive }; + +bool IncrementRecursiveLock(void* mutex, RecursiveLockType type); +bool DecrementRecursiveLock(void* mutex, RecursiveLockType type); + +} // namespace Detail + +template +class RecursiveScopedLock { +public: + explicit RecursiveScopedLock(MutexType& mutex) : m_mutex(mutex), m_locked(false) { + if (Detail::IncrementRecursiveLock(&m_mutex, Detail::RecursiveLockType::Exclusive)) { + m_locked = true; + m_lock.emplace(m_mutex); + } + } + + ~RecursiveScopedLock() { + Detail::DecrementRecursiveLock(&m_mutex, Detail::RecursiveLockType::Exclusive); + if (m_locked) { + m_lock.reset(); + } + } + +private: + MutexType& m_mutex; + std::optional> m_lock; + bool m_locked = false; +}; + +template +class RecursiveSharedLock { +public: + explicit RecursiveSharedLock(MutexType& mutex) : m_mutex(mutex), m_locked(false) { + if (Detail::IncrementRecursiveLock(&m_mutex, Detail::RecursiveLockType::Shared)) { + m_locked = true; + m_lock.emplace(m_mutex); + } + } + + ~RecursiveSharedLock() { + Detail::DecrementRecursiveLock(&m_mutex, Detail::RecursiveLockType::Shared); + if (m_locked) { + m_lock.reset(); + } + } + +private: + MutexType& m_mutex; + std::optional> m_lock; + bool m_locked = false; +}; + +} // namespace Common \ No newline at end of file diff --git a/gpu/shadps4/common/ring_buffer_queue.h b/gpu/shadps4/common/ring_buffer_queue.h new file mode 100644 index 0000000..79a5ac9 --- /dev/null +++ b/gpu/shadps4/common/ring_buffer_queue.h @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "common/types.h" + +template +class RingBufferQueue { +public: + RingBufferQueue(u64 size) : m_storage(size) {} + + void Push(T item) { + const u64 index = (m_begin + m_size) % m_storage.size(); + m_storage[index] = std::move(item); + if (m_size < m_storage.size()) { + m_size += 1; + } else { + m_begin = (m_begin + 1) % m_storage.size(); + } + } + + std::optional Pop() { + if (m_size == 0) { + return {}; + } + const u64 index = m_begin; + m_begin = (m_begin + 1) % m_storage.size(); + m_size -= 1; + return std::move(m_storage[index]); + } + + std::optional Peek() { + if (m_size == 0) { + return {}; + } + return m_storage[m_begin]; + } + + void Clear() { + m_begin = 0; + m_size = 0; + } + +private: + u64 m_begin = 0; + u64 m_size = 0; + std::vector m_storage; +}; diff --git a/gpu/shadps4/common/scm_rev.cpp.in b/gpu/shadps4/common/scm_rev.cpp.in new file mode 100644 index 0000000..0b113eb --- /dev/null +++ b/gpu/shadps4/common/scm_rev.cpp.in @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/scm_rev.h" + +namespace Common { + +constexpr char g_version[] = "@APP_VERSION@"; +constexpr bool g_is_release = @APP_IS_RELEASE@; + +constexpr char g_scm_rev[] = "@GIT_REV@"; +constexpr char g_scm_branch[] = "@GIT_BRANCH@"; +constexpr char g_scm_desc[] = "@GIT_DESC@"; +constexpr char g_scm_remote_name[] = "@GIT_REMOTE_NAME@"; +constexpr char g_scm_remote_url[] = "@GIT_REMOTE_URL@"; +constexpr char g_scm_date[] = "@BUILD_DATE@"; + +const std::string GetRemoteNameFromLink() { + std::string remote_url(Common::g_scm_remote_url); + std::string remote_host; + try { + if (remote_url.starts_with("http")) { + if (*remote_url.rbegin() == '/') { + remote_url.pop_back(); + } + remote_host = remote_url.substr(19, remote_url.rfind('/') - 19); + } else if (remote_url.starts_with("git@")) { + auto after_comma_pos = remote_url.find(':') + 1, slash_pos = remote_url.find('/'); + remote_host = remote_url.substr(after_comma_pos, slash_pos - after_comma_pos); + } else { + remote_host = "unknown"; + } + } catch (...) { + remote_host = "unknown"; + } + return remote_host; +} + +} // namespace + diff --git a/gpu/shadps4/common/scm_rev.h b/gpu/shadps4/common/scm_rev.h new file mode 100644 index 0000000..2f6d770 --- /dev/null +++ b/gpu/shadps4/common/scm_rev.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Common { + +extern const char g_version[]; +extern const bool g_is_release; + +extern const char g_scm_rev[]; +extern const char g_scm_branch[]; +extern const char g_scm_desc[]; +extern const char g_scm_remote_name[]; +extern const char g_scm_remote_url[]; +extern const char g_scm_date[]; + +const std::string GetRemoteNameFromLink(); + +} // namespace Common diff --git a/gpu/shadps4/common/scope_exit.h b/gpu/shadps4/common/scope_exit.h new file mode 100644 index 0000000..e8c7090 --- /dev/null +++ b/gpu/shadps4/common/scope_exit.h @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace detail { +template +class ScopeGuard { +private: + F f; + bool active; + +public: + constexpr ScopeGuard(F f_) : f(std::move(f_)), active(true) {} + constexpr ~ScopeGuard() { + if (active) { + f(); + } + } + constexpr void Cancel() { + active = false; + } + + constexpr ScopeGuard(ScopeGuard&& rhs) : f(std::move(rhs.f)), active(rhs.active) { + rhs.Cancel(); + } + + ScopeGuard& operator=(ScopeGuard&& rhs) = delete; +}; + +template +constexpr ScopeGuard MakeScopeGuard(F f) { + return ScopeGuard(std::move(f)); +} + +enum class ScopeGuardOnExit {}; + +template +constexpr ScopeGuard operator+(ScopeGuardOnExit, F&& f) { + return ScopeGuard(std::forward(f)); +} + +} // namespace detail + +#define CONCATENATE_IMPL(s1, s2) s1##s2 +#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2) + +#ifdef __COUNTER__ +#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__) +#else +#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __LINE__) +#endif + +/** + * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be + * used when the caller might want to cancel the ScopeExit. + */ +#define SCOPE_GUARD detail::ScopeGuardOnExit() + [&]() + +/** + * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy + * for doing ad-hoc clean-up tasks in a function with multiple returns. + * + * Example usage: + * \code + * const int saved_val = g_foo; + * g_foo = 55; + * SCOPE_EXIT{ g_foo = saved_val; }; + * + * if (Bar()) { + * return 0; + * } else { + * return 20; + * } + * \endcode + */ +#define SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_) = SCOPE_GUARD diff --git a/gpu/shadps4/common/serdes.h b/gpu/shadps4/common/serdes.h new file mode 100644 index 0000000..a8152e9 --- /dev/null +++ b/gpu/shadps4/common/serdes.h @@ -0,0 +1,143 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/types.h" + +#include +#include + +namespace Serialization { + +template +concept Container = requires(T t) { + typename T::iterator; + { t.begin() } -> std::same_as; + { t.end() } -> std::same_as; + { t.size() } -> std::convertible_to; +}; + +struct Archive { + void Alloc(size_t size) { + container.resize(size); + } + + void Grow(size_t size) { + container.resize(container.size() + size); + } + + void Merge(const Archive& ar) { + container.insert(container.end(), ar.container.cbegin(), ar.container.cend()); + offset = container.size(); + } + + [[nodiscard]] size_t SizeBytes() const { + return container.size(); + } + + u8* CurrPtr() { + return container.data() + offset; + } + + void Advance(size_t size) { + ASSERT_MSG(offset + size <= container.size(), + "Invalid or corrupted deserialization container/shader cache"); + offset += size; + } + + std::vector&& TakeOff() { + offset = 0; + return std::move(container); + } + + [[nodiscard]] bool IsEoS() const { + return offset >= container.size(); + } + + Archive() = default; + explicit Archive(std::vector&& v) : container{v} {} + +private: + u32 offset{}; + std::vector container{}; + + friend struct Writer; + friend struct Reader; +}; + +struct Writer { + template + void Write(const T* ptr, size_t size) { + if (ar.offset + size >= ar.container.size()) { + ar.Grow(size); + } + std::memcpy(ar.CurrPtr(), reinterpret_cast(ptr), size); + ar.Advance(size); + } + + template + requires(!Container) + void Write(const T& value) { + const auto size = sizeof(value); + Write(&value, size); + } + + void Write(const auto& v) { + Write(v.size()); + for (const auto& elem : v) { + Write(elem); + } + } + + void Write(const std::string& s) { + Write(s.size()); + Write(s.c_str(), s.size()); + } + + Writer() = delete; + explicit Writer(Archive& ar_) : ar{ar_} {} + + Archive& ar; +}; + +struct Reader { + template + void Read(T* ptr, size_t size) { + ASSERT_MSG(ar.offset + size <= ar.container.size(), + "Invalid or corrupted deserialization container/shader cache"); + std::memcpy(reinterpret_cast(ptr), ar.CurrPtr(), size); + ar.Advance(size); + } + + template + requires(!Container) + void Read(T& value) { + const auto size = sizeof(value); + Read(&value, size); + } + + void Read(auto& v) { + size_t num_elements{}; + Read(num_elements); + for (int i = 0; i < num_elements; ++i) { + v.emplace_back(); + Read(v.back()); + } + } + + void Read(std::string& s) { + size_t length{}; + Read(length); + s.resize(length); + Read(s.data(), length); + } + + Reader() = delete; + explicit Reader(Archive& ar_) : ar{ar_} {} + + Archive& ar; +}; + +} // namespace Serialization diff --git a/gpu/shadps4/common/sha1.h b/gpu/shadps4/common/sha1.h new file mode 100644 index 0000000..fad849d --- /dev/null +++ b/gpu/shadps4/common/sha1.h @@ -0,0 +1,180 @@ +// SPDX-FileCopyrightText: 2012 SAURAV MOHAPATRA +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include + +namespace sha1 { +class SHA1 { +public: + typedef uint32_t digest32_t[5]; + typedef uint8_t digest8_t[20]; + inline static uint32_t LeftRotate(uint32_t value, size_t count) { + return (value << count) ^ (value >> (32 - count)); + } + SHA1() { + reset(); + } + virtual ~SHA1() {} + SHA1(const SHA1& s) { + *this = s; + } + const SHA1& operator=(const SHA1& s) { + memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); + memcpy(m_block, s.m_block, 64); + m_blockByteIndex = s.m_blockByteIndex; + m_byteCount = s.m_byteCount; + return *this; + } + SHA1& reset() { + m_digest[0] = 0x67452301; + m_digest[1] = 0xEFCDAB89; + m_digest[2] = 0x98BADCFE; + m_digest[3] = 0x10325476; + m_digest[4] = 0xC3D2E1F0; + m_blockByteIndex = 0; + m_byteCount = 0; + return *this; + } + SHA1& processByte(uint8_t octet) { + this->m_block[this->m_blockByteIndex++] = octet; + ++this->m_byteCount; + if (m_blockByteIndex == 64) { + this->m_blockByteIndex = 0; + processBlock(); + } + return *this; + } + SHA1& processBlock(const void* const start, const void* const end) { + const uint8_t* begin = static_cast(start); + const uint8_t* finish = static_cast(end); + while (begin != finish) { + processByte(*begin); + begin++; + } + return *this; + } + SHA1& processBytes(const void* const data, size_t len) { + const uint8_t* block = static_cast(data); + processBlock(block, block + len); + return *this; + } + const uint32_t* getDigest(digest32_t digest) { + size_t bitCount = this->m_byteCount * 8; + processByte(0x80); + if (this->m_blockByteIndex > 56) { + while (m_blockByteIndex != 0) { + processByte(0); + } + while (m_blockByteIndex < 56) { + processByte(0); + } + } else { + while (m_blockByteIndex < 56) { + processByte(0); + } + } + processByte(0); + processByte(0); + processByte(0); + processByte(0); + processByte(static_cast((bitCount >> 24) & 0xFF)); + processByte(static_cast((bitCount >> 16) & 0xFF)); + processByte(static_cast((bitCount >> 8) & 0xFF)); + processByte(static_cast((bitCount) & 0xFF)); + + memcpy(digest, m_digest, 5 * sizeof(uint32_t)); + return digest; + } + const uint8_t* getDigestBytes(digest8_t digest) { + digest32_t d32; + getDigest(d32); + size_t di = 0; + digest[di++] = ((d32[0] >> 24) & 0xFF); + digest[di++] = ((d32[0] >> 16) & 0xFF); + digest[di++] = ((d32[0] >> 8) & 0xFF); + digest[di++] = ((d32[0]) & 0xFF); + + digest[di++] = ((d32[1] >> 24) & 0xFF); + digest[di++] = ((d32[1] >> 16) & 0xFF); + digest[di++] = ((d32[1] >> 8) & 0xFF); + digest[di++] = ((d32[1]) & 0xFF); + + digest[di++] = ((d32[2] >> 24) & 0xFF); + digest[di++] = ((d32[2] >> 16) & 0xFF); + digest[di++] = ((d32[2] >> 8) & 0xFF); + digest[di++] = ((d32[2]) & 0xFF); + + digest[di++] = ((d32[3] >> 24) & 0xFF); + digest[di++] = ((d32[3] >> 16) & 0xFF); + digest[di++] = ((d32[3] >> 8) & 0xFF); + digest[di++] = ((d32[3]) & 0xFF); + + digest[di++] = ((d32[4] >> 24) & 0xFF); + digest[di++] = ((d32[4] >> 16) & 0xFF); + digest[di++] = ((d32[4] >> 8) & 0xFF); + digest[di++] = ((d32[4]) & 0xFF); + return digest; + } + +protected: + void processBlock() { + uint32_t w[80]; + for (size_t i = 0; i < 16; i++) { + w[i] = (m_block[i * 4 + 0] << 24); + w[i] |= (m_block[i * 4 + 1] << 16); + w[i] |= (m_block[i * 4 + 2] << 8); + w[i] |= (m_block[i * 4 + 3]); + } + for (size_t i = 16; i < 80; i++) { + w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); + } + + uint32_t a = m_digest[0]; + uint32_t b = m_digest[1]; + uint32_t c = m_digest[2]; + uint32_t d = m_digest[3]; + uint32_t e = m_digest[4]; + + for (std::size_t i = 0; i < 80; ++i) { + uint32_t f = 0; + uint32_t k = 0; + + if (i < 20) { + f = (b & c) | (~b & d); + k = 0x5A827999; + } else if (i < 40) { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } else if (i < 60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } else { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = LeftRotate(b, 30); + b = a; + a = temp; + } + + m_digest[0] += a; + m_digest[1] += b; + m_digest[2] += c; + m_digest[3] += d; + m_digest[4] += e; + } + +private: + digest32_t m_digest; + uint8_t m_block[64]; + size_t m_blockByteIndex; + size_t m_byteCount; +}; +} // namespace sha1 diff --git a/gpu/shadps4/common/shared_first_mutex.h b/gpu/shadps4/common/shared_first_mutex.h new file mode 100644 index 0000000..dc4a2ca --- /dev/null +++ b/gpu/shadps4/common/shared_first_mutex.h @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +namespace Common { + +// Like std::shared_mutex, but reader has priority over writer. +class SharedFirstMutex { +public: + void lock() { + std::unique_lock lock(mtx); + cv.wait(lock, [this]() { return !writer_active && readers == 0; }); + writer_active = true; + } + + bool try_lock() { + std::lock_guard lock(mtx); + if (writer_active || readers > 0) { + return false; + } + writer_active = true; + return true; + } + + template + bool try_lock_until(const std::chrono::time_point& abs_time) { + std::unique_lock lock(mtx); + if (!cv.wait_until(lock, abs_time, [this]() { return !writer_active && readers == 0; })) { + return false; + } + writer_active = true; + return true; + } + + void unlock() { + std::lock_guard lock(mtx); + writer_active = false; + cv.notify_all(); + } + + void lock_shared() { + std::unique_lock lock(mtx); + cv.wait(lock, [this]() { return !writer_active; }); + ++readers; + } + + bool try_lock_shared() { + std::lock_guard lock(mtx); + if (writer_active) { + return false; + } + ++readers; + return true; + } + + template + bool try_lock_shared_until(const std::chrono::time_point& abs_time) { + std::unique_lock lock(mtx); + if (!cv.wait_until(lock, abs_time, [this]() { return !writer_active; })) { + return false; + } + ++readers; + return true; + } + + void unlock_shared() { + std::lock_guard lock(mtx); + if (--readers == 0) { + cv.notify_all(); + } + } + +private: + std::mutex mtx; + std::condition_variable cv; + int readers = 0; + bool writer_active = false; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/signal_context.cpp b/gpu/shadps4/common/signal_context.cpp new file mode 100644 index 0000000..67d8294 --- /dev/null +++ b/gpu/shadps4/common/signal_context.cpp @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/arch.h" +#include "common/signal_context.h" + +#ifdef _WIN32 +#include +#elif defined(__FreeBSD__) +#include +#include +#else +#include +#endif + +namespace Common { + +void* GetRip(void* ctx) { +#if defined(_WIN32) + return (void*)((EXCEPTION_POINTERS*)ctx)->ContextRecord->Rip; +#elif defined(__APPLE__) && defined(ARCH_X86_64) + return (void*)((ucontext_t*)ctx)->uc_mcontext->__ss.__rip; +#elif defined(__APPLE__) && defined(ARCH_ARM64) + return (void*)((ucontext_t*)ctx)->uc_mcontext->__ss.__pc; +#elif defined(__FreeBSD__) + return (void*)((ucontext_t*)ctx)->uc_mcontext.mc_rip; +#elif defined(ARCH_X86_64) + return (void*)((ucontext_t*)ctx)->uc_mcontext.gregs[REG_RIP]; +#else +#error "Unsupported architecture" +#endif +} + +bool IsWriteError(void* ctx) { +#if defined(_WIN32) + return ((EXCEPTION_POINTERS*)ctx)->ExceptionRecord->ExceptionInformation[0] == 1; +#elif defined(__APPLE__) && defined(ARCH_X86_64) + return ((ucontext_t*)ctx)->uc_mcontext->__es.__err & 0x2; +#elif defined(__APPLE__) && defined(ARCH_ARM64) + return ((ucontext_t*)ctx)->uc_mcontext->__es.__esr & 0x40; +#elif defined(__FreeBSD__) && defined(ARCH_X86_64) + return ((ucontext_t*)ctx)->uc_mcontext.mc_err & 0x2; +#elif defined(ARCH_X86_64) + return ((ucontext_t*)ctx)->uc_mcontext.gregs[REG_ERR] & 0x2; +#else +#error "Unsupported architecture" +#endif +} + +} // namespace Common diff --git a/gpu/shadps4/common/signal_context.h b/gpu/shadps4/common/signal_context.h new file mode 100644 index 0000000..b09da64 --- /dev/null +++ b/gpu/shadps4/common/signal_context.h @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Common { + +void* GetXmmPointer(void* ctx, u8 index); + +void* GetRip(void* ctx); + +void IncrementRip(void* ctx, u64 length); + +bool IsWriteError(void* ctx); + +} // namespace Common \ No newline at end of file diff --git a/gpu/shadps4/common/singleton.h b/gpu/shadps4/common/singleton.h new file mode 100644 index 0000000..0838980 --- /dev/null +++ b/gpu/shadps4/common/singleton.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Common { + +template +class Singleton { +public: + static T* Instance() { + if (!m_instance) { + m_instance = std::make_unique(); + } + return m_instance.get(); + } + +protected: + Singleton(); + ~Singleton(); + +private: + static inline std::unique_ptr m_instance{}; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/slab_heap.h b/gpu/shadps4/common/slab_heap.h new file mode 100644 index 0000000..17c539c --- /dev/null +++ b/gpu/shadps4/common/slab_heap.h @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/assert.h" +#include "common/spin_lock.h" + +namespace Common { + +class SlabHeapImpl { +public: + struct Node { + Node* next{}; + }; + +public: + constexpr SlabHeapImpl() = default; + + void Initialize() { + ASSERT(m_head == nullptr); + } + + Node* GetHead() const { + return m_head; + } + + void* Allocate() { + m_lock.lock(); + + Node* ret = m_head; + if (ret != nullptr) { + m_head = ret->next; + } + + m_lock.unlock(); + return ret; + } + + void Free(void* obj) { + m_lock.lock(); + + Node* node = static_cast(obj); + node->next = m_head; + m_head = node; + + m_lock.unlock(); + } + +private: + std::atomic m_head{}; + Common::SpinLock m_lock; +}; + +class SlabHeapBase : protected SlabHeapImpl { +private: + size_t m_obj_size{}; + uintptr_t m_peak{}; + uintptr_t m_start{}; + uintptr_t m_end{}; + +public: + constexpr SlabHeapBase() = default; + + bool Contains(uintptr_t address) const { + return m_start <= address && address < m_end; + } + + void Initialize(size_t obj_size, void* memory, size_t memory_size) { + // Ensure we don't initialize a slab using null memory. + ASSERT(memory != nullptr); + + // Set our object size. + m_obj_size = obj_size; + + // Initialize the base allocator. + SlabHeapImpl::Initialize(); + + // Set our tracking variables. + const size_t num_obj = (memory_size / obj_size); + m_start = reinterpret_cast(memory); + m_end = m_start + num_obj * obj_size; + m_peak = m_start; + + // Free the objects. + u8* cur = reinterpret_cast(m_end); + + for (size_t i = 0; i < num_obj; i++) { + cur -= obj_size; + SlabHeapImpl::Free(cur); + } + } + + size_t GetSlabHeapSize() const { + return (m_end - m_start) / this->GetObjectSize(); + } + + size_t GetObjectSize() const { + return m_obj_size; + } + + void* Allocate() { + void* obj = SlabHeapImpl::Allocate(); + return obj; + } + + void Free(void* obj) { + // Don't allow freeing an object that wasn't allocated from this heap. + const bool contained = this->Contains(reinterpret_cast(obj)); + ASSERT(contained); + SlabHeapImpl::Free(obj); + } + + size_t GetObjectIndex(const void* obj) const { + return (reinterpret_cast(obj) - m_start) / this->GetObjectSize(); + } + + size_t GetPeakIndex() const { + return this->GetObjectIndex(reinterpret_cast(m_peak)); + } + + uintptr_t GetSlabHeapAddress() const { + return m_start; + } + + size_t GetNumRemaining() const { + // Only calculate the number of remaining objects under debug configuration. + return 0; + } +}; + +template +class SlabHeap final : public SlabHeapBase { +private: + using BaseHeap = SlabHeapBase; + +public: + constexpr SlabHeap() = default; + + void Initialize(void* memory, size_t memory_size) { + BaseHeap::Initialize(sizeof(T), memory, memory_size); + } + + T* Allocate() { + T* obj = static_cast(BaseHeap::Allocate()); + + if (obj != nullptr) [[likely]] { + std::construct_at(obj); + } + return obj; + } + + void Free(T* obj) { + std::destroy_at(obj); + BaseHeap::Free(obj); + } + + size_t GetObjectIndex(const T* obj) const { + return BaseHeap::GetObjectIndex(obj); + } +}; + +} // namespace Common diff --git a/gpu/shadps4/common/slot_array.h b/gpu/shadps4/common/slot_array.h new file mode 100644 index 0000000..3a57899 --- /dev/null +++ b/gpu/shadps4/common/slot_array.h @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// #include + +#include +#include +#include +#include + +#include +#include + +namespace Common { + +template ::max(), IndexType MinIndex = 0> +class SlotArray { +public: + SlotArray() { + std::iota(m_free_indices.begin(), m_free_indices.end(), MinIndex); + } + + template + std::optional Create(Types&&... args) { + if (!HasFreeSlots()) { + return std::nullopt; + } + const auto index = m_free_indices[m_curr_cursor]; + m_resources[index - MinIndex] = ResourceType(std::forward(args)...); + m_curr_cursor += 1; + return index; + } + + bool Destroy(IndexType index) { + if (!m_resources[index - MinIndex].has_value()) { + return false; + } + m_curr_cursor -= 1; + m_free_indices[m_curr_cursor] = index; + m_resources[index - MinIndex] = std::nullopt; + return true; + } + + ResourceType* Get(IndexType index) { + auto& resource = m_resources[index - MinIndex]; + if (!resource.has_value()) { + return nullptr; + } + return &resource.value(); + } + + bool HasFreeSlots() { + return m_curr_cursor < m_free_indices.size(); + } + +private: + size_t m_curr_cursor = 0; + std::array m_free_indices; + std::array, MaxIndex - MinIndex> m_resources; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/slot_vector.h b/gpu/shadps4/common/slot_vector.h new file mode 100644 index 0000000..2f693fb --- /dev/null +++ b/gpu/shadps4/common/slot_vector.h @@ -0,0 +1,273 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include "common/assert.h" +#include "common/types.h" + +namespace Common { + +struct SlotId { + static constexpr u32 INVALID_INDEX = std::numeric_limits::max(); + + SlotId() noexcept = default; + constexpr SlotId(u32 index) noexcept : index(index) {} + + constexpr auto operator<=>(const SlotId&) const noexcept = default; + + constexpr explicit operator bool() const noexcept { + return index != INVALID_INDEX; + } + + u32 index = INVALID_INDEX; +}; + +template +class SlotVector { + constexpr static std::size_t InitialCapacity = 2048; + +public: + template + class Iterator { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = ValueType; + using difference_type = std::ptrdiff_t; + using pointer = Pointer; + using reference = Reference; + + Iterator(SlotVector& vector_, SlotId index_) : vector(vector_), slot(index_) { + AdvanceToValid(); + } + + reference operator*() const { + return vector[slot]; + } + + pointer operator->() const { + return &vector[slot]; + } + + Iterator& operator++() { + ++slot.index; + AdvanceToValid(); + return *this; + } + + Iterator operator++(int) { + Iterator temp = *this; + ++(*this); + return temp; + } + + bool operator==(const Iterator& other) const { + return slot == other.slot; + } + + bool operator!=(const Iterator& other) const { + return !(*this == other); + } + + private: + void AdvanceToValid() { + while (slot < vector.values_capacity && !vector.ReadStorageBit(slot.index)) { + ++slot.index; + } + } + + SlotVector& vector; + SlotId slot; + }; + + using iterator = Iterator; + using const_iterator = Iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + SlotVector() { + Reserve(InitialCapacity); + } + + ~SlotVector() noexcept { + std::size_t index = 0; + for (u64 bits : stored_bitset) { + for (std::size_t bit = 0; bits; ++bit, bits >>= 1) { + if ((bits & 1) != 0) { + values[index + bit].object.~T(); + } + } + index += 64; + } + delete[] values; + } + + [[nodiscard]] T& operator[](SlotId id) noexcept { + ValidateIndex(id); + return values[id.index].object; + } + + [[nodiscard]] const T& operator[](SlotId id) const noexcept { + ValidateIndex(id); + return values[id.index].object; + } + + bool is_allocated(SlotId id) const { + return ReadStorageBit(id.index); + } + + template + SlotId insert(Args&&... args) noexcept { + const u32 index = FreeValueIndex(); + new (&values[index].object) T(std::forward(args)...); + SetStorageBit(index); + + return SlotId{index}; + } + + void erase(SlotId id) noexcept { + values[id.index].object.~T(); + free_list.push_back(id.index); + ResetStorageBit(id.index); + } + + std::size_t size() const noexcept { + return values_capacity - free_list.size(); + } + + iterator begin() noexcept { + return iterator(*this, 0); + } + + const_iterator begin() const noexcept { + return const_iterator(*this, 0); + } + + const_iterator cbegin() const noexcept { + return begin(); + } + + iterator end() noexcept { + return iterator(*this, values_capacity); + } + + const_iterator end() const noexcept { + return const_iterator(*this, values_capacity); + } + + const_iterator cend() const noexcept { + return end(); + } + + reverse_iterator rbegin() noexcept { + return reverse_iterator(end()); + } + + const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(end()); + } + + const_reverse_iterator crbegin() const noexcept { + return rbegin(); + } + + reverse_iterator rend() noexcept { + return reverse_iterator(begin()); + } + + const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator crend() const noexcept { + return rend(); + } + +private: + struct NonTrivialDummy { + NonTrivialDummy() noexcept {} + }; + + union Entry { + Entry() noexcept : dummy{} {} + ~Entry() noexcept {} + + NonTrivialDummy dummy; + T object; + }; + + void SetStorageBit(u32 index) noexcept { + stored_bitset[index / 64] |= u64(1) << (index % 64); + } + + void ResetStorageBit(u32 index) noexcept { + stored_bitset[index / 64] &= ~(u64(1) << (index % 64)); + } + + bool ReadStorageBit(u32 index) const noexcept { + return ((stored_bitset[index / 64] >> (index % 64)) & 1) != 0; + } + + void ValidateIndex([[maybe_unused]] SlotId id) const noexcept { + DEBUG_ASSERT(id); + DEBUG_ASSERT(id.index / 64 < stored_bitset.size()); + DEBUG_ASSERT(((stored_bitset[id.index / 64] >> (id.index % 64)) & 1) != 0); + } + + [[nodiscard]] u32 FreeValueIndex() noexcept { + if (free_list.empty()) { + Reserve(values_capacity ? (values_capacity << 1) : 1); + } + + const u32 free_index = free_list.back(); + free_list.pop_back(); + return free_index; + } + + void Reserve(std::size_t new_capacity) noexcept { + Entry* const new_values = new Entry[new_capacity]; + std::size_t index = 0; + for (u64 bits : stored_bitset) { + for (std::size_t bit = 0; bits; ++bit, bits >>= 1) { + const std::size_t i = index + bit; + if ((bits & 1) == 0) { + continue; + } + T& old_value = values[i].object; + new (&new_values[i].object) T(std::move(old_value)); + old_value.~T(); + } + index += 64; + } + + stored_bitset.resize((new_capacity + 63) / 64); + + const std::size_t old_free_size = free_list.size(); + free_list.resize(old_free_size + (new_capacity - values_capacity)); + const std::size_t new_free_size = free_list.size(); + std::iota(free_list.rbegin(), free_list.rbegin() + new_free_size - old_free_size, + static_cast(values_capacity)); + + delete[] values; + values = new_values; + values_capacity = new_capacity; + } + + Entry* values = nullptr; + std::size_t values_capacity = 0; + + std::vector stored_bitset; + std::vector free_list; +}; + +} // namespace Common + +template <> +struct std::hash { + std::size_t operator()(const Common::SlotId& id) const noexcept { + return std::hash{}(id.index); + } +}; diff --git a/gpu/shadps4/common/spin_lock.cpp b/gpu/shadps4/common/spin_lock.cpp new file mode 100755 index 0000000..b2ef4ea --- /dev/null +++ b/gpu/shadps4/common/spin_lock.cpp @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/spin_lock.h" + +#if _MSC_VER +#include +#if _M_AMD64 +#define __x86_64__ 1 +#endif +#if _M_ARM64 +#define __aarch64__ 1 +#endif +#else +#if __x86_64__ +#include +#endif +#endif + +namespace { + +void ThreadPause() { +#if __x86_64__ + _mm_pause(); +#elif __aarch64__ && _MSC_VER + __yield(); +#elif __aarch64__ + asm("yield"); +#endif +} + +} // Anonymous namespace + +namespace Common { + +void SpinLock::lock() { + while (lck.test_and_set(std::memory_order_acquire)) { + ThreadPause(); + } +} + +void SpinLock::unlock() { + lck.clear(std::memory_order_release); +} + +bool SpinLock::try_lock() { + if (lck.test_and_set(std::memory_order_acquire)) { + return false; + } + return true; +} + +} // namespace Common diff --git a/gpu/shadps4/common/spin_lock.h b/gpu/shadps4/common/spin_lock.h new file mode 100755 index 0000000..a832748 --- /dev/null +++ b/gpu/shadps4/common/spin_lock.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Common { + +/** + * SpinLock class + * a lock similar to mutex that forces a thread to spin wait instead calling the + * supervisor. Should be used on short sequences of code. + */ +class SpinLock { +public: + SpinLock() = default; + + SpinLock(const SpinLock&) = delete; + SpinLock& operator=(const SpinLock&) = delete; + + SpinLock(SpinLock&&) = delete; + SpinLock& operator=(SpinLock&&) = delete; + + void lock(); + void unlock(); + [[nodiscard]] bool try_lock(); + +private: + std::atomic_flag lck = ATOMIC_FLAG_INIT; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/stb.cpp b/gpu/shadps4/common/stb.cpp new file mode 100644 index 0000000..5ab045f --- /dev/null +++ b/gpu/shadps4/common/stb.cpp @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_WRITE_IMPLEMENTATION +#define STBI_ONLY_PNG +#define STBI_NO_STDIO +#include "common/stb.h" diff --git a/gpu/shadps4/common/stb.h b/gpu/shadps4/common/stb.h new file mode 100644 index 0000000..7ecf164 --- /dev/null +++ b/gpu/shadps4/common/stb.h @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include diff --git a/gpu/shadps4/common/string_literal.h b/gpu/shadps4/common/string_literal.h new file mode 100644 index 0000000..9f64f62 --- /dev/null +++ b/gpu/shadps4/common/string_literal.h @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +template +struct StringLiteral { + static constexpr size_t len = N; + + constexpr StringLiteral(const C (&str)[N]) { + std::copy_n(str, N, value); + } + + C value[N]{}; +}; diff --git a/gpu/shadps4/common/string_util.cpp b/gpu/shadps4/common/string_util.cpp new file mode 100644 index 0000000..4658d0e --- /dev/null +++ b/gpu/shadps4/common/string_util.cpp @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include "common/string_util.h" +#include "common/types.h" + +#ifdef _WIN32 +#include +#endif + +namespace Common { + +std::string ToLower(std::string_view input) { + std::string str; + str.resize(input.size()); + std::ranges::transform(input, str.begin(), tolower); + return str; +} + +void ToLowerInPlace(std::string& str) { + std::ranges::transform(str, str.begin(), tolower); +} + +std::vector SplitString(const std::string& str, char delimiter) { + std::istringstream iss(str); + std::vector output(1); + + while (std::getline(iss, *output.rbegin(), delimiter)) { + output.emplace_back(); + } + + output.pop_back(); + return output; +} + +std::string_view U8stringToString(std::u8string_view u8str) { + return std::string_view{reinterpret_cast(u8str.data()), u8str.size()}; +} + +#ifdef _WIN32 +static std::wstring CPToUTF16(u32 code_page, std::string_view input) { + const auto size = + MultiByteToWideChar(code_page, 0, input.data(), static_cast(input.size()), nullptr, 0); + + if (size == 0) { + return {}; + } + + std::wstring output(size, L'\0'); + + if (size != MultiByteToWideChar(code_page, 0, input.data(), static_cast(input.size()), + &output[0], static_cast(output.size()))) { + output.clear(); + } + + return output; +} + +std::string UTF16ToUTF8(std::wstring_view input) { + const auto size = WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast(input.size()), + nullptr, 0, nullptr, nullptr); + if (size == 0) { + return {}; + } + + std::string output(size, '\0'); + + if (size != WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast(input.size()), + &output[0], static_cast(output.size()), nullptr, + nullptr)) { + output.clear(); + } + + return output; +} + +std::wstring UTF8ToUTF16W(std::string_view input) { + return CPToUTF16(CP_UTF8, input); +} +#endif + +} // namespace Common diff --git a/gpu/shadps4/common/string_util.h b/gpu/shadps4/common/string_util.h new file mode 100644 index 0000000..18972de --- /dev/null +++ b/gpu/shadps4/common/string_util.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +namespace Common { + +/// Make a string lowercase +[[nodiscard]] std::string ToLower(std::string_view str); + +void ToLowerInPlace(std::string& str); + +std::vector SplitString(const std::string& str, char delimiter); + +std::string_view U8stringToString(std::u8string_view u8str); + +#ifdef _WIN32 +[[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input); +[[nodiscard]] std::wstring UTF8ToUTF16W(std::string_view str); +#endif + +} // namespace Common diff --git a/gpu/shadps4/common/support/avdec.h b/gpu/shadps4/common/support/avdec.h new file mode 100644 index 0000000..fa3483d --- /dev/null +++ b/gpu/shadps4/common/support/avdec.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +// support header file for libav + +// The av_err2str macro in libavutil/error.h does not play nice with C++ +#ifdef av_err2str +#undef av_err2str +#include +av_always_inline std::string av_err2string(int errnum) { + char errbuf[AV_ERROR_MAX_STRING_SIZE]; + return av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, errnum); +} +#define av_err2str(err) av_err2string(err).c_str() +#endif // av_err2str diff --git a/gpu/shadps4/common/thread.cpp b/gpu/shadps4/common/thread.cpp new file mode 100644 index 0000000..a6c9dd9 --- /dev/null +++ b/gpu/shadps4/common/thread.cpp @@ -0,0 +1,263 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include + + +#include "common/error.h" +#include "common/logging/log.h" +#include "common/thread.h" +#include "ntapi.h" +#ifdef __APPLE__ +#include +#include +#include +#elif defined(_WIN32) +#include +#include "common/string_util.h" +#else +#if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#include +#else +#include +#endif +#include +#endif +#ifndef _WIN32 +#include +#endif + +#ifdef __FreeBSD__ +#define cpu_set_t cpuset_t +#endif + +namespace Common { + +#ifdef __APPLE__ + +void SetCurrentThreadRealtime(const std::chrono::nanoseconds period_ns) { + // CPU time to grant. + const std::chrono::nanoseconds computation_ns = period_ns / 2; + + // Determine the timebase for converting time to ticks. + struct mach_timebase_info timebase{}; + mach_timebase_info(&timebase); + const auto ticks_per_ns = + static_cast(timebase.denom) / static_cast(timebase.numer); + + const auto period_ticks = + static_cast(static_cast(period_ns.count()) * ticks_per_ns); + const auto computation_ticks = + static_cast(static_cast(computation_ns.count()) * ticks_per_ns); + + thread_time_constraint_policy policy = { + .period = period_ticks, + .computation = computation_ticks, + // Should not matter since preemptible is false, but needs to be >= computation regardless. + .constraint = computation_ticks, + .preemptible = false, + }; + + int ret = thread_policy_set( + pthread_mach_thread_np(pthread_self()), THREAD_TIME_CONSTRAINT_POLICY, + reinterpret_cast(&policy), THREAD_TIME_CONSTRAINT_POLICY_COUNT); + if (ret != KERN_SUCCESS) { + LOG_ERROR(Common, "Could not set thread to real-time with period {} ns: {}", + period_ns.count(), ret); + } +} + +#else + +void SetCurrentThreadRealtime(const std::chrono::nanoseconds period_ns) { + // Not implemented +} + +#endif + +#ifdef _WIN32 + +void SetCurrentThreadPriority(ThreadPriority new_priority) { + auto handle = GetCurrentThread(); + int windows_priority = 0; + switch (new_priority) { + case ThreadPriority::Low: + windows_priority = THREAD_PRIORITY_BELOW_NORMAL; + break; + case ThreadPriority::Normal: + windows_priority = THREAD_PRIORITY_NORMAL; + break; + case ThreadPriority::High: + windows_priority = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case ThreadPriority::VeryHigh: + windows_priority = THREAD_PRIORITY_HIGHEST; + break; + case ThreadPriority::Critical: + windows_priority = THREAD_PRIORITY_TIME_CRITICAL; + break; + default: + windows_priority = THREAD_PRIORITY_NORMAL; + break; + } + SetThreadPriority(handle, windows_priority); +} + +bool AccurateSleep(const std::chrono::nanoseconds duration, std::chrono::nanoseconds* remaining, + const bool interruptible) { + const auto begin_sleep = std::chrono::high_resolution_clock::now(); + + LARGE_INTEGER interval{ + .QuadPart = -1 * (duration.count() / 100u), + }; + HANDLE timer = ::CreateWaitableTimer(NULL, TRUE, NULL); + SetWaitableTimer(timer, &interval, 0, NULL, NULL, 0); + const auto ret = WaitForSingleObjectEx(timer, INFINITE, interruptible); + ::CloseHandle(timer); + + if (remaining) { + const auto end_sleep = std::chrono::high_resolution_clock::now(); + const auto sleep_time = end_sleep - begin_sleep; + *remaining = duration > sleep_time ? duration - sleep_time : std::chrono::nanoseconds(0); + } + return ret == WAIT_OBJECT_0; +} + +#else + +void SetCurrentThreadPriority(ThreadPriority new_priority) { + pthread_t this_thread = pthread_self(); + + const auto scheduling_type = SCHED_OTHER; + s32 max_prio = sched_get_priority_max(scheduling_type); + s32 min_prio = sched_get_priority_min(scheduling_type); + u32 level = std::max(static_cast(new_priority) + 1, 4U); + + struct sched_param params; + if (max_prio > min_prio) { + params.sched_priority = min_prio + ((max_prio - min_prio) * level) / 4; + } else { + params.sched_priority = min_prio - ((min_prio - max_prio) * level) / 4; + } + + pthread_setschedparam(this_thread, scheduling_type, ¶ms); +} + +bool AccurateSleep(const std::chrono::nanoseconds duration, std::chrono::nanoseconds* remaining, + const bool interruptible) { + timespec request = { + .tv_sec = duration.count() / 1'000'000'000, + .tv_nsec = duration.count() % 1'000'000'000, + }; + timespec remain; + int ret; + while ((ret = nanosleep(&request, &remain)) < 0 && errno == EINTR) { + if (interruptible) { + break; + } + request = remain; + } + if (remaining) { + *remaining = std::chrono::nanoseconds(remain.tv_sec * 1'000'000'000 + remain.tv_nsec); + } + return ret == 0 || errno != EINTR; +} + +#endif + +#ifdef _WIN32 + +// Sets the debugger-visible name of the current thread. +void SetCurrentThreadName(const char* name) { + // bbport: guest thread names are kept by the C runtime. + SetThreadDescription(GetCurrentThread(), UTF8ToUTF16W(name).data()); +} + +void SetThreadName(void* thread, const char* name) { + SetThreadDescription(thread, UTF8ToUTF16W(name).data()); +} + +#else // !_WIN32, so must be POSIX threads + +// MinGW with the POSIX threading model does not support pthread_setname_np +#if !defined(_WIN32) || defined(_MSC_VER) +void SetCurrentThreadName(const char* name) { + // bbport: guest thread names are kept by the C runtime. +#ifdef __APPLE__ + pthread_setname_np(name); +#elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) + pthread_set_name_np(pthread_self(), name); +#elif defined(__NetBSD__) + pthread_setname_np(pthread_self(), "%s", (void*)name); +#elif defined(__linux__) + // Linux limits thread names to 15 characters and will outright reject any + // attempt to set a longer name with ERANGE. + std::string truncated(name, std::min(strlen(name), static_cast(15))); + if (int e = pthread_setname_np(pthread_self(), truncated.c_str())) { + errno = e; + LOG_ERROR(Common, "Failed to set thread name to '{}': {}", truncated, GetLastErrorMsg()); + } +#else + pthread_setname_np(pthread_self(), name); +#endif +} + +void SetThreadName(void* thread, const char* name) { + // TODO +} +#endif + +#if defined(_WIN32) +void SetCurrentThreadName(const char* name) { + // bbport: guest thread names are kept by the C runtime. + // Do Nothing on MinGW +} + +void SetThreadName(void* thread, const char* name) { + // Do Nothing on MinGW +} +#endif + +#endif + +AccurateTimer::AccurateTimer(std::chrono::nanoseconds target_interval) + : target_interval(target_interval) {} + +void AccurateTimer::Start() { + const auto begin_sleep = std::chrono::high_resolution_clock::now(); + if (total_wait.count() > 0) { + AccurateSleep(total_wait, nullptr, false); + } + start_time = std::chrono::high_resolution_clock::now(); + total_wait -= std::chrono::duration_cast(start_time - begin_sleep); +} + +void AccurateTimer::End() { + auto now = std::chrono::high_resolution_clock::now(); + total_wait += + target_interval - std::chrono::duration_cast(now - start_time); +} + +std::string GetCurrentThreadName() { +#ifdef _WIN32 + PWSTR name{}; + if (FAILED(GetThreadDescription(GetCurrentThread(), &name)) || name == nullptr) { + return ""; + } + const auto result = Common::UTF16ToUTF8(name); + LocalFree(name); + return result; +#else + char name[256]; + if (pthread_getname_np(pthread_self(), name, sizeof(name)) != 0) { + return ""; + } + return std::string{name}; +#endif +} + +} // namespace Common diff --git a/gpu/shadps4/common/thread.h b/gpu/shadps4/common/thread.h new file mode 100644 index 0000000..a300d10 --- /dev/null +++ b/gpu/shadps4/common/thread.h @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project +// SPDX-FileCopyrightText: 2014 Citra Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace Common { + +enum class ThreadPriority : u32 { + Low = 0, + Normal = 1, + High = 2, + VeryHigh = 3, + Critical = 4, +}; + +void SetCurrentThreadRealtime(std::chrono::nanoseconds period_ns); + +void SetCurrentThreadPriority(ThreadPriority new_priority); + +void SetCurrentThreadName(const char* name); + +void SetThreadName(void* thread, const char* name); + +bool AccurateSleep(std::chrono::nanoseconds duration, std::chrono::nanoseconds* remaining, + bool interruptible); + +class AccurateTimer { + std::chrono::nanoseconds target_interval{}; + std::chrono::nanoseconds total_wait{}; + + std::chrono::high_resolution_clock::time_point start_time; + +public: + explicit AccurateTimer(std::chrono::nanoseconds target_interval); + + void Start(); + + void End(); + + std::chrono::nanoseconds GetTotalWait() const { + return total_wait; + } +}; + +std::string GetCurrentThreadName(); + +} // namespace Common diff --git a/gpu/shadps4/common/types.h b/gpu/shadps4/common/types.h new file mode 100644 index 0000000..c2b7bd3 --- /dev/null +++ b/gpu/shadps4/common/types.h @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +using s8 = std::int8_t; +using s16 = std::int16_t; +using s32 = std::int32_t; +using s64 = std::int64_t; + +using u8 = std::uint8_t; +using u16 = std::uint16_t; +using u32 = std::uint32_t; +using u64 = std::uint64_t; + +using f32 = float; +using f64 = double; + +using u128 = std::array; +static_assert(sizeof(u128) == 16, "u128 must be 128 bits wide"); + +using VAddr = uintptr_t; +using PAddr = uintptr_t; + +#define PS4_SYSV_ABI __attribute__((sysv_abi)) + +// UDLs for memory size values +constexpr unsigned long long operator""_KB(unsigned long long x) { + return 1024ULL * x; +} +constexpr unsigned long long operator""_MB(unsigned long long x) { + return 1024_KB * x; +} +constexpr unsigned long long operator""_GB(unsigned long long x) { + return 1024_MB * x; +} diff --git a/gpu/shadps4/common/uint128.h b/gpu/shadps4/common/uint128.h new file mode 100644 index 0000000..77c4a27 --- /dev/null +++ b/gpu/shadps4/common/uint128.h @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#ifdef _MSC_VER +#ifndef __clang__ +#define HAS_INTRINSICS +#include +#pragma intrinsic(__umulh) +#pragma intrinsic(_umul128) +#pragma intrinsic(_udiv128) +#else +#endif +#else +#include +#endif + +#include "common/types.h" + +namespace Common { + +// This function multiplies 2 u64 values and divides it by a u64 value. +[[nodiscard]] static inline u64 MultiplyAndDivide64(u64 a, u64 b, u64 d) { +#ifdef HAS_INTRINSICS + u128 r{}; + r[0] = _umul128(a, b, &r[1]); + u64 remainder; + return _udiv128(r[1], r[0], d, &remainder); +#else + const u64 diva = a / d; + const u64 moda = a % d; + const u64 divb = b / d; + const u64 modb = b % d; + return diva * b + moda * divb + moda * modb / d; +#endif +} + +// This function multiplies 2 u64 values and produces a u128 value; +[[nodiscard]] static inline u128 Multiply64Into128(u64 a, u64 b) { + u128 result; +#ifdef HAS_INTRINSICS + result[0] = _umul128(a, b, &result[1]); +#else + unsigned __int128 tmp = a; + tmp *= b; + std::memcpy(&result, &tmp, sizeof(u128)); +#endif + return result; +} + +[[nodiscard]] static inline u64 GetFixedPoint64Factor(u64 numerator, u64 divisor) { +#ifdef __SIZEOF_INT128__ + const auto base = static_cast(numerator) << 64ULL; + return static_cast(base / divisor); +#elif defined(_M_X64) || defined(_M_ARM64) + std::array r = {0, numerator}; + u64 remainder; + return _udiv128(r[1], r[0], divisor, &remainder); +#else + // This one is bit more inaccurate. + return MultiplyAndDivide64(std::numeric_limits::max(), numerator, divisor); +#endif +} + +[[nodiscard]] static inline u64 MultiplyHigh(u64 a, u64 b) { +#ifdef __SIZEOF_INT128__ + return (static_cast(a) * static_cast(b)) >> 64; +#elif defined(_M_X64) || defined(_M_ARM64) + return __umulh(a, b); // MSVC +#else + // Generic fallback + const u64 a_lo = u32(a); + const u64 a_hi = a >> 32; + const u64 b_lo = u32(b); + const u64 b_hi = b >> 32; + + const u64 a_x_b_hi = a_hi * b_hi; + const u64 a_x_b_mid = a_hi * b_lo; + const u64 b_x_a_mid = b_hi * a_lo; + const u64 a_x_b_lo = a_lo * b_lo; + + const u64 carry_bit = (static_cast(static_cast(a_x_b_mid)) + + static_cast(static_cast(b_x_a_mid)) + (a_x_b_lo >> 32)) >> + 32; + + const u64 multhi = a_x_b_hi + (a_x_b_mid >> 32) + (b_x_a_mid >> 32) + carry_bit; + + return multhi; +#endif +} + +// This function divides a u128 by a u32 value and produces two u64 values: +// the result of division and the remainder +[[nodiscard]] static inline std::pair Divide128On32(const u128& dividend, u32 divisor) { + u64 remainder = dividend[0] % divisor; + u64 accum = dividend[0] / divisor; + if (dividend[1] == 0) + return {accum, remainder}; + // We ignore dividend[1] / divisor as that overflows + const u64 first_segment = (dividend[1] % divisor) << 32; + accum += (first_segment / divisor) << 32; + const u64 second_segment = (first_segment % divisor) << 32; + accum += (second_segment / divisor); + remainder += second_segment % divisor; + if (remainder >= divisor) { + accum++; + remainder -= divisor; + } + return {accum, remainder}; +} + +} // namespace Common diff --git a/gpu/shadps4/common/unique_function.h b/gpu/shadps4/common/unique_function.h new file mode 100755 index 0000000..c15d883 --- /dev/null +++ b/gpu/shadps4/common/unique_function.h @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +namespace Common { + +/// General purpose function wrapper similar to std::function. +/// Unlike std::function, the captured values don't have to be copyable. +/// This class can be moved but not copied. +template +class UniqueFunction { + class CallableBase { + public: + virtual ~CallableBase() = default; + virtual ResultType operator()(Args&&...) = 0; + }; + + template + class Callable final : public CallableBase { + public: + Callable(Functor&& functor_) : functor{std::move(functor_)} {} + ~Callable() override = default; + + ResultType operator()(Args&&... args) override { + return functor(std::forward(args)...); + } + + private: + Functor functor; + }; + +public: + UniqueFunction() = default; + + template + UniqueFunction(Functor&& functor) + : callable{std::make_unique>(std::move(functor))} {} + + UniqueFunction& operator=(UniqueFunction&& rhs) noexcept = default; + UniqueFunction(UniqueFunction&& rhs) noexcept = default; + + UniqueFunction& operator=(const UniqueFunction&) = delete; + UniqueFunction(const UniqueFunction&) = delete; + + ResultType operator()(Args&&... args) const { + return (*callable)(std::forward(args)...); + } + + explicit operator bool() const noexcept { + return static_cast(callable); + } + +private: + std::unique_ptr callable; +}; + +} // namespace Common diff --git a/gpu/shadps4/common/va_ctx.h b/gpu/shadps4/common/va_ctx.h new file mode 100644 index 0000000..ed2deed --- /dev/null +++ b/gpu/shadps4/common/va_ctx.h @@ -0,0 +1,118 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include "common/arch.h" +#include "common/types.h" + +#ifdef ARCH_X86_64 +#include +#else +// FIXME +typedef __int128 __m128; +#endif + +#define VA_ARGS \ + uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9, \ + uint64_t overflow_arg_area, __m128 xmm0, __m128 xmm1, __m128 xmm2, __m128 xmm3, \ + __m128 xmm4, __m128 xmm5, __m128 xmm6, __m128 xmm7 + +#define VA_CTX(ctx) \ + alignas(16)::Common::VaCtx ctx{}; \ + (ctx).reg_save_area.gp[0] = rdi; \ + (ctx).reg_save_area.gp[1] = rsi; \ + (ctx).reg_save_area.gp[2] = rdx; \ + (ctx).reg_save_area.gp[3] = rcx; \ + (ctx).reg_save_area.gp[4] = r8; \ + (ctx).reg_save_area.gp[5] = r9; \ + (ctx).reg_save_area.fp[0] = xmm0; \ + (ctx).reg_save_area.fp[1] = xmm1; \ + (ctx).reg_save_area.fp[2] = xmm2; \ + (ctx).reg_save_area.fp[3] = xmm3; \ + (ctx).reg_save_area.fp[4] = xmm4; \ + (ctx).reg_save_area.fp[5] = xmm5; \ + (ctx).reg_save_area.fp[6] = xmm6; \ + (ctx).reg_save_area.fp[7] = xmm7; \ + (ctx).va_list.reg_save_area = &(ctx).reg_save_area; \ + (ctx).va_list.gp_offset = offsetof(::Common::VaRegSave, gp); \ + (ctx).va_list.fp_offset = offsetof(::Common::VaRegSave, fp); \ + (ctx).va_list.overflow_arg_area = &overflow_arg_area; + +namespace Common { + +// https://stackoverflow.com/questions/4958384/what-is-the-format-of-the-x86-64-va-list-structure + +struct VaList { + u32 gp_offset; + u32 fp_offset; + void* overflow_arg_area; + void* reg_save_area; +}; + +struct VaRegSave { + u64 gp[6]; + __m128 fp[8]; +}; + +struct VaCtx { + VaRegSave reg_save_area; + VaList va_list; +}; + +template +T vaArgRegSaveAreaGp(VaList* l) { + auto* addr = reinterpret_cast(static_cast(l->reg_save_area) + l->gp_offset); + l->gp_offset += Size; + return *addr; +} +template +T vaArgOverflowArgArea(VaList* l) { + auto ptr = ((reinterpret_cast(l->overflow_arg_area) + (Align - 1)) & ~(Align - 1)); + auto* addr = reinterpret_cast(ptr); + l->overflow_arg_area = reinterpret_cast(ptr + Size); + return *addr; +} + +template +T vaArgRegSaveAreaFp(VaList* l) { + auto* addr = reinterpret_cast(static_cast(l->reg_save_area) + l->fp_offset); + l->fp_offset += Size; + return *addr; +} + +inline int vaArgInteger(VaList* l) { + if (l->gp_offset <= 40) { + return vaArgRegSaveAreaGp(l); + } + return vaArgOverflowArgArea(l); +} + +inline long long vaArgLongLong(VaList* l) { + if (l->gp_offset <= 40) { + return vaArgRegSaveAreaGp(l); + } + return vaArgOverflowArgArea(l); +} +inline long vaArgLong(VaList* l) { + if (l->gp_offset <= 40) { + return vaArgRegSaveAreaGp(l); + } + return vaArgOverflowArgArea(l); +} + +inline double vaArgDouble(VaList* l) { + if (l->fp_offset <= 160) { + return vaArgRegSaveAreaFp(l); + } + return vaArgOverflowArgArea(l); +} + +template +T* vaArgPtr(VaList* l) { + if (l->gp_offset <= 40) { + return vaArgRegSaveAreaGp(l); + } + return vaArgOverflowArgArea(l); +} + +} // namespace Common diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer.cpp b/gpu/shadps4/core/libraries/avplayer/avplayer.cpp new file mode 100644 index 0000000..63556db --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer.cpp @@ -0,0 +1,283 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/libraries/avplayer/avplayer.h" +#include "core/libraries/avplayer/avplayer_error.h" +#include "core/libraries/avplayer/avplayer_impl.h" +#include "core/libraries/libs.h" + +#include + +namespace Libraries::AvPlayer { + +s32 PS4_SYSV_ABI sceAvPlayerAddSource(AvPlayerHandle handle, const char* filename) { + LOG_TRACE(Lib_AvPlayer, "filename = {}", filename); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->AddSource(filename); +} + +s32 PS4_SYSV_ABI sceAvPlayerAddSourceEx(AvPlayerHandle handle, AvPlayerUriType uri_type, + AvPlayerSourceDetails* source_details) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr || uri_type != AvPlayerUriType::Source || source_details == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + const auto path = std::string_view(source_details->uri.name, source_details->uri.length); + return handle->AddSourceEx(path, source_details->source_type); +} + +int PS4_SYSV_ABI sceAvPlayerChangeStream() { + LOG_ERROR(Lib_AvPlayer, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceAvPlayerClose(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + delete handle; + return ORBIS_OK; +} + +u64 PS4_SYSV_ABI sceAvPlayerCurrentTime(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->CurrentTime(); +} + +s32 PS4_SYSV_ABI sceAvPlayerDisableStream(AvPlayerHandle handle, u32 stream_id) { + LOG_ERROR(Lib_AvPlayer, "(STUBBED) called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceAvPlayerEnableStream(AvPlayerHandle handle, u32 stream_id) { + LOG_TRACE(Lib_AvPlayer, "stream_id = {}", stream_id); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->EnableStream(stream_id); +} + +bool PS4_SYSV_ABI sceAvPlayerGetAudioData(AvPlayerHandle handle, AvPlayerFrameInfo* p_info) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr || p_info == nullptr) { + return false; + } + return handle->GetAudioData(*p_info); +} + +s32 PS4_SYSV_ABI sceAvPlayerGetStreamInfo(AvPlayerHandle handle, u32 stream_id, + AvPlayerStreamInfo* p_info) { + LOG_TRACE(Lib_AvPlayer, "stream_id = {}", stream_id); + if (handle == nullptr || p_info == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->GetStreamInfo(stream_id, *p_info); +} + +bool PS4_SYSV_ABI sceAvPlayerGetVideoData(AvPlayerHandle handle, AvPlayerFrameInfo* video_info) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr || video_info == nullptr) { + return false; + } + return handle->GetVideoData(*video_info); +} + +bool PS4_SYSV_ABI sceAvPlayerGetVideoDataEx(AvPlayerHandle handle, + AvPlayerFrameInfoEx* video_info) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr || video_info == nullptr) { + return false; + } + return handle->GetVideoData(*video_info); +} + +AvPlayerHandle PS4_SYSV_ABI sceAvPlayerInit(AvPlayerInitData* data) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (data == nullptr) { + return nullptr; + } + + if (data->memory_replacement.allocate == nullptr || + data->memory_replacement.allocate_texture == nullptr || + data->memory_replacement.deallocate == nullptr || + data->memory_replacement.deallocate_texture == nullptr) { + LOG_ERROR(Lib_AvPlayer, "All allocators are required for AvPlayer Initialisation."); + return nullptr; + } + + return new AvPlayer(*data); +} + +s32 PS4_SYSV_ABI sceAvPlayerInitEx(const AvPlayerInitDataEx* p_data, AvPlayerHandle* p_player) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (p_data == nullptr || p_player == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + + if (p_data->memory_replacement.allocate == nullptr || + p_data->memory_replacement.allocate_texture == nullptr || + p_data->memory_replacement.deallocate == nullptr || + p_data->memory_replacement.deallocate_texture == nullptr) { + LOG_ERROR(Lib_AvPlayer, "All allocators are required for AvPlayer Initialisation."); + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + + AvPlayerInitData data = {}; + data.memory_replacement = p_data->memory_replacement; + data.file_replacement = p_data->file_replacement; + data.event_replacement = p_data->event_replacement; + data.default_language = p_data->default_language; + data.num_output_video_framebuffers = p_data->num_output_video_framebuffers; + data.auto_start = p_data->auto_start; + + *p_player = new AvPlayer(data); + return ORBIS_OK; +} + +bool PS4_SYSV_ABI sceAvPlayerIsActive(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return false; + } + return handle->IsActive(); +} + +s32 PS4_SYSV_ABI sceAvPlayerJumpToTime(AvPlayerHandle handle, uint64_t time) { + LOG_ERROR(Lib_AvPlayer, "(STUBBED) called, time (msec) = {}", time); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceAvPlayerPause(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->Pause(); +} + +s32 PS4_SYSV_ABI sceAvPlayerPostInit(AvPlayerHandle handle, AvPlayerPostInitData* data) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr || data == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->PostInit(*data); +} + +s32 PS4_SYSV_ABI sceAvPlayerPrintf(const char* format, ...) { + LOG_ERROR(Lib_AvPlayer, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceAvPlayerResume(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->Resume(); +} + +s32 PS4_SYSV_ABI sceAvPlayerSetAvSyncMode(AvPlayerHandle handle, AvPlayerAvSyncMode sync_mode) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->SetAvSyncMode(sync_mode); +} + +s32 PS4_SYSV_ABI sceAvPlayerSetLogCallback(AvPlayerLogCallback log_cb, void* user_data) { + LOG_ERROR(Lib_AvPlayer, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceAvPlayerSetLooping(AvPlayerHandle handle, bool loop_flag) { + LOG_TRACE(Lib_AvPlayer, "called, looping = {}", loop_flag); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + if (!handle->SetLooping(loop_flag)) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceAvPlayerSetTrickSpeed(AvPlayerHandle handle, s32 trick_speed) { + LOG_ERROR(Lib_AvPlayer, "(STUBBED) called speed = {}", trick_speed); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceAvPlayerStart(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->Start(); +} + +s32 PS4_SYSV_ABI sceAvPlayerStop(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->Stop(); +} + +s32 PS4_SYSV_ABI sceAvPlayerStreamCount(AvPlayerHandle handle) { + LOG_TRACE(Lib_AvPlayer, "called"); + if (handle == nullptr) { + return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS; + } + return handle->GetStreamCount(); +} + +s32 PS4_SYSV_ABI sceAvPlayerVprintf(const char* format, va_list args) { + LOG_ERROR(Lib_AvPlayer, "(STUBBED) called"); + return ORBIS_OK; +} + +void RegisterLib(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("KMcEa+rHsIo", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerAddSource); + LIB_FUNCTION("x8uvuFOPZhU", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerAddSourceEx); + LIB_FUNCTION("buMCiJftcfw", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerChangeStream); + LIB_FUNCTION("NkJwDzKmIlw", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerClose); + LIB_FUNCTION("wwM99gjFf1Y", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerCurrentTime); + LIB_FUNCTION("BOVKAzRmuTQ", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerDisableStream); + LIB_FUNCTION("ODJK2sn9w4A", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerEnableStream); + LIB_FUNCTION("Wnp1OVcrZgk", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerGetAudioData); + LIB_FUNCTION("d8FcbzfAdQw", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerGetStreamInfo); + LIB_FUNCTION("o3+RWnHViSg", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerGetVideoData); + LIB_FUNCTION("JdksQu8pNdQ", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerGetVideoDataEx); + LIB_FUNCTION("aS66RI0gGgo", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerInit); + LIB_FUNCTION("o9eWRkSL+M4", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerInitEx); + LIB_FUNCTION("UbQoYawOsfY", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerIsActive); + LIB_FUNCTION("XC9wM+xULz8", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerJumpToTime); + LIB_FUNCTION("9y5v+fGN4Wk", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerPause); + LIB_FUNCTION("HD1YKVU26-M", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerPostInit); + // LIB_FUNCTION("agig-iDRrTE", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerPrintf); + LIB_FUNCTION("w5moABNwnRY", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerResume); + LIB_FUNCTION("k-q+xOxdc3E", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerSetAvSyncMode); + LIB_FUNCTION("eBTreZ84JFY", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerSetLogCallback); + LIB_FUNCTION("OVths0xGfho", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerSetLooping); + LIB_FUNCTION("av8Z++94rs0", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerSetTrickSpeed); + LIB_FUNCTION("ET4Gr-Uu07s", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerStart); + LIB_FUNCTION("ZC17w3vB5Lo", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerStop); + LIB_FUNCTION("hdTyRzCXQeQ", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerStreamCount); + LIB_FUNCTION("yN7Jhuv8g24", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerVprintf); +}; + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer.h b/gpu/shadps4/core/libraries/avplayer/avplayer.h new file mode 100644 index 0000000..31378d6 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer.h @@ -0,0 +1,295 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +#include // va_list +#include // size_t + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::AvPlayer { + +class AvPlayer; + +using AvPlayerHandle = AvPlayer*; + +enum class AvPlayerUriType : u32 { + Source = 0, +}; + +struct AvPlayerUri { + const char* name; + u32 length; +}; + +enum class AvPlayerSourceType { + Unknown = 0, + FileMp4 = 1, + Hls = 8, +}; + +enum class AvPlayerStreamType : u32 { + Video, + Audio, + TimedText, + Unknown, +}; + +struct AvPlayerSourceDetails { + AvPlayerUri uri; + u8 reserved1[64]; + AvPlayerSourceType source_type; + u8 reserved2[44]; +}; + +struct AvPlayerAudio { + u16 channel_count; + u8 reserved1[2]; + u32 sample_rate; + u32 size; + char language_code[4]; +}; + +struct AvPlayerVideo { + u32 width; + u32 height; + f32 aspect_ratio; + char language_code[4]; +}; + +struct AvPlayerTextPosition { + u16 top; + u16 left; + u16 bottom; + u16 right; +}; + +struct AvPlayerTimedText { + char language_code[4]; + u16 text_size; + u16 font_size; + AvPlayerTextPosition position; +}; + +union AvPlayerStreamDetails { + u8 reserved[16]; + AvPlayerAudio audio; + AvPlayerVideo video; + AvPlayerTimedText subs; +}; + +struct AvPlayerFrameInfo { + u8* p_data; + u8 reserved[4]; + u64 timestamp; + AvPlayerStreamDetails details; +}; + +struct AvPlayerStreamInfo { + AvPlayerStreamType type; + u8 reserved[4]; + AvPlayerStreamDetails details; + u64 duration; + u64 start_time; +}; + +struct AvPlayerAudioEx { + u16 channel_count; + u8 reserved[2]; + u32 sample_rate; + u32 size; + u8 language_code[4]; + u8 reserved1[64]; +}; + +struct AvPlayerVideoEx { + u32 width; + u32 height; + f32 aspect_ratio; + u8 language_code[4]; + u32 framerate; + u32 crop_left_offset; + u32 crop_right_offset; + u32 crop_top_offset; + u32 crop_bottom_offset; + u32 pitch; + u8 luma_bit_depth; + u8 chroma_bit_depth; + bool video_full_range_flag; + u8 reserved1[37]; +}; + +struct AvPlayerTimedTextEx { + u8 language_code[4]; + u8 reserved[12]; + u8 reserved1[64]; +}; + +union AvPlayerStreamDetailsEx { + AvPlayerAudioEx audio; + AvPlayerVideoEx video; + AvPlayerTimedTextEx subs; + u8 reserved1[80]; +}; + +struct AvPlayerFrameInfoEx { + void* p_data; + u8 reserved[4]; + u64 timestamp; + AvPlayerStreamDetailsEx details; +}; + +using AvPlayerAllocate = void* PS4_SYSV_ABI (*)(void* p, u32 align, u32 size); +using AvPlayerDeallocate = void PS4_SYSV_ABI (*)(void* p, void* mem); +using AvPlayerAllocateTexture = void* PS4_SYSV_ABI (*)(void* p, u32 align, u32 size); +using AvPlayerDeallocateTexture = void PS4_SYSV_ABI (*)(void* p, void* mem); + +struct AvPlayerMemAllocator { + void* object_ptr; + AvPlayerAllocate allocate; + AvPlayerDeallocate deallocate; + AvPlayerAllocateTexture allocate_texture; + AvPlayerDeallocateTexture deallocate_texture; +}; + +using AvPlayerOpenFile = s32 PS4_SYSV_ABI (*)(void* p, const char* name); +using AvPlayerCloseFile = s32 PS4_SYSV_ABI (*)(void* p); +using AvPlayerReadOffsetFile = s32 PS4_SYSV_ABI (*)(void* p, u8* buf, u64 pos, u32 len); +using AvPlayerSizeFile = u64 PS4_SYSV_ABI (*)(void* p); + +struct AvPlayerFileReplacement { + void* object_ptr; + AvPlayerOpenFile open; + AvPlayerCloseFile close; + AvPlayerReadOffsetFile read_offset; + AvPlayerSizeFile size; +}; + +enum class AvPlayerEvents { + StateStop = 0x01, + StateReady = 0x02, + StatePlay = 0x03, + StatePause = 0x04, + StateBuffering = 0x05, + TimedTextDelivery = 0x10, + WarningId = 0x20, + Encryption = 0x30, + DrmError = 0x40, +}; + +using AvPlayerEventCallback = void PS4_SYSV_ABI (*)(void* p, AvPlayerEvents event, s32 src_id, + void* data); + +struct AvPlayerEventReplacement { + void* object_ptr; + AvPlayerEventCallback event_callback; +}; + +enum class AvPlayerDebuglevels { + None, + Info, + Warnings, + All, +}; + +struct AvPlayerInitData { + AvPlayerMemAllocator memory_replacement; + AvPlayerFileReplacement file_replacement; + AvPlayerEventReplacement event_replacement; + AvPlayerDebuglevels debug_level; + u32 base_priority; + s32 num_output_video_framebuffers; + bool auto_start; + u8 reserved[3]; + const char* default_language; +}; + +struct AvPlayerInitDataEx { + size_t this_size; + AvPlayerMemAllocator memory_replacement; + AvPlayerFileReplacement file_replacement; + AvPlayerEventReplacement event_replacement; + const char* default_language; + AvPlayerDebuglevels debug_level; + u32 audio_decoder_priority; + u32 audio_decoder_affinity; + u32 video_decoder_priority; + u32 video_decoder_affinity; + u32 demuxer_priority; + u32 demuxer_affinity; + u32 controller_priority; + u32 controller_affinity; + u32 http_streaming_priority; + u32 http_streaming_affinity; + u32 file_streaming_priority; + u32 file_streaming_affinity; + s32 num_output_video_framebuffers; + bool auto_start; + u8 reserved[3]; +}; + +enum class AvPlayerVideoDecoderType { + Default = 0, + Reserved1, + Software, + Software2, +}; + +enum class AvPlayerAudioDecoderType { + Default = 0, + Reserved1, + Reserved2, +}; + +struct AvPlayerDecoderInit { + union { + AvPlayerVideoDecoderType video_type; + AvPlayerAudioDecoderType audio_type; + u8 reserved[4]; + } decoder_type; + union { + struct { + s32 cpu_affinity_mask; + s32 cpu_thread_priority; + u8 decode_pipeline_depth; + u8 compute_pipe_id; + u8 compute_queue_id; + u8 enable_interlaced; + u8 reserved[16]; + } avc_sw2; + struct { + u8 audio_channel_order; + u8 reserved[27]; + } aac; + u8 reserved[28]; + } decoder_params; +}; + +struct AvPlayerHTTPCtx { + u32 http_context_id; + u32 ssl_context_id; +}; + +struct AvPlayerPostInitData { + u32 demux_video_buffer_size; + AvPlayerDecoderInit video_decoder_init; + AvPlayerDecoderInit audio_decoder_init; + AvPlayerHTTPCtx http_context; + u8 reserved[56]; +}; + +enum class AvPlayerAvSyncMode { + Default = 0, + None, +}; + +using AvPlayerLogCallback = int PS4_SYSV_ABI (*)(void* p, const char* format, va_list args); + +void RegisterLib(Core::Loader::SymbolsResolver* sym); + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_common.cpp b/gpu/shadps4/core/libraries/avplayer/avplayer_common.cpp new file mode 100644 index 0000000..b31ccf8 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_common.cpp @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include // std::equal +#include // std::tolower + +#include "core/libraries/avplayer/avplayer_common.h" + +namespace Libraries::AvPlayer { + +static bool iequals(std::string_view l, std::string_view r) { + return std::ranges::equal(l, r, [](u8 a, u8 b) { return std::tolower(a) == std::tolower(b); }); +} + +AvPlayerSourceType GetSourceType(std::string_view path) { + if (path.empty()) { + return AvPlayerSourceType::Unknown; + } + + std::string_view name = path; + if (path.find("://") != std::string_view::npos) { + // This path is a URI. Strip HTTP parameters from it. + // schema://server.domain/path/file.ext/and/beyond?param=value#paragraph -> + // -> schema://server.domain/path/to/file.ext/and/beyond + name = path.substr(0, path.find_first_of("?#")); + if (name.empty()) { + return AvPlayerSourceType::Unknown; + } + } + + // schema://server.domain/path/to/file.ext/and/beyond -> .ext/and/beyond + + // Find extension dot + auto dot_pos = name.rfind('.'); + if (dot_pos == std::string_view::npos) { + return AvPlayerSourceType::Unknown; + } + + // Extract extension (".ext/anything" or ".ext") + auto ext = name.substr(dot_pos); + if (ext.empty()) { + return AvPlayerSourceType::Unknown; + } + + // .ext/and/beyond -> .ext + ext = ext.substr(0, ext.find('/')); + + if (iequals(ext, ".mp4") || iequals(ext, ".m4v") || iequals(ext, ".m3d") || + iequals(ext, ".m4a") || iequals(ext, ".mov")) { + return AvPlayerSourceType::FileMp4; + } + + if (iequals(ext, ".m3u8")) { + return AvPlayerSourceType::Hls; + } + + return AvPlayerSourceType::Unknown; +} + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_common.h b/gpu/shadps4/core/libraries/avplayer/avplayer_common.h new file mode 100644 index 0000000..1e57150 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_common.h @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include + +#include "core/libraries/avplayer/avplayer.h" + +#define AVPLAYER_IS_ERROR(x) ((x) < 0) + +namespace Libraries::AvPlayer { + +enum class AvState { + Unknown, + Initial, + AddingSource, + Ready, + Play, + Stop, + EndOfFile, + Pause, + C0x08, + Jump, + TrickMode, + C0x0B, + Buffering, + Starting, + Error, +}; + +enum class AvEventType { + ChangeFlowState = 21, + WarningId = 22, + RevertState = 30, + AddSource = 40, + Error = 255, +}; + +union AvPlayerEventData { + u32 num_frames; // 20 + AvState state; // AvEventType::ChangeFlowState + s32 error; // AvEventType::WarningId + u32 attempt; // AvEventType::AddSource +}; + +struct AvPlayerEvent { + AvEventType event; + AvPlayerEventData payload; +}; + +template +class AvPlayerQueue { +public: + size_t Size() { + return m_queue.size(); + } + + void Push(T&& value) { + std::lock_guard guard(m_mutex); + m_queue.emplace(std::forward(value)); + } + + T& Front() { + return m_queue.front(); + } + + std::optional Pop() { + if (Size() == 0) { + return std::nullopt; + } + std::lock_guard guard(m_mutex); + auto result = std::move(m_queue.front()); + m_queue.pop(); + return result; + } + + void Clear() { + std::lock_guard guard(m_mutex); + m_queue = {}; + } + +private: + std::mutex m_mutex{}; + std::queue m_queue{}; +}; + +AvPlayerSourceType GetSourceType(std::string_view path); + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_data_streamer.h b/gpu/shadps4/core/libraries/avplayer/avplayer_data_streamer.h new file mode 100644 index 0000000..ebdabb0 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_data_streamer.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +struct AVIOContext; + +namespace Libraries::AvPlayer { + +class IDataStreamer { +public: + virtual ~IDataStreamer() = default; + virtual bool Init(std::string_view path) = 0; + virtual void Reset() = 0; + virtual AVIOContext* GetContext() = 0; +}; + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_error.h b/gpu/shadps4/core/libraries/avplayer/avplayer_error.h new file mode 100644 index 0000000..ebe4d0d --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_error.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// AvPlayer library +constexpr int ORBIS_AVPLAYER_ERROR_INVALID_PARAMS = 0x806A0001; +constexpr int ORBIS_AVPLAYER_ERROR_OPERATION_FAILED = 0x806A0002; +constexpr int ORBIS_AVPLAYER_ERROR_NO_MEMORY = 0x806A0003; +constexpr int ORBIS_AVPLAYER_ERROR_NOT_SUPPORTED = 0x806A0004; +constexpr int ORBIS_AVPLAYER_ERROR_WAR_FILE_NONINTERLEAVED = 0x806A00A0; +constexpr int ORBIS_AVPLAYER_ERROR_WAR_LOOPING_BACK = 0x806A00A1; +constexpr int ORBIS_AVPLAYER_ERROR_WAR_JUMP_COMPLETE = 0x806A00A3; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_MARLIN_ENCRY = 0x806A00B0; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_PLAYREADY_ENCRY = 0x806A00B4; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_AES_ENCRY = 0x806A00B5; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF; diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_file_streamer.cpp b/gpu/shadps4/core/libraries/avplayer/avplayer_file_streamer.cpp new file mode 100644 index 0000000..1535394 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_file_streamer.cpp @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include // std::max, std::min +#include "core/libraries/avplayer/avplayer_file_streamer.h" + +extern "C" { +#include +#include +#include +} + +constexpr u32 AVPLAYER_AVIO_BUFFER_SIZE = 4096; + +namespace Libraries::AvPlayer { + +AvPlayerFileStreamer::AvPlayerFileStreamer(const AvPlayerFileReplacement& file_replacement) + : m_file_replacement(file_replacement) {} + +AvPlayerFileStreamer::~AvPlayerFileStreamer() { + if (m_avio_context != nullptr) { + avio_context_free(&m_avio_context); + } + if (m_file_replacement.close != nullptr && m_fd >= 0) { + const auto close = m_file_replacement.close; + const auto ptr = m_file_replacement.object_ptr; + close(ptr); + } +} + +bool AvPlayerFileStreamer::Init(std::string_view path) { + const auto ptr = m_file_replacement.object_ptr; + m_fd = m_file_replacement.open(ptr, path.data()); + if (m_fd < 0) { + return false; + } + m_file_size = m_file_replacement.size(ptr); + // avio_buffer is deallocated in `avio_context_free` + const auto avio_buffer = reinterpret_cast(av_malloc(AVPLAYER_AVIO_BUFFER_SIZE)); + m_avio_context = + avio_alloc_context(avio_buffer, AVPLAYER_AVIO_BUFFER_SIZE, 0, this, + &AvPlayerFileStreamer::ReadPacket, nullptr, &AvPlayerFileStreamer::Seek); + return true; +} + +void AvPlayerFileStreamer::Reset() { + m_position = 0; +} + +s32 AvPlayerFileStreamer::ReadPacket(void* opaque, u8* buffer, s32 size) { + const auto self = reinterpret_cast(opaque); + if (self->m_position >= self->m_file_size) { + return AVERROR_EOF; + } + if (self->m_position + size > self->m_file_size) { + size = self->m_file_size - self->m_position; + } + const auto read_offset = self->m_file_replacement.read_offset; + const auto ptr = self->m_file_replacement.object_ptr; + const auto bytes_read = read_offset(ptr, buffer, self->m_position, size); + if (bytes_read == 0 && size != 0) { + return AVERROR_EOF; + } + self->m_position += bytes_read; + return bytes_read; +} + +s64 AvPlayerFileStreamer::Seek(void* opaque, s64 offset, int whence) { + const auto self = reinterpret_cast(opaque); + if (whence & AVSEEK_SIZE) { + return self->m_file_size; + } + + if (whence == SEEK_CUR) { + self->m_position = + std::min(u64(std::max(s64(0), s64(self->m_position) + offset)), self->m_file_size); + return self->m_position; + } else if (whence == SEEK_SET) { + self->m_position = std::min(u64(std::max(s64(0), offset)), self->m_file_size); + return self->m_position; + } else if (whence == SEEK_END) { + self->m_position = + std::min(u64(std::max(s64(0), s64(self->m_file_size) + offset)), self->m_file_size); + return self->m_position; + } + + return -1; +} + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_file_streamer.h b/gpu/shadps4/core/libraries/avplayer/avplayer_file_streamer.h new file mode 100644 index 0000000..8e9b6bf --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_file_streamer.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "core/libraries/avplayer/avplayer.h" +#include "core/libraries/avplayer/avplayer_data_streamer.h" + +struct AVIOContext; + +namespace Libraries::AvPlayer { + +class AvPlayerFileStreamer : public IDataStreamer { +public: + AvPlayerFileStreamer(const AvPlayerFileReplacement& file_replacement); + ~AvPlayerFileStreamer(); + + bool Init(std::string_view path) override; + void Reset() override; + + AVIOContext* GetContext() override { + return m_avio_context; + } + +private: + static s32 ReadPacket(void* opaque, u8* buffer, s32 size); + static s64 Seek(void* opaque, s64 buffer, int whence); + + AvPlayerFileReplacement m_file_replacement; + + int m_fd = -1; + u64 m_position{}; + u64 m_file_size{}; + AVIOContext* m_avio_context{}; +}; + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_impl.cpp b/gpu/shadps4/core/libraries/avplayer/avplayer_impl.cpp new file mode 100644 index 0000000..277f44b --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_impl.cpp @@ -0,0 +1,227 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/libraries/avplayer/avplayer_common.h" +#include "core/libraries/avplayer/avplayer_error.h" +#include "core/libraries/avplayer/avplayer_impl.h" + +namespace Libraries::AvPlayer { + +void* PS4_SYSV_ABI AvPlayer::Allocate(void* handle, u32 alignment, u32 size) { + const auto* const self = reinterpret_cast(handle); + const auto allocate = self->m_init_data_original.memory_replacement.allocate; + const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; + return allocate(ptr, alignment, size); +} + +void PS4_SYSV_ABI AvPlayer::Deallocate(void* handle, void* memory) { + const auto* const self = reinterpret_cast(handle); + const auto deallocate = self->m_init_data_original.memory_replacement.deallocate; + const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; + return deallocate(ptr, memory); +} + +void* PS4_SYSV_ABI AvPlayer::AllocateTexture(void* handle, u32 alignment, u32 size) { + const auto* const self = reinterpret_cast(handle); + const auto allocate = self->m_init_data_original.memory_replacement.allocate_texture; + const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; + return allocate(ptr, alignment, size); +} + +void PS4_SYSV_ABI AvPlayer::DeallocateTexture(void* handle, void* memory) { + const auto* const self = reinterpret_cast(handle); + const auto deallocate = self->m_init_data_original.memory_replacement.deallocate_texture; + const auto ptr = self->m_init_data_original.memory_replacement.object_ptr; + return deallocate(ptr, memory); +} + +int PS4_SYSV_ABI AvPlayer::OpenFile(void* handle, const char* filename) { + auto const self = reinterpret_cast(handle); + std::lock_guard guard(self->m_file_io_mutex); + + const auto open = self->m_init_data_original.file_replacement.open; + const auto ptr = self->m_init_data_original.file_replacement.object_ptr; + return open(ptr, filename); +} + +int PS4_SYSV_ABI AvPlayer::CloseFile(void* handle) { + auto const self = reinterpret_cast(handle); + std::lock_guard guard(self->m_file_io_mutex); + + const auto close = self->m_init_data_original.file_replacement.close; + const auto ptr = self->m_init_data_original.file_replacement.object_ptr; + return close(ptr); +} + +int PS4_SYSV_ABI AvPlayer::ReadOffsetFile(void* handle, u8* buffer, u64 position, u32 length) { + auto const self = reinterpret_cast(handle); + std::lock_guard guard(self->m_file_io_mutex); + + const auto read_offset = self->m_init_data_original.file_replacement.read_offset; + const auto ptr = self->m_init_data_original.file_replacement.object_ptr; + return read_offset(ptr, buffer, position, length); +} + +u64 PS4_SYSV_ABI AvPlayer::SizeFile(void* handle) { + auto const self = reinterpret_cast(handle); + std::lock_guard guard(self->m_file_io_mutex); + + const auto size = self->m_init_data_original.file_replacement.size; + const auto ptr = self->m_init_data_original.file_replacement.object_ptr; + return size(ptr); +} + +AvPlayerInitData AvPlayer::StubInitData(const AvPlayerInitData& data) { + AvPlayerInitData result = data; + result.memory_replacement.object_ptr = this; + result.memory_replacement.allocate = &AvPlayer::Allocate; + result.memory_replacement.deallocate = &AvPlayer::Deallocate; + result.memory_replacement.allocate_texture = &AvPlayer::AllocateTexture; + result.memory_replacement.deallocate_texture = &AvPlayer::DeallocateTexture; + if (data.file_replacement.open == nullptr || data.file_replacement.close == nullptr || + data.file_replacement.read_offset == nullptr || data.file_replacement.size == nullptr) { + result.file_replacement = {}; + } else { + result.file_replacement.object_ptr = this; + result.file_replacement.open = &AvPlayer::OpenFile; + result.file_replacement.close = &AvPlayer::CloseFile; + result.file_replacement.read_offset = &AvPlayer::ReadOffsetFile; + result.file_replacement.size = &AvPlayer::SizeFile; + } + return result; +} + +AvPlayer::AvPlayer(const AvPlayerInitData& data) + : m_init_data(StubInitData(data)), m_init_data_original(data), + m_state(std::make_unique(m_init_data)) {} + +s32 AvPlayer::PostInit(const AvPlayerPostInitData& data) { + m_state->PostInit(data); + return ORBIS_OK; +} + +s32 AvPlayer::AddSource(std::string_view path) { + return AddSourceEx(path, AvPlayerSourceType::Unknown); +} + +s32 AvPlayer::AddSourceEx(std::string_view path, AvPlayerSourceType source_type) { + if (source_type == AvPlayerSourceType::Unknown) { + source_type = GetSourceType(path); + } + if (source_type == AvPlayerSourceType::Hls) { + LOG_ERROR(Lib_AvPlayer, "HTTP Live Streaming is not implemented"); + return ORBIS_AVPLAYER_ERROR_NOT_SUPPORTED; + } + if (!m_state->AddSource(path, GetSourceType(path))) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 AvPlayer::GetStreamCount() { + if (m_state == nullptr) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + const auto res = m_state->GetStreamCount(); + if (AVPLAYER_IS_ERROR(res)) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return res; +} + +s32 AvPlayer::GetStreamInfo(u32 stream_index, AvPlayerStreamInfo& info) { + if (!m_state->GetStreamInfo(stream_index, info)) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 AvPlayer::EnableStream(u32 stream_index) { + if (m_state == nullptr) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + if (!m_state->EnableStream(stream_index)) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 AvPlayer::Start() { + if (m_state == nullptr || !m_state->Start()) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 AvPlayer::Pause() { + if (m_state == nullptr || !m_state->Pause()) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 AvPlayer::Resume() { + if (m_state == nullptr || !m_state->Resume()) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +s32 AvPlayer::SetAvSyncMode(AvPlayerAvSyncMode sync_mode) { + if (m_state == nullptr) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + m_state->SetAvSyncMode(sync_mode); + return ORBIS_OK; +} + +bool AvPlayer::GetVideoData(AvPlayerFrameInfo& video_info) { + if (m_state == nullptr) { + return false; + } + return m_state->GetVideoData(video_info); +} + +bool AvPlayer::GetVideoData(AvPlayerFrameInfoEx& video_info) { + if (m_state == nullptr) { + return false; + } + return m_state->GetVideoData(video_info); +} + +bool AvPlayer::GetAudioData(AvPlayerFrameInfo& audio_info) { + if (m_state == nullptr) { + return false; + } + return m_state->GetAudioData(audio_info); +} + +bool AvPlayer::IsActive() { + if (m_state == nullptr) { + return false; + } + return m_state->IsActive(); +} + +u64 AvPlayer::CurrentTime() { + if (m_state == nullptr) { + return 0; + } + return m_state->CurrentTime(); +} + +s32 AvPlayer::Stop() { + if (m_state == nullptr || !m_state->Stop()) { + return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED; + } + return ORBIS_OK; +} + +bool AvPlayer::SetLooping(bool is_looping) { + if (m_state == nullptr) { + return false; + } + return m_state->SetLooping(is_looping); +} + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_impl.h b/gpu/shadps4/core/libraries/avplayer/avplayer_impl.h new file mode 100644 index 0000000..7153b9f --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_impl.h @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/avplayer/avplayer.h" +#include "core/libraries/avplayer/avplayer_state.h" + +#include +#include +#include + +namespace Libraries::AvPlayer { + +class AvPlayer { +public: + AvPlayer(const AvPlayerInitData& data); + + s32 PostInit(const AvPlayerPostInitData& data); + s32 AddSource(std::string_view filename); + s32 AddSourceEx(std::string_view path, AvPlayerSourceType source_type); + s32 GetStreamCount(); + s32 GetStreamInfo(u32 stream_index, AvPlayerStreamInfo& info); + s32 EnableStream(u32 stream_index); + s32 Start(); + s32 Pause(); + s32 Resume(); + s32 SetAvSyncMode(AvPlayerAvSyncMode sync_mode); + bool GetAudioData(AvPlayerFrameInfo& audio_info); + bool GetVideoData(AvPlayerFrameInfo& video_info); + bool GetVideoData(AvPlayerFrameInfoEx& video_info); + bool IsActive(); + u64 CurrentTime(); + s32 Stop(); + bool SetLooping(bool is_looping); + +private: + // Memory Replacement + static void* PS4_SYSV_ABI Allocate(void* handle, u32 alignment, u32 size); + static void PS4_SYSV_ABI Deallocate(void* handle, void* memory); + static void* PS4_SYSV_ABI AllocateTexture(void* handle, u32 alignment, u32 size); + static void PS4_SYSV_ABI DeallocateTexture(void* handle, void* memory); + + // File Replacement + static int PS4_SYSV_ABI OpenFile(void* handle, const char* filename); + static int PS4_SYSV_ABI CloseFile(void* handle); + static int PS4_SYSV_ABI ReadOffsetFile(void* handle, u8* buffer, u64 position, u32 length); + static u64 PS4_SYSV_ABI SizeFile(void* handle); + + AvPlayerInitData StubInitData(const AvPlayerInitData& data); + + AvPlayerInitData m_init_data{}; + AvPlayerInitData m_init_data_original{}; + std::mutex m_file_io_mutex{}; + + std::unique_ptr m_state{}; +}; + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_source.cpp b/gpu/shadps4/core/libraries/avplayer/avplayer_source.cpp new file mode 100644 index 0000000..ad22920 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_source.cpp @@ -0,0 +1,890 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/alignment.h" +#include "common/singleton.h" +#include "common/thread.h" +#include "core/libraries/avplayer/avplayer_error.h" +#include "core/libraries/avplayer/avplayer_file_streamer.h" +#include "core/libraries/avplayer/avplayer_source.h" +#include "core/libraries/videodec/video_utils.h" +#include "core/memory.h" + +#include + +extern "C" { +#include +#include +#include +#include +#include +#include +} + +#include "common/support/avdec.h" + +extern "C" int runtime_file_translate(const char* guest, char* out, size_t size); + +namespace Libraries::AvPlayer { + +static AvPlayerStreamType CodecTypeToStreamType(AVMediaType codec_type) { + switch (codec_type) { + case AVMediaType::AVMEDIA_TYPE_VIDEO: + return AvPlayerStreamType::Video; + case AVMediaType::AVMEDIA_TYPE_AUDIO: + return AvPlayerStreamType::Audio; + case AVMediaType::AVMEDIA_TYPE_SUBTITLE: + return AvPlayerStreamType::TimedText; + default: + LOG_ERROR(Lib_AvPlayer, "Unexpected AVMediaType {}", magic_enum::enum_name(codec_type)); + return AvPlayerStreamType::Unknown; + } +} + +static bool IsStreamSupported(AVStream* stream) { + const auto codec_id = stream->codecpar->codec_id; + return codec_id == AV_CODEC_ID_H264 || codec_id == AV_CODEC_ID_HEVC || + codec_id == AV_CODEC_ID_AAC; +} + +AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state) : m_state(state) {} + +AvPlayerSource::~AvPlayerSource() { + Stop(); +} + +bool AvPlayerSource::Init(const AvPlayerInitData& init_data, std::string_view path) { + m_memory_replacement = init_data.memory_replacement; + m_max_num_video_framebuffers = + std::min(std::max(2, init_data.num_output_video_framebuffers), 16); + + AVFormatContext* context = avformat_alloc_context(); + if (context == nullptr) { + LOG_ERROR(Lib_AvPlayer, "Could not allocate AVFormatContext for {}", path); + return false; + } + + const auto attach_custom_io = [&]() { + context->pb = m_up_data_streamer->GetContext(); + context->flags |= AVFMT_FLAG_CUSTOM_IO; + }; + + if (init_data.file_replacement.open != nullptr) { + LOG_INFO(Lib_AvPlayer, "Opening {} through the game-provided file replacement", path); + m_up_data_streamer = std::make_unique(init_data.file_replacement); + if (!m_up_data_streamer->Init(path)) { + avformat_free_context(context); + return false; + } + attach_custom_io(); + if (AVPLAYER_IS_ERROR(avformat_open_input(&context, nullptr, nullptr, nullptr))) { + return false; + } + } else { + // bbport: guest paths are translated by the port's file system (runtime_file.c). + char host[1024]; + if (runtime_file_translate(std::string(path).c_str(), host, sizeof(host)) != 0) { + LOG_ERROR(Lib_AvPlayer, "Cannot translate guest path {}", path); + avformat_free_context(context); + return false; + } + LOG_INFO(Lib_AvPlayer, "Opening {} from host path {}", path, host); + if (AVPLAYER_IS_ERROR(avformat_open_input(&context, host, nullptr, nullptr))) { + return false; + } + } + m_avformat_context = AVFormatContextPtr(context, &ReleaseAVFormatContext); + + return true; +} + +bool AvPlayerSource::FindStreams() { + if (avformat_find_stream_info(m_avformat_context.get(), nullptr) >= 0) { + m_streams.reserve(m_avformat_context->nb_streams); + for (u32 idx = 0; idx < m_avformat_context->nb_streams; ++idx) { + if (!IsStreamSupported(m_avformat_context->streams[idx])) { + continue; + } + m_streams.push_back({idx, CreateStreamInfo(idx)}); + } + } + m_duration = DurationMillis(); + return m_streams.size() > 0; +} + +s32 AvPlayerSource::GetStreamCount() { + LOG_INFO(Lib_AvPlayer, "Stream Count: {}", m_streams.size()); + return m_streams.size(); +} + +static u64 TimestampToMillis(s64 timestamp, AVRational time_base) { + if (timestamp == AV_NOPTS_VALUE || timestamp <= 0 || time_base.num <= 0 || time_base.den <= 0) { + return 0; + } + + const auto millis = av_rescale_q(timestamp, time_base, AVRational{1, 1000}); + return millis > 0 ? u64(millis) : 0; +} + +static u64 StreamDurationMillis(const AVFormatContext& context, const AVStream& stream) { + const auto stream_duration = TimestampToMillis(stream.duration, stream.time_base); + if (stream_duration != 0) { + return stream_duration; + } + return TimestampToMillis(context.duration, AVRational{1, AV_TIME_BASE}); +} + +AvPlayerStreamInfo AvPlayerSource::CreateStreamInfo(u32 stream_index) { + AvPlayerStreamInfo info = {}; + const auto p_stream = m_avformat_context->streams[stream_index]; + info.type = CodecTypeToStreamType(p_stream->codecpar->codec_type); + info.start_time = 0; // start_time is currently unused and defaults to 0. + info.duration = StreamDurationMillis(*m_avformat_context, *p_stream); + const auto p_lang_node = av_dict_get(p_stream->metadata, "language", nullptr, 0); + if (p_lang_node != nullptr) { + LOG_INFO(Lib_AvPlayer, "Stream {} language = {}", stream_index, p_lang_node->value); + } else { + LOG_WARNING(Lib_AvPlayer, "Stream {} language is unknown", stream_index); + } + switch (info.type) { + case AvPlayerStreamType::Video: { + LOG_INFO(Lib_AvPlayer, "Stream {} is a video stream.", stream_index); + info.details.video.aspect_ratio = + f32(p_stream->codecpar->width) / p_stream->codecpar->height; + const auto width = Common::AlignUp(p_stream->codecpar->width, 16); + const auto height = Common::AlignUp(p_stream->codecpar->height, 16); + info.details.video.width = width; + info.details.video.height = height; + if (p_lang_node != nullptr) { + std::memcpy(info.details.video.language_code, p_lang_node->value, + std::min(strlen(p_lang_node->value), size_t(3))); + } + break; + } + case AvPlayerStreamType::Audio: { + LOG_INFO(Lib_AvPlayer, "Stream {} is an audio stream.", stream_index); + info.details.audio.channel_count = p_stream->codecpar->ch_layout.nb_channels; + info.details.audio.sample_rate = p_stream->codecpar->sample_rate; + info.details.audio.size = 0; // sceAvPlayerGetStreamInfo() is expected to set this to 0 + if (p_lang_node != nullptr) { + std::memcpy(info.details.audio.language_code, p_lang_node->value, + std::min(strlen(p_lang_node->value), size_t(3))); + } + break; + } + case AvPlayerStreamType::TimedText: { + info.details.subs.font_size = 12; + info.details.subs.text_size = 12; + if (p_lang_node != nullptr) { + std::memcpy(info.details.subs.language_code, p_lang_node->value, + std::min(strlen(p_lang_node->value), size_t(3))); + } + break; + } + default: { + UNREACHABLE_MSG("Unknown stream type, codec id {}", + magic_enum::enum_name(p_stream->codecpar->codec_type)); + } + } + return info; +} + +bool AvPlayerSource::GetStreamInfo(u32 stream_index, AvPlayerStreamInfo& info) { + if (stream_index >= m_streams.size()) { + LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info.", stream_index); + return false; + } + info = m_streams[stream_index].info; + return true; +} + +bool AvPlayerSource::EnableStream(u32 stream_index) { + if (m_avformat_context == nullptr || stream_index >= m_streams.size()) { + return false; + } + stream_index = m_streams[stream_index].ffmpeg_index; + const auto stream = m_avformat_context->streams[stream_index]; + switch (stream->codecpar->codec_type) { + case AVMediaType::AVMEDIA_TYPE_VIDEO: { + m_video_stream_index = stream_index; + LOG_INFO(Lib_AvPlayer, "Video stream {} enabled", stream_index); + break; + } + case AVMediaType::AVMEDIA_TYPE_AUDIO: { + m_audio_stream_index = stream_index; + LOG_INFO(Lib_AvPlayer, "Audio stream {} enabled", stream_index); + break; + } + default: + LOG_WARNING(Lib_AvPlayer, "Unknown stream type {} for stream {}", + magic_enum::enum_name(stream->codecpar->codec_type), stream_index); + break; + } + return true; +} + +void AvPlayerSource::SetLooping(bool is_looping) { + m_is_looping = is_looping; +} + +std::optional AvPlayerSource::HasFrames(u32 num_frames) { + return m_video_packets.Size() > num_frames || m_is_eof; +} + +bool AvPlayerSource::Start() { + std::unique_lock lock(m_state_mutex); + + if (!m_video_stream_index && !m_audio_stream_index) { + LOG_ERROR(Lib_AvPlayer, "Could not start playback. No streams."); + return false; + } + if (m_video_stream_index) { + const auto stream_index = m_streams[m_video_stream_index.value()].ffmpeg_index; + const auto stream = m_avformat_context->streams[stream_index]; + avformat_seek_file(m_avformat_context.get(), m_video_stream_index.value(), 0, 0, + stream->duration, 0); + const auto decoder = avcodec_find_decoder(stream->codecpar->codec_id); + if (decoder == nullptr) { + return false; + } + m_video_codec_context = + AVCodecContextPtr(avcodec_alloc_context3(decoder), &ReleaseAVCodecContext); + if (avcodec_parameters_to_context(m_video_codec_context.get(), stream->codecpar) < 0) { + LOG_ERROR(Lib_AvPlayer, "Could not copy stream {} avcodec parameters to context.", + m_video_stream_index.value()); + return false; + } + if (avcodec_open2(m_video_codec_context.get(), decoder, nullptr) < 0) { + LOG_ERROR(Lib_AvPlayer, "Could not open avcodec for video stream {}.", + m_video_stream_index.value()); + return false; + } + const auto pitch = Common::AlignUp(m_video_codec_context->width, 64); + const auto height = Common::AlignUp(m_video_codec_context->height, 16); + const auto size = (pitch * height * 3) / 2; + for (u64 index = 0; index < m_max_num_video_framebuffers; ++index) { + m_video_buffers.Push(GuestBuffer(m_memory_replacement, 0x100, size, true)); + } + } + if (m_audio_stream_index) { + const auto stream_index = m_streams[m_audio_stream_index.value()].ffmpeg_index; + const auto stream = m_avformat_context->streams[stream_index]; + avformat_seek_file(m_avformat_context.get(), m_audio_stream_index.value(), 0, 0, + stream->duration, 0); + const auto decoder = avcodec_find_decoder(stream->codecpar->codec_id); + if (decoder == nullptr) { + return false; + } + m_audio_codec_context = + AVCodecContextPtr(avcodec_alloc_context3(decoder), &ReleaseAVCodecContext); + if (avcodec_parameters_to_context(m_audio_codec_context.get(), stream->codecpar) < 0) { + LOG_ERROR(Lib_AvPlayer, "Could not copy stream {} avcodec parameters to context.", + m_audio_stream_index.value()); + return false; + } + if (avcodec_open2(m_audio_codec_context.get(), decoder, nullptr) < 0) { + LOG_ERROR(Lib_AvPlayer, "Could not open avcodec for audio stream {}.", + m_audio_stream_index.value()); + return false; + } + constexpr u8 max_channels = 8; + constexpr size_t max_sample_size = sizeof(s32); + const auto size = max_channels * max_sample_size * 1024; + for (u64 index = 0; index < (m_max_num_video_framebuffers * 2); ++index) { + m_audio_buffers.Push(GuestBuffer(m_memory_replacement, 0x10, size, false)); + } + } + m_demuxer_thread.Run([this](std::stop_token stop) { this->DemuxerThread(stop); }); + m_video_decoder_thread.Run([this](std::stop_token stop) { this->VideoDecoderThread(stop); }); + m_audio_decoder_thread.Run([this](std::stop_token stop) { this->AudioDecoderThread(stop); }); + m_start_time = std::chrono::high_resolution_clock::now(); + return true; +} + +bool AvPlayerSource::Stop() { + std::unique_lock lock(m_state_mutex); + + if (!HasRunningThreads()) { + LOG_WARNING(Lib_AvPlayer, "Could not stop playback: already stopped."); + return false; + } + + if (m_up_data_streamer) { + m_up_data_streamer->Reset(); + } + + m_video_decoder_thread.Stop(); + m_audio_decoder_thread.Stop(); + m_demuxer_thread.Stop(); + + m_current_audio_frame.reset(); + m_current_video_frame.reset(); + + m_video_buffers.Clear(); + m_audio_buffers.Clear(); + m_audio_packets.Clear(); + m_video_packets.Clear(); + m_audio_frames.Clear(); + m_video_frames.Clear(); + + m_last_audio_ts.reset(); + m_last_data_time.reset(); + m_start_time.reset(); + m_pause_time = {}; + m_pause_duration = {}; + + m_is_paused = false; + m_is_eof = false; + + return true; +} + +void AvPlayerSource::Pause() { + m_pause_time = std::chrono::high_resolution_clock::now(); + m_is_paused = true; +} + +void AvPlayerSource::Resume() { + m_pause_duration += std::chrono::high_resolution_clock::now() - m_pause_time; + m_is_paused = false; +} + +bool AvPlayerSource::GetVideoData(AvPlayerFrameInfo& video_info) { + AvPlayerFrameInfoEx info{}; + if (!GetVideoData(info)) { + return false; + } + video_info = {}; + video_info.timestamp = u64(info.timestamp); + video_info.p_data = reinterpret_cast(info.p_data); + video_info.details.video.aspect_ratio = info.details.video.aspect_ratio; + video_info.details.video.width = info.details.video.width; + video_info.details.video.height = info.details.video.height; + return true; +} + +bool AvPlayerSource::GetVideoData(AvPlayerFrameInfoEx& video_info) { + if (!IsActive() || m_is_paused) { + return false; + } + + if (m_video_frames.Size() == 0) { + return false; + } + + const auto current_time = CurrentTime(); + const auto& new_frame = m_video_frames.Front(); + if (m_state.GetSyncMode() == AvPlayerAvSyncMode::Default) { + if (new_frame.info.timestamp > current_time) { + return false; + } + } + + if (m_current_video_frame.has_value()) { + m_video_buffers.Push(std::move(m_current_video_frame->buffer)); + m_current_video_frame.reset(); + m_video_buffers_cv.Notify(); + } + + auto frame = m_video_frames.Pop(); + video_info = frame->info; + + m_current_video_frame = std::move(frame); + return true; +} + +bool AvPlayerSource::GetAudioData(AvPlayerFrameInfo& audio_info) { + if (!IsActive() || m_is_paused) { + return false; + } + + if (m_audio_frames.Size() == 0) { + return false; + } + + if (m_current_audio_frame.has_value()) { + m_audio_buffers.Push(std::move(m_current_audio_frame->buffer)); + m_current_audio_frame.reset(); + m_audio_buffers_cv.Notify(); + } + + auto frame = m_audio_frames.Pop(); + m_last_audio_ts = frame->info.timestamp; + m_last_data_time = std::chrono::high_resolution_clock::now(); + m_pause_duration = std::chrono::high_resolution_clock::duration(0); + + audio_info = {}; + audio_info.timestamp = frame->info.timestamp; + audio_info.p_data = reinterpret_cast(frame->info.p_data); + audio_info.details.audio.sample_rate = frame->info.details.audio.sample_rate; + audio_info.details.audio.size = frame->info.details.audio.size; + audio_info.details.audio.channel_count = frame->info.details.audio.channel_count; + m_current_audio_frame = std::move(frame); + return true; +} + +u64 AvPlayerSource::DurationMillis() const { + if (m_avformat_context == nullptr) { + return 0; + } + + u64 duration = 0; + const auto add_stream_duration = [&](std::optional stream_index) { + if (!stream_index.has_value()) { + return; + } + if (stream_index.value() < 0) { + return; + } + const auto index = m_streams[stream_index.value()].ffmpeg_index; + if (index >= m_streams.size()) { + return; + } + const auto stream = m_avformat_context->streams[index]; + if (stream == nullptr) { + return; + } + duration = std::max(duration, StreamDurationMillis(*m_avformat_context, *stream)); + }; + + add_stream_duration(m_video_stream_index); + add_stream_duration(m_audio_stream_index); + + if (duration == 0) { + for (u32 index = 0; index < m_avformat_context->nb_streams; ++index) { + const auto stream = m_avformat_context->streams[index]; + if (stream != nullptr) { + duration = std::max(duration, StreamDurationMillis(*m_avformat_context, *stream)); + } + } + } + + return duration; +} + +u64 AvPlayerSource::CurrentTime() { + if (!m_start_time.has_value()) { + return 0; + } + + if (m_is_eof && !IsActive()) { + return m_duration; + } + if (!IsActive()) { + return 0; + } + + using namespace std::chrono; + const auto now = m_is_paused.load() ? m_pause_time : high_resolution_clock::now(); + if (m_audio_stream_index) { + const auto last_audio = m_last_data_time.value_or(now); + const auto elapsed = + duration_cast(now - last_audio - m_pause_duration).count(); + return m_last_audio_ts.value_or(0) + elapsed; + } + + const auto elapsed = + duration_cast(now - m_start_time.value() - m_pause_duration).count(); + if (elapsed <= 0) { + return 0; + } + const auto current_time = u64(elapsed); + return m_duration != 0 && current_time > m_duration ? m_duration : current_time; +} + +bool AvPlayerSource::IsActive() { + return !m_is_eof || m_audio_packets.Size() != 0 || m_video_packets.Size() != 0 || + m_video_frames.Size() != 0 || m_audio_frames.Size() != 0; +} + +void AvPlayerSource::ReleaseAVPacket(AVPacket* packet) { + if (packet != nullptr) { + av_packet_free(&packet); + } +} + +void AvPlayerSource::ReleaseAVFrame(AVFrame* frame) { + if (frame != nullptr) { + av_frame_free(&frame); + } +} + +void AvPlayerSource::ReleaseAVCodecContext(AVCodecContext* context) { + if (context != nullptr) { + avcodec_free_context(&context); + } +} + +void AvPlayerSource::ReleaseSWRContext(SwrContext* context) { + if (context != nullptr) { + swr_free(&context); + } +} + +void AvPlayerSource::ReleaseSWSContext(SwsContext* context) { + if (context != nullptr) { + sws_freeContext(context); + } +} + +void AvPlayerSource::ReleaseAVFormatContext(AVFormatContext* context) { + if (context != nullptr) { + avformat_close_input(&context); + } +} + +void AvPlayerSource::DemuxerThread(std::stop_token stop) { + using namespace std::chrono; + Common::SetCurrentThreadName("shadPS4:AvDemuxer"); + + if (!m_audio_stream_index.has_value() && !m_video_stream_index.has_value()) { + LOG_WARNING(Lib_AvPlayer, "Could not start DEMUXER thread. No streams enabled."); + return; + } + LOG_INFO(Lib_AvPlayer, "Demuxer Thread started"); + + while (!stop.stop_requested()) { + if (m_video_packets.Size() > 30 && + (!m_audio_stream_index.has_value() || m_audio_packets.Size() > 8)) { + std::this_thread::sleep_for(milliseconds(5)); + continue; + } + AVPacketPtr up_packet(av_packet_alloc(), &ReleaseAVPacket); + const auto res = av_read_frame(m_avformat_context.get(), up_packet.get()); + if (res < 0) { + if (res == AVERROR_EOF) { + if (m_is_looping) { + LOG_INFO(Lib_AvPlayer, "EOF reached in demuxer. Looping the source..."); + m_state.OnWarning(ORBIS_AVPLAYER_ERROR_WAR_LOOPING_BACK); + avio_seek(m_avformat_context->pb, 0, SEEK_SET); + if (m_video_stream_index.has_value()) { + const auto index = m_streams[m_video_stream_index.value()].ffmpeg_index; + const auto stream = m_avformat_context->streams[index]; + avformat_seek_file(m_avformat_context.get(), index, 0, 0, stream->duration, + 0); + } + if (m_audio_stream_index.has_value()) { + const auto index = m_streams[m_audio_stream_index.value()].ffmpeg_index; + const auto stream = m_avformat_context->streams[index]; + avformat_seek_file(m_avformat_context.get(), index, 0, 0, stream->duration, + 0); + } + continue; + } else { + LOG_INFO(Lib_AvPlayer, "EOF reached in demuxer. Exiting."); + break; + } + } else { + LOG_ERROR(Lib_AvPlayer, "Could not read AV frame: error = {}", res); + m_state.OnError(); + return; + } + break; + } + if (up_packet->stream_index == m_video_stream_index) { + m_video_packets.Push(std::move(up_packet)); + m_video_packets_cv.Notify(); + } else if (up_packet->stream_index == m_audio_stream_index) { + m_audio_packets.Push(std::move(up_packet)); + m_audio_packets_cv.Notify(); + } + } + + m_is_eof = true; + + m_video_packets_cv.Notify(); + m_audio_packets_cv.Notify(); + m_video_frames_cv.Notify(); + m_audio_frames_cv.Notify(); + m_video_buffers_cv.Notify(); + m_audio_buffers_cv.Notify(); + + m_video_decoder_thread.Join(); + m_audio_decoder_thread.Join(); + m_state.OnEOF(); + + LOG_INFO(Lib_AvPlayer, "Demuxer Thread exited normally"); + m_demuxer_thread.Join(); +} + +AvPlayerSource::AVFramePtr AvPlayerSource::ConvertVideoFrame(const AVFrame& frame) { + auto nv12_frame = AVFramePtr{av_frame_alloc(), &ReleaseAVFrame}; + nv12_frame->best_effort_timestamp = frame.best_effort_timestamp; + nv12_frame->pts = frame.pts; + nv12_frame->pkt_dts = frame.pkt_dts < 0 ? 0 : frame.pkt_dts; + nv12_frame->format = AV_PIX_FMT_NV12; + nv12_frame->width = frame.width; + nv12_frame->height = frame.height; + nv12_frame->sample_aspect_ratio = frame.sample_aspect_ratio; + nv12_frame->crop_top = frame.crop_top; + nv12_frame->crop_bottom = frame.crop_bottom; + nv12_frame->crop_left = frame.crop_left; + nv12_frame->crop_right = frame.crop_right; + + av_frame_get_buffer(nv12_frame.get(), 0); + + if (m_sws_context == nullptr) { + m_sws_context = + SWSContextPtr(sws_getContext(frame.width, frame.height, AVPixelFormat(frame.format), + nv12_frame->width, nv12_frame->height, AV_PIX_FMT_NV12, + SWS_FAST_BILINEAR, nullptr, nullptr, nullptr), + &ReleaseSWSContext); + } + const auto res = sws_scale(m_sws_context.get(), frame.data, frame.linesize, 0, frame.height, + nv12_frame->data, nv12_frame->linesize); + if (res < 0) { + LOG_ERROR(Lib_AvPlayer, "Could not convert to NV12: {}", av_err2str(res)); + return AVFramePtr{nullptr, &ReleaseAVFrame}; + } + return nv12_frame; +} + +static u64 FrameTimestampMillis(const AVFrame& frame, AVRational time_base) { + auto timestamp = frame.best_effort_timestamp; + if (timestamp == AV_NOPTS_VALUE) { + timestamp = frame.pts; + } + if (timestamp == AV_NOPTS_VALUE) { + timestamp = frame.pkt_dts; + } + if (timestamp == AV_NOPTS_VALUE || timestamp < 0 || time_base.den <= 0) { + return 0; + } + + const auto millis = av_rescale_q(timestamp, time_base, AVRational{1, 1000}); + return millis > 0 ? u64(millis) : 0; +} + +Frame AvPlayerSource::PrepareVideoFrame(GuestBuffer buffer, const AVFrame& frame) { + ASSERT(frame.format == AV_PIX_FMT_NV12); + + auto p_buffer = buffer.GetBuffer(); + Videodec::CopyNV12Data(p_buffer, buffer.Size(), frame); + + const auto stream_index = m_streams[m_video_stream_index.value()].ffmpeg_index; + const auto stream = m_avformat_context->streams[stream_index]; + const auto timestamp = FrameTimestampMillis(frame, stream->time_base); + + const auto width = Common::AlignUp(frame.width, 16); + const auto pitch = Common::AlignUp(frame.width, 64); + const auto height = Common::AlignUp(frame.height, 16); + Core::Memory::Instance()->InvalidateMemory(reinterpret_cast(p_buffer), + (width * height * 3) / 2); + + return Frame{ + .buffer = std::move(buffer), + .info = + { + .p_data = p_buffer, + .timestamp = timestamp, + .details = + { + .video = + { + .width = width, + .height = height, + .aspect_ratio = (float)av_q2d(frame.sample_aspect_ratio), + .crop_left_offset = u32(frame.crop_left), + .crop_right_offset = u32(frame.crop_right + (pitch - frame.width)), + .crop_top_offset = u32(frame.crop_top), + .crop_bottom_offset = + u32(frame.crop_bottom + (height - frame.height)), + .pitch = pitch, + .luma_bit_depth = 8, + .chroma_bit_depth = 8, + }, + }, + }, + }; +} + +void AvPlayerSource::VideoDecoderThread(std::stop_token stop) { + using namespace std::chrono; + Common::SetCurrentThreadName("shadPS4:AvVideoDecoder"); + + LOG_INFO(Lib_AvPlayer, "Video Decoder Thread started"); + while ((!m_is_eof || m_video_packets.Size() != 0) && !stop.stop_requested()) { + if (m_video_packets.Size() == 0 && + !m_video_packets_cv.Wait(stop, [this] { return m_video_packets.Size() != 0; })) { + continue; + } + const auto packet = m_video_packets.Pop(); + if (!packet.has_value()) { + continue; + } + + auto res = avcodec_send_packet(m_video_codec_context.get(), packet->get()); + if (res < 0 && res != AVERROR(EAGAIN)) { + m_state.OnError(); + LOG_ERROR(Lib_AvPlayer, "Could not send packet to the video codec. Error = {}", + av_err2str(res)); + return; + } + while (res >= 0) { + if (m_video_buffers.Size() == 0 && + !m_video_buffers_cv.Wait(stop, [this] { return m_video_buffers.Size() != 0; })) { + break; + } + auto up_frame = AVFramePtr(av_frame_alloc(), &ReleaseAVFrame); + res = avcodec_receive_frame(m_video_codec_context.get(), up_frame.get()); + if (res < 0) { + if (res == AVERROR_EOF) { + LOG_INFO(Lib_AvPlayer, "EOF reached in video decoder"); + return; + } else if (res != AVERROR(EAGAIN)) { + LOG_ERROR(Lib_AvPlayer, + "Could not receive frame from the video codec. Error = {}", + av_err2str(res)); + m_state.OnError(); + return; + } + } else { + auto buffer = m_video_buffers.Pop(); + if (!buffer.has_value()) { + // Video buffers queue was cleared. This means that player was stopped. + break; + } + if (up_frame->format != AV_PIX_FMT_NV12) { + const auto nv12_frame = ConvertVideoFrame(*up_frame); + if (nv12_frame == nullptr) { + m_state.OnError(); + return; + } + m_video_frames.Push(PrepareVideoFrame(std::move(buffer.value()), *nv12_frame)); + } else { + m_video_frames.Push(PrepareVideoFrame(std::move(buffer.value()), *up_frame)); + } + m_video_frames_cv.Notify(); + } + } + } + + LOG_INFO(Lib_AvPlayer, "Video Decoder Thread exited normally"); + m_video_decoder_thread.Join(); +} + +AvPlayerSource::AVFramePtr AvPlayerSource::ConvertAudioFrame(const AVFrame& frame) { + auto pcm16_frame = AVFramePtr{av_frame_alloc(), &ReleaseAVFrame}; + pcm16_frame->best_effort_timestamp = frame.best_effort_timestamp; + pcm16_frame->pts = frame.pts; + pcm16_frame->pkt_dts = frame.pkt_dts < 0 ? 0 : frame.pkt_dts; + pcm16_frame->format = AV_SAMPLE_FMT_S16; + pcm16_frame->ch_layout = frame.ch_layout; + pcm16_frame->sample_rate = frame.sample_rate; + + if (m_swr_context == nullptr) { + SwrContext* swr_context = nullptr; + AVChannelLayout in_ch_layout = frame.ch_layout; + AVChannelLayout out_ch_layout = frame.ch_layout; + swr_alloc_set_opts2(&swr_context, &out_ch_layout, AV_SAMPLE_FMT_S16, frame.sample_rate, + &in_ch_layout, AVSampleFormat(frame.format), frame.sample_rate, 0, + nullptr); + m_swr_context = SWRContextPtr(swr_context, &ReleaseSWRContext); + swr_init(m_swr_context.get()); + } + const auto res = swr_convert_frame(m_swr_context.get(), pcm16_frame.get(), &frame); + if (res < 0) { + LOG_ERROR(Lib_AvPlayer, "Could not convert to NV12: {}", av_err2str(res)); + return AVFramePtr{nullptr, &ReleaseAVFrame}; + } + return pcm16_frame; +} + +Frame AvPlayerSource::PrepareAudioFrame(GuestBuffer buffer, const AVFrame& frame) { + ASSERT(frame.format == AV_SAMPLE_FMT_S16); + ASSERT(frame.nb_samples <= 1024); + + auto p_buffer = buffer.GetBuffer(); + const auto size = frame.ch_layout.nb_channels * frame.nb_samples * sizeof(u16); + std::memcpy(p_buffer, frame.data[0], size); + + const auto stream_index = m_streams[m_audio_stream_index.value()].ffmpeg_index; + const auto stream = m_avformat_context->streams[stream_index]; + const auto timestamp = FrameTimestampMillis(frame, stream->time_base); + + return Frame{ + .buffer = std::move(buffer), + .info = + { + .p_data = p_buffer, + .timestamp = timestamp, + .details = + { + .audio = + { + .channel_count = u16(frame.ch_layout.nb_channels), + .sample_rate = u32(frame.sample_rate), + .size = u32(size), + }, + }, + }, + }; +} + +void AvPlayerSource::AudioDecoderThread(std::stop_token stop) { + using namespace std::chrono; + Common::SetCurrentThreadName("shadPS4:AvAudioDecoder"); + + LOG_INFO(Lib_AvPlayer, "Audio Decoder Thread started"); + while ((!m_is_eof || m_audio_packets.Size() != 0) && !stop.stop_requested()) { + if (m_audio_packets.Size() == 0 && + !m_audio_packets_cv.Wait(stop, [this] { return m_audio_packets.Size() != 0; })) { + continue; + } + const auto packet = m_audio_packets.Pop(); + if (!packet.has_value()) { + continue; + } + auto res = avcodec_send_packet(m_audio_codec_context.get(), packet->get()); + if (res < 0 && res != AVERROR(EAGAIN)) { + m_state.OnError(); + LOG_ERROR(Lib_AvPlayer, "Could not send packet to the audio codec. Error = {}", + av_err2str(res)); + return; + } + while (res >= 0) { + if (m_audio_buffers.Size() == 0 && + !m_audio_buffers_cv.Wait(stop, [this] { return m_audio_buffers.Size() != 0; })) { + break; + } + + auto up_frame = AVFramePtr(av_frame_alloc(), &ReleaseAVFrame); + res = avcodec_receive_frame(m_audio_codec_context.get(), up_frame.get()); + if (res < 0) { + if (res == AVERROR_EOF) { + LOG_INFO(Lib_AvPlayer, "EOF reached in audio decoder"); + return; + } else if (res != AVERROR(EAGAIN)) { + m_state.OnError(); + LOG_ERROR(Lib_AvPlayer, + "Could not receive frame from the audio codec. Error = {}", + av_err2str(res)); + return; + } + } else { + auto buffer = m_audio_buffers.Pop(); + if (!buffer.has_value()) { + // Audio buffers queue was cleared. This means that player was stopped. + break; + } + if (up_frame->format != AV_SAMPLE_FMT_S16) { + const auto pcm16_frame = ConvertAudioFrame(*up_frame); + m_audio_frames.Push(PrepareAudioFrame(std::move(buffer.value()), *pcm16_frame)); + } else { + m_audio_frames.Push(PrepareAudioFrame(std::move(buffer.value()), *up_frame)); + } + m_audio_frames_cv.Notify(); + } + } + } + + LOG_INFO(Lib_AvPlayer, "Audio Decoder Thread exited normally"); + m_audio_decoder_thread.Join(); +} + +bool AvPlayerSource::HasRunningThreads() const { + return m_demuxer_thread.Joinable() || m_video_decoder_thread.Joinable() || + m_audio_decoder_thread.Joinable(); +} + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_source.h b/gpu/shadps4/core/libraries/avplayer/avplayer_source.h new file mode 100644 index 0000000..a835a14 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_source.h @@ -0,0 +1,260 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "core/libraries/avplayer/avplayer.h" +#include "core/libraries/avplayer/avplayer_common.h" +#include "core/libraries/avplayer/avplayer_data_streamer.h" +#include "core/libraries/kernel/threads.h" + +struct AVCodecContext; +struct AVFormatContext; +struct AVFrame; +struct AVIOContext; +struct AVPacket; +struct SwrContext; +struct SwsContext; + +namespace Libraries::AvPlayer { + +class AvPlayerStateCallback { +public: + virtual ~AvPlayerStateCallback() = default; + + virtual AvPlayerAvSyncMode GetSyncMode() = 0; + + virtual void OnWarning(u32 id) = 0; + virtual void OnError() = 0; + virtual void OnEOF() = 0; +}; + +class GuestBuffer { +public: + GuestBuffer(const AvPlayerMemAllocator& memory_replacement, u32 align, u32 size, + bool is_texture) noexcept + : m_memory_replacement(memory_replacement), + m_data(is_texture ? AllocateTexture(memory_replacement, align, size) + : Allocate(memory_replacement, align, size)), + m_size(size), m_is_texture(is_texture) { + ASSERT_MSG(m_data, "Could not allocate frame buffer."); + } + + ~GuestBuffer() { + if (m_data != nullptr) { + if (m_is_texture) { + DeallocateTexture(m_memory_replacement, m_data); + } else { + Deallocate(m_memory_replacement, m_data); + } + m_data = {}; + } + } + + GuestBuffer(const GuestBuffer&) noexcept = delete; + GuestBuffer& operator=(const GuestBuffer&) noexcept = delete; + + GuestBuffer(GuestBuffer&& r) noexcept + : m_memory_replacement(r.m_memory_replacement), m_data(r.m_data), m_size(r.m_size), + m_is_texture(r.m_is_texture) { + r.m_data = nullptr; + }; + + GuestBuffer& operator=(GuestBuffer&& r) noexcept { + std::swap(m_data, r.m_data); + return *this; + } + + u8* GetBuffer() const noexcept { + return m_data; + } + + u64 Size() const noexcept { + return m_size; + } + +private: + static u8* Allocate(const AvPlayerMemAllocator& memory_replacement, u32 align, u32 size) { + return reinterpret_cast( + memory_replacement.allocate(memory_replacement.object_ptr, align, size)); + } + + static void Deallocate(const AvPlayerMemAllocator& memory_replacement, void* ptr) { + memory_replacement.deallocate(memory_replacement.object_ptr, ptr); + } + + static u8* AllocateTexture(const AvPlayerMemAllocator& memory_replacement, u32 align, + u32 size) { + return reinterpret_cast( + memory_replacement.allocate_texture(memory_replacement.object_ptr, align, size)); + } + + static void DeallocateTexture(const AvPlayerMemAllocator& memory_replacement, void* ptr) { + memory_replacement.deallocate_texture(memory_replacement.object_ptr, ptr); + } + + const AvPlayerMemAllocator& m_memory_replacement; + u8* m_data = nullptr; + u64 m_size = 0; + bool m_is_texture = false; +}; + +struct Frame { + GuestBuffer buffer; + AvPlayerFrameInfoEx info; +}; + +class EventCV { +public: + template + void Wait(Pred pred) { + std::unique_lock lock(m_mutex); + m_cv.wait(lock, std::move(pred)); + } + + template + bool Wait(std::stop_token stop, Pred pred) { + std::unique_lock lock(m_mutex); + return m_cv.wait(lock, std::move(stop), std::move(pred)); + } + + template + bool WaitFor(std::chrono::duration timeout, Pred pred) { + std::unique_lock lock(m_mutex); + return m_cv.wait_for(lock, timeout, std::move(pred)); + } + + void Notify() { + std::unique_lock lock(m_mutex); + m_cv.notify_all(); + } + +private: + std::mutex m_mutex{}; + std::condition_variable_any m_cv{}; +}; + +class AvPlayerSource { +public: + AvPlayerSource(AvPlayerStateCallback& state); + ~AvPlayerSource(); + + bool Init(const AvPlayerInitData& init_data, std::string_view path); + bool FindStreams(); + s32 GetStreamCount(); + bool GetStreamInfo(u32 stream_index, AvPlayerStreamInfo& info); + bool EnableStream(u32 stream_index); + void SetLooping(bool is_looping); + std::optional HasFrames(u32 num_frames); + bool Start(); + bool Stop(); + void Pause(); + void Resume(); + bool GetAudioData(AvPlayerFrameInfo& audio_info); + bool GetVideoData(AvPlayerFrameInfo& video_info); + bool GetVideoData(AvPlayerFrameInfoEx& video_info); + u64 CurrentTime(); + bool IsActive(); + +private: + u64 DurationMillis() const; + AvPlayerStreamInfo CreateStreamInfo(u32 stream_index); + + static void ReleaseAVPacket(AVPacket* packet); + static void ReleaseAVFrame(AVFrame* frame); + static void ReleaseAVCodecContext(AVCodecContext* context); + static void ReleaseSWRContext(SwrContext* context); + static void ReleaseSWSContext(SwsContext* context); + static void ReleaseAVFormatContext(AVFormatContext* context); + + using AVPacketPtr = std::unique_ptr; + using AVFramePtr = std::unique_ptr; + using AVCodecContextPtr = std::unique_ptr; + using SWRContextPtr = std::unique_ptr; + using SWSContextPtr = std::unique_ptr; + using AVFormatContextPtr = std::unique_ptr; + + void DemuxerThread(std::stop_token stop); + void VideoDecoderThread(std::stop_token stop); + void AudioDecoderThread(std::stop_token stop); + + bool HasRunningThreads() const; + + AVFramePtr ConvertAudioFrame(const AVFrame& frame); + AVFramePtr ConvertVideoFrame(const AVFrame& frame); + + Frame PrepareAudioFrame(GuestBuffer buffer, const AVFrame& frame); + Frame PrepareVideoFrame(GuestBuffer buffer, const AVFrame& frame); + + AvPlayerStateCallback& m_state; + + struct Stream { + size_t ffmpeg_index = 0; + AvPlayerStreamInfo info; + }; + + std::vector m_streams; + u64 m_duration = 0; + + AvPlayerMemAllocator m_memory_replacement{}; + u32 m_max_num_video_framebuffers{}; + + std::atomic_bool m_is_looping = false; + std::atomic_bool m_is_paused = false; + std::atomic_bool m_is_eof = false; + + std::unique_ptr m_up_data_streamer; + + AvPlayerQueue m_audio_buffers; + AvPlayerQueue m_video_buffers; + + AvPlayerQueue m_audio_packets; + AvPlayerQueue m_video_packets; + + AvPlayerQueue m_audio_frames; + AvPlayerQueue m_video_frames; + + std::optional m_current_video_frame; + std::optional m_current_audio_frame; + + std::optional m_video_stream_index{}; + std::optional m_audio_stream_index{}; + + EventCV m_audio_packets_cv{}; + EventCV m_audio_frames_cv{}; + EventCV m_audio_buffers_cv{}; + + EventCV m_video_packets_cv{}; + EventCV m_video_frames_cv{}; + EventCV m_video_buffers_cv{}; + + std::mutex m_state_mutex{}; + Kernel::Thread m_demuxer_thread{}; + Kernel::Thread m_video_decoder_thread{}; + Kernel::Thread m_audio_decoder_thread{}; + + AVFormatContextPtr m_avformat_context{nullptr, &ReleaseAVFormatContext}; + AVCodecContextPtr m_video_codec_context{nullptr, &ReleaseAVCodecContext}; + AVCodecContextPtr m_audio_codec_context{nullptr, &ReleaseAVCodecContext}; + SWRContextPtr m_swr_context{nullptr, &ReleaseSWRContext}; + SWSContextPtr m_sws_context{nullptr, &ReleaseSWSContext}; + + std::optional m_last_audio_ts{}; + std::optional m_last_data_time{}; + std::optional m_start_time{}; + std::chrono::high_resolution_clock::time_point m_pause_time{}; + std::chrono::high_resolution_clock::duration m_pause_duration{}; +}; + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_state.cpp b/gpu/shadps4/core/libraries/avplayer/avplayer_state.cpp new file mode 100644 index 0000000..c81f9e1 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_state.cpp @@ -0,0 +1,581 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/elf_info.h" +#include "common/logging/log.h" +#include "common/thread.h" +#include "core/libraries/avplayer/avplayer_error.h" +#include "core/libraries/avplayer/avplayer_state.h" +#include "core/libraries/kernel/process.h" + +#include + +namespace Libraries::AvPlayer { + +void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, AvPlayerEvents event_id, + s32 source_id, void* event_data) { + auto const self = reinterpret_cast(opaque); + + if (event_id == AvPlayerEvents::StateReady) { + s32 video_stream_index = -1; + s32 audio_stream_index = -1; + s32 timedtext_stream_index = -1; + const s32 stream_count = self->GetStreamCount(); + if (AVPLAYER_IS_ERROR(stream_count)) { + self->Stop(); + return; + } + if (stream_count == 0) { + self->Stop(); + return; + } + for (u32 stream_index = 0; stream_index < stream_count; ++stream_index) { + AvPlayerStreamInfo info{}; + if (!self->GetStreamInfo(stream_index, info)) { + self->Stop(); + return; + } + + const std::string_view default_language{self->m_default_language}; + switch (info.type) { + case AvPlayerStreamType::Video: + if (video_stream_index == -1) { + video_stream_index = stream_index; + } + if (!default_language.empty() && + default_language == info.details.video.language_code) { + video_stream_index = stream_index; + } + break; + case AvPlayerStreamType::Audio: + if (audio_stream_index == -1) { + audio_stream_index = stream_index; + } + if (!default_language.empty() && + default_language == info.details.audio.language_code) { + audio_stream_index = stream_index; + } + break; + case AvPlayerStreamType::TimedText: + if (timedtext_stream_index == -1) { + timedtext_stream_index = stream_index; + } + if (!default_language.empty() && + default_language == info.details.subs.language_code) { + timedtext_stream_index = stream_index; + } + break; + default: + break; + } + } + + if (video_stream_index != -1) { + self->EnableStream(video_stream_index); + } + if (audio_stream_index != -1) { + self->EnableStream(audio_stream_index); + } + if (timedtext_stream_index != -1) { + self->EnableStream(timedtext_stream_index); + } + self->Start(); + return; + } + + DefaultEventCallback(opaque, event_id, 0, event_data); +} + +void AvPlayerState::DefaultEventCallback(void* opaque, AvPlayerEvents event_id, s32 source_id, + void* event_data) { + auto const self = reinterpret_cast(opaque); + const auto callback = self->m_event_replacement.event_callback; + const auto ptr = self->m_event_replacement.object_ptr; + if (callback != nullptr) { + callback(ptr, event_id, 0, event_data); + } +} + +// Called inside GAME thread +AvPlayerState::AvPlayerState(const AvPlayerInitData& init_data) + : m_init_data(init_data), m_event_replacement(init_data.event_replacement) { + if (m_event_replacement.event_callback == nullptr || init_data.auto_start) { + m_auto_start = true; + m_init_data.event_replacement.event_callback = &AvPlayerState::AutoPlayEventCallback; + } else { + m_init_data.event_replacement.event_callback = &AvPlayerState::DefaultEventCallback; + } + m_init_data.event_replacement.object_ptr = this; + if (init_data.default_language != nullptr) { + std::memcpy(m_default_language, init_data.default_language, sizeof(m_default_language)); + } + SetState(AvState::Initial); + StartControllerThread(); +} + +AvPlayerState::~AvPlayerState() { + { + std::unique_lock lock(m_source_mutex); + m_up_source.reset(); + } + m_controller_thread.Stop(); + m_event_queue.Clear(); +} + +void AvPlayerState::PostInit(const AvPlayerPostInitData& post_init_data) { + m_post_init_data = post_init_data; +} + +// Called inside GAME thread +bool AvPlayerState::AddSource(std::string_view path, AvPlayerSourceType source_type) { + if (path.empty()) { + LOG_ERROR(Lib_AvPlayer, "File path is empty."); + return false; + } + + { + std::unique_lock lock(m_source_mutex); + if (m_up_source != nullptr) { + LOG_ERROR(Lib_AvPlayer, "Only one source is supported."); + return false; + } + + s32 sdk_ver{}; + Libraries::Kernel::sceKernelGetCompiledSdkVersion(&sdk_ver); + m_up_source = std::make_unique(*this); + if (!m_up_source->Init(m_init_data, path)) { + SetState(AvState::Error); + m_up_source.reset(); + return false; + } + } + AddSourceEvent(); + return true; +} + +// Called inside GAME thread +s32 AvPlayerState::GetStreamCount() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + LOG_ERROR(Lib_AvPlayer, "Could not get stream count. No source."); + return -1; + } + return m_up_source->GetStreamCount(); +} + +// Called inside GAME thread +bool AvPlayerState::GetStreamInfo(u32 stream_index, AvPlayerStreamInfo& info) { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info. No source.", stream_index); + return false; + } + return m_up_source->GetStreamInfo(stream_index, info); +} + +// Called inside GAME thread +bool AvPlayerState::Start() { + std::unique_lock lock(m_source_mutex); + if (m_current_state == AvState::Ready || m_current_state == AvState::Stop || Stop()) { + m_eof_stop_event_sent = false; + SetState(AvState::Starting); + if (!m_up_source->Start()) { + LOG_ERROR(Lib_AvPlayer, "Could not start playback."); + SetState(AvState::Error); + return false; + } + SetState(AvState::Play); + OnPlaybackStateChanged(AvState::Play); + return true; + } + + LOG_ERROR(Lib_AvPlayer, "Could not start playback."); + return false; +} + +// Called inside GAME thread +bool AvPlayerState::Pause() { + std::shared_lock lock(m_source_mutex); + if (m_current_state == AvState::EndOfFile) { + return true; + } + if (m_up_source == nullptr || m_current_state == AvState::Pause || + m_current_state == AvState::Ready || m_current_state == AvState::Initial || + m_current_state == AvState::Unknown || m_current_state == AvState::AddingSource) { + LOG_ERROR(Lib_AvPlayer, "Could not pause playback."); + return false; + } + m_up_source->Pause(); + if (!SetState(AvState::Pause)) { + return false; + } + OnPlaybackStateChanged(AvState::Pause); + return true; +} + +// Called inside GAME thread +bool AvPlayerState::Resume() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr || m_current_state != AvState::Pause) { + LOG_ERROR(Lib_AvPlayer, "Could not resume playback."); + return false; + } + m_up_source->Resume(); + const auto state = m_previous_state.load(); + SetState(state); + OnPlaybackStateChanged(state); + return true; +} + +void AvPlayerState::SetAvSyncMode(AvPlayerAvSyncMode sync_mode) { + m_sync_mode = sync_mode; +} + +void AvPlayerState::AvControllerThread(std::stop_token stop) { + using std::chrono::milliseconds; + Common::SetCurrentThreadName("shadPS4:AvController"); + + while (!stop.stop_requested()) { + if (m_event_queue.Size() != 0) { + ProcessEvent(); + continue; + } + std::this_thread::sleep_for(milliseconds(5)); + UpdateBufferingState(); + } +} + +// Called inside GAME thread +void AvPlayerState::AddSourceEvent() { + SetState(AvState::AddingSource); + m_event_queue.Push(AvPlayerEvent{ + .event = AvEventType::AddSource, + }); +} + +void AvPlayerState::WarningEvent(s32 id) { + m_event_queue.Push(AvPlayerEvent{ + .event = AvEventType::WarningId, + .payload = + { + .error = id, + }, + }); +} + +// Called inside GAME thread +void AvPlayerState::StartControllerThread() { + m_controller_thread.Run([this](std::stop_token stop) { this->AvControllerThread(stop); }); +} + +// Called inside GAME thread +bool AvPlayerState::EnableStream(u32 stream_index) { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + return false; + } + return m_up_source->EnableStream(stream_index); +} + +// Called inside GAME thread +bool AvPlayerState::Stop() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr || m_current_state == AvState::Stop) { + return false; + } + if (!m_up_source->Stop()) { + return false; + } + if (!SetState(AvState::Stop)) { + return false; + } + m_eof_stop_event_sent = true; + OnPlaybackStateChanged(AvState::Stop); + return true; +} + +bool AvPlayerState::GetVideoData(AvPlayerFrameInfo& video_info) { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + return false; + } + return m_up_source->GetVideoData(video_info); +} + +bool AvPlayerState::GetVideoData(AvPlayerFrameInfoEx& video_info) { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + return false; + } + return m_up_source->GetVideoData(video_info); +} + +bool AvPlayerState::GetAudioData(AvPlayerFrameInfo& audio_info) { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + return false; + } + return m_up_source->GetAudioData(audio_info); +} + +bool AvPlayerState::IsActive() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + return false; + } + return m_current_state != AvState::Stop && m_current_state != AvState::Error && + m_up_source->IsActive(); +} + +u64 AvPlayerState::CurrentTime() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + LOG_ERROR(Lib_AvPlayer, "Could not get current time. No source."); + return 0; + } + return m_up_source->CurrentTime(); +} + +bool AvPlayerState::SetLooping(bool is_looping) { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr) { + LOG_ERROR(Lib_AvPlayer, "Could not set loop flag. No source."); + return false; + } + m_up_source->SetLooping(is_looping); + return true; +} + +// May be called from different threads +void AvPlayerState::OnWarning(u32 id) { + // Forward to CONTROLLER thread + WarningEvent(id); +} + +AvPlayerAvSyncMode AvPlayerState::GetSyncMode() { + return m_sync_mode; +} + +void AvPlayerState::OnError() { + SetState(AvState::Error); + OnPlaybackStateChanged(AvState::Error); +} + +void AvPlayerState::OnEOF() { + SetState(AvState::EndOfFile); +} + +void AvPlayerState::UpdateEndOfFileState() { + std::shared_lock lock(m_source_mutex); + if (m_up_source == nullptr || m_up_source->IsActive() || m_eof_stop_event_sent.exchange(true)) { + return; + } + lock.unlock(); + + EmitEvent(AvPlayerEvents::StateStop); +} + +// Called inside CONTROLLER thread +void AvPlayerState::OnPlaybackStateChanged(AvState state) { + switch (state) { + case AvState::Ready: { + EmitEvent(AvPlayerEvents::StateReady); + break; + } + case AvState::Play: { + EmitEvent(AvPlayerEvents::StatePlay); + break; + } + case AvState::Stop: { + EmitEvent(AvPlayerEvents::StateStop); + break; + } + case AvState::Pause: { + EmitEvent(AvPlayerEvents::StatePause); + break; + } + case AvState::Buffering: { + EmitEvent(AvPlayerEvents::StateBuffering); + break; + } + default: + break; + } +} + +// Called inside CONTROLLER and GAME threads +bool AvPlayerState::SetState(AvState state) { + std::lock_guard guard(m_state_machine_mutex); + + if (!IsStateTransitionValid(state)) { + LOG_ERROR(Lib_AvPlayer, "Invalid state transition: {} -> {}", + magic_enum::enum_name(m_current_state.load()), magic_enum::enum_name(state)); + return false; + } + m_previous_state.store(m_current_state); + m_current_state.store(state); + return true; +} + +// Called inside CONTROLLER thread +std::optional AvPlayerState::OnBufferingCheckEvent(u32 num_frames) { + std::shared_lock lock(m_source_mutex); + if (!m_up_source) { + return std::nullopt; + } + return m_up_source->HasFrames(num_frames); +} + +// Called inside CONTROLLER thread +void AvPlayerState::EmitEvent(AvPlayerEvents event_id, void* event_data) { + LOG_INFO(Lib_AvPlayer, "Sending event to the game: id = {}", magic_enum::enum_name(event_id)); + const auto callback = m_init_data.event_replacement.event_callback; + if (callback) { + const auto ptr = m_init_data.event_replacement.object_ptr; + callback(ptr, event_id, 0, event_data); + } +} + +// Called inside CONTROLLER thread +void AvPlayerState::ProcessEvent() { + if (m_current_state == AvState::Jump) { + return; + } + + std::lock_guard guard(m_event_handler_mutex); + + auto event = m_event_queue.Pop(); + if (!event.has_value()) { + return; + } + switch (event->event) { + case AvEventType::WarningId: { + EmitEvent(AvPlayerEvents::WarningId, &event->payload.error); + break; + } + case AvEventType::RevertState: { + SetState(m_previous_state.load()); + break; + } + case AvEventType::AddSource: { + bool found = false; + { + std::unique_lock lock(m_source_mutex); + found = m_up_source != nullptr && m_up_source->FindStreams(); + } + if (found) { + SetState(AvState::Ready); + OnPlaybackStateChanged(AvState::Ready); + } else { + OnWarning(ORBIS_AVPLAYER_ERROR_NOT_SUPPORTED); + SetState(AvState::Error); + } + break; + } + case AvEventType::Error: { + OnWarning(event->payload.error); + SetState(AvState::Error); + break; + } + default: + break; + } +} + +// Called inside CONTROLLER thread +void AvPlayerState::UpdateBufferingState() { + if (m_current_state == AvState::EndOfFile) { + UpdateEndOfFileState(); + } else if (m_current_state == AvState::Buffering) { + const auto has_frames = OnBufferingCheckEvent(10); + if (!has_frames.has_value()) { + return; + } + if (has_frames.value()) { + const auto state = + m_previous_state >= AvState::C0x0B ? m_previous_state.load() : AvState::Play; + SetState(state); + OnPlaybackStateChanged(state); + } + } else if (m_current_state == AvState::Play) { + const auto has_frames = OnBufferingCheckEvent(0); + if (!has_frames.has_value()) { + return; + } + if (!has_frames.value()) { + SetState(AvState::Buffering); + OnPlaybackStateChanged(AvState::Buffering); + } + } +} + +bool AvPlayerState::IsStateTransitionValid(AvState state) { + switch (state) { + case AvState::Play: { + switch (m_current_state.load()) { + case AvState::Stop: + case AvState::EndOfFile: + // case AvState::C0x08: + case AvState::Error: + return false; + default: + return true; + } + } + case AvState::Pause: { + switch (m_current_state.load()) { + case AvState::Stop: + case AvState::EndOfFile: + // case AvState::C0x08: + case AvState::Starting: + case AvState::Error: + return false; + default: + return true; + } + } + case AvState::Jump: { + switch (m_current_state.load()) { + case AvState::Stop: + case AvState::EndOfFile: + // case AvState::C0x08: + case AvState::TrickMode: + case AvState::Starting: + case AvState::Error: + return false; + default: + return true; + } + } + case AvState::TrickMode: { + switch (m_current_state.load()) { + case AvState::Stop: + case AvState::EndOfFile: + // case AvState::C0x08: + case AvState::Jump: + case AvState::Starting: + case AvState::Error: + return false; + default: + return true; + } + } + case AvState::Buffering: { + switch (m_current_state.load()) { + case AvState::Stop: + case AvState::EndOfFile: + case AvState::Pause: + // case AvState::C0x08: + case AvState::Starting: + case AvState::Error: + return false; + default: + return true; + } + } + default: + return true; + } +} + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/avplayer/avplayer_state.h b/gpu/shadps4/core/libraries/avplayer/avplayer_state.h new file mode 100644 index 0000000..8933521 --- /dev/null +++ b/gpu/shadps4/core/libraries/avplayer/avplayer_state.h @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "core/libraries/avplayer/avplayer.h" +#include "core/libraries/avplayer/avplayer_source.h" +#include "core/libraries/kernel/threads.h" + +namespace Libraries::AvPlayer { + +class Stream; +class AvDecoder; + +class AvPlayerState : public AvPlayerStateCallback { +public: + AvPlayerState(const AvPlayerInitData& init_data); + ~AvPlayerState(); + + void PostInit(const AvPlayerPostInitData& post_init_data); + bool AddSource(std::string_view filename, AvPlayerSourceType source_type); + s32 GetStreamCount(); + bool GetStreamInfo(u32 stream_index, AvPlayerStreamInfo& info); + bool EnableStream(u32 stream_index); + bool Start(); + bool Stop(); + bool Pause(); + bool Resume(); + void SetAvSyncMode(AvPlayerAvSyncMode sync_mode); + bool GetAudioData(AvPlayerFrameInfo& audio_info); + bool GetVideoData(AvPlayerFrameInfo& video_info); + bool GetVideoData(AvPlayerFrameInfoEx& video_info); + bool IsActive(); + u64 CurrentTime(); + bool SetLooping(bool is_looping); + +private: + // Event Replacement + static void PS4_SYSV_ABI AutoPlayEventCallback(void* handle, AvPlayerEvents event_id, + s32 source_id, void* event_data); + + static void PS4_SYSV_ABI DefaultEventCallback(void* handle, AvPlayerEvents event_id, + s32 source_id, void* event_data); + + AvPlayerAvSyncMode GetSyncMode() override; + void OnWarning(u32 id) override; + void OnError() override; + void OnEOF() override; + + void OnPlaybackStateChanged(AvState state); + std::optional OnBufferingCheckEvent(u32 num_frames); + + void EmitEvent(AvPlayerEvents event_id, void* event_data = nullptr); + bool SetState(AvState state); + + void AvControllerThread(std::stop_token stop); + + void AddSourceEvent(); + void WarningEvent(s32 id); + + void StartControllerThread(); + void ProcessEvent(); + void UpdateBufferingState(); + void UpdateEndOfFileState(); + bool IsStateTransitionValid(AvState state); + + std::unique_ptr m_up_source; + + AvPlayerInitData m_init_data{}; + AvPlayerPostInitData m_post_init_data{}; + AvPlayerEventReplacement m_event_replacement{}; + bool m_auto_start{}; + char m_default_language[4]{}; + AvPlayerAvSyncMode m_sync_mode = AvPlayerAvSyncMode::Default; + + std::atomic m_current_state; + std::atomic m_previous_state; + std::atomic_bool m_eof_stop_event_sent{false}; + u32 m_thread_priority; + u32 m_thread_affinity; + std::atomic_uint32_t m_some_event_result{}; + + std::shared_mutex m_source_mutex{}; + std::mutex m_state_machine_mutex{}; + std::mutex m_event_handler_mutex{}; + Kernel::Thread m_controller_thread{}; + AvPlayerQueue m_event_queue{}; +}; + +} // namespace Libraries::AvPlayer diff --git a/gpu/shadps4/core/libraries/error_codes.h b/gpu/shadps4/core/libraries/error_codes.h new file mode 100644 index 0000000..e1902b6 --- /dev/null +++ b/gpu/shadps4/core/libraries/error_codes.h @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +// Generic +constexpr int ORBIS_OK = 0x00000000; +constexpr int ORBIS_FAIL = 0xFFFFFFFF; diff --git a/gpu/shadps4/core/libraries/gnmdriver/gnm_error.h b/gpu/shadps4/core/libraries/gnmdriver/gnm_error.h new file mode 100644 index 0000000..b8e57f6 --- /dev/null +++ b/gpu/shadps4/core/libraries/gnmdriver/gnm_error.h @@ -0,0 +1,87 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +constexpr int ORBIS_GNM_ERROR_SUBMISSION_FAILED_INVALID_ARGUMENT = 0x80D11000; +constexpr int ORBIS_GNM_ERROR_SUBMISSION_NOT_ENOUGH_RESOURCES = 0x80D11001; +constexpr int ORBIS_GNM_ERROR_SUBMISSION_AND_FLIP_FAILED_INVALID_COMMAND_BUFFER = 0x80D11080; +constexpr int ORBIS_GNM_ERROR_SUBMISSION_AND_FLIP_FAILED_INVALID_QUEUE_FULL = 0x80D11081; +constexpr int ORBIS_GNM_ERROR_SUBMISSION_AND_FLIP_FAILED_REQUEST_FAILED = 0x80D11082; +constexpr int ORBIS_GNM_ERROR_SUBMISSION_FAILED_INTERNAL_ERROR = 0x80D110FF; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING = 0x80D12000; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_RWBUFFER_ROTYPE = 0x80D12001; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_BLENDING = 0x80D12002; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_DRAW_CU_MASK = 0x80D12003; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_MRT_SETUP = 0x80D12004; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_DEPTH_RT_SETUP = 0x80D12005; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_PS_AND_MRT_FORMAT = 0x80D1200F; +constexpr int ORBIS_GNM_ERROR_VALIDATION_ERROR = 0x80D13000; +constexpr int ORBIS_GNM_ERROR_VALIDATION_VSHARP = 0x80D13001; +constexpr int ORBIS_GNM_ERROR_VALIDATION_TSHARP = 0x80D13002; +constexpr int ORBIS_GNM_ERROR_VALIDATION_RESOURCE = 0x80D13003; +constexpr int ORBIS_GNM_ERROR_VALIDATION_TABLE_MEMORY = 0x80D13004; +constexpr int ORBIS_GNM_ERROR_VALIDATION_WRITE_EVENT_OP = 0x80D13005; +constexpr int ORBIS_GNM_ERROR_VALIDATION_INDEX_BUFFER = 0x80D13006; +constexpr int ORBIS_GNM_ERROR_VALIDATION_TESS_FACTOR_BUFFER = 0x80D13007; +constexpr int ORBIS_GNM_ERROR_VALIDATION_SCRATCH_RING = 0x80D13008; +constexpr int ORBIS_GNM_ERROR_VALIDATION_PRIMITIVE_TYPE = 0x80D13009; +constexpr int ORBIS_GNM_ERROR_VALIDATION_INDEX_SIZE = 0x80D1300A; +constexpr int ORBIS_GNM_ERROR_VALIDATION_INLINE_DRAW_SIZE = 0x80D1300B; +constexpr int ORBIS_GNM_ERROR_VALIDATION_NUM_INPUT_PATCHES = 0x80D1300C; +constexpr int ORBIS_GNM_ERROR_VALIDATION_GS_MODE = 0x80D1300D; +constexpr int ORBIS_GNM_ERROR_VALIDATION_SHADER_ADDRESS = 0x80D1300E; +constexpr int ORBIS_GNM_ERROR_VALIDATION_BORDER_COLOR_TABLE = 0x80D1300F; +constexpr int ORBIS_GNM_ERROR_VALIDATION_SSHARP = 0x80D13010; +constexpr int ORBIS_GNM_ERROR_VALIDATION_DISPATCH_DRAW = 0x80D13011; +constexpr int ORBIS_GNM_ERROR_VALIDATION_ACTIVE_SHADER_STAGE = 0x80D13012; +constexpr int ORBIS_GNM_ERROR_VALIDATION_DCB = 0x80D13013; +constexpr int ORBIS_GNM_ERROR_VALIDATION_MISMATCH_SHADER_STAGE = 0x80D13014; +constexpr int ORBIS_GNM_ERROR_VALIDATION_MRT_SETUP = 0x80D13015; +constexpr int ORBIS_GNM_ERROR_VALIDATION_BAD_OP_CODE = 0x80D13016; +constexpr int ORBIS_GNM_ERROR_VALIDATION_DEPTH_RT_SETUP = 0x80D13017; +constexpr int ORBIS_GNM_ERROR_VALIDATION_NUM_INSTANCES = 0x80D13018; +constexpr int ORBIS_GNM_ERROR_VALIDATION_SRT = 0x80D13019; +constexpr int ORBIS_GNM_ERROR_VALIDATION_INVALID_ARGUMENT = 0x80D13FFD; +constexpr int ORBIS_GNM_ERROR_VALIDATION_FAILED_INTERNAL_ERROR = 0x80D13FFE; +constexpr int ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED = 0x80D13FFF; +constexpr int ORBIS_GNM_ERROR_CAPTURE_FILE_IO = 0x80D15000; +constexpr int ORBIS_GNM_ERROR_CAPTURE_RAZOR_NOT_LOADED = 0x80D15001; +constexpr int ORBIS_GNM_ERROR_CAPTURE_NOTHING_TO_CAPTURE = 0x80D15002; +constexpr int ORBIS_GNM_ERROR_CAPTURE_FAILED_INTERNAL = 0x80D1500F; +constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_ID = 0x80D17000; +constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_QUEUE_ID = 0x80D17001; +constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_SIZE = 0x80D17002; +constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_BASE_ADDR = 0x80D17003; +constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_READ_PTR_ADDR = 0x80D17004; +constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_PRIORITY = 0x80D17005; +constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INTERNAL = 0x80D170FF; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_ARGUMENT = 0x80D19000; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_SHADER = 0x80D19001; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_STALE_HANDLE = 0x80D19002; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_FULL = 0x80D19003; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_NOT_PERMITTED = 0x80D19004; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_OUTPUT_ARGUMENT_IS_NULL = 0x80D19005; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_OWNER_HANDLE_INVALID = 0x80D19006; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_HANDLE_INVALID = 0x80D19007; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_TYPE_INVALID = 0x80D19008; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_GDS_RESOURCE_TYPE_INVALID = 0x80D19009; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_SIZE_INVALID = 0x80D1900A; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_ADDRESS_IS_NULL = 0x80D1900B; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_GDS_OFFSET_INVALID = 0x80D1900C; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_NAME_IS_NULL = 0x80D1900D; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_OWNER_NAME_IS_NULL = 0x80D1900E; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_FIND_CALLBACK_IS_NULL = 0x80D1900F; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_IS_NOT_SHADER = 0x80D19010; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_USER_MEMORY_PARAM_IS_NULL = 0x80D19011; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_USER_MEMORY_PARAM_NOT_ALIGNED = 0x80D19012; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_NAME_LENGTH_PARAM = 0x80D19013; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_SIZE_PARAM = 0x80D19014; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_NUM_RESOURCES_PARAM = 0x80D19015; +constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INTERNAL = 0x80D19FFF; +constexpr int ORBIS_GNM_ERROR_GET_GPU_INFO_PARAMETER_NULL = 0x80D1B000; +constexpr int ORBIS_GNM_ERROR_GET_GPU_INFO_FAILED = 0x80D1B001; +constexpr int ORBIS_GNM_ERROR_GET_GPU_INFO_PARAMETER_INVALID = 0x80D1B002; +constexpr int ORBIS_GNM_ERROR_FAILURE = 0x8EEE00FF; diff --git a/gpu/shadps4/core/libraries/gnmdriver/gnmdriver.cpp b/gpu/shadps4/core/libraries/gnmdriver/gnmdriver.cpp new file mode 100644 index 0000000..65087ec --- /dev/null +++ b/gpu/shadps4/core/libraries/gnmdriver/gnmdriver.cpp @@ -0,0 +1,3297 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "gnm_error.h" +#include "gnmdriver.h" + +#include "common/assert.h" +#include "common/debug.h" +#include "common/elf_info.h" +#include "common/logging/log.h" +#include "common/slot_vector.h" +#include "core/address_space.h" +#include "core/debug_state.h" +#include "core/emulator_settings.h" +#include "core/libraries/gnmdriver/gnm_error.h" +#include "core/libraries/gnmdriver/gnmdriver_init.h" +#include "core/libraries/kernel/orbis_error.h" +#include "core/libraries/kernel/process.h" +#include "core/libraries/libs.h" +#include "core/libraries/videoout/video_out.h" +#include "core/memory.h" +#include "core/platform.h" +#include "video_core/amdgpu/liverpool.h" +#include "video_core/amdgpu/pm4_cmds.h" +#include "video_core/renderer_vulkan/vk_presenter.h" + +extern Frontend::WindowSDL* g_window; +std::unique_ptr presenter; +std::unique_ptr liverpool; + +namespace Libraries::GnmDriver { + +using namespace AmdGpu; + +enum GnmEventType : u64 { + Compute0RelMem = 0x00, + Compute1RelMem = 0x01, + Compute2RelMem = 0x02, + Compute3RelMem = 0x03, + Compute4RelMem = 0x04, + Compute5RelMem = 0x05, + Compute6RelMem = 0x06, + GfxEop = 0x40 +}; + +enum ShaderStages : u32 { + Cs, + Ps, + Vs, + Gs, + Es, + Hs, + Ls, + + Max +}; + +static constexpr std::array indirect_sgpr_offsets{0u, 0u, 0x4cu, 0u, 0xccu, 0u, 0x14cu}; + +// Gates use of what appear to be the neo-mode init sequences but with the older +// IA_MULTI_VGT_PARAM register address. No idea what this is for as the ioctl +// that controls it is still a mystery, but leaving the sequences in gated behind +// this flag in case we need it in the future. +static constexpr bool UseNeoCompatSequences = false; + +// In case if `submitDone` is issued we need to block submissions until GPU idle +static u32 submission_lock{}; +std::condition_variable cv_lock{}; +std::mutex m_wait_idle{}; +std::mutex m_submit_lock{}; +static u64 frames_submitted{}; // frame counter +static bool send_init_packet{true}; // initialize HW state before first game's submit in a frame +static s32 sdk_version{0}; + +static u32 asc_next_offs_dw[Liverpool::NumComputeRings]; + +// This address is initialized in sceGnmGetTheTessellationFactorRingBufferBaseAddress +static VAddr tessellation_factors_ring_addr = -1; +static constexpr u32 tessellation_offchip_buffer_size = 0x800000u; + +static void ResetSubmissionLock(Platform::InterruptId irq) { + std::unique_lock lock{m_wait_idle}; + submission_lock = 0; + cv_lock.notify_all(); +} + +static void WaitGpuIdle() { + HLE_TRACE; + std::unique_lock lock{m_wait_idle}; + cv_lock.wait(lock, [] { return submission_lock == 0; }); +} + +// Write a special ending NOP packet with N DWs data block +static inline u32* WriteTrailingNop(u32* cmdbuf, u32 data_block_size) { + auto* nop = reinterpret_cast(cmdbuf); + nop->header = PM4Type3Header{PM4ItOpcode::Nop, data_block_size - 1}; + nop->data_block[0] = 0u; // only one out of `data_block_size` is initialized + return cmdbuf + data_block_size + 1 /* header */; +} + +// Write a special ending NOP packet with N DWs data block +template +static inline u32* WriteTrailingNop(u32* cmdbuf) { + auto* nop = reinterpret_cast(cmdbuf); + nop->header = PM4Type3Header{PM4ItOpcode::Nop, data_block_size - 1}; + nop->data_block[0] = 0u; // only one out of `data_block_size` is initialized + return cmdbuf + data_block_size + 1 /* header */; +} + +static inline u32* ClearContextState(u32* cmdbuf) { + static constexpr std::array ClearStateSequence{ + 0xc0012800u, 0x80000000u, 0x80000000u, 0xc0001200u, 0u, 0xc0055800u, + 0x2ec47fc0u, 0xffffffffu, 0u, 0u, 0u, 10u, + }; + static_assert(ClearStateSequence.size() == 0xc); + + std::memcpy(cmdbuf, ClearStateSequence.data(), ClearStateSequence.size() * 4); + return cmdbuf + ClearStateSequence.size(); +} + +static inline bool IsValidEventType(Platform::InterruptId id) { + return (static_cast(id) >= static_cast(Platform::InterruptId::Compute0RelMem) && + static_cast(id) <= static_cast(Platform::InterruptId::Compute6RelMem)) || + static_cast(id) == static_cast(Platform::InterruptId::GfxEop); +} + +s32 PS4_SYSV_ABI sceGnmAddEqEvent(OrbisKernelEqueue eq, u64 id, void* udata) { + LOG_TRACE(Lib_GnmDriver, "called"); + + auto equeue = GetEqueue(eq); + if (!equeue) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + EqueueEvent kernel_event{}; + kernel_event.event.ident = id; + kernel_event.event.filter = OrbisKernelEvent::Filter::GraphicsCore; + kernel_event.event.flags = OrbisKernelEvent::Flags::Add; + kernel_event.event.fflags = 0; + kernel_event.event.data = id; + kernel_event.event.udata = udata; + + equeue->AddEvent(kernel_event); + + Platform::IrqC::Instance()->Register( + static_cast(id), + [=](Platform::InterruptId irq) { + ASSERT_MSG(irq == static_cast(id), "An unexpected IRQ occured"); + + // We need to convert IRQ# to event id + if (!IsValidEventType(irq)) + return; + + // Event data is expected to be an event type as per sceGnmGetEqEventType. + equeue->TriggerEvent(static_cast(id), + OrbisKernelEvent::Filter::GraphicsCore, + reinterpret_cast(id)); + }, + equeue); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmAreSubmitsAllowed() { + LOG_TRACE(Lib_GnmDriver, "called"); + return submission_lock == 0; +} + +int PS4_SYSV_ABI sceGnmBeginWorkload(u32 workload_stream, u64* workload) { + if (workload) { + *workload = (-(u32)(workload_stream < 0x10) & 1); + return 0xf < workload_stream; + } + return 3; +} + +s32 PS4_SYSV_ABI sceGnmComputeWaitOnAddress(u32* cmdbuf, u32 size, uintptr_t addr, u32 mask, + u32 cmp_func, u32 ref) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 0xe)) { + cmdbuf = WriteHeader(cmdbuf, 3); + cmdbuf = WriteBody(cmdbuf, 0u); + cmdbuf += 2; + + const u32 is_mem = addr > 0xffffu; + const u32 addr_mask = is_mem ? 0xfffffffcu : 0xffffu; + auto* wait_reg_mem = reinterpret_cast(cmdbuf); + wait_reg_mem->header = PM4Type3Header{PM4ItOpcode::WaitRegMem, 5}; + wait_reg_mem->raw = (is_mem << 4u) | (cmp_func & 7u); + wait_reg_mem->poll_addr_lo_raw = u32(addr & addr_mask); + wait_reg_mem->poll_addr_hi = u32(addr >> 32u); + wait_reg_mem->ref = ref; + wait_reg_mem->mask = mask; + wait_reg_mem->poll_interval = 10u; + + WriteTrailingNop<2>(cmdbuf + 7); + return ORBIS_OK; + } + return -1; +} + +int PS4_SYSV_ABI sceGnmComputeWaitSemaphore() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmCreateWorkloadStream(u64 param1, u32* workload_stream) { + if (param1 != 0 && workload_stream) { + *workload_stream = 1; + return 0; + } + return 3; +} + +int PS4_SYSV_ABI sceGnmDebuggerGetAddressWatch() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerHaltWavefront() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerReadGds() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerReadSqIndirectRegister() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerResumeWavefront() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerResumeWavefrontCreation() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerSetAddressWatch() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerWriteGds() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebuggerWriteSqIndirectRegister() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebugHardwareStatus() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(OrbisKernelEqueue eq, u64 id) { + LOG_TRACE(Lib_GnmDriver, "called"); + + auto equeue = GetEqueue(eq); + if (!equeue) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + equeue->RemoveEvent(id, OrbisKernelEvent::Filter::GraphicsCore); + + Platform::IrqC::Instance()->Unregister(static_cast(id), equeue); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmDestroyWorkloadStream() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw) { + HLE_TRACE; + LOG_DEBUG(Lib_GnmDriver, "vqid {}, offset_dw {}", gnm_vqid, next_offs_dw); + + if (gnm_vqid == 0) { + return; + } + + std::scoped_lock lk{m_submit_lock}; + WaitGpuIdle(); + + if (DebugState.ShouldPauseInSubmit()) { + DebugState.PauseGuestThreads(); + } + + auto vqid = gnm_vqid - 1; + auto& asc_queue = liverpool->asc_queues[{vqid}]; + + auto& offs_dw = asc_next_offs_dw[vqid]; + + if (next_offs_dw == offs_dw) { + return; + } + + if (next_offs_dw < offs_dw && next_offs_dw != 0) { + // For cases if a submission is split at the end of the ring buffer, we need to submit it in + // two parts to handle the wrap + liverpool->SubmitAsc(gnm_vqid, {reinterpret_cast(asc_queue.map_addr) + offs_dw, + asc_queue.ring_size_dw - offs_dw}); + offs_dw = 0; + } + + const auto* acb_ptr = reinterpret_cast(asc_queue.map_addr) + offs_dw; + const auto acb_size_dw = (next_offs_dw ? next_offs_dw : asc_queue.ring_size_dw) - offs_dw; + const std::span acb_span{acb_ptr, acb_size_dw}; + + asc_next_offs_dw[vqid] = next_offs_dw; + + if (DebugState.DumpingCurrentFrame()) { + static auto last_frame_num = -1LL; + static u32 seq_num{}; + if (last_frame_num == frames_submitted) { + ++seq_num; + } else { + last_frame_num = frames_submitted; + seq_num = 0u; + } + + // Up to this point, all ACB submissions have been stored in a secondary command buffer. + // Dumping them using the current ring pointer would result in files containing only the + // `IndirectBuffer` command. To access the actual command stream, we need to unwrap the IB. + auto acb = acb_span; + auto base_addr = reinterpret_cast(acb_ptr); + const auto* indirect_buffer = + reinterpret_cast(acb_span.data()); + if (indirect_buffer->header.opcode == PM4ItOpcode::IndirectBuffer) { + base_addr = reinterpret_cast(indirect_buffer->Address()); + acb = {reinterpret_cast(base_addr), indirect_buffer->ib_size}; + } + + using namespace DebugStateType; + + DebugState.PushQueueDump({ + .type = QueueType::acb, + .submit_num = seq_num, + .num2 = gnm_vqid, + .data = {acb.begin(), acb.end()}, + .base_addr = base_addr, + }); + } + liverpool->SubmitAsc(gnm_vqid, acb_span); +} + +void PS4_SYSV_ABI sceGnmDingDongForWorkload(u32 gnm_vqid, u32 next_offs_dw, u64 workload_id) { + LOG_DEBUG(Lib_GnmDriver, "called, redirecting to sceGnmDingDong"); + sceGnmDingDong(gnm_vqid, next_offs_dw); +} + +int PS4_SYSV_ABI sceGnmDisableMipStatsReport() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmDispatchDirect(u32* cmdbuf, u32 size, u32 threads_x, u32 threads_y, + u32 threads_z, u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 9) && ((s32)(threads_x | threads_y | threads_z) > -1)) { + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader(cmdbuf, 4, PM4ShaderType::ShaderCompute, + predicate); + cmdbuf = WriteBody(cmdbuf, threads_x, threads_y, threads_z); + cmdbuf[0] = (flags & 0x18) + 1; // ordered append mode + + WriteTrailingNop<3>(cmdbuf + 1); + return ORBIS_OK; + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmDispatchIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 7)) { + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader(cmdbuf, 2, PM4ShaderType::ShaderCompute, + predicate); + cmdbuf[0] = data_offset; + cmdbuf[1] = (flags & 0x18) + 1; // ordered append mode + + WriteTrailingNop<3>(cmdbuf + 2); + return ORBIS_OK; + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmDispatchIndirectOnMec(u32* cmdbuf, u32 size, VAddr args, u32 modifier) { + if (cmdbuf != nullptr && size == 8 && args != 0 && ((args & 3u) == 0)) { + cmdbuf[0] = 0xc0021602 | (modifier & 1u); + *(VAddr*)(&cmdbuf[1]) = args; + cmdbuf[3] = (modifier & 0x18) | 1u; + cmdbuf[4] = 0xc0021000; + cmdbuf[5] = 0; + return ORBIS_OK; + } + return ORBIS_FAIL; +} + +u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (size < HwInitPacketSize) { + return 0; + } + + cmdbuf = PM4CmdSetData::SetShReg( + cmdbuf, 0x216u, + 0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE0 + cmdbuf = PM4CmdSetData::SetShReg( + cmdbuf, 0x217u, + 0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE1 + + if (sceKernelIsNeoMode()) { + cmdbuf = PM4CmdSetData::SetShReg( + cmdbuf, 0x219u, + 0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE2 + cmdbuf = PM4CmdSetData::SetShReg( + cmdbuf, 0x21au, + 0xffffffffu); // COMPUTE_STATIC_THREAD_MGMT_SE3 + } + + cmdbuf = PM4CmdSetData::SetShReg( + cmdbuf, 0x215u, 0x170u); // COMPUTE_RESOURCE_LIMITS + + cmdbuf = WriteHeader(cmdbuf, 6); + cmdbuf = WriteBody(cmdbuf, 0x28000000u, 0u, 0u, 0u, 0u, 0xau); + + cmdbuf = WriteHeader(cmdbuf, sceKernelIsNeoMode() ? 0xe9 : 0xef); + cmdbuf = WriteBody(cmdbuf, 0u); + return HwInitPacketSize; +} + +s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr_t index_addr, + u32 flags, u32 type) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 10) && (index_addr != 0) && (index_addr & 1) == 0 && + (flags & 0x1ffffffe) == 0) { // no predication will be set in the packet + auto* draw_index = reinterpret_cast(cmdbuf); + draw_index->header = + PM4Type3Header{PM4ItOpcode::DrawIndex2, 4, PM4ShaderType::ShaderGraphics}; + draw_index->max_size = index_count; + draw_index->index_base_lo = u32(index_addr); + draw_index->index_base_hi = u32(index_addr >> 32); + draw_index->index_count = index_count; + draw_index->draw_initiator = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0; + + WriteTrailingNop<3>(cmdbuf + 6); + return ORBIS_OK; + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 7) && + (flags & 0x1ffffffe) == 0) { // no predication will be set in the packet + cmdbuf = WritePacket( + cmdbuf, PM4ShaderType::ShaderGraphics, index_count, + sceKernelIsNeoMode() ? flags & 0xe0000000u | 2u : 2u); + WriteTrailingNop<3>(cmdbuf); + return ORBIS_OK; + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage, + u32 vertex_sgpr_offset, u32 instance_sgpr_offset, + u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) && + (vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u)) { + + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader( + cmdbuf, 4, PM4ShaderType::ShaderGraphics, predicate); + + const auto sgpr_offset = indirect_sgpr_offsets[shader_stage]; + + cmdbuf[0] = data_offset; + cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[3] = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0u; + + cmdbuf += 4; + WriteTrailingNop<3>(cmdbuf); + return ORBIS_OK; + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 data_offset, + u32 max_count, u64 count_addr, u32 shader_stage, + u32 vertex_sgpr_offset, u32 instance_sgpr_offset, + u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if ((!sceKernelIsNeoMode() || !UseNeoCompatSequences) && cmdbuf && (size == 16) && + (vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u) && + (shader_stage == ShaderStages::Vs || shader_stage == ShaderStages::Es || + shader_stage == ShaderStages::Ls)) { + + cmdbuf = WriteHeader(cmdbuf, 2); + cmdbuf = WriteBody(cmdbuf, 0u); + cmdbuf += 1; + + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader( + cmdbuf, 9, PM4ShaderType::ShaderGraphics, predicate); + + const auto sgpr_offset = indirect_sgpr_offsets[shader_stage]; + + cmdbuf[0] = data_offset; + cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[3] = (count_addr != 0 ? 1u : 0u) << 0x1e; + cmdbuf[4] = max_count; + *(u64*)(&cmdbuf[5]) = count_addr; + cmdbuf[7] = sizeof(DrawIndexedIndirectArgs); + cmdbuf[8] = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0; + + cmdbuf += 9; + WriteTrailingNop<2>(cmdbuf); + return ORBIS_OK; + } + return -1; +} + +int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count, + u32 shader_stage, u32 vertex_sgpr_offset, + u32 instance_sgpr_offset, u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 11) && (vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u) && + (shader_stage == ShaderStages::Vs || shader_stage == ShaderStages::Es || + shader_stage == ShaderStages::Ls)) { + + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader( + cmdbuf, 6, PM4ShaderType::ShaderGraphics, predicate); + + const auto sgpr_offset = indirect_sgpr_offsets[shader_stage]; + + cmdbuf[0] = data_offset; + cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[3] = max_count; + cmdbuf[4] = sizeof(DrawIndexedIndirectArgs); + cmdbuf[5] = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0; + + cmdbuf += 6; + WriteTrailingNop<3>(cmdbuf); + return ORBIS_OK; + } + return -1; +} + +int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + UNREACHABLE(); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset, u32 index_count, + u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 9)) { + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader( + cmdbuf, 4, PM4ShaderType::ShaderGraphics, predicate); + cmdbuf = WriteBody(cmdbuf, index_count, index_offset, index_count, + sceKernelIsNeoMode() ? flags & 0xe0000000u : 0u); + + WriteTrailingNop<3>(cmdbuf); + return ORBIS_OK; + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage, + u32 vertex_sgpr_offset, u32 instance_sgpr_offset, u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) && + (vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u)) { + + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader(cmdbuf, 4, PM4ShaderType::ShaderGraphics, + predicate); + + const auto sgpr_offset = indirect_sgpr_offsets[shader_stage]; + + cmdbuf[0] = data_offset; + cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[3] = sceKernelIsNeoMode() ? flags & 0xe0000000u | 2u : 2u; // auto index + + cmdbuf += 4; + WriteTrailingNop<3>(cmdbuf); + return ORBIS_OK; + } + return -1; +} + +int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + UNREACHABLE(); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmDrawIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count, + u32 shader_stage, u32 vertex_sgpr_offset, + u32 instance_sgpr_offset, u32 flags) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && size == 11 && shader_stage < ShaderStages::Max && vertex_sgpr_offset < 0x10 && + instance_sgpr_offset < 0x10) { + const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable; + cmdbuf = WriteHeader( + cmdbuf, 4, PM4ShaderType::ShaderGraphics, predicate); + + const auto sgpr_offset = indirect_sgpr_offsets[shader_stage]; + cmdbuf[0] = data_offset; + cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset; + cmdbuf[3] = max_count; + cmdbuf[4] = sizeof(DrawIndirectArgs); + cmdbuf[5] = sceKernelIsNeoMode() ? flags & 0xe0000000u | 2u : 2u; // auto index + + cmdbuf += 6; + WriteTrailingNop<3>(cmdbuf); + return ORBIS_OK; + } + return -1; +} + +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (size < HwInitPacketSize) { + return 0; + } + + const auto& SetupContext = [](u32* cmdbuf, u32 size, bool clear_state) { + const auto* cmdbuf_end = cmdbuf + HwInitPacketSize; + if (clear_state) { + cmdbuf = ClearContextState(cmdbuf); + } + + std::memcpy(cmdbuf, &InitSequence[2], (InitSequence.size() - 2) * 4); + cmdbuf += InitSequence.size() - 2; + + const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1; + WriteTrailingNop(cmdbuf, cmdbuf_left); + + return HwInitPacketSize; + }; + + return SetupContext(cmdbuf, size, true); +} + +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (size < HwInitPacketSize) { + return 0; + } + + const auto* cmdbuf_end = cmdbuf + HwInitPacketSize; + cmdbuf = ClearContextState(cmdbuf); + std::memcpy(cmdbuf, &InitSequence175[2], (InitSequence175.size() - 2) * 4); + cmdbuf += InitSequence175.size() - 2; + + const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1; + WriteTrailingNop(cmdbuf, cmdbuf_left); + + return HwInitPacketSize; +} + +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (size < HwInitPacketSize) { + return 0; + } + + const auto& SetupContext200 = [](u32* cmdbuf, u32 size, bool clear_state) { + const auto* cmdbuf_end = cmdbuf + HwInitPacketSize; + if (clear_state) { + cmdbuf = ClearContextState(cmdbuf); + } + + if (sceKernelIsNeoMode()) { + if (!UseNeoCompatSequences) { + std::memcpy(cmdbuf, &InitSequence200Neo[2], (InitSequence200Neo.size() - 2) * 4); + cmdbuf += InitSequence200Neo.size() - 2; + } else { + std::memcpy(cmdbuf, &InitSequence200NeoCompat[2], + (InitSequence200NeoCompat.size() - 2) * 4); + cmdbuf += InitSequence200NeoCompat.size() - 2; + } + } else { + std::memcpy(cmdbuf, &InitSequence200[2], (InitSequence200.size() - 2) * 4); + cmdbuf += InitSequence200.size() - 2; + } + + const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1; + WriteTrailingNop(cmdbuf, cmdbuf_left); + + return HwInitPacketSize; + }; + + return SetupContext200(cmdbuf, size, true); +} + +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (size < HwInitPacketSize) { + return 0; + } + + const auto& SetupContext350 = [](u32* cmdbuf, u32 size, bool clear_state) { + const auto* cmdbuf_end = cmdbuf + HwInitPacketSize; + if (clear_state) { + cmdbuf = ClearContextState(cmdbuf); + } + + if (sceKernelIsNeoMode()) { + if (!UseNeoCompatSequences) { + std::memcpy(cmdbuf, &InitSequence350Neo[2], (InitSequence350Neo.size() - 2) * 4); + cmdbuf += InitSequence350Neo.size() - 2; + } else { + std::memcpy(cmdbuf, &InitSequence350NeoCompat[2], + (InitSequence350NeoCompat.size() - 2) * 4); + cmdbuf += InitSequence350NeoCompat.size() - 2; + } + } else { + std::memcpy(cmdbuf, &InitSequence350[2], (InitSequence350.size() - 2) * 4); + cmdbuf += InitSequence350.size() - 2; + } + + const auto cmdbuf_left = cmdbuf_end - cmdbuf - 1; + WriteTrailingNop(cmdbuf, cmdbuf_left); + + return HwInitPacketSize; + }; + + return SetupContext350(cmdbuf, size, true); +} + +u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + constexpr auto CtxInitPacketSize = 0x20u; + if (size != CtxInitPacketSize) { + return 0; + } + + if (sceKernelIsNeoMode()) { + std::memcpy(cmdbuf, CtxInitSequenceNeo.data(), CtxInitSequenceNeo.size() * 4); + } else { + std::memcpy(cmdbuf, CtxInitSequence.data(), CtxInitSequence.size() * 4); + } + return CtxInitPacketSize; +} + +u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + constexpr auto CtxInitPacketSize = 0x100u; + if (size != CtxInitPacketSize) { + return 0; + } + + if (sceKernelIsNeoMode()) { + if (!UseNeoCompatSequences) { + std::memcpy(cmdbuf, CtxInitSequence400Neo.data(), CtxInitSequence400Neo.size() * 4); + } else { + std::memcpy(cmdbuf, CtxInitSequence400NeoCompat.data(), + CtxInitSequence400NeoCompat.size() * 4); + } + } else { + std::memcpy(cmdbuf, CtxInitSequence400.data(), CtxInitSequence400.size() * 4); + } + return CtxInitPacketSize; +} + +int PS4_SYSV_ABI sceGnmDrawOpaqueAuto() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +bool PS4_SYSV_ABI sceGnmDriverCaptureInProgress() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return false; +} + +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterface() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0x80000000; +} + +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForGpuDebugger() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0x80000000; +} + +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForGpuException() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0x80000000; +} + +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForHDRScopes() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0x80000000; +} + +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForReplay() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0x80000000; +} + +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForResourceRegistration() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0x80000000; +} + +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForValidation() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0x80000000; +} + +int PS4_SYSV_ABI sceGnmDriverInternalVirtualQuery() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +bool PS4_SYSV_ABI sceGnmDriverTraceInProgress() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return false; +} + +int PS4_SYSV_ABI sceGnmDriverTriggerCapture() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_CAPTURE_RAZOR_NOT_LOADED; +} + +int PS4_SYSV_ABI sceGnmEndWorkload(u64 workload) { + if (workload != 0) { + return (0xf < ((workload >> 0x38) & 0xff)) * 2; + } + return 2; +} + +s32 PS4_SYSV_ABI sceGnmFindResourcesPublic() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +void PS4_SYSV_ABI sceGnmFlushGarlic() { + LOG_TRACE(Lib_GnmDriver, "(STUBBED) called"); +} + +int PS4_SYSV_ABI sceGnmGetCoredumpAddress() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetCoredumpMode() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetCoredumpProtectionFaultTimestamp() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetDbgGcHandle() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return -1; +} + +int PS4_SYSV_ABI sceGnmGetDebugTimestamp() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetEqEventType(const OrbisKernelEvent* ev) { + LOG_TRACE(Lib_GnmDriver, "called"); + return sceKernelGetEventData(ev); +} + +int PS4_SYSV_ABI sceGnmGetEqTimeStamp() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetGpuBlockStatus() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +u32 PS4_SYSV_ABI sceGnmGetGpuCoreClockFrequency() { + LOG_TRACE(Lib_GnmDriver, "called"); + // On console this uses an ioctl check, but we assume it is equal to just checking for neo mode. + return sceKernelIsNeoMode() ? 911'000'000 : 800'000'000; +} + +int PS4_SYSV_ABI sceGnmGetGpuInfoStatus() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetLastWaitedAddress() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetNumTcaUnits() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetOffChipTessellationBufferSize() { + LOG_TRACE(Lib_GnmDriver, "called"); + return tessellation_offchip_buffer_size; +} + +int PS4_SYSV_ABI sceGnmGetOwnerName() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmGetPhysicalCounterFromVirtualized() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +u32 PS4_SYSV_ABI sceGnmGetProtectionFaultTimeStamp() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0; +} + +int PS4_SYSV_ABI sceGnmGetResourceBaseAddressAndSizeInBytes() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmGetResourceName() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmGetResourceShaderGuid() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmGetResourceType() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmGetResourceUserData() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmGetShaderProgramBaseAddress() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmGetShaderStatus() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +VAddr PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress() { + LOG_TRACE(Lib_GnmDriver, "called"); + if (tessellation_factors_ring_addr == -1) { + auto* memory = Core::Memory::Instance(); + auto& address_space = memory->GetAddressSpace(); + tessellation_factors_ring_addr = address_space.SystemReservedVirtualBase() + + address_space.SystemReservedVirtualSize() - 0x10000000; + } + + return tessellation_factors_ring_addr; +} + +void PS4_SYSV_ABI sceGnmGpuPaDebugEnter() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware +} + +void PS4_SYSV_ABI sceGnmGpuPaDebugLeave() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware +} + +s32 PS4_SYSV_ABI sceGnmInsertDingDongMarker(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf == nullptr || size != 4) { + return -1; + } + WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0u, 0u, 0u); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && (size == 6)) { + cmdbuf = + WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, + PM4CmdNop::PayloadType::DebugMarkerPop, 0u, 0u, 0u, 0u); + return ORBIS_OK; + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmInsertPushColorMarker(u32* cmdbuf, u32 size, const char* marker, u32 color) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && marker) { + const auto len = std::strlen(marker); + const u32 packet_size = ((len + 0xc) >> 2) + ((len + 0x10) >> 3) * 2; + if (packet_size + 2 == size) { + auto* nop = reinterpret_cast(cmdbuf); + nop->header = + PM4Type3Header{PM4ItOpcode::Nop, packet_size, PM4ShaderType::ShaderGraphics}; + nop->data_block[0] = PM4CmdNop::PayloadType::DebugColorMarkerPush; + const auto marker_len = len + 1; + std::memcpy(&nop->data_block[1], marker, marker_len); + *reinterpret_cast(reinterpret_cast(&nop->data_block[1]) + marker_len + 8) = + color; + std::memset(reinterpret_cast(&nop->data_block[1]) + marker_len + 8 + sizeof(u32), + 0, packet_size * 4 - marker_len - 8 - sizeof(u32)); + return ORBIS_OK; + } + } + return -1; +} + +s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && marker) { + const auto len = std::strlen(marker); + const u32 packet_size = ((len + 8) >> 2) + ((len + 0xc) >> 3) * 2; + if (packet_size + 2 == size) { + auto* nop = reinterpret_cast(cmdbuf); + nop->header = + PM4Type3Header{PM4ItOpcode::Nop, packet_size, PM4ShaderType::ShaderGraphics}; + nop->data_block[0] = PM4CmdNop::PayloadType::DebugMarkerPush; + const auto marker_len = len + 1; + std::memcpy(&nop->data_block[1], marker, marker_len); + std::memset(reinterpret_cast(&nop->data_block[1]) + marker_len, 0, + packet_size * 4 - marker_len); + return ORBIS_OK; + } + } + return -1; +} + +int PS4_SYSV_ABI sceGnmInsertSetColorMarker() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmInsertSetMarker(u32* cmdbuf, u32 size, const char* marker) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (cmdbuf && marker) { + const auto len = std::strlen(marker); + const u32 packet_size = ((len + 8) >> 2) + ((len + 0xc) >> 3) * 2; + if (packet_size + 2 == size) { + auto* nop = reinterpret_cast(cmdbuf); + nop->header = + PM4Type3Header{PM4ItOpcode::Nop, packet_size, PM4ShaderType::ShaderGraphics}; + nop->data_block[0] = PM4CmdNop::PayloadType::DebugSetMarker; + const auto marker_len = len + 1; + std::memcpy(&nop->data_block[1], marker, marker_len); + std::memset(reinterpret_cast(&nop->data_block[1]) + marker_len, 0, + packet_size * 4 - marker_len); + return ORBIS_OK; + } + } + return -1; +} + +int PS4_SYSV_ABI sceGnmInsertThreadTraceMarker() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmInsertWaitFlipDone(u32* cmdbuf, u32 size, s32 vo_handle, u32 buf_idx) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (size != 7) { + return -1; + } + + uintptr_t label_addr{}; + ASSERT_MSG(VideoOut::sceVideoOutGetBufferLabelAddress(vo_handle, &label_addr) == 16, + "sceVideoOutGetBufferLabelAddress call failed"); + + auto* wait_reg_mem = reinterpret_cast(cmdbuf); + wait_reg_mem->header = PM4Type3Header{PM4ItOpcode::WaitRegMem, 5}; + wait_reg_mem->raw = 0x13u; + *reinterpret_cast(&wait_reg_mem->poll_addr_lo) = + (label_addr + buf_idx * sizeof(uintptr_t)) & ~0x3ull; + wait_reg_mem->ref = 0u; + wait_reg_mem->mask = 0xffff'ffffu; + wait_reg_mem->poll_interval = 10u; + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmIsCoredumpValid() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +bool PS4_SYSV_ABI sceGnmIsUserPaEnabled() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return false; +} + +int PS4_SYSV_ABI sceGnmLogicalCuIndexToPhysicalCuIndex() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmLogicalCuMaskToPhysicalCuMask(s64, s32 logical_cu_mask) { + LOG_INFO(Lib_GnmDriver, "called, logical_cu_mask: {}", logical_cu_mask); + return logical_cu_mask; +} + +int PS4_SYSV_ABI sceGnmLogicalTcaUnitToPhysical() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmMapComputeQueue(u32 pipe_id, u32 queue_id, VAddr ring_base_addr, + u32 ring_size_dw, u32* read_ptr_addr) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (pipe_id >= Liverpool::NumComputePipes) { + return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_ID; + } + + if (queue_id >= Liverpool::NumQueuesPerPipe) { + return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_QUEUE_ID; + } + + if (VAddr(ring_base_addr) % 256 != 0) { // alignment check + return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_BASE_ADDR; + } + + if (!std::has_single_bit(ring_size_dw)) { + return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_SIZE; + } + + if (VAddr(read_ptr_addr) % 4 != 0) { // alignment check + return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_READ_PTR_ADDR; + } + + const auto vqid = + liverpool->asc_queues.insert(VAddr(ring_base_addr), read_ptr_addr, ring_size_dw, pipe_id); + // We need to offset index as `dingDong` assumes it to be from the range [1..64] + const auto gnm_vqid = vqid.index + 1; + LOG_INFO(Lib_GnmDriver, "ASC pipe {} queue {} mapped to vqueue {}", pipe_id, queue_id, + gnm_vqid); + + const auto& queue = liverpool->asc_queues[vqid]; + *queue.read_addr = 0u; + + return gnm_vqid; +} + +int PS4_SYSV_ABI sceGnmMapComputeQueueWithPriority(u32 pipe_id, u32 queue_id, VAddr ring_base_addr, + u32 ring_size_dw, u32* read_ptr_addr, + u32 pipePriority) { + LOG_TRACE(Lib_GnmDriver, "called"); + + (void)pipePriority; + return sceGnmMapComputeQueue(pipe_id, queue_id, ring_base_addr, ring_size_dw, read_ptr_addr); +} + +int PS4_SYSV_ABI sceGnmPaDisableFlipCallbacks() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmPaEnableFlipCallbacks() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmPaHeartbeat() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmQueryResourceRegistrationUserMemoryRequirements() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmRaiseUserExceptionEvent() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmRegisterGdsResource() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +void PS4_SYSV_ABI sceGnmRegisterGnmLiveCallbackConfig() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware +} + +s32 PS4_SYSV_ABI sceGnmRegisterOwner(void* handle, const char* name) { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +s32 PS4_SYSV_ABI sceGnmRegisterResource(void* res_handle, void* owner_handle, const void* addr, + size_t size, const char* name, int res_type, + u64 user_data) { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmRequestFlipAndSubmitDone() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmRequestFlipAndSubmitDoneForWorkload() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmRequestMipStatsReportAndReset() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmResetVgtControl(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + if (cmdbuf == nullptr || size != 3) { + return -1; + } + if (sceKernelIsNeoMode()) { + if (!UseNeoCompatSequences) { + PM4CmdSetData::SetUconfigReg(cmdbuf, 0x40000258u, 0x6d007fu); // IA_MULTI_VGT_PARAM + } else { + PM4CmdSetData::SetContextReg(cmdbuf, 0x100002aau, 0xd00ffu); // IA_MULTI_VGT_PARAM + } + } else { + PM4CmdSetData::SetContextReg(cmdbuf, 0x2aau, 0xffu); // IA_MULTI_VGT_PARAM + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmSdmaClose() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSdmaConstFill() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSdmaCopyLinear() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSdmaCopyTiled() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSdmaCopyWindow() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSdmaFlush() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSdmaGetMinCmdSize() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSdmaOpen() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +s32 PS4_SYSV_ABI sceGnmSetCsShader(u32* cmdbuf, u32 size, const u32* cs_regs) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x18) { + return -1; + } + if (!cs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer in shader registers."); + return -1; + } + if (cs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address."); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x20cu, cs_regs[0], + 0u); // COMPUTE_PGM_LO/COMPUTE_PGM_HI + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x212u, cs_regs[2], + cs_regs[3]); // COMPUTE_PGM_RSRC1/COMPUTE_PGM_RSRC2 + cmdbuf = PM4CmdSetData::SetShReg( + cmdbuf, 0x207u, cs_regs[4], cs_regs[5], + cs_regs[6]); // COMPUTE_NUM_THREAD_X/COMPUTE_NUM_THREAD_Y/COMPUTE_NUM_THREAD_Z + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetCsShaderWithModifier(u32* cmdbuf, u32 size, const u32* cs_regs, + u32 modifier) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x18) { + return -1; + } + if (!cs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer in shader registers."); + return -1; + } + if ((modifier & 0xfffffc3fu) != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid modifier mask."); + return -1; + } + if (cs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address."); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x20cu, cs_regs[0], + 0u); // COMPUTE_PGM_LO/COMPUTE_PGM_HI + const u32 rsrc1 = modifier == 0 ? cs_regs[2] : (cs_regs[2] & 0xfffffc3fu) | modifier; + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x212u, rsrc1, + cs_regs[3]); // COMPUTE_PGM_RSRC1/COMPUTE_PGM_RSRC2 + cmdbuf = PM4CmdSetData::SetShReg( + cmdbuf, 0x207u, cs_regs[4], cs_regs[5], + cs_regs[6]); // COMPUTE_NUM_THREAD_X/COMPUTE_NUM_THREAD_Y/COMPUTE_NUM_THREAD_Z + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetEmbeddedPsShader(u32* cmdbuf, u32 size, u32 shader_id, + u32 shader_modifier) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (shader_id > 1) { + LOG_ERROR(Lib_GnmDriver, "Unknown shader id {}", shader_id); + return ORBIS_GNM_ERROR_FAILURE; + } + + // clang-format off + constexpr static std::array ps0_code alignas(256) = { + 0xbeeb03ffu, 0x00000003u, // s_mov_b32 vcc_hi, $0x00000003 + 0x7e000280u, // v_mov_b32 v0, 0 + 0x5e000100u, // v_cvt_pkrtz_f16_f32 v0, v0, v0 + 0xbf800000u, // s_nop + 0xf8001c0fu, 0x00000000u, // exp mrt0, v0, v0 compr vm done + 0xbf810000u, // s_endpgm + + // Binary header + 0x5362724fu, 0x07726468u, 0x00002043u, 0u, 0xb0a45b2bu, 0x1d39766du, 0x72044b7bu, 0x0000000fu, + // PS regs + 0x0fe000f0u, 0u, 0xc0000u, 4u, 0u, 4u, 2u, 2u, 0u, 0u, 0x10u, 0xfu, 0xcu, 0u, 0u, 0u, + }; + + const auto shader0_addr = uintptr_t(ps0_code.data()); // Original address is 0xfe000f00 + const static u32 ps0_regs[] = { + u32(shader0_addr >> 8), u32(shader0_addr >> 40), 0xc0000u, 4u, 0u, 4u, 2u, 2u, 0u, 0u, 0x10u, 0xfu, 0xcu}; + + constexpr static std::array ps1_code alignas(256) = { + 0xbeeb03ffu, 0x00000003u, // s_mov_b32 vcc_hi, $0x00000003 + 0x7e040280u, // v_mov_b32 v2, 0 + 0xf8001803u, 0x02020202u, // exp mrt0, v2, v2, off, off vm done + 0xbf810000u, // s_endpgm + + // Binary header + 0x5362724fu, 0x07726468u, 0x00001841u, 0x04080002u, 0x98b9cb94u, 0u, 0x6f130734u, 0x0000000fu, + // PS regs + 0x0fe000f2u, 0u, 0x2000u, 0u, 0u, 2u, 2u, 2u, 0u, 0u, 0x10u, 3u, 0xcu, + }; + + const auto shader1_addr = uintptr_t(ps1_code.data()); // Original address is 0xfe000f20 + const static u32 ps1_regs[] = { + u32(shader1_addr >> 8), u32(shader1_addr >> 40), 0x2000u, 0u, 0u, 2u, 2u, 2u, 0u, 0u, 0x10u, 3u, 0xcu}; + // clang-format on + + const auto ps_regs = shader_id == 0 ? ps0_regs : ps1_regs; + + // Normally the driver will do a call to `sceGnmSetPsShader350()`, but this function has + // a check for zero in the upper part of shader address. In our case, the address is a + // pointer to a stack memory, so the check will likely fail. To workaround it we will + // repeat set shader functionality here as it is trivial. + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0], + ps_regs[1]); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2], + ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c4u, ps_regs[4], + ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6], + ps_regs[7]); // SPI_PS_INPUT_ENA/SPI_PS_INPUT_ADDR + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b6u, ps_regs[8]); // SPI_PS_IN_CONTROL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b8u, ps_regs[9]); // SPI_BARYC_CNTL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x203u, ps_regs[10]); // DB_SHADER_CONTROL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x8fu, ps_regs[11]); // CB_SHADER_MASK + + WriteTrailingNop<11>(cmdbuf); + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetEmbeddedVsShader(u32* cmdbuf, u32 size, u32 shader_id, + u32 shader_modifier) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (shader_id != 0) { + LOG_ERROR(Lib_GnmDriver, "Unknown shader id {}", shader_id); + return ORBIS_GNM_ERROR_FAILURE; + } + + // A fullscreen triangle with one uv set + // clang-format off + constexpr static std::array shader_code alignas(256) = { + 0xbeeb03ffu, 0x00000007u, // s_mov_b32 vcc_hi, $0x00000007 + 0x36020081u, // v_and_b32 v1, 1, v0 + 0x34020281u, // v_lshlrev_b32 v1, 1, v1 + 0x360000c2u, // v_and_b32 v0, -2, v0 + 0x4a0202c1u, // v_add_i32 v1, vcc, -1, v1 + 0x4a0000c1u, // v_add_i32 v0, vcc, -1, v0 + 0x7e020b01u, // v_cvt_f32_i32 v1, v1 + 0x7e000b00U, // v_cvt_f32_i32 v0, v0 + 0x7e040280u, // v_mov_b32 v2, 0 + 0x7e0602f2u, // v_mov_b32 v3, 1.0 + 0xf80008cfu, 0x03020001u, // exp pos0, v1, v0, v2, v3 done + 0xf800020fu, 0x03030303u, // exp param0, v3, v3, v3, v3 + 0xbf810000u, // s_endpgm + + // Binary header + 0x5362724fu, 0x07726468u, 0x00004047u, 0u, 0x47f8c29fu, 0x9b2da5cfu, 0xff7c5b7du, 0x00000017u, + // VS regs + 0x0fe000f1u, 0u, 0x000c0000u, 4u, 0u, 4u, 0u, 7u, + }; + // clang-format on + + const auto shader_addr = uintptr_t(shader_code.data()); // Original address is 0xfe000f10 + const static u32 vs_regs[] = { + u32(shader_addr >> 8), u32(shader_addr >> 40), 0xc0000u, 4, 0, 4, 0, 7}; + + // Normally the driver will do a call to `sceGnmSetVsShader()`, but this function has + // a check for zero in the upper part of shader address. In our case, the address is a + // pointer to a stack memory, so the check will likely fail. To workaround it we will + // repeat set shader functionality here as it is trivial. + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], vs_regs[1]); // SPI_SHADER_PGM_LO_VS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, vs_regs[2], + vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS/SPI_SHADER_PGM_RSRC2_VS + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b1u, vs_regs[4]); // SPI_VS_OUT_CONFIG + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c3u, vs_regs[5]); // SPI_SHADER_POS_FORMAT + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetEsShader(u32* cmdbuf, u32 size, const u32* es_regs, u32 shader_modifier) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size < 0x14) { + return -1; + } + + if (!es_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + if (shader_modifier & 0xfcfffc3f) { + LOG_ERROR(Lib_GnmDriver, "Invalid modifier mask"); + return -1; + } + + if (es_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + const u32 var = + shader_modifier == 0 ? es_regs[2] : ((es_regs[2] & 0xfcfffc3f) | shader_modifier); + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0xc8u, es_regs[0], 0u); // SPI_SHADER_PGM_LO_ES + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0xcau, var, es_regs[3]); // SPI_SHADER_PGM_RSRC1_ES + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmSetGsRingSizes() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetGsShader(u32* cmdbuf, u32 size, const u32* gs_regs) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size < 0x1d) { + return -1; + } + + if (!gs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + if (gs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x88u, gs_regs[0], 0u); // SPI_SHADER_PGM_LO_GS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x8au, gs_regs[2], + gs_regs[3]); // SPI_SHADER_PGM_RSRC1_GS/SPI_SHADER_PGM_RSRC2_GS + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2e5u, gs_regs[4]); // VGT_STRMOUT_CONFIG + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x29bu, gs_regs[5]); // VGT_GS_OUT_PRIM_TYPE + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2e4u, gs_regs[6]); // VGT_GS_INSTANCE_CNT + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetHsShader(u32* cmdbuf, u32 size, const u32* hs_regs, u32 param4) { + LOG_TRACE(Lib_GnmDriver, "called"); + if (!cmdbuf || size < 0x1E) { + return -1; + } + + if (!hs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + if (hs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x108u, hs_regs[0], 0u); // SPI_SHADER_PGM_LO_HS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x10au, hs_regs[2], + hs_regs[3]); // SPI_SHADER_PGM_RSRC1_HS/SPI_SHADER_PGM_RSRC2_HS + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x286u, + hs_regs[5], // VGT_HOS_MAX_TESS_LEVEL + hs_regs[6]); // VGT_HOS_MIN_TESS_LEVEL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2dbu, hs_regs[4]); // VGT_TF_PARAM + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2d6u, param4); // VGT_LS_HS_CONFIG + + // right padding? + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetLsShader(u32* cmdbuf, u32 size, const u32* ls_regs, u32 shader_modifier) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size < 0x17) { + return -1; + } + + if (!ls_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + const auto modifier_mask = ((shader_modifier & 0xfffffc3f) == 0) ? 0xfffffc3f : 0xfcfffc3f; + if (shader_modifier & modifier_mask) { + LOG_ERROR(Lib_GnmDriver, "Invalid modifier mask"); + return -1; + } + + if (ls_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + const u32 var = + shader_modifier == 0 ? ls_regs[2] : ((ls_regs[2] & modifier_mask) | shader_modifier); + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x148u, ls_regs[0], 0u); // SPI_SHADER_PGM_LO_LS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x14bu, ls_regs[3]); // SPI_SHADER_PGM_RSRC2_LS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x14au, var, ls_regs[3]); // SPI_SHADER_PGM_RSRC1_LS + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetPsShader(u32* cmdbuf, u32 size, const u32* ps_regs) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x27) { + return -1; + } + if (!ps_regs) { + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, 0u, + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x203u, 0u); // DB_SHADER_CONTROL + + WriteTrailingNop<0x20>(cmdbuf); + } else { + if (ps_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address."); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0], + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = + PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2], + ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS + cmdbuf = PM4CmdSetData::SetContextReg( + cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6], + ps_regs[7]); // SPI_PS_INPUT_ENA/SPI_PS_INPUT_ADDR + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b6u, ps_regs[8]); // SPI_PS_IN_CONTROL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b8u, ps_regs[9]); // SPI_BARYC_CNTL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x203u, ps_regs[10]); // DB_SHADER_CONTROL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x8fu, ps_regs[11]); // CB_SHADER_MASK + + WriteTrailingNop<11>(cmdbuf); + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetPsShader350(u32* cmdbuf, u32 size, const u32* ps_regs) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x27) { + return -1; + } + if (!ps_regs) { + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, 0u, + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x203u, 0u); // DB_SHADER_CONTROL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x8fu, 0xfu); // CB_SHADER_MASK + + WriteTrailingNop<0x1d>(cmdbuf); + } else { + if (ps_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address."); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0], + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = + PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2], + ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS + cmdbuf = PM4CmdSetData::SetContextReg( + cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6], + ps_regs[7]); // SPI_PS_INPUT_ENA/SPI_PS_INPUT_ADDR + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b6u, ps_regs[8]); // SPI_PS_IN_CONTROL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b8u, ps_regs[9]); // SPI_BARYC_CNTL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x203u, ps_regs[10]); // DB_SHADER_CONTROL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x8fu, ps_regs[11]); // CB_SHADER_MASK + + WriteTrailingNop<11>(cmdbuf); + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmSetResourceRegistrationUserMemory() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSetResourceUserData() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSetSpiEnableSqCounters() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSetSpiEnableSqCountersForUnitInstance() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSetupMipStatsReport() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetVgtControl(u32* cmdbuf, u32 size, u32 prim_group_sz_minus_one, + u32 partial_vs_wave_mode, u32 wd_switch_only_on_eop_mode) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size != 3 || (prim_group_sz_minus_one >= 0x100) || + ((wd_switch_only_on_eop_mode | partial_vs_wave_mode) >= 2)) { + return -1; + } + + if (sceKernelIsNeoMode()) { + const u32 wd_switch_on_eop = u32(wd_switch_only_on_eop_mode != 0) << 0x14; + const u32 switch_on_eoi = u32(wd_switch_only_on_eop_mode == 0) << 0x13; + const u32 reg_value = + wd_switch_only_on_eop_mode != 0 + ? (partial_vs_wave_mode & 1) << 0x10 | prim_group_sz_minus_one | wd_switch_on_eop | + switch_on_eoi | 0x40000u + : prim_group_sz_minus_one & 0x1cffffu | wd_switch_on_eop | switch_on_eoi | 0x50000u; + if (!UseNeoCompatSequences) { + PM4CmdSetData::SetUconfigReg(cmdbuf, 0x40000258u, + reg_value | 0x600000u); // IA_MULTI_VGT_PARAM + } else { + PM4CmdSetData::SetContextReg(cmdbuf, 0x100002aau, reg_value); // IA_MULTI_VGT_PARAM + } + } else { + const u32 reg_value = + ((partial_vs_wave_mode & 1) << 0x10) | (prim_group_sz_minus_one & 0xffffu); + PM4CmdSetData::SetContextReg(cmdbuf, 0x2aau, reg_value); // IA_MULTI_VGT_PARAM + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSetVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, u32 shader_modifier) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x1c) { + return -1; + } + + if (!vs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + if (shader_modifier & 0xfcfffc3f) { + LOG_ERROR(Lib_GnmDriver, "Invalid modifier mask"); + return -1; + } + + if (vs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + const u32 var = shader_modifier == 0 ? vs_regs[2] : (vs_regs[2] & 0xfcfffc3f) | shader_modifier; + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], 0u); // SPI_SHADER_PGM_LO_VS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b1u, vs_regs[4]); // SPI_VS_OUT_CONFIG + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c3u, vs_regs[5]); // SPI_SHADER_POS_FORMAT + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmSetWaveLimitMultiplier() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmSetWaveLimitMultipliers() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmSpmEndSpm() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmInit() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmInit2() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmSetDelay() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmSetMuxRam() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmSetMuxRam2() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmSetSelectCounter() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmSetSpmSelects() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmSetSpmSelects2() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSpmStartSpm() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttFini() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttFinishTrace() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetBcInfo() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetGpuClocks() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetHiWater() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetStatus() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetTraceCounter() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetTraceWptr() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetWrapCounts() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetWrapCounts2() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttGetWritebackLabels() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttInit() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSelectMode() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSelectTarget() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSelectTokens() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSetCuPerfMask() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSetDceEventWrite() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSetHiWater() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSetTraceBuffer2() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSetTraceBuffers() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSetUserData() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSetUserdataTimer() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttStartTrace() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttStopTrace() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSwitchTraceBuffer() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttSwitchTraceBuffer2() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmSqttWaitForEvent() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +static inline s32 PatchFlipRequest(u32* cmdbuf, u32 size, u32 vo_handle, u32 buf_idx, u32 flip_mode, + s64 flip_arg, void* unk) { + // check for `prepareFlip` packet + cmdbuf += size - 64; + ASSERT_MSG(cmdbuf[0] == 0xc03e1000, "Can't find `prepareFlip` packet"); + + std::array backup{}; + std::memcpy(backup.data(), cmdbuf, backup.size() * sizeof(decltype(backup)::value_type)); + + ASSERT_MSG(((backup[2] & 3) == 0u) || (backup[1] != PM4CmdNop::PayloadType::PrepareFlipLabel), + "Invalid flip packet"); + ASSERT_MSG(buf_idx != 0xffff'ffffu, "Invalid VO buffer index"); + + const s32 flip_result = VideoOut::sceVideoOutSubmitEopFlip(vo_handle, buf_idx, flip_mode, + flip_arg, nullptr /*unk*/); + if (flip_result != 0) { + if (flip_result == 0x80290012) { + LOG_ERROR(Lib_GnmDriver, "Flip queue is full"); + return 0x80d11081; + } else { + LOG_ERROR(Lib_GnmDriver, "Flip request failed"); + return flip_result; + } + } + + uintptr_t label_addr{}; + ASSERT_MSG(VideoOut::sceVideoOutGetBufferLabelAddress(vo_handle, &label_addr) == 16, + "sceVideoOutGetBufferLabelAddress call failed"); + + // Write event to lock the VO surface + auto* write_lock = reinterpret_cast(cmdbuf); + write_lock->header = PM4Type3Header{PM4ItOpcode::WriteData, 3}; + write_lock->raw = 0x500u; + const auto addr = (label_addr + buf_idx * sizeof(label_addr)) & ~0x3ull; + write_lock->Address(addr); + write_lock->data[0] = 1; + + auto* nop = reinterpret_cast(cmdbuf + 5); + + if (backup[1] == PM4CmdNop::PayloadType::PrepareFlip) { + nop->header = PM4Type3Header{PM4ItOpcode::Nop, 0x39}; + nop->data_block[0] = PM4CmdNop::PayloadType::PatchedFlip; + } else { + if (backup[1] == PM4CmdNop::PayloadType::PrepareFlipLabel) { + nop->header = PM4Type3Header{PM4ItOpcode::Nop, 0x34}; + nop->data_block[0] = PM4CmdNop::PayloadType::PatchedFlip; + + // Write event to update label + auto* write_label = reinterpret_cast(cmdbuf + 0x3b); + write_label->header = PM4Type3Header{PM4ItOpcode::WriteData, 3}; + write_label->raw = 0x500u; + write_label->dst_addr_lo = backup[2] & 0xffff'fffcu; + write_label->dst_addr_hi = backup[3]; + write_label->data[0] = backup[4]; + } + if (backup[1] == PM4CmdNop::PayloadType::PrepareFlipInterruptLabel) { + nop->header = PM4Type3Header{PM4ItOpcode::Nop, 0x33}; + nop->data_block[0] = PM4CmdNop::PayloadType::PatchedFlip; + + auto* write_eop = reinterpret_cast(cmdbuf + 0x3a); + write_eop->header = PM4Type3Header{PM4ItOpcode::EventWriteEop, 4}; + write_eop->event_control = (backup[5] & 0x3f) + 0x500u + (backup[6] & 0x3f) * 0x1000; + write_eop->address_lo = backup[2] & 0xffff'fffcu; + write_eop->data_control = (backup[3] & 0xffffu) | 0x2200'0000u; + write_eop->data_lo = backup[4]; + write_eop->data_hi = 0u; + } + if (backup[1] == PM4CmdNop::PayloadType::PrepareFlipInterrupt) { + nop->header = PM4Type3Header{PM4ItOpcode::Nop, 0x33}; + nop->data_block[0] = PM4CmdNop::PayloadType::PatchedFlip; + + auto* write_eop = reinterpret_cast(cmdbuf + 0x3a); + write_eop->header = PM4Type3Header{PM4ItOpcode::EventWriteEop, 4}; + write_eop->event_control = (backup[5] & 0x3f) + 0x500u + (backup[6] & 0x3f) * 0x1000; + write_eop->address_lo = 0u; + write_eop->data_control = 0x100'0000u; + write_eop->data_lo = 0u; + write_eop->data_hi = 0u; + } + } + + return ORBIS_OK; +} + +static inline s32 PerformSubmit(u32 count, const u32* dcb_gpu_addrs[], u32* dcb_sizes_in_bytes, + const u32* ccb_gpu_addrs[], u32* ccb_sizes_in_bytes) { + if (DebugState.ShouldPauseInSubmit()) { + DebugState.PauseGuestThreads(); + } + + if (send_init_packet) { + if (sdk_version < Common::ElfInfo::FW_200) { + liverpool->SubmitGfx(InitSequence, {}); + } else if (sdk_version < Common::ElfInfo::FW_400) { + if (sceKernelIsNeoMode()) { + if (!UseNeoCompatSequences) { + liverpool->SubmitGfx(InitSequence200Neo, {}); + } else { + liverpool->SubmitGfx(InitSequence200NeoCompat, {}); + } + } else { + liverpool->SubmitGfx(InitSequence200, {}); + } + } else { + if (sceKernelIsNeoMode()) { + if (!UseNeoCompatSequences) { + liverpool->SubmitGfx(InitSequence350Neo, {}); + } else { + liverpool->SubmitGfx(InitSequence350NeoCompat, {}); + } + } else { + liverpool->SubmitGfx(InitSequence350, {}); + } + } + send_init_packet = false; + } + + for (auto cbpair = 0u; cbpair < count; ++cbpair) { + const auto* ccb = ccb_gpu_addrs ? ccb_gpu_addrs[cbpair] : nullptr; + const auto ccb_size_in_bytes = ccb_sizes_in_bytes ? ccb_sizes_in_bytes[cbpair] : 0; + + const auto dcb_size_dw = dcb_sizes_in_bytes[cbpair] >> 2; + const auto ccb_size_dw = ccb_size_in_bytes >> 2; + + const auto& dcb_span = std::span{dcb_gpu_addrs[cbpair], dcb_size_dw}; + const auto& ccb_span = std::span{ccb, ccb_size_dw}; + + if (DebugState.DumpingCurrentFrame()) { + static auto last_frame_num = -1LL; + static u32 seq_num{}; + if (last_frame_num == frames_submitted && cbpair == 0) { + ++seq_num; + } else { + last_frame_num = frames_submitted; + seq_num = 0u; + } + + using DebugStateType::QueueType; + + DebugState.PushQueueDump({ + .type = QueueType::dcb, + .submit_num = seq_num, + .num2 = cbpair, + .data = {dcb_span.begin(), dcb_span.end()}, + .base_addr = reinterpret_cast(dcb_gpu_addrs[cbpair]), + }); + DebugState.PushQueueDump({ + .type = QueueType::ccb, + .submit_num = seq_num, + .num2 = cbpair, + .data = {ccb_span.begin(), ccb_span.end()}, + .base_addr = reinterpret_cast(ccb), + }); + } + liverpool->SubmitGfx(dcb_span, ccb_span); + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffers(u32 count, u32* dcb_gpu_addrs[], + u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes, u32 vo_handle, + u32 buf_idx, u32 flip_mode, s64 flip_arg) { + return sceGnmSubmitAndFlipCommandBuffersForWorkload( + count, count, dcb_gpu_addrs, dcb_sizes_in_bytes, ccb_gpu_addrs, ccb_sizes_in_bytes, + vo_handle, buf_idx, flip_mode, flip_arg); +} + +s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffersForWorkload( + u32 workload, u32 count, u32* dcb_gpu_addrs[], u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes, u32 vo_handle, u32 buf_idx, u32 flip_mode, s64 flip_arg) { + LOG_DEBUG(Lib_GnmDriver, "called [buf = {}]", buf_idx); + + if (count != 0) { + if (!dcb_gpu_addrs) { + LOG_ERROR(Lib_GnmDriver, "dcbGpuAddrs must not be NULL"); + return 0x80d11000; + } + if (!dcb_sizes_in_bytes) { + LOG_ERROR(Lib_GnmDriver, "dcbSizesInBytes must not be NULL"); + return 0x80d11000; + } + if (ccb_sizes_in_bytes && !ccb_gpu_addrs) { + LOG_ERROR(Lib_GnmDriver, "ccbGpuAddrs must not be NULL if ccbSizesInBytes is non-NULL"); + return 0x80d11000; + } + } + + for (u32 i = 0; i < count; i++) { + if (dcb_sizes_in_bytes[i] == 0) { + LOG_ERROR(Lib_GnmDriver, "Submitting a null DCB {}", i); + return 0x80d11000; + } + if (dcb_sizes_in_bytes[i] > 0x3ffffc) { + LOG_ERROR(Lib_GnmDriver, "dcbSizesInBytes[{}] ({}) is limited to (2*20)-1 DWORDS", i, + dcb_sizes_in_bytes[i]); + return 0x80d11000; + } + if (ccb_sizes_in_bytes && ccb_sizes_in_bytes[i] > 0x3ffffc) { + LOG_ERROR(Lib_GnmDriver, "ccbSizesInBytes[{}] ({}) is limited to (2*20)-1 DWORDS", i, + ccb_sizes_in_bytes[i]); + return 0x80d11000; + } + } + + auto* cmdbuf = dcb_gpu_addrs[count - 1]; + const auto size_dw = dcb_sizes_in_bytes[count - 1] / 4; + + std::scoped_lock lk{m_submit_lock}; + WaitGpuIdle(); + + const s32 patch_result = + PatchFlipRequest(cmdbuf, size_dw, vo_handle, buf_idx, flip_mode, flip_arg, nullptr /*unk*/); + if (patch_result != ORBIS_OK) { + return patch_result; + } + + return PerformSubmit(count, const_cast(dcb_gpu_addrs), dcb_sizes_in_bytes, + const_cast(ccb_gpu_addrs), ccb_sizes_in_bytes); +} + +s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload(u32 workload, u32 count, + const u32* dcb_gpu_addrs[], + u32* dcb_sizes_in_bytes, + const u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes) { + HLE_TRACE; + LOG_DEBUG(Lib_GnmDriver, "called"); + + if (!dcb_gpu_addrs || !dcb_sizes_in_bytes) { + LOG_ERROR(Lib_GnmDriver, "dcbGpuAddrs and dcbSizesInBytes must not be NULL"); + return 0x80d11000; + } + + for (u32 i = 0; i < count; i++) { + if (dcb_sizes_in_bytes[i] == 0) { + LOG_ERROR(Lib_GnmDriver, "Submitting a null DCB {}", i); + return 0x80d11000; + } + if (dcb_sizes_in_bytes[i] > 0x3ffffc) { + LOG_ERROR(Lib_GnmDriver, "dcbSizesInBytes[{}] ({}) is limited to (2*20)-1 DWORDS", i, + dcb_sizes_in_bytes[i]); + return 0x80d11000; + } + if (ccb_sizes_in_bytes && ccb_sizes_in_bytes[i] > 0x3ffffc) { + LOG_ERROR(Lib_GnmDriver, "ccbSizesInBytes[{}] ({}) is limited to (2*20)-1 DWORDS", i, + ccb_sizes_in_bytes[i]); + return 0x80d11000; + } + } + + std::scoped_lock lk{m_submit_lock}; + WaitGpuIdle(); + + return PerformSubmit(count, const_cast(dcb_gpu_addrs), dcb_sizes_in_bytes, + const_cast(ccb_gpu_addrs), ccb_sizes_in_bytes); +} + +s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[], + u32* dcb_sizes_in_bytes, const u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes) { + return sceGnmSubmitCommandBuffersForWorkload(count, count, dcb_gpu_addrs, dcb_sizes_in_bytes, + ccb_gpu_addrs, ccb_sizes_in_bytes); +} + +s32 PS4_SYSV_ABI sceGnmSubmitDone() { + HLE_TRACE; + LOG_DEBUG(Lib_GnmDriver, "called"); + std::scoped_lock lk{m_submit_lock}; + WaitGpuIdle(); + if (!liverpool->IsGpuIdle()) { + submission_lock = true; + } + liverpool->SubmitDone(); + send_init_packet = true; + ++frames_submitted; + DebugState.IncGnmFrameNum(); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmUnmapComputeQueue(u32 vqid) { + liverpool->asc_queues.erase(Common::SlotId{vqid - 1}); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmUnregisterAllResourcesForOwner() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmUnregisterOwnerAndResources() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmUnregisterResource() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +s32 PS4_SYSV_ABI sceGnmUpdateGsShader(u32* cmdbuf, u32 size, const u32* gs_regs) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size < 0x1d) { + return -1; + } + + if (!gs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + if (gs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x88u, gs_regs[0], 0u); // SPI_SHADER_PGM_LO_GS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x8au, gs_regs[2], + gs_regs[3]); // SPI_SHADER_PGM_RSRC1_GS/SPI_SHADER_PGM_RSRC2_GS + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e02e5u, + gs_regs[4]); + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e029bu, + gs_regs[5]); + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e02e4u, + gs_regs[6]); + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmUpdateHsShader(u32* cmdbuf, u32 size, const u32* hs_regs, u32 ls_hs_config) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x1c) { + return -1; + } + + if (!hs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + if (hs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x108u, hs_regs[0], + 0u); // SPI_SHADER_PGM_LO_HS/SPI_SHADER_PGM_HI_HS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x10au, hs_regs[2], + hs_regs[3]); // SPI_SHADER_PGM_RSRC1_HS/SPI_SHADER_PGM_RSRC1_LS + cmdbuf = WritePacket( + cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0286u, hs_regs[5], + hs_regs[6]); // VGT_HOS_MAX_TESS_LEVEL/VGT_HOS_MIN_TESS_LEVEL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e02dbu, + hs_regs[4]); // VGT_TF_PARAM update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e02d6u, + ls_hs_config); // VGT_LS_HS_CONFIG update + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmUpdatePsShader(u32* cmdbuf, u32 size, const u32* ps_regs) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x27) { + return -1; + } + if (!ps_regs) { + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, 0u, + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0203u, + 0u); // DB_SHADER_CONTROL update + WriteTrailingNop<0x20>(cmdbuf); + } else { + if (ps_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address."); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0], + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = + PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2], + ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS + cmdbuf = WritePacket( + cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4], + ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT update + cmdbuf = WritePacket( + cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01b3u, ps_regs[6], + ps_regs[7]); // SPI_PS_INPUT_ENA/SPI_PS_INPUT_ADDR update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01b6u, + ps_regs[8]); // SPI_PS_IN_CONTROL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01b8u, + ps_regs[9]); // SPI_BARYC_CNTL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0203u, + ps_regs[10]); // DB_SHADER_CONTROL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e008fu, + ps_regs[11]); // CB_SHADER_MASK update + + WriteTrailingNop<11>(cmdbuf); + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmUpdatePsShader350(u32* cmdbuf, u32 size, const u32* ps_regs) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x27) { + return -1; + } + if (!ps_regs) { + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, 0u, + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0203u, + 0u); // DB_SHADER_CONTROL update + cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x8fu, 0xfu); // CB_SHADER_MASK + + WriteTrailingNop<0x1d>(cmdbuf); + } else { + if (ps_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address."); + return -1; + } + + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0], + 0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS + cmdbuf = + PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2], + ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS + cmdbuf = WritePacket( + cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4], + ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT update + cmdbuf = WritePacket( + cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01b3u, ps_regs[6], + ps_regs[7]); // SPI_PS_INPUT_ENA/SPI_PS_INPUT_ADDR update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01b6u, + ps_regs[8]); // SPI_PS_IN_CONTROL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01b8u, + ps_regs[9]); // SPI_BARYC_CNTL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0203u, + ps_regs[10]); // DB_SHADER_CONTROL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e008fu, + ps_regs[11]); // CB_SHADER_MASK update + + WriteTrailingNop<11>(cmdbuf); + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmUpdateVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, + u32 shader_modifier) { + LOG_TRACE(Lib_GnmDriver, "called"); + + if (!cmdbuf || size <= 0x1c) { + return -1; + } + + if (!vs_regs) { + LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument"); + return -1; + } + + if (shader_modifier & 0xfcfffc3f) { + LOG_ERROR(Lib_GnmDriver, "Invalid modifier mask"); + return -1; + } + + if (vs_regs[1] != 0) { + LOG_ERROR(Lib_GnmDriver, "Invalid shader address"); + return -1; + } + + const u32 var = + shader_modifier == 0 ? vs_regs[2] : ((vs_regs[2] & 0xfcfffc3f) | shader_modifier); + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], 0u); // SPI_SHADER_PGM_LO_VS + cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0207u, + vs_regs[6]); // PA_CL_VS_OUT_CNTL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01b1u, + vs_regs[4]); // PA_CL_VS_OUT_CNTL update + cmdbuf = WritePacket(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c3u, + vs_regs[5]); // PA_CL_VS_OUT_CNTL update + + WriteTrailingNop<11>(cmdbuf); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceGnmValidateCommandBuffers() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics2() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidateDispatchCommandBuffers() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidateDrawCommandBuffers() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidateGetDiagnosticInfo() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidateGetDiagnostics() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidateGetVersion() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return 0; +} + +bool PS4_SYSV_ABI sceGnmValidateOnSubmitEnabled() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return false; +} + +int PS4_SYSV_ABI sceGnmValidateResetState() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceGnmValidationRegisterMemoryCheckCallback() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED; +} + +int PS4_SYSV_ABI sceRazorCaptureCommandBuffersOnlyImmediate() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_CAPTURE_FAILED_INTERNAL; +} + +int PS4_SYSV_ABI sceRazorCaptureCommandBuffersOnlySinceLastFlip() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_CAPTURE_FAILED_INTERNAL; +} + +int PS4_SYSV_ABI sceRazorCaptureImmediate() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_CAPTURE_FAILED_INTERNAL; +} + +int PS4_SYSV_ABI sceRazorCaptureSinceLastFlip() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_CAPTURE_FAILED_INTERNAL; +} + +bool PS4_SYSV_ABI sceRazorIsLoaded() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return false; +} + +int PS4_SYSV_ABI Func_063D065A2D6359C3() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_0CABACAFB258429D() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_150CF336FC2E99A3() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_17CA687F9EE52D49() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_1870B89F759C6B45() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_26F9029EF68A955E() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_301E3DBBAB092DB0() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_30BAFE172AF17FEF() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_3E6A3E8203D95317() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_40FEEF0C6534C434() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_416B9079DE4CBACE() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_4774D83BB4DDBF9A() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_50678F1CCEEB9A00() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_54A2EC5FA4C62413() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_5A9C52C83138AE6B() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_5D22193A31EA1142() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_725A36DEBB60948D() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_8021A502FA61B9BB() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_9D002FE0FA40F0E6() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_9D297F36A7028B71() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_A2D7EC7A7BCF79B3() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_AA12A3CB8990854A() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_ADC8DDC005020BC6() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_B0A8688B679CB42D() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_B489020B5157A5FF() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_BADE7B4C199140DD() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_D1511B9DCFFB3DD9() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_D53446649B02E58E() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_D8B6E8E28E1EF0A3() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_D93D733A19DD7454() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_DE995443BC2A8317() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_DF6E9528150C23FF() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_ECB4C6BA41FE3350() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmDebugModuleReset() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmDebugReset() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI Func_C4C328B7CF3B4171() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalCommand(u32* cmdbuf, u32 size) { + LOG_TRACE(Lib_GnmDriver, "called"); + if (sdk_version >= Common::ElfInfo::FW_400) { + return sceGnmDrawInitToDefaultContextState400(cmdbuf, size); + } + return sceGnmDrawInitToDefaultContextState(cmdbuf, size); +} + +int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalSize() { + LOG_TRACE(Lib_GnmDriver, "called"); + if (sdk_version >= Common::ElfInfo::FW_400) { + return 0x100; + } + return 0x20; +} + +int PS4_SYSV_ABI sceGnmFindResources() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmGetResourceRegistrationBuffers() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI sceGnmRegisterOwnerForSystem() { + LOG_TRACE(Lib_GnmDriver, "called"); + // Not available in retail firmware + return ORBIS_GNM_ERROR_FAILURE; +} + +int PS4_SYSV_ABI Func_1C43886B16EE5530() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_81037019ECCD0E01() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_BFB41C057478F0BF() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_E51D44DB8151238C() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI Func_F916890425496553() { + LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + return ORBIS_OK; +} + +void RegisterLib(Core::Loader::SymbolsResolver* sym) { + LOG_INFO(Lib_GnmDriver, "Initializing presenter"); + liverpool = std::make_unique(); + presenter = std::make_unique(*g_window, liverpool.get()); + + const s32 result = sceKernelGetCompiledSdkVersion(&sdk_version); + if (result != ORBIS_OK) { + sdk_version = 0; + } + + if (EmulatorSettings.IsCopyGpuBuffers()) { + liverpool->ReserveCopyBufferSpace(); + } + + Platform::IrqC::Instance()->Register(Platform::InterruptId::GpuIdle, ResetSubmissionLock, + nullptr); + + LIB_FUNCTION("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmAddEqEvent); + LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmAreSubmitsAllowed); + LIB_FUNCTION("ihxrbsoSKWc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmBeginWorkload); + LIB_FUNCTION("ffrNQOshows", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmComputeWaitOnAddress); + LIB_FUNCTION("EJapNl2+pgU", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmComputeWaitSemaphore); + LIB_FUNCTION("5udAm+6boVg", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmCreateWorkloadStream); + LIB_FUNCTION("jwCEzr7uEP4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDebuggerGetAddressWatch); + LIB_FUNCTION("PNf0G7gvFHQ", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDebuggerHaltWavefront); + LIB_FUNCTION("nO-tMnaxJiE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDebuggerReadGds); + LIB_FUNCTION("t0HIQWnvK9E", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDebuggerReadSqIndirectRegister); + LIB_FUNCTION("HsLtF4jKe48", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDebuggerResumeWavefront); + LIB_FUNCTION("JRKSSV0YzwA", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDebuggerResumeWavefrontCreation); + LIB_FUNCTION("jpTMyYB8UBI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDebuggerSetAddressWatch); + LIB_FUNCTION("MJG69Q7ti+s", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDebuggerWriteGds); + LIB_FUNCTION("PaFw9w6f808", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDebuggerWriteSqIndirectRegister); + LIB_FUNCTION("qpGITzPE+Zc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDebugHardwareStatus); + LIB_FUNCTION("PVT+fuoS9gU", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDeleteEqEvent); + LIB_FUNCTION("UtObDRQiGbs", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDestroyWorkloadStream); + LIB_FUNCTION("bX5IbRvECXk", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDingDong); + LIB_FUNCTION("byXlqupd8cE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDingDongForWorkload); + LIB_FUNCTION("HHo1BAljZO8", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDisableMipStatsReport); + LIB_FUNCTION("0BzLGljcwBo", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDispatchDirect); + LIB_FUNCTION("Z43vKp5k7r0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDispatchIndirect); + LIB_FUNCTION("wED4ZXCFJT0", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDispatchIndirectOnMec); + LIB_FUNCTION("nF6bFRUBRAU", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDispatchInitDefaultHardwareState); + LIB_FUNCTION("HlTPoZ-oY7Y", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDrawIndex); + LIB_FUNCTION("GGsn7jMTxw4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDrawIndexAuto); + LIB_FUNCTION("ED9-Fjr8Ta4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDrawIndexIndirect); + LIB_FUNCTION("thbPcG7E7qk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawIndexIndirectCountMulti); + LIB_FUNCTION("5q95ravnueg", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawIndexIndirectMulti); + LIB_FUNCTION("jHdPvIzlpKc", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawIndexMultiInstanced); + LIB_FUNCTION("oYM+YzfCm2Y", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDrawIndexOffset); + LIB_FUNCTION("4v+otIIdjqg", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDrawIndirect); + LIB_FUNCTION("cUCo8OvArrw", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawIndirectCountMulti); + LIB_FUNCTION("f5QQLp9rzGk", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDrawIndirectMulti); + LIB_FUNCTION("Idffwf3yh8s", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawInitDefaultHardwareState); + LIB_FUNCTION("QhnyReteJ1M", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawInitDefaultHardwareState175); + LIB_FUNCTION("0H2vBYbTLHI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawInitDefaultHardwareState200); + LIB_FUNCTION("yb2cRhagD1I", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawInitDefaultHardwareState350); + LIB_FUNCTION("8lH54sfjfmU", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawInitToDefaultContextState); + LIB_FUNCTION("im2ZuItabu4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDrawInitToDefaultContextState400); + LIB_FUNCTION("stDSYW2SBVM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmDrawOpaqueAuto); + LIB_FUNCTION("TLV4mswiZ4A", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverCaptureInProgress); + LIB_FUNCTION("ODEeJ1GfDtE", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalRetrieveGnmInterface); + LIB_FUNCTION("4LSXsEKPTsE", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalRetrieveGnmInterfaceForGpuDebugger); + LIB_FUNCTION("MpncRjHNYRE", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalRetrieveGnmInterfaceForGpuException); + LIB_FUNCTION("EwjWGcIOgeM", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalRetrieveGnmInterfaceForHDRScopes); + LIB_FUNCTION("3EXdrVC7WFk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalRetrieveGnmInterfaceForReplay); + LIB_FUNCTION("P9iKqxAGeck", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalRetrieveGnmInterfaceForResourceRegistration); + LIB_FUNCTION("t-vIc5cTEzg", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalRetrieveGnmInterfaceForValidation); + LIB_FUNCTION("BvvO8Up88Zc", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverInternalVirtualQuery); + LIB_FUNCTION("R6z1xM3pW-w", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverTraceInProgress); + LIB_FUNCTION("d88anrgNoKY", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmDriverTriggerCapture); + LIB_FUNCTION("Fa3x75OOLRA", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmEndWorkload); + LIB_FUNCTION("4Mv9OXypBG8", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmFindResourcesPublic); + LIB_FUNCTION("iBt3Oe00Kvc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmFlushGarlic); + LIB_FUNCTION("GviyYfFQIkc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetCoredumpAddress); + LIB_FUNCTION("meiO-5ZCVIE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetCoredumpMode); + LIB_FUNCTION("O-7nHKgcNSQ", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetCoredumpProtectionFaultTimestamp); + LIB_FUNCTION("bSJFzejYrJI", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetDbgGcHandle); + LIB_FUNCTION("pd4C7da6sEg", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetDebugTimestamp); + LIB_FUNCTION("UoYY0DWMC0U", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetEqEventType); + LIB_FUNCTION("H7-fgvEutM0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetEqTimeStamp); + LIB_FUNCTION("oL4hGI1PMpw", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetGpuBlockStatus); + LIB_FUNCTION("Fwvh++m9IQI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetGpuCoreClockFrequency); + LIB_FUNCTION("tZCSL5ulnB4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetGpuInfoStatus); + LIB_FUNCTION("iFirFzgYsvw", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetLastWaitedAddress); + LIB_FUNCTION("KnldROUkWJY", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetNumTcaUnits); + LIB_FUNCTION("FFVZcCu3zWU", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetOffChipTessellationBufferSize); + LIB_FUNCTION("QJjPjlmPAL0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetOwnerName); + LIB_FUNCTION("dewXw5roLs0", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetPhysicalCounterFromVirtualized); + LIB_FUNCTION("fzJdEihTFV4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetProtectionFaultTimeStamp); + LIB_FUNCTION("4PKnYXOhcx4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetResourceBaseAddressAndSizeInBytes); + LIB_FUNCTION("O0S96YnD04U", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetResourceName); + LIB_FUNCTION("UBv7FkVfzcQ", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetResourceShaderGuid); + LIB_FUNCTION("bdqdvIkLPIU", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetResourceType); + LIB_FUNCTION("UoBuWAhKk7U", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetResourceUserData); + LIB_FUNCTION("nEyFbYUloIM", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetShaderProgramBaseAddress); + LIB_FUNCTION("k7iGTvDQPLQ", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGetShaderStatus); + LIB_FUNCTION("ln33zjBrfjk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmGetTheTessellationFactorRingBufferBaseAddress); + LIB_FUNCTION("QLdG7G-PBZo", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGpuPaDebugEnter); + LIB_FUNCTION("tVEdZe3wlbY", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmGpuPaDebugLeave); + LIB_FUNCTION("NfvOrNzy6sk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmInsertDingDongMarker); + LIB_FUNCTION("7qZVNgEu+SY", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmInsertPopMarker); + LIB_FUNCTION("aPIZJTXC+cU", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmInsertPushColorMarker); + LIB_FUNCTION("W1Etj-jlW7Y", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmInsertPushMarker); + LIB_FUNCTION("aj3L-iaFmyk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmInsertSetColorMarker); + LIB_FUNCTION("jiItzS6+22g", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmInsertSetMarker); + LIB_FUNCTION("URDgJcXhQOs", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmInsertThreadTraceMarker); + LIB_FUNCTION("1qXLHIpROPE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmInsertWaitFlipDone); + LIB_FUNCTION("HRyNHoAjb6E", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmIsCoredumpValid); + LIB_FUNCTION("jg33rEKLfVs", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmIsUserPaEnabled); + LIB_FUNCTION("26PM5Mzl8zc", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmLogicalCuIndexToPhysicalCuIndex); + LIB_FUNCTION("RU74kek-N0c", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmLogicalCuMaskToPhysicalCuMask); + LIB_FUNCTION("Kl0Z3LH07QI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmLogicalTcaUnitToPhysical); + LIB_FUNCTION("29oKvKXzEZo", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmMapComputeQueue); + LIB_FUNCTION("A+uGq+3KFtQ", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmMapComputeQueueWithPriority); + LIB_FUNCTION("+N+wrSYBLIw", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmPaDisableFlipCallbacks); + LIB_FUNCTION("8WDA9RiXLaw", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmPaEnableFlipCallbacks); + LIB_FUNCTION("tNuT48mApTc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmPaHeartbeat); + LIB_FUNCTION("6IMbpR7nTzA", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmQueryResourceRegistrationUserMemoryRequirements); + LIB_FUNCTION("+rJnw2e9O+0", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmRaiseUserExceptionEvent); + LIB_FUNCTION("9Mv61HaMhfA", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmRegisterGdsResource); + LIB_FUNCTION("t7-VbMosbR4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmRegisterGnmLiveCallbackConfig); + LIB_FUNCTION("ZFqKFl23aMc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmRegisterOwner); + LIB_FUNCTION("nvEwfYAImTs", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmRegisterResource); + LIB_FUNCTION("gObODli-OH8", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmRequestFlipAndSubmitDone); + LIB_FUNCTION("6YRHhh5mHCs", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmRequestFlipAndSubmitDoneForWorkload); + LIB_FUNCTION("f85orjx7qts", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmRequestMipStatsReportAndReset); + LIB_FUNCTION("MYRtYhojKdA", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmResetVgtControl); + LIB_FUNCTION("hS0MKPRdNr0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaClose); + LIB_FUNCTION("31G6PB2oRYQ", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaConstFill); + LIB_FUNCTION("Lg2isla2XeQ", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaCopyLinear); + LIB_FUNCTION("-Se2FY+UTsI", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaCopyTiled); + LIB_FUNCTION("OlFgKnBsALE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaCopyWindow); + LIB_FUNCTION("LQQN0SwQv8c", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaFlush); + LIB_FUNCTION("suUlSjWr7CE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaGetMinCmdSize); + LIB_FUNCTION("5AtqyMgO7fM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSdmaOpen); + LIB_FUNCTION("KXltnCwEJHQ", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetCsShader); + LIB_FUNCTION("Kx-h-nWQJ8A", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSetCsShaderWithModifier); + LIB_FUNCTION("X9Omw9dwv5M", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetEmbeddedPsShader); + LIB_FUNCTION("+AFvOEXrKJk", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetEmbeddedVsShader); + LIB_FUNCTION("FUHG8sQ3R58", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetEsShader); + LIB_FUNCTION("jtkqXpAOY6w", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetGsRingSizes); + LIB_FUNCTION("UJwNuMBcUAk", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetGsShader); + LIB_FUNCTION("VJNjFtqiF5w", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetHsShader); + LIB_FUNCTION("vckdzbQ46SI", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetLsShader); + LIB_FUNCTION("bQVd5YzCal0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetPsShader); + LIB_FUNCTION("5uFKckiJYRM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetPsShader350); + LIB_FUNCTION("q-qhDxP67Hg", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSetResourceRegistrationUserMemory); + LIB_FUNCTION("K3BKBBYKUSE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetResourceUserData); + LIB_FUNCTION("0O3xxFaiObw", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSetSpiEnableSqCounters); + LIB_FUNCTION("lN7Gk-p9u78", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSetSpiEnableSqCountersForUnitInstance); + LIB_FUNCTION("+xuDhxlWRPg", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetupMipStatsReport); + LIB_FUNCTION("cFCp0NX8wf0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetVgtControl); + LIB_FUNCTION("gAhCn6UiU4Y", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSetVsShader); + LIB_FUNCTION("y+iI2lkX+qI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSetWaveLimitMultiplier); + LIB_FUNCTION("XiyzNZ9J4nQ", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSetWaveLimitMultipliers); + LIB_FUNCTION("kkn+iy-mhyg", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmEndSpm); + LIB_FUNCTION("aqhuK2Mj4X4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmInit); + LIB_FUNCTION("KHpZ9hJo1c0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmInit2); + LIB_FUNCTION("QEsMC+M3yjE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmSetDelay); + LIB_FUNCTION("hljMAxTLNF0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmSetMuxRam); + LIB_FUNCTION("bioGsp74SLM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmSetMuxRam2); + LIB_FUNCTION("cMWWYeqQQlM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmSetSelectCounter); + LIB_FUNCTION("-zJi8Vb4Du4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmSetSpmSelects); + LIB_FUNCTION("xTsOqp-1bE4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmSetSpmSelects2); + LIB_FUNCTION("AmmYLcJGTl0", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSpmStartSpm); + LIB_FUNCTION("UHDiSFDxNao", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttFini); + LIB_FUNCTION("a3tLC56vwug", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttFinishTrace); + LIB_FUNCTION("L-owl1dSKKg", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetBcInfo); + LIB_FUNCTION("LQtzqghKQm4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetGpuClocks); + LIB_FUNCTION("wYN5mmv6Ya8", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetHiWater); + LIB_FUNCTION("9X4SkENMS0M", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetStatus); + LIB_FUNCTION("lbMccQM2iqc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetTraceCounter); + LIB_FUNCTION("DYAC6JUeZvM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetTraceWptr); + LIB_FUNCTION("pS2tjBxzJr4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetWrapCounts); + LIB_FUNCTION("rXV8az6X+fM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttGetWrapCounts2); + LIB_FUNCTION("ARS+TNLopyk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSqttGetWritebackLabels); + LIB_FUNCTION("X6yCBYPP7HA", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttInit); + LIB_FUNCTION("2IJhUyK8moE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSelectMode); + LIB_FUNCTION("QA5h6Gh3r60", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSelectTarget); + LIB_FUNCTION("F5XJY1XHa3Y", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSelectTokens); + LIB_FUNCTION("wJtaTpNZfH4", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSetCuPerfMask); + LIB_FUNCTION("kY4dsQh+SH4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSqttSetDceEventWrite); + LIB_FUNCTION("7XRH1CIfNpI", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSetHiWater); + LIB_FUNCTION("05YzC2r3hHo", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSetTraceBuffer2); + LIB_FUNCTION("ASUric-2EnI", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSetTraceBuffers); + LIB_FUNCTION("gPxYzPp2wlo", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttSetUserData); + LIB_FUNCTION("d-YcZX7SIQA", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSqttSetUserdataTimer); + LIB_FUNCTION("ru8cb4he6O8", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttStartTrace); + LIB_FUNCTION("gVuGo1nBnG8", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttStopTrace); + LIB_FUNCTION("OpyolX6RwS0", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSqttSwitchTraceBuffer); + LIB_FUNCTION("dl5u5eGBgNk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSqttSwitchTraceBuffer2); + LIB_FUNCTION("QLzOwOF0t+A", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSqttWaitForEvent); + LIB_FUNCTION("xbxNatawohc", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSubmitAndFlipCommandBuffers); + LIB_FUNCTION("Ga6r7H6Y0RI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSubmitAndFlipCommandBuffersForWorkload); + LIB_FUNCTION("zwY0YV91TTI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSubmitCommandBuffers); + LIB_FUNCTION("jRcI8VcgTz4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmSubmitCommandBuffersForWorkload); + LIB_FUNCTION("yvZ73uQUqrk", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmSubmitDone); + LIB_FUNCTION("ArSg-TGinhk", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmUnmapComputeQueue); + LIB_FUNCTION("yhFCnaz5daw", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmUnregisterAllResourcesForOwner); + LIB_FUNCTION("fhKwCVVj9nk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmUnregisterOwnerAndResources); + LIB_FUNCTION("k8EXkhIP+lM", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmUnregisterResource); + LIB_FUNCTION("nLM2i2+65hA", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmUpdateGsShader); + LIB_FUNCTION("GNlx+y7xPdE", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmUpdateHsShader); + LIB_FUNCTION("4MgRw-bVNQU", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmUpdatePsShader); + LIB_FUNCTION("mLVL7N7BVBg", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmUpdatePsShader350); + LIB_FUNCTION("V31V01UiScY", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmUpdateVsShader); + LIB_FUNCTION("iCO804ZgzdA", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateCommandBuffers); + LIB_FUNCTION("SXw4dZEkgpA", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateDisableDiagnostics); + LIB_FUNCTION("BgM3t3LvcNk", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateDisableDiagnostics2); + LIB_FUNCTION("qGP74T5OWJc", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateDispatchCommandBuffers); + LIB_FUNCTION("hsZPf1lON7E", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateDrawCommandBuffers); + LIB_FUNCTION("RX7XCNSaL6I", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateGetDiagnosticInfo); + LIB_FUNCTION("5SHGNwLXBV4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateGetDiagnostics); + LIB_FUNCTION("HzMN7ANqYEc", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmValidateGetVersion); + LIB_FUNCTION("rTIV11nMQuM", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidateOnSubmitEnabled); + LIB_FUNCTION("MBMa6EFu4Ko", "libSceGnmDriver", 1, "libSceGnmDriver", sceGnmValidateResetState); + LIB_FUNCTION("Q7t4VEYLafI", "libSceGnmDriver", 1, "libSceGnmDriver", + sceGnmValidationRegisterMemoryCheckCallback); + LIB_FUNCTION("xeTLfxVIQO4", "libSceGnmDriver", 1, "libSceGnmDriver", + sceRazorCaptureCommandBuffersOnlyImmediate); + LIB_FUNCTION("9thMn+uB1is", "libSceGnmDriver", 1, "libSceGnmDriver", + sceRazorCaptureCommandBuffersOnlySinceLastFlip); + LIB_FUNCTION("u9YKpRRHe-M", "libSceGnmDriver", 1, "libSceGnmDriver", sceRazorCaptureImmediate); + LIB_FUNCTION("4UFagYlfuAM", "libSceGnmDriver", 1, "libSceGnmDriver", + sceRazorCaptureSinceLastFlip); + LIB_FUNCTION("f33OrruQYbM", "libSceGnmDriver", 1, "libSceGnmDriver", sceRazorIsLoaded); + LIB_FUNCTION("Bj0GWi1jWcM", "libSceGnmDriver", 1, "libSceGnmDriver", Func_063D065A2D6359C3); + LIB_FUNCTION("DKusr7JYQp0", "libSceGnmDriver", 1, "libSceGnmDriver", Func_0CABACAFB258429D); + LIB_FUNCTION("FQzzNvwumaM", "libSceGnmDriver", 1, "libSceGnmDriver", Func_150CF336FC2E99A3); + LIB_FUNCTION("F8pof57lLUk", "libSceGnmDriver", 1, "libSceGnmDriver", Func_17CA687F9EE52D49); + LIB_FUNCTION("GHC4n3Wca0U", "libSceGnmDriver", 1, "libSceGnmDriver", Func_1870B89F759C6B45); + LIB_FUNCTION("JvkCnvaKlV4", "libSceGnmDriver", 1, "libSceGnmDriver", Func_26F9029EF68A955E); + LIB_FUNCTION("MB49u6sJLbA", "libSceGnmDriver", 1, "libSceGnmDriver", Func_301E3DBBAB092DB0); + LIB_FUNCTION("MLr+Fyrxf+8", "libSceGnmDriver", 1, "libSceGnmDriver", Func_30BAFE172AF17FEF); + LIB_FUNCTION("Pmo+ggPZUxc", "libSceGnmDriver", 1, "libSceGnmDriver", Func_3E6A3E8203D95317); + LIB_FUNCTION("QP7vDGU0xDQ", "libSceGnmDriver", 1, "libSceGnmDriver", Func_40FEEF0C6534C434); + LIB_FUNCTION("QWuQed5Mus4", "libSceGnmDriver", 1, "libSceGnmDriver", Func_416B9079DE4CBACE); + LIB_FUNCTION("R3TYO7Tdv5o", "libSceGnmDriver", 1, "libSceGnmDriver", Func_4774D83BB4DDBF9A); + LIB_FUNCTION("UGePHM7rmgA", "libSceGnmDriver", 1, "libSceGnmDriver", Func_50678F1CCEEB9A00); + LIB_FUNCTION("VKLsX6TGJBM", "libSceGnmDriver", 1, "libSceGnmDriver", Func_54A2EC5FA4C62413); + LIB_FUNCTION("WpxSyDE4rms", "libSceGnmDriver", 1, "libSceGnmDriver", Func_5A9C52C83138AE6B); + LIB_FUNCTION("XSIZOjHqEUI", "libSceGnmDriver", 1, "libSceGnmDriver", Func_5D22193A31EA1142); + LIB_FUNCTION("clo23rtglI0", "libSceGnmDriver", 1, "libSceGnmDriver", Func_725A36DEBB60948D); + LIB_FUNCTION("gCGlAvphubs", "libSceGnmDriver", 1, "libSceGnmDriver", Func_8021A502FA61B9BB); + LIB_FUNCTION("nQAv4PpA8OY", "libSceGnmDriver", 1, "libSceGnmDriver", Func_9D002FE0FA40F0E6); + LIB_FUNCTION("nSl-NqcCi3E", "libSceGnmDriver", 1, "libSceGnmDriver", Func_9D297F36A7028B71); + LIB_FUNCTION("otfsenvPebM", "libSceGnmDriver", 1, "libSceGnmDriver", Func_A2D7EC7A7BCF79B3); + LIB_FUNCTION("qhKjy4mQhUo", "libSceGnmDriver", 1, "libSceGnmDriver", Func_AA12A3CB8990854A); + LIB_FUNCTION("rcjdwAUCC8Y", "libSceGnmDriver", 1, "libSceGnmDriver", Func_ADC8DDC005020BC6); + LIB_FUNCTION("sKhoi2ectC0", "libSceGnmDriver", 1, "libSceGnmDriver", Func_B0A8688B679CB42D); + LIB_FUNCTION("tIkCC1FXpf8", "libSceGnmDriver", 1, "libSceGnmDriver", Func_B489020B5157A5FF); + LIB_FUNCTION("ut57TBmRQN0", "libSceGnmDriver", 1, "libSceGnmDriver", Func_BADE7B4C199140DD); + LIB_FUNCTION("0VEbnc-7Pdk", "libSceGnmDriver", 1, "libSceGnmDriver", Func_D1511B9DCFFB3DD9); + LIB_FUNCTION("1TRGZJsC5Y4", "libSceGnmDriver", 1, "libSceGnmDriver", Func_D53446649B02E58E); + LIB_FUNCTION("2Lbo4o4e8KM", "libSceGnmDriver", 1, "libSceGnmDriver", Func_D8B6E8E28E1EF0A3); + LIB_FUNCTION("2T1zOhnddFQ", "libSceGnmDriver", 1, "libSceGnmDriver", Func_D93D733A19DD7454); + LIB_FUNCTION("3plUQ7wqgxc", "libSceGnmDriver", 1, "libSceGnmDriver", Func_DE995443BC2A8317); + LIB_FUNCTION("326VKBUMI-8", "libSceGnmDriver", 1, "libSceGnmDriver", Func_DF6E9528150C23FF); + LIB_FUNCTION("7LTGukH+M1A", "libSceGnmDriver", 1, "libSceGnmDriver", Func_ECB4C6BA41FE3350); + LIB_FUNCTION("dqPBvjFVpTA", "libSceGnmDebugModuleReset", 1, "libSceGnmDriver", + sceGnmDebugModuleReset); + LIB_FUNCTION("RNPAItiMLIg", "libSceGnmDebugReset", 1, "libSceGnmDriver", sceGnmDebugReset); + LIB_FUNCTION("xMMot887QXE", "libSceGnmDebugReset", 1, "libSceGnmDriver", Func_C4C328B7CF3B4171); + LIB_FUNCTION("pF1HQjbmQJ0", "libSceGnmDriverCompat", 1, "libSceGnmDriver", + sceGnmDrawInitToDefaultContextStateInternalCommand); + LIB_FUNCTION("jajhf-Gi3AI", "libSceGnmDriverCompat", 1, "libSceGnmDriver", + sceGnmDrawInitToDefaultContextStateInternalSize); + LIB_FUNCTION("vbcR4Ken6AA", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + sceGnmFindResources); + LIB_FUNCTION("eLQbNsKeTkU", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + sceGnmGetResourceRegistrationBuffers); + LIB_FUNCTION("j6mSQs3UgaY", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + sceGnmRegisterOwnerForSystem); + LIB_FUNCTION("HEOIaxbuVTA", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + Func_1C43886B16EE5530); + LIB_FUNCTION("gQNwGezNDgE", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + Func_81037019ECCD0E01); + LIB_FUNCTION("v7QcBXR48L8", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + Func_BFB41C057478F0BF); + LIB_FUNCTION("5R1E24FRI4w", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + Func_E51D44DB8151238C); + LIB_FUNCTION("+RaJBCVJZVM", "libSceGnmDriverResourceRegistration", 1, "libSceGnmDriver", + Func_F916890425496553); + LIB_FUNCTION("Fwvh++m9IQI", "libSceGnmGetGpuCoreClockFrequency", 1, "libSceGnmDriver", + sceGnmGetGpuCoreClockFrequency); + LIB_FUNCTION("R3TYO7Tdv5o", "libSceGnmWaitFreeSubmit", 1, "libSceGnmDriver", + Func_4774D83BB4DDBF9A); + LIB_FUNCTION("ut57TBmRQN0", "libSceGnmWaitFreeSubmit", 1, "libSceGnmDriver", + Func_BADE7B4C199140DD); +}; + +} // namespace Libraries::GnmDriver diff --git a/gpu/shadps4/core/libraries/gnmdriver/gnmdriver.h b/gpu/shadps4/core/libraries/gnmdriver/gnmdriver.h new file mode 100644 index 0000000..c8e0385 --- /dev/null +++ b/gpu/shadps4/core/libraries/gnmdriver/gnmdriver.h @@ -0,0 +1,303 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "core/libraries/kernel/equeue.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::GnmDriver { + +using namespace Kernel; + +s32 PS4_SYSV_ABI sceGnmAddEqEvent(OrbisKernelEqueue eq, u64 id, void* udata); +int PS4_SYSV_ABI sceGnmAreSubmitsAllowed(); +int PS4_SYSV_ABI sceGnmBeginWorkload(u32 workload_stream, u64* workload); +s32 PS4_SYSV_ABI sceGnmComputeWaitOnAddress(u32* cmdbuf, u32 size, uintptr_t addr, u32 mask, + u32 cmp_func, u32 ref); +int PS4_SYSV_ABI sceGnmComputeWaitSemaphore(); +int PS4_SYSV_ABI sceGnmCreateWorkloadStream(u64 param1, u32* workload_stream); +int PS4_SYSV_ABI sceGnmDebuggerGetAddressWatch(); +int PS4_SYSV_ABI sceGnmDebuggerHaltWavefront(); +int PS4_SYSV_ABI sceGnmDebuggerReadGds(); +int PS4_SYSV_ABI sceGnmDebuggerReadSqIndirectRegister(); +int PS4_SYSV_ABI sceGnmDebuggerResumeWavefront(); +int PS4_SYSV_ABI sceGnmDebuggerResumeWavefrontCreation(); +int PS4_SYSV_ABI sceGnmDebuggerSetAddressWatch(); +int PS4_SYSV_ABI sceGnmDebuggerWriteGds(); +int PS4_SYSV_ABI sceGnmDebuggerWriteSqIndirectRegister(); +int PS4_SYSV_ABI sceGnmDebugHardwareStatus(); +s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(OrbisKernelEqueue eq, u64 id); +int PS4_SYSV_ABI sceGnmDestroyWorkloadStream(); +void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw); +void PS4_SYSV_ABI sceGnmDingDongForWorkload(u32 gnm_vqid, u32 next_offs_dw, u64 workload_id); +int PS4_SYSV_ABI sceGnmDisableMipStatsReport(); +s32 PS4_SYSV_ABI sceGnmDispatchDirect(u32* cmdbuf, u32 size, u32 threads_x, u32 threads_y, + u32 threads_z, u32 flags); +s32 PS4_SYSV_ABI sceGnmDispatchIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 flags); +s32 PS4_SYSV_ABI sceGnmDispatchIndirectOnMec(u32* cmdbuf, u32 size, VAddr args, u32 modifier); +u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size); +s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr_t index_addr, + u32 flags, u32 type); +s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32 flags); +s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage, + u32 vertex_sgpr_offset, u32 instance_sgpr_offset, + u32 flags); +s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 data_offset, + u32 max_count, u64 count_addr, u32 shader_stage, + u32 vertex_sgpr_offset, u32 instance_sgpr_offset, + u32 flags); +int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count, + u32 shader_stage, u32 vertex_sgpr_offset, + u32 instance_sgpr_offset, u32 flags); +int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced(); +s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset, u32 index_count, + u32 flags); +s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage, + u32 vertex_sgpr_offset, u32 instance_sgpr_offset, u32 flags); +int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti(); +s32 PS4_SYSV_ABI sceGnmDrawIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count, + u32 shader_stage, u32 vertex_sgpr_offset, + u32 instance_sgpr_offset, u32 flags); +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size); +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size); +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size); +u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size); +u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState(u32* cmdbuf, u32 size); +u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400(u32* cmdbuf, u32 size); +int PS4_SYSV_ABI sceGnmDrawOpaqueAuto(); +bool PS4_SYSV_ABI sceGnmDriverCaptureInProgress(); +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterface(); +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForGpuDebugger(); +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForGpuException(); +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForHDRScopes(); +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForReplay(); +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForResourceRegistration(); +u32 PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForValidation(); +int PS4_SYSV_ABI sceGnmDriverInternalVirtualQuery(); +bool PS4_SYSV_ABI sceGnmDriverTraceInProgress(); +int PS4_SYSV_ABI sceGnmDriverTriggerCapture(); +int PS4_SYSV_ABI sceGnmEndWorkload(u64 workload); +s32 PS4_SYSV_ABI sceGnmFindResourcesPublic(); +void PS4_SYSV_ABI sceGnmFlushGarlic(); +int PS4_SYSV_ABI sceGnmGetCoredumpAddress(); +int PS4_SYSV_ABI sceGnmGetCoredumpMode(); +int PS4_SYSV_ABI sceGnmGetCoredumpProtectionFaultTimestamp(); +int PS4_SYSV_ABI sceGnmGetDbgGcHandle(); +int PS4_SYSV_ABI sceGnmGetDebugTimestamp(); +int PS4_SYSV_ABI sceGnmGetEqEventType(const OrbisKernelEvent* ev); +int PS4_SYSV_ABI sceGnmGetEqTimeStamp(); +int PS4_SYSV_ABI sceGnmGetGpuBlockStatus(); +u32 PS4_SYSV_ABI sceGnmGetGpuCoreClockFrequency(); +int PS4_SYSV_ABI sceGnmGetGpuInfoStatus(); +int PS4_SYSV_ABI sceGnmGetLastWaitedAddress(); +int PS4_SYSV_ABI sceGnmGetNumTcaUnits(); +int PS4_SYSV_ABI sceGnmGetOffChipTessellationBufferSize(); +int PS4_SYSV_ABI sceGnmGetOwnerName(); +int PS4_SYSV_ABI sceGnmGetPhysicalCounterFromVirtualized(); +u32 PS4_SYSV_ABI sceGnmGetProtectionFaultTimeStamp(); +int PS4_SYSV_ABI sceGnmGetResourceBaseAddressAndSizeInBytes(); +int PS4_SYSV_ABI sceGnmGetResourceName(); +int PS4_SYSV_ABI sceGnmGetResourceShaderGuid(); +int PS4_SYSV_ABI sceGnmGetResourceType(); +int PS4_SYSV_ABI sceGnmGetResourceUserData(); +int PS4_SYSV_ABI sceGnmGetShaderProgramBaseAddress(); +int PS4_SYSV_ABI sceGnmGetShaderStatus(); +VAddr PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress(); +void PS4_SYSV_ABI sceGnmGpuPaDebugEnter(); +void PS4_SYSV_ABI sceGnmGpuPaDebugLeave(); +s32 PS4_SYSV_ABI sceGnmInsertDingDongMarker(u32* cmdbuf, u32 size); +s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size); +s32 PS4_SYSV_ABI sceGnmInsertPushColorMarker(u32* cmdbuf, u32 size, const char* marker, u32 color); +s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker); +int PS4_SYSV_ABI sceGnmInsertSetColorMarker(); +s32 PS4_SYSV_ABI sceGnmInsertSetMarker(u32* cmdbuf, u32 size, const char* marker); +int PS4_SYSV_ABI sceGnmInsertThreadTraceMarker(); +s32 PS4_SYSV_ABI sceGnmInsertWaitFlipDone(u32* cmdbuf, u32 size, s32 vo_handle, u32 buf_idx); +int PS4_SYSV_ABI sceGnmIsCoredumpValid(); +bool PS4_SYSV_ABI sceGnmIsUserPaEnabled(); +int PS4_SYSV_ABI sceGnmLogicalCuIndexToPhysicalCuIndex(); +s32 PS4_SYSV_ABI sceGnmLogicalCuMaskToPhysicalCuMask(s64, s32 logical_cu_mask); +int PS4_SYSV_ABI sceGnmLogicalTcaUnitToPhysical(); +int PS4_SYSV_ABI sceGnmMapComputeQueue(u32 pipe_id, u32 queue_id, VAddr ring_base_addr, + u32 ring_size_dw, u32* read_ptr_addr); +int PS4_SYSV_ABI sceGnmMapComputeQueueWithPriority(u32 pipe_id, u32 queue_id, VAddr ring_base_addr, + u32 ring_size_dw, u32* read_ptr_addr, + u32 pipePriority); +int PS4_SYSV_ABI sceGnmPaDisableFlipCallbacks(); +int PS4_SYSV_ABI sceGnmPaEnableFlipCallbacks(); +int PS4_SYSV_ABI sceGnmPaHeartbeat(); +int PS4_SYSV_ABI sceGnmQueryResourceRegistrationUserMemoryRequirements(); +int PS4_SYSV_ABI sceGnmRaiseUserExceptionEvent(); +int PS4_SYSV_ABI sceGnmRegisterGdsResource(); +void PS4_SYSV_ABI sceGnmRegisterGnmLiveCallbackConfig(); +s32 PS4_SYSV_ABI sceGnmRegisterOwner(void* handle, const char* name); +s32 PS4_SYSV_ABI sceGnmRegisterResource(void* res_handle, void* owner_handle, const void* addr, + size_t size, const char* name, int res_type, u64 user_data); +int PS4_SYSV_ABI sceGnmRequestFlipAndSubmitDone(); +int PS4_SYSV_ABI sceGnmRequestFlipAndSubmitDoneForWorkload(); +int PS4_SYSV_ABI sceGnmRequestMipStatsReportAndReset(); +s32 PS4_SYSV_ABI sceGnmResetVgtControl(u32* cmdbuf, u32 size); +int PS4_SYSV_ABI sceGnmSdmaClose(); +int PS4_SYSV_ABI sceGnmSdmaConstFill(); +int PS4_SYSV_ABI sceGnmSdmaCopyLinear(); +int PS4_SYSV_ABI sceGnmSdmaCopyTiled(); +int PS4_SYSV_ABI sceGnmSdmaCopyWindow(); +int PS4_SYSV_ABI sceGnmSdmaFlush(); +int PS4_SYSV_ABI sceGnmSdmaGetMinCmdSize(); +int PS4_SYSV_ABI sceGnmSdmaOpen(); +s32 PS4_SYSV_ABI sceGnmSetCsShader(u32* cmdbuf, u32 size, const u32* cs_regs); +s32 PS4_SYSV_ABI sceGnmSetCsShaderWithModifier(u32* cmdbuf, u32 size, const u32* cs_regs, + u32 modifier); +s32 PS4_SYSV_ABI sceGnmSetEmbeddedPsShader(u32* cmdbuf, u32 size, u32 shader_id, + u32 shader_modifier); +s32 PS4_SYSV_ABI sceGnmSetEmbeddedVsShader(u32* cmdbuf, u32 size, u32 shader_id, u32 modifier); +s32 PS4_SYSV_ABI sceGnmSetEsShader(u32* cmdbuf, u32 size, const u32* es_regs, u32 shader_modifier); +int PS4_SYSV_ABI sceGnmSetGsRingSizes(); +s32 PS4_SYSV_ABI sceGnmSetGsShader(u32* cmdbuf, u32 size, const u32* gs_regs); +s32 PS4_SYSV_ABI sceGnmSetHsShader(u32* cmdbuf, u32 size, const u32* hs_regs, u32 param4); +s32 PS4_SYSV_ABI sceGnmSetLsShader(u32* cmdbuf, u32 size, const u32* ls_regs, u32 shader_modifier); +s32 PS4_SYSV_ABI sceGnmSetPsShader(u32* cmdbuf, u32 size, const u32* ps_regs); +s32 PS4_SYSV_ABI sceGnmSetPsShader350(u32* cmdbuf, u32 size, const u32* ps_regs); +int PS4_SYSV_ABI sceGnmSetResourceRegistrationUserMemory(); +int PS4_SYSV_ABI sceGnmSetResourceUserData(); +int PS4_SYSV_ABI sceGnmSetSpiEnableSqCounters(); +int PS4_SYSV_ABI sceGnmSetSpiEnableSqCountersForUnitInstance(); +int PS4_SYSV_ABI sceGnmSetupMipStatsReport(); +s32 PS4_SYSV_ABI sceGnmSetVgtControl(u32* cmdbuf, u32 size, u32 prim_group_sz_minus_one, + u32 partial_vs_wave_mode, u32 wd_switch_only_on_eop_mode); +s32 PS4_SYSV_ABI sceGnmSetVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, u32 shader_modifier); +int PS4_SYSV_ABI sceGnmSetWaveLimitMultiplier(); +int PS4_SYSV_ABI sceGnmSetWaveLimitMultipliers(); +int PS4_SYSV_ABI sceGnmSpmEndSpm(); +int PS4_SYSV_ABI sceGnmSpmInit(); +int PS4_SYSV_ABI sceGnmSpmInit2(); +int PS4_SYSV_ABI sceGnmSpmSetDelay(); +int PS4_SYSV_ABI sceGnmSpmSetMuxRam(); +int PS4_SYSV_ABI sceGnmSpmSetMuxRam2(); +int PS4_SYSV_ABI sceGnmSpmSetSelectCounter(); +int PS4_SYSV_ABI sceGnmSpmSetSpmSelects(); +int PS4_SYSV_ABI sceGnmSpmSetSpmSelects2(); +int PS4_SYSV_ABI sceGnmSpmStartSpm(); +int PS4_SYSV_ABI sceGnmSqttFini(); +int PS4_SYSV_ABI sceGnmSqttFinishTrace(); +int PS4_SYSV_ABI sceGnmSqttGetBcInfo(); +int PS4_SYSV_ABI sceGnmSqttGetGpuClocks(); +int PS4_SYSV_ABI sceGnmSqttGetHiWater(); +int PS4_SYSV_ABI sceGnmSqttGetStatus(); +int PS4_SYSV_ABI sceGnmSqttGetTraceCounter(); +int PS4_SYSV_ABI sceGnmSqttGetTraceWptr(); +int PS4_SYSV_ABI sceGnmSqttGetWrapCounts(); +int PS4_SYSV_ABI sceGnmSqttGetWrapCounts2(); +int PS4_SYSV_ABI sceGnmSqttGetWritebackLabels(); +int PS4_SYSV_ABI sceGnmSqttInit(); +int PS4_SYSV_ABI sceGnmSqttSelectMode(); +int PS4_SYSV_ABI sceGnmSqttSelectTarget(); +int PS4_SYSV_ABI sceGnmSqttSelectTokens(); +int PS4_SYSV_ABI sceGnmSqttSetCuPerfMask(); +int PS4_SYSV_ABI sceGnmSqttSetDceEventWrite(); +int PS4_SYSV_ABI sceGnmSqttSetHiWater(); +int PS4_SYSV_ABI sceGnmSqttSetTraceBuffer2(); +int PS4_SYSV_ABI sceGnmSqttSetTraceBuffers(); +int PS4_SYSV_ABI sceGnmSqttSetUserData(); +int PS4_SYSV_ABI sceGnmSqttSetUserdataTimer(); +int PS4_SYSV_ABI sceGnmSqttStartTrace(); +int PS4_SYSV_ABI sceGnmSqttStopTrace(); +int PS4_SYSV_ABI sceGnmSqttSwitchTraceBuffer(); +int PS4_SYSV_ABI sceGnmSqttSwitchTraceBuffer2(); +int PS4_SYSV_ABI sceGnmSqttWaitForEvent(); +s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffers(u32 count, u32* dcb_gpu_addrs[], + u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes, u32 vo_handle, + u32 buf_idx, u32 flip_mode, s64 flip_arg); +s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffersForWorkload( + u32 workload, u32 count, u32* dcb_gpu_addrs[], u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes, u32 vo_handle, u32 buf_idx, u32 flip_mode, s64 flip_arg); +s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[], + u32* dcb_sizes_in_bytes, const u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes); +s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload(u32 workload, u32 count, + const u32* dcb_gpu_addrs[], + u32* dcb_sizes_in_bytes, + const u32* ccb_gpu_addrs[], + u32* ccb_sizes_in_bytes); +s32 PS4_SYSV_ABI sceGnmSubmitDone(); +int PS4_SYSV_ABI sceGnmUnmapComputeQueue(u32 vqid); +int PS4_SYSV_ABI sceGnmUnregisterAllResourcesForOwner(); +int PS4_SYSV_ABI sceGnmUnregisterOwnerAndResources(); +int PS4_SYSV_ABI sceGnmUnregisterResource(); +s32 PS4_SYSV_ABI sceGnmUpdateGsShader(u32* cmdbuf, u32 size, const u32* gs_regs); +int PS4_SYSV_ABI sceGnmUpdateHsShader(u32* cmdbuf, u32 size, const u32* ps_regs, u32 ls_hs_config); +s32 PS4_SYSV_ABI sceGnmUpdatePsShader(u32* cmdbuf, u32 size, const u32* ps_regs); +s32 PS4_SYSV_ABI sceGnmUpdatePsShader350(u32* cmdbuf, u32 size, const u32* ps_regs); +s32 PS4_SYSV_ABI sceGnmUpdateVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, + u32 shader_modifier); +s32 PS4_SYSV_ABI sceGnmValidateCommandBuffers(); +int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics(); +int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics2(); +int PS4_SYSV_ABI sceGnmValidateDispatchCommandBuffers(); +int PS4_SYSV_ABI sceGnmValidateDrawCommandBuffers(); +int PS4_SYSV_ABI sceGnmValidateGetDiagnosticInfo(); +int PS4_SYSV_ABI sceGnmValidateGetDiagnostics(); +int PS4_SYSV_ABI sceGnmValidateGetVersion(); +bool PS4_SYSV_ABI sceGnmValidateOnSubmitEnabled(); +int PS4_SYSV_ABI sceGnmValidateResetState(); +int PS4_SYSV_ABI sceGnmValidationRegisterMemoryCheckCallback(); +int PS4_SYSV_ABI sceRazorCaptureCommandBuffersOnlyImmediate(); +int PS4_SYSV_ABI sceRazorCaptureCommandBuffersOnlySinceLastFlip(); +int PS4_SYSV_ABI sceRazorCaptureImmediate(); +int PS4_SYSV_ABI sceRazorCaptureSinceLastFlip(); +bool PS4_SYSV_ABI sceRazorIsLoaded(); +int PS4_SYSV_ABI Func_063D065A2D6359C3(); +int PS4_SYSV_ABI Func_0CABACAFB258429D(); +int PS4_SYSV_ABI Func_150CF336FC2E99A3(); +int PS4_SYSV_ABI Func_17CA687F9EE52D49(); +int PS4_SYSV_ABI Func_1870B89F759C6B45(); +int PS4_SYSV_ABI Func_26F9029EF68A955E(); +int PS4_SYSV_ABI Func_301E3DBBAB092DB0(); +int PS4_SYSV_ABI Func_30BAFE172AF17FEF(); +int PS4_SYSV_ABI Func_3E6A3E8203D95317(); +int PS4_SYSV_ABI Func_40FEEF0C6534C434(); +int PS4_SYSV_ABI Func_416B9079DE4CBACE(); +int PS4_SYSV_ABI Func_4774D83BB4DDBF9A(); +int PS4_SYSV_ABI Func_50678F1CCEEB9A00(); +int PS4_SYSV_ABI Func_54A2EC5FA4C62413(); +int PS4_SYSV_ABI Func_5A9C52C83138AE6B(); +int PS4_SYSV_ABI Func_5D22193A31EA1142(); +int PS4_SYSV_ABI Func_725A36DEBB60948D(); +int PS4_SYSV_ABI Func_8021A502FA61B9BB(); +int PS4_SYSV_ABI Func_9D002FE0FA40F0E6(); +int PS4_SYSV_ABI Func_9D297F36A7028B71(); +int PS4_SYSV_ABI Func_A2D7EC7A7BCF79B3(); +int PS4_SYSV_ABI Func_AA12A3CB8990854A(); +int PS4_SYSV_ABI Func_ADC8DDC005020BC6(); +int PS4_SYSV_ABI Func_B0A8688B679CB42D(); +int PS4_SYSV_ABI Func_B489020B5157A5FF(); +int PS4_SYSV_ABI Func_BADE7B4C199140DD(); +int PS4_SYSV_ABI Func_D1511B9DCFFB3DD9(); +int PS4_SYSV_ABI Func_D53446649B02E58E(); +int PS4_SYSV_ABI Func_D8B6E8E28E1EF0A3(); +int PS4_SYSV_ABI Func_D93D733A19DD7454(); +int PS4_SYSV_ABI Func_DE995443BC2A8317(); +int PS4_SYSV_ABI Func_DF6E9528150C23FF(); +int PS4_SYSV_ABI Func_ECB4C6BA41FE3350(); +int PS4_SYSV_ABI sceGnmDebugModuleReset(); +int PS4_SYSV_ABI sceGnmDebugReset(); +int PS4_SYSV_ABI Func_C4C328B7CF3B4171(); +int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalCommand(u32* cmdbuf, u32 size); +int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalSize(); +int PS4_SYSV_ABI sceGnmFindResources(); +int PS4_SYSV_ABI sceGnmGetResourceRegistrationBuffers(); +int PS4_SYSV_ABI sceGnmRegisterOwnerForSystem(); +int PS4_SYSV_ABI Func_1C43886B16EE5530(); +int PS4_SYSV_ABI Func_81037019ECCD0E01(); +int PS4_SYSV_ABI Func_BFB41C057478F0BF(); +int PS4_SYSV_ABI Func_E51D44DB8151238C(); +int PS4_SYSV_ABI Func_F916890425496553(); + +void RegisterLib(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::GnmDriver diff --git a/gpu/shadps4/core/libraries/gnmdriver/gnmdriver_init.h b/gpu/shadps4/core/libraries/gnmdriver/gnmdriver_init.h new file mode 100644 index 0000000..348b670 --- /dev/null +++ b/gpu/shadps4/core/libraries/gnmdriver/gnmdriver_init.h @@ -0,0 +1,542 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Libraries::GnmDriver { + +constexpr auto HwInitPacketSize = 0x100u; + +// clang-format off +constexpr std::array InitSequence{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1ffu, + 0xc0017600u, 0x46u, 0x1ffu, + 0xc0017600u, 0x87u, 0x1ffu, + 0xc0017600u, 0xc7u, 0x1ffu, + 0xc0017600u, 0x107u, 0u, + 0xc0017600u, 0x147u, 0x1ffu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6000000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, +}; +static_assert(InitSequence.size() == 0x73 + 2); + +constexpr std::array InitSequence175{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1ffu, + 0xc0017600u, 0x46u, 0x1ffu, + 0xc0017600u, 0x87u, 0x1ffu, + 0xc0017600u, 0xc7u, 0x1ffu, + 0xc0017600u, 0x107u, 0u, + 0xc0017600u, 0x147u, 0x1ffu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, +}; +static_assert(InitSequence175.size() == 0x73 + 2); + +constexpr std::array InitSequence200{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1701ffu, + 0xc0017600u, 0x46u, 0x1701fdu, + 0xc0017600u, 0x87u, 0x1701ffu, + 0xc0017600u, 0xc7u, 0x1701fdu, + 0xc0017600u, 0x107u, 0x17u, + 0xc0017600u, 0x147u, 0x1701fdu, + 0xc0017600u, 0x47u, 0x1cu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, +}; +static_assert(InitSequence200.size() == 0x76 + 2); + +constexpr std::array InitSequence200Neo{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x219u, 0xffffffffu, + 0xc0017600u, 0x21au, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1701ffu, + 0xc0017600u, 0x46u, 0x1701fdu, + 0xc0017600u, 0x87u, 0x1701ffu, + 0xc0017600u, 0xc7u, 0x1701fdu, + 0xc0017600u, 0x107u, 0x17u, + 0xc0017600u, 0x147u, 0x1701fdu, + 0xc0017600u, 0x47u, 0x1cu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, + 0xc0017900u, 0x40000258u, 0x6d007fu, +}; +static_assert(InitSequence200Neo.size() == 0x83 + 2); + +constexpr std::array InitSequence200NeoCompat{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x219u, 0xffffffffu, + 0xc0017600u, 0x21au, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1701ffu, + 0xc0017600u, 0x46u, 0x1701fdu, + 0xc0017600u, 0x87u, 0x1701ffu, + 0xc0017600u, 0xc7u, 0x1701fdu, + 0xc0017600u, 0x107u, 0x17u, + 0xc0017600u, 0x147u, 0x1701fdu, + 0xc0017600u, 0x47u, 0x1cu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, + 0xc0016900u, 0x100002aau, 0xd00ffu, +}; +static_assert(InitSequence200NeoCompat.size() == 0x83 + 2); + +constexpr std::array InitSequence350{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1701ffu, + 0xc0017600u, 0x46u, 0x1701fdu, + 0xc0017600u, 0x87u, 0x1701ffu, + 0xc0017600u, 0xc7u, 0x1701fdu, + 0xc0017600u, 0x107u, 0x17u, + 0xc0017600u, 0x147u, 0x1701fdu, + 0xc0017600u, 0x47u, 0x1cu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, + 0xc0016900u, 0x2aau, 0xffu, +}; +static_assert(InitSequence350.size() == 0x7c + 2); + +constexpr std::array InitSequence350Neo{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x219u, 0xffffffffu, + 0xc0017600u, 0x21au, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1701ffu, + 0xc0017600u, 0x46u, 0x1701fdu, + 0xc0017600u, 0x87u, 0x1701ffu, + 0xc0017600u, 0xc7u, 0x1701fdu, + 0xc0017600u, 0x107u, 0x17u, + 0xc0017600u, 0x147u, 0x1701fdu, + 0xc0017600u, 0x47u, 0x1cu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, + 0xc0017900u, 0x40000258u, 0x6d007fu, +}; +static_assert(InitSequence350Neo.size() == 0x86 + 2); + +constexpr std::array InitSequence350NeoCompat{ + // A fake preamble to mimic context reset sent by FW + 0xc0001200u, 0u, // IT_CLEAR_STATE + + // Actual init state sequence + 0xc0017600u, 0x216u, 0xffffffffu, + 0xc0017600u, 0x217u, 0xffffffffu, + 0xc0017600u, 0x219u, 0xffffffffu, + 0xc0017600u, 0x21au, 0xffffffffu, + 0xc0017600u, 0x215u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0017600u, 7u, 0x1701ffu, + 0xc0017600u, 0x46u, 0x1701fdu, + 0xc0017600u, 0x87u, 0x1701ffu, + 0xc0017600u, 0xc7u, 0x1701fdu, + 0xc0017600u, 0x107u, 0x17u, + 0xc0017600u, 0x147u, 0x1701fdu, + 0xc0017600u, 0x47u, 0x1cu, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x200u, 0xe0000000u, + 0xc0016900u, 0x100002aau, 0xd00ffu, +}; +static_assert(InitSequence350NeoCompat.size() == 0x86 + 2); + +constexpr std::array CtxInitSequence{ + 0xc0012800u, 0x80000000u, 0x80000000u, + 0xc0001200u, 0u, + 0xc0002f00u, 1u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0111000u, 0u +}; +static_assert(CtxInitSequence.size() == 0x0f); + +constexpr std::array CtxInitSequenceNeo{ + 0xc0012800u, 0x80000000u, 0x80000000u, + 0xc0001200u, 0u, + 0xc0002f00u, 1u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u, + 0xc00d1000, 0u +}; +static_assert(CtxInitSequenceNeo.size() == 0x13); + +constexpr std::array CtxInitSequence400{ + 0xc0012800u, 0x80000000u, 0x80000000u, + 0xc0001200u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0016900u, 0x2aau, 0xffu, + 0xc09e1000u, 0u, +}; +static_assert(CtxInitSequence400.size() == 0x62); + +constexpr std::array CtxInitSequence400Neo{ + 0xc0012800u, 0x80000000u, 0x80000000u, + 0xc0001200u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0017900u, 0x40000258u, 0x6d007fu, + 0xc09a1000u, 0u, +}; +static_assert(CtxInitSequence400Neo.size() == 0x66); + +constexpr std::array CtxInitSequence400NeoCompat{ + 0xc0012800u, 0x80000000u, 0x80000000u, + 0xc0001200u, 0u, + 0xc0016900u, 0x2f9u, 0x2du, + 0xc0016900u, 0x282u, 8u, + 0xc0016900u, 0x280u, 0x80008u, + 0xc0016900u, 0x281u, 0xffff0000u, + 0xc0016900u, 0x204u, 0u, + 0xc0016900u, 0x206u, 0x43fu, + 0xc0016900u, 0x83u, 0xffffu, + 0xc0016900u, 0x317u, 0x10u, + 0xc0016900u, 0x2fau, 0x3f800000u, + 0xc0016900u, 0x2fcu, 0x3f800000u, + 0xc0016900u, 0x2fbu, 0x3f800000u, + 0xc0016900u, 0x2fdu, 0x3f800000u, + 0xc0016900u, 0x202u, 0xcc0010u, + 0xc0016900u, 0x30eu, 0xffffffffu, + 0xc0016900u, 0x30fu, 0xffffffffu, + 0xc0002f00u, 1u, + 0xc0016900u, 0x1b1u, 2u, + 0xc0016900u, 0x101u, 0u, + 0xc0016900u, 0x100u, 0xffffffffu, + 0xc0016900u, 0x103u, 0u, + 0xc0016900u, 0x284u, 0u, + 0xc0016900u, 0x290u, 0u, + 0xc0016900u, 0x2aeu, 0u, + 0xc0016900u, 0x102u, 0u, + 0xc0016900u, 0x292u, 0u, + 0xc0016900u, 0x293u, 0x6020000u, + 0xc0016900u, 0x2f8u, 0u, + 0xc0016900u, 0x2deu, 0x1e9u, + 0xc0026900u, 0xebu, 0xff00ff00u, 0xff00u, + 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, + 0xc0016900u, 0x100002aau, 0xd00ffu, + 0xc09a1000u, 0u, +}; +static_assert(CtxInitSequence400Neo.size() == 0x66); +// clang-format on + +} // namespace Libraries::GnmDriver diff --git a/gpu/shadps4/core/libraries/kernel/equeue.cpp b/gpu/shadps4/core/libraries/kernel/equeue.cpp new file mode 100644 index 0000000..7ed911d --- /dev/null +++ b/gpu/shadps4/core/libraries/kernel/equeue.cpp @@ -0,0 +1,664 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include + +#include "common/assert.h" +#include "common/debug.h" +#include "common/logging/log.h" +#include "common/singleton.h" +#include "core/libraries/kernel/equeue.h" +#include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/orbis_error.h" +#include "core/libraries/kernel/posix_error.h" +#include "core/libraries/kernel/time.h" +#include "core/libraries/libs.h" + +namespace Libraries::Kernel { + +extern boost::asio::io_context io_context; +extern void KernelSignalRequest(); + +static std::unordered_map kqueues; +static constexpr auto HrTimerSpinlockThresholdNs = 1200000u; + +EqueueInternal* GetEqueue(OrbisKernelEqueue eq) { + if (!kqueues.contains(eq)) { + return nullptr; + } + return kqueues[eq]; +} + +static void HrTimerCallback(OrbisKernelEqueue eq, const OrbisKernelEvent& kevent) { + if (kqueues.contains(eq)) { + kqueues[eq]->TriggerEvent(kevent.ident, OrbisKernelEvent::Filter::HrTimer, kevent.udata); + } +} + +static void TimerCallback(OrbisKernelEqueue eq, const OrbisKernelEvent& kevent) { + if (kqueues.contains(eq) && kqueues[eq]->EventExists(kevent.ident, kevent.filter)) { + kqueues[eq]->TriggerEvent(kevent.ident, OrbisKernelEvent::Filter::Timer, kevent.udata); + if (!(kevent.flags & OrbisKernelEvent::Flags::OneShot)) { + // Reschedule the event for its next period. + kqueues[eq]->ScheduleEvent(kevent.ident, kevent.filter, TimerCallback); + } + } +} + +// Events are uniquely identified by id and filter. +bool EqueueInternal::AddEvent(EqueueEvent& event) { + // Save id and filter before event is moved into m_events. + const u64 id = event.event.ident; + const auto filter = event.event.filter; + + { + std::scoped_lock lock{m_mutex}; + + // Calculate timer interval + event.time_added = std::chrono::steady_clock::now(); + if (event.event.filter == OrbisKernelEvent::Filter::Timer) { + // Set timer interval, this is stored in milliseconds for timers. + event.timer_interval = std::chrono::milliseconds(event.event.data); + } else if (event.event.filter == OrbisKernelEvent::Filter::HrTimer) { + // Retrieve inputted time, this is stored in the bintime format. + OrbisKernelBintime* time = reinterpret_cast(event.event.data); + + // Convert the bintime format to a timespec. + OrbisKernelTimespec ts; + ts.tv_sec = time->sec; + ts.tv_nsec = (1000000000 * (time->frac >> 32)) >> 32; + + // Then use the timespec to set the timer interval. + event.timer_interval = std::chrono::nanoseconds(ts.tv_nsec + ts.tv_sec * 1000000000); + } + + // First, check if there's already an event with the same id and filter. + const auto& find_it = std::ranges::find_if(m_events, [id, filter](auto& ev) { + return ev.event.ident == id && ev.event.filter == filter; + }); + // If there is a duplicate event, we need to update that instead. + if (find_it != m_events.cend()) { + // Specifically, update user data and timer_interval. + // Trigger status and event data should remain intact. + auto& old_event = *find_it; + old_event.timer_interval = event.timer_interval; + old_event.event.udata = event.event.udata; + return true; + } + + // Clear input data from event. + event.event.data = 0; + + // Remove add flag from event + event.event.flags &= ~OrbisKernelEvent::Flags::Add; + + // Clear flag is appended to most event types internally. + if (event.event.filter != OrbisKernelEvent::Filter::User) { + event.event.flags |= OrbisKernelEvent::Flags::Clear; + } + + const auto& it = std::ranges::find(m_events, event); + if (it != m_events.cend()) { + *it = std::move(event); + } else { + m_events.emplace_back(std::move(event)); + } + } + + // Schedule callbacks for timer events + if (filter == OrbisKernelEvent::Filter::Timer) { + return this->ScheduleEvent(id, OrbisKernelEvent::Filter::Timer, TimerCallback); + } else if (filter == OrbisKernelEvent::Filter::HrTimer) { + return this->ScheduleEvent(id, OrbisKernelEvent::Filter::HrTimer, HrTimerCallback); + } + + return true; +} + +bool EqueueInternal::ScheduleEvent(u64 id, s16 filter, + void (*callback)(OrbisKernelEqueue, const OrbisKernelEvent&)) { + std::scoped_lock lock{m_mutex}; + + const auto& it = std::ranges::find_if(m_events, [id, filter](auto& ev) { + return ev.event.ident == id && ev.event.filter == filter; + }); + if (it == m_events.cend()) { + return false; + } + + const auto& event = *it; + ASSERT(event.event.filter == OrbisKernelEvent::Filter::Timer || + event.event.filter == OrbisKernelEvent::Filter::HrTimer); + + if (!it->timer) { + it->timer = std::make_unique(io_context, event.timer_interval); + } else { + // If the timer already exists we are scheduling a reoccurrence after the next period. + // Set the expiration time to the previous occurrence plus the period. + it->timer->expires_at(it->timer->expiry() + event.timer_interval); + } + + it->timer->async_wait( + [this, event_data = event.event, callback](const boost::system::error_code& ec) { + if (ec) { + if (ec != boost::system::errc::operation_canceled) { + LOG_ERROR(Kernel_Event, "Timer callback error: {}", ec.message()); + } else { + // Timer was cancelled (removed) before it triggered + LOG_DEBUG(Kernel_Event, "Timer cancelled"); + } + return; + } + callback(this->m_handle, event_data); + }); + KernelSignalRequest(); + + return true; +} + +bool EqueueInternal::RemoveEvent(u64 id, s16 filter) { + bool has_found = false; + std::scoped_lock lock{m_mutex}; + + const auto& it = std::ranges::find_if(m_events, [id, filter](auto& ev) { + return ev.event.ident == id && ev.event.filter == filter; + }); + if (it != m_events.cend()) { + m_events.erase(it); + has_found = true; + } + return has_found; +} + +int EqueueInternal::WaitForEvents(OrbisKernelEvent* ev, int num, const OrbisKernelUseconds* timo) { + if (timo != nullptr && *timo == 0) { + // Effectively acts as a poll; only events that have already + // arrived at the time of this function call can be received + return GetTriggeredEvents(ev, num); + } + const auto micros = timo ? *timo : 0u; + + if (HasSmallTimer()) { + // If a small timer is set, just wait for it to expire. + return WaitForSmallTimer(ev, num, micros); + } + + int count = 0; + + const auto predicate = [&] { + count = GetTriggeredEvents(ev, num); + return count > 0; + }; + + if (micros == 0) { + // Wait indefinitely for events + std::unique_lock lock{m_mutex}; + m_cond.wait(lock, predicate); + } else { + // Wait up until the timeout value + std::unique_lock lock{m_mutex}; + m_cond.wait_for(lock, std::chrono::microseconds(micros), predicate); + } + + return count; +} + +bool EqueueInternal::TriggerEvent(u64 ident, s16 filter, void* trigger_data) { + bool has_found = false; + { + std::scoped_lock lock{m_mutex}; + for (auto& event : m_events) { + if (event.event.ident == ident && event.event.filter == filter) { + if (filter == OrbisKernelEvent::Filter::VideoOut) { + event.TriggerDisplay(trigger_data); + } else if (filter == OrbisKernelEvent::Filter::User) { + event.TriggerUser(trigger_data); + } else if (filter == OrbisKernelEvent::Filter::Timer || + filter == OrbisKernelEvent::Filter::HrTimer) { + event.TriggerTimer(); + } else { + event.Trigger(trigger_data); + } + has_found = true; + } + } + } + m_cond.notify_one(); + return has_found; +} + +int EqueueInternal::GetTriggeredEvents(OrbisKernelEvent* ev, int num) { + int count = 0; + for (auto it = m_events.begin(); it != m_events.end();) { + if (it->IsTriggered()) { + ev[count++] = it->event; + if (it->event.flags & OrbisKernelEvent::Flags::Clear) { + it->Clear(); + } + if (it->event.flags & OrbisKernelEvent::Flags::OneShot) { + it = m_events.erase(it); + } else { + ++it; + } + + if (count == num) { + break; + } + } else { + ++it; + } + } + + return count; +} + +bool EqueueInternal::AddSmallTimer(EqueueEvent& ev) { + // Retrieve inputted time, this is stored in the bintime format + OrbisKernelBintime* time = reinterpret_cast(ev.event.data); + OrbisKernelTimespec ts; + ts.tv_sec = time->sec; + ts.tv_nsec = ((1000000000 * (time->frac >> 32)) >> 32); + + // Create the small timer + SmallTimer st; + st.event = ev.event; + st.added = std::chrono::steady_clock::now(); + st.interval = std::chrono::nanoseconds(ts.tv_nsec + ts.tv_sec * 1000000000); + { + std::scoped_lock lock{m_mutex}; + m_small_timers[st.event.ident] = std::move(st); + } + return true; +} + +int EqueueInternal::WaitForSmallTimer(OrbisKernelEvent* ev, int num, u32 micros) { + ASSERT(num >= 1); + + auto curr_clock = std::chrono::steady_clock::now(); + const auto wait_end_us = (micros == 0) ? std::chrono::steady_clock::time_point::max() + : curr_clock + std::chrono::microseconds{micros}; + int count = 0; + do { + curr_clock = std::chrono::steady_clock::now(); + { + std::scoped_lock lock{m_mutex}; + for (auto it = m_small_timers.begin(); it != m_small_timers.end() && count < num;) { + const SmallTimer& st = it->second; + + if (curr_clock - st.added >= st.interval) { + ev[count++] = st.event; + it = m_small_timers.erase(it); + } else { + ++it; + } + } + + if (count > 0) + return count; + } + std::this_thread::yield(); + } while (curr_clock < wait_end_us); + + return 0; +} + +bool EqueueInternal::EventExists(u64 id, s16 filter) { + std::scoped_lock lock{m_mutex}; + + const auto& it = std::ranges::find_if(m_events, [id, filter](auto& ev) { + return ev.event.ident == id && ev.event.filter == filter; + }); + + return it != m_events.cend(); +} + +static s32 NextEqueueHandle() { // bbport + static std::atomic next{0x40000}; + return next++; +} + +s32 PS4_SYSV_ABI posix_kqueue() { + // Reserve a file handle for the kqueue + // bbport: equeue handles come from their own range, not the file table. + s32 kqueue_handle = NextEqueueHandle(); + + // Plenty of equeue logic uses names to identify queues. + // Create a unique name for the queue we create. + char name[32]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "kqueue%i", kqueue_handle); + + // Create the queue + kqueues[kqueue_handle] = new EqueueInternal(kqueue_handle, name); + LOG_INFO(Kernel_Event, "kqueue created with name {}", name); + + // Return handle. + return kqueue_handle; +} + +// Helper method to detect supported filters. +// We don't want to allow adding events we don't handle properly. +bool SupportedEqueueFilter(OrbisKernelEvent::Filter filter) { + return filter == OrbisKernelEvent::Filter::GraphicsCore || + filter == OrbisKernelEvent::Filter::HrTimer || + filter == OrbisKernelEvent::Filter::Timer || filter == OrbisKernelEvent::Filter::User || + filter == OrbisKernelEvent::Filter::VideoOut; +} + +s32 PS4_SYSV_ABI posix_kevent(s32 handle, OrbisKernelEvent* changelist, u64 nchanges, + OrbisKernelEvent* eventlist, u64 nevents, + OrbisKernelTimespec* timeout) { + LOG_INFO(Kernel_Event, "called, eq = {}, nchanges = {}, nevents = {}", handle, nchanges, + nevents); + + // Get the equeue + if (!kqueues.contains(handle)) { + *__Error() = POSIX_EBADF; + return ORBIS_FAIL; + } + auto equeue = kqueues[handle]; + + // First step is to apply all changes in changelist. + for (u64 i = 0; i < nchanges; i++) { + auto event = changelist[i]; + if (!SupportedEqueueFilter(event.filter)) { + LOG_ERROR(Kernel_Event, "Unsupported event filter {}", + magic_enum::enum_name(event.filter)); + continue; + } + + // Check the event flags to determine the appropriate action + if (event.flags & OrbisKernelEvent::Flags::Add) { + // The caller is requesting to add an event. + EqueueEvent internal_event{}; + internal_event.event = event; + if (!equeue->AddEvent(internal_event)) { + // Failed to add event, return error. + *__Error() = POSIX_ENOMEM; + return ORBIS_FAIL; + } + } + + if (event.flags & OrbisKernelEvent::Flags::Delete) { + // The caller is requesting to remove an event. + if (!equeue->RemoveEvent(event.ident, event.filter)) { + // Failed to remove event, return error. + *__Error() = POSIX_ENOENT; + return ORBIS_FAIL; + } + } + + if (event.filter == OrbisKernelEvent::Filter::User && event.fflags == 0x1000000) { + // For user events, this fflags value indicates we need to trigger the event. + if (!equeue->TriggerEvent(event.ident, OrbisKernelEvent::Filter::User, event.udata)) { + *__Error() = POSIX_ENOENT; + return ORBIS_FAIL; + } + } else if (event.fflags != 0) { + // The title is using filter-specific flags. Right now, these are unhandled. + LOG_ERROR(Kernel_Event, "Unhandled fflags {:#x} for event filter {}", event.fflags, + magic_enum::enum_name(event.filter)); + continue; + } + } + + // Now we need to wait on the event list. + s32 count = 0; + if (nevents > 0) { + if (timeout != nullptr) { + OrbisKernelUseconds micros = (timeout->tv_sec * 1000000) + (timeout->tv_nsec / 1000); + count = equeue->WaitForEvents(eventlist, nevents, µs); + } else { + count = equeue->WaitForEvents(eventlist, nevents, nullptr); + } + } + return count; +} + +int PS4_SYSV_ABI sceKernelCreateEqueue(OrbisKernelEqueue* eq, const char* name) { + if (eq == nullptr) { + LOG_ERROR(Kernel_Event, "Event queue is null!"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + if (name == nullptr) { + LOG_ERROR(Kernel_Event, "Event queue name is null!"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + // Maximum is 32 including null terminator + static constexpr u64 MaxEventQueueNameSize = 32; + if (std::strlen(name) > MaxEventQueueNameSize) { + LOG_ERROR(Kernel_Event, "Event queue name exceeds 32 bytes!"); + return ORBIS_KERNEL_ERROR_ENAMETOOLONG; + } + + LOG_INFO(Kernel_Event, "name = {}", name); + + // Reserve a file handle for the kqueue + // bbport: equeue handles come from their own range, not the file table. + OrbisKernelEqueue kqueue_handle = NextEqueueHandle(); + + // Create the equeue + kqueues[kqueue_handle] = new EqueueInternal(kqueue_handle, name); + *eq = kqueue_handle; + + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceKernelDeleteEqueue(OrbisKernelEqueue eq) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + delete kqueues[eq]; + kqueues.erase(eq); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceKernelWaitEqueue(OrbisKernelEqueue eq, OrbisKernelEvent* ev, int num, int* out, + OrbisKernelUseconds* timo) { + HLE_TRACE; + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + auto& equeue = kqueues[eq]; + + TRACE_HINT(equeue->GetName()); + LOG_TRACE(Kernel_Event, "equeue = {} num = {}", equeue->GetName(), num); + + if (ev == nullptr) { + return ORBIS_KERNEL_ERROR_EFAULT; + } + + if (num < 1) { + *out = 0; + return ORBIS_KERNEL_ERROR_EINVAL; + } + + *out = equeue->WaitForEvents(ev, num, timo); + + if (*out == 0) { + return ORBIS_KERNEL_ERROR_ETIMEDOUT; + } + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceKernelAddHRTimerEvent(OrbisKernelEqueue eq, int id, OrbisKernelTimespec* ts, + void* udata) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + const auto total_ns = ts->tv_sec * 1000000000 + ts->tv_nsec; + + EqueueEvent event{}; + event.event.ident = id; + event.event.filter = OrbisKernelEvent::Filter::HrTimer; + event.event.flags = OrbisKernelEvent::Flags::Add | OrbisKernelEvent::Flags::OneShot; + event.event.fflags = 0; + // Data is stored as the address of a OrbisKernelBintime struct. + OrbisKernelBintime time{ts->tv_sec, ts->tv_nsec * 0x44b82fa09}; + event.event.data = reinterpret_cast(&time); + event.event.udata = udata; + + // HR timers cannot be implemented within the existing event queue architecture due to the + // slowness of the notification mechanism. For instance, a 100us timer will lose its precision + // as the trigger time drifts by +50-700%, depending on the host PC and workload. To address + // this issue, we use a spinlock for small waits (which can be adjusted using + // `HrTimerSpinlockThresholdUs`) and fall back to boost asio timers if the time to tick is + // large. Even for large delays, we truncate a small portion to complete the wait + // using the spinlock, prioritizing precision. + auto& equeue = kqueues[eq]; + if (total_ns < HrTimerSpinlockThresholdNs) { + return equeue->AddSmallTimer(event) ? ORBIS_OK : ORBIS_KERNEL_ERROR_ENOMEM; + } + + if (!equeue->AddEvent(event)) { + return ORBIS_KERNEL_ERROR_ENOMEM; + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceKernelDeleteHRTimerEvent(OrbisKernelEqueue eq, int id) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + auto& equeue = kqueues[eq]; + if (equeue->HasSmallTimer()) { + return equeue->RemoveSmallTimer(id) ? ORBIS_OK : ORBIS_KERNEL_ERROR_ENOENT; + } else { + return equeue->RemoveEvent(id, OrbisKernelEvent::Filter::HrTimer) + ? ORBIS_OK + : ORBIS_KERNEL_ERROR_ENOENT; + } +} + +int PS4_SYSV_ABI sceKernelAddTimerEvent(OrbisKernelEqueue eq, int id, OrbisKernelUseconds usec, + void* udata) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + EqueueEvent event{}; + event.event.ident = static_cast(id); + event.event.filter = OrbisKernelEvent::Filter::Timer; + event.event.flags = OrbisKernelEvent::Flags::Add; + event.event.fflags = 0; + event.event.data = usec / 1000; + event.event.udata = udata; + + auto& equeue = kqueues[eq]; + if (!equeue->AddEvent(event)) { + return ORBIS_KERNEL_ERROR_ENOMEM; + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceKernelDeleteTimerEvent(OrbisKernelEqueue eq, int id) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + return kqueues[eq]->RemoveEvent(id, OrbisKernelEvent::Filter::Timer) + ? ORBIS_OK + : ORBIS_KERNEL_ERROR_ENOENT; +} + +int PS4_SYSV_ABI sceKernelAddUserEvent(OrbisKernelEqueue eq, int id) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + EqueueEvent event{}; + event.event.ident = id; + event.event.filter = OrbisKernelEvent::Filter::User; + event.event.udata = 0; + event.event.flags = OrbisKernelEvent::Flags::Add; + event.event.fflags = 0; + event.event.data = 0; + + return kqueues[eq]->AddEvent(event) ? ORBIS_OK : ORBIS_KERNEL_ERROR_ENOMEM; +} + +int PS4_SYSV_ABI sceKernelAddUserEventEdge(OrbisKernelEqueue eq, int id) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + EqueueEvent event{}; + event.event.ident = id; + event.event.filter = OrbisKernelEvent::Filter::User; + event.event.udata = 0; + event.event.flags = OrbisKernelEvent::Flags::Add | OrbisKernelEvent::Flags::Clear; + event.event.fflags = 0; + event.event.data = 0; + + return kqueues[eq]->AddEvent(event) ? ORBIS_OK : ORBIS_KERNEL_ERROR_ENOMEM; +} + +void* PS4_SYSV_ABI sceKernelGetEventUserData(const OrbisKernelEvent* ev) { + ASSERT(ev); + return ev->udata; +} + +u64 PS4_SYSV_ABI sceKernelGetEventId(const OrbisKernelEvent* ev) { + return ev->ident; +} + +int PS4_SYSV_ABI sceKernelTriggerUserEvent(OrbisKernelEqueue eq, int id, void* udata) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + if (!kqueues[eq]->TriggerEvent(id, OrbisKernelEvent::Filter::User, udata)) { + return ORBIS_KERNEL_ERROR_ENOENT; + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceKernelDeleteUserEvent(OrbisKernelEqueue eq, int id) { + if (!kqueues.contains(eq)) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + if (!kqueues[eq]->RemoveEvent(id, OrbisKernelEvent::Filter::User)) { + return ORBIS_KERNEL_ERROR_ENOENT; + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceKernelGetEventFilter(const OrbisKernelEvent* ev) { + return ev->filter; +} + +u64 PS4_SYSV_ABI sceKernelGetEventData(const OrbisKernelEvent* ev) { + return ev->data; +} + +void RegisterEventQueue(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("nh2IFMgKTv8", "libScePosix", 1, "libkernel", posix_kqueue); + LIB_FUNCTION("RW-GEfpnsqg", "libScePosix", 1, "libkernel", posix_kevent); + LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", sceKernelCreateEqueue); + LIB_FUNCTION("jpFjmgAC5AE", "libkernel", 1, "libkernel", sceKernelDeleteEqueue); + LIB_FUNCTION("fzyMKs9kim0", "libkernel", 1, "libkernel", sceKernelWaitEqueue); + LIB_FUNCTION("vz+pg2zdopI", "libkernel", 1, "libkernel", sceKernelGetEventUserData); + LIB_FUNCTION("4R6-OvI2cEA", "libkernel", 1, "libkernel", sceKernelAddUserEvent); + LIB_FUNCTION("WDszmSbWuDk", "libkernel", 1, "libkernel", sceKernelAddUserEventEdge); + LIB_FUNCTION("R74tt43xP6k", "libkernel", 1, "libkernel", sceKernelAddHRTimerEvent); + LIB_FUNCTION("J+LF6LwObXU", "libkernel", 1, "libkernel", sceKernelDeleteHRTimerEvent); + LIB_FUNCTION("57ZK+ODEXWY", "libkernel", 1, "libkernel", sceKernelAddTimerEvent); + LIB_FUNCTION("YWQFUyXIVdU", "libkernel", 1, "libkernel", sceKernelDeleteTimerEvent); + LIB_FUNCTION("F6e0kwo4cnk", "libkernel", 1, "libkernel", sceKernelTriggerUserEvent); + LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", sceKernelDeleteUserEvent); + LIB_FUNCTION("mJ7aghmgvfc", "libkernel", 1, "libkernel", sceKernelGetEventId); + LIB_FUNCTION("23CPPI1tyBY", "libkernel", 1, "libkernel", sceKernelGetEventFilter); + LIB_FUNCTION("kwGyyjohI50", "libkernel", 1, "libkernel", sceKernelGetEventData); +} + +} // namespace Libraries::Kernel diff --git a/gpu/shadps4/core/libraries/kernel/equeue.h b/gpu/shadps4/core/libraries/kernel/equeue.h new file mode 100644 index 0000000..9b3c73c --- /dev/null +++ b/gpu/shadps4/core/libraries/kernel/equeue.h @@ -0,0 +1,197 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include "common/rdtsc.h" +#include "common/types.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Kernel { + +class EqueueInternal; +struct EqueueEvent; + +struct OrbisKernelBintime { + s64 sec; + s64 frac; +}; + +using OrbisKernelUseconds = u32; +using OrbisKernelEqueue = s64; + +struct OrbisKernelEvent { + enum Filter : s16 { + None = 0, + Read = -1, + Write = -2, + Aio = -3, + Vnode = -4, + Proc = -5, + Signal = -6, + Timer = -7, + Fs = -9, + Lio = -10, + User = -11, + Polling = -12, + VideoOut = -13, + GraphicsCore = -14, + HrTimer = -15, + }; + + enum Flags : u16 { + Add = 1u, + Delete = 2u, + Enable = 4u, + Disable = 8u, + OneShot = 0x10u, + Clear = 0x20u, + Receipt = 0x40u, + Dispatch = 0x80u, + Flag1 = 0x2000u, + System = 0xf000u, + }; + + u64 ident = 0; /* identifier for this event */ + Filter filter = Filter::None; /* filter for event */ + u16 flags = 0; + u32 fflags = 0; + u64 data = 0; + void* udata = nullptr; /* opaque user data identifier */ +}; + +struct OrbisVideoOutEventHint { + u64 event_id : 8; + u64 video_id : 8; + u64 flip_arg : 48; +}; + +struct OrbisVideoOutEventData { + u64 time : 12; + u64 count : 4; + u64 flip_arg : 48; +}; + +struct EqueueEvent { + OrbisKernelEvent event; + void* data = nullptr; + std::chrono::steady_clock::time_point time_added; + std::chrono::nanoseconds timer_interval; + std::unique_ptr timer; + + void Clear() { + is_triggered = false; + event.fflags = 0; + event.data = 0; + } + + void Trigger(void* data) { + is_triggered = true; + event.data = reinterpret_cast(data); + } + + void TriggerUser(void* data) { + is_triggered = true; + event.udata = data; + } + + void TriggerTimer() { + is_triggered = true; + event.data++; + } + + void TriggerDisplay(void* data) { + is_triggered = true; + if (data != nullptr) { + auto event_data = std::bit_cast(event.data); + auto event_hint_raw = reinterpret_cast(data); + auto event_hint = static_cast(event_hint_raw); + if (event_hint.event_id == event.ident && event.ident != 0xfe) { + auto time = Common::FencedRDTSC(); + auto counter = event_data.count; + if (counter != 0xf) { + counter++; + } + event.data = + (time & 0xfff) | (counter << 0xc) | (event_hint_raw & 0xffffffffffff0000); + } + } + } + + bool IsTriggered() const { + return is_triggered; + } + + bool operator==(const EqueueEvent& ev) const { + return ev.event.ident == event.ident && ev.event.filter == event.filter; + } + +private: + bool is_triggered = false; +}; + +class EqueueInternal { + struct SmallTimer { + OrbisKernelEvent event; + std::chrono::steady_clock::time_point added; + std::chrono::nanoseconds interval; + }; + +public: + explicit EqueueInternal(OrbisKernelEqueue handle, std::string_view name) + : m_handle(handle), m_name(name) {} + + std::string_view GetName() const { + return m_name; + } + + bool AddEvent(EqueueEvent& event); + bool ScheduleEvent(u64 id, s16 filter, + void (*callback)(OrbisKernelEqueue, const OrbisKernelEvent&)); + bool RemoveEvent(u64 id, s16 filter); + int WaitForEvents(OrbisKernelEvent* ev, int num, const OrbisKernelUseconds* timo); + bool TriggerEvent(u64 ident, s16 filter, void* trigger_data); + int GetTriggeredEvents(OrbisKernelEvent* ev, int num); + + bool AddSmallTimer(EqueueEvent& event); + bool HasSmallTimer() { + std::scoped_lock lock{m_mutex}; + return !m_small_timers.empty(); + } + bool RemoveSmallTimer(u64 id) { + if (HasSmallTimer()) { + std::scoped_lock lock{m_mutex}; + return m_small_timers.erase(id) > 0; + } + return false; + } + + int WaitForSmallTimer(OrbisKernelEvent* ev, int num, u32 micros); + + bool EventExists(u64 id, s16 filter); + +private: + OrbisKernelEqueue m_handle; + std::string m_name; + std::mutex m_mutex; + std::vector m_events; + std::condition_variable m_cond; + std::unordered_map m_small_timers; +}; + +EqueueInternal* GetEqueue(OrbisKernelEqueue eq); +u64 PS4_SYSV_ABI sceKernelGetEventData(const OrbisKernelEvent* ev); + +void RegisterEventQueue(Core::Loader::SymbolsResolver* sym); + +} // namespace Libraries::Kernel diff --git a/gpu/shadps4/core/libraries/kernel/orbis_error.h b/gpu/shadps4/core/libraries/kernel/orbis_error.h new file mode 100644 index 0000000..6ebff0b --- /dev/null +++ b/gpu/shadps4/core/libraries/kernel/orbis_error.h @@ -0,0 +1,110 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// Libkernel library +constexpr int ORBIS_KERNEL_ERROR_UNKNOWN = 0x80020000; +constexpr int ORBIS_KERNEL_ERROR_EPERM = 0x80020001; +constexpr int ORBIS_KERNEL_ERROR_ENOENT = 0x80020002; +constexpr int ORBIS_KERNEL_ERROR_ESRCH = 0x80020003; +constexpr int ORBIS_KERNEL_ERROR_EINTR = 0x80020004; +constexpr int ORBIS_KERNEL_ERROR_EIO = 0x80020005; +constexpr int ORBIS_KERNEL_ERROR_ENXIO = 0x80020006; +constexpr int ORBIS_KERNEL_ERROR_E2BIG = 0x80020007; +constexpr int ORBIS_KERNEL_ERROR_ENOEXEC = 0x80020008; +constexpr int ORBIS_KERNEL_ERROR_EBADF = 0x80020009; +constexpr int ORBIS_KERNEL_ERROR_ECHILD = 0x8002000A; +constexpr int ORBIS_KERNEL_ERROR_EDEADLK = 0x8002000B; +constexpr int ORBIS_KERNEL_ERROR_ENOMEM = 0x8002000C; +constexpr int ORBIS_KERNEL_ERROR_EACCES = 0x8002000D; +constexpr int ORBIS_KERNEL_ERROR_EFAULT = 0x8002000E; +constexpr int ORBIS_KERNEL_ERROR_ENOTBLK = 0x8002000F; +constexpr int ORBIS_KERNEL_ERROR_EBUSY = 0x80020010; +constexpr int ORBIS_KERNEL_ERROR_EEXIST = 0x80020011; +constexpr int ORBIS_KERNEL_ERROR_EXDEV = 0x80020012; +constexpr int ORBIS_KERNEL_ERROR_ENODEV = 0x80020013; +constexpr int ORBIS_KERNEL_ERROR_ENOTDIR = 0x80020014; +constexpr int ORBIS_KERNEL_ERROR_EISDIR = 0x80020015; +constexpr int ORBIS_KERNEL_ERROR_EINVAL = 0x80020016; +constexpr int ORBIS_KERNEL_ERROR_ENFILE = 0x80020017; +constexpr int ORBIS_KERNEL_ERROR_EMFILE = 0x80020018; +constexpr int ORBIS_KERNEL_ERROR_ENOTTY = 0x80020019; +constexpr int ORBIS_KERNEL_ERROR_ETXTBSY = 0x8002001A; +constexpr int ORBIS_KERNEL_ERROR_EFBIG = 0x8002001B; +constexpr int ORBIS_KERNEL_ERROR_ENOSPC = 0x8002001C; +constexpr int ORBIS_KERNEL_ERROR_ESPIPE = 0x8002001D; +constexpr int ORBIS_KERNEL_ERROR_EROFS = 0x8002001E; +constexpr int ORBIS_KERNEL_ERROR_EMLINK = 0x8002001F; +constexpr int ORBIS_KERNEL_ERROR_EPIPE = 0x80020020; +constexpr int ORBIS_KERNEL_ERROR_EDOM = 0x80020021; +constexpr int ORBIS_KERNEL_ERROR_ERANGE = 0x80020022; +constexpr int ORBIS_KERNEL_ERROR_EAGAIN = 0x80020023; +constexpr int ORBIS_KERNEL_ERROR_EWOULDBLOCK = 0x80020023; +constexpr int ORBIS_KERNEL_ERROR_EINPROGRESS = 0x80020024; +constexpr int ORBIS_KERNEL_ERROR_EALREADY = 0x80020025; +constexpr int ORBIS_KERNEL_ERROR_ENOTSOCK = 0x80020026; +constexpr int ORBIS_KERNEL_ERROR_EDESTADDRREQ = 0x80020027; +constexpr int ORBIS_KERNEL_ERROR_EMSGSIZE = 0x80020028; +constexpr int ORBIS_KERNEL_ERROR_EPROTOTYPE = 0x80020029; +constexpr int ORBIS_KERNEL_ERROR_ENOPROTOOPT = 0x8002002A; +constexpr int ORBIS_KERNEL_ERROR_EPROTONOSUPPORT = 0x8002002B; +constexpr int ORBIS_KERNEL_ERROR_ESOCKTNOSUPPORT = 0x8002002C; +constexpr int ORBIS_KERNEL_ERROR_ENOTSUP = 0x8002002D; +constexpr int ORBIS_KERNEL_ERROR_EOPNOTSUPP = 0x8002002D; +constexpr int ORBIS_KERNEL_ERROR_EPFNOSUPPORT = 0x8002002E; +constexpr int ORBIS_KERNEL_ERROR_EAFNOSUPPORT = 0x8002002F; +constexpr int ORBIS_KERNEL_ERROR_EADDRINUSE = 0x80020030; +constexpr int ORBIS_KERNEL_ERROR_EADDRNOTAVAIL = 0x80020031; +constexpr int ORBIS_KERNEL_ERROR_ENETDOWN = 0x80020032; +constexpr int ORBIS_KERNEL_ERROR_ENETUNREACH = 0x80020033; +constexpr int ORBIS_KERNEL_ERROR_ENETRESET = 0x80020034; +constexpr int ORBIS_KERNEL_ERROR_ECONNABORTED = 0x80020035; +constexpr int ORBIS_KERNEL_ERROR_ECONNRESET = 0x80020036; +constexpr int ORBIS_KERNEL_ERROR_ENOBUFS = 0x80020037; +constexpr int ORBIS_KERNEL_ERROR_EISCONN = 0x80020038; +constexpr int ORBIS_KERNEL_ERROR_ENOTCONN = 0x80020039; +constexpr int ORBIS_KERNEL_ERROR_ESHUTDOWN = 0x8002003A; +constexpr int ORBIS_KERNEL_ERROR_ETOOMANYREFS = 0x8002003B; +constexpr int ORBIS_KERNEL_ERROR_ETIMEDOUT = 0x8002003C; +constexpr int ORBIS_KERNEL_ERROR_ECONNREFUSED = 0x8002003D; +constexpr int ORBIS_KERNEL_ERROR_ELOOP = 0x8002003E; +constexpr int ORBIS_KERNEL_ERROR_ENAMETOOLONG = 0x8002003F; +constexpr int ORBIS_KERNEL_ERROR_EHOSTDOWN = 0x80020040; +constexpr int ORBIS_KERNEL_ERROR_EHOSTUNREACH = 0x80020041; +constexpr int ORBIS_KERNEL_ERROR_ENOTEMPTY = 0x80020042; +constexpr int ORBIS_KERNEL_ERROR_EPROCLIM = 0x80020043; +constexpr int ORBIS_KERNEL_ERROR_EUSERS = 0x80020044; +constexpr int ORBIS_KERNEL_ERROR_EDQUOT = 0x80020045; +constexpr int ORBIS_KERNEL_ERROR_ESTALE = 0x80020046; +constexpr int ORBIS_KERNEL_ERROR_EREMOTE = 0x80020047; +constexpr int ORBIS_KERNEL_ERROR_EBADRPC = 0x80020048; +constexpr int ORBIS_KERNEL_ERROR_ERPCMISMATCH = 0x80020049; +constexpr int ORBIS_KERNEL_ERROR_EPROGUNAVAIL = 0x8002004A; +constexpr int ORBIS_KERNEL_ERROR_EPROGMISMATCH = 0x8002004B; +constexpr int ORBIS_KERNEL_ERROR_EPROCUNAVAIL = 0x8002004C; +constexpr int ORBIS_KERNEL_ERROR_ENOLCK = 0x8002004D; +constexpr int ORBIS_KERNEL_ERROR_ENOSYS = 0x8002004E; +constexpr int ORBIS_KERNEL_ERROR_EFTYPE = 0x8002004F; +constexpr int ORBIS_KERNEL_ERROR_EAUTH = 0x80020050; +constexpr int ORBIS_KERNEL_ERROR_ENEEDAUTH = 0x80020051; +constexpr int ORBIS_KERNEL_ERROR_EIDRM = 0x80020052; +constexpr int ORBIS_KERNEL_ERROR_ENOMSG = 0x80020053; +constexpr int ORBIS_KERNEL_ERROR_EOVERFLOW = 0x80020054; +constexpr int ORBIS_KERNEL_ERROR_ECANCELED = 0x80020055; +constexpr int ORBIS_KERNEL_ERROR_EILSEQ = 0x80020056; +constexpr int ORBIS_KERNEL_ERROR_ENOATTR = 0x80020057; +constexpr int ORBIS_KERNEL_ERROR_EDOOFUS = 0x80020058; +constexpr int ORBIS_KERNEL_ERROR_EBADMSG = 0x80020059; +constexpr int ORBIS_KERNEL_ERROR_EMULTIHOP = 0x8002005A; +constexpr int ORBIS_KERNEL_ERROR_ENOLINK = 0x8002005B; +constexpr int ORBIS_KERNEL_ERROR_EPROTO = 0x8002005C; +constexpr int ORBIS_KERNEL_ERROR_ENOTCAPABLE = 0x8002005D; +constexpr int ORBIS_KERNEL_ERROR_ECAPMODE = 0x8002005E; +constexpr int ORBIS_KERNEL_ERROR_ENOBLK = 0x8002005F; +constexpr int ORBIS_KERNEL_ERROR_EICV = 0x80020060; +constexpr int ORBIS_KERNEL_ERROR_ENOPLAYGOENT = 0x80020061; +constexpr int ORBIS_KERNEL_ERROR_ESDKVERSION = 0x80020063; +constexpr int ORBIS_KERNEL_ERROR_ESTART = 0x80020064; \ No newline at end of file diff --git a/gpu/shadps4/core/libraries/kernel/posix_error.h b/gpu/shadps4/core/libraries/kernel/posix_error.h new file mode 100644 index 0000000..0f7cf3e --- /dev/null +++ b/gpu/shadps4/core/libraries/kernel/posix_error.h @@ -0,0 +1,128 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// Posix error codes +constexpr int POSIX_EPERM = 1; +constexpr int POSIX_ENOENT = 2; +constexpr int POSIX_ESRCH = 3; +constexpr int POSIX_EINTR = 4; +constexpr int POSIX_EIO = 5; +constexpr int POSIX_ENXIO = 6; +constexpr int POSIX_E2BIG = 7; +constexpr int POSIX_ENOEXEC = 8; +constexpr int POSIX_EBADF = 9; +constexpr int POSIX_ECHILD = 10; +constexpr int POSIX_EDEADLK = 11; +constexpr int POSIX_ENOMEM = 12; +constexpr int POSIX_EACCES = 13; +constexpr int POSIX_EFAULT = 14; +constexpr int POSIX_ENOTBLK = 15; +constexpr int POSIX_EBUSY = 16; +constexpr int POSIX_EEXIST = 17; +constexpr int POSIX_EXDEV = 18; +constexpr int POSIX_ENODEV = 19; +constexpr int POSIX_ENOTDIR = 20; +constexpr int POSIX_EISDIR = 21; +constexpr int POSIX_EINVAL = 22; +constexpr int POSIX_ENFILE = 23; +constexpr int POSIX_EMFILE = 24; +constexpr int POSIX_ENOTTY = 25; +constexpr int POSIX_ETXTBSY = 26; +constexpr int POSIX_EFBIG = 27; +constexpr int POSIX_ENOSPC = 28; +constexpr int POSIX_ESPIPE = 29; +constexpr int POSIX_EROFS = 30; +constexpr int POSIX_EMLINK = 31; +constexpr int POSIX_EPIPE = 32; +constexpr int POSIX_EDOM = 33; +constexpr int POSIX_ERANGE = 34; +constexpr int POSIX_EAGAIN = 35; +constexpr int POSIX_EWOULDBLOCK = 35; +constexpr int POSIX_EINPROGRESS = 36; +constexpr int POSIX_EALREADY = 37; +constexpr int POSIX_ENOTSOCK = 38; +constexpr int POSIX_EDESTADDRREQ = 39; +constexpr int POSIX_EMSGSIZE = 40; +constexpr int POSIX_EPROTOTYPE = 41; +constexpr int POSIX_ENOPROTOOPT = 42; +constexpr int POSIX_EPROTONOSUPPORT = 43; +constexpr int POSIX_ESOCKTNOSUPPORT = 44; +constexpr int POSIX_EOPNOTSUPP = 45; +constexpr int POSIX_ENOTSUP = 45; +constexpr int POSIX_EPFNOSUPPORT = 46; +constexpr int POSIX_EAFNOSUPPORT = 47; +constexpr int POSIX_EADDRINUSE = 48; +constexpr int POSIX_EADDRNOTAVAIL = 49; +constexpr int POSIX_ENETDOWN = 50; +constexpr int POSIX_ENETUNREACH = 51; +constexpr int POSIX_ENETRESET = 52; +constexpr int POSIX_ECONNABORTED = 53; +constexpr int POSIX_ECONNRESET = 54; +constexpr int POSIX_ENOBUFS = 55; +constexpr int POSIX_EISCONN = 56; +constexpr int POSIX_ENOTCONN = 57; +constexpr int POSIX_ESHUTDOWN = 58; +constexpr int POSIX_ETOOMANYREFS = 59; +constexpr int POSIX_ETIMEDOUT = 60; +constexpr int POSIX_ECONNREFUSED = 61; +constexpr int POSIX_ELOOP = 62; +constexpr int POSIX_ENAMETOOLONG = 63; +constexpr int POSIX_EHOSTDOWN = 64; +constexpr int POSIX_EHOSTUNREACH = 65; +constexpr int POSIX_ENOTEMPTY = 66; +constexpr int POSIX_EPROCLIM = 67; +constexpr int POSIX_EUSERS = 68; +constexpr int POSIX_EDQUOT = 69; +constexpr int POSIX_ESTALE = 70; +constexpr int POSIX_EREMOTE = 71; +constexpr int POSIX_EBADRPC = 72; +constexpr int POSIX_ERPCMISMATCH = 73; +constexpr int POSIX_EPROGUNAVAIL = 74; +constexpr int POSIX_EPROGMISMATCH = 75; +constexpr int POSIX_EPROCUNAVAIL = 76; +constexpr int POSIX_ENOLCK = 77; +constexpr int POSIX_ENOSYS = 78; +constexpr int POSIX_EFTYPE = 79; +constexpr int POSIX_EAUTH = 80; +constexpr int POSIX_ENEEDAUTH = 81; +constexpr int POSIX_EIDRM = 82; +constexpr int POSIX_ENOMSG = 83; +constexpr int POSIX_EOVERFLOW = 84; +constexpr int POSIX_ECANCELED = 85; +constexpr int POSIX_EILSEQ = 86; +constexpr int POSIX_ENOATTR = 87; +constexpr int POSIX_EDOOFUS = 88; +constexpr int POSIX_EBADMSG = 89; +constexpr int POSIX_EMULTIHOP = 90; +constexpr int POSIX_ENOLINK = 91; +constexpr int POSIX_EPROTO = 92; +constexpr int POSIX_ENOTCAPABLE = 93; +constexpr int POSIX_ECAPMODE = 94; +constexpr int POSIX_ENOBLK = 95; +constexpr int POSIX_EICV = 96; +constexpr int POSIX_ENOPLAYGOENT = 97; +constexpr int POSIX_EREVOKE = 98; +constexpr int POSIX_ESDKVERSION = 99; +constexpr int POSIX_ESTART = 100; +constexpr int POSIX_ESTOP = 101; +constexpr int POSIX_EINVALID2MB = 102; +constexpr int POSIX_ELAST = 102; +constexpr int POSIX_EADHOC = 160; +constexpr int POSIX_EINACTIVEDISABLED = 163; +constexpr int POSIX_ENETNODATA = 164; +constexpr int POSIX_ENETDESC = 165; +constexpr int POSIX_ENETDESCTIMEDOUT = 166; +constexpr int POSIX_ENETINTR = 167; +constexpr int POSIX_ERETURN = 205; +constexpr int POSIX_EFPOS = 152; +constexpr int POSIX_ENODATA = 1040; +constexpr int POSIX_ENOSR = 1050; +constexpr int POSIX_ENOSTR = 1051; +constexpr int POSIX_ENOTRECOVERABLE = 1056; +constexpr int POSIX_EOTHER = 1062; +constexpr int POSIX_EOWNERDEAD = 1064; +constexpr int POSIX_ETIME = 1074; diff --git a/gpu/shadps4/core/libraries/kernel/process.h b/gpu/shadps4/core/libraries/kernel/process.h new file mode 100644 index 0000000..6296fe4 --- /dev/null +++ b/gpu/shadps4/core/libraries/kernel/process.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Kernel { + +static constexpr u64 ORBIS_DBG_MAX_NAME_LENGTH = 256; + +struct OrbisModuleInfoForUnwind { + u64 st_size; + std::array name; + VAddr eh_frame_hdr_addr; + VAddr eh_frame_addr; + u64 eh_frame_size; + VAddr seg0_addr; + u64 seg0_size; +}; + +s32 PS4_SYSV_ABI sceKernelIsNeoMode(); + +s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver); + +s32 PS4_SYSV_ABI sceKernelGetModuleInfoForUnwind(VAddr addr, s32 flags, + OrbisModuleInfoForUnwind* info); + +void RegisterProcess(Core::Loader::SymbolsResolver* sym); + +} // namespace Libraries::Kernel diff --git a/gpu/shadps4/core/libraries/kernel/time.h b/gpu/shadps4/core/libraries/kernel/time.h new file mode 100644 index 0000000..d876fe7 --- /dev/null +++ b/gpu/shadps4/core/libraries/kernel/time.h @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" + +namespace Common { +class NativeClock; +} + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Kernel { + +struct OrbisKernelTimeval { + s64 tv_sec; + s64 tv_usec; +}; + +struct OrbisKernelTimezone { + s32 tz_minuteswest; + s32 tz_dsttime; +}; + +struct OrbisKernelTimespec { + s64 tv_sec; + s64 tv_nsec; + + std::chrono::system_clock::time_point TimePoint() const noexcept { + using namespace std::chrono; + const auto duration = + duration_cast(seconds{tv_sec} + nanoseconds{tv_nsec}); + return system_clock::time_point{duration}; + } +}; + +struct OrbisTimesec { + time_t t; + u32 west_sec; + u32 dst_sec; +}; + +constexpr int ORBIS_CLOCK_REALTIME = 0; +constexpr int ORBIS_CLOCK_VIRTUAL = 1; +constexpr int ORBIS_CLOCK_PROF = 2; +constexpr int ORBIS_CLOCK_MONOTONIC = 4; +constexpr int ORBIS_CLOCK_UPTIME = 5; +constexpr int ORBIS_CLOCK_UPTIME_PRECISE = 7; +constexpr int ORBIS_CLOCK_UPTIME_FAST = 8; +constexpr int ORBIS_CLOCK_REALTIME_PRECISE = 9; +constexpr int ORBIS_CLOCK_REALTIME_FAST = 10; +constexpr int ORBIS_CLOCK_MONOTONIC_PRECISE = 11; +constexpr int ORBIS_CLOCK_MONOTONIC_FAST = 12; +constexpr int ORBIS_CLOCK_SECOND = 13; +constexpr int ORBIS_CLOCK_THREAD_CPUTIME_ID = 14; +constexpr int ORBIS_CLOCK_PROCTIME = 15; +constexpr int ORBIS_CLOCK_EXT_NETWORK = 16; +constexpr int ORBIS_CLOCK_EXT_DEBUG_NETWORK = 17; +constexpr int ORBIS_CLOCK_EXT_AD_NETWORK = 18; +constexpr int ORBIS_CLOCK_EXT_RAW_NETWORK = 19; + +namespace Dev { +u64& GetInitialPtc(); + +Common::NativeClock* GetClock(); +} // namespace Dev + +u64 PS4_SYSV_ABI sceKernelGetTscFrequency(); +u64 PS4_SYSV_ABI sceKernelGetProcessTime(); +u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter(); +u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency(); +u64 PS4_SYSV_ABI sceKernelReadTsc(); +s32 PS4_SYSV_ABI sceKernelClockGettime(u32 clock_id, OrbisKernelTimespec* tp); +s32 PS4_SYSV_ABI sceKernelGettimezone(OrbisKernelTimezone* tz); +s32 PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2, time_t* seconds, + OrbisKernelTimezone* timezone, s32* dst_seconds); + +s32 PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, OrbisTimesec* st, + u64* dst_sec); +s32 PS4_SYSV_ABI sceKernelUsleep(u32 microseconds); +s32 PS4_SYSV_ABI posix_clock_gettime(u32 clock_id, OrbisKernelTimespec* ts); +s32 PS4_SYSV_ABI posix_clock_settime(s32 clock_id, OrbisKernelTimespec* tp); +s32 PS4_SYSV_ABI posix_settimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz); +s32 PS4_SYSV_ABI sceKernelSettimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz); + +void RegisterTime(Core::Loader::SymbolsResolver* sym); + +} // namespace Libraries::Kernel diff --git a/gpu/shadps4/core/libraries/system/systemservice.h b/gpu/shadps4/core/libraries/system/systemservice.h new file mode 100644 index 0000000..e3eeb21 --- /dev/null +++ b/gpu/shadps4/core/libraries/system/systemservice.h @@ -0,0 +1,612 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later +// reference +// https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/blob/master/include/orbis/_types/sys_service.h +#pragma once + +#include +#include +#include "common/types.h" +#include "userservice.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::SystemService { + +enum class OrbisSystemServiceParamId { + Lang = 1, + DateFormat = 2, + TimeFormat = 3, + TimeZone = 4, + Summertime = 5, + SystemName = 6, + GameParentalLevel = 7, + EnterButtonAssign = 1000, +}; + +enum class OrbisSystemParamDateFormat { + FmtYYYYMMDD = 0, + FmtDDMMYYYY = 1, + FmtMMDDYYYY = 2, +}; + +enum class OrbisSystemParamTimeFormat { + Fmt12Hour = 0, + Fmt24Hour = 1, +}; + +enum class OrbisSystemParamGameParentalLevel { + Off = 0, + Level01 = 1, + Level02 = 2, + Level03 = 3, + Level04 = 4, + Level05 = 5, + Level06 = 6, + Level07 = 7, + Level08 = 8, + Level09 = 9, + Level10 = 10, + Level11 = 11, +}; + +enum class OrbisSystemParamEnterButtonAssign { + Circle = 0, + Cross = 1, +}; + +enum class OrbisSystemServiceEventType { + Invalid = -1, + OnResume = 0x10000000, + GameLiveStreamingStatusUpdate = 0x10000001, + SessionInvitation = 0x10000002, + EntitlementUpdate = 0x10000003, + GameCustomData = 0x10000004, + DisplaySafeAreaUpdate = 0x10000005, + UrlOpen = 0x10000006, + LaunchApp = 0x10000007, + AppLaunchLink = 0x10000008, + AddcontentInstall = 0x10000009, + ResetVrPosition = 0x1000000a, + JoinEvent = 0x1000000b, + PlaygoLocusUpdate = 0x1000000c, + PlayTogetherHost = 0x1000000d, + ServiceEntitlementUpdate = 0x1000000e, + EyeToEyeDistanceUpdate = 0x1000000f, + JoinMatchEvent = 0x10000010, + PlayTogetherHostA = 0x10000011, + WebBrowserClosed = 0x10000012, + ControllerSettingsClosed = 0x10000013, + JoinTeamOnTeamMatchEvent = 0x10000014, + OpenShareMenu = 0x30000000 +}; + +struct OrbisSystemServiceStatus { + s32 event_num; + bool is_system_ui_overlaid; + bool is_in_background_execution; + bool is_cpu_mode7_cpu_normal; + bool is_game_live_streaming_on_air; + bool is_out_of_vr_play_area; + u8 reserved[]; +}; + +struct OrbisSystemServiceDisplaySafeAreaInfo { + float ratio; + uint8_t reserved[128]; +}; + +struct OrbisSystemServiceEvent { + OrbisSystemServiceEventType event_type; + union { + char param[8192]; + struct { + char source[1024]; + char url[4096]; + } url_open; + struct { + u32 size; + u8 arg[8188]; + } launch_app; + struct { + u32 size; + u8 arg[2020]; + } app_launch_link; + struct { + s32 user_id; + char event_id[37]; + char boot_argument[7169]; + } join_event; + struct { + Libraries::UserService::OrbisUserServiceUserId userId; + u32 np_service_label; + u8 reserved[8184]; + } service_entitlement_update; + struct { + Libraries::UserService::OrbisUserServiceUserId userId; + u32 np_service_label; + u8 reserved[8184]; + } unified_entitlement_update; + u8 reserved[8192]; + }; +}; + +bool IsSplashVisible(); + +int PS4_SYSV_ABI sceAppMessagingClearEventFlag(); +int PS4_SYSV_ABI sceAppMessagingReceiveMsg(); +int PS4_SYSV_ABI sceAppMessagingSendMsg(); +int PS4_SYSV_ABI sceAppMessagingSendMsgToShellCore(); +int PS4_SYSV_ABI sceAppMessagingSendMsgToShellUI(); +int PS4_SYSV_ABI sceAppMessagingSetEventFlag(); +int PS4_SYSV_ABI sceAppMessagingTryGetEventFlag(); +int PS4_SYSV_ABI sceAppMessagingTryReceiveMsg(); +int PS4_SYSV_ABI Func_C8E899ABEF7F64C4(); +int PS4_SYSV_ABI Func_F74BA759B9C8D2A1(); +int PS4_SYSV_ABI sceLncUtilAcquireCpuBudgetOfExtraAudioDevices(); +int PS4_SYSV_ABI sceLncUtilAcquireCpuBudgetOfImeForBigApp(); +int PS4_SYSV_ABI sceLncUtilAcquireCpuBudgetOfInGameStore(); +int PS4_SYSV_ABI sceLncUtilActivateCdlg(); +int PS4_SYSV_ABI sceLncUtilAddLocalProcess(); +int PS4_SYSV_ABI sceLncUtilBlockAppSuspend(); +int PS4_SYSV_ABI sceLncUtilBlockingGetEventForDaemon(); +int PS4_SYSV_ABI sceLncUtilContinueApp(); +int PS4_SYSV_ABI sceLncUtilCrashSyscore(); +int PS4_SYSV_ABI sceLncUtilDeactivateCdlg(); +int PS4_SYSV_ABI sceLncUtilDeclareReadyForSuspend(); +int PS4_SYSV_ABI sceLncUtilDisableSuspendNotification(); +int PS4_SYSV_ABI sceLncUtilEnableSuspendNotification(); +int PS4_SYSV_ABI sceLncUtilFinishSpecialResume(); +int PS4_SYSV_ABI sceLncUtilForceKillApp(); +int PS4_SYSV_ABI sceLncUtilForceKillLocalProcess(); +int PS4_SYSV_ABI sceLncUtilGetApp0DirPath(); +int PS4_SYSV_ABI sceLncUtilGetAppCategory(); +int PS4_SYSV_ABI sceLncUtilGetAppFocusedAppStatus(); +int PS4_SYSV_ABI sceLncUtilGetAppId(); +int PS4_SYSV_ABI sceLncUtilGetAppIdOfBigApp(); +int PS4_SYSV_ABI sceLncUtilGetAppIdOfMiniApp(); +int PS4_SYSV_ABI sceLncUtilGetAppLaunchedUser(); +int PS4_SYSV_ABI sceLncUtilGetAppStatus(); +int PS4_SYSV_ABI sceLncUtilGetAppStatusListForShellUIReboot(); +int PS4_SYSV_ABI sceLncUtilGetAppTitleId(); +int PS4_SYSV_ABI sceLncUtilGetAppType(); +int PS4_SYSV_ABI sceLncUtilGetCdlgExec(); +int PS4_SYSV_ABI sceLncUtilGetCoredumpState(); +int PS4_SYSV_ABI sceLncUtilGetDbgExecutablePath(); +int PS4_SYSV_ABI sceLncUtilGetEventForDaemon(); +int PS4_SYSV_ABI sceLncUtilGetEventForShellUI(); +int PS4_SYSV_ABI sceLncUtilGetGpuCrashFullDumpAppStatus(); +int PS4_SYSV_ABI sceLncUtilGetLocalProcessStatusList(); +int PS4_SYSV_ABI sceLncUtilGetParentSocket(); +int PS4_SYSV_ABI sceLncUtilGetResultKillApp(); +int PS4_SYSV_ABI sceLncUtilGetResultLaunchAppByTitleId(); +int PS4_SYSV_ABI sceLncUtilInitialize(); +int PS4_SYSV_ABI sceLncUtilIsActiveCdlg(); +int PS4_SYSV_ABI sceLncUtilIsAppLaunched(); +int PS4_SYSV_ABI sceLncUtilIsAppSuspended(); +int PS4_SYSV_ABI sceLncUtilIsCpuBudgetOfExtraAudioDevicesAvailable(); +int PS4_SYSV_ABI sceLncUtilIsPs2Emu(); +int PS4_SYSV_ABI sceLncUtilIsShellUiFgAndGameBgCpuMode(); +int PS4_SYSV_ABI sceLncUtilKickCoredumpOnlyProcMem(); +int PS4_SYSV_ABI sceLncUtilKillApp(); +int PS4_SYSV_ABI sceLncUtilKillAppWithReason(); +int PS4_SYSV_ABI sceLncUtilKillLocalProcess(); +int PS4_SYSV_ABI sceLncUtilLaunchApp(); +int PS4_SYSV_ABI sceLncUtilLoadExec(); +int PS4_SYSV_ABI sceLncUtilNotifyCoredumpRequestEnd(); +int PS4_SYSV_ABI sceLncUtilNotifyCoredumpRequestProgress(); +int PS4_SYSV_ABI sceLncUtilNotifyVshReady(); +int PS4_SYSV_ABI sceLncUtilRaiseException(); +int PS4_SYSV_ABI sceLncUtilRaiseExceptionLocalProcess(); +int PS4_SYSV_ABI sceLncUtilRegisterCdlgSharedMemoryName(); +int PS4_SYSV_ABI sceLncUtilRegisterDaemon(); +int PS4_SYSV_ABI sceLncUtilRegisterShellUI(); +int PS4_SYSV_ABI sceLncUtilReleaseCpuBudgetOfExtraAudioDevices(); +int PS4_SYSV_ABI sceLncUtilReleaseCpuBudgetOfImeForBigApp(); +int PS4_SYSV_ABI sceLncUtilReleaseCpuBudgetOfInGameStore(); +int PS4_SYSV_ABI sceLncUtilResumeApp(); +int PS4_SYSV_ABI sceLncUtilResumeLocalProcess(); +int PS4_SYSV_ABI sceLncUtilSetAppFocus(); +int PS4_SYSV_ABI sceLncUtilSetCdlgExec(); +int PS4_SYSV_ABI sceLncUtilSetControllerFocus(); +int PS4_SYSV_ABI sceLncUtilSetControllerFocusPermission(); +int PS4_SYSV_ABI sceLncUtilStartKillApp(); +int PS4_SYSV_ABI sceLncUtilStartLaunchAppByTitleId(); +int PS4_SYSV_ABI sceLncUtilSuspendApp(); +int PS4_SYSV_ABI sceLncUtilSuspendBackgroundApp(); +int PS4_SYSV_ABI sceLncUtilSuspendLocalProcess(); +int PS4_SYSV_ABI sceLncUtilSystemSuspend(); +int PS4_SYSV_ABI sceLncUtilTerminate(); +int PS4_SYSV_ABI sceLncUtilTryBlockAppSuspend(); +int PS4_SYSV_ABI sceLncUtilUnblockAppSuspend(); +int PS4_SYSV_ABI sceLncUtilUnregisterCdlgSharedMemoryName(); +int PS4_SYSV_ABI sceLncUtilUnregisterDaemon(); +int PS4_SYSV_ABI sceLncUtilUnregisterShellUI(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcSoft(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcSoftAbort(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcSoftGetStatus(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcSoftInit(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcSoftIsActivated(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcSoftStart(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcSoftTerm(); +int PS4_SYSV_ABI sceShellCoreUtilAccessibilityZoomLock(); +int PS4_SYSV_ABI sceShellCoreUtilAccessibilityZoomUnlock(); +int PS4_SYSV_ABI sceShellCoreUtilAcquireBgmCpuBudget(); +int PS4_SYSV_ABI sceShellCoreUtilAcquireRemotePlayCpuBudget(); +int PS4_SYSV_ABI sceShellCoreUtilAcquireSharePlayCpuBudget(); +int PS4_SYSV_ABI sceShellCoreUtilActivateAbort(); +int PS4_SYSV_ABI sceShellCoreUtilActivateGetStatus(); +int PS4_SYSV_ABI sceShellCoreUtilActivateInit(); +int PS4_SYSV_ABI sceShellCoreUtilActivateIsActivated(); +int PS4_SYSV_ABI sceShellCoreUtilActivateRecordActivation(); +int PS4_SYSV_ABI sceShellCoreUtilActivateStart(); +int PS4_SYSV_ABI sceShellCoreUtilActivateStartAsync(); +int PS4_SYSV_ABI sceShellCoreUtilActivateTerm(); +int PS4_SYSV_ABI sceShellCoreUtilChangeRunLevel(); +int PS4_SYSV_ABI sceShellCoreUtilChangeToStaffModeForIDU(); +int PS4_SYSV_ABI sceShellCoreUtilCheckerAbort(); +int PS4_SYSV_ABI sceShellCoreUtilCleanupCrashReport(); +int PS4_SYSV_ABI sceShellCoreUtilClearAppData(); +int PS4_SYSV_ABI sceShellCoreUtilClearPsnAccountInfo(); +int PS4_SYSV_ABI sceShellCoreUtilCrashReportRequestCancel(); +int PS4_SYSV_ABI sceShellCoreUtilDeclareBeginOfExternalStorageAppMove(); +int PS4_SYSV_ABI sceShellCoreUtilDeclareEndOfExternalStorageAppMove(); +int PS4_SYSV_ABI sceShellCoreUtilDeleteDiscInstalledTitleWorkaroundFile(); +int PS4_SYSV_ABI sceShellCoreUtilDeleteDownloadedHidConfigFile(); +int PS4_SYSV_ABI sceShellCoreUtilDeleteDownloadedNetEvConfigFile(); +int PS4_SYSV_ABI sceShellCoreUtilDeleteDownloadedTitleWorkaroundFile(); +int PS4_SYSV_ABI sceShellCoreUtilDeleteSmrHddDummyData(); +int PS4_SYSV_ABI sceShellCoreUtilDoFsck(); +int PS4_SYSV_ABI sceShellCoreUtilDownloadHidConfigFileFromServer(); +int PS4_SYSV_ABI sceShellCoreUtilDownloadNetEvConfigFileFromServer(); +int PS4_SYSV_ABI sceShellCoreUtilDownloadTitleWorkaroundFileFromServer(); +int PS4_SYSV_ABI sceShellCoreUtilEnterPowerLockSection(); +int PS4_SYSV_ABI sceShellCoreUtilExecuteCrashReport(); +int PS4_SYSV_ABI sceShellCoreUtilExfatFormatExternalHdd(); +int PS4_SYSV_ABI sceShellCoreUtilExitMiniApp(); +int PS4_SYSV_ABI sceShellCoreUtilExitMiniAppWithValue(); +int PS4_SYSV_ABI sceShellCoreUtilFillUpSpaceOnSmrHdd(); +int PS4_SYSV_ABI sceShellCoreUtilFormatExternalHdd(); +int PS4_SYSV_ABI sceShellCoreUtilFormatHddForRestore(); +int PS4_SYSV_ABI sceShellCoreUtilFreeUpSpaceOnSmrHdd(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppData(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppEnableTTS(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppEnterButtonAssign(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppLaunchedParamInt(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppLaunchedParamIntByBudgetType(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppLaunchedParamString(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppLaunchedParamStringByBudgetType(); +int PS4_SYSV_ABI sceShellCoreUtilGetAppLaunchTypeInfo(); +int PS4_SYSV_ABI sceShellCoreUtilGetAutoPowerDownRemainingSeconds(); +int PS4_SYSV_ABI sceShellCoreUtilGetBasicProductShape(); +int PS4_SYSV_ABI sceShellCoreUtilGetCheckerString(); +int PS4_SYSV_ABI sceShellCoreUtilGetCheckerStringEx(); +int PS4_SYSV_ABI sceShellCoreUtilGetCloudClientStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportCoreFileSetSize(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportFilterInfoStart(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportInfoForBoot(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportInfoForBootStart(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportInfoStart(); +int PS4_SYSV_ABI sceShellCoreutilGetCrashReportProcessInformation(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportResult(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetCrashReportUploadStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetDeviceIndexBehavior(); +int PS4_SYSV_ABI sceShellCoreUtilGetDeviceIndexBehaviorWithTimeout(); +int PS4_SYSV_ABI sceShellCoreUtilGetEffectiveTotalSizeOfUserPartition(); +int PS4_SYSV_ABI sceShellCoreUtilGetFreeSizeOfAvContentsTmp(); +int PS4_SYSV_ABI sceShellCoreUtilGetFreeSizeOfUserPartition(); +int PS4_SYSV_ABI sceShellCoreUtilGetFsckProgress(); +int PS4_SYSV_ABI sceShellCoreUtilGetGameLiveStreamingStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetGnmCompositorOnScreenProfilerFlag(); +int PS4_SYSV_ABI sceShellCoreUtilGetGpuLoadEmulationMode(); +int PS4_SYSV_ABI sceShellCoreUtilGetGpuLoadEmulationModeByAppId(); +int PS4_SYSV_ABI sceShellCoreUtilGetHidConfigFileInfoString(); +int PS4_SYSV_ABI sceShellCoreUtilGetHidConfigFileString(); +int PS4_SYSV_ABI sceShellCoreUtilGetHidConfigName(); +int PS4_SYSV_ABI sceShellCoreUtilGetHidConfigNum(); +int PS4_SYSV_ABI sceShellCoreUtilGetIDUMode(); +int PS4_SYSV_ABI sceShellCoreUtilGetImposeMenuFlagForPs2Emu(); +int PS4_SYSV_ABI sceShellCoreUtilGetManifestFileStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetNeedSizeOfAppContent(); +int PS4_SYSV_ABI sceShellCoreUtilGetNetEvConfigFileInfoString(); +int PS4_SYSV_ABI sceShellCoreUtilGetOptimizationStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetOutOfVrPlayZoneWarning(); +int PS4_SYSV_ABI sceShellCoreUtilGetPapcGamePcl(); +int PS4_SYSV_ABI sceShellCoreUtilGetPbtcUserInfoList(); +int PS4_SYSV_ABI sceShellCoreUtilGetPlatformPrivacyDefinitionEventData(); +int PS4_SYSV_ABI sceShellCoreUtilGetPlatformPrivacySetting(); +int PS4_SYSV_ABI sceShellCoreUtilGetProgressOfFormatExternalHdd(); +int PS4_SYSV_ABI sceShellCoreUtilGetProgressOfFsck(); +int PS4_SYSV_ABI sceShellCoreUtilGetPsnAccountInfo(); +int PS4_SYSV_ABI sceShellCoreUtilGetPsStoreIconLayout(); +int PS4_SYSV_ABI sceShellCoreUtilGetPsStoreIconState(); +int PS4_SYSV_ABI sceShellCoreUtilGetRegion(); +int PS4_SYSV_ABI sceShellCoreUtilGetRemotePlayStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetRunLevel(); +int PS4_SYSV_ABI sceShellCoreUtilGetSharePlayStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetShellUIVMStats(); +int PS4_SYSV_ABI sceShellCoreUtilGetSmrHddInfoString(); +int PS4_SYSV_ABI sceShellCoreUtilGetSocialScreenStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetSplashScreenState(); +int PS4_SYSV_ABI sceShellCoreUtilGetSupportSiteURL(); +int PS4_SYSV_ABI sceShellCoreUtilGetSuspendConfirmationDialogFlag(); +int PS4_SYSV_ABI sceShellCoreUtilGetSystemBGState(); +int PS4_SYSV_ABI sceShellCoreUtilGetSystemBGWaveColor(); +int PS4_SYSV_ABI sceShellCoreUtilGetSystemBGWaveState(); +int PS4_SYSV_ABI sceShellCoreUtilGetTitleWorkaroundFileInfoString(); +int PS4_SYSV_ABI sceShellCoreUtilGetTitleWorkaroundFileString(); +int PS4_SYSV_ABI sceShellCoreUtilGetUIStatus(); +int PS4_SYSV_ABI sceShellCoreUtilGetUserFocus(); +int PS4_SYSV_ABI sceShellCoreUtilGetUserIdOfMorpheusUser(); +int PS4_SYSV_ABI sceShellCoreUtilGetVersionNumberOfCameraCalibrationData(); +int PS4_SYSV_ABI sceShellCoreUtilGoBackToKratosCurrentSessionGame(); +int PS4_SYSV_ABI sceShellCoreUtilHideBlocksFromUser(); +int PS4_SYSV_ABI sceShellCoreUtilIncrementVersionNumberOfCameraCalibrationData(); +int PS4_SYSV_ABI sceShellCoreUtilIsAccessibilityZoomLocked(); +int PS4_SYSV_ABI sceShellCoreUtilIsBgmCpuBudgetAcquired(); +int PS4_SYSV_ABI sceShellCoreUtilIsBgmCpuBudgetAvailable(); +int PS4_SYSV_ABI sceShellCoreUtilIsBgmPlaying(); +int PS4_SYSV_ABI sceShellCoreUtilIsExternalStorageAppMoveInProgress(); +int PS4_SYSV_ABI sceShellCoreUtilIsEyeToEyeDistanceAdjusted(); +int PS4_SYSV_ABI sceShellCoreUtilIsGameLiveStreamingOnAir(); +int PS4_SYSV_ABI sceShellCoreUtilIsImposeScreenOverlaid(); +int PS4_SYSV_ABI sceShellCoreUtilIsInSystemSuspendBlackList(); +int PS4_SYSV_ABI sceShellCoreUtilIsInternalKratosUser(); +int PS4_SYSV_ABI sceShellCoreUtilIsKilledOrSuspendedByLogout(); +int PS4_SYSV_ABI sceShellCoreUtilIsNeededCrashReport(); +int PS4_SYSV_ABI sceShellCoreUtilIsPowerSaveAlertRequested(); +int PS4_SYSV_ABI sceShellCoreUtilIsRemotePlayCpuBudgetAcquired(); +int PS4_SYSV_ABI sceShellCoreUtilIsScreenSaverOn(); +int PS4_SYSV_ABI sceShellCoreUtilIsSharePlayCpuBudgetAcquired(); +int PS4_SYSV_ABI sceShellCoreUtilIsShowCrashReport(); +int PS4_SYSV_ABI sceShellCoreUtilIsTemperatureDanger(); +int PS4_SYSV_ABI sceShellCoreUtilIsTitleWorkaroundEnabled(); +int PS4_SYSV_ABI sceShellCoreUtilIsUsbMassStorageMounted(); +int PS4_SYSV_ABI sceShellCoreUtilLaunchByUri(); +int PS4_SYSV_ABI sceShellCoreUtilLeavePowerLockSection(); +int PS4_SYSV_ABI sceShellCoreUtilLog(); +int PS4_SYSV_ABI sceShellCoreUtilMakeManifestFile(); +int PS4_SYSV_ABI sceShellCoreUtilMountAppRight(); +int PS4_SYSV_ABI sceShellCoreUtilMountDownloadDataForShellUI(); +int PS4_SYSV_ABI sceShellCoreUtilMountHddForBackup(); +int PS4_SYSV_ABI sceShellCoreUtilMountHddForRestore(); +int PS4_SYSV_ABI sceShellCoreUtilNavigateToAnotherApp(); +int PS4_SYSV_ABI sceShellCoreUtilNavigateToGoHome(); +int PS4_SYSV_ABI sceShellCoreUtilNavigateToLaunchedApp(); +int PS4_SYSV_ABI sceShellCoreUtilNotificationCancelForIDU(); +int PS4_SYSV_ABI sceShellCoreUtilNotificationRequestedForIDU(); +int PS4_SYSV_ABI sceShellCoreUtilNotifyBgmCoreTermination(); +int PS4_SYSV_ABI sceShellCoreUtilNotifyFarsightUIDone(); +int PS4_SYSV_ABI sceShellCoreUtilNotifyFsReadError(); +int PS4_SYSV_ABI sceShellCoreUtilNotifyPsnAccountInfoReceived(); +int PS4_SYSV_ABI sceShellCoreUtilNotifyYouTubeAccountLinkStatusChanged(); +int PS4_SYSV_ABI sceShellCoreUtilPfAuthClientConsoleTokenClearCache(); +int PS4_SYSV_ABI sceShellCoreUtilPostActivityForPsNow(); +int PS4_SYSV_ABI sceShellCoreUtilPostErrorLog(); +int PS4_SYSV_ABI sceShellCoreUtilPostLaunchConfirmResult(); +int PS4_SYSV_ABI sceShellCoreUtilPostPsmEventToShellUI(); +int PS4_SYSV_ABI sceShellCoreUtilPreNotifyOfGameLiveStreaming(); +int PS4_SYSV_ABI sceShellCoreUtilPreNotifyOfRemotePlay(); +int PS4_SYSV_ABI sceShellCoreUtilPreNotifyOfSharePlay(); +int PS4_SYSV_ABI sceShellCoreUtilReleaseBgmCpuBudget(); +int PS4_SYSV_ABI sceShellCoreUtilReleaseRemotePlayCpuBudget(); +int PS4_SYSV_ABI sceShellCoreUtilReleaseSharePlayCpuBudget(); +int PS4_SYSV_ABI sceShellCoreUtilReportSessionErrorToGaikaiController(); +int PS4_SYSV_ABI sceShellCoreUtilReportUnexpectedFatalErrorToSystemTelemetry(); +int PS4_SYSV_ABI sceShellCoreUtilRequestCameraCalibration(); +int PS4_SYSV_ABI sceShellCoreUtilRequestEjectDevice(); +int PS4_SYSV_ABI sceShellCoreUtilRequestRebootApp(); +int PS4_SYSV_ABI sceShellCoreUtilRequestShutdown(); +int PS4_SYSV_ABI sceShellCoreUtilResetAutoPowerDownTimer(); +int PS4_SYSV_ABI sceShellCoreUtilResetBgdcConfig(); +int PS4_SYSV_ABI sceShellCoreUtilSetAppData(); +int PS4_SYSV_ABI sceShellCoreUtilSetBgmProhibition(); +int PS4_SYSV_ABI sceShellCoreUtilSetDeviceIndexBehavior(); +int PS4_SYSV_ABI sceShellCoreUtilSetGameLiveStreamingOnAirFlag(); +int PS4_SYSV_ABI sceShellCoreUtilSetGameLiveStreamingStatus(); +int PS4_SYSV_ABI sceShellCoreUtilSetGnmCompositorOnScreenProfilerFlag(); +int PS4_SYSV_ABI sceShellCoreUtilSetGpuLoadEmulationMode(); +int PS4_SYSV_ABI sceShellCoreUtilSetGpuLoadEmulationModeByAppId(); +int PS4_SYSV_ABI sceShellCoreUtilSetIDUMode(); +int PS4_SYSV_ABI sceShellCoreUtilSetImposeStatusFlag(); +int PS4_SYSV_ABI sceShellCoreUtilSetPsStoreIconLayout(); +int PS4_SYSV_ABI sceShellCoreUtilSetPsStoreIconState(); +int PS4_SYSV_ABI sceShellCoreUtilSetRemotePlayStatus(); +int PS4_SYSV_ABI sceShellCoreUtilSetSharePlayStatus(); +int PS4_SYSV_ABI sceShellCoreUtilSetSkipUpdateCheck(); +int PS4_SYSV_ABI sceShellCoreUtilSetSocialScreenStatus(); +int PS4_SYSV_ABI sceShellCoreUtilSetSplashScreenState(); +int PS4_SYSV_ABI sceShellCoreUtilSetSystemBGState(); +int PS4_SYSV_ABI sceShellCoreUtilSetSystemBGWaveColor(); +int PS4_SYSV_ABI sceShellCoreUtilSetSystemBGWaveState(); +int PS4_SYSV_ABI sceShellCoreUtilSetUIStatus(); +int PS4_SYSV_ABI sceShellCoreUtilSetUserFocus(); +int PS4_SYSV_ABI sceShellCoreUtilShowCriticalErrorDialog(); +int PS4_SYSV_ABI sceShellCoreUtilShowErrorDialog(); +int PS4_SYSV_ABI sceShellCoreUtilShowErrorDialogWithFormatArgs(); +int PS4_SYSV_ABI sceShellCoreUtilShowErrorDialogWithParam(); +int PS4_SYSV_ABI sceShellCoreUtilShowPsUnderLockIndicator(); +int PS4_SYSV_ABI sceShellCoreUtilSignalUserInput(); +int PS4_SYSV_ABI sceShellCoreUtilStartOptimization(); +int PS4_SYSV_ABI sceShellCoreUtilStartPsNowGame(); +int PS4_SYSV_ABI sceShellCoreUtilStopOptimization(); +int PS4_SYSV_ABI sceShellCoreUtilStopPsNowGame(); +int PS4_SYSV_ABI sceShellCoreUtilTestBusTransferSpeed(); +int PS4_SYSV_ABI sceShellCoreUtilTickHeartBeat(); +int PS4_SYSV_ABI sceShellCoreUtilTriggerPapcRecalculation(); +int PS4_SYSV_ABI sceShellCoreUtilTriggerPapcUpdate(); +int PS4_SYSV_ABI sceShellCoreUtilTurnOffScreenSaver(); +int PS4_SYSV_ABI sceShellCoreUtilUnmountAppRight(); +int PS4_SYSV_ABI sceShellCoreUtilUnmountDownloadDataForShellUI(); +int PS4_SYSV_ABI sceShellCoreUtilUnmountHddForBackup(); +int PS4_SYSV_ABI sceShellCoreUtilUnmountHddForRestore(); +int PS4_SYSV_ABI sceShellCoreUtilWriteSmrHddDummyData(); +int PS4_SYSV_ABI Func_1E5CA5A71FA7F028(); +int PS4_SYSV_ABI Func_6D43644F75C38346(); +int PS4_SYSV_ABI Func_739FB849CB28F445(); +int PS4_SYSV_ABI Func_B20628FF35C74111(); +int PS4_SYSV_ABI sceSystemServiceAddLocalProcessForJvm(); +int PS4_SYSV_ABI sceSystemServiceGetParentSocketForJvm(); +int PS4_SYSV_ABI sceSystemServiceKillLocalProcessForJvm(); +int PS4_SYSV_ABI sceSystemServiceAcquireFb0(); +int PS4_SYSV_ABI sceSystemServiceAddLocalProcess(); +int PS4_SYSV_ABI sceSystemServiceAddLocalProcessForPsmKit(); +int PS4_SYSV_ABI sceSystemServiceChangeAcpClock(); +int PS4_SYSV_ABI sceSystemServiceChangeCpuClock(); +int PS4_SYSV_ABI sceSystemServiceChangeGpuClock(); +int PS4_SYSV_ABI sceSystemServiceChangeMemoryClock(); +int PS4_SYSV_ABI sceSystemServiceChangeMemoryClockToBaseMode(); +int PS4_SYSV_ABI sceSystemServiceChangeMemoryClockToDefault(); +int PS4_SYSV_ABI sceSystemServiceChangeMemoryClockToMultiMediaMode(); +int PS4_SYSV_ABI sceSystemServiceChangeNumberOfGpuCu(); +int PS4_SYSV_ABI sceSystemServiceChangeSamuClock(); +int PS4_SYSV_ABI sceSystemServiceChangeUvdClock(); +int PS4_SYSV_ABI sceSystemServiceChangeVceClock(); +int PS4_SYSV_ABI sceSystemServiceDisableMusicPlayer(); +int PS4_SYSV_ABI sceSystemServiceDisablePersonalEyeToEyeDistanceSetting(); +int PS4_SYSV_ABI sceSystemServiceDisableSuspendConfirmationDialog(); +int PS4_SYSV_ABI sceSystemServiceEnablePersonalEyeToEyeDistanceSetting(); +int PS4_SYSV_ABI sceSystemServiceEnableSuspendConfirmationDialog(); +int PS4_SYSV_ABI sceSystemServiceGetAppFocusedAppStatus(); +int PS4_SYSV_ABI sceSystemServiceGetAppIdOfBigApp(); +int PS4_SYSV_ABI sceSystemServiceGetAppIdOfMiniApp(); +int PS4_SYSV_ABI sceSystemServiceGetAppStatus(); +int PS4_SYSV_ABI sceSystemServiceGetAppType(); +s32 PS4_SYSV_ABI +sceSystemServiceGetDisplaySafeAreaInfo(OrbisSystemServiceDisplaySafeAreaInfo* info); +int PS4_SYSV_ABI sceSystemServiceGetEventForDaemon(); +int PS4_SYSV_ABI sceSystemServiceGetGpuLoadEmulationMode(); +int PS4_SYSV_ABI sceSystemServiceGetHdrToneMapLuminance(); +int PS4_SYSV_ABI sceSystemServiceGetLocalProcessStatusList(); +int PS4_SYSV_ABI sceSystemServiceGetParentSocket(); +int PS4_SYSV_ABI sceSystemServiceGetParentSocketForPsmKit(); +int PS4_SYSV_ABI sceSystemServiceGetPSButtonEvent(); +int PS4_SYSV_ABI sceSystemServiceGetRenderingMode(); +s32 PS4_SYSV_ABI sceSystemServiceGetStatus(OrbisSystemServiceStatus* status); +int PS4_SYSV_ABI sceSystemServiceGetTitleWorkaroundInfo(); +int PS4_SYSV_ABI sceSystemServiceGetVersionNumberOfCameraCalibrationData(); +s32 PS4_SYSV_ABI sceSystemServiceHideSplashScreen(); +int PS4_SYSV_ABI sceSystemServiceIsAppSuspended(); +int PS4_SYSV_ABI sceSystemServiceIsBgmPlaying(); +int PS4_SYSV_ABI sceSystemServiceIsEyeToEyeDistanceAdjusted(); +int PS4_SYSV_ABI sceSystemServiceIsScreenSaverOn(); +int PS4_SYSV_ABI sceSystemServiceIsShellUiFgAndGameBgCpuMode(); +int PS4_SYSV_ABI sceSystemServiceKillApp(); +int PS4_SYSV_ABI sceSystemServiceKillLocalProcess(); +int PS4_SYSV_ABI sceSystemServiceKillLocalProcessForPsmKit(); +int PS4_SYSV_ABI sceSystemServiceLaunchApp(); +int PS4_SYSV_ABI sceSystemServiceLaunchEventDetails(); +int PS4_SYSV_ABI sceSystemServiceLaunchTournamentList(); +int PS4_SYSV_ABI sceSystemServiceLaunchTournamentsTeamProfile(); +int PS4_SYSV_ABI sceSystemServiceLaunchWebBrowser(); +int PS4_SYSV_ABI sceSystemServiceLoadExec(const char* path, const char* argv[]); +int PS4_SYSV_ABI sceSystemServiceNavigateToAnotherApp(); +int PS4_SYSV_ABI sceSystemServiceNavigateToGoBack(); +int PS4_SYSV_ABI sceSystemServiceNavigateToGoBackWithValue(); +int PS4_SYSV_ABI sceSystemServiceNavigateToGoHome(); +s32 PS4_SYSV_ABI sceSystemServiceParamGetInt(OrbisSystemServiceParamId param_id, int* value); +int PS4_SYSV_ABI sceSystemServiceParamGetString(); +int PS4_SYSV_ABI sceSystemServicePowerTick(); +int PS4_SYSV_ABI sceSystemServiceRaiseExceptionLocalProcess(); +s32 PS4_SYSV_ABI sceSystemServiceReceiveEvent(OrbisSystemServiceEvent* event); +int PS4_SYSV_ABI sceSystemServiceReenableMusicPlayer(); +int PS4_SYSV_ABI sceSystemServiceRegisterDaemon(); +int PS4_SYSV_ABI sceSystemServiceReleaseFb0(); +int PS4_SYSV_ABI sceSystemServiceReportAbnormalTermination(); +int PS4_SYSV_ABI sceSystemServiceRequestCameraCalibration(); +int PS4_SYSV_ABI sceSystemServiceRequestToChangeRenderingMode(); +int PS4_SYSV_ABI sceSystemServiceResumeLocalProcess(); +int PS4_SYSV_ABI sceSystemServiceSetControllerFocusPermission(); +int PS4_SYSV_ABI sceSystemServiceSetGpuLoadEmulationMode(); +int PS4_SYSV_ABI sceSystemServiceSetOutOfVrPlayAreaFlag(); +int PS4_SYSV_ABI sceSystemServiceSetOutOfVrPlayZoneWarning(); +int PS4_SYSV_ABI sceSystemServiceShowControllerSettings(); +int PS4_SYSV_ABI sceSystemServiceShowDisplaySafeAreaSettings(); +int PS4_SYSV_ABI sceSystemServiceShowEyeToEyeDistanceSetting(); +int PS4_SYSV_ABI sceSystemServiceSuspendBackgroundApp(); +int PS4_SYSV_ABI sceSystemServiceSuspendLocalProcess(); +int PS4_SYSV_ABI sceSystemServiceTickVideoPlayback(); +int PS4_SYSV_ABI sceSystemServiceTurnOffScreenSaver(); +int PS4_SYSV_ABI Func_9031A344CB540F1A(); +int PS4_SYSV_ABI Func_A9D4CF2568EAB837(); +int PS4_SYSV_ABI sceSystemServiceLaunchWebApp(); +int PS4_SYSV_ABI Func_B8495C766861FDCF(); +int PS4_SYSV_ABI sceSystemServiceGetDbgExecutablePath(); +int PS4_SYSV_ABI sceSystemServiceActivateHevc(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcAbort(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcGetStatus(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcInit(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcIsActivated(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcStart(); +int PS4_SYSV_ABI sceSystemServiceActivateHevcTerm(); +int PS4_SYSV_ABI sceSystemServiceActivateMpeg2Abort(); +int PS4_SYSV_ABI sceSystemServiceActivateMpeg2GetStatus(); +int PS4_SYSV_ABI sceSystemServiceActivateMpeg2Init(); +int PS4_SYSV_ABI sceSystemServiceActivateMpeg2IsActivated(); +int PS4_SYSV_ABI sceSystemServiceActivateMpeg2Start(); +int PS4_SYSV_ABI sceSystemServiceActivateMpeg2Term(); +int PS4_SYSV_ABI sceSystemStateMgrCancelShutdownTimer(); +int PS4_SYSV_ABI sceSystemStateMgrEnterMediaPlaybackMode(); +int PS4_SYSV_ABI sceSystemStateMgrEnterStandby(); +int PS4_SYSV_ABI sceSystemStateMgrExtendShutdownTimer(); +int PS4_SYSV_ABI sceSystemStateMgrExtendShutdownTimerForPostAutoUpdateProcess(); +int PS4_SYSV_ABI sceSystemStateMgrGetCurrentState(); +int PS4_SYSV_ABI sceSystemStateMgrGetTriggerCode(); +int PS4_SYSV_ABI sceSystemStateMgrIsBdDriveReady(); +int PS4_SYSV_ABI sceSystemStateMgrIsGpuPerformanceNormal(); +int PS4_SYSV_ABI sceSystemStateMgrIsShellUIShutdownInProgress(); +int PS4_SYSV_ABI sceSystemStateMgrIsStandbyModeEnabled(); +int PS4_SYSV_ABI sceSystemStateMgrLeaveMediaPlaybackMode(); +int PS4_SYSV_ABI sceSystemStateMgrNotifySystemSuspendResumeProgress(); +int PS4_SYSV_ABI sceSystemStateMgrReboot(); +int PS4_SYSV_ABI sceSystemStateMgrSendCecOneTouchPlayCommand(); +int PS4_SYSV_ABI sceSystemStateMgrStartRebootTimer(); +int PS4_SYSV_ABI sceSystemStateMgrStartShutdownTimer(); +int PS4_SYSV_ABI sceSystemStateMgrStartStadbyTimer(); +int PS4_SYSV_ABI sceSystemStateMgrStartVshAutoUpdateTimer(); +int PS4_SYSV_ABI sceSystemStateMgrTickMusicPlayback(); +int PS4_SYSV_ABI sceSystemStateMgrTickPartyChat(); +int PS4_SYSV_ABI sceSystemStateMgrTurnOff(); +int PS4_SYSV_ABI sceSystemStateMgrVshAutoUpdate(); +int PS4_SYSV_ABI sceSystemStateMgrWaitVshAutoUpdateVerifyDone(); +int PS4_SYSV_ABI sceSystemStateMgrWakeUp(); +int PS4_SYSV_ABI Func_89F262179C22B49E(); +int PS4_SYSV_ABI Func_AC8A8FAB4A1696B8(); +int PS4_SYSV_ABI sceSystemServiceInvokeAppLaunchLink(); +int PS4_SYSV_ABI sceSystemServiceShowClosedCaptionAdvancedSettings(); +int PS4_SYSV_ABI sceSystemServiceShowClosedCaptionSettings(); +int PS4_SYSV_ABI sceSystemServiceSetPowerSaveLevel(); +int PS4_SYSV_ABI sceSystemServiceInitializeForShellCore(); +int PS4_SYSV_ABI Func_7C1183FC73629929(); +int PS4_SYSV_ABI sceSystemServiceDisablePartyVoice(); +int PS4_SYSV_ABI sceSystemServiceReenablePartyVoice(); +int PS4_SYSV_ABI sceSystemServiceGetPlatformPrivacyDefinitionData(); +int PS4_SYSV_ABI sceSystemServiceGetPlatformPrivacyDefinitionVersion(); +int PS4_SYSV_ABI sceSystemServiceGetPlatformPrivacySetting(); +int PS4_SYSV_ABI sceSystemServiceDeclareReadyForSuspend(); +int PS4_SYSV_ABI sceSystemServiceDisableSuspendNotification(); +int PS4_SYSV_ABI sceSystemServiceEnableSuspendNotification(); +int PS4_SYSV_ABI sceSystemServiceRequestPowerOff(); +int PS4_SYSV_ABI sceSystemServiceRequestReboot(); +int PS4_SYSV_ABI sceSystemServiceAddLocalProcessForPs2Emu(); +int PS4_SYSV_ABI sceSystemServiceGetParentSocketForPs2Emu(); +int PS4_SYSV_ABI sceSystemServiceKillLocalProcessForPs2Emu(); +int PS4_SYSV_ABI sceSystemServiceShowImposeMenuForPs2Emu(); +int PS4_SYSV_ABI sceSystemServiceSaveVideoToken(); +int PS4_SYSV_ABI sceSystemServiceLaunchStore(); +int PS4_SYSV_ABI sceSystemServiceTelemetrySetData(); +int PS4_SYSV_ABI Func_C67FC780F5B6F71E(); +int PS4_SYSV_ABI sceSystemServiceLaunchUdsApp(); +int PS4_SYSV_ABI sceSystemServiceLoadExecVideoServiceWebApp(); +int PS4_SYSV_ABI sceSystemServiceDisableVoiceRecognition(); +int PS4_SYSV_ABI sceSystemServiceReenableVoiceRecognition(); +int PS4_SYSV_ABI Func_6B1CDB955F0EBD65(); +int PS4_SYSV_ABI Func_CB5E885E225F69F0(); + +void PushSystemServiceEvent(const OrbisSystemServiceEvent& event); + +void RegisterLib(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::SystemService diff --git a/gpu/shadps4/core/libraries/system/userservice.h b/gpu/shadps4/core/libraries/system/userservice.h new file mode 100644 index 0000000..799bf89 --- /dev/null +++ b/gpu/shadps4/core/libraries/system/userservice.h @@ -0,0 +1,487 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later +// reference : +// https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/blob/master/include/orbis/_types/user.h +#pragma once + +#include "common/types.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::UserService { + +// Maximum number of users that can be logged in at once +constexpr int ORBIS_USER_SERVICE_MAX_LOGIN_USERS = 4; +// Maximum number of users that can be registered in the system +constexpr int ORBIS_USER_SERVICE_MAX_REGISTER_USERS = 16; +// Maximum user name length +constexpr int ORBIS_USER_SERVICE_MAX_USER_NAME_LENGTH = 16; + +constexpr int ORBIS_USER_SERVICE_USER_ID_SYSTEM = 0xFF; +constexpr int ORBIS_USER_SERVICE_USER_ID_INVALID = -1; + +using OrbisUserServiceUserId = s32; + +constexpr int ORBIS_KERNEL_PRIO_FIFO_LOWEST = 0x2FF; +constexpr int ORBIS_KERNEL_PRIO_FIFO_NORMAL = 0x2BC; +constexpr int ORBIS_KERNEL_PRIO_FIFO_HIGHEST = 0x100; + +struct OrbisUserServiceInitializeParams { + s32 priority; +}; + +struct OrbisUserServiceLoginUserIdList { + int user_id[ORBIS_USER_SERVICE_MAX_LOGIN_USERS]; +}; + +struct OrbisUserServiceRegisteredUserIdList { + OrbisUserServiceUserId userId[ORBIS_USER_SERVICE_MAX_REGISTER_USERS]; +}; + +enum class OrbisUserServiceUserColor { + Blue = 0, + Red = 1, + Green = 2, + Pink = 3, +}; + +enum class OrbisUserServiceEventType { + Login = 0, // Login event + Logout = 1, // Logout event +}; + +struct OrbisUserServiceEvent { + OrbisUserServiceEventType event; + OrbisUserServiceUserId userId; +}; + +void AddUserServiceEvent(const OrbisUserServiceEvent e); + +int PS4_SYSV_ABI sceUserServiceInitializeForShellCore(); +int PS4_SYSV_ABI sceUserServiceTerminateForShellCore(); +int PS4_SYSV_ABI sceUserServiceDestroyUser(); +int PS4_SYSV_ABI sceUserServiceGetAccessibilityKeyremapData(); +int PS4_SYSV_ABI sceUserServiceGetAccessibilityKeyremapEnable(); +int PS4_SYSV_ABI sceUserServiceGetAccessibilityPressAndHoldDelay(); +int PS4_SYSV_ABI sceUserServiceGetAccessibilityVibration(); +int PS4_SYSV_ABI sceUserServiceGetAccessibilityZoom(); +int PS4_SYSV_ABI sceUserServiceGetAccessibilityZoomEnabled(); +int PS4_SYSV_ABI sceUserServiceGetAccountRemarks(); +int PS4_SYSV_ABI sceUserServiceGetAgeVerified(); +int PS4_SYSV_ABI sceUserServiceGetAppearOfflineSetting(); +int PS4_SYSV_ABI sceUserServiceGetAppSortOrder(); +int PS4_SYSV_ABI sceUserServiceGetAutoLoginEnabled(); +int PS4_SYSV_ABI sceUserServiceGetCreatedVersion(); +int PS4_SYSV_ABI sceUserServiceGetCurrentUserGroupIndex(); +int PS4_SYSV_ABI sceUserServiceGetDefaultNewUserGroupName(); +int PS4_SYSV_ABI sceUserServiceGetDeletedUserInfo(); +int PS4_SYSV_ABI sceUserServiceGetDiscPlayerFlag(); +int PS4_SYSV_ABI sceUserServiceGetEvent(OrbisUserServiceEvent* event); +int PS4_SYSV_ABI sceUserServiceGetEventCalendarType(); +int PS4_SYSV_ABI sceUserServiceGetEventFilterTeamEvent(); +int PS4_SYSV_ABI sceUserServiceGetEventSortEvent(); +int PS4_SYSV_ABI sceUserServiceGetEventSortTitle(); +int PS4_SYSV_ABI sceUserServiceGetEventUiFlag(); +int PS4_SYSV_ABI sceUserServiceGetEventVsh(); +int PS4_SYSV_ABI sceUserServiceGetFaceRecognitionDeleteCount(); +int PS4_SYSV_ABI sceUserServiceGetFaceRecognitionRegisterCount(); +int PS4_SYSV_ABI sceUserServiceGetFileBrowserFilter(); +int PS4_SYSV_ABI sceUserServiceGetFileBrowserSortContent(); +int PS4_SYSV_ABI sceUserServiceGetFileBrowserSortTitle(); +int PS4_SYSV_ABI sceUserServiceGetFileSelectorFilter(); +int PS4_SYSV_ABI sceUserServiceGetFileSelectorSortContent(); +int PS4_SYSV_ABI sceUserServiceGetFileSelectorSortTitle(); +int PS4_SYSV_ABI sceUserServiceGetForegroundUser(); +int PS4_SYSV_ABI sceUserServiceGetFriendCustomListLastFocus(); +int PS4_SYSV_ABI sceUserServiceGetFriendFlag(); +int PS4_SYSV_ABI sceUserServiceGetGlsAccessTokenNiconicoLive(); +int PS4_SYSV_ABI sceUserServiceGetGlsAccessTokenTwitch(); +int PS4_SYSV_ABI sceUserServiceGetGlsAccessTokenUstream(); +int PS4_SYSV_ABI sceUserServiceGetGlsAnonymousUserId(); +int PS4_SYSV_ABI sceUserServiceGetGlsBcTags(); +int PS4_SYSV_ABI sceUserServiceGetGlsBcTitle(); +int PS4_SYSV_ABI sceUserServiceGetGlsBroadcastChannel(); +int PS4_SYSV_ABI sceUserServiceGetGlsBroadcastersComment(); +int PS4_SYSV_ABI sceUserServiceGetGlsBroadcastersCommentColor(); +int PS4_SYSV_ABI sceUserServiceGetGlsBroadcastService(); +int PS4_SYSV_ABI sceUserServiceGetGlsBroadcastUiLayout(); +int PS4_SYSV_ABI sceUserServiceGetGlsCamCrop(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraBgFilter(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraBrightness(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraChromaKeyLevel(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraContrast(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraDepthLevel(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraEdgeLevel(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraEffect(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraEliminationLevel(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraPosition(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraReflection(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraSize(); +int PS4_SYSV_ABI sceUserServiceGetGlsCameraTransparency(); +int PS4_SYSV_ABI sceUserServiceGetGlsCommunityId(); +int PS4_SYSV_ABI sceUserServiceGetGlsFloatingMessage(); +int PS4_SYSV_ABI sceUserServiceGetGlsHintFlag(); +int PS4_SYSV_ABI sceUserServiceGetGlsInitSpectating(); +int PS4_SYSV_ABI sceUserServiceGetGlsIsCameraHidden(); +int PS4_SYSV_ABI sceUserServiceGetGlsIsFacebookEnabled(); +int PS4_SYSV_ABI sceUserServiceGetGlsIsMuteEnabled(); +int PS4_SYSV_ABI sceUserServiceGetGlsIsRecDisabled(); +int PS4_SYSV_ABI sceUserServiceGetGlsIsRecievedMessageHidden(); +int PS4_SYSV_ABI sceUserServiceGetGlsIsTwitterEnabled(); +int PS4_SYSV_ABI sceUserServiceGetGlsLanguageFilter(); +int PS4_SYSV_ABI sceUserServiceGetGlsLfpsSortOrder(); +int PS4_SYSV_ABI sceUserServiceGetGlsLiveQuality(); +int PS4_SYSV_ABI sceUserServiceGetGlsLiveQuality2(); +int PS4_SYSV_ABI sceUserServiceGetGlsLiveQuality3(); +int PS4_SYSV_ABI sceUserServiceGetGlsLiveQuality4(); +int PS4_SYSV_ABI sceUserServiceGetGlsLiveQuality5(); +int PS4_SYSV_ABI sceUserServiceGetGlsMessageFilterLevel(); +int PS4_SYSV_ABI sceUserServiceGetGlsTtsFlags(); +int PS4_SYSV_ABI sceUserServiceGetGlsTtsPitch(); +int PS4_SYSV_ABI sceUserServiceGetGlsTtsSpeed(); +int PS4_SYSV_ABI sceUserServiceGetGlsTtsVolume(); +int PS4_SYSV_ABI sceUserServiceGetHmuBrightness(); +int PS4_SYSV_ABI sceUserServiceGetHmuZoom(); +int PS4_SYSV_ABI sceUserServiceGetHoldAudioOutDevice(); +int PS4_SYSV_ABI sceUserServiceGetHomeDirectory(); +int PS4_SYSV_ABI sceUserServiceGetImeAutoCapitalEnabled(); +int PS4_SYSV_ABI sceUserServiceGetImeInitFlag(); +int PS4_SYSV_ABI sceUserServiceGetImeInputType(); +int PS4_SYSV_ABI sceUserServiceGetImeLastUnit(); +int PS4_SYSV_ABI sceUserServiceGetImePointerMode(); +int PS4_SYSV_ABI sceUserServiceGetImePredictiveTextEnabled(); +int PS4_SYSV_ABI sceUserServiceGetImeRunCount(); +s32 PS4_SYSV_ABI sceUserServiceGetInitialUser(int* user_id); +int PS4_SYSV_ABI sceUserServiceGetIPDLeft(); +int PS4_SYSV_ABI sceUserServiceGetIPDRight(); +int PS4_SYSV_ABI sceUserServiceGetIsFakePlus(); +int PS4_SYSV_ABI sceUserServiceGetIsQuickSignup(); +int PS4_SYSV_ABI sceUserServiceGetIsRemotePlayAllowed(); +int PS4_SYSV_ABI sceUserServiceGetJapaneseInputType(); +int PS4_SYSV_ABI sceUserServiceGetKeyboardType(); +int PS4_SYSV_ABI sceUserServiceGetKeyRepeatSpeed(); +int PS4_SYSV_ABI sceUserServiceGetKeyRepeatStartingTime(); +int PS4_SYSV_ABI sceUserServiceGetKratosPrimaryUser(); +int PS4_SYSV_ABI sceUserServiceGetLastLoginOrder(); +int PS4_SYSV_ABI sceUserServiceGetLightBarBaseBrightness(); +int PS4_SYSV_ABI sceUserServiceGetLoginFlag(); +s32 PS4_SYSV_ABI sceUserServiceGetLoginUserIdList(OrbisUserServiceLoginUserIdList* userIdList); +int PS4_SYSV_ABI sceUserServiceGetMicLevel(); +int PS4_SYSV_ABI sceUserServiceGetMouseHandType(); +int PS4_SYSV_ABI sceUserServiceGetMousePointerSpeed(); +int PS4_SYSV_ABI sceUserServiceGetNotificationBehavior(); +int PS4_SYSV_ABI sceUserServiceGetNotificationSettings(); +int PS4_SYSV_ABI sceUserServiceGetNpAccountId(); +int PS4_SYSV_ABI sceUserServiceGetNpAccountUpgradeFlag(); +int PS4_SYSV_ABI sceUserServiceGetNpAge(); +int PS4_SYSV_ABI sceUserServiceGetNpAuthErrorFlag(); +int PS4_SYSV_ABI sceUserServiceGetNpCountryCode(); +int PS4_SYSV_ABI sceUserServiceGetNpDateOfBirth(); +int PS4_SYSV_ABI sceUserServiceGetNpEnv(); +int PS4_SYSV_ABI sceUserServiceGetNpLanguageCode(); +int PS4_SYSV_ABI sceUserServiceGetNpLanguageCode2(); +int PS4_SYSV_ABI sceUserServiceGetNpLoginId(); +int PS4_SYSV_ABI sceUserServiceGetNpMAccountId(); +int PS4_SYSV_ABI sceUserServiceGetNpNpId(); +int PS4_SYSV_ABI sceUserServiceGetNpOfflineAccountAdult(); +int PS4_SYSV_ABI sceUserServiceGetNpOfflineAccountId(); +int PS4_SYSV_ABI sceUserServiceGetNpOnlineId(); +int PS4_SYSV_ABI sceUserServiceGetNpSubAccount(); +int PS4_SYSV_ABI sceUserServiceGetPadSpeakerVolume(); +int PS4_SYSV_ABI sceUserServiceGetParentalBdAge(); +int PS4_SYSV_ABI sceUserServiceGetParentalBrowser(); +int PS4_SYSV_ABI sceUserServiceGetParentalDvd(); +int PS4_SYSV_ABI sceUserServiceGetParentalDvdRegion(); +int PS4_SYSV_ABI sceUserServiceGetParentalGame(); +int PS4_SYSV_ABI sceUserServiceGetParentalGameAgeLevel(); +int PS4_SYSV_ABI sceUserServiceGetParentalMorpheus(); +int PS4_SYSV_ABI sceUserServiceGetPartyMuteList(); +int PS4_SYSV_ABI sceUserServiceGetPartyMuteListA(); +int PS4_SYSV_ABI sceUserServiceGetPartySettingFlags(); +int PS4_SYSV_ABI sceUserServiceGetPasscode(); +int PS4_SYSV_ABI sceUserServiceGetPbtcAdditionalTime(); +int PS4_SYSV_ABI sceUserServiceGetPbtcFlag(); +int PS4_SYSV_ABI sceUserServiceGetPbtcFridayDuration(); +int PS4_SYSV_ABI sceUserServiceGetPbtcFridayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceGetPbtcFridayHoursStart(); +int PS4_SYSV_ABI sceUserServiceGetPbtcMode(); +int PS4_SYSV_ABI sceUserServiceGetPbtcMondayDuration(); +int PS4_SYSV_ABI sceUserServiceGetPbtcMondayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceGetPbtcMondayHoursStart(); +int PS4_SYSV_ABI sceUserServiceGetPbtcPlayTime(); +int PS4_SYSV_ABI sceUserServiceGetPbtcPlayTimeLastUpdated(); +int PS4_SYSV_ABI sceUserServiceGetPbtcSaturdayDuration(); +int PS4_SYSV_ABI sceUserServiceGetPbtcSaturdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceGetPbtcSaturdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceGetPbtcSundayDuration(); +int PS4_SYSV_ABI sceUserServiceGetPbtcSundayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceGetPbtcSundayHoursStart(); +int PS4_SYSV_ABI sceUserServiceGetPbtcThursdayDuration(); +int PS4_SYSV_ABI sceUserServiceGetPbtcThursdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceGetPbtcThursdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceGetPbtcTuesdayDuration(); +int PS4_SYSV_ABI sceUserServiceGetPbtcTuesdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceGetPbtcTuesdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceGetPbtcTzOffset(); +int PS4_SYSV_ABI sceUserServiceGetPbtcWednesdayDuration(); +int PS4_SYSV_ABI sceUserServiceGetPbtcWednesdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceGetPbtcWednesdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceGetPlayTogetherFlags(); +int PS4_SYSV_ABI sceUserServiceGetPsnPasswordForDebug(); +int PS4_SYSV_ABI sceUserServiceGetRegisteredHomeUserIdList(); +int PS4_SYSV_ABI sceUserServiceGetRegisteredUserIdList(); +int PS4_SYSV_ABI sceUserServiceGetSaveDataAutoUpload(); +int PS4_SYSV_ABI sceUserServiceGetSaveDataSort(); +int PS4_SYSV_ABI sceUserServiceGetSaveDataTutorialFlag(); +int PS4_SYSV_ABI sceUserServiceGetSecureHomeDirectory(); +int PS4_SYSV_ABI sceUserServiceGetShareButtonAssign(); +int PS4_SYSV_ABI sceUserServiceGetShareDailymotionAccessToken(); +int PS4_SYSV_ABI sceUserServiceGetShareDailymotionRefreshToken(); +int PS4_SYSV_ABI sceUserServiceGetSharePlayFlags(); +int PS4_SYSV_ABI sceUserServiceGetSharePlayFramerateHost(); +int PS4_SYSV_ABI sceUserServiceGetSharePlayResolutionHost(); +int PS4_SYSV_ABI sceUserServiceGetShareStatus(); +int PS4_SYSV_ABI sceUserServiceGetShareStatus2(); +int PS4_SYSV_ABI sceUserServiceGetSystemLoggerHashedAccountId(); +int PS4_SYSV_ABI sceUserServiceGetSystemLoggerHashedAccountIdClockType(); +int PS4_SYSV_ABI sceUserServiceGetSystemLoggerHashedAccountIdParam(); +int PS4_SYSV_ABI sceUserServiceGetSystemLoggerHashedAccountIdTtl(); +int PS4_SYSV_ABI sceUserServiceGetTeamShowAboutTeam(); +int PS4_SYSV_ABI sceUserServiceGetThemeBgImageDimmer(); +int PS4_SYSV_ABI sceUserServiceGetThemeBgImageWaveColor(); +int PS4_SYSV_ABI sceUserServiceGetThemeBgImageZoom(); +int PS4_SYSV_ABI sceUserServiceGetThemeEntitlementId(); +int PS4_SYSV_ABI sceUserServiceGetThemeHomeShareOwner(); +int PS4_SYSV_ABI sceUserServiceGetThemeTextShadow(); +int PS4_SYSV_ABI sceUserServiceGetThemeWaveColor(); +int PS4_SYSV_ABI sceUserServiceGetTopMenuLimitItem(); +int PS4_SYSV_ABI sceUserServiceGetTopMenuNotificationFlag(); +int PS4_SYSV_ABI sceUserServiceGetTopMenuTutorialFlag(); +int PS4_SYSV_ABI sceUserServiceGetTraditionalChineseInputType(); +s32 PS4_SYSV_ABI sceUserServiceGetUserColor(int user_id, OrbisUserServiceUserColor* color); +int PS4_SYSV_ABI sceUserServiceGetUserGroupName(); +int PS4_SYSV_ABI sceUserServiceGetUserGroupNameList(); +int PS4_SYSV_ABI sceUserServiceGetUserGroupNum(); +s32 PS4_SYSV_ABI sceUserServiceGetUserName(int user_id, char* user_name, std::size_t size); +int PS4_SYSV_ABI sceUserServiceGetUserStatus(); +int PS4_SYSV_ABI sceUserServiceGetVibrationEnabled(); +int PS4_SYSV_ABI sceUserServiceGetVoiceRecognitionLastUsedOsk(); +int PS4_SYSV_ABI sceUserServiceGetVoiceRecognitionTutorialState(); +int PS4_SYSV_ABI sceUserServiceGetVolumeForController(); +int PS4_SYSV_ABI sceUserServiceGetVolumeForGenericUSB(); +int PS4_SYSV_ABI sceUserServiceGetVolumeForMorpheusSidetone(); +int PS4_SYSV_ABI sceUserServiceGetVolumeForSidetone(); +s32 PS4_SYSV_ABI sceUserServiceInitialize(const OrbisUserServiceInitializeParams* initParams); +int PS4_SYSV_ABI sceUserServiceInitialize2(); +int PS4_SYSV_ABI sceUserServiceIsGuestUser(); +int PS4_SYSV_ABI sceUserServiceIsKratosPrimaryUser(); +int PS4_SYSV_ABI sceUserServiceIsKratosUser(); +int PS4_SYSV_ABI sceUserServiceIsLoggedIn(); +int PS4_SYSV_ABI sceUserServiceIsLoggedInWithoutLock(); +int PS4_SYSV_ABI sceUserServiceIsSharePlayClientUser(); +int PS4_SYSV_ABI sceUserServiceIsUserStorageAccountBound(); +int PS4_SYSV_ABI sceUserServiceLogin(); +int PS4_SYSV_ABI sceUserServiceLogout(); +int PS4_SYSV_ABI sceUserServiceRegisterEventCallback(); +int PS4_SYSV_ABI sceUserServiceSetAccessibilityKeyremapData(); +int PS4_SYSV_ABI sceUserServiceSetAccessibilityKeyremapEnable(); +int PS4_SYSV_ABI sceUserServiceSetAccessibilityZoom(); +int PS4_SYSV_ABI sceUserServiceSetAccountRemarks(); +int PS4_SYSV_ABI sceUserServiceSetAgeVerified(); +int PS4_SYSV_ABI sceUserServiceSetAppearOfflineSetting(); +int PS4_SYSV_ABI sceUserServiceSetAppSortOrder(); +int PS4_SYSV_ABI sceUserServiceSetAutoLoginEnabled(); +int PS4_SYSV_ABI sceUserServiceSetCreatedVersion(); +int PS4_SYSV_ABI sceUserServiceSetDiscPlayerFlag(); +int PS4_SYSV_ABI sceUserServiceSetEventCalendarType(); +int PS4_SYSV_ABI sceUserServiceSetEventFilterTeamEvent(); +int PS4_SYSV_ABI sceUserServiceSetEventSortEvent(); +int PS4_SYSV_ABI sceUserServiceSetEventSortTitle(); +int PS4_SYSV_ABI sceUserServiceSetEventUiFlag(); +int PS4_SYSV_ABI sceUserServiceSetFaceRecognitionDeleteCount(); +int PS4_SYSV_ABI sceUserServiceSetFaceRecognitionRegisterCount(); +int PS4_SYSV_ABI sceUserServiceSetFileBrowserFilter(); +int PS4_SYSV_ABI sceUserServiceSetFileBrowserSortContent(); +int PS4_SYSV_ABI sceUserServiceSetFileBrowserSortTitle(); +int PS4_SYSV_ABI sceUserServiceSetFileSelectorFilter(); +int PS4_SYSV_ABI sceUserServiceSetFileSelectorSortContent(); +int PS4_SYSV_ABI sceUserServiceSetFileSelectorSortTitle(); +int PS4_SYSV_ABI sceUserServiceSetForegroundUser(); +int PS4_SYSV_ABI sceUserServiceSetFriendCustomListLastFocus(); +int PS4_SYSV_ABI sceUserServiceSetFriendFlag(); +int PS4_SYSV_ABI sceUserServiceSetGlsAccessTokenNiconicoLive(); +int PS4_SYSV_ABI sceUserServiceSetGlsAccessTokenTwitch(); +int PS4_SYSV_ABI sceUserServiceSetGlsAccessTokenUstream(); +int PS4_SYSV_ABI sceUserServiceSetGlsAnonymousUserId(); +int PS4_SYSV_ABI sceUserServiceSetGlsBcTags(); +int PS4_SYSV_ABI sceUserServiceSetGlsBcTitle(); +int PS4_SYSV_ABI sceUserServiceSetGlsBroadcastChannel(); +int PS4_SYSV_ABI sceUserServiceSetGlsBroadcastersComment(); +int PS4_SYSV_ABI sceUserServiceSetGlsBroadcastersCommentColor(); +int PS4_SYSV_ABI sceUserServiceSetGlsBroadcastService(); +int PS4_SYSV_ABI sceUserServiceSetGlsBroadcastUiLayout(); +int PS4_SYSV_ABI sceUserServiceSetGlsCamCrop(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraBgFilter(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraBrightness(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraChromaKeyLevel(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraContrast(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraDepthLevel(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraEdgeLevel(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraEffect(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraEliminationLevel(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraPosition(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraReflection(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraSize(); +int PS4_SYSV_ABI sceUserServiceSetGlsCameraTransparency(); +int PS4_SYSV_ABI sceUserServiceSetGlsCommunityId(); +int PS4_SYSV_ABI sceUserServiceSetGlsFloatingMessage(); +int PS4_SYSV_ABI sceUserServiceSetGlsHintFlag(); +int PS4_SYSV_ABI sceUserServiceSetGlsInitSpectating(); +int PS4_SYSV_ABI sceUserServiceSetGlsIsCameraHidden(); +int PS4_SYSV_ABI sceUserServiceSetGlsIsFacebookEnabled(); +int PS4_SYSV_ABI sceUserServiceSetGlsIsMuteEnabled(); +int PS4_SYSV_ABI sceUserServiceSetGlsIsRecDisabled(); +int PS4_SYSV_ABI sceUserServiceSetGlsIsRecievedMessageHidden(); +int PS4_SYSV_ABI sceUserServiceSetGlsIsTwitterEnabled(); +int PS4_SYSV_ABI sceUserServiceSetGlsLanguageFilter(); +int PS4_SYSV_ABI sceUserServiceSetGlsLfpsSortOrder(); +int PS4_SYSV_ABI sceUserServiceSetGlsLiveQuality(); +int PS4_SYSV_ABI sceUserServiceSetGlsLiveQuality2(); +int PS4_SYSV_ABI sceUserServiceSetGlsLiveQuality3(); +int PS4_SYSV_ABI sceUserServiceSetGlsLiveQuality4(); +int PS4_SYSV_ABI sceUserServiceSetGlsLiveQuality5(); +int PS4_SYSV_ABI sceUserServiceSetGlsMessageFilterLevel(); +int PS4_SYSV_ABI sceUserServiceSetGlsTtsFlags(); +int PS4_SYSV_ABI sceUserServiceSetGlsTtsPitch(); +int PS4_SYSV_ABI sceUserServiceSetGlsTtsSpeed(); +int PS4_SYSV_ABI sceUserServiceSetGlsTtsVolume(); +int PS4_SYSV_ABI sceUserServiceSetHmuBrightness(); +int PS4_SYSV_ABI sceUserServiceSetHmuZoom(); +int PS4_SYSV_ABI sceUserServiceSetHoldAudioOutDevice(); +int PS4_SYSV_ABI sceUserServiceSetImeAutoCapitalEnabled(); +int PS4_SYSV_ABI sceUserServiceSetImeInitFlag(); +int PS4_SYSV_ABI sceUserServiceSetImeInputType(); +int PS4_SYSV_ABI sceUserServiceSetImeLastUnit(); +int PS4_SYSV_ABI sceUserServiceSetImePointerMode(); +int PS4_SYSV_ABI sceUserServiceSetImePredictiveTextEnabled(); +int PS4_SYSV_ABI sceUserServiceSetImeRunCount(); +int PS4_SYSV_ABI sceUserServiceSetIPDLeft(); +int PS4_SYSV_ABI sceUserServiceSetIPDRight(); +int PS4_SYSV_ABI sceUserServiceSetIsFakePlus(); +int PS4_SYSV_ABI sceUserServiceSetIsQuickSignup(); +int PS4_SYSV_ABI sceUserServiceSetIsRemotePlayAllowed(); +int PS4_SYSV_ABI sceUserServiceSetJapaneseInputType(); +int PS4_SYSV_ABI sceUserServiceSetKeyboardType(); +int PS4_SYSV_ABI sceUserServiceSetKeyRepeatSpeed(); +int PS4_SYSV_ABI sceUserServiceSetKeyRepeatStartingTime(); +int PS4_SYSV_ABI sceUserServiceSetLightBarBaseBrightness(); +int PS4_SYSV_ABI sceUserServiceSetLoginFlag(); +int PS4_SYSV_ABI sceUserServiceSetMicLevel(); +int PS4_SYSV_ABI sceUserServiceSetMouseHandType(); +int PS4_SYSV_ABI sceUserServiceSetMousePointerSpeed(); +int PS4_SYSV_ABI sceUserServiceSetNotificationBehavior(); +int PS4_SYSV_ABI sceUserServiceSetNotificationSettings(); +int PS4_SYSV_ABI sceUserServiceSetNpAccountUpgradeFlag(); +int PS4_SYSV_ABI sceUserServiceSetNpAge(); +int PS4_SYSV_ABI sceUserServiceSetNpAuthErrorFlag(); +int PS4_SYSV_ABI sceUserServiceSetNpCountryCode(); +int PS4_SYSV_ABI sceUserServiceSetNpDateOfBirth(); +int PS4_SYSV_ABI sceUserServiceSetNpEnv(); +int PS4_SYSV_ABI sceUserServiceSetNpLanguageCode(); +int PS4_SYSV_ABI sceUserServiceSetNpLanguageCode2(); +int PS4_SYSV_ABI sceUserServiceSetNpLoginId(); +int PS4_SYSV_ABI sceUserServiceSetNpMAccountId(); +int PS4_SYSV_ABI sceUserServiceSetNpNpId(); +int PS4_SYSV_ABI sceUserServiceSetNpOfflineAccountAdult(); +int PS4_SYSV_ABI sceUserServiceSetNpOnlineId(); +int PS4_SYSV_ABI sceUserServiceSetNpSubAccount(); +int PS4_SYSV_ABI sceUserServiceSetPadSpeakerVolume(); +int PS4_SYSV_ABI sceUserServiceSetParentalBdAge(); +int PS4_SYSV_ABI sceUserServiceSetParentalBrowser(); +int PS4_SYSV_ABI sceUserServiceSetParentalDvd(); +int PS4_SYSV_ABI sceUserServiceSetParentalDvdRegion(); +int PS4_SYSV_ABI sceUserServiceSetParentalGame(); +int PS4_SYSV_ABI sceUserServiceSetParentalGameAgeLevel(); +int PS4_SYSV_ABI sceUserServiceSetParentalMorpheus(); +int PS4_SYSV_ABI sceUserServiceSetPartyMuteList(); +int PS4_SYSV_ABI sceUserServiceSetPartyMuteListA(); +int PS4_SYSV_ABI sceUserServiceSetPartySettingFlags(); +int PS4_SYSV_ABI sceUserServiceSetPasscode(); +int PS4_SYSV_ABI sceUserServiceSetPbtcAdditionalTime(); +int PS4_SYSV_ABI sceUserServiceSetPbtcFlag(); +int PS4_SYSV_ABI sceUserServiceSetPbtcFridayDuration(); +int PS4_SYSV_ABI sceUserServiceSetPbtcFridayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceSetPbtcFridayHoursStart(); +int PS4_SYSV_ABI sceUserServiceSetPbtcMode(); +int PS4_SYSV_ABI sceUserServiceSetPbtcMondayDuration(); +int PS4_SYSV_ABI sceUserServiceSetPbtcMondayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceSetPbtcMondayHoursStart(); +int PS4_SYSV_ABI sceUserServiceSetPbtcPlayTime(); +int PS4_SYSV_ABI sceUserServiceSetPbtcPlayTimeLastUpdated(); +int PS4_SYSV_ABI sceUserServiceSetPbtcSaturdayDuration(); +int PS4_SYSV_ABI sceUserServiceSetPbtcSaturdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceSetPbtcSaturdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceSetPbtcSundayDuration(); +int PS4_SYSV_ABI sceUserServiceSetPbtcSundayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceSetPbtcSundayHoursStart(); +int PS4_SYSV_ABI sceUserServiceSetPbtcThursdayDuration(); +int PS4_SYSV_ABI sceUserServiceSetPbtcThursdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceSetPbtcThursdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceSetPbtcTuesdayDuration(); +int PS4_SYSV_ABI sceUserServiceSetPbtcTuesdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceSetPbtcTuesdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceSetPbtcTzOffset(); +int PS4_SYSV_ABI sceUserServiceSetPbtcWednesdayDuration(); +int PS4_SYSV_ABI sceUserServiceSetPbtcWednesdayHoursEnd(); +int PS4_SYSV_ABI sceUserServiceSetPbtcWednesdayHoursStart(); +int PS4_SYSV_ABI sceUserServiceSetPlayTogetherFlags(); +int PS4_SYSV_ABI sceUserServiceSetPsnPasswordForDebug(); +int PS4_SYSV_ABI sceUserServiceSetSaveDataAutoUpload(); +int PS4_SYSV_ABI sceUserServiceSetSaveDataSort(); +int PS4_SYSV_ABI sceUserServiceSetSaveDataTutorialFlag(); +int PS4_SYSV_ABI sceUserServiceSetShareButtonAssign(); +int PS4_SYSV_ABI sceUserServiceSetShareDailymotionAccessToken(); +int PS4_SYSV_ABI sceUserServiceSetShareDailymotionRefreshToken(); +int PS4_SYSV_ABI sceUserServiceSetSharePlayFlags(); +int PS4_SYSV_ABI sceUserServiceSetSharePlayFramerateHost(); +int PS4_SYSV_ABI sceUserServiceSetSharePlayResolutionHost(); +int PS4_SYSV_ABI sceUserServiceSetShareStatus(); +int PS4_SYSV_ABI sceUserServiceSetShareStatus2(); +int PS4_SYSV_ABI sceUserServiceSetSystemLoggerHashedAccountId(); +int PS4_SYSV_ABI sceUserServiceSetSystemLoggerHashedAccountIdClockType(); +int PS4_SYSV_ABI sceUserServiceSetSystemLoggerHashedAccountIdParam(); +int PS4_SYSV_ABI sceUserServiceSetSystemLoggerHashedAccountIdTtl(); +int PS4_SYSV_ABI sceUserServiceSetTeamShowAboutTeam(); +int PS4_SYSV_ABI sceUserServiceSetThemeBgImageDimmer(); +int PS4_SYSV_ABI sceUserServiceSetThemeBgImageWaveColor(); +int PS4_SYSV_ABI sceUserServiceSetThemeBgImageZoom(); +int PS4_SYSV_ABI sceUserServiceSetThemeEntitlementId(); +int PS4_SYSV_ABI sceUserServiceSetThemeHomeShareOwner(); +int PS4_SYSV_ABI sceUserServiceSetThemeTextShadow(); +int PS4_SYSV_ABI sceUserServiceSetThemeWaveColor(); +int PS4_SYSV_ABI sceUserServiceSetTopMenuLimitItem(); +int PS4_SYSV_ABI sceUserServiceSetTopMenuNotificationFlag(); +int PS4_SYSV_ABI sceUserServiceSetTopMenuTutorialFlag(); +int PS4_SYSV_ABI sceUserServiceSetTraditionalChineseInputType(); +int PS4_SYSV_ABI sceUserServiceSetUserGroupIndex(); +int PS4_SYSV_ABI sceUserServiceSetUserGroupName(); +int PS4_SYSV_ABI sceUserServiceSetUserName(); +int PS4_SYSV_ABI sceUserServiceSetUserStatus(); +int PS4_SYSV_ABI sceUserServiceSetVibrationEnabled(); +int PS4_SYSV_ABI sceUserServiceSetVoiceRecognitionLastUsedOsk(); +int PS4_SYSV_ABI sceUserServiceSetVoiceRecognitionTutorialState(); +int PS4_SYSV_ABI sceUserServiceSetVolumeForController(); +int PS4_SYSV_ABI sceUserServiceSetVolumeForGenericUSB(); +int PS4_SYSV_ABI sceUserServiceSetVolumeForMorpheusSidetone(); +int PS4_SYSV_ABI sceUserServiceSetVolumeForSidetone(); +int PS4_SYSV_ABI sceUserServiceTerminate(); +int PS4_SYSV_ABI sceUserServiceUnregisterEventCallback(); +int PS4_SYSV_ABI Func_8AC6DC4168D5FEA5(); +int PS4_SYSV_ABI Func_A6BDC9DFDAFD02B4(); +int PS4_SYSV_ABI Func_BB9491DFE6B4953C(); +int PS4_SYSV_ABI Func_D2B814603E7B4477(); + +void RegisterLib(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::UserService diff --git a/gpu/shadps4/core/libraries/videodec/video_utils.cpp b/gpu/shadps4/core/libraries/videodec/video_utils.cpp new file mode 100644 index 0000000..6854e90 --- /dev/null +++ b/gpu/shadps4/core/libraries/videodec/video_utils.cpp @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "video_utils.h" + +#include "common/alignment.h" +#include "common/assert.h" + +#include + +#include + +namespace Libraries::Videodec { + +void CopyNV12Data(u8* dst, u64 max_size, const AVFrame& src) { + const auto dst_pitch = Common::AlignUp(src.width, 64); + const auto dst_height = Common::AlignUp(src.height, 16); + + ASSERT(((dst_pitch * dst_height * 3) / 2) <= max_size); + + const auto luma_dst = dst; + const auto chroma_dst = dst + dst_pitch * dst_height; + + if (src.width != dst_pitch) { + for (u32 y = 0; y < src.height; ++y) { + std::memcpy(luma_dst + y * dst_pitch, src.data[0] + y * src.linesize[0], src.width); + } + for (u32 y = 0; y < src.height / 2; ++y) { + std::memcpy(chroma_dst + y * dst_pitch, src.data[1] + y * src.linesize[1], src.width); + } + } else { + std::memcpy(luma_dst, src.data[0], src.width * src.height); + std::memcpy(chroma_dst, src.data[1], (src.width * src.height) / 2); + } + + if (src.height != dst_height) { + // Extend the data vertically to the crop space + const auto ly = src.height - 1; + for (u32 y = src.height; y < dst_height; ++y) { + std::memcpy(luma_dst + y * dst_pitch, src.data[0] + ly * src.linesize[0], src.width); + } + const auto cy = (src.height / 2) - 1; + for (u32 y = src.height / 2; y < dst_height / 2; ++y) { + std::memcpy(chroma_dst + y * dst_pitch, src.data[1] + cy * src.linesize[1], src.width); + } + } +} + +} // namespace Libraries::Videodec diff --git a/gpu/shadps4/core/libraries/videodec/video_utils.h b/gpu/shadps4/core/libraries/videodec/video_utils.h new file mode 100644 index 0000000..c9d1d84 --- /dev/null +++ b/gpu/shadps4/core/libraries/videodec/video_utils.h @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +struct AVFrame; + +namespace Libraries::Videodec { + +void CopyNV12Data(u8* dst, u64 max_size, const AVFrame& src); + +} diff --git a/gpu/shadps4/core/libraries/videoout/buffer.h b/gpu/shadps4/core/libraries/videoout/buffer.h new file mode 100644 index 0000000..08552bd --- /dev/null +++ b/gpu/shadps4/core/libraries/videoout/buffer.h @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/assert.h" +#include "common/types.h" + +namespace Libraries::VideoOut { + +constexpr std::size_t MaxDisplayBuffers = 16; +constexpr std::size_t MaxDisplayBufferGroups = 4; + +enum class PixelFormat : u32 { + Unknown, + A8R8G8B8Srgb = 0x80000000, + A8B8G8R8Srgb = 0x80002200, + A2R10G10B10 = 0x88060000, + A2R10G10B10Srgb = 0x88000000, + A2R10G10B10Bt2020Pq = 0x88740000, + A16R16G16B16Float = 0xC1060000, +}; + +enum class TilingMode : s32 { + Tile = 0, + Linear = 1, +}; + +constexpr std::string_view GetPixelFormatString(PixelFormat format) { + switch (format) { + case PixelFormat::A8R8G8B8Srgb: + return "A8R8G8B8Srgb"; + case PixelFormat::A8B8G8R8Srgb: + return "A8B8G8R8Srgb"; + case PixelFormat::A2R10G10B10: + return "A2R10G10B10"; + case PixelFormat::A2R10G10B10Srgb: + return "A2R10G10B10Srgb"; + case PixelFormat::A2R10G10B10Bt2020Pq: + return "A2R10G10B10Bt2020Pq"; + case PixelFormat::A16R16G16B16Float: + return "A16R16G16B16Float"; + default: + UNREACHABLE_MSG("Unknown pixel format {}", static_cast(format)); + return ""; + } +} + +struct BufferAttribute { + PixelFormat pixel_format; + TilingMode tiling_mode; + s32 aspect_ratio; + u32 width; + u32 height; + u32 pitch_in_pixel; + u32 option; + u32 reserved0; + u64 reserved1; +}; + +struct BufferAttributeGroup { + bool is_occupied; + BufferAttribute attrib; +}; + +struct VideoOutBuffer { + s32 group_index{-1}; + uintptr_t address_left; + uintptr_t address_right; +}; + +} // namespace Libraries::VideoOut diff --git a/gpu/shadps4/core/libraries/videoout/driver.cpp b/gpu/shadps4/core/libraries/videoout/driver.cpp new file mode 100644 index 0000000..3bcbc90 --- /dev/null +++ b/gpu/shadps4/core/libraries/videoout/driver.cpp @@ -0,0 +1,447 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "common/assert.h" +#include "common/debug.h" +#include "common/thread.h" +#include "core/debug_state.h" +#include "core/emulator_settings.h" +#include "core/libraries/kernel/time.h" +#include "core/libraries/videoout/driver.h" +#include "core/libraries/videoout/videoout_error.h" +#include "imgui/renderer/imgui_core.h" +#include "video_core/amdgpu/liverpool.h" +#include "video_core/renderer_vulkan/vk_presenter.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" + +extern std::unique_ptr presenter; +extern std::unique_ptr liverpool; + +namespace Vulkan { +extern std::atomic g_bb_compile_ns; +extern std::atomic g_bb_compiles; +} // namespace Vulkan + +namespace Libraries::VideoOut { + +constexpr static bool Is32BppPixelFormat(PixelFormat format) { + switch (format) { + case PixelFormat::A8R8G8B8Srgb: + case PixelFormat::A8B8G8R8Srgb: + case PixelFormat::A2R10G10B10: + case PixelFormat::A2R10G10B10Srgb: + case PixelFormat::A2R10G10B10Bt2020Pq: + return true; + default: + return false; + } +} + +constexpr u32 PixelFormatBpp(PixelFormat pixel_format) { + switch (pixel_format) { + case PixelFormat::A16R16G16B16Float: + return 8; + default: + return 4; + } +} + +VideoOutDriver::VideoOutDriver(u32 width, u32 height) { + main_port.resolution.full_width = width; + main_port.resolution.full_height = height; + main_port.resolution.pane_width = width; + main_port.resolution.pane_height = height; + present_thread = std::jthread([&](std::stop_token token) { PresentThread(token); }); +} + +VideoOutDriver::~VideoOutDriver() = default; + +int VideoOutDriver::Open(const ServiceThreadParams* params) { + if (main_port.is_open) { + return ORBIS_VIDEO_OUT_ERROR_RESOURCE_BUSY; + } + main_port.is_open = true; + liverpool->SetVoPort(&main_port); + return 1; +} + +void VideoOutDriver::Close(s32 handle) { + std::scoped_lock lock{mutex}; + + // Mark as closed + main_port.is_open = false; + main_port.flip_rate = 0; + main_port.prev_index = -1; + + // Clear port information + std::memset(main_port.buffer_labels.data(), 0, sizeof(main_port.buffer_labels)); + std::memset(main_port.groups.data(), 0, sizeof(main_port.groups)); + std::memset(&main_port.vblank_status, 0, sizeof(main_port.vblank_status)); + main_port.flip_status = FlipStatus{}; + + // Re-initialize buffers + std::memset(main_port.buffer_slots.data(), 0, sizeof(main_port.buffer_slots)); + for (auto& buffer : main_port.buffer_slots) { + buffer.group_index = -1; + } + + // Clear events + for (auto event : main_port.flip_events) { + auto equeue = Kernel::GetEqueue(event); + if (equeue != nullptr) { + equeue->RemoveEvent(static_cast(OrbisVideoOutInternalEventId::Flip), + Kernel::OrbisKernelEvent::Filter::VideoOut); + } + } + main_port.flip_events.clear(); + for (auto event : main_port.vblank_events) { + auto equeue = Kernel::GetEqueue(event); + if (equeue != nullptr) { + equeue->RemoveEvent(static_cast(OrbisVideoOutInternalEventId::Vblank), + Kernel::OrbisKernelEvent::Filter::VideoOut); + } + } + main_port.vblank_events.clear(); +} + +VideoOutPort* VideoOutDriver::GetPort(int handle) { + if (handle != 1) [[unlikely]] { + return nullptr; + } + return &main_port; +} + +int VideoOutDriver::RegisterBuffers(VideoOutPort* port, s32 startIndex, void* const* addresses, + s32 bufferNum, const BufferAttribute* attribute) { + const s32 group_index = port->FindFreeGroup(); + if (group_index >= MaxDisplayBufferGroups) { + return ORBIS_VIDEO_OUT_ERROR_NO_EMPTY_SLOT; + } + + if (startIndex + bufferNum > MaxDisplayBuffers || startIndex > MaxDisplayBuffers || + bufferNum > MaxDisplayBuffers) { + LOG_ERROR(Lib_VideoOut, + "Attempted to register too many buffers startIndex = {}, bufferNum = {}", + startIndex, bufferNum); + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + + const s32 end_index = startIndex + bufferNum; + if (bufferNum > 0 && + std::any_of(port->buffer_slots.begin() + startIndex, port->buffer_slots.begin() + end_index, + [](auto& buffer) { return buffer.group_index != -1; })) { + return ORBIS_VIDEO_OUT_ERROR_SLOT_OCCUPIED; + } + + if (attribute->reserved0 != 0 || attribute->reserved1 != 0) { + LOG_ERROR(Lib_VideoOut, "Invalid reserved members"); + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + if (attribute->aspect_ratio != 0) { + LOG_ERROR(Lib_VideoOut, "Invalid aspect ratio = {}", attribute->aspect_ratio); + return ORBIS_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO; + } + if (attribute->width > attribute->pitch_in_pixel) { + LOG_ERROR(Lib_VideoOut, "Buffer width {} is larger than pitch {}", attribute->width, + attribute->pitch_in_pixel); + return ORBIS_VIDEO_OUT_ERROR_INVALID_PITCH; + } + if (attribute->tiling_mode < TilingMode::Tile || attribute->tiling_mode > TilingMode::Linear) { + LOG_ERROR(Lib_VideoOut, "Invalid tilingMode = {}", + static_cast(attribute->tiling_mode)); + return ORBIS_VIDEO_OUT_ERROR_INVALID_TILING_MODE; + } + + LOG_INFO(Lib_VideoOut, + "startIndex = {}, bufferNum = {}, pixelFormat = {}, aspectRatio = {}, " + "tilingMode = {}, width = {}, height = {}, pitchInPixel = {}, option = {:#x}", + startIndex, bufferNum, GetPixelFormatString(attribute->pixel_format), + attribute->aspect_ratio, static_cast(attribute->tiling_mode), attribute->width, + attribute->height, attribute->pitch_in_pixel, attribute->option); + + auto& group = port->groups[group_index]; + std::memcpy(&group.attrib, attribute, sizeof(BufferAttribute)); + group.is_occupied = true; + + for (u32 i = 0; i < bufferNum; i++) { + const uintptr_t address = reinterpret_cast(addresses[i]); + port->buffer_slots[startIndex + i] = VideoOutBuffer{ + .group_index = group_index, + .address_left = address, + .address_right = 0, + }; + + // Reset flip label also when registering buffer + port->buffer_labels[startIndex + i] = 0; + port->SignalVoLabel(); + + presenter->RegisterVideoOutSurface(group, address); + LOG_INFO(Lib_VideoOut, "buffers[{}] = {:#x}", i + startIndex, address); + } + + return group_index; +} + +int VideoOutDriver::UnregisterBuffers(VideoOutPort* port, s32 attributeIndex) { + if (attributeIndex >= MaxDisplayBufferGroups || !port->groups[attributeIndex].is_occupied) { + LOG_ERROR(Lib_VideoOut, "Invalid attribute index {}", attributeIndex); + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + + auto& group = port->groups[attributeIndex]; + group.is_occupied = false; + + for (auto& buffer : port->buffer_slots) { + if (buffer.group_index != attributeIndex) { + continue; + } + buffer.group_index = -1; + } + + return ORBIS_OK; +} + +int VideoOutDriver::ChangeBufferAttribute(VideoOutPort* port, s32 attributeIndex, + const BufferAttribute* attribute) { + if (attributeIndex >= MaxDisplayBufferGroups || !port->groups[attributeIndex].is_occupied) { + LOG_ERROR(Lib_VideoOut, "Invalid attribute index {}", attributeIndex); + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + + if (attribute->reserved0 != 0 || attribute->reserved1 != 0) { + LOG_ERROR(Lib_VideoOut, "Invalid reserved members"); + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + if (attribute->aspect_ratio != 0) { + LOG_ERROR(Lib_VideoOut, "Invalid aspect ratio = {}", attribute->aspect_ratio); + return ORBIS_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO; + } + if (attribute->width > attribute->pitch_in_pixel) { + LOG_ERROR(Lib_VideoOut, "Buffer width {} is larger than pitch {}", attribute->width, + attribute->pitch_in_pixel); + return ORBIS_VIDEO_OUT_ERROR_INVALID_PITCH; + } + if (attribute->tiling_mode < TilingMode::Tile || attribute->tiling_mode > TilingMode::Linear) { + LOG_ERROR(Lib_VideoOut, "Invalid tilingMode = {}", + static_cast(attribute->tiling_mode)); + return ORBIS_VIDEO_OUT_ERROR_INVALID_TILING_MODE; + } + + LOG_INFO(Lib_VideoOut, + "attributeIndex = {}, pixelFormat = {}, aspectRatio = {}, " + "tilingMode = {}, width = {}, height = {}, pitchInPixel = {}, option = {:#x}", + attributeIndex, GetPixelFormatString(attribute->pixel_format), attribute->aspect_ratio, + static_cast(attribute->tiling_mode), attribute->width, attribute->height, + attribute->pitch_in_pixel, attribute->option); + + std::unique_lock lock{port->port_mutex}; + std::memcpy(&port->groups[attributeIndex].attrib, attribute, sizeof(BufferAttribute)); + return 0; +} + +void VideoOutDriver::Flip(const Request& req) { + // Update HDR status before presenting. + presenter->SetHDR(req.port->is_hdr); + + // Present the frame. + presenter->Present(req.frame); + + // bbport: BB_FRAME_STATS=1 prints flip rate and frame time spread every 5 seconds. + static const bool frame_stats = EmulatorSettingsImpl::Flag("BB_FRAME_STATS", false); + if (frame_stats) { + using Clock = std::chrono::steady_clock; + static Clock::time_point window_start = Clock::now(), last = window_start; + static u32 frames; + static double worst_ms; + const auto now = Clock::now(); + worst_ms = std::max(worst_ms, std::chrono::duration(now - last).count()); + last = now; + ++frames; + const double window = std::chrono::duration(now - window_start).count(); + if (window >= 5.0) { + const u32 compiles = Vulkan::g_bb_compiles.exchange(0); + const u64 compile_ns = Vulkan::g_bb_compile_ns.exchange(0); + const u64 direct = Vulkan::Scheduler::direct_recordings.exchange(0); + std::printf("Frame stats: %.1f FPS, worst frame %.1f ms (vblank %u Hz); " + "%u shader/pipeline compiles, %.1f ms; %llu recorder syncs\n", + frames / window, worst_ms, EmulatorSettings.GetVblankFrequency(), compiles, + compile_ns / 1e6, static_cast(direct)); + window_start = now; + frames = 0; + worst_ms = 0; + } + } + + // Update flip status. + auto* port = req.port; + { + std::unique_lock lock{port->port_mutex}; + auto& flip_status = port->flip_status; + flip_status.count++; + flip_status.process_time = Libraries::Kernel::sceKernelGetProcessTime(); + flip_status.tsc = Libraries::Kernel::sceKernelReadTsc(); + flip_status.flip_arg = req.flip_arg; + flip_status.current_buffer = req.index; + if (req.eop) { + --flip_status.gc_queue_num; + } + --flip_status.flip_pending_num; + } + + // Trigger flip events for the port. + for (auto event : port->flip_events) { + auto equeue = Kernel::GetEqueue(event); + if (equeue != nullptr) { + equeue->TriggerEvent( + static_cast(OrbisVideoOutInternalEventId::Flip), + Kernel::OrbisKernelEvent::Filter::VideoOut, + reinterpret_cast(static_cast(OrbisVideoOutInternalEventId::Flip) | + (req.flip_arg << 16))); + } + } + + // Reset prev flip label + if (port->prev_index != -1) { + port->buffer_labels[port->prev_index] = 0; + port->SignalVoLabel(); + } + // save to prev buf index + port->prev_index = req.index; +} + +void VideoOutDriver::DrawBlankFrame() { + const auto empty_frame = presenter->PrepareBlankFrame(true); + presenter->Present(empty_frame, false, false); +} + +void VideoOutDriver::DrawLastFrame() { + const auto frame = presenter->PrepareLastFrame(); + if (frame != nullptr) { + presenter->Present(frame, true); + } +} + +bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg, + bool is_eop /*= false*/) { + { + std::unique_lock lock{port->port_mutex}; + if (index != -1 && port->flip_status.flip_pending_num > 16) { + LOG_ERROR(Lib_VideoOut, "Flip queue is full"); + return false; + } + + if (is_eop) { + ++port->flip_status.gc_queue_num; + } + ++port->flip_status.flip_pending_num; // integral GPU and CPU pending flips counter + port->flip_status.submit_tsc = Libraries::Kernel::sceKernelReadTsc(); + } + + if (!is_eop) { + // Non EOP flips can arrive from any thread so ask GPU thread to perform them + liverpool->SendCommand([=, this]() { SubmitFlipInternal(port, index, flip_arg, is_eop); }); + } else { + SubmitFlipInternal(port, index, flip_arg, is_eop); + } + + return true; +} + +void VideoOutDriver::SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop) { + Vulkan::Frame* frame; + if (index == -1) { + frame = presenter->PrepareBlankFrame(false); + } else { + const auto& buffer = port->buffer_slots[index]; + ASSERT_MSG(buffer.group_index >= 0, "Trying to flip an unregistered buffer!"); + const auto& group = port->groups[buffer.group_index]; + frame = presenter->PrepareFrame(group, buffer.address_left); + } + + std::scoped_lock lock{mutex}; + requests.push({ + .frame = frame, + .port = port, + .flip_arg = flip_arg, + .index = index, + .eop = is_eop, + }); +} + +void VideoOutDriver::PresentThread(std::stop_token token) { + const std::chrono::nanoseconds vblank_period(1000000000 / + EmulatorSettings.GetVblankFrequency()); + + Common::SetCurrentThreadName("shadPS4:PresentThread"); + Common::SetCurrentThreadRealtime(vblank_period); + + Common::AccurateTimer timer{vblank_period}; + + const auto receive_request = [this] -> Request { + std::scoped_lock lk{mutex}; + if (!requests.empty()) { + const auto request = requests.front(); + requests.pop(); + return request; + } + return {}; + }; + + while (!token.stop_requested()) { + timer.Start(); + + if (DebugState.IsGuestThreadsPaused()) { + DrawLastFrame(); + timer.End(); + continue; + } + + // Check if it's time to take a request. + auto& vblank_status = main_port.vblank_status; + if (vblank_status.count % (main_port.flip_rate + 1) == 0) { + const auto request = receive_request(); + if (!request) { + if (timer.GetTotalWait().count() < 0) { // Dont draw too fast + if (!main_port.is_open) { + DrawBlankFrame(); + } else if (ImGui::Core::MustKeepDrawing()) { + DrawLastFrame(); + } + } + } else { + Flip(request); + FRAME_END; + } + } + + { + // Needs lock here as can be concurrently read by `sceVideoOutGetVblankStatus` + std::scoped_lock lock{main_port.vo_mutex}; + + // Trigger flip events for the port + for (auto event : main_port.vblank_events) { + auto equeue = Kernel::GetEqueue(event); + if (equeue != nullptr) { + equeue->TriggerEvent( + static_cast(OrbisVideoOutInternalEventId::Vblank), + Kernel::OrbisKernelEvent::Filter::VideoOut, + reinterpret_cast( + static_cast(OrbisVideoOutInternalEventId::Vblank) | + (vblank_status.count << 16))); + } + } + + // Update vblank status + vblank_status.count++; + vblank_status.process_time = Libraries::Kernel::sceKernelGetProcessTime(); + vblank_status.tsc = Libraries::Kernel::sceKernelReadTsc(); + main_port.vblank_cv.notify_all(); + } + + timer.End(); + } +} + +} // namespace Libraries::VideoOut diff --git a/gpu/shadps4/core/libraries/videoout/driver.h b/gpu/shadps4/core/libraries/videoout/driver.h new file mode 100644 index 0000000..ca2b645 --- /dev/null +++ b/gpu/shadps4/core/libraries/videoout/driver.h @@ -0,0 +1,120 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/debug.h" +#include "common/polyfill_thread.h" +#include "core/libraries/videoout/video_out.h" + +#include +#include +#include + +namespace Vulkan { +struct Frame; +} + +namespace Libraries::VideoOut { + +struct VideoOutPort { + SceVideoOutResolutionStatus resolution; + std::array buffer_slots; + std::array buffer_labels; // should be contiguous in memory + static_assert(sizeof(buffer_labels[0]) == 8u); + std::array groups; + FlipStatus flip_status; + SceVideoOutVblankStatus vblank_status; + std::vector flip_events; + std::vector vblank_events; + std::mutex vo_mutex; + std::mutex port_mutex; + std::condition_variable vo_cv; + std::condition_variable vblank_cv; + int flip_rate = 0; + int prev_index = -1; + bool is_open = false; + bool is_hdr = false; + + s32 FindFreeGroup() const { + s32 index = 0; + while (index < groups.size() && groups[index].is_occupied) { + index++; + } + return index; + } + + bool IsVoLabel(const u64* address) const { + const u64* start = &buffer_labels[0]; + const u64* end = &buffer_labels[MaxDisplayBuffers - 1]; + return address >= start && address <= end; + } + + void WaitVoLabel(auto&& pred) { + std::unique_lock lk{vo_mutex}; + vo_cv.wait(lk, pred); + } + + void SignalVoLabel() { + std::scoped_lock lk{vo_mutex}; + vo_cv.notify_one(); + } + + [[nodiscard]] int NumRegisteredBuffers() const { + return std::count_if(buffer_slots.cbegin(), buffer_slots.cend(), + [](auto& buffer) { return buffer.group_index != -1; }); + } +}; + +struct ServiceThreadParams { + u32 unknown; + bool set_priority; + u32 priority; + bool set_affinity; + u64 affinity; +}; + +class VideoOutDriver { +public: + VideoOutDriver(u32 width, u32 height); + ~VideoOutDriver(); + + int Open(const ServiceThreadParams* params); + void Close(s32 handle); + + VideoOutPort* GetPort(s32 handle); + + int RegisterBuffers(VideoOutPort* port, s32 startIndex, void* const* addresses, s32 bufferNum, + const BufferAttribute* attribute); + int UnregisterBuffers(VideoOutPort* port, s32 attributeIndex); + int ChangeBufferAttribute(VideoOutPort* port, s32 bufferIndex, + const BufferAttribute* attribute); + + bool SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop = false); + +private: + struct Request { + Vulkan::Frame* frame; + VideoOutPort* port; + s64 flip_arg; + s32 index; + bool eop; + + operator bool() const noexcept { + return frame != nullptr; + } + }; + + void Flip(const Request& req); + void DrawBlankFrame(); // Video port out not open + void DrawLastFrame(); // Used when there is no flip request + void SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop = false); + void PresentThread(std::stop_token token); + + std::mutex mutex; + VideoOutPort main_port{}; + std::jthread present_thread; + std::queue requests; +}; + +} // namespace Libraries::VideoOut diff --git a/gpu/shadps4/core/libraries/videoout/video_out.cpp b/gpu/shadps4/core/libraries/videoout/video_out.cpp new file mode 100644 index 0000000..1cf6d2a --- /dev/null +++ b/gpu/shadps4/core/libraries/videoout/video_out.cpp @@ -0,0 +1,515 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "common/elf_info.h" +#include "common/logging/log.h" +#include "core/emulator_settings.h" +#include "core/libraries/libs.h" +#include "core/libraries/system/userservice.h" +#include "core/libraries/videoout/driver.h" +#include "core/libraries/videoout/video_out.h" +#include "core/libraries/videoout/videoout_error.h" +#include "core/platform.h" +#include "video_core/renderer_vulkan/vk_presenter.h" + +extern std::unique_ptr presenter; + +namespace Libraries::VideoOut { + +static std::unique_ptr driver; + +void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat, + u32 tilingMode, u32 aspectRatio, u32 width, + u32 height, u32 pitchInPixel) { + LOG_INFO(Lib_VideoOut, + "pixelFormat = {}, tilingMode = {}, aspectRatio = {}, width = {}, height = {}, " + "pitchInPixel = {}", + GetPixelFormatString(pixelFormat), tilingMode, aspectRatio, width, height, + pitchInPixel); + + std::memset(attribute, 0, sizeof(BufferAttribute)); + attribute->pixel_format = static_cast(pixelFormat); + attribute->tiling_mode = static_cast(tilingMode); + attribute->aspect_ratio = aspectRatio; + attribute->width = width; + attribute->height = height; + attribute->pitch_in_pixel = pitchInPixel; + attribute->option = SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE; +} + +s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::OrbisKernelEqueue eq, s32 handle, void* udata) { + LOG_INFO(Lib_VideoOut, "handle = {}", handle); + + auto* port = driver->GetPort(handle); + if (port == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + auto equeue = Kernel::GetEqueue(eq); + if (equeue == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE; + } + + Kernel::EqueueEvent event{}; + event.event.ident = static_cast(OrbisVideoOutInternalEventId::Flip); + event.event.filter = Kernel::OrbisKernelEvent::Filter::VideoOut; + event.event.flags = Kernel::OrbisKernelEvent::Flags::Add; + event.event.udata = udata; + event.event.fflags = 0; + event.event.data = 0; + event.data = port; + equeue->AddEvent(event); + + port->flip_events.push_back(eq); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutDeleteFlipEvent(Kernel::OrbisKernelEqueue eq, s32 handle) { + auto* port = driver->GetPort(handle); + if (port == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + auto equeue = Kernel::GetEqueue(eq); + if (equeue == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE; + } + equeue->RemoveEvent(handle, Kernel::OrbisKernelEvent::Filter::VideoOut); + port->flip_events.erase(find(port->flip_events.begin(), port->flip_events.end(), eq)); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::OrbisKernelEqueue eq, s32 handle, void* udata) { + LOG_INFO(Lib_VideoOut, "handle = {}", handle); + + auto* port = driver->GetPort(handle); + if (port == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + auto equeue = Kernel::GetEqueue(eq); + if (equeue == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE; + } + + Kernel::EqueueEvent event{}; + event.event.ident = static_cast(OrbisVideoOutInternalEventId::Vblank); + event.event.filter = Kernel::OrbisKernelEvent::Filter::VideoOut; + event.event.flags = Kernel::OrbisKernelEvent::Flags::Add; + event.event.udata = udata; + event.event.fflags = 0; + event.event.data = 0; + event.data = port; + equeue->AddEvent(event); + + port->vblank_events.push_back(eq); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutDeleteVblankEvent(Kernel::OrbisKernelEqueue eq, s32 handle) { + auto* port = driver->GetPort(handle); + if (port == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + auto equeue = Kernel::GetEqueue(eq); + if (equeue == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE; + } + equeue->RemoveEvent(handle, Kernel::OrbisKernelEvent::Filter::VideoOut); + port->vblank_events.erase(find(port->vblank_events.begin(), port->vblank_events.end(), eq)); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, + s32 bufferNum, const BufferAttribute* attribute) { + if (!addresses || !attribute) { + LOG_ERROR(Lib_VideoOut, "Addresses are null"); + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + + auto* port = driver->GetPort(handle); + if (!port || !port->is_open) { + LOG_ERROR(Lib_VideoOut, "Invalid handle = {}", handle); + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + return driver->RegisterBuffers(port, startIndex, addresses, bufferNum, attribute); +} + +s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate) { + LOG_TRACE(Lib_VideoOut, "called"); + driver->GetPort(handle)->flip_rate = rate; + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) { + LOG_TRACE(Lib_VideoOut, "called"); + auto* port = driver->GetPort(handle); + std::unique_lock lock{port->port_mutex}; + s32 pending = port->flip_status.flip_pending_num; + return pending; +} + +s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg) { + auto* port = driver->GetPort(handle); + if (!port) { + LOG_ERROR(Lib_VideoOut, "Invalid handle = {}", handle); + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + if (flipMode != 1) { + LOG_WARNING(Lib_VideoOut, "flipmode = {}", flipMode); + } + + if (bufferIndex < -1 || bufferIndex > 15) { + LOG_ERROR(Lib_VideoOut, "Invalid bufferIndex = {}", bufferIndex); + return ORBIS_VIDEO_OUT_ERROR_INVALID_INDEX; + } + + if (bufferIndex != -1 && port->buffer_slots[bufferIndex].group_index < 0) { + LOG_ERROR(Lib_VideoOut, "Slot in bufferIndex = {} is not registered", bufferIndex); + return ORBIS_VIDEO_OUT_ERROR_INVALID_INDEX; + } + + LOG_DEBUG(Lib_VideoOut, "bufferIndex = {}, flipMode = {}, flipArg = {}", bufferIndex, flipMode, + flipArg); + + if (!driver->SubmitFlip(port, bufferIndex, flipArg)) { + LOG_ERROR(Lib_VideoOut, "Flip queue is full"); + return ORBIS_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL; + } + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::OrbisKernelEvent* ev) { + if (ev == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + if (ev->filter != Kernel::OrbisKernelEvent::Filter::VideoOut) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT; + } + + OrbisVideoOutInternalEventId internal_event_id = + static_cast(ev->ident); + switch (internal_event_id) { + case OrbisVideoOutInternalEventId::Flip: + return static_cast(OrbisVideoOutEventId::Flip); + case OrbisVideoOutInternalEventId::Vblank: + case OrbisVideoOutInternalEventId::SysVblank: + return static_cast(OrbisVideoOutEventId::Vblank); + case OrbisVideoOutInternalEventId::PreVblankStart: + return static_cast(OrbisVideoOutEventId::PreVblankStart); + case OrbisVideoOutInternalEventId::SetMode: + return static_cast(OrbisVideoOutEventId::SetMode); + case OrbisVideoOutInternalEventId::Position: + return static_cast(OrbisVideoOutEventId::Position); + default: { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT; + } + } +} + +s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::OrbisKernelEvent* ev, s64* data) { + if (ev == nullptr || data == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + if (ev->filter != Kernel::OrbisKernelEvent::Filter::VideoOut) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT; + } + + auto event_data = ev->data >> 0x10; + if (ev->ident != static_cast(OrbisVideoOutInternalEventId::Flip) || ev->data >= 0) { + *data = event_data; + } else { + *data = event_data | 0xffff000000000000; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutGetEventCount(const Kernel::OrbisKernelEvent* ev) { + if (ev == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + if (ev->filter != Kernel::OrbisKernelEvent::Filter::VideoOut) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT; + } + + auto event_data = static_cast(ev->data); + return event_data.count; +} + +s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) { + if (!status) { + LOG_ERROR(Lib_VideoOut, "Flip status is null"); + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + + auto* port = driver->GetPort(handle); + if (!port) { + LOG_ERROR(Lib_VideoOut, "Invalid port handle = {}", handle); + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + { + std::unique_lock lock{port->port_mutex}; + *status = port->flip_status; + } + + LOG_TRACE(Lib_VideoOut, + "count = {}, processTime = {}, tsc = {}, submitTsc = {}, flipArg = {}, gcQueueNum = " + "{}, flipPendingNum = {}, currentBuffer = {}", + status->count, status->process_time, status->tsc, status->submit_tsc, + status->flip_arg, status->gc_queue_num, status->flip_pending_num, + status->current_buffer); + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutGetVblankStatus(int handle, SceVideoOutVblankStatus* status) { + if (status == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + + auto* port = driver->GetPort(handle); + if (!port) { + LOG_ERROR(Lib_VideoOut, "Invalid port handle = {}", handle); + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + std::unique_lock lock{port->vo_mutex}; + *status = port->vblank_status; + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutionStatus* status) { + LOG_INFO(Lib_VideoOut, "called"); + auto* port = driver->GetPort(handle); + if (!port || !port->is_open) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + *status = port->resolution; + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutOpen(Libraries::UserService::OrbisUserServiceUserId userId, s32 busType, + s32 index, const void* param) { + LOG_INFO(Lib_VideoOut, "called"); + ASSERT(busType == SCE_VIDEO_OUT_BUS_TYPE_MAIN); + + if (index != 0) { + LOG_ERROR(Lib_VideoOut, "Index != 0"); + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + + auto* params = reinterpret_cast(param); + int handle = driver->Open(params); + + if (handle < 0) { + LOG_ERROR(Lib_VideoOut, "All available handles are open"); + return ORBIS_VIDEO_OUT_ERROR_RESOURCE_BUSY; + } + + return handle; +} + +s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle) { + driver->Close(handle); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutUnregisterBuffers(s32 handle, s32 attributeIndex) { + auto* port = driver->GetPort(handle); + if (!port || !port->is_open) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + return driver->UnregisterBuffers(port, attributeIndex); +} + +s32 PS4_SYSV_ABI sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr) { + if (label_addr == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + auto* port = driver->GetPort(handle); + if (!port) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + *label_addr = reinterpret_cast(port->buffer_labels.data()); + return 16; +} + +s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, void** unk) { + auto* port = driver->GetPort(handle); + if (!port) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + Platform::IrqC::Instance()->RegisterOnce( + Platform::InterruptId::GfxFlip, [=](Platform::InterruptId irq) { + ASSERT_MSG(irq == Platform::InterruptId::GfxFlip, "An unexpected IRQ occured"); + ASSERT_MSG(port->buffer_labels[buf_id] == 1, "Out of order flip IRQ"); + const auto result = driver->SubmitFlip(port, buf_id, flip_arg, true); + ASSERT_MSG(result, "EOP flip submission failed"); + }); + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutGetDeviceCapabilityInfo( + s32 handle, SceVideoOutDeviceCapabilityInfo* pDeviceCapabilityInfo) { + pDeviceCapabilityInfo->capability = 0; + if (presenter->IsHDRSupported()) { + auto& game_info = Common::ElfInfo::Instance(); + if (game_info.GetPSFAttributes().support_hdr) { + pDeviceCapabilityInfo->capability |= ORBIS_VIDEO_OUT_DEVICE_CAPABILITY_BT2020_PQ; + } + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutWaitVblank(s32 handle) { + auto* port = driver->GetPort(handle); + if (!port) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + std::unique_lock lock{port->vo_mutex}; + const auto prev_counter = port->vblank_status.count; + port->vblank_cv.wait(lock, [&]() { return prev_counter != port->vblank_status.count; }); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma) { + if (gamma < 0.1f || gamma > 2.0f) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + settings->gamma = gamma; + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings) { + if (settings == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + + auto* port = driver->GetPort(handle); + if (!port) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + presenter->GetPPSettingsRef().gamma = settings->gamma; + return ORBIS_OK; +} + +struct Mode { + u32 size; + u8 encoding; + u8 range; + u8 colorimetry; + u8 depth; + u64 refresh_rate; + u64 resolution; + u8 reserved[8]; +}; + +void PS4_SYSV_ABI sceVideoOutModeSetAny_(Mode* mode, u32 size) { + std::memset(mode, 0xff, size); + mode->size = size; +} + +s32 PS4_SYSV_ABI sceVideoOutConfigureOutputMode_(s32 handle, u32 reserved, const Mode* mode, + const void* options, u32 size_mode, + u32 size_options) { + auto* port = driver->GetPort(handle); + if (!port) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + if (reserved != 0) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + + switch (mode->colorimetry) { + case OrbisVideoOutColorimetry::Any: + port->is_hdr = false; + break; + case OrbisVideoOutColorimetry::Bt2020PQ: + if (Common::ElfInfo::Instance().GetPSFAttributes().support_hdr) { + port->is_hdr = true; + } + break; + default: + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutSubmitChangeBufferAttribute(s32 handle, s32 attributeIndex, + const BufferAttribute* attribute) { + auto* port = driver->GetPort(handle); + if (!port || !port->is_open) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + return driver->ChangeBufferAttribute(port, attributeIndex, attribute); +} + +s32 PS4_SYSV_ABI sceVideoOutSetWindowModeMargins(s32 handle, s32 top, s32 bottom) { + LOG_ERROR(Lib_VideoOut, "(STUBBED) called top = {}, bottom = {}", top, bottom); + return ORBIS_OK; +} + +void RegisterLib(Core::Loader::SymbolsResolver* sym) { + driver = std::make_unique(EmulatorSettings.GetInternalScreenWidth(), + EmulatorSettings.GetInternalScreenHeight()); + + LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutGetFlipStatus); + LIB_FUNCTION("U46NwOiJpys", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutSubmitFlip); + LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutRegisterBuffers); + LIB_FUNCTION("HXzjK9yI30k", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutAddFlipEvent); + LIB_FUNCTION("Xru92wHJRmg", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutAddVblankEvent); + LIB_FUNCTION("CBiu4mCE1DA", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutSetFlipRate); + LIB_FUNCTION("i6-sR91Wt-4", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutSetBufferAttribute); + LIB_FUNCTION("6kPnj51T62Y", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutGetResolutionStatus); + LIB_FUNCTION("8XGijEoThE0", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutGetResolutionStatus); // sceVideoOutSysGetResolutionStatus + LIB_FUNCTION("Ek+VR4lcJQI", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutAddVblankEvent); // sceVideoOutSysAddVblankEvent + LIB_FUNCTION("Up36PTk687E", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutOpen); + LIB_FUNCTION("zgXifHT9ErY", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutIsFlipPending); + LIB_FUNCTION("N5KDtkIjjJ4", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutUnregisterBuffers); + LIB_FUNCTION("OcQybQejHEY", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutGetBufferLabelAddress); + LIB_FUNCTION("uquVH4-Du78", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutClose); + LIB_FUNCTION("1FZBKy8HeNU", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutGetVblankStatus); + LIB_FUNCTION("d1AjT2uZJn0", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutGetVblankStatus); + LIB_FUNCTION("kGVLc3htQE8", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutGetDeviceCapabilityInfo); + LIB_FUNCTION("j6RaAUlaLv0", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutWaitVblank); + LIB_FUNCTION("U2JJtSqNKZI", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutGetEventId); + LIB_FUNCTION("rWUTcKdkUzQ", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutGetEventData); + LIB_FUNCTION("Mt4QHHkxkOc", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutGetEventCount); + LIB_FUNCTION("DYhhWbJSeRg", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutColorSettingsSetGamma); + LIB_FUNCTION("pv9CI5VC+R0", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutAdjustColor); + LIB_FUNCTION("-Ozn0F1AFRg", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutDeleteFlipEvent); + LIB_FUNCTION("oNOQn3knW6s", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutDeleteVblankEvent); + LIB_FUNCTION("pjkDsgxli6c", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutModeSetAny_); + LIB_FUNCTION("N1bEoJ4SRw4", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutConfigureOutputMode_); + LIB_FUNCTION("MTxxrOCeSig", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutSetWindowModeMargins); + LIB_FUNCTION("IOdgHlCGU-k", "libSceVideoOut", 1, "libSceVideoOut", + sceVideoOutSubmitChangeBufferAttribute); +} + +} // namespace Libraries::VideoOut diff --git a/gpu/shadps4/core/libraries/videoout/video_out.h b/gpu/shadps4/core/libraries/videoout/video_out.h new file mode 100644 index 0000000..09b79e8 --- /dev/null +++ b/gpu/shadps4/core/libraries/videoout/video_out.h @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "core/libraries/kernel/equeue.h" +#include "core/libraries/videoout/buffer.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::VideoOut { + +// SceVideoOutBusType +constexpr int SCE_VIDEO_OUT_BUS_TYPE_MAIN = 0; // Main output +constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_SOCIAL_SCREEN = 5; // Aux output for social +constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_GAME_LIVE_STREAMING = 6; // Aux output for screaming + +// SceVideoOutRefreshRate +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_UNKNOWN = 0; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_23_98HZ = 1; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_50HZ = 2; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ = 3; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_119_88HZ = 13; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_89_91HZ = 35; +constexpr s64 SCE_VIDEO_OUT_REFRESH_RATE_ANY = 0xFFFFFFFFFFFFFFFFUL; + +constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB = 0x80000000; +constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB = 0x80002200; +constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10 = 0x88060000; +constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_SRGB = 0x88000000; +constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_BT2020_PQ = 0x88740000; +constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A16R16G16B16_FLOAT = 0xC1060000; +constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_YCBCR420_BT709 = 0x08322200; + +constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE = 0; +constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_VR = 7; +constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_STRICT_COLORIMETRY = 8; + +constexpr int ORBIS_VIDEO_OUT_DEVICE_CAPABILITY_BT2020_PQ = 0x80; + +enum OrbisVideoOutColorimetry : u8 { + Bt2020PQ = 12, + Any = 0xFF, +}; + +enum class OrbisVideoOutEventId : s16 { + Flip = 0, + Vblank = 1, + PreVblankStart = 2, + SetMode = 8, + Position = 12, +}; + +enum class OrbisVideoOutInternalEventId : s16 { + Flip = 0x6, + Vblank = 0x7, + SetMode = 0x51, + Position = 0x58, + PreVblankStart = 0x59, + SysVblank = 0x63, +}; + +enum class AspectRatioMode : s32 { + Ratio16_9 = 0, +}; + +struct FlipStatus { + u64 count = 0; + u64 process_time = 0; + u64 tsc = 0; + s64 flip_arg = -1; + u64 submit_tsc = 0; + u64 reserved0 = 0; + s32 gc_queue_num = 0; + s32 flip_pending_num = 0; + s32 current_buffer = -1; + u32 reserved1 = 0; +}; + +struct SceVideoOutResolutionStatus { + s32 full_width = 1280; + s32 full_height = 720; + s32 pane_width = 1280; + s32 pane_height = 720; + u64 refresh_rate = SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ; + float screen_size_in_inch = 50; + u16 flags = 0; + u16 reserved0 = 0; + u32 reserved1[3] = {0}; +}; + +struct SceVideoOutVblankStatus { + u64 count = 0; + u64 process_time = 0; + u64 tsc = 0; + u64 reserved[1] = {0}; + u8 flags = 0; + u8 pad1[7] = {}; +}; + +struct SceVideoOutDeviceCapabilityInfo { + u64 capability; +}; + +struct SceVideoOutColorSettings { + float gamma; + u32 reserved[3]; +}; + +struct OrbisVideoOutEventData { + u64 time : 12; + u64 count : 4; + u64 flip_arg : 48; +}; + +void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat, + u32 tilingMode, u32 aspectRatio, u32 width, + u32 height, u32 pitchInPixel); +s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::OrbisKernelEqueue eq, s32 handle, void* udata); +s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::OrbisKernelEqueue eq, s32 handle, void* udata); +s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, + s32 bufferNum, const BufferAttribute* attribute); +s32 PS4_SYSV_ABI sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr); +s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate); +s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle); +s32 PS4_SYSV_ABI sceVideoOutWaitVblank(s32 handle); +s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg); +s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status); +s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutionStatus* status); +s32 PS4_SYSV_ABI sceVideoOutOpen(Libraries::UserService::OrbisUserServiceUserId userId, s32 busType, + s32 index, const void* param); +s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle); +s32 PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::OrbisKernelEvent* ev); +s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::OrbisKernelEvent* ev, s64* data); +s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma); +s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings); + +// Internal system functions +s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, void** unk); + +void RegisterLib(Core::Loader::SymbolsResolver* sym); + +} // namespace Libraries::VideoOut diff --git a/gpu/shadps4/core/libraries/videoout/videoout_error.h b/gpu/shadps4/core/libraries/videoout/videoout_error.h new file mode 100644 index 0000000..b1ed18c --- /dev/null +++ b/gpu/shadps4/core/libraries/videoout/videoout_error.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// VideoOut library +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_PIXEL_FORMAT = 0x80290003; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_PITCH = 0x80290004; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_RESOLUTION = 0x80290005; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_FLIP_MODE = 0x80290006; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_TILING_MODE = 0x80290007; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO = 0x80290008; +constexpr int ORBIS_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT = 0x8029000D; +constexpr int ORBIS_VIDEO_OUT_ERROR_NO_EMPTY_SLOT = 0x8029000F; +constexpr int ORBIS_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; +constexpr int ORBIS_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_MEMORY = 0x80290013; +constexpr int ORBIS_VIDEO_OUT_ERROR_MEMORY_NOT_PHYSICALLY_CONTIGUOUS = 0x80290014; +constexpr int ORBIS_VIDEO_OUT_ERROR_MEMORY_INVALID_ALIGNMENT = 0x80290015; +constexpr int ORBIS_VIDEO_OUT_ERROR_UNSUPPORTED_OUTPUT_MODE = 0x80290016; +constexpr int ORBIS_VIDEO_OUT_ERROR_OVERFLOW = 0x80290017; +constexpr int ORBIS_VIDEO_OUT_ERROR_NO_DEVICE = 0x80290018; +constexpr int ORBIS_VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE = 0x80290019; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; +constexpr int ORBIS_VIDEO_OUT_ERROR_UNKNOWN = 0x802900FE; +constexpr int ORBIS_VIDEO_OUT_ERROR_FATAL = 0x802900FF; +constexpr int ORBIS_VIDEO_OUT_ERROR_ENOMEM = 0x8029100C; diff --git a/gpu/shadps4/core/platform.h b/gpu/shadps4/core/platform.h new file mode 100644 index 0000000..bdb5070 --- /dev/null +++ b/gpu/shadps4/core/platform.h @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/logging/log.h" +#include "common/singleton.h" +#include "common/types.h" + +#include + +#include +#include +#include +#include + +namespace Platform { + +enum class InterruptId : u32 { + Compute0RelMem = 0x00, + Compute1RelMem = 0x01, + Compute2RelMem = 0x02, + Compute3RelMem = 0x03, + Compute4RelMem = 0x04, + Compute5RelMem = 0x05, + Compute6RelMem = 0x06, + GfxEop = 0x40, + GfxFlip = 0x08, + GpuIdle = 0x09, + + InterruptIdMax = 0x40, ///< Max possible value (GfxEop) +}; + +using IrqHandler = std::function; + +struct IrqController { + void RegisterOnce(InterruptId irq, IrqHandler handler) { + ASSERT_MSG(static_cast(irq) <= static_cast(InterruptId::InterruptIdMax), + "Invalid IRQ number"); + auto& ctx = irq_contexts.try_emplace(irq).first->second; + std::unique_lock lock{ctx.m_lock}; + ctx.one_time_subscribers.emplace(handler); + } + + void Register(InterruptId irq, IrqHandler handler, void* uid) { + ASSERT_MSG(static_cast(irq) <= static_cast(InterruptId::InterruptIdMax), + "Invalid IRQ number"); + auto& ctx = irq_contexts.try_emplace(irq).first->second; + + std::unique_lock lock{ctx.m_lock}; + ASSERT_MSG(ctx.persistent_handlers.find(uid) == ctx.persistent_handlers.cend(), + "The handler is already registered!"); + ctx.persistent_handlers.emplace(uid, handler); + } + + void Unregister(InterruptId irq, void* uid) { + ASSERT_MSG(static_cast(irq) <= static_cast(InterruptId::InterruptIdMax), + "Invalid IRQ number"); + auto& ctx = irq_contexts.try_emplace(irq).first->second; + std::unique_lock lock{ctx.m_lock}; + ctx.persistent_handlers.erase(uid); + } + + void Signal(InterruptId irq) { + ASSERT_MSG(static_cast(irq) <= static_cast(InterruptId::InterruptIdMax), + "Unexpected IRQ signaled"); + auto& ctx = irq_contexts.try_emplace(irq).first->second; + std::unique_lock lock{ctx.m_lock}; + + LOG_TRACE(Core, "IRQ signaled: {}", magic_enum::enum_name(irq)); + + for (auto& [uid, h] : ctx.persistent_handlers) { + h(irq); + } + + if (!ctx.one_time_subscribers.empty()) { + const auto& h = ctx.one_time_subscribers.front(); + h(irq); + + ctx.one_time_subscribers.pop(); + } + } + +private: + struct IrqContext { + std::unordered_map persistent_handlers{}; + std::queue one_time_subscribers{}; + std::mutex m_lock{}; + }; + std::unordered_map irq_contexts{}; +}; + +using IrqC = Common::Singleton; + +} // namespace Platform diff --git a/gpu/shadps4/shader_recompiler/backend/bindings.h b/gpu/shadps4/shader_recompiler/backend/bindings.h new file mode 100644 index 0000000..510b0c0 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/bindings.h @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Shader::Backend { + +struct Bindings { + u32 unified{}; + u32 buffer{}; + u32 user_data{}; + + auto operator<=>(const Bindings&) const = default; +}; + +} // namespace Shader::Backend diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv.cpp new file mode 100644 index 0000000..10d661c --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -0,0 +1,743 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/func_traits.h" +#include "shader_recompiler/backend/spirv/emit_spirv.h" +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::Backend::SPIRV { +namespace { + +static constexpr spv::ExecutionMode GetInputPrimitiveType(AmdGpu::PrimitiveType type) { + switch (type) { + case AmdGpu::PrimitiveType::PointList: + return spv::ExecutionMode::InputPoints; + case AmdGpu::PrimitiveType::LineList: + case AmdGpu::PrimitiveType::LineStrip: + return spv::ExecutionMode::InputLines; + case AmdGpu::PrimitiveType::TriangleList: + case AmdGpu::PrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::RectList: + return spv::ExecutionMode::Triangles; + case AmdGpu::PrimitiveType::AdjTriangleList: + return spv::ExecutionMode::InputTrianglesAdjacency; + case AmdGpu::PrimitiveType::AdjLineList: + return spv::ExecutionMode::InputLinesAdjacency; + default: + UNREACHABLE_MSG("Unknown input primitive type {}", u32(type)); + } +} + +static constexpr spv::ExecutionMode GetOutputPrimitiveType(AmdGpu::GsOutputPrimitiveType type) { + switch (type) { + case AmdGpu::GsOutputPrimitiveType::PointList: + return spv::ExecutionMode::OutputVertices; + case AmdGpu::GsOutputPrimitiveType::LineStrip: + return spv::ExecutionMode::OutputLineStrip; + case AmdGpu::GsOutputPrimitiveType::TriangleStrip: + return spv::ExecutionMode::OutputTriangleStrip; + default: + UNREACHABLE_MSG("Unknown output primitive type {}", u32(type)); + } +} + +template +void SetDefinition(EmitContext& ctx, IR::Inst* inst, Args... args) { + inst->SetDefinition(func(ctx, std::forward(args)...)); +} + +template +ArgType Arg(EmitContext& ctx, const IR::Value& arg) { + if constexpr (std::is_same_v) { + return ctx.Def(arg); + } else if constexpr (std::is_same_v) { + return arg; + } else if constexpr (std::is_same_v) { + return arg.U32(); + } else if constexpr (std::is_same_v) { + return arg.U64(); + } else if constexpr (std::is_same_v) { + return arg.U1(); + } else if constexpr (std::is_same_v) { + return arg.Attribute(); + } else if constexpr (std::is_same_v) { + return arg.ScalarReg(); + } else if constexpr (std::is_same_v) { + return arg.VectorReg(); + } else if constexpr (std::is_same_v) { + return arg.StringLiteral(); + } else if constexpr (std::is_same_v) { + return arg.Patch(); + } + UNREACHABLE(); +} + +template +void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence) { + using Traits = Common::FuncTraits; + if constexpr (std::is_same_v) { + if constexpr (is_first_arg_inst) { + SetDefinition( + ctx, inst, inst, + Arg>(ctx, inst->Arg(I))...); + } else { + SetDefinition( + ctx, inst, Arg>(ctx, inst->Arg(I))...); + } + } else { + if constexpr (is_first_arg_inst) { + func(ctx, inst, Arg>(ctx, inst->Arg(I))...); + } else { + func(ctx, Arg>(ctx, inst->Arg(I))...); + } + } +} + +template +void Invoke(EmitContext& ctx, IR::Inst* inst) { + using Traits = Common::FuncTraits; + static_assert(Traits::NUM_ARGS >= 1, "Insufficient arguments"); + if constexpr (Traits::NUM_ARGS == 1) { + Invoke(ctx, inst, std::make_index_sequence<0>{}); + } else { + using FirstArgType = typename Traits::template ArgType<1>; + static constexpr bool is_first_arg_inst = std::is_same_v; + using Indices = std::make_index_sequence; + Invoke(ctx, inst, Indices{}); + } +} + +void EmitInst(EmitContext& ctx, IR::Inst* inst) { + switch (inst->GetOpcode()) { +#define OPCODE(name, result_type, ...) \ + case IR::Opcode::name: \ + return Invoke<&Emit##name>(ctx, inst); +#include "shader_recompiler/ir/opcodes.inc" +#undef OPCODE + } + UNREACHABLE_MSG("Invalid opcode {}", inst->GetOpcode()); +} + +Id TypeId(const EmitContext& ctx, IR::Type type) { + switch (type) { + case IR::Type::U1: + return ctx.U1[1]; + case IR::Type::U32: + return ctx.U32[1]; + case IR::Type::U32x2: + return ctx.U32[2]; + case IR::Type::U32x3: + return ctx.U32[3]; + case IR::Type::U32x4: + return ctx.U32[4]; + case IR::Type::F32: + return ctx.F32[1]; + case IR::Type::U64: + return ctx.U64; + default: + UNREACHABLE_MSG("Phi node type {}", type); + } +} + +void Traverse(EmitContext& ctx, const IR::Program& program) { + IR::Block* current_block{}; + for (const IR::AbstractSyntaxNode& node : program.syntax_list) { + switch (node.type) { + case IR::AbstractSyntaxNode::Type::Block: { + const Id label{node.data.block->Definition()}; + if (current_block) { + ctx.OpBranch(label); + } + current_block = node.data.block; + ctx.AddLabel(label); + for (IR::Inst& inst : node.data.block->Instructions()) { + EmitInst(ctx, &inst); + } + ctx.first_to_last_label_map[label.value] = ctx.last_label; + break; + } + case IR::AbstractSyntaxNode::Type::If: { + const Id if_label{node.data.if_node.body->Definition()}; + const Id endif_label{node.data.if_node.merge->Definition()}; + ctx.OpSelectionMerge(endif_label, spv::SelectionControlMask::MaskNone); + ctx.OpBranchConditional(ctx.Def(node.data.if_node.cond), if_label, endif_label); + break; + } + case IR::AbstractSyntaxNode::Type::Loop: { + const Id body_label{node.data.loop.body->Definition()}; + const Id continue_label{node.data.loop.continue_block->Definition()}; + const Id endloop_label{node.data.loop.merge->Definition()}; + + ctx.OpLoopMerge(endloop_label, continue_label, spv::LoopControlMask::MaskNone); + ctx.OpBranch(body_label); + break; + } + case IR::AbstractSyntaxNode::Type::Break: { + const Id break_label{node.data.break_node.merge->Definition()}; + const Id skip_label{node.data.break_node.skip->Definition()}; + ctx.OpBranchConditional(ctx.Def(node.data.break_node.cond), break_label, skip_label); + break; + } + case IR::AbstractSyntaxNode::Type::EndIf: + if (current_block) { + ctx.OpBranch(node.data.end_if.merge->Definition()); + } + break; + case IR::AbstractSyntaxNode::Type::Repeat: { + Id cond{ctx.Def(node.data.repeat.cond)}; + const Id loop_header_label{node.data.repeat.loop_header->Definition()}; + const Id merge_label{node.data.repeat.merge->Definition()}; + ctx.OpBranchConditional(cond, loop_header_label, merge_label); + break; + } + case IR::AbstractSyntaxNode::Type::Return: + ctx.OpReturn(); + break; + case IR::AbstractSyntaxNode::Type::Unreachable: + ctx.OpUnreachable(); + break; + } + if (node.type != IR::AbstractSyntaxNode::Type::Block) { + current_block = nullptr; + } + } +} + +Id DefineMain(EmitContext& ctx, const IR::Program& program) { + const Id void_function{ctx.TypeFunction(ctx.void_id)}; + const Id main{ctx.OpFunction(ctx.void_id, spv::FunctionControlMask::MaskNone, void_function)}; + for (IR::Block* const block : program.blocks) { + block->SetDefinition(ctx.OpLabel()); + } + Traverse(ctx, program); + ctx.OpFunctionEnd(); + return main; +} + +spv::ExecutionMode ExecutionMode(AmdGpu::TessellationType primitive) { + switch (primitive) { + case AmdGpu::TessellationType::Isoline: + return spv::ExecutionMode::Isolines; + case AmdGpu::TessellationType::Triangle: + return spv::ExecutionMode::Triangles; + case AmdGpu::TessellationType::Quad: + return spv::ExecutionMode::Quads; + } + UNREACHABLE_MSG("Tessellation primitive {}", magic_enum::enum_name(primitive)); +} + +spv::ExecutionMode ExecutionMode(AmdGpu::TessellationPartitioning spacing) { + switch (spacing) { + case AmdGpu::TessellationPartitioning::Integer: + return spv::ExecutionMode::SpacingEqual; + case AmdGpu::TessellationPartitioning::FracOdd: + return spv::ExecutionMode::SpacingFractionalOdd; + case AmdGpu::TessellationPartitioning::FracEven: + return spv::ExecutionMode::SpacingFractionalEven; + case AmdGpu::TessellationPartitioning::Pow2: + // Pow2 rounds tessellation factors to the nearest power of 2, which has no + // direct Vulkan equivalent. SpacingEqual (integer) is the closest match. + LOG_WARNING(Render_Vulkan, "Tessellation partitioning Pow2 has no Vulkan equivalent, " + "falling back to SpacingEqual"); + return spv::ExecutionMode::SpacingEqual; + default: + break; + } + UNREACHABLE_MSG("Tessellation spacing {}", magic_enum::enum_name(spacing)); +} + +void SetupCapabilities(const Info& info, const Profile& profile, const RuntimeInfo& runtime_info, + EmitContext& ctx) { + ctx.AddCapability(spv::Capability::Image1D); + ctx.AddCapability(spv::Capability::Sampled1D); + ctx.AddCapability(spv::Capability::ImageQuery); + ctx.AddCapability(spv::Capability::Int8); + ctx.AddCapability(spv::Capability::Int16); + ctx.AddCapability(spv::Capability::Int64); + ctx.AddCapability(spv::Capability::StorageBuffer8BitAccess); + ctx.AddCapability(spv::Capability::StorageBuffer16BitAccess); + if (info.uses_fp16) { + ctx.AddCapability(spv::Capability::Float16); + } + if (info.uses_fp64) { + ctx.AddCapability(spv::Capability::Float64); + } + if (info.has_storage_images) { + ctx.AddCapability(spv::Capability::StorageImageExtendedFormats); + ctx.AddCapability(spv::Capability::StorageImageReadWithoutFormat); + ctx.AddCapability(spv::Capability::StorageImageWriteWithoutFormat); + if (profile.supports_image_load_store_lod) { + ctx.AddExtension("SPV_AMD_shader_image_load_store_lod"); + ctx.AddCapability(spv::Capability::ImageReadWriteLodAMD); + } + } + if (info.has_image_gather) { + ctx.AddCapability(spv::Capability::ImageGatherExtended); + } + if (info.has_image_query) { + ctx.AddCapability(spv::Capability::ImageQuery); + } + if ((info.uses_image_atomic_float_min_max && profile.supports_image_fp32_atomic_min_max) || + (info.uses_buffer_atomic_float_min_max && profile.supports_buffer_fp32_atomic_min_max)) { + ctx.AddExtension("SPV_EXT_shader_atomic_float_min_max"); + ctx.AddCapability(spv::Capability::AtomicFloat32MinMaxEXT); + } + if (info.uses_lane_id) { + ctx.AddCapability(spv::Capability::GroupNonUniform); + } + if (info.uses_group_quad) { + ctx.AddCapability(spv::Capability::GroupNonUniformQuad); + } + if (info.uses_group_shuffle) { + ctx.AddCapability(spv::Capability::GroupNonUniformShuffle); + } + if (info.uses_group_ballot || info.loads.Get(IR::Attribute::SubgroupLtMask)) { + ctx.AddCapability(spv::Capability::GroupNonUniformBallot); + } + if (info.uses_shader_clock) { + if (ctx.profile.supports_shader_subgroup_clock) { + ctx.AddExtension("SPV_KHR_shader_clock"); + ctx.AddCapability(spv::Capability::ShaderClockKHR); + } else { + LOG_WARNING(Render_Recompiler, + "Shader requires support for ShaderClockKHR capability" + " that your Vulkan instance does not advertise. Results may vary"); + } + } + const auto stage = info.sw_stage; + if (stage == SwStage::Vertex) { + ctx.AddExtension("SPV_KHR_shader_draw_parameters"); + ctx.AddCapability(spv::Capability::DrawParameters); + } + if (stage == SwStage::Geometry) { + ctx.AddCapability(spv::Capability::Geometry); + } + if (info.hw_stage == HwStage::Fragment) { + if (profile.supports_amd_shader_explicit_vertex_parameter) { + ctx.AddExtension("SPV_AMD_shader_explicit_vertex_parameter"); + } else if (profile.supports_fragment_shader_barycentric) { + ctx.AddExtension("SPV_KHR_fragment_shader_barycentric"); + ctx.AddCapability(spv::Capability::FragmentBarycentricKHR); + ctx.AddCapability(spv::Capability::InterpolationFunction); + } + if (info.loads.Get(IR::Attribute::SampleIndex) || + runtime_info.hw.fs.addr_flags.linear_sample_ena || + runtime_info.hw.fs.addr_flags.persp_sample_ena || + (!profile.supports_amd_shader_explicit_vertex_parameter && + profile.supports_fragment_shader_barycentric && + info.loads.Get(IR::Attribute::BaryCoordSmoothSample))) { + ctx.AddCapability(spv::Capability::SampleRateShading); + } + if (info.loads.GetAny(IR::Attribute::RenderTargetIndex)) { + ctx.AddCapability(spv::Capability::Geometry); + } + if (info.stores.Get(IR::Attribute::StencilRef) && profile.supports_shader_stencil_export) { + ctx.AddExtension("SPV_EXT_shader_stencil_export"); + ctx.AddCapability(spv::Capability::StencilExportEXT); + } + } + if (stage == SwStage::TessellationControl || stage == SwStage::TessellationEval) { + ctx.AddCapability(spv::Capability::Tessellation); + } + if (stage == SwStage::Vertex || stage == SwStage::TessellationControl || + stage == SwStage::TessellationEval) { + if (info.stores.GetAny(IR::Attribute::RenderTargetIndex)) { + ctx.AddCapability(spv::Capability::ShaderLayer); + } + if (info.stores.GetAny(IR::Attribute::ViewportIndex)) { + ctx.AddCapability(spv::Capability::ShaderViewportIndex); + } + } else if (stage == SwStage::Geometry && info.stores.GetAny(IR::Attribute::ViewportIndex)) { + ctx.AddCapability(spv::Capability::MultiViewport); + } + if (info.uses_dma) { + ctx.AddCapability(spv::Capability::PhysicalStorageBufferAddresses); + ctx.AddExtension("SPV_KHR_physical_storage_buffer"); + } + const auto shared_type_count = std::popcount(static_cast(info.shared_types)); + if (shared_type_count > 1 && profile.supports_workgroup_explicit_memory_layout) { + ctx.AddExtension("SPV_KHR_workgroup_memory_explicit_layout"); + ctx.AddCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR); + ctx.AddCapability(spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR); + } + if (info.uses_buffer_int64_atomics || info.uses_shared_int64_atomics) { + if (info.uses_buffer_int64_atomics) { + ASSERT_MSG(ctx.profile.supports_buffer_int64_atomics, + "Shader requires support for atomic Int64 buffer operations that your " + "Vulkan instance does not advertise"); + } + if (info.uses_shared_int64_atomics) { + ASSERT_MSG(ctx.profile.supports_shared_int64_atomics, + "Shader requires support for atomic Int64 shared memory operations that " + "your Vulkan instance does not advertise"); + } + ctx.AddCapability(spv::Capability::Int64Atomics); + } +} + +void DefineEntryPoint(const Info& info, EmitContext& ctx, Id main) { + const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size()); + spv::ExecutionModel execution_model{}; + switch (info.sw_stage) { + case SwStage::Compute: { + const std::array workgroup_size{ctx.runtime_info.hw.cs.workgroup_size}; + execution_model = spv::ExecutionModel::GLCompute; + ctx.AddExecutionMode(main, spv::ExecutionMode::LocalSize, workgroup_size[0], + workgroup_size[1], workgroup_size[2]); + break; + } + case SwStage::Vertex: + execution_model = spv::ExecutionModel::Vertex; + break; + case SwStage::TessellationControl: + execution_model = spv::ExecutionModel::TessellationControl; + ctx.AddCapability(spv::Capability::Tessellation); + ctx.AddExecutionMode(main, spv::ExecutionMode::OutputVertices, + ctx.runtime_info.sw.tcs.NumOutputControlPoints()); + break; + case SwStage::TessellationEval: { + execution_model = spv::ExecutionModel::TessellationEvaluation; + ctx.AddExecutionMode(main, ExecutionMode(ctx.runtime_info.sw.tes.tess_type)); + ctx.AddExecutionMode(main, ExecutionMode(ctx.runtime_info.sw.tes.tess_partitioning)); + ctx.AddExecutionMode(main, ctx.runtime_info.sw.tes.tess_topology == + AmdGpu::TessellationTopology::TriangleCcw + ? spv::ExecutionMode::VertexOrderCcw + : spv::ExecutionMode::VertexOrderCw); + break; + } + case SwStage::Fragment: + execution_model = spv::ExecutionModel::Fragment; + if (ctx.profile.lower_left_origin_mode) { + ctx.AddExecutionMode(main, spv::ExecutionMode::OriginLowerLeft); + } else { + ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); + } + if (info.has_discard) { + ctx.AddCapability(spv::Capability::DemoteToHelperInvocation); + } + if (info.stores.GetAny(IR::Attribute::Depth)) { + ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); + } + break; + case SwStage::Geometry: + execution_model = spv::ExecutionModel::Geometry; + ctx.AddExecutionMode(main, GetInputPrimitiveType(ctx.runtime_info.hw.gs.in_primitive)); + ctx.AddExecutionMode(main, GetOutputPrimitiveType(ctx.runtime_info.hw.gs.out_primitive[0])); + ctx.AddExecutionMode(main, spv::ExecutionMode::OutputVertices, + ctx.runtime_info.hw.gs.output_vertices); + ctx.AddExecutionMode(main, spv::ExecutionMode::Invocations, + ctx.runtime_info.hw.gs.num_invocations); + break; + default: + UNREACHABLE_MSG("Stage {}", u32(info.hw_stage)); + } + ctx.AddEntryPoint(execution_model, main, "main", interfaces); +} + +void SetupDenormFlushMode(EmitContext& ctx, const Profile& profile, const RuntimeInfo& runtime_info, + Id main_func) { + const auto fp32_denorm_mode = runtime_info.props.fp_denorm_mode32; + if (fp32_denorm_mode == AmdGpu::FpDenormMode::InOutFlush) { + if (profile.support_fp32_denorm_flush) { + ctx.AddCapability(spv::Capability::DenormFlushToZero); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 32U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float32 denorm flushing is not supported by the GPU"); + }); + } + } else { + LOG_WARNING(Render_Vulkan, "Unknown FP denorm mode {}", u32(fp32_denorm_mode)); + } + + if (!ctx.info.uses_fp16 && !ctx.info.uses_fp64) { + return; + } + + const auto fp16_64_denorm_mode = runtime_info.props.fp_denorm_mode16_64; + const auto same_denorm_mode = fp16_64_denorm_mode == fp32_denorm_mode; + if (!same_denorm_mode && !profile.supports_denorm_behavior_independence) { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float32 and Float16/64 denorm modes are different but the " + "GPU does not support that"); + }); + return; + } + + if (fp16_64_denorm_mode == AmdGpu::FpDenormMode::InOutFlush) { + if (profile.support_fp16_denorm_flush) { + ctx.AddCapability(spv::Capability::DenormFlushToZero); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 16U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float16 denorm flushing is not supported by the GPU"); + }); + } + if (profile.support_fp64_denorm_flush) { + ctx.AddCapability(spv::Capability::DenormFlushToZero); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 64U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float64 denorm flushing is not supported by the GPU"); + }); + } + } else if (fp16_64_denorm_mode == AmdGpu::FpDenormMode::InOutAllow) { + if (profile.support_fp16_denorm_preserve) { + ctx.AddCapability(spv::Capability::DenormPreserve); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 16U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float16 denorm preserving is not supported by the GPU"); + }); + } + if (profile.support_fp64_denorm_preserve) { + ctx.AddCapability(spv::Capability::DenormPreserve); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 64U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float64 denorm preserving is not supported by the GPU"); + }); + } + } else { + LOG_WARNING(Render_Vulkan, "Unknown Float16/64 denorm mode {}", u32(fp16_64_denorm_mode)); + } +} + +void SetupRoundingMode(EmitContext& ctx, const Profile& profile, const RuntimeInfo& runtime_info, + Id main_func) { + const auto fp_round_mode = runtime_info.props.fp_round_mode32; + if (fp_round_mode == AmdGpu::FpRoundMode::ToZero) { + if (profile.support_fp32_round_to_zero) { + ctx.AddCapability(spv::Capability::RoundingModeRTZ); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::RoundingModeRTZ, 32U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float32 rounding to zero is not supported by the GPU"); + }); + } + } else if (fp_round_mode != AmdGpu::FpRoundMode::NearestEven) { + LOG_WARNING(Render_Vulkan, "Unimplemented FP rounding mode {}", + magic_enum::enum_name(fp_round_mode)); + } + + if (ctx.info.uses_fp16 || ctx.info.uses_fp64) { + const auto fp16_64_round_mode = runtime_info.props.fp_round_mode16_64; + const auto same_round_mode = fp16_64_round_mode == fp_round_mode; + if (!same_round_mode && !profile.supports_rounding_mode_independence) { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, "Float32 and Float16/64 rounding modes are different " + "but the GPU does not support that"); + }); + return; + } + + if (fp16_64_round_mode == AmdGpu::FpRoundMode::ToZero) { + if (ctx.info.uses_fp16) { + if (profile.support_fp16_round_to_zero) { + ctx.AddCapability(spv::Capability::RoundingModeRTZ); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::RoundingModeRTZ, 16U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, + "Float16 rounding to zero is not supported by the GPU"); + }); + } + } + if (ctx.info.uses_fp64) { + if (profile.support_fp64_round_to_zero) { + ctx.AddCapability(spv::Capability::RoundingModeRTZ); + ctx.AddExecutionMode(main_func, spv::ExecutionMode::RoundingModeRTZ, 64U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, + "Float64 rounding to zero is not supported by the GPU"); + }); + } + } + } else if (fp16_64_round_mode != AmdGpu::FpRoundMode::NearestEven) { + LOG_WARNING(Render_Vulkan, "Unknown Float16/64 rounding mode {}", + u32(fp16_64_round_mode)); + } + } +} + +void SetupInfNanPreserveMode(EmitContext& ctx, const Profile& profile, + const RuntimeInfo& runtime_info, Id main_func) { + if (profile.support_fp16_signed_zero_inf_nan_preserve || + profile.support_fp32_signed_zero_inf_nan_preserve || + profile.support_fp64_signed_zero_inf_nan_preserve) { + ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve); + } + + if (profile.support_fp32_signed_zero_inf_nan_preserve) { + ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 32U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING(Render_Vulkan, + "Float32 signed zero/inf/nan preserve mode is not supported by the GPU"); + }); + } + if (ctx.info.uses_fp16) { + if (profile.support_fp16_signed_zero_inf_nan_preserve) { + ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 16U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING( + Render_Vulkan, + "Float16 signed zero/inf/nan preserve mode is not supported by the GPU"); + }); + } + } + if (ctx.info.uses_fp64) { + if (profile.support_fp64_signed_zero_inf_nan_preserve) { + ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 64U); + } else { + static std::once_flag logged; + std::call_once(logged, [] { + LOG_WARNING( + Render_Vulkan, + "Float64 signed zero/inf/nan preserve mode is not supported by the GPU"); + }); + } + } +} + +void SetupFloatMode(EmitContext& ctx, const Profile& profile, const RuntimeInfo& runtime_info, + Id main_func) { + ctx.AddExtension("SPV_KHR_float_controls"); + SetupDenormFlushMode(ctx, profile, runtime_info, main_func); + SetupRoundingMode(ctx, profile, runtime_info, main_func); + SetupInfNanPreserveMode(ctx, profile, runtime_info, main_func); +} + +void PatchPhiNodes(const IR::Program& program, EmitContext& ctx) { + auto inst{program.blocks.front()->begin()}; + size_t block_index{0}; + ctx.PatchDeferredPhi([&](u32 phi_arg, Id first_parent) { + if (phi_arg == 0) { + ++inst; + while (inst == program.blocks[block_index]->end() || + inst->GetOpcode() != IR::Opcode::Phi) { + ++block_index; + inst = program.blocks[block_index]->begin(); + } + } + ASSERT(inst != program.blocks[block_index]->end()); + const Id arg = ctx.Def(inst->Arg(phi_arg)); + const Id parent = ctx.first_to_last_label_map[first_parent.value]; + return std::make_pair(arg, parent); + }); +} +} // Anonymous namespace + +std::vector EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, + const IR::Program& program, Bindings& binding) { + EmitContext ctx{profile, runtime_info, program.info, binding}; + const Id main{DefineMain(ctx, program)}; + DefineEntryPoint(program.info, ctx, main); + SetupCapabilities(program.info, profile, runtime_info, ctx); + SetupFloatMode(ctx, profile, runtime_info, main); + PatchPhiNodes(program, ctx); + binding.user_data += program.info.ud_mask.NumRegs(); + return ctx.Assemble(); +} + +Id EmitPhi(EmitContext& ctx, IR::Inst* inst) { + const size_t num_args{inst->NumArgs()}; + boost::container::small_vector blocks; + blocks.reserve(num_args); + for (size_t index = 0; index < num_args; ++index) { + blocks.push_back(inst->PhiBlock(index)->Definition()); + } + // The type of a phi instruction is stored in its flags + const Id result_type{TypeId(ctx, inst->Flags())}; + return ctx.DeferredOpPhi(result_type, std::span(blocks.data(), blocks.size())); +} + +void EmitVoid(EmitContext&) {} + +Id EmitConditionRef(EmitContext& ctx, const IR::Value& value) { + const Id id{ctx.Def(value)}; + ASSERT_MSG(Sirit::ValidId(id), "Forward identity declaration"); + return id; +} + +Id EmitGetPcLo(EmitContext& ctx, const IR::Value& value) { + const Id id{ctx.Def(value)}; + ASSERT_MSG(Sirit::ValidId(id), "Forward identity declaration"); + return id; +} + +void EmitGetScc(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetExec(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetVcc(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetVccLo(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetVccHi(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetM0(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetScc(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetExec(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetVcc(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetVccLo(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetVccHi(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetM0(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv.h b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv.h new file mode 100644 index 0000000..5b8da44 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "shader_recompiler/backend/bindings.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Backend::SPIRV { + +[[nodiscard]] std::vector EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, + const IR::Program& program, Bindings& binding); + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp new file mode 100644 index 0000000..ce0817e --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp @@ -0,0 +1,471 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +namespace { +using PointerType = EmitContext::PointerType; +using PointerSize = EmitContext::PointerSize; + +std::pair AtomicArgs(EmitContext& ctx) { + const Id scope{ctx.ConstU32(static_cast(spv::Scope::Device))}; + const Id semantics{ctx.u32_zero_value}; + return {scope, semantics}; +} + +Id SharedAtomicU32(EmitContext& ctx, Id offset, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + const Id shift_id{ctx.ConstU32(2U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index)}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value); +} + +Id SharedAtomicU32IncDec(EmitContext& ctx, Id offset, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id)) { + const Id shift_id{ctx.ConstU32(2U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index)}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics); +} + +Id SharedAtomicU64(EmitContext& ctx, Id offset, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + const Id shift_id{ctx.ConstU32(3U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index)}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U64, pointer, scope, semantics, value); +} + +Id SharedAtomicU64IncDec(EmitContext& ctx, Id offset, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id)) { + const Id shift_id{ctx.ConstU32(3U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index)}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U64, pointer, scope, semantics); +} + +Id SharedAtomicU32CmpSwap(EmitContext& ctx, Id offset, Id value, Id cmp_value) { + const Id shift_id{ctx.ConstU32(2U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index)}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return ctx.OpAtomicCompareExchange(ctx.U32[1], pointer, scope, semantics, semantics, value, + cmp_value); +} + +Id SharedAtomicU64CmpSwap(EmitContext& ctx, Id offset, Id value, Id cmp_value) { + const Id shift_id{ctx.ConstU32(3U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer{ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index)}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return ctx.OpAtomicCompareExchange(ctx.U64, pointer, scope, semantics, semantics, value, + cmp_value); +} + +template +Id BufferAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + const auto& buffer = ctx.buffers[handle]; + const Id type = is_float ? ctx.F32[1] : ctx.U32[1]; + if (const Id offset = buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = buffer.Alias(is_float ? PointerType::F32 : PointerType::U32); + const Id ptr = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address); + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(type, ptr, scope, semantics, value); +} + +Id BufferAtomicU32IncDec(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id)) { + const auto& buffer = ctx.buffers[handle]; + if (const Id offset = buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = buffer.Alias(PointerType::U32); + const Id ptr = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address); + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], ptr, scope, semantics); +} + +Id BufferAtomicU32CmpSwap(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id cmp_value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id, Id, Id)) { + const auto& buffer = ctx.buffers[handle]; + if (const Id offset = buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = buffer.Alias(PointerType::U32); + const Id ptr = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address); + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], ptr, scope, semantics, semantics, value, cmp_value); +} + +Id BufferAtomicU64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + const auto& buffer = ctx.buffers[handle]; + if (const Id offset = buffer.Offset(PointerSize::B64); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = buffer.Alias(PointerType::U64); + const Id ptr = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address); + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U64, ptr, scope, semantics, value); +} + +Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id pointer{ctx.OpImageTexelPointer(ctx.image_u32, texture.id, coords, ctx.ConstU32(0U))}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value); +} + +Id ImageAtomicF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id pointer{ctx.OpImageTexelPointer(ctx.image_f32, texture.id, coords, ctx.ConstU32(0U))}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.F32[1], pointer, scope, semantics, value); +} + +Id ImageAtomicU32CmpSwap(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value, + Id cmp_value, + Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id, Id, Id)) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id pointer{ctx.OpImageTexelPointer(ctx.image_u32, texture.id, coords, ctx.ConstU32(0U))}; + const auto [scope, semantics]{AtomicArgs(ctx)}; + return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, semantics, value, cmp_value); +} +} // Anonymous namespace + +Id EmitSharedAtomicIAdd32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicIAdd); +} + +Id EmitSharedAtomicIAdd64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicIAdd); +} + +Id EmitSharedAtomicUMax32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicUMax); +} + +Id EmitSharedAtomicUMax64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicUMax); +} + +Id EmitSharedAtomicSMax32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicSMax); +} + +Id EmitSharedAtomicSMax64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicSMax); +} + +Id EmitSharedAtomicUMin32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicUMin); +} + +Id EmitSharedAtomicUMin64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicUMin); +} + +Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicSMin); +} + +Id EmitSharedAtomicSMin64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicSMin); +} + +Id EmitSharedAtomicAnd32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicAnd); +} + +Id EmitSharedAtomicAnd64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicAnd); +} + +Id EmitSharedAtomicOr32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicOr); +} + +Id EmitSharedAtomicOr64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicOr); +} + +Id EmitSharedAtomicXor32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicXor); +} + +Id EmitSharedAtomicXor64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicXor); +} + +Id EmitSharedAtomicISub32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicISub); +} + +Id EmitSharedAtomicISub64(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU64(ctx, offset, value, &Sirit::Module::OpAtomicISub); +} + +Id EmitSharedAtomicCmpSwap32(EmitContext& ctx, Id offset, Id value, Id cmp_value) { + return SharedAtomicU32CmpSwap(ctx, offset, value, cmp_value); +} + +Id EmitSharedAtomicCmpSwap64(EmitContext& ctx, Id offset, Id value, Id cmp_value) { + return SharedAtomicU64CmpSwap(ctx, offset, value, cmp_value); +} + +Id EmitSharedAtomicInc32(EmitContext& ctx, Id offset) { + return SharedAtomicU32IncDec(ctx, offset, &Sirit::Module::OpAtomicIIncrement); +} + +Id EmitSharedAtomicInc64(EmitContext& ctx, Id offset) { + return SharedAtomicU64IncDec(ctx, offset, &Sirit::Module::OpAtomicIIncrement); +} + +Id EmitSharedAtomicDec32(EmitContext& ctx, Id offset) { + return SharedAtomicU32IncDec(ctx, offset, &Sirit::Module::OpAtomicIDecrement); +} + +Id EmitSharedAtomicDec64(EmitContext& ctx, Id offset) { + return SharedAtomicU64IncDec(ctx, offset, &Sirit::Module::OpAtomicIDecrement); +} + +Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicIAdd); +} + +Id EmitBufferAtomicIAdd64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU64(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicIAdd); +} + +Id EmitBufferAtomicISub32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicISub); +} + +Id EmitBufferAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMin); +} + +Id EmitBufferAtomicSMin64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU64(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMin); +} + +Id EmitBufferAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMin); +} + +Id EmitBufferAtomicUMin64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU64(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMin); +} + +Id EmitBufferAtomicFMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + if (ctx.profile.supports_buffer_fp32_atomic_min_max) { + return BufferAtomicU32(ctx, inst, handle, address, value, + &Sirit::Module::OpAtomicFMin); + } + + const auto u32_value = ctx.OpBitcast(ctx.U32[1], value); + // OpSelect requires a bool condition; produce one by comparing the sign bit to 0. + const auto sign_bit_set = ctx.OpINotEqual( + ctx.U1[1], + ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)), + ctx.u32_zero_value); + + // FIXME this needs control flow because it currently executes both atomics + const auto result = ctx.OpSelect( + ctx.F32[1], sign_bit_set, + EmitBitCastF32U32(ctx, EmitBufferAtomicUMax32(ctx, inst, handle, address, u32_value)), + EmitBitCastF32U32(ctx, EmitBufferAtomicSMin32(ctx, inst, handle, address, u32_value))); + + return result; +} + +Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMax); +} + +Id EmitBufferAtomicSMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU64(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMax); +} + +Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMax); +} + +Id EmitBufferAtomicUMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU64(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMax); +} + +Id EmitBufferAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + if (ctx.profile.supports_buffer_fp32_atomic_min_max) { + return BufferAtomicU32(ctx, inst, handle, address, value, + &Sirit::Module::OpAtomicFMax); + } + + const auto u32_value = ctx.OpBitcast(ctx.U32[1], value); + // OpSelect requires a bool condition; produce one by comparing the sign bit to 0. + const auto sign_bit_set = ctx.OpINotEqual( + ctx.U1[1], + ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)), + ctx.u32_zero_value); + + // FIXME this needs control flow because it currently executes both atomics + const auto result = ctx.OpSelect( + ctx.F32[1], sign_bit_set, + EmitBitCastF32U32(ctx, EmitBufferAtomicUMin32(ctx, inst, handle, address, u32_value)), + EmitBitCastF32U32(ctx, EmitBufferAtomicSMax32(ctx, inst, handle, address, u32_value))); + + return result; +} + +Id EmitBufferAtomicInc32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return BufferAtomicU32IncDec(ctx, inst, handle, address, &Sirit::Module::OpAtomicIIncrement); +} + +Id EmitBufferAtomicDec32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return BufferAtomicU32IncDec(ctx, inst, handle, address, &Sirit::Module::OpAtomicIDecrement); +} + +Id EmitBufferAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicAnd); +} + +Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicOr); +} + +Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicXor); +} + +Id EmitBufferAtomicSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicExchange); +} + +Id EmitBufferAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id cmp_value) { + return BufferAtomicU32CmpSwap(ctx, inst, handle, address, value, cmp_value, + &Sirit::Module::OpAtomicCompareExchange); +} + +Id EmitBufferAtomicFCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id cmp_value) { + const auto u32_value = ctx.OpBitcast(ctx.U32[1], value); + const auto u32_cmp = ctx.OpBitcast(ctx.U32[1], cmp_value); + const auto result = BufferAtomicU32CmpSwap(ctx, inst, handle, address, u32_value, u32_cmp, + &Sirit::Module::OpAtomicCompareExchange); + return ctx.OpBitcast(ctx.F32[1], result); +} + +Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicIAdd); +} + +Id EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicSMin); +} + +Id EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicUMin); +} + +Id EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicSMax); +} + +Id EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicUMax); +} + +Id EmitImageAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + if (ctx.profile.supports_image_fp32_atomic_min_max) { + return ImageAtomicF32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicFMax); + } + + const auto u32_value = ctx.OpBitcast(ctx.U32[1], value); + // OpSelect requires a bool condition; produce one by comparing the sign bit to 0. + const auto sign_bit_set = ctx.OpINotEqual( + ctx.U1[1], + ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)), + ctx.u32_zero_value); + + const auto result = ctx.OpSelect( + ctx.F32[1], sign_bit_set, + EmitBitCastF32U32(ctx, EmitImageAtomicUMin32(ctx, inst, handle, coords, u32_value)), + EmitBitCastF32U32(ctx, EmitImageAtomicSMax32(ctx, inst, handle, coords, u32_value))); + + return result; +} + +Id EmitImageAtomicFMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + if (ctx.profile.supports_image_fp32_atomic_min_max) { + return ImageAtomicF32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicFMin); + } + + const auto u32_value = ctx.OpBitcast(ctx.U32[1], value); + // OpSelect requires a bool condition; produce one by comparing the sign bit to 0. + const auto sign_bit_set = ctx.OpINotEqual( + ctx.U1[1], + ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)), + ctx.u32_zero_value); + + const auto result = ctx.OpSelect( + ctx.F32[1], sign_bit_set, + EmitBitCastF32U32(ctx, EmitImageAtomicUMax32(ctx, inst, handle, coords, u32_value)), + EmitBitCastF32U32(ctx, EmitImageAtomicSMin32(ctx, inst, handle, coords, u32_value))); + + return result; +} + +Id EmitImageAtomicInc32(EmitContext&, IR::Inst*, u32, Id, Id) { + UNREACHABLE_MSG("SPIR-V Instruction"); +} + +Id EmitImageAtomicDec32(EmitContext&, IR::Inst*, u32, Id, Id) { + UNREACHABLE_MSG("SPIR-V Instruction"); +} + +Id EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicAnd); +} + +Id EmitImageAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicOr); +} + +Id EmitImageAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicXor); +} + +Id EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) { + return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicExchange); +} + +Id EmitImageAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value, + Id cmp_value) { + return ImageAtomicU32CmpSwap(ctx, inst, handle, coords, value, cmp_value, + &Sirit::Module::OpAtomicCompareExchange); +} + +Id EmitDataAppend(EmitContext& ctx, Id gds_dw_offset, Id exec) { + UNREACHABLE_MSG("SPIR-V Instruction"); +} + +Id EmitDataConsume(EmitContext& ctx, Id gds_dw_offset, Id exec) { + UNREACHABLE_MSG("SPIR-V Instruction"); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp new file mode 100644 index 0000000..a7cd675 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { +namespace { +void MemoryBarrier(EmitContext& ctx, spv::Scope scope) { + const auto semantics{ + spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory | + spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::AtomicCounterMemory | + spv::MemorySemanticsMask::ImageMemory}; + ctx.OpMemoryBarrier(ctx.ConstU32(static_cast(scope)), + ctx.ConstU32(static_cast(semantics))); +} +} // Anonymous namespace + +void EmitBarrier(EmitContext& ctx) { + const auto execution{spv::Scope::Workgroup}; + spv::Scope memory; + spv::MemorySemanticsMask memory_semantics; + if (ctx.sw_stage == Shader::SwStage::TessellationControl) { + memory = spv::Scope::Invocation; + memory_semantics = spv::MemorySemanticsMask::MaskNone; + } else { + memory = spv::Scope::Workgroup; + memory_semantics = + spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::WorkgroupMemory; + } + ctx.OpControlBarrier(ctx.ConstU32(static_cast(execution)), + ctx.ConstU32(static_cast(memory)), + ctx.ConstU32(static_cast(memory_semantics))); +} + +void EmitWorkgroupMemoryBarrier(EmitContext& ctx) { + MemoryBarrier(ctx, spv::Scope::Workgroup); +} + +void EmitDeviceMemoryBarrier(EmitContext& ctx) { + MemoryBarrier(ctx, spv::Scope::Device); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp new file mode 100644 index 0000000..43655ba --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp @@ -0,0 +1,261 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +struct R { + R(u32 a, u32 b) : offset(a), size(b) {} + u32 offset; + u32 size; +}; +template +static std::array ExtractBitFields(EmitContext& ctx, const Id value, + const Args... args) { + const auto op_func = + is_signed ? &EmitContext::OpBitFieldSExtract : &EmitContext::OpBitFieldUExtract; + std::array result{}; + u32 i = 0; + ( + [&] { + result[i++] = (ctx.*op_func)(ctx.U32[1], value, ctx.ConstU32(args.offset), + ctx.ConstU32(args.size)); + }(), + ...); + return result; +} + +template +static Id InsertBitFields(EmitContext& ctx, const std::initializer_list values, + const Args... args) { + Id result{}; + auto it = values.begin(); + ( + [&] { + if (it == values.begin()) { + result = *it; + } else { + result = ctx.OpBitFieldInsert(ctx.U32[1], result, *it, ctx.ConstU32(args.offset), + ctx.ConstU32(args.size)); + } + ++it; + }(), + ...); + return result; +} + +template +static std::array ExtractComposite(EmitContext& ctx, const VectorIds type, + const Id value) { + std::array result{}; + for (u32 i = 0; i < num_components; i++) { + result[i] = ctx.OpCompositeExtract(type[1], value, i); + } + return result; +} + +Id EmitBitCastU16F16(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.U16, value); +} + +Id EmitBitCastU32F32(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.U32[1], value); +} + +Id EmitBitCastF16U16(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.F16[1], value); +} + +Id EmitBitCastF32U32(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.F32[1], value); +} + +Id EmitPackUint2x32(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.U64, value); +} + +Id EmitUnpackUint2x32(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.U32[2], value); +} + +Id EmitPackDouble2x32(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.F64[1], value); +} + +Id EmitUnpackDouble2x32(EmitContext& ctx, Id value) { + return ctx.OpBitcast(ctx.U32[2], value); +} + +Id EmitPackUnorm2x16(EmitContext& ctx, Id value) { + return ctx.OpPackUnorm2x16(ctx.U32[1], value); +} + +Id EmitUnpackUnorm2x16(EmitContext& ctx, Id value) { + return ctx.OpUnpackUnorm2x16(ctx.F32[2], value); +} + +Id EmitPackSnorm2x16(EmitContext& ctx, Id value) { + return ctx.OpPackSnorm2x16(ctx.U32[1], value); +} + +Id EmitUnpackSnorm2x16(EmitContext& ctx, Id value) { + return ctx.OpUnpackSnorm2x16(ctx.F32[2], value); +} + +Id EmitPackUint2x16(EmitContext& ctx, Id value) { + const auto unpacked{ctx.OpBitcast(ctx.U32[2], value)}; + const auto [x, y] = ExtractComposite<2>(ctx, ctx.U32, unpacked); + return InsertBitFields(ctx, {x, y}, R(0, 16), R(16, 16)); +} + +Id EmitUnpackUint2x16(EmitContext& ctx, Id value) { + const auto [x, y] = ExtractBitFields(ctx, value, R(0, 16), R(16, 16)); + const auto unpacked{ctx.OpCompositeConstruct(ctx.U32[2], x, y)}; + return ctx.OpBitcast(ctx.F32[2], unpacked); +} + +Id EmitPackSint2x16(EmitContext& ctx, Id value) { + return EmitPackUint2x16(ctx, value); +} + +Id EmitUnpackSint2x16(EmitContext& ctx, Id value) { + const auto [x, y] = ExtractBitFields(ctx, value, R(0, 16), R(16, 16)); + const auto unpacked{ctx.OpCompositeConstruct(ctx.U32[2], x, y)}; + return ctx.OpBitcast(ctx.F32[2], unpacked); +} + +Id EmitPackHalf2x16(EmitContext& ctx, Id value) { + return ctx.OpPackHalf2x16(ctx.U32[1], value); +} + +Id EmitUnpackHalf2x16(EmitContext& ctx, Id value) { + return ctx.OpUnpackHalf2x16(ctx.F32[2], value); +} + +Id EmitPackUnorm4x8(EmitContext& ctx, Id value) { + return ctx.OpPackUnorm4x8(ctx.U32[1], value); +} + +Id EmitUnpackUnorm4x8(EmitContext& ctx, Id value) { + return ctx.OpUnpackUnorm4x8(ctx.F32[4], value); +} + +Id EmitPackSnorm4x8(EmitContext& ctx, Id value) { + return ctx.OpPackSnorm4x8(ctx.U32[1], value); +} + +Id EmitUnpackSnorm4x8(EmitContext& ctx, Id value) { + return ctx.OpUnpackSnorm4x8(ctx.F32[4], value); +} + +Id EmitPackUint4x8(EmitContext& ctx, Id value) { + const auto unpacked{ctx.OpBitcast(ctx.U32[4], value)}; + const auto [x, y, z, w] = ExtractComposite<4>(ctx, ctx.U32, unpacked); + return InsertBitFields(ctx, {x, y, z, w}, R(0, 8), R(8, 8), R(16, 8), R(24, 8)); +} + +Id EmitUnpackUint4x8(EmitContext& ctx, Id value) { + const auto [x, y, z, w] = + ExtractBitFields(ctx, value, R(0, 8), R(8, 8), R(16, 8), R(24, 8)); + const auto unpacked{ctx.OpCompositeConstruct(ctx.U32[4], x, y, z, w)}; + return ctx.OpBitcast(ctx.F32[4], unpacked); +} + +Id EmitPackSint4x8(EmitContext& ctx, Id value) { + return EmitPackUint4x8(ctx, value); +} + +Id EmitUnpackSint4x8(EmitContext& ctx, Id value) { + const auto [x, y, z, w] = + ExtractBitFields(ctx, value, R(0, 8), R(8, 8), R(16, 8), R(24, 8)); + const auto unpacked{ctx.OpCompositeConstruct(ctx.U32[4], x, y, z, w)}; + return ctx.OpBitcast(ctx.F32[4], unpacked); +} + +Id EmitPackUfloat10_11_11(EmitContext& ctx, Id value) { + const auto [x, y, z] = ExtractComposite<3>(ctx, ctx.F32, value); + const auto cvt_x{ctx.OpFunctionCall(ctx.U32[1], ctx.f32_to_uf11, x)}; + const auto cvt_y{ctx.OpFunctionCall(ctx.U32[1], ctx.f32_to_uf11, y)}; + const auto cvt_z{ctx.OpFunctionCall(ctx.U32[1], ctx.f32_to_uf10, z)}; + return InsertBitFields(ctx, {cvt_x, cvt_y, cvt_z}, R(0, 11), R(11, 11), R(22, 10)); +} + +Id EmitUnpackUfloat10_11_11(EmitContext& ctx, Id value) { + const auto [x, y, z] = ExtractBitFields(ctx, value, R(0, 11), R(11, 11), R(22, 10)); + const auto cvt_x{ctx.OpFunctionCall(ctx.F32[1], ctx.uf11_to_f32, x)}; + const auto cvt_y{ctx.OpFunctionCall(ctx.F32[1], ctx.uf11_to_f32, y)}; + const auto cvt_z{ctx.OpFunctionCall(ctx.F32[1], ctx.uf10_to_f32, z)}; + return ctx.OpCompositeConstruct(ctx.F32[3], cvt_x, cvt_y, cvt_z); +} + +Id EmitPackUnorm2_10_10_10(EmitContext& ctx, Id value) { + const auto unorm_min{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(0.f), ctx.ConstF32(0.f), + ctx.ConstF32(0.f), ctx.ConstF32(0.f))}; + const auto unorm_max{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(1.f), ctx.ConstF32(1.f), + ctx.ConstF32(1.f), ctx.ConstF32(1.f))}; + const auto clamped{ctx.OpFClamp(ctx.F32[4], value, unorm_min, unorm_max)}; + const auto unorm_mul{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(1023.f), + ctx.ConstF32(1023.f), ctx.ConstF32(1023.f), + ctx.ConstF32(3.f))}; + const auto as_float{ctx.OpFMul(ctx.F32[4], clamped, unorm_mul)}; + const auto as_uint{ctx.OpConvertFToU(ctx.U32[4], ctx.OpRoundEven(ctx.F32[4], as_float))}; + return EmitPackUint2_10_10_10(ctx, ctx.OpBitcast(ctx.F32[4], as_uint)); +} + +Id EmitUnpackUnorm2_10_10_10(EmitContext& ctx, Id value) { + const auto unpacked{ctx.OpBitcast(ctx.U32[4], EmitUnpackUint2_10_10_10(ctx, value))}; + const auto as_float{ctx.OpConvertUToF(ctx.F32[4], unpacked)}; + const auto unorm_div{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(1023.f), + ctx.ConstF32(1023.f), ctx.ConstF32(1023.f), + ctx.ConstF32(3.f))}; + return ctx.OpFDiv(ctx.F32[4], as_float, unorm_div); +} + +Id EmitPackSnorm2_10_10_10(EmitContext& ctx, Id value) { + const auto snorm_min{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(-1.f), ctx.ConstF32(-1.f), + ctx.ConstF32(-1.f), ctx.ConstF32(-1.f))}; + const auto snorm_max{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(1.f), ctx.ConstF32(1.f), + ctx.ConstF32(1.f), ctx.ConstF32(1.f))}; + const auto clamped{ctx.OpFClamp(ctx.F32[4], value, snorm_min, snorm_max)}; + const auto snorm_mul{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(511.f), ctx.ConstF32(511.f), + ctx.ConstF32(511.f), ctx.ConstF32(1.f))}; + const auto as_float{ctx.OpFMul(ctx.F32[4], clamped, snorm_mul)}; + const auto as_sint{ctx.OpConvertFToS(ctx.U32[4], ctx.OpRoundEven(ctx.F32[4], as_float))}; + return EmitPackSint2_10_10_10(ctx, ctx.OpBitcast(ctx.F32[4], as_sint)); +} + +Id EmitUnpackSnorm2_10_10_10(EmitContext& ctx, Id value) { + const auto unpacked{ctx.OpBitcast(ctx.U32[4], EmitUnpackSint2_10_10_10(ctx, value))}; + const auto as_float{ctx.OpConvertSToF(ctx.F32[4], unpacked)}; + const auto snorm_div{ctx.ConstantComposite(ctx.F32[4], ctx.ConstF32(511.f), ctx.ConstF32(511.f), + ctx.ConstF32(511.f), ctx.ConstF32(1.f))}; + return ctx.OpFDiv(ctx.F32[4], as_float, snorm_div); +} + +Id EmitPackUint2_10_10_10(EmitContext& ctx, Id value) { + const auto unpacked{ctx.OpBitcast(ctx.U32[4], value)}; + const auto [x, y, z, w] = ExtractComposite<4>(ctx, ctx.U32, unpacked); + return InsertBitFields(ctx, {x, y, z, w}, R(0, 10), R(10, 10), R(20, 10), R(30, 2)); +} + +Id EmitUnpackUint2_10_10_10(EmitContext& ctx, Id value) { + const auto [x, y, z, w] = + ExtractBitFields(ctx, value, R(0, 10), R(10, 10), R(20, 10), R(30, 2)); + const auto unpacked{ctx.OpCompositeConstruct(ctx.U32[4], x, y, z, w)}; + return ctx.OpBitcast(ctx.F32[4], unpacked); +} + +Id EmitPackSint2_10_10_10(EmitContext& ctx, Id value) { + return EmitPackUint2_10_10_10(ctx, value); +} + +Id EmitUnpackSint2_10_10_10(EmitContext& ctx, Id value) { + const auto [x, y, z, w] = + ExtractBitFields(ctx, value, R(0, 10), R(10, 10), R(20, 10), R(30, 2)); + const auto unpacked{ctx.OpCompositeConstruct(ctx.U32[4], x, y, z, w)}; + return ctx.OpBitcast(ctx.F32[4], unpacked); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_composite.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_composite.cpp new file mode 100644 index 0000000..ed53742 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_composite.cpp @@ -0,0 +1,124 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/ir/microinstruction.h" + +namespace Shader::Backend::SPIRV { + +template +Id EmitCompositeConstruct(EmitContext& ctx, IR::Inst* inst, Args&&... args) { + return inst->AreAllArgsImmediates() ? ctx.ConstantComposite(args...) + : ctx.OpCompositeConstruct(args...); +} + +Id EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2) { + return EmitCompositeConstruct(ctx, inst, ctx.U32[2], e1, e2); +} + +Id EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3) { + return EmitCompositeConstruct(ctx, inst, ctx.U32[3], e1, e2, e3); +} + +Id EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3, Id e4) { + return EmitCompositeConstruct(ctx, inst, ctx.U32[4], e1, e2, e3, e4); +} + +Id EmitCompositeConstructU32x2x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2) { + return EmitCompositeConstruct(ctx, inst, ctx.U32[4], e1, e2); +} + +Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index) { + return ctx.OpCompositeExtract(ctx.U32[1], composite, index); +} + +Id EmitCompositeExtractU32x3(EmitContext& ctx, Id composite, u32 index) { + return ctx.OpCompositeExtract(ctx.U32[1], composite, index); +} + +Id EmitCompositeExtractU32x4(EmitContext& ctx, Id composite, u32 index) { + return ctx.OpCompositeExtract(ctx.U32[1], composite, index); +} + +Id EmitCompositeInsertU32x2(EmitContext& ctx, Id composite, Id object, u32 index) { + return ctx.OpCompositeInsert(ctx.U32[2], object, composite, index); +} + +Id EmitCompositeInsertU32x3(EmitContext& ctx, Id composite, Id object, u32 index) { + return ctx.OpCompositeInsert(ctx.U32[3], object, composite, index); +} + +Id EmitCompositeInsertU32x4(EmitContext& ctx, Id composite, Id object, u32 index) { + return ctx.OpCompositeInsert(ctx.U32[4], object, composite, index); +} + +Id EmitCompositeShuffleU32x2(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1) { + return ctx.OpVectorShuffle(ctx.U32[2], composite1, composite2, comp0, comp1); +} + +Id EmitCompositeShuffleU32x3(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2) { + return ctx.OpVectorShuffle(ctx.U32[3], composite1, composite2, comp0, comp1, comp2); +} + +Id EmitCompositeShuffleU32x4(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2, u32 comp3) { + return ctx.OpVectorShuffle(ctx.U32[4], composite1, composite2, comp0, comp1, comp2, comp3); +} + +Id EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2) { + return EmitCompositeConstruct(ctx, inst, ctx.F32[2], e1, e2); +} + +Id EmitCompositeConstructF32x3(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3) { + return EmitCompositeConstruct(ctx, inst, ctx.F32[3], e1, e2, e3); +} + +Id EmitCompositeConstructF32x4(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3, Id e4) { + return EmitCompositeConstruct(ctx, inst, ctx.F32[4], e1, e2, e3, e4); +} + +Id EmitCompositeConstructF32x2x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2) { + return EmitCompositeConstruct(ctx, inst, ctx.F32[4], e1, e2); +} + +Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index) { + return ctx.OpCompositeExtract(ctx.F32[1], composite, index); +} + +Id EmitCompositeExtractF32x3(EmitContext& ctx, Id composite, u32 index) { + return ctx.OpCompositeExtract(ctx.F32[1], composite, index); +} + +Id EmitCompositeExtractF32x4(EmitContext& ctx, Id composite, u32 index) { + return ctx.OpCompositeExtract(ctx.F32[1], composite, index); +} + +Id EmitCompositeInsertF32x2(EmitContext& ctx, Id composite, Id object, u32 index) { + return ctx.OpCompositeInsert(ctx.F32[2], object, composite, index); +} + +Id EmitCompositeInsertF32x3(EmitContext& ctx, Id composite, Id object, u32 index) { + return ctx.OpCompositeInsert(ctx.F32[3], object, composite, index); +} + +Id EmitCompositeInsertF32x4(EmitContext& ctx, Id composite, Id object, u32 index) { + return ctx.OpCompositeInsert(ctx.F32[4], object, composite, index); +} + +Id EmitCompositeShuffleF32x2(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1) { + return ctx.OpVectorShuffle(ctx.F32[2], composite1, composite2, comp0, comp1); +} + +Id EmitCompositeShuffleF32x3(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2) { + return ctx.OpVectorShuffle(ctx.F32[3], composite1, composite2, comp0, comp1, comp2); +} + +Id EmitCompositeShuffleF32x4(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2, u32 comp3) { + return ctx.OpVectorShuffle(ctx.F32[4], composite1, composite2, comp0, comp1, comp2, comp3); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp new file mode 100644 index 0000000..9408070 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -0,0 +1,595 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "core/emulator_settings.h" +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/microinstruction.h" +#include "shader_recompiler/ir/patch.h" +#include "shader_recompiler/runtime_info.h" + +#include + +namespace Shader::Backend::SPIRV { + +using PointerType = EmitContext::PointerType; +using PointerSize = EmitContext::PointerSize; + +static std::pair OutputAttrComponentType(EmitContext& ctx, IR::Attribute attr) { + if (IR::IsParam(attr)) { + const u32 index{u32(attr) - u32(IR::Attribute::Param0)}; + const auto& info{ctx.output_params.at(index)}; + return {info.component_type, info.is_integer}; + } + if (IR::IsMrt(attr)) { + const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)}; + const auto& info{ctx.frag_outputs.at(index)}; + return {info.component_type, info.is_integer}; + } + switch (attr) { + case IR::Attribute::Position0: + case IR::Attribute::ClipDistance: + case IR::Attribute::CullDistance: + case IR::Attribute::Depth: + case IR::Attribute::PointSize: + return {ctx.F32[1], false}; + case IR::Attribute::RenderTargetIndex: + case IR::Attribute::ViewportIndex: + case IR::Attribute::SampleMask: + return {ctx.U32[1], true}; + case IR::Attribute::StencilRef: + return {ctx.S32[1], true}; + default: + UNREACHABLE_MSG("Write attribute {}", attr); + } +} + +Id EmitGetUserData(EmitContext& ctx, IR::ScalarReg reg) { + const u32 index = ctx.binding.user_data + ctx.info.ud_mask.Index(reg); + const u32 half = PushData::UdRegsIndex + (index >> 2); + const Id ud_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, ctx.U32[1]), + ctx.push_data_block, ctx.ConstU32(half), + ctx.ConstU32(index & 3))}; + const Id ud_reg{ctx.OpLoad(ctx.U32[1], ud_ptr)}; + ctx.Name(ud_reg, fmt::format("ud_{}", u32(reg))); + return ud_reg; +} + +Id EmitReadConst(EmitContext& ctx, IR::Inst* inst, Id addr, Id offset) { + const u32 flatbuf_off_dw = inst->Flags(); + if (!EmulatorSettings.IsDirectMemoryAccessEnabled()) { + return ctx.EmitFlatbufferLoad(ctx.ConstU32(flatbuf_off_dw)); + } + if (flatbuf_off_dw == 0) { + return ctx.OpFunctionCall(ctx.U32[1], ctx.read_const_dynamic, addr, offset); + } else { + return ctx.EmitFlatbufferLoad(ctx.ConstU32(flatbuf_off_dw)); + } +} + +Id EmitReadConstBuffer(EmitContext& ctx, u32 handle, Id index) { + const auto& buffer = ctx.buffers[handle]; + if (const Id offset = buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) { + index = ctx.OpIAdd(ctx.U32[1], index, offset); + } + const auto [id, pointer_type] = buffer.Alias(PointerType::U32); + const Id ptr{ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, index)}; + const Id result{ctx.OpLoad(ctx.U32[1], ptr)}; + return result; +} + +Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) { + if (IR::IsParam(attr)) { + const u32 param_index{u32(attr) - u32(IR::Attribute::Param0)}; + const auto& param{ctx.input_params.at(param_index)}; + const Id value = [&] { + if (param.is_array) { + ASSERT(param.num_components > 1); + if (param.is_loaded) { + return ctx.OpCompositeExtract(param.component_type, param.id_array[index], + comp); + } else { + return ctx.OpLoad(param.component_type, + ctx.OpAccessChain(param.pointer_type, param.id, + ctx.ConstU32(index), ctx.ConstU32(comp))); + } + } else { + ASSERT(!param.is_loaded); + if (param.num_components > 1) { + return ctx.OpLoad( + param.component_type, + ctx.OpAccessChain(param.pointer_type, param.id, ctx.ConstU32(comp))); + } else { + return ctx.OpLoad(param.component_type, param.id); + } + } + }(); + return param.is_integer ? ctx.OpBitcast(ctx.F32[1], value) : value; + } + if (IR::IsBarycentricCoord(attr) && attr != IR::Attribute::BaryCoordPullModel && + ctx.profile.supports_fragment_shader_barycentric) { + ++comp; + } + switch (attr) { + case IR::Attribute::Position0: + ASSERT(ctx.sw_stage == SwStage::Geometry); + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.gl_in, ctx.ConstU32(index), + ctx.ConstU32(0U), ctx.ConstU32(comp))); + case IR::Attribute::FragCoord: + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.frag_coord, ctx.ConstU32(comp))); + case IR::Attribute::TessellationEvaluationPointU: + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.tess_coord, ctx.u32_zero_value)); + case IR::Attribute::TessellationEvaluationPointV: + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.tess_coord, ctx.ConstU32(1U))); + case IR::Attribute::BaryCoordSmooth: + if (ctx.profile.supports_amd_shader_explicit_vertex_parameter) { + return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth, + ctx.ConstU32(comp))); + } else { + return ctx.OpCompositeExtract(ctx.F32[1], ctx.OpLoad(ctx.F32[3], ctx.bary_coord), comp); + } + case IR::Attribute::BaryCoordSmoothCentroid: + if (ctx.profile.supports_amd_shader_explicit_vertex_parameter) { + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_centroid, + ctx.ConstU32(comp))); + } else { + return ctx.OpCompositeExtract( + ctx.F32[1], ctx.OpInterpolateAtCentroid(ctx.F32[3], ctx.bary_coord), comp); + } + case IR::Attribute::BaryCoordSmoothSample: + if (ctx.profile.supports_amd_shader_explicit_vertex_parameter) { + return ctx.OpLoad( + ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_sample, ctx.ConstU32(comp))); + } else { + return ctx.OpCompositeExtract( + ctx.F32[1], + ctx.OpInterpolateAtSample(ctx.F32[3], ctx.bary_coord, + ctx.OpLoad(ctx.U32[1], ctx.sample_index)), + comp); + } + case IR::Attribute::BaryCoordNoPersp: + return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_nopersp, + ctx.ConstU32(comp))); + case IR::Attribute::BaryCoordNoPerspSample: + return ctx.OpLoad( + ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_nopersp_sample, ctx.ConstU32(comp))); + case IR::Attribute::BaryCoordPullModel: { + ASSERT_MSG(comp < 3, "Invalid BaryCoordPullModel component {}", comp); + + if (ctx.profile.supports_amd_shader_explicit_vertex_parameter) { + return ctx.OpLoad( + ctx.F32[1], + ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_pull_model, ctx.ConstU32(comp))); + } + + // FragCoord.w is reciprocal clip W at the fragment center. Perspective barycentrics + // are (I/W)/(1/W) and (J/W)/(1/W), so multiplying by FragCoord.w recovers the + // pull-model values expected by the guest. + const Id inv_w = ctx.OpLoad( + ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.frag_coord, ctx.ConstU32(3U))); + if (comp == 2) { + return inv_w; + } + const Id ij = + ctx.OpCompositeExtract(ctx.F32[1], ctx.OpLoad(ctx.F32[3], ctx.bary_coord), comp + 1); + return ctx.OpFMul(ctx.F32[1], ij, inv_w); + } + default: + UNREACHABLE_MSG("Read attribute {}", attr); + } +} + +Id EmitGetAttributeU1(EmitContext& ctx, IR::Attribute attr, u32 comp) { + ASSERT(comp == 0); + switch (attr) { + case IR::Attribute::IsFrontFace: + return ctx.OpLoad(ctx.U1[1], ctx.front_facing); + case IR::Attribute::IsHelperInvocation: + return ctx.OpLoad(ctx.U1[1], ctx.helper_invocation); + default: + UNREACHABLE_MSG("Unsupported U1 attribute {}", attr); + } +} + +Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp) { + switch (attr) { + case IR::Attribute::VertexId: + return ctx.OpLoad(ctx.U32[1], ctx.vertex_index); + case IR::Attribute::InstanceId: + return ctx.OpLoad(ctx.U32[1], ctx.instance_id); + case IR::Attribute::BaseVertex: + return ctx.OpLoad(ctx.U32[1], ctx.base_vertex); + case IR::Attribute::BaseInstance: + return ctx.OpLoad(ctx.U32[1], ctx.base_instance); + case IR::Attribute::WorkgroupIndex: + return ctx.workgroup_index_id; + case IR::Attribute::WorkgroupId: + return ctx.OpCompositeExtract(ctx.U32[1], ctx.OpLoad(ctx.U32[3], ctx.workgroup_id), comp); + case IR::Attribute::LocalInvocationId: + return ctx.OpCompositeExtract(ctx.U32[1], ctx.OpLoad(ctx.U32[3], ctx.local_invocation_id), + comp); + case IR::Attribute::LocalInvocationIndex: + return ctx.OpLoad(ctx.U32[1], ctx.local_invocation_index); + case IR::Attribute::SampleIndex: + return ctx.OpLoad(ctx.U32[1], ctx.sample_index); + case IR::Attribute::SampleMask: + return ctx.OpLoad(ctx.U32[1], + ctx.OpAccessChain(ctx.input_u32, ctx.sample_mask_in, ctx.u32_zero_value)); + case IR::Attribute::RenderTargetIndex: + return ctx.OpLoad(ctx.U32[1], ctx.output_layer); + case IR::Attribute::PrimitiveId: + return ctx.OpLoad(ctx.U32[1], ctx.primitive_id); + case IR::Attribute::InvocationId: + ASSERT(ctx.info.sw_stage == SwStage::Geometry || + ctx.info.sw_stage == SwStage::TessellationControl); + return ctx.OpLoad(ctx.U32[1], ctx.invocation_id); + case IR::Attribute::SubgroupLtMask: + return ctx.OpLoad( + ctx.U32[1], ctx.OpAccessChain(ctx.input_u32, ctx.subgroup_lt_mask, ctx.ConstU32(comp))); + case IR::Attribute::PatchVertices: + ASSERT(ctx.info.sw_stage == SwStage::TessellationControl); + return ctx.OpLoad(ctx.U32[1], ctx.patch_vertices); + case IR::Attribute::PackedHullInvocationInfo: { + ASSERT(ctx.info.sw_stage == SwStage::TessellationControl); + // [0:8]: patch id within VGT + // [8:12]: output control point id + // But 0:8 should be treated as 0 for attribute addressing purposes + if (ctx.runtime_info.sw.tcs.IsPassthrough()) { + // Gcn shader would run with 1 thread, but we need to run a thread for + // each output control point. + // If Gcn shader uses this value, we should make sure all threads in the + // Vulkan shader use 0 + return ctx.u32_zero_value; + } else { + const Id invocation_id = ctx.OpLoad(ctx.U32[1], ctx.invocation_id); + return ctx.OpShiftLeftLogical(ctx.U32[1], invocation_id, ctx.ConstU32(8u)); + } + } + default: + UNREACHABLE_MSG("Read U32 attribute {}", attr); + } +} + +void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 element) { + const auto op_store = [&](Id pointer) { + const auto [component_type, is_integer] = OutputAttrComponentType(ctx, attr); + if (is_integer) { + ctx.OpStore(pointer, ctx.OpBitcast(component_type, value)); + } else { + ctx.OpStore(pointer, value); + } + }; + if (IR::IsParam(attr)) { + const u32 attr_index{u32(attr) - u32(IR::Attribute::Param0)}; + if (ctx.hw_stage == HwStage::Local) { + const auto component_ptr = ctx.TypePointer(spv::StorageClass::Output, ctx.F32[1]); + return op_store(ctx.OpAccessChain(component_ptr, ctx.output_attr_array, + ctx.ConstU32(attr_index), ctx.ConstU32(element))); + } else { + const auto& info{ctx.output_params.at(attr_index)}; + ASSERT(info.num_components > 0); + if (info.num_components == 1) { + return op_store(info.id); + } else { + return op_store( + ctx.OpAccessChain(info.pointer_type, info.id, ctx.ConstU32(element))); + } + } + } + if (IR::IsMrt(attr)) { + const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)}; + const auto& info{ctx.frag_outputs.at(index)}; + if (element < 3 && ctx.runtime_info.hw.fs.color_buffers[index].blend_self_scale) { + // Emulates GCN's factor-scaled min/max blend: min/max(src*src, dst*dst). + value = ctx.OpFMul(ctx.F32[1], value, value); + } + if (info.num_components == 1) { + return op_store(info.id); + } else { + return op_store(ctx.OpAccessChain(info.pointer_type, info.id, ctx.ConstU32(element))); + } + } + switch (attr) { + case IR::Attribute::Position0: + return op_store( + ctx.OpAccessChain(ctx.output_f32, ctx.output_position, ctx.ConstU32(element))); + case IR::Attribute::ClipDistance: + return op_store( + ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, ctx.ConstU32(element))); + case IR::Attribute::CullDistance: + return op_store( + ctx.OpAccessChain(ctx.output_f32, ctx.cull_distances, ctx.ConstU32(element))); + case IR::Attribute::PointSize: + return op_store(ctx.output_point_size); + case IR::Attribute::RenderTargetIndex: + return op_store(ctx.output_layer); + case IR::Attribute::ViewportIndex: + return op_store(ctx.output_viewport_index); + case IR::Attribute::Depth: + return op_store(ctx.frag_depth); + case IR::Attribute::SampleMask: + return op_store(ctx.OpAccessChain(ctx.output_u32, ctx.sample_mask, ctx.u32_zero_value)); + case IR::Attribute::StencilRef: + if (ctx.profile.supports_shader_stencil_export) { + return op_store(ctx.stencil_ref); + } + return; + default: + UNREACHABLE_MSG("Write attribute {}", attr); + } +} + +Id EmitGetTessGenericAttribute(EmitContext& ctx, Id vertex_index, Id attr_index, Id comp_index) { + const auto attr_comp_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[1]); + return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(attr_comp_ptr, ctx.input_attr_array, + vertex_index, attr_index, comp_index)); +} + +Id EmitReadTcsGenericOuputAttribute(EmitContext& ctx, Id vertex_index, Id attr_index, + Id comp_index) { + const auto attr_comp_ptr = ctx.TypePointer(spv::StorageClass::Output, ctx.F32[1]); + return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(attr_comp_ptr, ctx.output_attr_array, + vertex_index, attr_index, comp_index)); +} + +void EmitSetTcsGenericAttribute(EmitContext& ctx, Id value, Id attr_index, Id comp_index) { + // Implied vertex index is invocation_id + const auto component_ptr = ctx.TypePointer(spv::StorageClass::Output, ctx.F32[1]); + Id pointer = + ctx.OpAccessChain(component_ptr, ctx.output_attr_array, + ctx.OpLoad(ctx.U32[1], ctx.invocation_id), attr_index, comp_index); + ctx.OpStore(pointer, value); +} + +Id EmitGetPatch(EmitContext& ctx, IR::Patch patch) { + const u32 index{IR::GenericPatchIndex(patch)}; + const Id element{ctx.ConstU32(IR::GenericPatchElement(patch))}; + const Id type{ctx.sw_stage == SwStage::TessellationControl ? ctx.output_f32 : ctx.input_f32}; + const Id pointer{ctx.OpAccessChain(type, ctx.patches.at(index), element)}; + return ctx.OpLoad(ctx.F32[1], pointer); +} + +void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value) { + const Id pointer{[&] { + if (IR::IsGeneric(patch)) { + const u32 index{IR::GenericPatchIndex(patch)}; + const Id element{ctx.ConstU32(IR::GenericPatchElement(patch))}; + return ctx.OpAccessChain(ctx.output_f32, ctx.patches.at(index), element); + } + switch (patch) { + case IR::Patch::TessellationLodLeft: + case IR::Patch::TessellationLodRight: + case IR::Patch::TessellationLodTop: + case IR::Patch::TessellationLodBottom: { + const u32 index{static_cast(patch) - u32(IR::Patch::TessellationLodLeft)}; + const Id index_id{ctx.ConstU32(index)}; + return ctx.OpAccessChain(ctx.output_f32, ctx.output_tess_level_outer, index_id); + } + case IR::Patch::TessellationLodInteriorU: + return ctx.OpAccessChain(ctx.output_f32, ctx.output_tess_level_inner, + ctx.u32_zero_value); + case IR::Patch::TessellationLodInteriorV: + return ctx.OpAccessChain(ctx.output_f32, ctx.output_tess_level_inner, ctx.ConstU32(1u)); + default: + UNREACHABLE_MSG("Patch {}", u32(patch)); + } + }()}; + ctx.OpStore(pointer, value); +} + +template +static Id EmitLoadBufferB32xN(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto& data_types = alias == PointerType::U32 ? ctx.U32 : ctx.F32; + const auto [id, pointer_type] = spv_buffer.Alias(alias); + + boost::container::static_vector ids; + for (u32 i = 0; i < N; i++) { + const Id index_i = i == 0 ? address : ctx.OpIAdd(ctx.U32[1], address, ctx.ConstU32(i)); + const Id ptr_i = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, index_i); + const Id result_i = ctx.OpLoad(data_types[1], ptr_i); + ids.push_back(result_i); + } + + const Id result = N == 1 ? ids[0] : ctx.OpCompositeConstruct(data_types[N], ids); + return result; +} + +Id EmitLoadBufferU8(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B8); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = spv_buffer.Alias(PointerType::U8); + const Id ptr{ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address)}; + const Id result{ctx.OpLoad(ctx.U8, ptr)}; + return result; +} + +Id EmitLoadBufferU16(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B16); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = spv_buffer.Alias(PointerType::U16); + const Id ptr{ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address)}; + const Id result{ctx.OpLoad(ctx.U16, ptr)}; + return result; +} + +Id EmitLoadBufferU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<1, PointerType::U32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferU32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<2, PointerType::U32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferU32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<3, PointerType::U32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferU32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<4, PointerType::U32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferU64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B64); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = spv_buffer.Alias(PointerType::U64); + const Id ptr{ctx.OpAccessChain(pointer_type, id, ctx.u64_zero_value, address)}; + const Id result{ctx.OpLoad(ctx.U64, ptr)}; + return result; +} + +Id EmitLoadBufferF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<1, PointerType::F32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<2, PointerType::F32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<3, PointerType::F32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + return EmitLoadBufferB32xN<4, PointerType::F32>(ctx, inst, handle, address); +} + +Id EmitLoadBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) { + UNREACHABLE_MSG("SPIR-V instruction"); +} + +template +static void EmitStoreBufferB32xN(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, + Id value) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B32); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto& data_types = alias == PointerType::U32 ? ctx.U32 : ctx.F32; + const auto [id, pointer_type] = spv_buffer.Alias(alias); + + for (u32 i = 0; i < N; i++) { + const Id index_i = i == 0 ? address : ctx.OpIAdd(ctx.U32[1], address, ctx.ConstU32(i)); + const Id ptr_i = ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, index_i); + const Id value_i = N == 1 ? value : ctx.OpCompositeExtract(data_types[1], value, i); + ctx.OpStore(ptr_i, value_i); + } +} + +void EmitStoreBufferU8(EmitContext& ctx, IR::Inst*, u32 handle, Id address, Id value) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B8); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = spv_buffer.Alias(PointerType::U8); + const Id ptr{ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address)}; + ctx.OpStore(ptr, value); +} + +void EmitStoreBufferU16(EmitContext& ctx, IR::Inst*, u32 handle, Id address, Id value) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B16); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = spv_buffer.Alias(PointerType::U16); + const Id ptr{ctx.OpAccessChain(pointer_type, id, ctx.u32_zero_value, address)}; + ctx.OpStore(ptr, value); +} + +void EmitStoreBufferU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<1, PointerType::U32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferU32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<2, PointerType::U32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferU32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<3, PointerType::U32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferU32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<4, PointerType::U32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferU64(EmitContext& ctx, IR::Inst*, u32 handle, Id address, Id value) { + const auto& spv_buffer = ctx.buffers[handle]; + if (const Id offset = spv_buffer.Offset(PointerSize::B64); Sirit::ValidId(offset)) { + address = ctx.OpIAdd(ctx.U32[1], address, offset); + } + const auto [id, pointer_type] = spv_buffer.Alias(PointerType::U64); + const Id ptr{ctx.OpAccessChain(pointer_type, id, ctx.u64_zero_value, address)}; + ctx.OpStore(ptr, value); +} + +void EmitStoreBufferF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<1, PointerType::F32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<2, PointerType::F32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<3, PointerType::F32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + EmitStoreBufferB32xN<4, PointerType::F32>(ctx, inst, handle, address, value); +} + +void EmitStoreBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { + UNREACHABLE_MSG("SPIR-V instruction"); +} + +void EmitGetScalarRegister(EmitContext&) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetScalarRegister(EmitContext&) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetVectorRegister(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetVectorRegister(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetVirtualRegister(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetVirtualRegister(EmitContext& ctx) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitSetGotoVariable(EmitContext&) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +void EmitGetGotoVariable(EmitContext&) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_convert.cpp new file mode 100644 index 0000000..8da66e8 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_convert.cpp @@ -0,0 +1,186 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { +namespace { +Id ExtractU16(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U16, value); +} + +Id ExtractS16(EmitContext& ctx, Id value) { + return ctx.OpSConvert(ctx.S16, value); +} + +Id ExtractU8(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U8, value); +} + +Id ExtractS8(EmitContext& ctx, Id value) { + return ctx.OpSConvert(ctx.S8, value); +} +} // Anonymous namespace + +Id EmitConvertS16F32(EmitContext& ctx, Id value) { + return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); +} + +Id EmitConvertS16F64(EmitContext& ctx, Id value) { + return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value)); +} + +Id EmitConvertS32F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U32[1], value); +} + +Id EmitConvertS32F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U32[1], value); +} + +Id EmitConvertS64F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U64, value); +} + +Id EmitConvertS64F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToS(ctx.U64, value); +} + +Id EmitConvertU16F32(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); +} + +Id EmitConvertU16F64(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value)); +} + +Id EmitConvertU32F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U32[1], value); +} + +Id EmitConvertU32F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U32[1], value); +} + +Id EmitConvertU64F32(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U64, value); +} + +Id EmitConvertU64F64(EmitContext& ctx, Id value) { + return ctx.OpConvertFToU(ctx.U64, value); +} + +Id EmitConvertU64U32(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U64, value); +} + +Id EmitConvertU32U64(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], value); +} + +Id EmitConvertF16F32(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F16[1], value); +} + +Id EmitConvertF32F16(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F32[1], value); +} + +Id EmitConvertF32F64(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F32[1], value); +} + +Id EmitConvertF64F32(EmitContext& ctx, Id value) { + return ctx.OpFConvert(ctx.F64[1], value); +} + +Id EmitConvertF32S8(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], ExtractS8(ctx, value)); +} + +Id EmitConvertF32S16(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], ExtractS16(ctx, value)); +} + +Id EmitConvertF32S32(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], value); +} + +Id EmitConvertF32S64(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F32[1], value); +} + +Id EmitConvertF32U8(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], ExtractU8(ctx, value)); +} + +Id EmitConvertF32U16(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], ExtractU16(ctx, value)); +} + +Id EmitConvertF32U32(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], value); +} + +Id EmitConvertF32U64(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F32[1], value); +} + +Id EmitConvertF64S8(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], ExtractS8(ctx, value)); +} + +Id EmitConvertF64S16(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], ExtractS16(ctx, value)); +} + +Id EmitConvertF64S32(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], value); +} + +Id EmitConvertF64S64(EmitContext& ctx, Id value) { + return ctx.OpConvertSToF(ctx.F64[1], value); +} + +Id EmitConvertF64U8(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], ExtractU8(ctx, value)); +} + +Id EmitConvertF64U16(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], ExtractU16(ctx, value)); +} + +Id EmitConvertF64U32(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], value); +} + +Id EmitConvertF64U64(EmitContext& ctx, Id value) { + return ctx.OpConvertUToF(ctx.F64[1], value); +} + +Id EmitConvertU16U32(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U16, value); +} + +Id EmitConvertU32U16(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], value); +} + +Id EmitConvertU8U32(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U8, value); +} + +Id EmitConvertU32U8(EmitContext& ctx, Id value) { + return ctx.OpUConvert(ctx.U32[1], value); +} + +Id EmitConvertS32S8(EmitContext& ctx, Id value) { + return ctx.OpSConvert(ctx.U32[1], value); +} + +Id EmitConvertS32S16(EmitContext& ctx, Id value) { + return ctx.OpSConvert(ctx.U32[1], value); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_discard_frag.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_discard_frag.cpp new file mode 100644 index 0000000..976555d --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_discard_frag.cpp @@ -0,0 +1,123 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include + +#include "shader_recompiler/backend/spirv/emit_spirv_discard_frag.h" + +namespace Shader::Backend::SPIRV { + +using Sirit::Id; + +constexpr u32 SPIRV_VERSION_1_5 = 0x00010500; + +struct DiscardShaderEmitter : public Sirit::Module { + explicit DiscardShaderEmitter(const std::array& outputs) + : Sirit::Module{SPIRV_VERSION_1_5} { + void_id = TypeVoid(); + bool_id = TypeBool(); + float_id = TypeFloat(32); + vec4_id = TypeVector(float_id, 4); + + float_zero = Constant(float_id, 0.0f); + + for (u8 location = 0; location < 3; ++location) { + for (u8 elem = 0; elem < 4; ++elem) { + switch (outputs.at(location).at(elem)) { + case Output::ClipDist0: + case Output::ClipDist1: + case Output::ClipDist2: + case Output::ClipDist3: + case Output::ClipDist4: + case Output::ClipDist5: + case Output::ClipDist6: + case Output::ClipDist7: { + clip_locations.emplace_back(location, elem); + break; + } + default: + break; + } + } + } + } + + void EmitDiscardShader() { + std::set locations; + + for (auto& [loc, elem] : clip_locations) { + locations.insert(loc); + } + + ASSERT_MSG(locations.size() <= 2, "more than 2 clip planes locations"); + + AddCapability(spv::Capability::Shader); + AddExtension("SPV_EXT_demote_to_helper_invocation"); + AddCapability(spv::Capability::DemoteToHelperInvocation); + SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450); + const Id void_function{TypeFunction(void_id)}; + main = OpFunction(void_id, spv::FunctionControlMask::MaskNone, void_function); + + auto ptr_id = TypePointer(spv::StorageClass::Input, vec4_id); + + std::array locations_id = {0}; + std::vector locations_v(locations.begin(), locations.end()); + std::map loc_vec_id; + auto locations_id_len = 0; + for (auto i = 0; i < locations_v.size(); ++i) { + locations_id_len++; + locations_id[i] = AddGlobalVariable(ptr_id, spv::StorageClass::Input); + Decorate(locations_id[i], spv::Decoration::Location, locations_v[i]); + Name(locations_id[i], fmt::format("ccdist{}_in", i)); + } + + AddEntryPoint(spv::ExecutionModel::Fragment, main, "main", + std::span(locations_id).first(locations_id_len)); + AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); + AddLabel(OpLabel()); + + for (auto i = 0; i < locations_id_len; ++i) { + auto loc_vec = OpLoad(vec4_id, locations_id[i]); + loc_vec_id[locations_v[i]] = loc_vec; + Name(loc_vec, fmt::format("ccdist{}", i)); + } + + for (auto& [loc, elem] : clip_locations) { + auto plane = OpCompositeExtract(float_id, loc_vec_id[loc], elem); + Name(plane, fmt::format("plane{}", loc * 4 + elem)); + + auto clipped = OpFOrdLessThan(bool_id, plane, float_zero); + const Id kill_label{OpLabel()}; + const Id merge_label{OpLabel()}; + OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone); + OpBranchConditional(clipped, kill_label, merge_label); + AddLabel(kill_label); + OpDemoteToHelperInvocationEXT(); + OpBranch(merge_label); + AddLabel(merge_label); + } + + OpReturn(); + OpFunctionEnd(); + } + +private: + Id main; + Id void_id; + Id bool_id; + Id float_id; + Id vec4_id; + Id float_zero; + + std::vector> clip_locations; +}; + +std::vector EmitDiscardFragmentShader(std::array outputs) { + DiscardShaderEmitter ctx{outputs}; + ctx.EmitDiscardShader(); + return ctx.Assemble(); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_discard_frag.h b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_discard_frag.h new file mode 100644 index 0000000..e1aa714 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_discard_frag.h @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::Backend::SPIRV { + +[[nodiscard]] std::vector EmitDiscardFragmentShader(std::array outputs); + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp new file mode 100644 index 0000000..6f78fdd --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp @@ -0,0 +1,396 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +Id Decorate(EmitContext& ctx, IR::Inst* inst, Id op) { + ctx.Decorate(op, spv::Decoration::NoContraction); + return op; +} + +Id EmitFPAbs32(EmitContext& ctx, Id value) { + return ctx.OpFAbs(ctx.F32[1], value); +} + +Id EmitFPAbs64(EmitContext& ctx, Id value) { + return ctx.OpFAbs(ctx.F64[1], value); +} + +Id EmitFPAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return Decorate(ctx, inst, ctx.OpFAdd(ctx.F32[1], a, b)); +} + +Id EmitFPAdd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return Decorate(ctx, inst, ctx.OpFAdd(ctx.F64[1], a, b)); +} + +Id EmitFPSub32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return Decorate(ctx, inst, ctx.OpFSub(ctx.F32[1], a, b)); +} + +Id EmitFPFma32(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c) { + return Decorate(ctx, inst, ctx.OpFma(ctx.F32[1], a, b, c)); +} + +Id EmitFPFma64(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c) { + return Decorate(ctx, inst, ctx.OpFma(ctx.F64[1], a, b, c)); +} + +Id EmitFPMax32(EmitContext& ctx, Id a, Id b) { + return ctx.OpFMax(ctx.F32[1], a, b); +} + +Id EmitFPMax64(EmitContext& ctx, Id a, Id b) { + return ctx.OpFMax(ctx.F64[1], a, b); +} + +Id EmitFPMin32(EmitContext& ctx, Id a, Id b) { + return ctx.OpFMin(ctx.F32[1], a, b); +} + +Id EmitFPMin64(EmitContext& ctx, Id a, Id b) { + return ctx.OpFMin(ctx.F64[1], a, b); +} + +Id EmitFPMinTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpFMin3AMD(ctx.F32[1], a, b, c); + } + return ctx.OpFMin(ctx.F32[1], a, ctx.OpFMin(ctx.F32[1], b, c)); +} + +Id EmitFPMaxTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpFMax3AMD(ctx.F32[1], a, b, c); + } + return ctx.OpFMax(ctx.F32[1], a, ctx.OpFMax(ctx.F32[1], b, c)); +} + +Id EmitFPMedTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpFMid3AMD(ctx.F32[1], a, b, c); + } + const Id mmx{ctx.OpFMin(ctx.F32[1], ctx.OpFMax(ctx.F32[1], a, b), c)}; + return ctx.OpFMax(ctx.F32[1], ctx.OpFMin(ctx.F32[1], a, b), mmx); +} + +Id EmitFPMul32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return Decorate(ctx, inst, ctx.OpFMul(ctx.F32[1], a, b)); +} + +Id EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return Decorate(ctx, inst, ctx.OpFMul(ctx.F64[1], a, b)); +} + +Id EmitFPDiv32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return Decorate(ctx, inst, ctx.OpFDiv(ctx.F32[1], a, b)); +} + +Id EmitFPDiv64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return Decorate(ctx, inst, ctx.OpFDiv(ctx.F64[1], a, b)); +} + +Id EmitFPNeg32(EmitContext& ctx, Id value) { + return ctx.OpFNegate(ctx.F32[1], value); +} + +Id EmitFPNeg64(EmitContext& ctx, Id value) { + return ctx.OpFNegate(ctx.F64[1], value); +} + +Id EmitFPSin(EmitContext& ctx, Id value) { + return ctx.OpSin(ctx.F32[1], ctx.OpFMul(ctx.F32[1], ctx.pi_x2, value)); +} + +Id EmitFPCos(EmitContext& ctx, Id value) { + return ctx.OpCos(ctx.F32[1], ctx.OpFMul(ctx.F32[1], ctx.pi_x2, value)); +} + +Id EmitFPExp2(EmitContext& ctx, Id value) { + return ctx.OpExp2(ctx.F32[1], value); +} + +Id EmitFPPow(EmitContext& ctx, Id x, Id y) { + return ctx.OpPow(ctx.F32[1], x, y); +} + +Id EmitFPLdexp(EmitContext& ctx, Id value, Id exp) { + return ctx.OpLdexp(ctx.F32[1], value, exp); +} + +Id EmitFPLog2(EmitContext& ctx, Id value) { + return ctx.OpLog2(ctx.F32[1], value); +} + +Id EmitFPRecip32(EmitContext& ctx, Id value) { + return ctx.OpFDiv(ctx.F32[1], ctx.ConstF32(1.0f), value); +} + +Id EmitFPRecip64(EmitContext& ctx, Id value) { + return ctx.OpFDiv(ctx.F64[1], ctx.Constant(ctx.F64[1], f64{1.0}), value); +} + +Id EmitFPRecipSqrt32(EmitContext& ctx, Id value) { + return ctx.OpInverseSqrt(ctx.F32[1], value); +} + +Id EmitFPRecipSqrt64(EmitContext& ctx, Id value) { + return ctx.OpInverseSqrt(ctx.F64[1], value); +} + +Id EmitFPSqrt(EmitContext& ctx, Id value) { + return ctx.OpSqrt(ctx.F32[1], value); +} + +Id EmitFPSaturate32(EmitContext& ctx, Id value) { + const Id zero{ctx.ConstF32(f32{0.0})}; + const Id one{ctx.ConstF32(f32{1.0})}; + return ctx.OpFClamp(ctx.F32[1], value, zero, one); +} + +Id EmitFPSaturate64(EmitContext& ctx, Id value) { + const Id zero{ctx.Constant(ctx.F64[1], f64{0.0})}; + const Id one{ctx.Constant(ctx.F64[1], f64{1.0})}; + return ctx.OpFClamp(ctx.F64[1], value, zero, one); +} + +Id EmitFPClamp32(EmitContext& ctx, Id value, Id min_value, Id max_value) { + return ctx.OpFClamp(ctx.F32[1], value, min_value, max_value); +} + +Id EmitFPClamp64(EmitContext& ctx, Id value, Id min_value, Id max_value) { + return ctx.OpFClamp(ctx.F64[1], value, min_value, max_value); +} + +Id EmitFPRoundEven32(EmitContext& ctx, Id value) { + return ctx.OpRoundEven(ctx.F32[1], value); +} + +Id EmitFPRoundEven64(EmitContext& ctx, Id value) { + return ctx.OpRoundEven(ctx.F64[1], value); +} + +Id EmitFPFloor32(EmitContext& ctx, Id value) { + return ctx.OpFloor(ctx.F32[1], value); +} + +Id EmitFPFloor64(EmitContext& ctx, Id value) { + return ctx.OpFloor(ctx.F64[1], value); +} + +Id EmitFPCeil32(EmitContext& ctx, Id value) { + return ctx.OpCeil(ctx.F32[1], value); +} + +Id EmitFPCeil64(EmitContext& ctx, Id value) { + return ctx.OpCeil(ctx.F64[1], value); +} + +Id EmitFPTrunc32(EmitContext& ctx, Id value) { + return ctx.OpTrunc(ctx.F32[1], value); +} + +Id EmitFPTrunc64(EmitContext& ctx, Id value) { + return ctx.OpTrunc(ctx.F64[1], value); +} + +Id EmitFPFract32(EmitContext& ctx, Id value) { + return ctx.OpFract(ctx.F32[1], value); +} + +Id EmitFPFract64(EmitContext& ctx, Id value) { + return ctx.OpFract(ctx.F64[1], value); +} + +Id EmitFPFrexpSig32(EmitContext& ctx, Id value) { + const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f32, value); + return ctx.OpCompositeExtract(ctx.F32[1], frexp, 0); +} + +Id EmitFPFrexpSig64(EmitContext& ctx, Id value) { + const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f64, value); + return ctx.OpCompositeExtract(ctx.F64[1], frexp, 0); +} + +Id EmitFPFrexpExp32(EmitContext& ctx, Id value) { + const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f32, value); + return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1)); +} + +Id EmitFPFrexpExp64(EmitContext& ctx, Id value) { + const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f64, value); + return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1)); +} + +Id EmitFPOrdEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdNotEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdNotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdNotEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdNotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdNotEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdNotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordNotEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordNotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordNotEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordNotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordNotEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordNotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdLessThan16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdLessThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdLessThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordLessThan16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordLessThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordLessThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdGreaterThan16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdGreaterThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdGreaterThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordGreaterThan16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordGreaterThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordGreaterThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdLessThanEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdLessThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdLessThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordLessThanEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordLessThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordLessThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdGreaterThanEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPOrdGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFOrdGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordGreaterThanEqual16(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPUnordGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpFUnordGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitFPIsNan16(EmitContext& ctx, Id value) { + return ctx.OpIsNan(ctx.U1[1], value); +} + +Id EmitFPIsNan32(EmitContext& ctx, Id value) { + return ctx.OpIsNan(ctx.U1[1], value); +} + +Id EmitFPIsNan64(EmitContext& ctx, Id value) { + return ctx.OpIsNan(ctx.U1[1], value); +} + +Id EmitFPIsInf32(EmitContext& ctx, Id value) { + return ctx.OpIsInf(ctx.U1[1], value); +} + +Id EmitFPIsInf64(EmitContext& ctx, Id value) { + return ctx.OpIsInf(ctx.U1[1], value); +} + +void EmitFPCmpClass32(EmitContext&) { + UNREACHABLE(); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_image.cpp new file mode 100644 index 0000000..fc4bf4b --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -0,0 +1,301 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/ir/microinstruction.h" + +namespace Shader::Backend::SPIRV { + +struct ImageOperands { + void Add(spv::ImageOperandsMask new_mask, Id value) { + if (!Sirit::ValidId(value)) { + return; + } + mask = static_cast(static_cast(mask) | + static_cast(new_mask)); + operands.push_back(value); + } + void Add(spv::ImageOperandsMask new_mask, Id value1, Id value2) { + mask = static_cast(static_cast(mask) | + static_cast(new_mask)); + operands.push_back(value1); + operands.push_back(value2); + } + + void AddOffset(EmitContext& ctx, const IR::Value& offset, + bool can_use_runtime_offsets = false) { + if (offset.IsEmpty()) { + return; + } + if (offset.IsImmediate()) { + const s32 operand = offset.U32(); + Add(spv::ImageOperandsMask::ConstOffset, ctx.ConstS32(operand)); + return; + } + IR::Inst* const inst{offset.Inst()}; + if (inst->AreAllArgsImmediates()) { + switch (inst->GetOpcode()) { + case IR::Opcode::CompositeConstructU32x2: + Add(spv::ImageOperandsMask::ConstOffset, + ctx.ConstS32(static_cast(inst->Arg(0).U32()), + static_cast(inst->Arg(1).U32()))); + return; + case IR::Opcode::CompositeConstructU32x3: + Add(spv::ImageOperandsMask::ConstOffset, + ctx.ConstS32(static_cast(inst->Arg(0).U32()), + static_cast(inst->Arg(1).U32()), + static_cast(inst->Arg(2).U32()))); + return; + default: + break; + } + } + if (can_use_runtime_offsets) { + Add(spv::ImageOperandsMask::Offset, ctx.Def(offset)); + } else { + LOG_WARNING(Render_Vulkan, + "Runtime offset provided to unsupported image sample instruction"); + } + } + + void AddDerivatives(EmitContext& ctx, Id derivatives_dx, Id derivatives_dy) { + if (!Sirit::ValidId(derivatives_dx) || !Sirit::ValidId(derivatives_dy)) { + return; + } + Add(spv::ImageOperandsMask::Grad, derivatives_dx, derivatives_dy); + } + + spv::ImageOperandsMask mask{}; + boost::container::static_vector operands; +}; + +Id EmitImageHandle(EmitContext& ctx, Id, Id) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +Id EmitImageSampleRaw(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address1, Id address2, + Id address3, Id address4) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id bias, + const IR::Value& offset) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(4); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + ImageOperands operands; + operands.Add(spv::ImageOperandsMask::Bias, bias); + operands.AddOffset(ctx, offset); + const Id sample = ctx.OpImageSampleImplicitLod(result_type, sampled_image, coords, + operands.mask, operands.operands); + return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], sample) : sample; +} + +Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, + const IR::Value& offset) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(4); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + ImageOperands operands; + operands.Add(spv::ImageOperandsMask::Lod, lod); + operands.AddOffset(ctx, offset); + const Id sample = ctx.OpImageSampleExplicitLod(result_type, sampled_image, coords, + operands.mask, operands.operands); + return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], sample) : sample; +} + +Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref, + Id bias, const IR::Value& offset) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(1); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + ImageOperands operands; + operands.Add(spv::ImageOperandsMask::Bias, bias); + operands.AddOffset(ctx, offset); + const Id sample = ctx.OpImageSampleDrefImplicitLod(result_type, sampled_image, coords, dref, + operands.mask, operands.operands); + const Id sample_typed = texture.is_integer ? ctx.OpBitcast(ctx.F32[1], sample) : sample; + return ctx.OpCompositeConstruct(ctx.F32[4], sample_typed, ctx.f32_zero_value, + ctx.f32_zero_value, ctx.f32_zero_value); +} + +Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref, + Id lod, const IR::Value& offset) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(1); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + ImageOperands operands; + operands.Add(spv::ImageOperandsMask::Lod, lod); + operands.AddOffset(ctx, offset); + const Id sample = ctx.OpImageSampleDrefExplicitLod(result_type, sampled_image, coords, dref, + operands.mask, operands.operands); + const Id sample_typed = texture.is_integer ? ctx.OpBitcast(ctx.F32[1], sample) : sample; + return ctx.OpCompositeConstruct(ctx.F32[4], sample_typed, ctx.f32_zero_value, + ctx.f32_zero_value, ctx.f32_zero_value); +} + +Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, + const IR::Value& offset) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(4); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + const u32 comp = inst->Flags().gather_comp.Value(); + ImageOperands operands; + operands.AddOffset(ctx, offset, true); + const Id texels = ctx.OpImageGather(result_type, sampled_image, coords, ctx.ConstU32(comp), + operands.mask, operands.operands); + return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], texels) : texels; +} + +Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, + const IR::Value& offset, Id dref) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(4); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + ImageOperands operands; + operands.AddOffset(ctx, offset, true); + const Id texels = ctx.OpImageDrefGather(result_type, sampled_image, coords, dref, operands.mask, + operands.operands); + return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], texels) : texels; +} + +Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool has_mips) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const auto sharp = ctx.info.images[handle & 0xFFFF].GetSharp(ctx.info); + const Id zero = ctx.u32_zero_value; + const auto mips{[&] { return has_mips ? ctx.OpImageQueryLevels(ctx.U32[1], image) : zero; }}; + const bool uses_lod{texture.view_type != AmdGpu::ImageType::Color2DMsaa && !texture.is_storage}; + const auto query{[&](Id type) { + return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod) + : ctx.OpImageQuerySize(type, image); + }}; + switch (texture.view_type) { + case AmdGpu::ImageType::Color1D: + return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips()); + case AmdGpu::ImageType::Color1DArray: + case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color2DMsaa: + return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[2]), zero, mips()); + case AmdGpu::ImageType::Color2DArray: + case AmdGpu::ImageType::Color3D: + return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[3]), mips()); + default: + UNREACHABLE_MSG("SPIR-V Instruction"); + } +} + +Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + const Id zero{ctx.f32_zero_value}; + return ctx.OpImageQueryLod(ctx.F32[2], sampled_image, coords); +} + +Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives_dx, + Id derivatives_dy, const IR::Value& offset, const IR::Value& lod_clamp) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id image = ctx.OpLoad(texture.image_type, texture.id); + const Id result_type = texture.data_types->Get(4); + const Id sampler = ctx.OpLoad(ctx.sampler_type, ctx.samplers[handle >> 16]); + const Id sampled_image = ctx.OpSampledImage(texture.sampled_type, image, sampler); + ImageOperands operands; + operands.AddDerivatives(ctx, derivatives_dx, derivatives_dy); + operands.AddOffset(ctx, offset); + const Id sample = ctx.OpImageSampleExplicitLod(result_type, sampled_image, coords, + operands.mask, operands.operands); + return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], sample) : sample; +} + +Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms) { + const auto& texture = ctx.images[handle & 0xFFFF]; + const Id color_type = texture.data_types->Get(4); + ImageOperands operands; + Id texel; + if (!texture.is_storage) { + const Id image = ctx.OpLoad(texture.image_type, texture.id); + if (texture.view_type == AmdGpu::ImageType::Color2DMsaa) { + // GCN hardware wraps out-of-range MSAA sample indices + if (Sirit::ValidId(ms)) { + const Id sample_count = ctx.OpImageQuerySamples(ctx.U32[1], image); + const Id wrapped_ms = ctx.OpUMod(ctx.U32[1], ms, sample_count); + operands.Add(spv::ImageOperandsMask::Sample, wrapped_ms); + } + } else { + if (Sirit::ValidId(ms)) { + LOG_ERROR(Render_Recompiler, "image is not MS but ms operand is provided"); + } + operands.Add(spv::ImageOperandsMask::Lod, lod); + operands.Add(spv::ImageOperandsMask::Sample, ms); + } + texel = ctx.OpImageFetch(color_type, image, coords, operands.mask, operands.operands); + } else { + Id image_ptr = texture.id; + if (ctx.profile.supports_image_load_store_lod) { + operands.Add(spv::ImageOperandsMask::Lod, lod); + } else if (Sirit::ValidId(lod)) { +#if 1 + // It's confusing what interactions will cause this code path so leave it as + // unreachable until a case is found. + // Normally IMAGE_LOAD_MIP should translate -> OpImageFetch + UNREACHABLE_MSG("Unsupported ImageRead with Lod"); +#else + LOG_WARNING(Render, "Fallback for ImageRead with LOD"); + ASSERT(texture.mip_fallback_mode == MipStorageFallbackMode::DynamicIndex); + const Id single_image_ptr_type = + ctx.TypePointer(spv::StorageClass::UniformConstant, texture.image_type); + image_ptr = ctx.OpAccessChain(single_image_ptr_type, image_ptr, std::array{lod}); +#endif + } + const Id image = ctx.OpLoad(texture.image_type, image_ptr); + texel = ctx.OpImageRead(color_type, image, coords, operands.mask, operands.operands); + } + return texture.is_integer ? ctx.OpBitcast(ctx.F32[4], texel) : texel; +} + +void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms, + Id color) { + const auto& texture = ctx.images[handle & 0xFFFF]; + Id image_ptr = texture.id; + const Id color_type = texture.data_types->Get(4); + ImageOperands operands; + operands.Add(spv::ImageOperandsMask::Sample, ms); + if (ctx.profile.supports_image_load_store_lod) { + operands.Add(spv::ImageOperandsMask::Lod, lod); + } else if (Sirit::ValidId(lod)) { + LOG_WARNING(Render, "Fallback for ImageWrite with LOD"); + ASSERT(texture.mip_fallback_mode == MipStorageFallbackMode::DynamicIndex); + const Id single_image_ptr_type = + ctx.TypePointer(spv::StorageClass::UniformConstant, texture.image_type); + image_ptr = ctx.OpAccessChain(single_image_ptr_type, image_ptr, std::array{lod}); + } + const Id image = ctx.OpLoad(texture.image_type, image_ptr); + const Id texel = texture.is_integer ? ctx.OpBitcast(color_type, color) : color; + ctx.OpImageWrite(image, coords, texel, operands.mask, operands.operands); +} + +Id EmitCubeFaceIndex(EmitContext& ctx, IR::Inst* inst, Id cube_coords) { + if (ctx.profile.supports_native_cube_calc) { + return ctx.OpCubeFaceIndexAMD(ctx.F32[1], cube_coords); + } else { + UNREACHABLE_MSG("SPIR-V Instruction"); + } +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_instructions.h new file mode 100644 index 0000000..2f6e052 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -0,0 +1,491 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace Shader::IR { +enum class Attribute : u64; +enum class ScalarReg : u32; +enum class Patch : u64; +class Inst; +class Value; +} // namespace Shader::IR + +namespace Shader::Backend::SPIRV { + +using Sirit::Id; + +class EmitContext; + +// Microinstruction emitters +Id EmitPhi(EmitContext& ctx, IR::Inst* inst); +void EmitVoid(EmitContext& ctx); +Id EmitConditionRef(EmitContext& ctx, const IR::Value& value); +void EmitGetScc(EmitContext& ctx); +void EmitGetExec(EmitContext& ctx); +void EmitGetVcc(EmitContext& ctx); +void EmitGetVccLo(EmitContext& ctx); +void EmitGetVccHi(EmitContext& ctx); +void EmitGetM0(EmitContext& ctx); +void EmitSetScc(EmitContext& ctx); +void EmitSetExec(EmitContext& ctx); +void EmitSetVcc(EmitContext& ctx); +void EmitSetVccLo(EmitContext& ctx); +void EmitSetVccHi(EmitContext& ctx); +void EmitSetM0(EmitContext& ctx); +void EmitFPCmpClass32(EmitContext& ctx); +void EmitPrologue(EmitContext& ctx); +void EmitEpilogue(EmitContext& ctx); +void EmitDiscard(EmitContext& ctx); +void EmitDiscardCond(EmitContext& ctx, Id condition); +void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id arg0, Id arg1, Id arg2, Id arg3, Id arg4); +Id EmitMemtime(EmitContext& ctx); +void EmitBarrier(EmitContext& ctx); +void EmitWorkgroupMemoryBarrier(EmitContext& ctx); +void EmitDeviceMemoryBarrier(EmitContext& ctx); +Id EmitGetUserData(EmitContext& ctx, IR::ScalarReg reg); +void EmitGetThreadBitScalarReg(EmitContext& ctx); +void EmitSetThreadBitScalarReg(EmitContext& ctx); +void EmitGetScalarRegister(EmitContext& ctx); +void EmitSetScalarRegister(EmitContext& ctx); +void EmitGetVectorRegister(EmitContext& ctx); +void EmitSetVectorRegister(EmitContext& ctx); +void EmitSetVirtualRegister(EmitContext& ctx); +void EmitGetVirtualRegister(EmitContext& ctx); +void EmitSetGotoVariable(EmitContext& ctx); +void EmitGetGotoVariable(EmitContext& ctx); +void EmitSetMaskLaneVariable(EmitContext& ctx); +void EmitGetMaskLaneVariable(EmitContext& ctx); +void EmitSetScc(EmitContext& ctx); +Id EmitReadConst(EmitContext& ctx, IR::Inst* inst, Id addr, Id offset); +Id EmitReadConstBuffer(EmitContext& ctx, u32 handle, Id index); +Id EmitLoadBufferU8(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferU16(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferU32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferU32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferU32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferU64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitLoadBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +void EmitStoreBufferU8(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferU16(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferU32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferU32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferU32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferU64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +void EmitStoreBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicIAdd64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicISub32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicSMin64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicUMin64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicFMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicSMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicUMax64(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicInc32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitBufferAtomicDec32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address); +Id EmitBufferAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value); +Id EmitBufferAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id cmp_value); +Id EmitBufferAtomicFCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id cmp_value); +Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index); +Id EmitGetAttributeU1(EmitContext& ctx, IR::Attribute attr, u32 comp); +Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp); +void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 comp); +Id EmitGetTessGenericAttribute(EmitContext& ctx, Id vertex_index, Id attr_index, Id comp_index); +void EmitSetTcsGenericAttribute(EmitContext& ctx, Id value, Id attr_index, Id comp_index); +Id EmitReadTcsGenericOuputAttribute(EmitContext& ctx, Id vertex_index, Id attr_index, + Id comp_index); +Id EmitGetPcLo(EmitContext& ctx, const IR::Value& value); +Id EmitGetPatch(EmitContext& ctx, IR::Patch patch); +void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value); +Id EmitWorkgroupId(EmitContext& ctx); +Id EmitLocalInvocationId(EmitContext& ctx); +Id EmitInvocationId(EmitContext& ctx); +Id EmitInvocationInfo(EmitContext& ctx); +Id EmitUndefU1(EmitContext& ctx); +Id EmitUndefU8(EmitContext& ctx); +Id EmitUndefU16(EmitContext& ctx); +Id EmitUndefU32(EmitContext& ctx); +Id EmitUndefU32x2(EmitContext& ctx); +Id EmitUndefU32x3(EmitContext& ctx); +Id EmitUndefU32x4(EmitContext& ctx); +Id EmitUndefF32(EmitContext& ctx); +Id EmitUndefU64(EmitContext& ctx); +Id EmitLoadSharedU16(EmitContext& ctx, Id offset); +Id EmitLoadSharedU32(EmitContext& ctx, Id offset); +Id EmitLoadSharedU64(EmitContext& ctx, Id offset); +void EmitWriteSharedU16(EmitContext& ctx, Id offset, Id value); +void EmitWriteSharedU32(EmitContext& ctx, Id offset, Id value); +void EmitWriteSharedU64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicIAdd32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicIAdd64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicUMax32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicUMax64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicSMax32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicSMax64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicUMin32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicUMin64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicSMin64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicAnd32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicAnd64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicOr32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicOr64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicXor32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicXor64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicInc32(EmitContext& ctx, Id offset); +Id EmitSharedAtomicInc64(EmitContext& ctx, Id offset); +Id EmitSharedAtomicDec32(EmitContext& ctx, Id offset); +Id EmitSharedAtomicDec64(EmitContext& ctx, Id offset); +Id EmitSharedAtomicISub32(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicISub64(EmitContext& ctx, Id offset, Id value); +Id EmitSharedAtomicCmpSwap32(EmitContext& ctx, Id offset, Id value, Id cmp_value); +Id EmitSharedAtomicCmpSwap64(EmitContext& ctx, Id offset, Id value, Id cmp_value); + +Id EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2); +Id EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3); +Id EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3, Id e4); +Id EmitCompositeConstructU32x2x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2); +Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index); +Id EmitCompositeExtractU32x3(EmitContext& ctx, Id composite, u32 index); +Id EmitCompositeExtractU32x4(EmitContext& ctx, Id composite, u32 index); +Id EmitCompositeInsertU32x2(EmitContext& ctx, Id composite, Id object, u32 index); +Id EmitCompositeInsertU32x3(EmitContext& ctx, Id composite, Id object, u32 index); +Id EmitCompositeInsertU32x4(EmitContext& ctx, Id composite, Id object, u32 index); +Id EmitCompositeShuffleU32x2(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1); +Id EmitCompositeShuffleU32x3(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2); +Id EmitCompositeShuffleU32x4(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2, u32 comp3); +Id EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2); +Id EmitCompositeConstructF32x3(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3); +Id EmitCompositeConstructF32x4(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3, Id e4); +Id EmitCompositeConstructF32x2x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2); +Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index); +Id EmitCompositeExtractF32x3(EmitContext& ctx, Id composite, u32 index); +Id EmitCompositeExtractF32x4(EmitContext& ctx, Id composite, u32 index); +Id EmitCompositeInsertF32x2(EmitContext& ctx, Id composite, Id object, u32 index); +Id EmitCompositeInsertF32x3(EmitContext& ctx, Id composite, Id object, u32 index); +Id EmitCompositeInsertF32x4(EmitContext& ctx, Id composite, Id object, u32 index); +Id EmitCompositeShuffleF32x2(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1); +Id EmitCompositeShuffleF32x3(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2); +Id EmitCompositeShuffleF32x4(EmitContext& ctx, Id composite1, Id composite2, u32 comp0, u32 comp1, + u32 comp2, u32 comp3); +Id EmitSelectU1(EmitContext& ctx, Id cond, Id true_value, Id false_value); +Id EmitSelectU32(EmitContext& ctx, Id cond, Id true_value, Id false_value); +Id EmitSelectF32(EmitContext& ctx, Id cond, Id true_value, Id false_value); +Id EmitSelectU64(EmitContext& ctx, Id cond, Id true_value, Id false_value); +Id EmitBitCastU16F16(EmitContext& ctx, Id value); +Id EmitBitCastU32F32(EmitContext& ctx, Id value); +Id EmitBitCastF16U16(EmitContext& ctx, Id value); +Id EmitBitCastF32U32(EmitContext& ctx, Id value); +Id EmitPackUint2x32(EmitContext& ctx, Id value); +Id EmitUnpackUint2x32(EmitContext& ctx, Id value); +Id EmitPackDouble2x32(EmitContext& ctx, Id value); +Id EmitUnpackDouble2x32(EmitContext& ctx, Id value); +Id EmitPackUnorm2x16(EmitContext& ctx, Id value); +Id EmitUnpackUnorm2x16(EmitContext& ctx, Id value); +Id EmitPackSnorm2x16(EmitContext& ctx, Id value); +Id EmitUnpackSnorm2x16(EmitContext& ctx, Id value); +Id EmitPackUint2x16(EmitContext& ctx, Id value); +Id EmitUnpackUint2x16(EmitContext& ctx, Id value); +Id EmitPackSint2x16(EmitContext& ctx, Id value); +Id EmitUnpackSint2x16(EmitContext& ctx, Id value); +Id EmitPackHalf2x16(EmitContext& ctx, Id value); +Id EmitUnpackHalf2x16(EmitContext& ctx, Id value); +Id EmitPackUnorm4x8(EmitContext& ctx, Id value); +Id EmitUnpackUnorm4x8(EmitContext& ctx, Id value); +Id EmitPackSnorm4x8(EmitContext& ctx, Id value); +Id EmitUnpackSnorm4x8(EmitContext& ctx, Id value); +Id EmitPackUint4x8(EmitContext& ctx, Id value); +Id EmitUnpackUint4x8(EmitContext& ctx, Id value); +Id EmitPackSint4x8(EmitContext& ctx, Id value); +Id EmitUnpackSint4x8(EmitContext& ctx, Id value); +Id EmitPackUfloat10_11_11(EmitContext& ctx, Id value); +Id EmitUnpackUfloat10_11_11(EmitContext& ctx, Id value); +Id EmitPackUnorm2_10_10_10(EmitContext& ctx, Id value); +Id EmitUnpackUnorm2_10_10_10(EmitContext& ctx, Id value); +Id EmitPackSnorm2_10_10_10(EmitContext& ctx, Id value); +Id EmitUnpackSnorm2_10_10_10(EmitContext& ctx, Id value); +Id EmitPackUint2_10_10_10(EmitContext& ctx, Id value); +Id EmitUnpackUint2_10_10_10(EmitContext& ctx, Id value); +Id EmitPackSint2_10_10_10(EmitContext& ctx, Id value); +Id EmitUnpackSint2_10_10_10(EmitContext& ctx, Id value); +Id EmitFPAbs32(EmitContext& ctx, Id value); +Id EmitFPAbs64(EmitContext& ctx, Id value); +Id EmitFPAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitFPAdd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitFPSub32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitFPFma32(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c); +Id EmitFPFma64(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c); +Id EmitFPMax32(EmitContext& ctx, Id a, Id b); +Id EmitFPMax64(EmitContext& ctx, Id a, Id b); +Id EmitFPMin32(EmitContext& ctx, Id a, Id b); +Id EmitFPMin64(EmitContext& ctx, Id a, Id b); +Id EmitFPMinTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitFPMaxTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitFPMedTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitFPMul32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitFPDiv32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitFPDiv64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitFPNeg32(EmitContext& ctx, Id value); +Id EmitFPNeg64(EmitContext& ctx, Id value); +Id EmitFPSin(EmitContext& ctx, Id value); +Id EmitFPCos(EmitContext& ctx, Id value); +Id EmitFPExp2(EmitContext& ctx, Id value); +Id EmitFPPow(EmitContext& ctx, Id x, Id y); +Id EmitFPLdexp(EmitContext& ctx, Id value, Id exp); +Id EmitFPLog2(EmitContext& ctx, Id value); +Id EmitFPRecip32(EmitContext& ctx, Id value); +Id EmitFPRecip64(EmitContext& ctx, Id value); +Id EmitFPRecipSqrt32(EmitContext& ctx, Id value); +Id EmitFPRecipSqrt64(EmitContext& ctx, Id value); +Id EmitFPSqrt(EmitContext& ctx, Id value); +Id EmitFPSaturate32(EmitContext& ctx, Id value); +Id EmitFPSaturate64(EmitContext& ctx, Id value); +Id EmitFPClamp32(EmitContext& ctx, Id value, Id min_value, Id max_value); +Id EmitFPClamp64(EmitContext& ctx, Id value, Id min_value, Id max_value); +Id EmitFPRoundEven32(EmitContext& ctx, Id value); +Id EmitFPRoundEven64(EmitContext& ctx, Id value); +Id EmitFPFloor32(EmitContext& ctx, Id value); +Id EmitFPFloor64(EmitContext& ctx, Id value); +Id EmitFPCeil32(EmitContext& ctx, Id value); +Id EmitFPCeil64(EmitContext& ctx, Id value); +Id EmitFPTrunc32(EmitContext& ctx, Id value); +Id EmitFPTrunc64(EmitContext& ctx, Id value); +Id EmitFPFract32(EmitContext& ctx, Id value); +Id EmitFPFract64(EmitContext& ctx, Id value); +Id EmitFPFrexpSig32(EmitContext& ctx, Id value); +Id EmitFPFrexpSig64(EmitContext& ctx, Id value); +Id EmitFPFrexpExp32(EmitContext& ctx, Id value); +Id EmitFPFrexpExp64(EmitContext& ctx, Id value); +Id EmitFPOrdEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdNotEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdNotEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordNotEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordNotEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdLessThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdLessThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordLessThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordLessThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdGreaterThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdGreaterThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordGreaterThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordGreaterThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdLessThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdLessThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordLessThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordLessThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPOrdGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPUnordGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitFPIsNan32(EmitContext& ctx, Id value); +Id EmitFPIsNan64(EmitContext& ctx, Id value); +Id EmitFPIsInf32(EmitContext& ctx, Id value); +Id EmitFPIsInf64(EmitContext& ctx, Id value); +Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitIAdd64(EmitContext& ctx, Id a, Id b); +Id EmitIAddCarry32(EmitContext& ctx, Id a, Id b); +Id EmitISub32(EmitContext& ctx, Id a, Id b); +Id EmitISub64(EmitContext& ctx, Id a, Id b); +Id EmitSMulHi(EmitContext& ctx, Id a, Id b); +Id EmitUMulHi(EmitContext& ctx, Id a, Id b); +Id EmitIMul32(EmitContext& ctx, Id a, Id b); +Id EmitIMul64(EmitContext& ctx, Id a, Id b); +Id EmitSDiv32(EmitContext& ctx, Id a, Id b); +Id EmitUDiv32(EmitContext& ctx, Id a, Id b); +Id EmitSMod32(EmitContext& ctx, Id a, Id b); +Id EmitUMod32(EmitContext& ctx, Id a, Id b); +Id EmitINeg32(EmitContext& ctx, Id value); +Id EmitINeg64(EmitContext& ctx, Id value); +Id EmitIAbs32(EmitContext& ctx, Id value); +Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift); +Id EmitShiftLeftLogical64(EmitContext& ctx, Id base, Id shift); +Id EmitShiftRightLogical32(EmitContext& ctx, Id base, Id shift); +Id EmitShiftRightLogical64(EmitContext& ctx, Id base, Id shift); +Id EmitShiftRightArithmetic32(EmitContext& ctx, Id base, Id shift); +Id EmitShiftRightArithmetic64(EmitContext& ctx, Id base, Id shift); +Id EmitBitwiseAnd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitBitwiseAnd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitBitwiseOr32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitBitwiseOr64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitBitwiseXor32(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitBitwiseXor64(EmitContext& ctx, IR::Inst* inst, Id a, Id b); +Id EmitBitFieldInsert32(EmitContext& ctx, Id base, Id insert, Id offset, Id count); +Id EmitBitFieldInsert64(EmitContext& ctx, Id base, Id insert, Id offset, Id count); +Id EmitBitFieldSExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count); +Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count); +Id EmitBitReverse32(EmitContext& ctx, Id value); +Id EmitBitCount32(EmitContext& ctx, Id value); +Id EmitBitCount64(EmitContext& ctx, Id value); +Id EmitBitwiseNot32(EmitContext& ctx, Id value); +Id EmitBitwiseNot64(EmitContext& ctx, Id value); +Id EmitMaskedBitCount32(EmitContext& ctx, Id value, Id addend, bool hi); +Id EmitFindSMsb32(EmitContext& ctx, Id value); +Id EmitFindUMsb32(EmitContext& ctx, Id value); +Id EmitFindUMsb64(EmitContext& ctx, Id value); +Id EmitFindILsb32(EmitContext& ctx, Id value); +Id EmitFindILsb64(EmitContext& ctx, Id value); +Id EmitSMin32(EmitContext& ctx, Id a, Id b); +Id EmitUMin32(EmitContext& ctx, Id a, Id b); +Id EmitSMax32(EmitContext& ctx, Id a, Id b); +Id EmitUMax32(EmitContext& ctx, Id a, Id b); +Id EmitSMinTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitUMinTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitSMaxTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitUMaxTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitSMedTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitUMedTri32(EmitContext& ctx, Id a, Id b, Id c); +Id EmitSClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max); +Id EmitUClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max); +Id EmitSLessThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitSLessThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitULessThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitULessThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitIEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitIEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitSLessThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitSLessThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitULessThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitULessThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitSGreaterThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitSGreaterThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitUGreaterThan32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitUGreaterThan64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitINotEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitINotEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitSGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitSGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitUGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs); +Id EmitUGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs); +Id EmitLogicalOr(EmitContext& ctx, Id a, Id b); +Id EmitLogicalAnd(EmitContext& ctx, Id a, Id b); +Id EmitLogicalXor(EmitContext& ctx, Id a, Id b); +Id EmitLogicalNot(EmitContext& ctx, Id value); +Id EmitConvertS16F32(EmitContext& ctx, Id value); +Id EmitConvertS16F64(EmitContext& ctx, Id value); +Id EmitConvertS32F32(EmitContext& ctx, Id value); +Id EmitConvertS32F64(EmitContext& ctx, Id value); +Id EmitConvertS64F32(EmitContext& ctx, Id value); +Id EmitConvertS64F64(EmitContext& ctx, Id value); +Id EmitConvertU16F32(EmitContext& ctx, Id value); +Id EmitConvertU16F64(EmitContext& ctx, Id value); +Id EmitConvertU32F32(EmitContext& ctx, Id value); +Id EmitConvertU32F64(EmitContext& ctx, Id value); +Id EmitConvertU64F32(EmitContext& ctx, Id value); +Id EmitConvertU64F64(EmitContext& ctx, Id value); +Id EmitConvertU64U32(EmitContext& ctx, Id value); +Id EmitConvertU32U64(EmitContext& ctx, Id value); +Id EmitConvertF16F32(EmitContext& ctx, Id value); +Id EmitConvertF32F16(EmitContext& ctx, Id value); +Id EmitConvertF32F64(EmitContext& ctx, Id value); +Id EmitConvertF64F32(EmitContext& ctx, Id value); +Id EmitConvertF32S8(EmitContext& ctx, Id value); +Id EmitConvertF32S16(EmitContext& ctx, Id value); +Id EmitConvertF32S32(EmitContext& ctx, Id value); +Id EmitConvertF32S64(EmitContext& ctx, Id value); +Id EmitConvertF32U8(EmitContext& ctx, Id value); +Id EmitConvertF32U16(EmitContext& ctx, Id value); +Id EmitConvertF32U32(EmitContext& ctx, Id value); +Id EmitConvertF32U64(EmitContext& ctx, Id value); +Id EmitConvertF64S8(EmitContext& ctx, Id value); +Id EmitConvertF64S16(EmitContext& ctx, Id value); +Id EmitConvertF64S32(EmitContext& ctx, Id value); +Id EmitConvertF64S64(EmitContext& ctx, Id value); +Id EmitConvertF64U8(EmitContext& ctx, Id value); +Id EmitConvertF64U16(EmitContext& ctx, Id value); +Id EmitConvertF64U32(EmitContext& ctx, Id value); +Id EmitConvertF64U64(EmitContext& ctx, Id value); +Id EmitConvertU16U32(EmitContext& ctx, Id value); +Id EmitConvertU32U16(EmitContext& ctx, Id value); +Id EmitConvertU8U32(EmitContext& ctx, Id value); +Id EmitConvertU32U8(EmitContext& ctx, Id value); +Id EmitConvertS32S8(EmitContext& ctx, Id value); +Id EmitConvertS32S16(EmitContext& ctx, Id value); + +Id EmitImageHandle(EmitContext& ctx, Id, Id); +Id EmitImageSampleRaw(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address1, Id address2, + Id address3, Id address4); +Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id bias, + const IR::Value& offset); +Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, + const IR::Value& offset); +Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref, + Id bias, const IR::Value& offset); +Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id dref, + Id lod, const IR::Value& offset); +Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, + const IR::Value& offset); +Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, + const IR::Value& offset, Id dref); +Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool skip_mips); +Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords); +Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id derivatives_dx, + Id derivatives_dy, const IR::Value& offset, const IR::Value& lod_clamp); +Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms); +void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id lod, Id ms, + Id color); + +Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicFMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicInc32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicDec32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value); +Id EmitImageAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value, + Id cmp_value); +Id EmitCubeFaceIndex(EmitContext& ctx, IR::Inst* inst, Id cube_coords); +Id EmitLaneId(EmitContext& ctx); +Id EmitWarpId(EmitContext& ctx); +Id EmitQuadBroadcast(EmitContext& ctx, Id value, Id index); +Id EmitShuffle(EmitContext& ctx, Id value, Id index); +Id EmitShuffleXor(EmitContext& ctx, Id value, Id mask); +Id EmitReadFirstLane(EmitContext& ctx, Id value); +Id EmitReadLane(EmitContext& ctx, Id value, Id lane); +Id EmitWriteLane(EmitContext& ctx, Id value, Id write_value, u32 lane); +Id EmitBallot(EmitContext& ctx, Id bit); +Id EmitBallotFindLsb(EmitContext& ctx, Id mask); +Id EmitInverseBallot(EmitContext& ctx, Id mask); +Id EmitGroupAny(EmitContext& ctx, Id bit); +Id EmitDataAppend(EmitContext& ctx, Id gds_dw_offset, Id exec); +Id EmitDataConsume(EmitContext& ctx, Id gds_dw_offset, Id exec); + +void EmitEmitVertex(EmitContext& ctx); +void EmitEmitPrimitive(EmitContext& ctx); + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_integer.cpp new file mode 100644 index 0000000..bc5acec --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_integer.cpp @@ -0,0 +1,449 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { +namespace { +void SetZeroFlag(EmitContext& ctx, IR::Inst* inst, Id result) { + // IR::Inst* const zero{inst->GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}; + // if (!zero) { + // return; + // } + // zero->SetDefinition(ctx.OpIEqual(ctx.U1[1], result, ctx.u32_zero_value)); + // zero->Invalidate(); +} + +void SetSignFlag(EmitContext& ctx, IR::Inst* inst, Id result) { + // IR::Inst* const sign{inst->GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp)}; + // if (!sign) { + // return; + // } + // sign->SetDefinition(ctx.OpSLessThan(ctx.U1[1], result, ctx.u32_zero_value)); + // sign->Invalidate(); +} +} // Anonymous namespace + +Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + return ctx.OpIAdd(ctx.U32[1], a, b); + // Id result{}; + // if (IR::Inst* const carry{inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp)}) { + // const Id carry_type{ctx.TypeStruct(ctx.U32[1], ctx.U32[1])}; + // const Id carry_result{ctx.OpIAddCarry(carry_type, a, b)}; + // result = ctx.OpCompositeExtract(ctx.U32[1], carry_result, 0U); + + // const Id carry_value{ctx.OpCompositeExtract(ctx.U32[1], carry_result, 1U)}; + // carry->SetDefinition(ctx.OpINotEqual(ctx.U1[1][1], carry_value, ctx.u32_zero_value)); + // carry->Invalidate(); + //} else { + // result = ctx.OpIAdd(ctx.U32[1], a, b); + //} + // SetZeroFlag(ctx, inst, result); + // SetSignFlag(ctx, inst, result); + // if (IR::Inst * overflow{inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)}) { + // // https://stackoverflow.com/questions/55468823/how-to-detect-integer-overflow-in-c + // constexpr u32 s32_max{static_cast(std::numeric_limits::max())}; + // const Id is_positive{ctx.OpSGreaterThanEqual(ctx.U1[1], a, ctx.u32_zero_value)}; + // const Id sub_a{ctx.OpISub(ctx.U32[1], ctx.Const(s32_max), a)}; + + // const Id positive_test{ctx.OpSGreaterThan(ctx.U1[1], b, sub_a)}; + // const Id negative_test{ctx.OpSLessThan(ctx.U1[1], b, sub_a)}; + // const Id carry_flag{ctx.OpSelect(ctx.U1[1], is_positive, positive_test, negative_test)}; + // overflow->SetDefinition(carry_flag); + // overflow->Invalidate(); + //} + // return result; +} + +Id EmitIAdd64(EmitContext& ctx, Id a, Id b) { + return ctx.OpIAdd(ctx.U64, a, b); +} + +Id EmitIAddCarry32(EmitContext& ctx, Id a, Id b) { + return ctx.OpIAddCarry(ctx.full_result_u32x2, a, b); +} + +Id EmitISub32(EmitContext& ctx, Id a, Id b) { + return ctx.OpISub(ctx.U32[1], a, b); +} + +Id EmitISub64(EmitContext& ctx, Id a, Id b) { + return ctx.OpISub(ctx.U64, a, b); +} + +Id EmitSMulHi(EmitContext& ctx, Id a, Id b) { + const auto signed_a{ctx.OpBitcast(ctx.S32[1], a)}; + const auto signed_b{ctx.OpBitcast(ctx.S32[1], b)}; + const auto mul_ext{ctx.OpSMulExtended(ctx.full_result_i32x2, signed_a, signed_b)}; + const auto signed_hi{ctx.OpCompositeExtract(ctx.S32[1], mul_ext, 1)}; + return ctx.OpBitcast(ctx.U32[1], signed_hi); +} + +Id EmitUMulHi(EmitContext& ctx, Id a, Id b) { + const auto mul_ext{ctx.OpUMulExtended(ctx.full_result_u32x2, a, b)}; + return ctx.OpCompositeExtract(ctx.U32[1], mul_ext, 1); +} + +Id EmitIMul32(EmitContext& ctx, Id a, Id b) { + return ctx.OpIMul(ctx.U32[1], a, b); +} + +Id EmitIMul64(EmitContext& ctx, Id a, Id b) { + return ctx.OpIMul(ctx.U64, a, b); +} + +Id EmitSDiv32(EmitContext& ctx, Id a, Id b) { + return ctx.OpSDiv(ctx.U32[1], a, b); +} + +Id EmitUDiv32(EmitContext& ctx, Id a, Id b) { + return ctx.OpUDiv(ctx.U32[1], a, b); +} + +Id EmitSMod32(EmitContext& ctx, Id a, Id b) { + return ctx.OpSMod(ctx.U32[1], a, b); +} + +Id EmitUMod32(EmitContext& ctx, Id a, Id b) { + return ctx.OpUMod(ctx.U32[1], a, b); +} + +Id EmitINeg32(EmitContext& ctx, Id value) { + return ctx.OpSNegate(ctx.U32[1], value); +} + +Id EmitINeg64(EmitContext& ctx, Id value) { + return ctx.OpSNegate(ctx.U64, value); +} + +Id EmitIAbs32(EmitContext& ctx, Id value) { + return ctx.OpSAbs(ctx.U32[1], value); +} + +Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift) { + return ctx.OpShiftLeftLogical(ctx.U32[1], base, shift); +} + +Id EmitShiftLeftLogical64(EmitContext& ctx, Id base, Id shift) { + return ctx.OpShiftLeftLogical(ctx.U64, base, shift); +} + +Id EmitShiftRightLogical32(EmitContext& ctx, Id base, Id shift) { + return ctx.OpShiftRightLogical(ctx.U32[1], base, shift); +} + +Id EmitShiftRightLogical64(EmitContext& ctx, Id base, Id shift) { + return ctx.OpShiftRightLogical(ctx.U64, base, shift); +} + +Id EmitShiftRightArithmetic32(EmitContext& ctx, Id base, Id shift) { + return ctx.OpShiftRightArithmetic(ctx.U32[1], base, shift); +} + +Id EmitShiftRightArithmetic64(EmitContext& ctx, Id base, Id shift) { + return ctx.OpShiftRightArithmetic(ctx.U64, base, shift); +} + +Id EmitBitwiseAnd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + const Id result{ctx.OpBitwiseAnd(ctx.U32[1], a, b)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitwiseAnd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + const Id result{ctx.OpBitwiseAnd(ctx.U64, a, b)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitwiseOr32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + const Id result{ctx.OpBitwiseOr(ctx.U32[1], a, b)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitwiseOr64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + const Id result{ctx.OpBitwiseOr(ctx.U64, a, b)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitwiseXor32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + const Id result{ctx.OpBitwiseXor(ctx.U32[1], a, b)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitwiseXor64(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { + const Id result{ctx.OpBitwiseXor(ctx.U64, a, b)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitFieldInsert32(EmitContext& ctx, Id base, Id insert, Id offset, Id count) { + return ctx.OpBitFieldInsert(ctx.U32[1], base, insert, offset, count); +} + +Id EmitBitFieldInsert64(EmitContext& ctx, Id base, Id insert, Id offset, Id count) { + return ctx.OpBitFieldInsert(ctx.U64, base, insert, offset, count); +} + +Id EmitBitFieldSExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count) { + const Id result{ctx.OpBitFieldSExtract(ctx.U32[1], base, offset, count)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count) { + const Id result{ctx.OpBitFieldUExtract(ctx.U32[1], base, offset, count)}; + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitBitReverse32(EmitContext& ctx, Id value) { + return ctx.OpBitReverse(ctx.U32[1], value); +} + +Id EmitBitCount32(EmitContext& ctx, Id value) { + return ctx.OpBitCount(ctx.U32[1], value); +} + +Id EmitBitCount64(EmitContext& ctx, Id value) { + // Vulkan restricts some bitwise operations to 32-bit only, so decompose into + // two 32-bit values and add the result. + const Id unpacked{ctx.OpBitcast(ctx.U32[2], value)}; + const Id lo{ctx.OpCompositeExtract(ctx.U32[1], unpacked, 0U)}; + const Id hi{ctx.OpCompositeExtract(ctx.U32[1], unpacked, 1U)}; + const Id lo_count{ctx.OpBitCount(ctx.U32[1], lo)}; + const Id hi_count{ctx.OpBitCount(ctx.U32[1], hi)}; + return ctx.OpIAdd(ctx.U32[1], lo_count, hi_count); +} + +Id EmitBitwiseNot32(EmitContext& ctx, Id value) { + return ctx.OpNot(ctx.U32[1], value); +} + +Id EmitBitwiseNot64(EmitContext& ctx, Id value) { + return ctx.OpNot(ctx.U64, value); +} + +Id EmitFindSMsb32(EmitContext& ctx, Id value) { + return ctx.OpFindSMsb(ctx.U32[1], value); +} + +Id EmitFindUMsb32(EmitContext& ctx, Id value) { + return ctx.OpFindUMsb(ctx.U32[1], value); +} + +Id EmitFindUMsb64(EmitContext& ctx, Id value) { + // Vulkan restricts some bitwise operations to 32-bit only, so decompose into + // two 32-bit values and select the correct result. + const Id unpacked{ctx.OpBitcast(ctx.U32[2], value)}; + const Id hi{ctx.OpCompositeExtract(ctx.U32[1], unpacked, 1U)}; + const Id lo{ctx.OpCompositeExtract(ctx.U32[1], unpacked, 0U)}; + const Id hi_msb{ctx.OpFindUMsb(ctx.U32[1], hi)}; + const Id lo_msb{ctx.OpFindUMsb(ctx.U32[1], lo)}; + const Id found_hi{ctx.OpINotEqual(ctx.U1[1], hi_msb, ctx.ConstU32(u32(-1)))}; + const Id shifted_hi{ctx.OpIAdd(ctx.U32[1], hi_msb, ctx.ConstU32(32u))}; + // value == 0 case is checked in IREmitter + return ctx.OpSelect(ctx.U32[1], found_hi, shifted_hi, lo_msb); +} + +Id EmitFindILsb32(EmitContext& ctx, Id value) { + return ctx.OpFindILsb(ctx.U32[1], value); +} + +Id EmitFindILsb64(EmitContext& ctx, Id value) { + // Vulkan restricts some bitwise operations to 32-bit only, so decompose into + // two 32-bit values and select the correct result. + const Id unpacked{ctx.OpBitcast(ctx.U32[2], value)}; + const Id lo{ctx.OpCompositeExtract(ctx.U32[1], unpacked, 0U)}; + const Id hi{ctx.OpCompositeExtract(ctx.U32[1], unpacked, 1U)}; + const Id lo_lsb{ctx.OpFindILsb(ctx.U32[1], lo)}; + const Id hi_lsb{ctx.OpFindILsb(ctx.U32[1], hi)}; + const Id found_lo{ctx.OpINotEqual(ctx.U1[1], lo_lsb, ctx.ConstU32(u32(-1)))}; + return ctx.OpSelect(ctx.U32[1], found_lo, lo_lsb, hi_lsb); +} + +Id EmitSMin32(EmitContext& ctx, Id a, Id b) { + return ctx.OpSMin(ctx.U32[1], a, b); +} + +Id EmitUMin32(EmitContext& ctx, Id a, Id b) { + return ctx.OpUMin(ctx.U32[1], a, b); +} + +Id EmitSMax32(EmitContext& ctx, Id a, Id b) { + return ctx.OpSMax(ctx.U32[1], a, b); +} + +Id EmitUMax32(EmitContext& ctx, Id a, Id b) { + return ctx.OpUMax(ctx.U32[1], a, b); +} + +Id EmitSMinTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpSMin3AMD(ctx.U32[1], a, b, c); + } + return ctx.OpSMin(ctx.U32[1], a, ctx.OpSMin(ctx.U32[1], b, c)); +} + +Id EmitUMinTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpUMin3AMD(ctx.U32[1], a, b, c); + } + return ctx.OpUMin(ctx.U32[1], a, ctx.OpUMin(ctx.U32[1], b, c)); +} + +Id EmitSMaxTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpSMax3AMD(ctx.U32[1], a, b, c); + } + return ctx.OpSMax(ctx.U32[1], a, ctx.OpSMax(ctx.U32[1], b, c)); +} + +Id EmitUMaxTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpUMax3AMD(ctx.U32[1], a, b, c); + } + return ctx.OpUMax(ctx.U32[1], a, ctx.OpUMax(ctx.U32[1], b, c)); +} + +Id EmitSMedTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpSMid3AMD(ctx.U32[1], a, b, c); + } + const Id mmx{ctx.OpSMin(ctx.U32[1], ctx.OpSMax(ctx.U32[1], a, b), c)}; + return ctx.OpSMax(ctx.U32[1], ctx.OpSMin(ctx.U32[1], a, b), mmx); +} + +Id EmitUMedTri32(EmitContext& ctx, Id a, Id b, Id c) { + if (ctx.profile.supports_trinary_minmax) { + return ctx.OpUMid3AMD(ctx.U32[1], a, b, c); + } + const Id mmx{ctx.OpUMin(ctx.U32[1], ctx.OpUMax(ctx.U32[1], a, b), c)}; + return ctx.OpUMax(ctx.U32[1], ctx.OpUMin(ctx.U32[1], a, b), mmx); +} + +Id EmitSClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max) { + Id result{}; + if (ctx.profile.has_broken_spirv_clamp) { + value = ctx.OpBitcast(ctx.S32[1], value); + min = ctx.OpBitcast(ctx.S32[1], min); + max = ctx.OpBitcast(ctx.S32[1], max); + result = ctx.OpSMax(ctx.S32[1], ctx.OpSMin(ctx.S32[1], value, max), min); + result = ctx.OpBitcast(ctx.U32[1], result); + } else { + result = ctx.OpSClamp(ctx.U32[1], value, min, max); + } + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitUClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max) { + Id result{}; + if (ctx.profile.has_broken_spirv_clamp) { + result = ctx.OpUMax(ctx.U32[1], ctx.OpUMin(ctx.U32[1], value, max), min); + } else { + result = ctx.OpUClamp(ctx.U32[1], value, min, max); + } + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); + return result; +} + +Id EmitSLessThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitSLessThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSLessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitULessThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpULessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitULessThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpULessThan(ctx.U1[1], lhs, rhs); +} + +Id EmitIEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpIEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitIEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpIEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitSLessThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitSLessThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSLessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitULessThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpULessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitULessThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpULessThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitSGreaterThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitSGreaterThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitUGreaterThan32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpUGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitUGreaterThan64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpUGreaterThan(ctx.U1[1], lhs, rhs); +} + +Id EmitINotEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpINotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitINotEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpINotEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitSGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitSGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpSGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitUGreaterThanEqual32(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpUGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitUGreaterThanEqual64(EmitContext& ctx, Id lhs, Id rhs) { + return ctx.OpUGreaterThanEqual(ctx.U1[1], lhs, rhs); +} + +Id EmitMaskedBitCount32(EmitContext& ctx, Id value, Id addend, bool hi) { + UNREACHABLE_MSG("Unreachable instruction"); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_logical.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_logical.cpp new file mode 100644 index 0000000..a80f1d6 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_logical.cpp @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +Id EmitLogicalOr(EmitContext& ctx, Id a, Id b) { + return ctx.OpLogicalOr(ctx.U1[1], a, b); +} + +Id EmitLogicalAnd(EmitContext& ctx, Id a, Id b) { + return ctx.OpLogicalAnd(ctx.U1[1], a, b); +} + +Id EmitLogicalXor(EmitContext& ctx, Id a, Id b) { + return ctx.OpLogicalNotEqual(ctx.U1[1], a, b); +} + +Id EmitLogicalNot(EmitContext& ctx, Id value) { + return ctx.OpLogicalNot(ctx.U1[1], value); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp new file mode 100644 index 0000000..cded3f1 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp @@ -0,0 +1,338 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "shader_recompiler/backend/spirv/emit_spirv_quad_rect.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::Backend::SPIRV { + +using Sirit::Id; + +constexpr u32 SPIRV_VERSION_1_5 = 0x00010500; + +struct QuadRectListEmitter : public Sirit::Module { + explicit QuadRectListEmitter(const HwFragmentRuntimeInfo& fs_info_) + : Sirit::Module{SPIRV_VERSION_1_5}, fs_info{fs_info_} { + void_id = TypeVoid(); + bool_id = TypeBool(); + float_id = TypeFloat(32); + uint_id = TypeUInt(32U); + int_id = TypeInt(32U, true); + bvec2_id = TypeVector(bool_id, 2); + vec2_id = TypeVector(float_id, 2); + vec3_id = TypeVector(float_id, 3); + vec4_id = TypeVector(float_id, 4); + + float_one = Constant(float_id, 1.0f); + float_min_one = Constant(float_id, -1.0f); + int_zero = Constant(int_id, 0); + + const Id float_arr{TypeArray(float_id, Constant(uint_id, 1U))}; + gl_per_vertex_type = TypeStruct(vec4_id, float_id, float_arr, float_arr); + Decorate(gl_per_vertex_type, spv::Decoration::Block); + MemberDecorate(gl_per_vertex_type, 0U, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::Position)); + MemberDecorate(gl_per_vertex_type, 1U, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::PointSize)); + MemberDecorate(gl_per_vertex_type, 2U, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::ClipDistance)); + MemberDecorate(gl_per_vertex_type, 3U, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::CullDistance)); + } + + /// Emits tessellation control shader for interpolating the 4th vertex of rectange primitive + void EmitRectListTCS() { + DefineEntry(spv::ExecutionModel::TessellationControl); + + // Set passthrough tessellation factors + const Id output_float_id{TypePointer(spv::StorageClass::Output, float_id)}; + for (int i = 0; i < 4; i++) { + const Id ptr{OpAccessChain(output_float_id, gl_tess_level_outer, Int(i))}; + OpStore(ptr, float_one); + } + for (int i = 0; i < 2; i++) { + const Id ptr{OpAccessChain(output_float_id, gl_tess_level_inner, Int(i))}; + OpStore(ptr, float_one); + } + + const Id input_vec4{TypePointer(spv::StorageClass::Input, vec4_id)}; + const Id output_vec4{TypePointer(spv::StorageClass::Output, vec4_id)}; + + // Emit interpolation block of the 4th vertex in rect. + // Load positions + std::array pos; + for (int i = 0; i < 3; i++) { + pos[i] = OpLoad(vec4_id, OpAccessChain(input_vec4, gl_in, Int(i), int_zero)); + } + + std::array point_coord_equal; + for (int i = 0; i < 3; i++) { + // point_coord_equal[i] = equal(gl_in[i].gl_Position.xy, gl_in[(i + 1) % + // 3].gl_Position.xy); + const Id pos_l_xy{OpVectorShuffle(vec2_id, pos[i], pos[i], 0, 1)}; + const Id pos_r_xy{OpVectorShuffle(vec2_id, pos[(i + 1) % 3], pos[(i + 1) % 3], 0, 1)}; + point_coord_equal[i] = OpFOrdEqual(bvec2_id, pos_l_xy, pos_r_xy); + } + + std::array bary_coord; + std::array is_edge_vertex; + for (int i = 0; i < 3; i++) { + // bool xy_equal = point_coord_equal[i].x && point_coord_equal[(i + 2) % 3].y; + const Id xy_equal{ + OpLogicalAnd(bool_id, OpCompositeExtract(bool_id, point_coord_equal[i], 0), + OpCompositeExtract(bool_id, point_coord_equal[(i + 2) % 3], 1))}; + // bool yx_equal = point_coord_equal[i].y && point_coord_equal[(i + 2) % 3].x; + const Id yx_equal{ + OpLogicalAnd(bool_id, OpCompositeExtract(bool_id, point_coord_equal[i], 1), + OpCompositeExtract(bool_id, point_coord_equal[(i + 2) % 3], 0))}; + // bary_coord[i] = (xy_equal || yx_equal) ? -1.f : 1.f; + is_edge_vertex[i] = OpLogicalOr(bool_id, xy_equal, yx_equal); + bary_coord[i] = OpSelect(float_id, is_edge_vertex[i], float_min_one, float_one); + } + + const auto interpolate = [&](Id v0, Id v1, Id v2) { + // return v0 * bary_coord.x + v1 * bary_coord.y + v2 * bary_coord.z; + const Id p0{OpVectorTimesScalar(vec4_id, v0, bary_coord[0])}; + const Id p1{OpVectorTimesScalar(vec4_id, v1, bary_coord[1])}; + const Id p2{OpVectorTimesScalar(vec4_id, v2, bary_coord[2])}; + return OpFAdd(vec4_id, p0, OpFAdd(vec4_id, p1, p2)); + }; + + // int vertex_index_id = is_edge_vertex[1] ? 1 : (is_edge_vertex[2] ? 2 : 0); + Id vertex_index{OpSelect(int_id, is_edge_vertex[2], Int(2), Int(0))}; + vertex_index = OpSelect(int_id, is_edge_vertex[1], Int(1), vertex_index); + + // int index = (vertex_index_id + gl_InvocationID) % 3; + const Id invocation_id{OpLoad(int_id, gl_invocation_id)}; + const Id invocation_3{OpIEqual(bool_id, invocation_id, Int(3))}; + const Id index{OpSMod(int_id, OpIAdd(int_id, vertex_index, invocation_id), Int(3))}; + + // gl_out[gl_InvocationID].gl_Position = gl_InvocationID == 3 ? pos3 : + // gl_in[index].gl_Position; + const Id pos3{interpolate(pos[0], pos[1], pos[2])}; + const Id in_ptr{OpAccessChain(input_vec4, gl_in, index, Int(0))}; + const Id position{OpSelect(vec4_id, invocation_3, pos3, OpLoad(vec4_id, in_ptr))}; + OpStore(OpAccessChain(output_vec4, gl_out, invocation_id, Int(0)), position); + + // Set attributes + for (int i = 0; i < inputs.size(); i++) { + // vec4 in_paramN3 = interpolate(bary_coord, in_paramN[0], in_paramN[1], in_paramN[2]); + const Id v0{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], Int(0)))}; + const Id v1{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], Int(1)))}; + const Id v2{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], Int(2)))}; + const Id in_param3{interpolate(v0, v1, v2)}; + // out_paramN[gl_InvocationID] = gl_InvocationID == 3 ? in_paramN3 : in_paramN[index]; + const Id in_param{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index))}; + const Id out_param{OpSelect(vec4_id, invocation_3, in_param3, in_param)}; + OpStore(OpAccessChain(output_vec4, outputs[i], invocation_id), out_param); + } + + OpReturn(); + OpFunctionEnd(); + } + + /// Emits a passthrough quad tessellation control shader that outputs 4 control points. + void EmitQuadListTCS() { + DefineEntry(spv::ExecutionModel::TessellationControl); + const Id array_type{TypeArray(int_id, Int(4))}; + const Id values{ConstantComposite(array_type, Int(1), Int(2), Int(0), Int(3))}; + const Id indices{AddLocalVariable(TypePointer(spv::StorageClass::Function, array_type), + spv::StorageClass::Function, values)}; + + // Set passthrough tessellation factors + const Id output_float{TypePointer(spv::StorageClass::Output, float_id)}; + for (int i = 0; i < 4; i++) { + const Id ptr{OpAccessChain(output_float, gl_tess_level_outer, Int(i))}; + OpStore(ptr, float_one); + } + for (int i = 0; i < 2; i++) { + const Id ptr{OpAccessChain(output_float, gl_tess_level_inner, Int(i))}; + OpStore(ptr, float_one); + } + + const Id input_vec4{TypePointer(spv::StorageClass::Input, vec4_id)}; + const Id output_vec4{TypePointer(spv::StorageClass::Output, vec4_id)}; + const Id func_int{TypePointer(spv::StorageClass::Function, int_id)}; + const Id invocation_id{OpLoad(int_id, gl_invocation_id)}; + const Id index{OpLoad(int_id, OpAccessChain(func_int, indices, invocation_id))}; + + // gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; + const Id in_position{OpLoad(vec4_id, OpAccessChain(input_vec4, gl_in, index, Int(0)))}; + OpStore(OpAccessChain(output_vec4, gl_out, invocation_id, Int(0)), in_position); + + for (int i = 0; i < inputs.size(); i++) { + // out_paramN[gl_InvocationID] = in_paramN[gl_InvocationID]; + const Id in_param{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index))}; + OpStore(OpAccessChain(output_vec4, outputs[i], invocation_id), in_param); + } + + OpReturn(); + OpFunctionEnd(); + } + + /// Emits a passthrough quad tessellation evaluation shader that outputs 4 control points. + void EmitPassthroughTES() { + DefineEntry(spv::ExecutionModel::TessellationEvaluation); + + // const int index = int(gl_TessCoord.y) * 2 + int(gl_TessCoord.x); + const Id input_float{TypePointer(spv::StorageClass::Input, float_id)}; + const Id tess_coord_x{OpLoad(float_id, OpAccessChain(input_float, gl_tess_coord, Int(0)))}; + const Id tess_coord_y{OpLoad(float_id, OpAccessChain(input_float, gl_tess_coord, Int(1)))}; + const Id index{OpIAdd(int_id, OpIMul(int_id, OpConvertFToS(int_id, tess_coord_y), Int(2)), + OpConvertFToS(int_id, tess_coord_x))}; + + // gl_Position = gl_in[index].gl_Position; + const Id input_vec4{TypePointer(spv::StorageClass::Input, vec4_id)}; + const Id output_vec4{TypePointer(spv::StorageClass::Output, vec4_id)}; + const Id position{OpLoad(vec4_id, OpAccessChain(input_vec4, gl_in, index, Int(0)))}; + OpStore(OpAccessChain(output_vec4, gl_per_vertex, Int(0)), position); + + // out_paramN = in_paramN[index]; + for (int i = 0; i < inputs.size(); i++) { + const Id param{OpLoad(vec4_id, OpAccessChain(input_vec4, inputs[i], index))}; + OpStore(outputs[i], param); + } + + OpReturn(); + OpFunctionEnd(); + } + +private: + Id Int(s32 value) { + return Constant(int_id, value); + } + + Id AddInput(Id type) { + const Id input{AddGlobalVariable(TypePointer(spv::StorageClass::Input, type), + spv::StorageClass::Input)}; + interfaces.push_back(input); + return input; + } + + Id AddOutput(Id type) { + const Id output{AddGlobalVariable(TypePointer(spv::StorageClass::Output, type), + spv::StorageClass::Output)}; + interfaces.push_back(output); + return output; + } + + void DefineEntry(spv::ExecutionModel model) { + AddCapability(spv::Capability::Shader); + AddCapability(spv::Capability::Tessellation); + const Id void_function{TypeFunction(void_id)}; + main = OpFunction(void_id, spv::FunctionControlMask::MaskNone, void_function); + if (model == spv::ExecutionModel::TessellationControl) { + AddExecutionMode(main, spv::ExecutionMode::OutputVertices, 4U); + } else { + AddExecutionMode(main, spv::ExecutionMode::Quads); + AddExecutionMode(main, spv::ExecutionMode::SpacingEqual); + AddExecutionMode(main, spv::ExecutionMode::VertexOrderCw); + } + DefineInputs(model); + DefineOutputs(model); + AddEntryPoint(model, main, "main", interfaces); + AddLabel(OpLabel()); + } + + void DefineOutputs(spv::ExecutionModel model) { + if (model == spv::ExecutionModel::TessellationControl) { + const Id gl_per_vertex_array{TypeArray(gl_per_vertex_type, Constant(uint_id, 4U))}; + gl_out = AddOutput(gl_per_vertex_array); + + const Id arr2_id{TypeArray(float_id, Constant(uint_id, 2U))}; + gl_tess_level_inner = AddOutput(arr2_id); + Decorate(gl_tess_level_inner, spv::Decoration::BuiltIn, spv::BuiltIn::TessLevelInner); + Decorate(gl_tess_level_inner, spv::Decoration::Patch); + + const Id arr4_id{TypeArray(float_id, Constant(uint_id, 4U))}; + gl_tess_level_outer = AddOutput(arr4_id); + Decorate(gl_tess_level_outer, spv::Decoration::BuiltIn, spv::BuiltIn::TessLevelOuter); + Decorate(gl_tess_level_outer, spv::Decoration::Patch); + } else { + gl_per_vertex = AddOutput(gl_per_vertex_type); + } + outputs.reserve(fs_info.num_inputs); + for (int i = 0; i < fs_info.num_inputs; i++) { + const auto& input = fs_info.inputs[i]; + if (input.IsDefault()) { + continue; + } + outputs.emplace_back(AddOutput(model == spv::ExecutionModel::TessellationControl + ? TypeArray(vec4_id, Int(4)) + : vec4_id)); + Decorate(outputs.back(), spv::Decoration::Location, input.param_index); + } + } + + void DefineInputs(spv::ExecutionModel model) { + if (model == spv::ExecutionModel::TessellationEvaluation) { + gl_tess_coord = AddInput(vec3_id); + Decorate(gl_tess_coord, spv::Decoration::BuiltIn, spv::BuiltIn::TessCoord); + } else { + gl_invocation_id = AddInput(int_id); + Decorate(gl_invocation_id, spv::Decoration::BuiltIn, spv::BuiltIn::InvocationId); + } + const Id gl_per_vertex_array{TypeArray(gl_per_vertex_type, Constant(uint_id, 32U))}; + gl_in = AddInput(gl_per_vertex_array); + const Id float_arr{TypeArray(vec4_id, Int(32))}; + inputs.reserve(fs_info.num_inputs); + for (int i = 0; i < fs_info.num_inputs; i++) { + const auto& input = fs_info.inputs[i]; + if (input.IsDefault()) { + continue; + } + inputs.emplace_back(AddInput(float_arr)); + Decorate(inputs.back(), spv::Decoration::Location, input.param_index); + } + } + +private: + HwFragmentRuntimeInfo fs_info; + Id main; + Id void_id; + Id bool_id; + Id float_id; + Id uint_id; + Id int_id; + Id bvec2_id; + Id vec2_id; + Id vec3_id; + Id vec4_id; + Id float_one; + Id float_min_one; + Id int_zero; + Id gl_per_vertex_type; + Id gl_in; + union { + Id gl_out; + Id gl_per_vertex; + }; + Id gl_tess_level_inner; + Id gl_tess_level_outer; + union { + Id gl_tess_coord; + Id gl_invocation_id; + }; + std::vector inputs; + std::vector outputs; + std::vector interfaces; +}; + +std::vector EmitAuxilaryTessShader(AuxShaderType type, const HwFragmentRuntimeInfo& fs_info) { + QuadRectListEmitter ctx{fs_info}; + switch (type) { + case AuxShaderType::RectListTCS: + ctx.EmitRectListTCS(); + break; + case AuxShaderType::QuadListTCS: + ctx.EmitQuadListTCS(); + break; + case AuxShaderType::PassthroughTES: + ctx.EmitPassthroughTES(); + break; + } + return ctx.Assemble(); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h new file mode 100644 index 0000000..adcfc19 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace Shader { +struct HwFragmentRuntimeInfo; +} + +namespace Shader::Backend::SPIRV { + +enum class AuxShaderType : u32 { + RectListTCS, + QuadListTCS, + PassthroughTES, +}; + +[[nodiscard]] std::vector EmitAuxilaryTessShader(AuxShaderType type, + const HwFragmentRuntimeInfo& fs_info); + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_select.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_select.cpp new file mode 100644 index 0000000..3726085 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_select.cpp @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +Id EmitSelectU1(EmitContext& ctx, Id cond, Id true_value, Id false_value) { + return ctx.OpSelect(ctx.U1[1], cond, true_value, false_value); +} + +Id EmitSelectU32(EmitContext& ctx, Id cond, Id true_value, Id false_value) { + return ctx.OpSelect(ctx.U32[1], cond, true_value, false_value); +} + +Id EmitSelectF32(EmitContext& ctx, Id cond, Id true_value, Id false_value) { + return ctx.OpSelect(ctx.F32[1], cond, true_value, false_value); +} + +Id EmitSelectU64(EmitContext& ctx, Id cond, Id true_value, Id false_value) { + return ctx.OpSelect(ctx.U64, cond, true_value, false_value); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp new file mode 100644 index 0000000..92231bb --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +Id EmitLoadSharedU16(EmitContext& ctx, Id offset) { + const Id shift_id{ctx.ConstU32(1U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u16, ctx.shared_memory_u16, index); + return ctx.OpLoad(ctx.U16, pointer); +} + +Id EmitLoadSharedU32(EmitContext& ctx, Id offset) { + const Id shift_id{ctx.ConstU32(2U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index); + return ctx.OpLoad(ctx.U32[1], pointer); +} + +Id EmitLoadSharedU64(EmitContext& ctx, Id offset) { + const Id shift_id{ctx.ConstU32(3U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift_id)}; + const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index); + return ctx.OpLoad(ctx.U64, pointer); +} + +void EmitWriteSharedU16(EmitContext& ctx, Id offset, Id value) { + const Id shift{ctx.ConstU32(1U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift)}; + const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u16, ctx.shared_memory_u16, index); + ctx.OpStore(pointer, value); +} + +void EmitWriteSharedU32(EmitContext& ctx, Id offset, Id value) { + const Id shift{ctx.ConstU32(2U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift)}; + const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u32, ctx.shared_memory_u32, index); + ctx.OpStore(pointer, value); +} + +void EmitWriteSharedU64(EmitContext& ctx, Id offset, Id value) { + const Id shift{ctx.ConstU32(3U)}; + const Id index{ctx.OpShiftRightLogical(ctx.U32[1], offset, shift)}; + const Id pointer = ctx.EmitSharedMemoryAccess(ctx.shared_u64, ctx.shared_memory_u64, index); + ctx.OpStore(pointer, value); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_special.cpp new file mode 100644 index 0000000..4eae5c3 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_special.cpp @@ -0,0 +1,125 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/ir/debug_print.h" +#include "shader_recompiler/ir/microinstruction.h" + +namespace Shader::Backend::SPIRV { + +void EmitPrologue(EmitContext& ctx) { + if (ctx.hw_stage == HwStage::Fragment) { + ctx.DefineAmdPerVertexAttribs(); + } + if (ctx.info.loads.Get(IR::Attribute::WorkgroupIndex)) { + ctx.DefineWorkgroupIndex(); + } + ctx.DefineBufferProperties(); +} + +void ConvertDepthMode(EmitContext& ctx) { + const Id type{ctx.F32[1]}; + const Id position{ctx.OpLoad(ctx.F32[4], ctx.output_position)}; + const Id z{ctx.OpCompositeExtract(type, position, 2u)}; + const Id w{ctx.OpCompositeExtract(type, position, 3u)}; + const Id screen_depth{ctx.OpFMul(type, ctx.OpFAdd(type, z, w), ctx.Constant(type, 0.5f))}; + const Id vector{ctx.OpCompositeInsert(ctx.F32[4], screen_depth, position, 2u)}; + ctx.OpStore(ctx.output_position, vector); +} + +void ConvertPositionToClipSpace(EmitContext& ctx) { + ASSERT_MSG(!ctx.info.stores.GetAny(IR::Attribute::ViewportIndex), + "Multi-viewport with shader clip space conversion not yet implemented."); + + const Id type{ctx.F32[1]}; + Id position{ctx.OpLoad(ctx.F32[4], ctx.output_position)}; + const Id x{ctx.OpCompositeExtract(type, position, 0u)}; + const Id y{ctx.OpCompositeExtract(type, position, 1u)}; + const Id z{ctx.OpCompositeExtract(type, position, 2u)}; + const Id w{ctx.OpCompositeExtract(type, position, 3u)}; + const Id xoffset_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type), + ctx.push_data_block, + ctx.ConstU32(PushData::XOffsetIndex))}; + const Id xoffset{ctx.OpLoad(type, xoffset_ptr)}; + const Id yoffset_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type), + ctx.push_data_block, + ctx.ConstU32(PushData::YOffsetIndex))}; + const Id yoffset{ctx.OpLoad(type, yoffset_ptr)}; + const Id xscale_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type), + ctx.push_data_block, + ctx.ConstU32(PushData::XScaleIndex))}; + const Id xscale{ctx.OpLoad(type, xscale_ptr)}; + const Id yscale_ptr{ctx.OpAccessChain(ctx.TypePointer(spv::StorageClass::PushConstant, type), + ctx.push_data_block, + ctx.ConstU32(PushData::YScaleIndex))}; + const Id yscale{ctx.OpLoad(type, yscale_ptr)}; + const Id vport_w = + ctx.Constant(type, float(std::min(ctx.profile.max_viewport_width / 2, 8_KB))); + const Id wnd_x = ctx.OpFAdd(type, ctx.OpFMul(type, x, xscale), xoffset); + const Id ndc_x = ctx.OpFSub(type, ctx.OpFDiv(type, wnd_x, vport_w), ctx.Constant(type, 1.f)); + const Id vport_h = + ctx.Constant(type, float(std::min(ctx.profile.max_viewport_height / 2, 8_KB))); + const Id wnd_y = ctx.OpFAdd(type, ctx.OpFMul(type, y, yscale), yoffset); + const Id ndc_y = ctx.OpFSub(type, ctx.OpFDiv(type, wnd_y, vport_h), ctx.Constant(type, 1.f)); + const Id vector{ctx.OpCompositeConstruct(ctx.F32[4], std::array({ndc_x, ndc_y, z, w}))}; + ctx.OpStore(ctx.output_position, vector); +} + +void EmitEpilogue(EmitContext& ctx) { + if (ctx.hw_stage == HwStage::Vertex && + ctx.runtime_info.hw.vs.emulate_depth_negative_one_to_one) { + ConvertDepthMode(ctx); + } + if (ctx.hw_stage == HwStage::Vertex && ctx.runtime_info.hw.vs.clip_disable) { + ConvertPositionToClipSpace(ctx); + } +} + +void EmitDiscard(EmitContext& ctx) { + ctx.OpDemoteToHelperInvocationEXT(); +} + +void EmitDiscardCond(EmitContext& ctx, Id condition) { + const Id kill_label{ctx.OpLabel()}; + const Id merge_label{ctx.OpLabel()}; + ctx.OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone); + ctx.OpBranchConditional(condition, kill_label, merge_label); + ctx.AddLabel(kill_label); + ctx.OpDemoteToHelperInvocationEXT(); + ctx.OpBranch(merge_label); + ctx.AddLabel(merge_label); +} + +void EmitEmitVertex(EmitContext& ctx) { + ctx.OpEmitVertex(); +} + +void EmitEmitPrimitive(EmitContext& ctx) { + ctx.OpEndPrimitive(); +} + +void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { + UNREACHABLE_MSG("Geometry streams"); +} + +void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { + UNREACHABLE_MSG("Geometry streams"); +} + +void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id fmt, Id arg0, Id arg1, Id arg2, Id arg3) { + IR::DebugPrintFlags flags = inst->Flags(); + std::array fmt_args = {arg0, arg1, arg2, arg3}; + auto fmt_args_span = std::span(fmt_args.begin(), fmt_args.begin() + flags.num_args); + ctx.OpDebugPrintf(fmt, fmt_args_span); +} + +Id EmitMemtime(EmitContext& ctx) { + if (ctx.profile.supports_shader_subgroup_clock) { + return ctx.OpReadClockKHR(ctx.U64, ctx.ConstU32(std::to_underlying(spv::Scope::Subgroup))); + } else { + return ctx.Constant(ctx.U64, 1U); + } +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp new file mode 100644 index 0000000..58a01fd --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +Id EmitUndefU1(EmitContext& ctx) { + return ctx.OpUndef(ctx.U1[1]); +} + +Id EmitUndefU8(EmitContext&) { + UNREACHABLE_MSG("SPIR-V Instruction"); +} + +Id EmitUndefU16(EmitContext&) { + UNREACHABLE_MSG("SPIR-V Instruction"); +} + +Id EmitUndefU32(EmitContext& ctx) { + return ctx.OpUndef(ctx.U32[1]); +} + +Id EmitUndefU32x2(EmitContext& ctx) { + return ctx.OpUndef(ctx.U32[2]); +} + +Id EmitUndefU32x3(EmitContext& ctx) { + return ctx.OpUndef(ctx.U32[3]); +} + +Id EmitUndefU32x4(EmitContext& ctx) { + return ctx.OpUndef(ctx.U32[4]); +} + +Id EmitUndefF32(EmitContext& ctx) { + return ctx.OpUndef(ctx.F32[1]); +} + +Id EmitUndefU64(EmitContext&) { + UNREACHABLE_MSG("SPIR-V Instruction"); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_warp.cpp new file mode 100644 index 0000000..1e45fe7 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/emit_spirv_warp.cpp @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" + +namespace Shader::Backend::SPIRV { + +Id SubgroupScope(EmitContext& ctx) { + return ctx.ConstU32(static_cast(spv::Scope::Subgroup)); +} + +Id EmitWarpId(EmitContext& ctx) { + UNREACHABLE(); +} + +Id EmitLaneId(EmitContext& ctx) { + return ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id); +} + +Id EmitQuadBroadcast(EmitContext& ctx, Id value, Id index) { + return ctx.OpGroupNonUniformQuadBroadcast(ctx.U32[1], SubgroupScope(ctx), value, index); +} + +Id EmitReadFirstLane(EmitContext& ctx, Id value) { + return ctx.OpGroupNonUniformBroadcastFirst(ctx.U32[1], SubgroupScope(ctx), value); +} + +Id EmitShuffle(EmitContext& ctx, Id value, Id index) { + return ctx.OpGroupNonUniformShuffle(ctx.U32[1], SubgroupScope(ctx), value, index); +} + +Id EmitShuffleXor(EmitContext& ctx, Id value, Id mask) { + return ctx.OpGroupNonUniformShuffleXor(ctx.U32[1], SubgroupScope(ctx), value, mask); +} + +Id EmitReadLane(EmitContext& ctx, Id value, Id lane) { + return ctx.OpGroupNonUniformBroadcast(ctx.U32[1], SubgroupScope(ctx), value, lane); +} + +Id EmitWriteLane(EmitContext& ctx, Id value, Id write_value, u32 lane) { + return ctx.u32_zero_value; +} + +Id EmitBallot(EmitContext& ctx, Id bit) { + const Id ballot{ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), bit)}; + return ctx.OpBitcast(ctx.U64, ctx.OpVectorShuffle(ctx.U32[2], ballot, ballot, 0, 1)); +} + +Id EmitBallotFindLsb(EmitContext& ctx, Id mask) { + const Id value{ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpBitcast(ctx.U32[2], mask), + ctx.u32_zero_value, ctx.u32_zero_value)}; + return ctx.OpGroupNonUniformBallotFindLSB(ctx.U32[1], SubgroupScope(ctx), value); +} + +Id EmitInverseBallot(EmitContext& ctx, Id mask) { + const Id value{ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpBitcast(ctx.U32[2], mask), + ctx.u32_zero_value, ctx.u32_zero_value)}; + return ctx.OpGroupNonUniformInverseBallot(ctx.U1[1], SubgroupScope(ctx), value); +} + +Id EmitGroupAny(EmitContext& ctx, Id bit) { + return ctx.OpGroupNonUniformAny(ctx.U1[1], SubgroupScope(ctx), bit); +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/gpu/shadps4/shader_recompiler/backend/spirv/spirv_emit_context.cpp new file mode 100644 index 0000000..5f3ae90 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -0,0 +1,1305 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "common/div_ceil.h" +#include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/frontend/fetch_shader.h" +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/microinstruction.h" +#include "shader_recompiler/runtime_info.h" + +#include +#include +#include + +#include +#include + +namespace Shader::Backend::SPIRV { +namespace { + +std::string_view StageName(HwStage stage) { + switch (stage) { + case HwStage::Vertex: + return "vs"; + case HwStage::Local: + return "ls"; + case HwStage::Export: + return "es"; + case HwStage::Hull: + return "hs"; + case HwStage::Geometry: + return "gs"; + case HwStage::Fragment: + return "fs"; + case HwStage::Compute: + return "cs"; + } + UNREACHABLE_MSG("Invalid hw stage {}", u32(stage)); +} + +static constexpr u32 NumVertices(AmdGpu::PrimitiveType type) { + switch (type) { + case AmdGpu::PrimitiveType::PointList: + return 1u; + case AmdGpu::PrimitiveType::LineList: + case AmdGpu::PrimitiveType::LineStrip: + return 2u; + case AmdGpu::PrimitiveType::TriangleList: + case AmdGpu::PrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::RectList: + return 3u; + case AmdGpu::PrimitiveType::AdjTriangleList: + return 6u; + case AmdGpu::PrimitiveType::AdjLineList: + return 4u; + default: + UNREACHABLE(); + } +} + +template +void Name(EmitContext& ctx, Id object, std::string_view format_str, Args&&... args) { + ctx.Name(object, fmt::format(fmt::runtime(format_str), StageName(ctx.hw_stage), + std::forward(args)...) + .c_str()); +} + +} // Anonymous namespace + +EmitContext::EmitContext(const Profile& profile_, const RuntimeInfo& runtime_info_, Info& info_, + Bindings& binding_) + : Sirit::Module(profile_.supported_spirv), info{info_}, runtime_info{runtime_info_}, + profile{profile_}, hw_stage{info.hw_stage}, sw_stage{info.sw_stage}, binding{binding_} { + if (info.uses_dma) { + SetMemoryModel(spv::AddressingModel::PhysicalStorageBuffer64, spv::MemoryModel::GLSL450); + } else { + SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450); + } + String(fmt::format("{:#x}", info.pgm_hash)); + + AddCapability(spv::Capability::Shader); + DefineArithmeticTypes(); + DefineInterfaces(); + DefineSharedMemory(); + DefineBuffers(); + DefineImagesAndSamplers(); + DefineFunctions(); +} + +EmitContext::~EmitContext() = default; + +Id EmitContext::Def(const IR::Value& value) { + if (!value.IsImmediate()) { + return value.Inst()->Definition(); + } + switch (value.Type()) { + case IR::Type::Void: + return Id{}; + case IR::Type::U1: + return value.U1() ? true_value : false_value; + case IR::Type::U32: + return ConstU32(value.U32()); + case IR::Type::U64: + return Constant(U64, value.U64()); + case IR::Type::F32: + return ConstF32(value.F32()); + case IR::Type::F64: + return Constant(F64[1], value.F64()); + case IR::Type::StringLiteral: + return String(value.StringLiteral()); + default: + UNREACHABLE_MSG("Immediate type {}", value.Type()); + } +} + +void EmitContext::DefineArithmeticTypes() { + void_id = Name(TypeVoid(), "void_id"); + U1[1] = Name(TypeBool(), "bool_id"); + U8 = Name(TypeUInt(8), "u8_id"); + S8 = Name(TypeSInt(8), "i8_id"); + U16 = Name(TypeUInt(16), "u16_id"); + S16 = Name(TypeSInt(16), "i16_id"); + if (info.uses_fp16) { + F16[1] = Name(TypeFloat(16), "f16_id"); + } + if (info.uses_fp64) { + F64[1] = Name(TypeFloat(64), "f64_id"); + } + F32[1] = Name(TypeFloat(32), "f32_id"); + S32[1] = Name(TypeSInt(32), "i32_id"); + U32[1] = Name(TypeUInt(32), "u32_id"); + U64 = Name(TypeUInt(64), "u64_id"); + + for (u32 i = 2; i <= 4; i++) { + if (info.uses_fp16) { + F16[i] = Name(TypeVector(F16[1], i), fmt::format("f16vec{}_id", i)); + } + if (info.uses_fp64) { + F64[i] = Name(TypeVector(F64[1], i), fmt::format("f64vec{}_id", i)); + } + F32[i] = Name(TypeVector(F32[1], i), fmt::format("f32vec{}_id", i)); + S32[i] = Name(TypeVector(S32[1], i), fmt::format("i32vec{}_id", i)); + U32[i] = Name(TypeVector(U32[1], i), fmt::format("u32vec{}_id", i)); + U1[i] = Name(TypeVector(U1[1], i), fmt::format("bvec{}_id", i)); + } + + true_value = ConstantTrue(U1[1]); + false_value = ConstantFalse(U1[1]); + u8_one_value = Constant(U8, 1U); + u8_zero_value = Constant(U8, 0U); + u16_zero_value = Constant(U16, 0U); + u32_one_value = ConstU32(1U); + u32_zero_value = ConstU32(0U); + f32_zero_value = ConstF32(0.0f); + u64_one_value = Constant(U64, 1ULL); + u64_zero_value = Constant(U64, 0ULL); + + pi_x2 = ConstF32(2.0f * float{std::numbers::pi}); + + input_f32 = Name(TypePointer(spv::StorageClass::Input, F32[1]), "input_f32"); + input_u32 = Name(TypePointer(spv::StorageClass::Input, U32[1]), "input_u32"); + input_s32 = Name(TypePointer(spv::StorageClass::Input, S32[1]), "input_s32"); + + output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32"); + output_u32 = Name(TypePointer(spv::StorageClass::Output, U32[1]), "output_u32"); + output_s32 = Name(TypePointer(spv::StorageClass::Output, S32[1]), "output_s32"); + + full_result_i32x2 = Name(TypeStruct(S32[1], S32[1]), "full_result_i32x2"); + full_result_u32x2 = Name(TypeStruct(U32[1], U32[1]), "full_result_u32x2"); + frexp_result_f32 = Name(TypeStruct(F32[1], S32[1]), "frexp_result_f32"); + if (info.uses_fp64) { + frexp_result_f64 = Name(TypeStruct(F64[1], S32[1]), "frexp_result_f64"); + } + if (info.uses_dma) { + physical_pointer_type_u32 = TypePointer(spv::StorageClass::PhysicalStorageBuffer, U32[1]); + } +} + +void EmitContext::DefineInterfaces() { + DefinePushDataBlock(); + DefineInputs(); + DefineOutputs(); +} + +const VectorIds& GetAttributeType(EmitContext& ctx, AmdGpu::NumberFormat fmt) { + switch (GetNumberClass(fmt)) { + case AmdGpu::NumberClass::Float: + return ctx.F32; + case AmdGpu::NumberClass::Sint: + return ctx.S32; + case AmdGpu::NumberClass::Uint: + return ctx.U32; + default: + break; + } + UNREACHABLE_MSG("Invalid attribute type {}", fmt); +} + +EmitContext::SpirvAttribute EmitContext::GetAttributeInfo(AmdGpu::NumberFormat fmt, Id id, + u32 num_components, bool output, + bool loaded, bool array) { + switch (GetNumberClass(fmt)) { + case AmdGpu::NumberClass::Float: + return {id, output ? output_f32 : input_f32, F32[1], num_components, false, loaded, array}; + case AmdGpu::NumberClass::Uint: + return {id, output ? output_u32 : input_u32, U32[1], num_components, true, loaded, array}; + case AmdGpu::NumberClass::Sint: + return {id, output ? output_s32 : input_s32, S32[1], num_components, true, loaded, array}; + default: + break; + } + UNREACHABLE_MSG("Invalid attribute type {}", fmt); +} + +Id EmitContext::GetBufferSize(const u32 sharp_idx) { + // Can this be done with memory access? Like we do now with ReadConst + const auto& srt_flatbuf = buffers[flatbuf_index]; + ASSERT(srt_flatbuf.buffer_type == BufferType::Flatbuf); + const auto [id, pointer_type] = srt_flatbuf.Alias(PointerType::U32); + + const auto rsrc1{ + OpLoad(U32[1], OpAccessChain(pointer_type, id, u32_zero_value, ConstU32(sharp_idx + 1)))}; + const auto rsrc2{ + OpLoad(U32[1], OpAccessChain(pointer_type, id, u32_zero_value, ConstU32(sharp_idx + 2)))}; + + const auto stride{OpBitFieldUExtract(U32[1], rsrc1, ConstU32(16u), ConstU32(14u))}; + const auto num_records{rsrc2}; + + const auto stride_zero{OpIEqual(U1[1], stride, u32_zero_value)}; + const auto stride_size{OpIMul(U32[1], num_records, stride)}; + return OpSelect(U32[1], stride_zero, num_records, stride_size); +} + +void EmitContext::DefineBufferProperties() { + if (!profile.needs_buffer_offsets) { + return; + } + for (u32 i = 0; i < buffers.size(); i++) { + auto& buffer = buffers[i]; + const auto& desc = info.buffers[i]; + const u32 binding = buffer.binding; + if (buffer.buffer_type != BufferType::Guest) { + continue; + } + + const u32 half = PushData::BufOffsetIndex + (binding >> 4); + const u32 comp = (binding & 0xf) >> 2; + const u32 offset = (binding & 0x3) << 3; + const Id ptr{OpAccessChain(TypePointer(spv::StorageClass::PushConstant, U32[1]), + push_data_block, ConstU32(half), ConstU32(comp))}; + const Id value{OpLoad(U32[1], ptr)}; + + const Id buf_offset{OpBitFieldUExtract(U32[1], value, ConstU32(offset), ConstU32(8U))}; + Name(buf_offset, fmt::format("buf{}_off", binding)); + buffer.Offset(PointerSize::B8) = buf_offset; + + if (True(desc.used_types & IR::Type::U16)) { + const Id buf_word_offset{OpShiftRightLogical(U32[1], buf_offset, ConstU32(1U))}; + Name(buf_word_offset, fmt::format("buf{}_word_off", binding)); + buffer.Offset(PointerSize::B16) = buf_word_offset; + } + if (True(desc.used_types & IR::Type::U32)) { + const Id buf_dword_offset{OpShiftRightLogical(U32[1], buf_offset, ConstU32(2U))}; + Name(buf_dword_offset, fmt::format("buf{}_dword_off", binding)); + buffer.Offset(PointerSize::B32) = buf_dword_offset; + } + if (True(desc.used_types & IR::Type::U64)) { + const Id buf_qword_offset{OpShiftRightLogical(U32[1], buf_offset, ConstU32(3U))}; + Name(buf_qword_offset, fmt::format("buf{}_qword_off", binding)); + buffer.Offset(PointerSize::B64) = buf_qword_offset; + } + } +} + +void EmitContext::DefineAmdPerVertexAttribs() { + if (!profile.supports_amd_shader_explicit_vertex_parameter) { + return; + } + for (s32 i = 0; i < runtime_info.hw.fs.num_inputs; i++) { + const auto& input = runtime_info.hw.fs.inputs[i]; + if (input.IsDefault() || info.fs_interpolation[i].primary != Qualifier::PerVertex) { + continue; + } + auto& param = input_params[i]; + const Id pointer = param.id; + param.id_array[0] = + OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(0U)); + param.id_array[1] = + OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(1U)); + param.id_array[2] = + OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(2U)); + param.is_loaded = true; + } +} + +void EmitContext::DefineWorkgroupIndex() { + const Id workgroup_id_val{OpLoad(U32[3], workgroup_id)}; + const Id workgroup_x{OpCompositeExtract(U32[1], workgroup_id_val, 0)}; + const Id workgroup_y{OpCompositeExtract(U32[1], workgroup_id_val, 1)}; + const Id workgroup_z{OpCompositeExtract(U32[1], workgroup_id_val, 2)}; + const Id num_workgroups{OpLoad(U32[3], num_workgroups_id)}; + const Id num_workgroups_x{OpCompositeExtract(U32[1], num_workgroups, 0)}; + const Id num_workgroups_y{OpCompositeExtract(U32[1], num_workgroups, 1)}; + workgroup_index_id = + OpIAdd(U32[1], OpIAdd(U32[1], workgroup_x, OpIMul(U32[1], workgroup_y, num_workgroups_x)), + OpIMul(U32[1], workgroup_z, OpIMul(U32[1], num_workgroups_x, num_workgroups_y))); + Name(workgroup_index_id, "workgroup_index"); +} + +void EmitContext::DefineInputs() { + if (info.uses_lane_id) { + subgroup_local_invocation_id = DefineVariable( + U32[1], spv::BuiltIn::SubgroupLocalInvocationId, spv::StorageClass::Input); + Decorate(subgroup_local_invocation_id, spv::Decoration::Flat); + } + if (info.loads.GetAny(IR::Attribute::SubgroupLtMask)) { + subgroup_lt_mask = + DefineVariable(U32[4], spv::BuiltIn::SubgroupLtMask, spv::StorageClass::Input); + Decorate(subgroup_lt_mask, spv::Decoration::Flat); + } + switch (sw_stage) { + case SwStage::Vertex: { + vertex_index = DefineVariable(U32[1], spv::BuiltIn::VertexIndex, spv::StorageClass::Input); + instance_id = DefineVariable(U32[1], spv::BuiltIn::InstanceIndex, spv::StorageClass::Input); + if (info.loads.Get(IR::Attribute::BaseVertex)) { + base_vertex = + DefineVariable(U32[1], spv::BuiltIn::BaseVertex, spv::StorageClass::Input); + } + if (info.loads.Get(IR::Attribute::BaseInstance)) { + base_instance = + DefineVariable(U32[1], spv::BuiltIn::BaseInstance, spv::StorageClass::Input); + } + + const auto fetch_shader = Gcn::ParseFetchShader(info); + if (!fetch_shader) { + break; + } + for (const auto& attrib : fetch_shader->attributes) { + ASSERT(attrib.semantic < IR::NumParams); + const auto sharp = attrib.GetSharp(info); + const Id type{GetAttributeType(*this, sharp.GetNumberFmt())[4]}; + Id id{DefineInput(type, attrib.semantic)}; + if (attrib.GetStepRate() != Gcn::VertexAttribute::InstanceIdType::None) { + Name(id, fmt::format("vs_instance_attr{}", attrib.semantic)); + } else { + Name(id, fmt::format("vs_in_attr{}", attrib.semantic)); + } + input_params[attrib.semantic] = GetAttributeInfo(sharp.GetNumberFmt(), id, 4, false); + } + break; + } + case SwStage::Fragment: { + if (info.loads.GetAny(IR::Attribute::FragCoord) || + (info.loads.GetAny(IR::Attribute::BaryCoordPullModel) && + !profile.supports_amd_shader_explicit_vertex_parameter)) { + frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input); + } + if (info.loads.Get(IR::Attribute::IsFrontFace)) { + front_facing = + DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input); + } + if (info.loads.GetAny(IR::Attribute::RenderTargetIndex)) { + output_layer = DefineVariable(U32[1], spv::BuiltIn::Layer, spv::StorageClass::Input); + Decorate(output_layer, spv::Decoration::Flat); + } + if (info.loads.Get(IR::Attribute::SampleIndex)) { + sample_index = DefineVariable(U32[1], spv::BuiltIn::SampleId, spv::StorageClass::Input); + Decorate(sample_index, spv::Decoration::Flat); + } + if (info.loads.Get(IR::Attribute::IsHelperInvocation)) { + helper_invocation = + DefineVariable(U1[1], spv::BuiltIn::HelperInvocation, spv::StorageClass::Input); + } + if (info.loads.Get(IR::Attribute::SampleMask)) { + sample_mask_in = DefineVariable(TypeArray(U32[1], u32_one_value), + spv::BuiltIn::SampleMask, spv::StorageClass::Input); + } + if (info.loads.GetAny(IR::Attribute::BaryCoordSmooth)) { + if (profile.supports_amd_shader_explicit_vertex_parameter) { + bary_coord_smooth = DefineVariable(F32[2], spv::BuiltIn::BaryCoordSmoothAMD, + spv::StorageClass::Input); + } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { + bary_coord = + DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); + } + } + if (info.loads.GetAny(IR::Attribute::BaryCoordPullModel)) { + if (profile.supports_amd_shader_explicit_vertex_parameter) { + bary_coord_pull_model = DefineVariable(F32[3], spv::BuiltIn::BaryCoordPullModelAMD, + spv::StorageClass::Input); + } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { + bary_coord = + DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); + } + } + if (info.loads.GetAny(IR::Attribute::BaryCoordSmoothCentroid)) { + if (profile.supports_amd_shader_explicit_vertex_parameter) { + bary_coord_smooth_centroid = DefineVariable( + F32[2], spv::BuiltIn::BaryCoordSmoothCentroidAMD, spv::StorageClass::Input); + } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { + bary_coord = + DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); + } + } + if (info.loads.GetAny(IR::Attribute::BaryCoordSmoothSample)) { + if (profile.supports_amd_shader_explicit_vertex_parameter) { + bary_coord_smooth_sample = DefineVariable( + F32[2], spv::BuiltIn::BaryCoordSmoothSampleAMD, spv::StorageClass::Input); + } else if (profile.supports_fragment_shader_barycentric && !ValidId(bary_coord)) { + bary_coord = + DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); + // we would need sample_index to interpolate the bary_coord later + if (!ValidId(sample_index)) { + sample_index = + DefineVariable(U32[1], spv::BuiltIn::SampleId, spv::StorageClass::Input); + Decorate(sample_index, spv::Decoration::Flat); + } + } + } + if (info.loads.GetAny(IR::Attribute::BaryCoordNoPersp)) { + if (profile.supports_amd_shader_explicit_vertex_parameter) { + bary_coord_nopersp = DefineVariable(F32[2], spv::BuiltIn::BaryCoordNoPerspAMD, + spv::StorageClass::Input); + } else if (profile.supports_fragment_shader_barycentric) { + bary_coord_nopersp = DefineVariable(F32[3], spv::BuiltIn::BaryCoordNoPerspKHR, + spv::StorageClass::Input); + } + } + if (info.loads.GetAny(IR::Attribute::BaryCoordNoPerspSample)) { + if (profile.supports_amd_shader_explicit_vertex_parameter) { + bary_coord_nopersp_sample = DefineVariable( + F32[2], spv::BuiltIn::BaryCoordNoPerspSampleAMD, spv::StorageClass::Input); + } else if (profile.supports_fragment_shader_barycentric) { + bary_coord_nopersp_sample = DefineVariable( + F32[3], spv::BuiltIn::BaryCoordNoPerspKHR, spv::StorageClass::Input); + // Decorate(bary_coord_nopersp_sample, spv::Decoration::Sample); + } + } + + const bool has_clip_distance_inputs = runtime_info.hw.fs.clip_distance_emulation; + // Clip distances attribute vector is the last in inputs array + const auto num_inputs = runtime_info.hw.fs.num_inputs - (has_clip_distance_inputs ? 1 : 0); + + for (s32 i = 0; i < num_inputs; i++) { + const auto& input = runtime_info.hw.fs.inputs[i]; + if (input.IsDefault()) { + continue; + } + const IR::Attribute param = IR::Attribute::Param0 + i; + const u32 num_components = info.loads.NumComponents(param); + const auto [primary, auxiliary] = info.fs_interpolation[i]; + const Id type = F32[num_components]; + const Id attr_id = [&] { + const auto bind_location = input.param_index + (has_clip_distance_inputs ? 1 : 0); + if (primary == Qualifier::PerVertex && + profile.supports_fragment_shader_barycentric) { + return Name(DefineInput(TypeArray(type, ConstU32(3U)), bind_location), + fmt::format("fs_in_attr{}_p", i)); + } + return Name(DefineInput(type, bind_location), fmt::format("fs_in_attr{}", i)); + }(); + if (primary == Qualifier::PerVertex) { + Decorate(attr_id, profile.supports_amd_shader_explicit_vertex_parameter + ? spv::Decoration::ExplicitInterpAMD + : spv::Decoration::PerVertexKHR); + } else if (primary != Qualifier::Smooth) { + Decorate(attr_id, primary == Qualifier::Flat ? spv::Decoration::Flat + : spv::Decoration::NoPerspective); + } + if (auxiliary != Qualifier::None) { + Decorate(attr_id, auxiliary == Qualifier::Centroid ? spv::Decoration::Centroid + : spv::Decoration::Sample); + } + input_params[i] = GetAttributeInfo(AmdGpu::NumberFormat::Float, attr_id, num_components, + false, false, primary == Qualifier::PerVertex); + } + + if (has_clip_distance_inputs) { + const auto type = F32[MaxEmulatedClipDistances]; + const auto attr_id = Name(DefineInput(type, 0), fmt::format("cldist_attr{}", 0)); + input_params[num_inputs] = GetAttributeInfo(AmdGpu::NumberFormat::Float, attr_id, + MaxEmulatedClipDistances, false); + } + break; + } + case SwStage::Compute: + if (info.loads.GetAny(IR::Attribute::WorkgroupIndex) || + info.loads.GetAny(IR::Attribute::WorkgroupId)) { + workgroup_id = + DefineVariable(U32[3], spv::BuiltIn::WorkgroupId, spv::StorageClass::Input); + } + if (info.loads.GetAny(IR::Attribute::WorkgroupIndex)) { + num_workgroups_id = + DefineVariable(U32[3], spv::BuiltIn::NumWorkgroups, spv::StorageClass::Input); + } + if (info.loads.GetAny(IR::Attribute::LocalInvocationId)) { + local_invocation_id = + DefineVariable(U32[3], spv::BuiltIn::LocalInvocationId, spv::StorageClass::Input); + } + if (info.loads.Get(IR::Attribute::LocalInvocationIndex)) { + local_invocation_index = DefineVariable(U32[1], spv::BuiltIn::LocalInvocationIndex, + spv::StorageClass::Input); + } + break; + case SwStage::Geometry: { + primitive_id = DefineVariable(U32[1], spv::BuiltIn::PrimitiveId, spv::StorageClass::Input); + const auto gl_per_vertex = + Name(TypeStruct(F32[4], F32[1], TypeArray(F32[1], ConstU32(1u))), "gl_PerVertex"); + MemberName(gl_per_vertex, 0, "gl_Position"); + MemberName(gl_per_vertex, 1, "gl_PointSize"); + MemberName(gl_per_vertex, 2, "gl_ClipDistance"); + MemberDecorate(gl_per_vertex, 0, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::Position)); + MemberDecorate(gl_per_vertex, 1, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::PointSize)); + MemberDecorate(gl_per_vertex, 2, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::ClipDistance)); + Decorate(gl_per_vertex, spv::Decoration::Block); + const auto num_verts_in = NumVertices(runtime_info.hw.gs.in_primitive); + const auto vertices_in = TypeArray(gl_per_vertex, ConstU32(num_verts_in)); + gl_in = Name(DefineVar(vertices_in, spv::StorageClass::Input), "gl_in"); + interfaces.push_back(gl_in); + + const auto num_params = runtime_info.hw.gs.in_vertex_data_size / 4 - 1u; + for (int param_id = 0; param_id < num_params; ++param_id) { + const Id type{TypeArray(F32[4], ConstU32(num_verts_in))}; + const Id id{DefineInput(type, param_id)}; + Name(id, fmt::format("gs_in_attr{}", param_id)); + input_params[param_id] = + GetAttributeInfo(AmdGpu::NumberFormat::Float, id, 4, false, false, true); + } + break; + } + case SwStage::TessellationControl: { + invocation_id = + DefineVariable(U32[1], spv::BuiltIn::InvocationId, spv::StorageClass::Input); + patch_vertices = + DefineVariable(U32[1], spv::BuiltIn::PatchVertices, spv::StorageClass::Input); + primitive_id = DefineVariable(U32[1], spv::BuiltIn::PrimitiveId, spv::StorageClass::Input); + + const u32 num_attrs = Common::AlignUp(runtime_info.sw.tcs.ls_stride, 16) >> 4; + if (num_attrs > 0) { + const Id per_vertex_type{TypeArray(F32[4], ConstU32(num_attrs))}; + // The input vertex count isn't statically known, so make length 32 (what + // glslang does) + const Id patch_array_type{TypeArray(per_vertex_type, ConstU32(32u))}; + input_attr_array = DefineInput(patch_array_type, 0); + Name(input_attr_array, "in_attrs"); + } + break; + } + case SwStage::TessellationEval: { + tess_coord = DefineInput(F32[3], std::nullopt, spv::BuiltIn::TessCoord); + primitive_id = DefineVariable(U32[1], spv::BuiltIn::PrimitiveId, spv::StorageClass::Input); + + const u32 num_attrs = Common::AlignUp(runtime_info.sw.tes.hs_output_cp_stride, 16) >> 4; + if (num_attrs > 0) { + const Id per_vertex_type{TypeArray(F32[4], ConstU32(num_attrs))}; + // The input vertex count isn't statically known, so make length 32 (what + // glslang does) + const Id patch_array_type{TypeArray(per_vertex_type, ConstU32(32u))}; + input_attr_array = DefineInput(patch_array_type, 0); + Name(input_attr_array, "in_attrs"); + } + + const u32 patch_base_location = num_attrs; + for (size_t index = 0; index < 30; ++index) { + if (!(info.uses_patches & (1U << index))) { + continue; + } + const Id id{DefineInput(F32[4], patch_base_location + index)}; + Decorate(id, spv::Decoration::Patch); + Name(id, fmt::format("patch_in{}", index)); + patches[index] = id; + } + break; + } + default: + break; + } +} + +void EmitContext::DefineVertexBlock() { + const std::array zero{f32_zero_value, f32_zero_value, f32_zero_value, f32_zero_value, + f32_zero_value, f32_zero_value, f32_zero_value, f32_zero_value}; + output_position = DefineVariable(F32[4], spv::BuiltIn::Position, spv::StorageClass::Output); + const bool needs_clip_distance_emulation = sw_stage == SwStage::Vertex && + hw_stage == HwStage::Vertex && + profile.needs_clip_distance_emulation; + const auto has_clip_distance_outputs = info.stores.GetAny(IR::Attribute::ClipDistance); + if (has_clip_distance_outputs && !needs_clip_distance_emulation) { + const Id type{TypeArray(F32[1], ConstU32(8U))}; + const Id initializer{ConstantComposite(type, zero)}; + clip_distances = DefineVariable(type, spv::BuiltIn::ClipDistance, spv::StorageClass::Output, + initializer); + } + if (info.stores.GetAny(IR::Attribute::CullDistance)) { + const Id type{TypeArray(F32[1], ConstU32(8U))}; + const Id initializer{ConstantComposite(type, zero)}; + cull_distances = DefineVariable(type, spv::BuiltIn::CullDistance, spv::StorageClass::Output, + initializer); + } + if (info.stores.GetAny(IR::Attribute::PointSize)) { + output_point_size = + DefineVariable(F32[1], spv::BuiltIn::PointSize, spv::StorageClass::Output); + } + if (info.stores.GetAny(IR::Attribute::RenderTargetIndex)) { + output_layer = DefineVariable(U32[1], spv::BuiltIn::Layer, spv::StorageClass::Output); + } + if (info.stores.GetAny(IR::Attribute::ViewportIndex)) { + output_viewport_index = + DefineVariable(U32[1], spv::BuiltIn::ViewportIndex, spv::StorageClass::Output); + } +} + +void EmitContext::DefineOutputs() { + switch (sw_stage) { + case SwStage::Vertex: { + DefineVertexBlock(); + if (hw_stage == Shader::HwStage::Local) { + const u32 num_attrs = Common::AlignUp(runtime_info.hw.ls.ls_stride, 16) >> 4; + if (num_attrs > 0) { + const Id type{TypeArray(F32[4], ConstU32(num_attrs))}; + output_attr_array = DefineOutput(type, 0); + Name(output_attr_array, "out_attrs"); + } + } else { + const bool needs_clip_distance_emulation = + hw_stage == HwStage::Vertex && profile.needs_clip_distance_emulation && + info.stores.GetAny(IR::Attribute::ClipDistance); + u32 num_attrs = 0u; + for (u32 i = 0; i < IR::NumParams; i++) { + const IR::Attribute param{IR::Attribute::Param0 + i}; + if (!info.stores.GetAny(param)) { + continue; + } + const u32 num_components = info.stores.NumComponents(param); + const Id id{ + DefineOutput(F32[num_components], i + (needs_clip_distance_emulation ? 1 : 0))}; + Name(id, fmt::format("out_attr{}", i)); + output_params[i] = + GetAttributeInfo(AmdGpu::NumberFormat::Float, id, num_components, true); + ++num_attrs; + } + + if (needs_clip_distance_emulation) { + clip_distances = Id{DefineOutput(F32[MaxEmulatedClipDistances], 0)}; + output_params[num_attrs] = GetAttributeInfo( + AmdGpu::NumberFormat::Float, clip_distances, MaxEmulatedClipDistances, true); + Name(clip_distances, fmt::format("cldist_attr{}", 0)); + } + } + break; + } + case SwStage::TessellationControl: { + if (info.stores_tess_level_outer) { + const Id type{TypeArray(F32[1], ConstU32(4U))}; + output_tess_level_outer = + DefineOutput(type, std::nullopt, spv::BuiltIn::TessLevelOuter); + Decorate(output_tess_level_outer, spv::Decoration::Patch); + } + if (info.stores_tess_level_inner) { + const Id type{TypeArray(F32[1], ConstU32(2U))}; + output_tess_level_inner = + DefineOutput(type, std::nullopt, spv::BuiltIn::TessLevelInner); + Decorate(output_tess_level_inner, spv::Decoration::Patch); + } + + const u32 num_attrs = Common::AlignUp(runtime_info.sw.tcs.hs_output_cp_stride, 16) >> 4; + if (num_attrs > 0) { + const Id per_vertex_type{TypeArray(F32[4], ConstU32(num_attrs))}; + // The input vertex count isn't statically known, so make length 32 (what + // glslang does) + const Id patch_array_type{ + TypeArray(per_vertex_type, ConstU32(runtime_info.sw.tcs.NumOutputControlPoints()))}; + output_attr_array = DefineOutput(patch_array_type, 0); + Name(output_attr_array, "out_attrs"); + } + + const u32 patch_base_location = num_attrs; + for (size_t index = 0; index < 30; ++index) { + if (!(info.uses_patches & (1U << index))) { + continue; + } + const Id id{DefineOutput(F32[4], patch_base_location + index)}; + Decorate(id, spv::Decoration::Patch); + Name(id, fmt::format("patch_out{}", index)); + patches[index] = id; + } + break; + } + case SwStage::TessellationEval: { + DefineVertexBlock(); + for (u32 i = 0; i < IR::NumParams; i++) { + const IR::Attribute param{IR::Attribute::Param0 + i}; + if (!info.stores.GetAny(param)) { + continue; + } + const u32 num_components = info.stores.NumComponents(param); + const Id id{DefineOutput(F32[num_components], i)}; + Name(id, fmt::format("out_attr{}", i)); + output_params[i] = + GetAttributeInfo(AmdGpu::NumberFormat::Float, id, num_components, true); + } + break; + } + case SwStage::Fragment: { + if (info.stores.Get(IR::Attribute::Depth)) { + frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output); + } + if (info.stores.Get(IR::Attribute::SampleMask)) { + sample_mask = DefineVariable(TypeArray(U32[1], u32_one_value), spv::BuiltIn::SampleMask, + spv::StorageClass::Output); + } + if (info.stores.Get(IR::Attribute::StencilRef) && profile.supports_shader_stencil_export) { + stencil_ref = + DefineVariable(S32[1], spv::BuiltIn::FragStencilRefEXT, spv::StorageClass::Output); + } + u32 num_render_targets = 0; + for (u32 i = 0; i < IR::NumRenderTargets; i++) { + const IR::Attribute mrt{IR::Attribute::RenderTarget0 + i}; + if (!info.stores.GetAny(mrt)) { + continue; + } + const u32 num_components = info.stores.NumComponents(mrt); + const AmdGpu::NumberFormat num_format{runtime_info.hw.fs.color_buffers[i].num_format}; + const Id type{GetAttributeType(*this, num_format)[num_components]}; + Id id; + if (runtime_info.hw.fs.dual_source_blending) { + id = DefineOutput(type, 0); + Decorate(id, spv::Decoration::Index, i); + } else { + id = DefineOutput(type, i); + } + Name(id, fmt::format("frag_color{}", i)); + frag_outputs[i] = GetAttributeInfo(num_format, id, num_components, true); + ++num_render_targets; + } + // Dual source blending allows at most 2 render targets, one for each source. + // Fewer targets are allowed but the missing blending source values will be + // undefined. + ASSERT_MSG(!runtime_info.hw.fs.dual_source_blending || num_render_targets <= 2, + "Dual source blending enabled, there must be at most two MRT exports"); + break; + } + case SwStage::Geometry: { + DefineVertexBlock(); + for (u32 attr_id = 0; attr_id < info.gs_copy_data.num_attrs; attr_id++) { + const Id id{DefineOutput(F32[4], attr_id)}; + Name(id, fmt::format("out_attr{}", attr_id)); + output_params[attr_id] = GetAttributeInfo(AmdGpu::NumberFormat::Float, id, 4, true); + } + break; + } + case SwStage::Compute: + break; + default: + UNREACHABLE(); + } +} + +void EmitContext::DefinePushDataBlock() { + // Create push constants block for instance steps rates + const Id struct_type{Name(TypeStruct(F32[1], F32[1], F32[1], F32[1], U32[4], U32[4], U32[4], + U32[4], U32[4], U32[4], U32[2]), + "AuxData")}; + Decorate(struct_type, spv::Decoration::Block); + MemberName(struct_type, PushData::XOffsetIndex, "xoffset"); + MemberName(struct_type, PushData::YOffsetIndex, "yoffset"); + MemberName(struct_type, PushData::XScaleIndex, "xscale"); + MemberName(struct_type, PushData::YScaleIndex, "yscale"); + MemberName(struct_type, PushData::UdRegsIndex + 0, "ud_regs0"); + MemberName(struct_type, PushData::UdRegsIndex + 1, "ud_regs1"); + MemberName(struct_type, PushData::UdRegsIndex + 2, "ud_regs2"); + MemberName(struct_type, PushData::UdRegsIndex + 3, "ud_regs3"); + MemberName(struct_type, PushData::BufOffsetIndex + 0, "buf_offsets0"); + MemberName(struct_type, PushData::BufOffsetIndex + 1, "buf_offsets1"); + MemberName(struct_type, PushData::BufOffsetIndex + 2, "buf_offsets2"); + MemberDecorate(struct_type, PushData::XOffsetIndex, spv::Decoration::Offset, 0U); + MemberDecorate(struct_type, PushData::YOffsetIndex, spv::Decoration::Offset, 4U); + MemberDecorate(struct_type, PushData::XScaleIndex, spv::Decoration::Offset, 8U); + MemberDecorate(struct_type, PushData::YScaleIndex, spv::Decoration::Offset, 12U); + MemberDecorate(struct_type, PushData::UdRegsIndex + 0, spv::Decoration::Offset, 16U); + MemberDecorate(struct_type, PushData::UdRegsIndex + 1, spv::Decoration::Offset, 32U); + MemberDecorate(struct_type, PushData::UdRegsIndex + 2, spv::Decoration::Offset, 48U); + MemberDecorate(struct_type, PushData::UdRegsIndex + 3, spv::Decoration::Offset, 64U); + MemberDecorate(struct_type, PushData::BufOffsetIndex + 0, spv::Decoration::Offset, 80U); + MemberDecorate(struct_type, PushData::BufOffsetIndex + 1, spv::Decoration::Offset, 96U); + MemberDecorate(struct_type, PushData::BufOffsetIndex + 2, spv::Decoration::Offset, 112U); + push_data_block = DefineVar(struct_type, spv::StorageClass::PushConstant); + Name(push_data_block, "push_data"); + interfaces.push_back(push_data_block); +} + +EmitContext::BufferSpv EmitContext::DefineBuffer(bool is_written, bool is_coherent, u32 elem_shift, + BufferType buffer_type, Id data_type) { + // Define array type. + const Id record_array_type{TypeRuntimeArray(data_type)}; + // Define block struct type. Don't perform decorations twice on the same Id. + const Id struct_type{TypeStruct(record_array_type)}; + if (std::ranges::find(buf_type_ids, record_array_type.value, &Id::value) == + buf_type_ids.end()) { + Decorate(record_array_type, spv::Decoration::ArrayStride, 1 << elem_shift); + Decorate(struct_type, spv::Decoration::Block); + MemberName(struct_type, 0, "data"); + MemberDecorate(struct_type, 0, spv::Decoration::Offset, 0U); + buf_type_ids.push_back(record_array_type); + } + // Define buffer binding interface. + constexpr auto storage_class = spv::StorageClass::StorageBuffer; + const Id struct_pointer_type{TypePointer(storage_class, struct_type)}; + const Id pointer_type = TypePointer(storage_class, data_type); + const Id id{AddGlobalVariable(struct_pointer_type, storage_class)}; + Decorate(id, spv::Decoration::Binding, binding.unified); + Decorate(id, spv::Decoration::DescriptorSet, 0U); + if (!is_written) { + Decorate(id, spv::Decoration::NonWritable); + } else if (is_coherent) { + // The guest V# MTYPE marks this buffer as shared between invocations; + // Coherent forbids caching its accesses in registers across barriers. + Decorate(id, spv::Decoration::Coherent); + } + switch (buffer_type) { + case BufferType::GdsBuffer: + Name(id, "gds_buffer"); + break; + case BufferType::Flatbuf: + Name(id, "srt_flatbuf"); + break; + case BufferType::ClipPlanes: + Name(id, "clip_planes"); + break; + case BufferType::BdaPagetable: + Name(id, "bda_pagetable"); + break; + case BufferType::FaultBuffer: + Name(id, "fault_buffer"); + break; + case BufferType::SharedMemory: + Name(id, "ssbo_shmem"); + break; + default: + Name(id, fmt::format("ssbo_{}", binding.buffer)); + break; + } + interfaces.push_back(id); + return {id, pointer_type}; +}; + +void EmitContext::DefineBuffers() { + for (const auto& desc : info.buffers) { + const auto buf_sharp = desc.GetSharp(info); + // MTYPE class 3 marks guest buffers shared between invocations; shared + // memory lowered to a storage buffer needs the same guarantee. + const bool is_coherent = + desc.buffer_type == BufferType::SharedMemory || buf_sharp.mtype == 3; + + // Set indexes for special buffers. + if (desc.buffer_type == BufferType::Flatbuf) { + flatbuf_index = buffers.size(); + } else if (desc.buffer_type == BufferType::BdaPagetable) { + bda_pagetable_index = buffers.size(); + } else if (desc.buffer_type == BufferType::FaultBuffer) { + fault_buffer_index = buffers.size(); + } + + // Define aliases depending on the shader usage. + auto& spv_buffer = buffers.emplace_back(binding.buffer++, desc.buffer_type); + if (True(desc.used_types & IR::Type::U64)) { + spv_buffer.Alias(PointerType::U64) = + DefineBuffer(desc.is_written, is_coherent, 3, desc.buffer_type, U64); + } + if (True(desc.used_types & IR::Type::U32)) { + spv_buffer.Alias(PointerType::U32) = + DefineBuffer(desc.is_written, is_coherent, 2, desc.buffer_type, U32[1]); + } + if (True(desc.used_types & IR::Type::F32)) { + spv_buffer.Alias(PointerType::F32) = + DefineBuffer(desc.is_written, is_coherent, 2, desc.buffer_type, F32[1]); + } + if (True(desc.used_types & IR::Type::U16)) { + spv_buffer.Alias(PointerType::U16) = + DefineBuffer(desc.is_written, is_coherent, 1, desc.buffer_type, U16); + } + if (True(desc.used_types & IR::Type::U8)) { + spv_buffer.Alias(PointerType::U8) = + DefineBuffer(desc.is_written, is_coherent, 0, desc.buffer_type, U8); + } + ++binding.unified; + } +} + +spv::ImageFormat GetFormat(const AmdGpu::Image& image) { + if (image.GetDataFmt() == AmdGpu::DataFormat::Format32 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Uint) { + return spv::ImageFormat::R32ui; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format32 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Sint) { + return spv::ImageFormat::R32i; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format32 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Float) { + return spv::ImageFormat::R32f; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format32_32 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Float) { + return spv::ImageFormat::Rg32f; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format32_32 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Uint) { + return spv::ImageFormat::Rg32ui; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format32_32_32_32 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Uint) { + return spv::ImageFormat::Rgba32ui; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format16 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Float) { + return spv::ImageFormat::R16f; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format16 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Uint) { + return spv::ImageFormat::R16ui; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format16_16 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Float) { + return spv::ImageFormat::Rg16f; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format16_16 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Snorm) { + return spv::ImageFormat::Rg16Snorm; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format8_8 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Unorm) { + return spv::ImageFormat::Rg8; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format16_16_16_16 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Float) { + return spv::ImageFormat::Rgba16f; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format16_16_16_16 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Unorm) { + return spv::ImageFormat::Rgba16; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format8 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Unorm) { + return spv::ImageFormat::R8; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format8_8_8_8 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Unorm) { + return spv::ImageFormat::Rgba8; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format8_8_8_8 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Uint) { + return spv::ImageFormat::Rgba8ui; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format10_11_11 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Float) { + return spv::ImageFormat::R11fG11fB10f; + } + if (image.GetDataFmt() == AmdGpu::DataFormat::Format32_32_32_32 && + image.GetNumberFmt() == AmdGpu::NumberFormat::Float) { + return spv::ImageFormat::Rgba32f; + } + UNREACHABLE_MSG("Unknown storage format data_format={}, num_format={}", image.GetDataFmt(), + image.GetNumberFmt()); +} + +Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) { + const auto image = desc.GetSharp(ctx.info); + const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown; + const auto type = image.GetViewType(desc.is_array); + const u32 sampled = desc.is_written ? 2 : 1; + switch (type) { + case AmdGpu::ImageType::Color1D: + return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format); + case AmdGpu::ImageType::Color1DArray: + return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, true, false, sampled, format); + case AmdGpu::ImageType::Color2D: + return ctx.TypeImage(sampled_type, spv::Dim::Dim2D, false, false, false, sampled, format); + case AmdGpu::ImageType::Color2DArray: + return ctx.TypeImage(sampled_type, spv::Dim::Dim2D, false, true, false, sampled, format); + case AmdGpu::ImageType::Color2DMsaa: + return ctx.TypeImage(sampled_type, spv::Dim::Dim2D, false, false, true, sampled, format); + case AmdGpu::ImageType::Color3D: + return ctx.TypeImage(sampled_type, spv::Dim::Dim3D, false, false, false, sampled, format); + default: + break; + } + UNREACHABLE_MSG("Invalid texture type {}", type); +} + +void EmitContext::DefineImagesAndSamplers() { + for (const auto& image_desc : info.images) { + const auto sharp = image_desc.GetSharp(info); + const auto nfmt = sharp.GetNumberFmt(); + const bool is_integer = AmdGpu::IsInteger(nfmt); + const bool is_storage = image_desc.is_written; + const MipStorageFallbackMode mip_fallback_mode = image_desc.mip_fallback_mode; + const VectorIds& data_types = GetAttributeType(*this, nfmt); + const Id sampled_type = data_types[1]; + const Id image_type{ImageType(*this, image_desc, sampled_type)}; + + const u32 num_bindings = image_desc.NumBindings(info); + Id pointee_type = image_type; + if (mip_fallback_mode == MipStorageFallbackMode::DynamicIndex) { + pointee_type = TypeArray(pointee_type, ConstU32(num_bindings)); + } + + const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, pointee_type)}; + const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; + Decorate(id, spv::Decoration::Binding, binding.unified); + binding.unified += num_bindings; + Decorate(id, spv::Decoration::DescriptorSet, 0U); + Name(id, fmt::format("{}_{}{}", hw_stage, "img", images.size())); + images.push_back({ + .data_types = &data_types, + .id = id, + .sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type), + .image_type = image_type, + .view_type = sharp.GetViewType(image_desc.is_array), + .is_integer = is_integer, + .is_storage = is_storage, + .mip_fallback_mode = mip_fallback_mode, + }); + interfaces.push_back(id); + } + if (std::ranges::any_of(info.images, + [](const ImageResource& image) { return image.is_atomic; })) { + image_u32 = TypePointer(spv::StorageClass::Image, U32[1]); + image_f32 = TypePointer(spv::StorageClass::Image, F32[1]); + } + if (info.samplers.empty()) { + return; + } + sampler_type = TypeSampler(); + sampler_pointer_type = TypePointer(spv::StorageClass::UniformConstant, sampler_type); + for (const auto& samp_desc : info.samplers) { + const Id id{AddGlobalVariable(sampler_pointer_type, spv::StorageClass::UniformConstant)}; + Decorate(id, spv::Decoration::Binding, binding.unified++); + Decorate(id, spv::Decoration::DescriptorSet, 0U); + Name(id, fmt::format("{}_{}{}", hw_stage, "samp", samplers.size())); + samplers.push_back(id); + interfaces.push_back(id); + } +} + +void EmitContext::DefineSharedMemory() { + const auto num_types = std::popcount(static_cast(info.shared_types)); + if (num_types == 0) { + return; + } + ASSERT(info.hw_stage == HwStage::Compute); + const u32 shared_memory_size = + runtime_info.hw.cs.shared_memory_size + info.shared_memory_scratch_size; + + const auto make_type = [&](IR::Type type, Id element_type, u32 element_size, + std::string_view name) { + if (False(info.shared_types & type)) { + // Skip unused shared memory types. + return std::make_tuple(Id{}, Id{}, Id{}); + } + + const u32 num_elements{Common::DivCeil(shared_memory_size, element_size)}; + const Id array_type{TypeArray(element_type, ConstU32(num_elements))}; + + const auto mem_type = [&] { + if (num_types > 1) { + const Id struct_type{TypeStruct(array_type)}; + Decorate(struct_type, spv::Decoration::Block); + MemberDecorate(struct_type, 0u, spv::Decoration::Offset, 0u); + return struct_type; + } else { + return array_type; + } + }(); + + const Id pointer = TypePointer(spv::StorageClass::Workgroup, mem_type); + const Id element_pointer = TypePointer(spv::StorageClass::Workgroup, element_type); + const Id variable = AddGlobalVariable(pointer, spv::StorageClass::Workgroup); + Name(variable, name); + interfaces.push_back(variable); + + if (num_types > 1) { + Decorate(array_type, spv::Decoration::ArrayStride, element_size); + Decorate(variable, spv::Decoration::Aliased); + } + + return std::make_tuple(variable, element_pointer, pointer); + }; + std::tie(shared_memory_u16, shared_u16, shared_memory_u16_type) = + make_type(IR::Type::U16, U16, 2u, "shared_mem_u16"); + std::tie(shared_memory_u32, shared_u32, shared_memory_u32_type) = + make_type(IR::Type::U32, U32[1], 4u, "shared_mem_u32"); + std::tie(shared_memory_u64, shared_u64, shared_memory_u64_type) = + make_type(IR::Type::U64, U64, 8u, "shared_mem_u64"); +} + +Id EmitContext::DefineFloat32ToUfloatM5(u32 mantissa_bits, const std::string_view name) { + // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/util/format_r11g11b10f.h + const auto func_type{TypeFunction(U32[1], F32[1])}; + const auto func{OpFunction(U32[1], spv::FunctionControlMask::MaskNone, func_type)}; + const auto value{OpFunctionParameter(F32[1])}; + Name(func, name); + AddLabel(); + + const auto raw_value{OpBitcast(U32[1], value)}; + const auto exponent{ + OpBitcast(S32[1], OpBitFieldSExtract(U32[1], raw_value, ConstU32(23U), ConstU32(8U)))}; + const auto sign{OpBitFieldUExtract(U32[1], raw_value, ConstU32(31U), ConstU32(1U))}; + + const auto is_zero{OpLogicalOr(U1[1], OpIEqual(U1[1], raw_value, ConstU32(0U)), + OpIEqual(U1[1], sign, ConstU32(1U)))}; + const auto is_nan{OpIsNan(U1[1], value)}; + const auto is_inf{OpIsInf(U1[1], value)}; + const auto is_denorm{OpSLessThanEqual(U1[1], exponent, ConstS32(-15))}; + + const auto denorm_mantissa{OpConvertFToU( + U32[1], + OpRoundEven(F32[1], OpFMul(F32[1], value, + ConstF32(static_cast(1 << (mantissa_bits + 14))))))}; + const auto denorm_overflow{ + OpINotEqual(U1[1], OpShiftRightLogical(U32[1], denorm_mantissa, ConstU32(mantissa_bits)), + ConstU32(0U))}; + const auto denorm{ + OpSelect(U32[1], denorm_overflow, ConstU32(1U << mantissa_bits), denorm_mantissa)}; + + const auto norm_mantissa{OpConvertFToU( + U32[1], + OpRoundEven(F32[1], + OpLdexp(F32[1], value, + OpISub(S32[1], ConstS32(static_cast(mantissa_bits)), exponent))))}; + const auto norm_overflow{ + OpUGreaterThanEqual(U1[1], norm_mantissa, ConstU32(2U << mantissa_bits))}; + const auto norm_final_mantissa{OpBitwiseAnd( + U32[1], + OpSelect(U32[1], norm_overflow, OpShiftRightLogical(U32[1], norm_mantissa, ConstU32(1U)), + norm_mantissa), + ConstU32((1U << mantissa_bits) - 1))}; + const auto norm_final_exponent{OpBitcast( + U32[1], + OpIAdd(S32[1], + OpSelect(S32[1], norm_overflow, OpIAdd(S32[1], exponent, ConstS32(1)), exponent), + ConstS32(15)))}; + const auto norm{OpBitFieldInsert(U32[1], norm_final_mantissa, norm_final_exponent, + ConstU32(mantissa_bits), ConstU32(5U))}; + + const auto result{OpSelect(U32[1], is_zero, ConstU32(0U), + OpSelect(U32[1], is_nan, ConstU32(31u << mantissa_bits | 1U), + OpSelect(U32[1], is_inf, ConstU32(31U << mantissa_bits), + OpSelect(U32[1], is_denorm, denorm, norm))))}; + + OpReturnValue(result); + OpFunctionEnd(); + return func; +} + +Id EmitContext::DefineUfloatM5ToFloat32(u32 mantissa_bits, const std::string_view name) { + // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/util/format_r11g11b10f.h + const auto func_type{TypeFunction(F32[1], U32[1])}; + const auto func{OpFunction(F32[1], spv::FunctionControlMask::MaskNone, func_type)}; + const auto value{OpFunctionParameter(U32[1])}; + Name(func, name); + AddLabel(); + + const Id exponent{OpBitFieldUExtract(U32[1], value, ConstU32(mantissa_bits), ConstU32(5U))}; + const Id mantissa{OpBitFieldUExtract(U32[1], value, ConstU32(0U), ConstU32(mantissa_bits))}; + const Id mantissa_f{OpConvertUToF(F32[1], mantissa)}; + const Id a{OpSelect(F32[1], OpINotEqual(U1[1], mantissa, u32_zero_value), + OpFMul(F32[1], ConstF32(1.f / (1 << (14 + mantissa_bits))), mantissa_f), + f32_zero_value)}; + const Id b{OpBitcast(F32[1], OpBitwiseOr(U32[1], mantissa, ConstU32(0x7f800000U)))}; + const Id exponent_c{OpISub(U32[1], exponent, ConstU32(15U))}; + const Id scale_a{ + OpFDiv(F32[1], ConstF32(1.f), + OpConvertUToF(F32[1], OpShiftLeftLogical(U32[1], u32_one_value, + OpSNegate(U32[1], exponent_c))))}; + const Id scale_b{OpConvertUToF(F32[1], OpShiftLeftLogical(U32[1], u32_one_value, exponent_c))}; + const Id scale{ + OpSelect(F32[1], OpSLessThan(U1[1], exponent_c, u32_zero_value), scale_a, scale_b)}; + const Id c{OpFMul(F32[1], scale, + OpFAdd(F32[1], ConstF32(1.f), + OpFDiv(F32[1], mantissa_f, ConstF32(f32(1 << mantissa_bits)))))}; + const Id result{OpSelect(F32[1], OpIEqual(U1[1], exponent, u32_zero_value), a, + OpSelect(F32[1], OpIEqual(U1[1], exponent, ConstU32(31U)), b, c))}; + OpReturnValue(result); + OpFunctionEnd(); + return func; +} + +Id EmitContext::DefineGetBdaPointer() { + const auto caching_pagebits{Constant(U64, static_cast(profile.sparse_page_shift))}; + const auto caching_pagemask{ + Constant(U64, static_cast((1u << profile.sparse_page_shift) - 1))}; + + const auto func_type{TypeFunction(U64, U64)}; + const auto func{OpFunction(U64, spv::FunctionControlMask::MaskNone, func_type)}; + const auto address{OpFunctionParameter(U64)}; + Name(func, "get_bda_pointer"); + AddLabel(); + + const auto fault_label{OpLabel()}; + const auto available_label{OpLabel()}; + const auto merge_label{OpLabel()}; + + // Get page BDA + const auto page{OpShiftRightLogical(U64, address, caching_pagebits)}; + const auto page32{OpUConvert(U32[1], page)}; + const auto& bda_buffer{buffers[bda_pagetable_index]}; + const auto [bda_buffer_id, bda_pointer_type] = bda_buffer.Alias(PointerType::U64); + const auto bda_ptr{OpAccessChain(bda_pointer_type, bda_buffer_id, u32_zero_value, page32)}; + const auto bda{OpLoad(U64, bda_ptr)}; + + // Check if page is GPU cached + const auto is_fault{OpIEqual(U1[1], bda, u64_zero_value)}; + OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone); + OpBranchConditional(is_fault, fault_label, available_label); + + // First time acces, mark as fault + AddLabel(fault_label); + const auto& fault_buffer{buffers[fault_buffer_index]}; + const auto [fault_buffer_id, fault_pointer_type] = fault_buffer.Alias(PointerType::U32); + const auto page_div32{OpShiftRightLogical(U32[1], page32, ConstU32(5U))}; + const auto page_mod32{OpBitwiseAnd(U32[1], page32, ConstU32(31U))}; + const auto page_mask{OpShiftLeftLogical(U32[1], u32_one_value, page_mod32)}; + const auto fault_ptr{ + OpAccessChain(fault_pointer_type, fault_buffer_id, u32_zero_value, page_div32)}; + const auto fault_value{OpLoad(U32[1], fault_ptr)}; + const auto fault_value_masked{OpBitwiseOr(U32[1], fault_value, page_mask)}; + OpStore(fault_ptr, fault_value_masked); + + // Return null pointer + const auto fallback_result{u64_zero_value}; + OpBranch(merge_label); + + // Value is available, compute address + AddLabel(available_label); + const auto offset_in_bda{OpBitwiseAnd(U64, address, caching_pagemask)}; + const auto addr{OpIAdd(U64, bda, offset_in_bda)}; + OpBranch(merge_label); + + // Merge + AddLabel(merge_label); + const auto result{OpPhi(U64, addr, available_label, fallback_result, fault_label)}; + OpReturnValue(result); + OpFunctionEnd(); + return func; +} + +Id EmitContext::DefineReadConst(bool dynamic) { + const auto func_type{!dynamic ? TypeFunction(U32[1], U32[2], U32[1], U32[1]) + : TypeFunction(U32[1], U32[2], U32[1])}; + const auto func{OpFunction(U32[1], spv::FunctionControlMask::MaskNone, func_type)}; + const auto base{OpFunctionParameter(U32[2])}; + const auto offset{OpFunctionParameter(U32[1])}; + const auto flatbuf_offset{!dynamic ? OpFunctionParameter(U32[1]) : Id{}}; + Name(func, dynamic ? "read_const_dynamic" : "read_const"); + AddLabel(); + + const auto base_lo{OpUConvert(U64, OpCompositeExtract(U32[1], base, 0))}; + const auto base_hi{OpUConvert(U64, OpCompositeExtract(U32[1], base, 1))}; + const auto base_shift{OpShiftLeftLogical(U64, base_hi, ConstU32(32U))}; + const auto base_addr{OpBitwiseOr(U64, base_lo, base_shift)}; + const auto offset_bytes{OpShiftLeftLogical(U32[1], offset, ConstU32(2U))}; + const auto addr{OpIAdd(U64, base_addr, OpUConvert(U64, offset_bytes))}; + + const auto result = EmitDwordMemoryRead(addr, [&]() { + if (dynamic) { + return u32_zero_value; + } else { + return EmitFlatbufferLoad(flatbuf_offset); + } + }); + + OpReturnValue(result); + OpFunctionEnd(); + return func; +} + +void EmitContext::DefineFunctions() { + if (info.uses_pack_10_11_11) { + f32_to_uf11 = DefineFloat32ToUfloatM5(6, "f32_to_uf11"); + f32_to_uf10 = DefineFloat32ToUfloatM5(5, "f32_to_uf10"); + } + if (info.uses_unpack_10_11_11) { + uf11_to_f32 = DefineUfloatM5ToFloat32(6, "uf11_to_f32"); + uf10_to_f32 = DefineUfloatM5ToFloat32(5, "uf10_to_f32"); + } + if (info.uses_dma) { + get_bda_pointer = DefineGetBdaPointer(); + } + + if (True(info.readconst_types & Info::ReadConstType::Immediate)) { + LOG_DEBUG(Render_Recompiler, "Shader {:#x} uses immediate ReadConst", info.pgm_hash); + read_const = DefineReadConst(false); + } + if (True(info.readconst_types & Info::ReadConstType::Dynamic)) { + LOG_DEBUG(Render_Recompiler, "Shader {:#x} uses dynamic ReadConst", info.pgm_hash); + read_const_dynamic = DefineReadConst(true); + } +} + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/backend/spirv/spirv_emit_context.h b/gpu/shadps4/shader_recompiler/backend/spirv/spirv_emit_context.h new file mode 100644 index 0000000..0057d4b --- /dev/null +++ b/gpu/shadps4/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -0,0 +1,423 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "shader_recompiler/backend/bindings.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/value.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Backend::SPIRV { + +using Sirit::Id; + +struct VectorIds { + [[nodiscard]] Id& operator[](u32 index) { + return ids[index - 1]; + } + + [[nodiscard]] const Id& operator[](u32 index) const { + return ids[index - 1]; + } + + [[nodiscard]] Id& Get(u32 index) { + return ids[index - 1]; + } + + [[nodiscard]] const Id& Get(u32 index) const { + return ids[index - 1]; + } + + std::array ids; +}; + +class EmitContext final : public Sirit::Module { +public: + explicit EmitContext(const Profile& profile, const RuntimeInfo& runtime_info, Info& info, + Bindings& binding); + ~EmitContext(); + + Id Def(const IR::Value& value); + + void DefineBufferProperties(); + void DefineAmdPerVertexAttribs(); + void DefineWorkgroupIndex(); + + [[nodiscard]] Id DefineInput(Id type, std::optional location = std::nullopt, + std::optional builtin = std::nullopt) { + const Id input_id{DefineVariable(type, builtin, spv::StorageClass::Input)}; + if (location) { + Decorate(input_id, spv::Decoration::Location, *location); + } + return input_id; + } + + [[nodiscard]] Id DefineOutput(Id type, std::optional location = std::nullopt, + std::optional builtin = std::nullopt) { + const Id output_id{DefineVariable(type, builtin, spv::StorageClass::Output)}; + if (location) { + Decorate(output_id, spv::Decoration::Location, *location); + } + return output_id; + } + + [[nodiscard]] Id DefineUniformConst(Id type, u32 set, u32 binding, bool readonly = false) { + const Id uniform_id{DefineVar(type, spv::StorageClass::UniformConstant)}; + Decorate(uniform_id, spv::Decoration::DescriptorSet, set); + Decorate(uniform_id, spv::Decoration::Binding, binding); + if (readonly) { + Decorate(uniform_id, spv::Decoration::NonWritable); + } + return uniform_id; + } + + template + [[nodiscard]] Id DefineVar(Id type, spv::StorageClass storage_class, + std::optional initializer = std::nullopt) { + const Id pointer_type_id{TypePointer(storage_class, type)}; + return global ? AddGlobalVariable(pointer_type_id, storage_class, initializer) + : AddLocalVariable(pointer_type_id, storage_class, initializer); + } + + [[nodiscard]] Id DefineVariable(Id type, std::optional builtin, + spv::StorageClass storage_class, + std::optional initializer = std::nullopt) { + const Id id{DefineVar(type, storage_class, initializer)}; + if (builtin) { + Decorate(id, spv::Decoration::BuiltIn, *builtin); + } + interfaces.push_back(id); + return id; + } + + [[nodiscard]] Id ConstU32(u32 value) { + return Constant(U32[1], value); + } + + template + [[nodiscard]] Id ConstU32(Args&&... values) { + constexpr u32 size = static_cast(sizeof...(values)); + static_assert(size >= 2); + const std::array constituents{Constant(U32[1], values)...}; + const Id type = size <= 4 ? U32[size] : TypeArray(U32[1], ConstU32(size)); + return ConstantComposite(type, constituents); + } + + [[nodiscard]] Id ConstS32(s32 value) { + return Constant(S32[1], value); + } + + template + [[nodiscard]] Id ConstS32(Args&&... values) { + constexpr u32 size = static_cast(sizeof...(values)); + static_assert(size >= 2); + const std::array constituents{Constant(S32[1], values)...}; + const Id type = size <= 4 ? S32[size] : TypeArray(S32[1], ConstU32(size)); + return ConstantComposite(type, constituents); + } + + [[nodiscard]] Id ConstF32(f32 value) { + return Constant(F32[1], value); + } + + template + [[nodiscard]] Id ConstF32(Args... values) { + constexpr u32 size = static_cast(sizeof...(values)); + static_assert(size >= 2); + const std::array constituents{Constant(F32[1], values)...}; + const Id type = size <= 4 ? F32[size] : TypeArray(F32[1], ConstU32(size)); + return ConstantComposite(type, constituents); + } + + inline Id AddLabel() { + last_label = Module::AddLabel(); + return last_label; + } + + inline Id AddLabel(Id label) { + last_label = Module::AddLabel(label); + return last_label; + } + + Id EmitDwordMemoryRead(Id address, auto&& fallback) { + const Id available_label = OpLabel(); + const Id fallback_label = OpLabel(); + const Id merge_label = OpLabel(); + + const Id addr = OpFunctionCall(U64, get_bda_pointer, address); + const Id is_available = OpINotEqual(U1[1], addr, u64_zero_value); + OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone); + OpBranchConditional(is_available, available_label, fallback_label); + + // Available + AddLabel(available_label); + const Id addr_ptr = OpConvertUToPtr(physical_pointer_type_u32, addr); + const Id result = OpLoad(U32[1], addr_ptr, spv::MemoryAccessMask::Aligned, 4u); + OpBranch(merge_label); + + // Fallback + AddLabel(fallback_label); + const Id fallback_result = fallback(); + OpBranch(merge_label); + + // Merge + AddLabel(merge_label); + const Id final_result = + OpPhi(U32[1], fallback_result, fallback_label, result, available_label); + return final_result; + } + + Id EmitSharedMemoryAccess(const Id result_type, const Id shared_mem, const Id index) { + if (std::popcount(static_cast(info.shared_types)) > 1) { + return OpAccessChain(result_type, shared_mem, u32_zero_value, index); + } + // Workgroup layout struct omitted. + return OpAccessChain(result_type, shared_mem, index); + } + + Id EmitFlatbufferLoad(Id flatbuf_offset) { + const auto& flatbuf_buffer{buffers[flatbuf_index]}; + ASSERT(flatbuf_buffer.binding >= 0 && flatbuf_buffer.buffer_type == BufferType::Flatbuf); + const auto [flatbuf_buffer_id, flatbuf_pointer_type] = + flatbuf_buffer.aliases[u32(PointerType::U32)]; + const auto ptr{ + OpAccessChain(flatbuf_pointer_type, flatbuf_buffer_id, u32_zero_value, flatbuf_offset)}; + return OpLoad(U32[1], ptr); + } + + Info& info; + const RuntimeInfo& runtime_info; + const Profile& profile; + HwStage hw_stage; + SwStage sw_stage{}; + + Id last_label{}; + + Id void_id{}; + Id U8{}; + Id S8{}; + Id U16{}; + Id S16{}; + Id U64{}; + VectorIds F16{}; + VectorIds F32{}; + VectorIds F64{}; + VectorIds S32{}; + VectorIds U32{}; + VectorIds U1{}; + + Id full_result_i32x2; + Id full_result_u32x2; + Id frexp_result_f32; + Id frexp_result_f64; + + Id pi_x2; + + Id true_value{}; + Id false_value{}; + Id u8_one_value{}; + Id u8_zero_value{}; + Id u16_zero_value{}; + Id u32_one_value{}; + Id u32_zero_value{}; + Id f32_zero_value{}; + Id u64_one_value{}; + Id u64_zero_value{}; + + Id shared_u16{}; + Id shared_u32{}; + Id shared_u64{}; + + Id input_u32{}; + Id input_f32{}; + Id input_s32{}; + Id output_u32{}; + Id output_f32{}; + Id output_s32{}; + + Id gl_in{}; + + boost::container::small_vector interfaces; + + Id output_position{}; + Id output_point_size{}; + Id output_layer{}; + Id output_viewport_index{}; + Id primitive_id{}; + Id vertex_index{}; + Id instance_id{}; + Id push_data_block{}; + Id base_vertex{}; + Id base_instance{}; + Id frag_coord{}; + Id front_facing{}; + Id frag_depth{}; + Id stencil_ref{}; + Id sample_mask{}; + Id sample_mask_in{}; + Id helper_invocation{}; + Id sample_index{}; + Id clip_distances{}; + Id cull_distances{}; + + Id patch_vertices{}; + Id output_tess_level_outer{}; + Id output_tess_level_inner{}; + Id tess_coord; + std::array patches{}; + + Id workgroup_id{}; + Id num_workgroups_id{}; + Id workgroup_index_id{}; + Id local_invocation_id{}; + Id local_invocation_index{}; + Id invocation_id{}; + Id subgroup_local_invocation_id{}; + Id subgroup_lt_mask{}; + Id image_u32{}; + Id image_f32{}; + + Id shared_memory_u16{}; + Id shared_memory_u32{}; + Id shared_memory_u64{}; + + Id shared_memory_u16_type{}; + Id shared_memory_u32_type{}; + Id shared_memory_u64_type{}; + + Id bary_coord{}; + Id bary_coord_smooth{}; + Id bary_coord_smooth_centroid{}; + Id bary_coord_smooth_sample{}; + Id bary_coord_pull_model{}; + Id bary_coord_nopersp{}; + Id bary_coord_nopersp_sample{}; + + struct TextureDefinition { + const VectorIds* data_types; + Id id; + Id sampled_type; + Id image_type; + AmdGpu::ImageType view_type; + bool is_integer = false; + bool is_storage = false; + MipStorageFallbackMode mip_fallback_mode{}; + }; + + enum class PointerType : u32 { + U8, + U16, + U32, + F32, + U64, + F64, + NumAlias, + }; + + enum class PointerSize : u32 { + B8, + B16, + B32, + B64, + NumClass, + }; + + struct BufferSpv { + Id id; + Id pointer_type; + }; + + struct BufferDefinition { + u32 binding; + BufferType buffer_type; + std::array offsets; + std::array aliases; + + template + auto& Alias(this Self& self, PointerType alias) { + return self.aliases[u32(alias)]; + } + + template + auto& Offset(this Self& self, PointerSize size) { + return self.offsets[u32(size)]; + } + }; + + Bindings& binding; + boost::container::small_vector buf_type_ids; + boost::container::small_vector buffers; + boost::container::small_vector images; + boost::container::small_vector samplers; + std::unordered_map first_to_last_label_map; + + size_t flatbuf_index{}; + size_t bda_pagetable_index{}; + size_t fault_buffer_index{}; + Id physical_pointer_type_u32; + + Id sampler_type{}; + Id sampler_pointer_type{}; + + struct SpirvAttribute { + union { + Id id; + std::array id_array; + }; + Id pointer_type; + Id component_type; + u32 num_components; + bool is_integer{}; + bool is_loaded{}; + bool is_array{}; + }; + Id input_attr_array; + Id output_attr_array; + std::array input_params{}; + std::array output_params{}; + std::array frag_outputs{}; + + Id uf11_to_f32{}; + Id f32_to_uf11{}; + Id uf10_to_f32{}; + Id f32_to_uf10{}; + + Id get_bda_pointer{}; + + Id read_const{}; + Id read_const_dynamic{}; + +private: + void DefineArithmeticTypes(); + void DefineInterfaces(); + void DefineInputs(); + void DefineVertexBlock(); + void DefineOutputs(); + void DefinePushDataBlock(); + void DefineBuffers(); + void DefineImagesAndSamplers(); + void DefineSharedMemory(); + void DefineFunctions(); + + SpirvAttribute GetAttributeInfo(AmdGpu::NumberFormat fmt, Id id, u32 num_components, + bool output, bool loaded = false, bool array = false); + + BufferSpv DefineBuffer(bool is_written, bool is_coherent, u32 elem_shift, + BufferType buffer_type, Id data_type); + + Id DefineFloat32ToUfloatM5(u32 mantissa_bits, std::string_view name); + Id DefineUfloatM5ToFloat32(u32 mantissa_bits, std::string_view name); + + Id DefineGetBdaPointer(); + + Id DefineReadConst(bool dynamic); + + Id GetBufferSize(u32 sharp_idx); +}; + +} // namespace Shader::Backend::SPIRV diff --git a/gpu/shadps4/shader_recompiler/frontend/control_flow_graph.cpp b/gpu/shadps4/shader_recompiler/frontend/control_flow_graph.cpp new file mode 100644 index 0000000..736d563 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/control_flow_graph.cpp @@ -0,0 +1,431 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "common/logging/log.h" +#include "shader_recompiler/frontend/control_flow_graph.h" +#include "shader_recompiler/ir/condition.h" + +namespace Shader::Gcn { + +struct Compare { + bool operator()(const Block& lhs, u32 rhs) const noexcept { + return lhs.begin < rhs; + } + + bool operator()(u32 lhs, const Block& rhs) const noexcept { + return lhs < rhs.begin; + } + + bool operator()(const Block& lhs, const Block& rhs) const noexcept { + return lhs.begin < rhs.begin; + } +}; + +static IR::Condition MakeCondition(const GcnInst& inst) { + if (inst.IsCmpx()) { + return IR::Condition::Execnz; + } + + switch (inst.opcode) { + case Opcode::S_CBRANCH_SCC0: + return IR::Condition::Scc0; + case Opcode::S_CBRANCH_SCC1: + return IR::Condition::Scc1; + case Opcode::S_CBRANCH_VCCZ: + return IR::Condition::Vccz; + case Opcode::S_CBRANCH_VCCNZ: + return IR::Condition::Vccnz; + case Opcode::S_CBRANCH_EXECZ: + return IR::Condition::Execz; + case Opcode::S_CBRANCH_EXECNZ: + return IR::Condition::Execnz; + default: + return IR::Condition::True; + } +} + +static bool IgnoresExecMask(const GcnInst& inst) { + // EXEC mask does not affect scalar instructions or branches. + switch (inst.category) { + case InstCategory::ScalarALU: + case InstCategory::ScalarMemory: + case InstCategory::FlowControl: + return true; + default: + break; + } + // Read/Write Lane instructions are not affected either. + switch (inst.opcode) { + case Opcode::V_READLANE_B32: + case Opcode::V_WRITELANE_B32: + case Opcode::V_READFIRSTLANE_B32: + return true; + default: + break; + } + return false; +} + +static std::optional ResolveSetPcTarget(std::span list, u32 setpc_index, + std::span pc_map) { + if (setpc_index < 3) { + return std::nullopt; + } + + const auto& getpc = list[setpc_index - 3]; + const auto& arith = list[setpc_index - 2]; + const auto& setpc = list[setpc_index]; + + if (getpc.opcode != Opcode::S_GETPC_B64 || + !(arith.opcode == Opcode::S_ADD_U32 || arith.opcode == Opcode::S_SUB_U32) || + setpc.opcode != Opcode::S_SETPC_B64) + return std::nullopt; + + if (getpc.dst[0].code != setpc.src[0].code || arith.dst[0].code != setpc.src[0].code) + return std::nullopt; + + if (arith.src_count < 2 || arith.src[1].field != OperandField::LiteralConst) + return std::nullopt; + + const u32 imm = arith.src[1].code; + + const s32 signed_offset = + (arith.opcode == Opcode::S_ADD_U32) ? static_cast(imm) : -static_cast(imm); + + const u32 base_pc = pc_map[setpc_index - 3] + getpc.length; + + const u32 result_pc = static_cast(static_cast(base_pc) + signed_offset); + LOG_DEBUG(Render_Recompiler, "SetPC target: {} + {} = {}", base_pc, signed_offset, result_pc); + return result_pc & ~0x3u; +} + +static constexpr size_t LabelReserveSize = 32; + +CFG::CFG(Common::ObjectPool& block_pool_, std::span inst_list_) + : block_pool{block_pool_}, inst_list{inst_list_} { + index_to_pc.resize(inst_list.size() + 1); + labels.reserve(LabelReserveSize); + EmitLabels(); + EmitBlocks(); + LinkBlocks(); + SplitDivergenceScopes(); + RemoveUnreachableBlocks(); +} + +void CFG::EmitLabels() { + // Always set a label at entry point. + u32 pc = 0; + AddLabel(pc); + + // Iterate instruction list and add labels to branch targets. + for (u32 i = 0; i < inst_list.size(); i++) { + index_to_pc[i] = pc; + const GcnInst inst = inst_list[i]; + if (inst.IsUnconditionalBranch()) { + u32 target = inst.BranchTarget(pc); + if (inst.opcode == Opcode::S_SETPC_B64) { + if (auto t = ResolveSetPcTarget(inst_list, i, index_to_pc)) { + target = *t; + } else { + ASSERT_MSG( + false, + "S_SETPC_B64 without a resolvable offset at PC {:#x} (Index {}): Involved " + "instructions not recognized or invalid pattern", + pc, i); + } + } + AddLabel(target); + // Emit this label so that the block ends with the branching instruction + AddLabel(pc + inst.length); + } else if (inst.IsConditionalBranch()) { + const u32 true_label = inst.BranchTarget(pc); + const u32 false_label = pc + inst.length; + if (true_label != false_label) { + AddLabel(true_label); + AddLabel(false_label); + } + } else if (inst.opcode == Opcode::S_ENDPGM) { + const u32 next_label = pc + inst.length; + AddLabel(next_label); + } + + pc += inst.length; + } + index_to_pc[inst_list.size()] = pc; + + // Sort labels to make sure block insertion is correct. + std::ranges::sort(labels); +} + +void CFG::SplitDivergenceScopes() { + const auto is_open_scope = [](const GcnInst& inst) { + // An open scope instruction is an instruction that modifies EXEC + // but also saves the previous value to restore later. This indicates + // we are entering a scope. + return inst.opcode == Opcode::S_AND_SAVEEXEC_B64 || + // While this instruction does not save EXEC it is often used paired + // with SAVEEXEC to mask the threads that didn't pass the condition + // of initial branch. + (inst.opcode == Opcode::S_ANDN2_B64 && inst.dst[0].field == OperandField::ExecLo) || + inst.IsCmpx(); + }; + const auto is_close_scope = [](const GcnInst& inst) { + // Closing an EXEC scope can be either a branch instruction + // (typical case when S_AND_SAVEEXEC_B64 is right before a branch) + // or by a move instruction to EXEC that restores the backup. + return (inst.opcode == Opcode::S_MOV_B64 && inst.dst[0].field == OperandField::ExecLo) || + // Sometimes compiler might insert instructions between the SAVEEXEC and the branch. + // Those instructions need to be wrapped in the condition as well so allow branch + // as end scope instruction. + inst.opcode == Opcode::S_CBRANCH_EXECZ || inst.opcode == Opcode::S_ENDPGM || + (inst.opcode == Opcode::S_ANDN2_B64 && inst.dst[0].field == OperandField::ExecLo); + }; + + for (auto blk = blocks.begin(); blk != blocks.end(); blk++) { + auto next_blk = std::next(blk); + s32 curr_begin = -1; + for (size_t index = blk->begin_index; index <= blk->end_index; index++) { + const auto& inst = inst_list[index]; + const bool is_close = is_close_scope(inst); + if ((is_close || index == blk->end_index) && curr_begin != -1) { + // If there are no instructions inside scope don't do anything. + if (index - curr_begin == 1 && is_close) { + curr_begin = -1; + continue; + } + // If all instructions in the scope ignore exec masking, we shouldn't insert a + // scope. + const auto start = inst_list.begin() + curr_begin + 1; + if (!std::ranges::all_of(start, inst_list.begin() + index + !is_close, + IgnoresExecMask)) { + // Determine the first instruction affected by the exec mask. + do { + ++curr_begin; + } while (IgnoresExecMask(inst_list[curr_begin])); + + // Determine the last instruction affected by the exec mask. + s32 curr_end = index; + while (IgnoresExecMask(inst_list[curr_end])) { + --curr_end; + } + + // Create a new block for the divergence scope. + Block* block = block_pool.Create(); + block->begin = index_to_pc[curr_begin]; + block->end = index_to_pc[curr_end]; + block->begin_index = curr_begin; + block->end_index = curr_end; + block->end_inst = inst_list[curr_end]; + block->num_predecessors = 1; + blocks.insert_before(next_blk, *block); + + // If we are inside the parent block, make an epilogue block and jump to it. + if (curr_end != blk->end_index) { + Block* epi_block = block_pool.Create(); + epi_block->begin = index_to_pc[curr_end + 1]; + epi_block->end = blk->end; + epi_block->begin_index = curr_end + 1; + epi_block->end_index = blk->end_index; + epi_block->end_inst = blk->end_inst; + epi_block->cond = blk->cond; + epi_block->end_class = blk->end_class; + epi_block->branch_true = blk->branch_true; + epi_block->branch_false = blk->branch_false; + epi_block->num_predecessors = 2; + blocks.insert_before(next_blk, *epi_block); + + // Have divergence block always jump to epilogue block. + block->cond = IR::Condition::True; + block->branch_true = epi_block; + block->branch_false = nullptr; + + // If the parent block fails to enter divergence block make it jump to + // epilogue too + blk->branch_false = epi_block; + } else { + // No epilogue block is needed since the divergence block + // also ends the parent block. Inherit the end condition. + auto& parent_blk = *blk; + ASSERT(blk->cond == IR::Condition::True && blk->branch_true); + block->cond = IR::Condition::True; + block->branch_true = blk->branch_true; + block->branch_false = nullptr; + + // If the parent block didn't enter the divergence scope + // have it jump directly to the next one + blk->branch_false = blk->branch_true; + blk->branch_true->num_predecessors++; + } + + // Shrink parent block to end right before curr_begin + // and make it jump to divergence block + --curr_begin; + blk->end = index_to_pc[curr_begin]; + blk->end_index = curr_begin; + blk->end_inst = inst_list[curr_begin]; + blk->cond = IR::Condition::Execnz; + blk->end_class = EndClass::Branch; + blk->branch_true = block; + } + // Reset scope begin. + curr_begin = -1; + } + // Mark a potential start of an exec scope. + if (is_open_scope(inst)) { + curr_begin = index; + } + } + } +} + +void CFG::EmitBlocks() { + for (auto it = labels.cbegin(); it != labels.cend(); ++it) { + const Label start = *it; + const auto next_it = std::next(it); + const bool is_last = (next_it == labels.cend()); + if (is_last) { + // Last label is special. + return; + } + // The end label is the start instruction of next block. + // The end instruction of this block is the previous one. + const Label end = *next_it; + const size_t end_index = GetIndex(end) - 1; + const auto& end_inst = inst_list[end_index]; + + // Insert block between the labels using the last instruction + // as an indicator for branching type. + Block* block = block_pool.Create(); + block->begin = start; + block->end = end; + block->begin_index = GetIndex(start); + block->end_index = end_index; + block->end_inst = end_inst; + block->cond = MakeCondition(end_inst); + blocks.insert(*block); + } +} + +void CFG::LinkBlocks() { + const auto get_block = [this](u32 address) { + auto it = blocks.find(address, Compare{}); + ASSERT_MSG(it != blocks.cend() && it->begin == address); + return &*it; + }; + + for (auto it = blocks.begin(); it != blocks.end(); it++) { + auto& block = *it; + const auto end_inst{block.end_inst}; + + // If the block doesn't end with a branch we simply + // need to link with the next block. + if (!end_inst.IsTerminateInstruction()) { + auto* next_block = get_block(block.end); + block.branch_true = next_block; + block.end_class = EndClass::Branch; + next_block->num_predecessors++; + continue; + } + + // Find the branch targets from the instruction and link the blocks. + // Note: Block end address is one instruction after end_inst. + const u32 branch_pc = block.end - end_inst.length; + u32 target_pc = 0; + if (end_inst.opcode == Opcode::S_SETPC_B64) { + auto tgt = ResolveSetPcTarget(inst_list, block.end_index, index_to_pc); + ASSERT_MSG(tgt, + "S_SETPC_B64 without a resolvable offset at PC {:#x} (Index {}): Involved " + "instructions not recognized or invalid pattern", + branch_pc, block.end_index); + target_pc = *tgt; + } else { + target_pc = end_inst.BranchTarget(branch_pc); + } + + if (end_inst.IsUnconditionalBranch()) { + auto* target_block = get_block(target_pc); + block.branch_true = target_block; + block.end_class = EndClass::Branch; + target_block->num_predecessors++; + } else if (end_inst.IsConditionalBranch()) { + auto* end_block = get_block(block.end); + block.end_class = EndClass::Branch; + if (target_pc != block.end) { + auto* target_block = get_block(target_pc); + block.branch_true = target_block; + block.branch_false = end_block; + target_block->num_predecessors++; + } else { + block.branch_true = end_block; + block.cond = IR::Condition::True; + } + end_block->num_predecessors++; + } else if (end_inst.opcode == Opcode::S_ENDPGM) { + block.end_class = EndClass::Exit; + } else { + UNREACHABLE(); + } + } +} + +void CFG::RemoveUnreachableBlocks() { + for (auto it = std::next(blocks.begin()); it != blocks.end();) { + if (it->num_predecessors == 0) { + LOG_WARNING(Render_Recompiler, "Removing unreachable block begin={:#x}", it->begin); + it = blocks.erase(it); + } else { + it++; + } + } +} + +std::string CFG::Dot() const { + int node_uid{0}; + + const auto name_of = [](const Block& block) { return fmt::format("\"{:#x}\"", block.begin); }; + + std::string dot{"digraph shader {\n"}; + dot += fmt::format("\tsubgraph cluster_{} {{\n", 0); + dot += fmt::format("\t\tnode [style=filled];\n"); + for (const Block& block : blocks) { + const std::string name{name_of(block)}; + const auto add_branch = [&](Block* branch, bool add_label) { + dot += fmt::format("\t\t{}->{}", name, name_of(*branch)); + if (add_label && block.cond != IR::Condition::True && + block.cond != IR::Condition::False) { + dot += fmt::format(" [label=\"{}\"]", block.cond); + } + dot += '\n'; + }; + dot += fmt::format("\t\t{};\n", name); + switch (block.end_class) { + case EndClass::Branch: + if (block.cond != IR::Condition::False) { + add_branch(block.branch_true, true); + } + if (block.cond != IR::Condition::True) { + add_branch(block.branch_false, false); + } + break; + case EndClass::Exit: + dot += fmt::format("\t\t{}->N{};\n", name, node_uid); + dot += + fmt::format("\t\tN{} [label=\"Exit\"][shape=square][style=stripped];\n", node_uid); + ++node_uid; + break; + } + } + dot += "\t\tlabel = \"main\";\n\t}\n"; + if (blocks.empty()) { + dot += "Start;\n"; + } else { + dot += fmt::format("\tStart -> {};\n", name_of(*blocks.begin())); + } + dot += fmt::format("\tStart [shape=diamond];\n"); + dot += "}\n"; + return dot; +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/control_flow_graph.h b/gpu/shadps4/shader_recompiler/frontend/control_flow_graph.h new file mode 100644 index 0000000..f7b44eb --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/control_flow_graph.h @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/object_pool.h" +#include "common/types.h" +#include "shader_recompiler/frontend/instruction.h" +#include "shader_recompiler/ir/condition.h" + +namespace Shader::IR { +class Block; +} + +namespace Shader::Gcn { + +using Hook = + boost::intrusive::set_base_hook>; + +enum class EndClass { + Branch, ///< Block ends with a (un)conditional branch. + Exit, ///< Block ends with an exit instruction. +}; + +/// A block represents a linear range of instructions. +struct Block : Hook { + [[nodiscard]] bool Contains(u32 pc) const noexcept; + + bool operator<(const Block& rhs) const noexcept { + return begin < rhs.begin; + } + + u32 begin; + u32 end; + u32 begin_index; + u32 end_index; + u32 num_predecessors{}; + IR::Condition cond{}; + GcnInst end_inst{}; + EndClass end_class{}; + Block* branch_true{}; + Block* branch_false{}; + IR::Block* ir_block{}; + bool is_dummy{}; +}; + +class CFG { + using Label = u32; + using BlockList = boost::intrusive::set; + using iterator = BlockList::iterator; + +public: + explicit CFG(Common::ObjectPool& block_pool, std::span inst_list); + + [[nodiscard]] iterator begin() { + return blocks.begin(); + } + [[nodiscard]] iterator end() { + return blocks.end(); + } + + [[nodiscard]] std::string Dot() const; + +private: + void EmitLabels(); + void EmitBlocks(); + void LinkBlocks(); + void SplitDivergenceScopes(); + void RemoveUnreachableBlocks(); + + void AddLabel(Label address) { + const auto it = std::ranges::find(labels, address); + if (it == labels.end()) { + labels.push_back(address); + } + } + + size_t GetIndex(Label label) { + if (label == 0) { + return 0ULL; + } + const auto it_index = std::ranges::lower_bound(index_to_pc, label); + ASSERT(it_index != index_to_pc.end() || label > index_to_pc.back()); + return std::distance(index_to_pc.begin(), it_index); + } + +public: + Common::ObjectPool& block_pool; + std::span inst_list; + std::vector index_to_pc; + boost::container::small_vector labels; + BlockList blocks; +}; + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/copy_shader.cpp b/gpu/shadps4/shader_recompiler/frontend/copy_shader.cpp new file mode 100644 index 0000000..3083607 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/copy_shader.cpp @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/copy_shader.h" +#include "shader_recompiler/frontend/decode.h" +#include "shader_recompiler/ir/attribute.h" + +namespace Shader { + +CopyShaderData ParseCopyShader(std::span code) { + Gcn::GcnCodeSlice code_slice{code.data(), code.data() + code.size()}; + Gcn::GcnDecodeContext decoder; + + constexpr u32 token_mov_vcchi = 0xBEEB03FF; + ASSERT_MSG(code[0] == token_mov_vcchi, "First instruction is not s_mov_b32 vcc_hi, #imm"); + + std::array offsets{}; + offsets.fill(-1); + + std::array sources{}; + sources.fill(-1); + + CopyShaderData data{}; + auto last_attr{IR::Attribute::Position0}; + while (!code_slice.atEnd()) { + auto inst = decoder.decodeInstruction(code_slice); + switch (inst.opcode) { + case Gcn::Opcode::S_LSHL_B32: { + ASSERT(inst.src[0].field == Gcn::OperandField::SignedConstIntPos && + inst.src[1].field == Gcn::OperandField::SignedConstIntPos); + sources[inst.dst[0].code] = + (inst.src[0].code - Gcn::OperandFieldRange::SignedConstIntPosMin + 1) + << (inst.src[1].code - Gcn::OperandFieldRange::SignedConstIntPosMin + 1); + break; + } + case Gcn::Opcode::S_MOVK_I32: { + sources[inst.dst[0].code] = inst.control.sopk.simm; + break; + } + case Gcn::Opcode::S_MOV_B32: { + sources[inst.dst[0].code] = inst.src[0].code; + break; + } + case Gcn::Opcode::S_ADDK_I32: { + sources[inst.dst[0].code] += inst.control.sopk.simm; + break; + } + case Gcn::Opcode::S_BFM_B32: { + ASSERT(inst.src[0].field == Gcn::OperandField::SignedConstIntPos && + inst.src[1].field == Gcn::OperandField::SignedConstIntPos); + const auto src0 = inst.src[0].code - Gcn::OperandFieldRange::SignedConstIntPosMin + 1; + const auto src1 = inst.src[1].code - Gcn::OperandFieldRange::SignedConstIntPosMin + 1; + sources[inst.dst[0].code] = ((1 << src0) - 1) << src1; + break; + } + case Gcn::Opcode::EXP: { + const auto& exp = inst.control.exp; + const IR::Attribute semantic = static_cast(exp.target); + for (int i = 0; i < inst.src_count; ++i) { + if ((exp.en & (1 << i)) == 0) { + continue; + } + const auto ofs = offsets[inst.src[i].code]; + if (ofs != -1) { + data.attr_map[ofs] = {semantic, i}; + if (semantic > last_attr) { + last_attr = semantic; + } + } + } + break; + } + case Gcn::Opcode::BUFFER_LOAD_DWORD: { + ASSERT_MSG(inst.src[1].code < offsets.size(), + "offsets array for geometry shaders is too short"); + offsets[inst.src[1].code] = inst.control.mubuf.offset; + if (inst.src[3].field != Gcn::OperandField::ConstZero) { + const u32 index = inst.src[3].code; + ASSERT(sources[index] != -1); + offsets[inst.src[1].code] += sources[index]; + } + data.num_comps++; + break; + } + default: + break; + } + } + + if (!IsPosition(last_attr)) { + data.num_attrs = static_cast(last_attr) - static_cast(IR::Attribute::Param0) + 1; + } + if (data.attr_map.size() > 1) { + const auto it = data.attr_map.begin(); + const u32 comp_stride = std::next(it)->first - it->first; + data.output_vertices = comp_stride / 64; + } + + return data; +} + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/frontend/copy_shader.h b/gpu/shadps4/shader_recompiler/frontend/copy_shader.h new file mode 100644 index 0000000..c416bde --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/copy_shader.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/types.h" +#include "shader_recompiler/ir/attribute.h" + +namespace Shader { + +struct CopyShaderData { + std::map> attr_map; + u32 num_attrs{0}; + u32 output_vertices{0}; + u32 num_comps{0}; +}; + +CopyShaderData ParseCopyShader(std::span code); + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/frontend/decode.cpp b/gpu/shadps4/shader_recompiler/frontend/decode.cpp new file mode 100644 index 0000000..c1d07c5 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/decode.cpp @@ -0,0 +1,1292 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "core/libraries/kernel/process.h" +#include "shader_recompiler/frontend/decode.h" + +#include + +namespace Shader::Gcn { + +namespace bit { +template +T extract(T value, u32 lst, u32 fst) { + return (value >> fst) & ~(~T(0) << (lst - fst + 1)); +} +} // namespace bit + +InstEncoding GetInstructionEncoding(u32 token) { + auto encoding = static_cast(token & (u32)EncodingMask::MASK_9bit); + switch (encoding) { + case InstEncoding::SOP1: + case InstEncoding::SOPP: + case InstEncoding::SOPC: + return encoding; + default: + break; + } + + encoding = static_cast(token & (u32)EncodingMask::MASK_7bit); + switch (encoding) { + case InstEncoding::VOP1: + case InstEncoding::VOPC: + return encoding; + default: + break; + } + + encoding = static_cast(token & (u32)EncodingMask::MASK_6bit); + switch (encoding) { + case InstEncoding::VOP3: + case InstEncoding::VOP3P: + case InstEncoding::EXP: + case InstEncoding::VINTRP: + case InstEncoding::DS: + case InstEncoding::MUBUF: + case InstEncoding::MTBUF: + case InstEncoding::MIMG: + return encoding; + default: + break; + } + + encoding = static_cast(token & (u32)EncodingMask::MASK_5bit); + switch (encoding) { + case InstEncoding::SMRD: + return encoding; + default: + break; + } + + encoding = static_cast(token & (u32)EncodingMask::MASK_4bit); + switch (encoding) { + case InstEncoding::SOPK: + return encoding; + default: + break; + } + + encoding = static_cast(token & (u32)EncodingMask::MASK_2bit); + switch (encoding) { + case InstEncoding::SOP2: + return encoding; + default: + break; + } + + encoding = static_cast(token & (u32)EncodingMask::MASK_1bit); + switch (encoding) { + case InstEncoding::VOP2: + return encoding; + default: + break; + } + + return InstEncoding::ILLEGAL; +} + +bool HasAdditionalLiteral(InstEncoding encoding, Opcode opcode) { + switch (encoding) { + case InstEncoding::SOPK: { + return opcode == Opcode::S_SETREG_IMM32_B32; + } + case InstEncoding::VOP2: { + return opcode == Opcode::V_MADMK_F32 || opcode == Opcode::V_MADAK_F32; + } + default: + return false; + } +} + +bool IsVop3BEncoding(Opcode opcode) { + return opcode == Opcode::V_ADD_I32 || opcode == Opcode::V_ADDC_U32 || + opcode == Opcode::V_SUB_I32 || opcode == Opcode::V_SUBB_U32 || + opcode == Opcode::V_SUBREV_I32 || opcode == Opcode::V_SUBBREV_U32 || + opcode == Opcode::V_DIV_SCALE_F32 || opcode == Opcode::V_DIV_SCALE_F64 || + opcode == Opcode::V_MAD_U64_U32 || opcode == Opcode::V_MAD_I64_I32; +} + +GcnInst GcnDecodeContext::decodeInstruction(GcnCodeSlice& code) { + const uint32_t token = code.at(0); + + InstEncoding encoding = GetInstructionEncoding(token); + ASSERT_MSG(encoding != InstEncoding::ILLEGAL, "illegal encoding: {:#x}", token); + uint32_t encodingLen = getEncodingLength(encoding); + + // Clear the instruction + m_instruction = GcnInst(); + + // Decode + if (encodingLen == sizeof(uint32_t)) { + decodeInstruction32(encoding, code); + } else { + decodeInstruction64(encoding, code); + } + + // Update instruction meta info. + updateInstructionMeta(encoding); + + // Detect literal constant. Only 32 bits instructions may have literal constant. + // Note: Literal constant decode must be performed after meta info updated. + if (encodingLen == sizeof(u32)) { + decodeLiteralConstant(encoding, code); + decodeSubDwordAddressing(encoding, code); + decodeDataParallelPrimitive(encoding, code); + } + + repairOperandType(); + return m_instruction; +} + +uint32_t GcnDecodeContext::getEncodingLength(InstEncoding encoding) { + uint32_t instLength = 0; + + switch (encoding) { + case InstEncoding::SOP1: + case InstEncoding::SOPP: + case InstEncoding::SOPC: + case InstEncoding::SOPK: + case InstEncoding::SOP2: + case InstEncoding::VOP1: + case InstEncoding::VOPC: + case InstEncoding::VOP2: + case InstEncoding::SMRD: + case InstEncoding::VINTRP: + instLength = sizeof(uint32_t); + break; + + case InstEncoding::VOP3: + case InstEncoding::VOP3P: + case InstEncoding::MUBUF: + case InstEncoding::MTBUF: + case InstEncoding::MIMG: + case InstEncoding::DS: + case InstEncoding::EXP: + instLength = sizeof(uint64_t); + break; + default: + break; + } + return instLength; +} + +uint32_t GcnDecodeContext::getOpMapOffset(InstEncoding encoding) { + uint32_t offset = 0; + switch (encoding) { + case InstEncoding::SOP1: + offset = (uint32_t)OpcodeMap::OP_MAP_SOP1; + break; + case InstEncoding::SOPP: + offset = (uint32_t)OpcodeMap::OP_MAP_SOPP; + break; + case InstEncoding::SOPC: + offset = (uint32_t)OpcodeMap::OP_MAP_SOPC; + break; + case InstEncoding::VOP1: + offset = (uint32_t)OpcodeMap::OP_MAP_VOP1; + break; + case InstEncoding::VOPC: + offset = (uint32_t)OpcodeMap::OP_MAP_VOPC; + break; + case InstEncoding::VOP3: + offset = (uint32_t)OpcodeMap::OP_MAP_VOP3; + break; + case InstEncoding::VOP3P: + offset = (uint32_t)OpcodeMap::OP_MAP_VOP3P; + break; + case InstEncoding::EXP: + offset = (uint32_t)OpcodeMap::OP_MAP_EXP; + break; + case InstEncoding::VINTRP: + offset = (uint32_t)OpcodeMap::OP_MAP_VINTRP; + break; + case InstEncoding::DS: + offset = (uint32_t)OpcodeMap::OP_MAP_DS; + break; + case InstEncoding::MUBUF: + offset = (uint32_t)OpcodeMap::OP_MAP_MUBUF; + break; + case InstEncoding::MTBUF: + offset = (uint32_t)OpcodeMap::OP_MAP_MTBUF; + break; + case InstEncoding::MIMG: + offset = (uint32_t)OpcodeMap::OP_MAP_MIMG; + break; + case InstEncoding::SMRD: + offset = (uint32_t)OpcodeMap::OP_MAP_SMRD; + break; + case InstEncoding::SOPK: + offset = (uint32_t)OpcodeMap::OP_MAP_SOPK; + break; + case InstEncoding::SOP2: + offset = (uint32_t)OpcodeMap::OP_MAP_SOP2; + break; + case InstEncoding::VOP2: + offset = (uint32_t)OpcodeMap::OP_MAP_VOP2; + break; + default: + break; + } + return offset; +} + +uint32_t GcnDecodeContext::mapEncodingOp(InstEncoding encoding, Opcode opcode) { + // Map from uniform opcode to encoding specific opcode. + uint32_t encodingOp = 0; + if (encoding == InstEncoding::VOP3) { + if (opcode >= Opcode::V_CMP_F_F32 && opcode <= Opcode::V_CMPX_T_U64) { + uint32_t op = + static_cast(opcode) - static_cast(OpcodeMap::OP_MAP_VOPC); + encodingOp = op + static_cast(OpMapVOP3VOPX::VOP3_TO_VOPC); + } else if (opcode >= Opcode::V_CNDMASK_B32 && opcode <= Opcode::V_LDEXP_F16) { + uint32_t op = + static_cast(opcode) - static_cast(OpcodeMap::OP_MAP_VOP2); + encodingOp = op + static_cast(OpMapVOP3VOPX::VOP3_TO_VOP2); + } else if (opcode >= Opcode::V_NOP && opcode <= Opcode::V_SQRT_F16) { + uint32_t op = + static_cast(opcode) - static_cast(OpcodeMap::OP_MAP_VOP1); + encodingOp = op + static_cast(OpMapVOP3VOPX::VOP3_TO_VOP1); + } else { + encodingOp = + static_cast(opcode) - static_cast(OpcodeMap::OP_MAP_VOP3); + } + } else { + uint32_t mapOffset = getOpMapOffset(encoding); + encodingOp = static_cast(opcode) - mapOffset; + } + + return encodingOp; +} + +void GcnDecodeContext::updateInstructionMeta(InstEncoding encoding) { + uint32_t encodingOp = mapEncodingOp(encoding, m_instruction.opcode); + InstFormat instFormat = InstructionFormat(encoding, encodingOp); + + ASSERT_MSG(instFormat.src_type != ScalarType::Undefined && + instFormat.dst_type != ScalarType::Undefined, + "Instruction format table incomplete for opcode {} ({}, encoding = 0x{:x})", + magic_enum::enum_name(m_instruction.opcode), u32(m_instruction.opcode), + u32(encoding)); + + m_instruction.inst_class = instFormat.inst_class; + m_instruction.category = instFormat.inst_category; + m_instruction.encoding = encoding; + m_instruction.src_count = instFormat.src_count; + m_instruction.length = getEncodingLength(encoding); + + // Update src operand scalar type. + auto setOperandType = [&instFormat](InstOperand& src) { + // Only update uninitialized numeric type. + if (src.type == ScalarType::Undefined) { + src.type = instFormat.src_type; + } + }; + + std::for_each_n(m_instruction.src.begin(), m_instruction.src_count, setOperandType); + + // Update dst operand scalar type. + switch (m_instruction.dst_count) { + case 2: { + if (m_instruction.dst[1].type == ScalarType::Undefined) { + // Only VOP3B has an additional sdst operand, + // and it must be Uint64 + m_instruction.dst[1].type = ScalarType::Uint64; + } + } + [[fallthrough]]; + case 1: { + if (m_instruction.dst[0].type == ScalarType::Undefined) { + m_instruction.dst[0].type = instFormat.dst_type; + } + } + } +} + +void GcnDecodeContext::repairOperandType() { + // Some instructions' operand type is not uniform, + // it's best to change the instruction table's format and fix them there, + // but it's a hard work. + // We fix them here. + switch (m_instruction.opcode) { + case Opcode::V_MAD_U64_U32: + m_instruction.src[2].type = ScalarType::Uint64; + break; + case Opcode::V_MAD_I64_I32: + m_instruction.src[2].type = ScalarType::Sint64; + break; + case Opcode::V_ADDC_U32: + m_instruction.src[2].type = ScalarType::Uint64; + break; + case Opcode::IMAGE_GATHER4_C: + case Opcode::IMAGE_GATHER4_C_O: + m_instruction.src[0].type = ScalarType::Any; + break; + default: + break; + } +} + +OperandField GcnDecodeContext::getOperandField(uint32_t code) { + OperandField field = {}; + if (code >= ScalarGPRMin && code <= ScalarGPRMax) { + field = OperandField::ScalarGPR; + } else if (code >= SignedConstIntPosMin && code <= SignedConstIntPosMax) { + field = OperandField::SignedConstIntPos; + } else if (code >= SignedConstIntNegMin && code <= SignedConstIntNegMax) { + field = OperandField::SignedConstIntNeg; + } else if (code >= VectorGPRMin && code <= VectorGPRMax) { + field = OperandField::VectorGPR; + } else { + field = static_cast(code); + } + return field; +} + +void GcnDecodeContext::decodeInstruction32(InstEncoding encoding, GcnCodeSlice& code) { + u32 hexInstruction = code.readu32(); + switch (encoding) { + case InstEncoding::SOP1: + decodeInstructionSOP1(hexInstruction); + break; + case InstEncoding::SOPP: + decodeInstructionSOPP(hexInstruction); + break; + case InstEncoding::SOPC: + decodeInstructionSOPC(hexInstruction); + break; + case InstEncoding::SOPK: + decodeInstructionSOPK(hexInstruction); + break; + case InstEncoding::SOP2: + decodeInstructionSOP2(hexInstruction); + break; + case InstEncoding::VOP1: + decodeInstructionVOP1(hexInstruction); + break; + case InstEncoding::VOPC: + decodeInstructionVOPC(hexInstruction); + break; + case InstEncoding::VOP2: + decodeInstructionVOP2(hexInstruction); + break; + case InstEncoding::SMRD: + decodeInstructionSMRD(hexInstruction); + break; + case InstEncoding::VINTRP: + decodeInstructionVINTRP(hexInstruction); + break; + default: + break; + } +} + +void GcnDecodeContext::decodeInstruction64(InstEncoding encoding, GcnCodeSlice& code) { + uint64_t hexInstruction = code.readu64(); + switch (encoding) { + case InstEncoding::VOP3: + decodeInstructionVOP3(hexInstruction); + break; + case InstEncoding::VOP3P: + decodeInstructionVOP3P(hexInstruction); + break; + case InstEncoding::MUBUF: + decodeInstructionMUBUF(hexInstruction); + break; + case InstEncoding::MTBUF: + decodeInstructionMTBUF(hexInstruction); + break; + case InstEncoding::MIMG: + decodeInstructionMIMG(hexInstruction); + break; + case InstEncoding::DS: + decodeInstructionDS(hexInstruction); + break; + case InstEncoding::EXP: + decodeInstructionEXP(hexInstruction); + break; + default: + break; + } +} + +void GcnDecodeContext::decodeLiteralConstant(InstEncoding encoding, GcnCodeSlice& code) { + if (HasAdditionalLiteral(encoding, m_instruction.opcode)) { + u32 encoding_op = mapEncodingOp(encoding, m_instruction.opcode); + InstFormat instFormat = InstructionFormat(encoding, encoding_op); + m_instruction.src[m_instruction.src_count].field = OperandField::LiteralConst; + m_instruction.src[m_instruction.src_count].type = instFormat.src_type; + m_instruction.src[m_instruction.src_count].code = code.readu32(); + ++m_instruction.src_count; + m_instruction.length += sizeof(u32); + return; + } + + // Find if the instruction contains a literal constant + const auto it = std::ranges::find_if(m_instruction.src, [](InstOperand& src) { + return src.field == OperandField::LiteralConst; + }); + if (it != m_instruction.src.end()) { + it->code = code.readu32(); + m_instruction.length += sizeof(u32); + } +} + +void GcnDecodeContext::decodeSubDwordAddressing(InstEncoding encoding, GcnCodeSlice& code) { + // Find if the instruction contains SDWA (it's legal only as src0) + if (m_instruction.src[0].field == OperandField::Sdwa) { + m_instruction.src[0].code = code.readu32(); + m_instruction.length += sizeof(u32); + + if (encoding == InstEncoding::VOPC) { + SdwaVopc sdwa = *reinterpret_cast(&m_instruction.src[0].code); + + m_instruction.src[0].field = + sdwa.s0 == 0 ? OperandField::VectorGPR : getOperandField(sdwa.src0); + m_instruction.src[0].code = sdwa.src0; + m_instruction.src[0].sdwa_sel = SdwaSelector(sdwa.src0_sel); + + m_instruction.src[0].input_modifier.neg = sdwa.src0_neg; + m_instruction.src[0].input_modifier.abs = sdwa.src0_abs; + m_instruction.src[0].input_modifier.sext = sdwa.src0_sext; + + m_instruction.src[1].field = + sdwa.s1 == 0 ? OperandField::VectorGPR : getOperandField(m_instruction.src[1].code); + m_instruction.src[1].sdwa_sel = SdwaSelector(sdwa.src1_sel); + + m_instruction.src[1].input_modifier.neg = sdwa.src1_neg; + m_instruction.src[1].input_modifier.abs = sdwa.src1_abs; + m_instruction.src[1].input_modifier.sext = sdwa.src1_sext; + + m_instruction.dst[0].field = sdwa.sd ? OperandField::ScalarGPR : OperandField::VccLo; + m_instruction.dst[0].code = sdwa.sdst; + + } else if (encoding == InstEncoding::VOP1 || encoding == InstEncoding::VOP2) { + SdwaVop12 sdwa = *reinterpret_cast(&m_instruction.src[0].code); + + m_instruction.src[0].field = + sdwa.s0 == 0 ? OperandField::VectorGPR : getOperandField(sdwa.src0); + m_instruction.src[0].code = sdwa.src0; + m_instruction.src[0].sdwa_sel = SdwaSelector(sdwa.src0_sel); + + m_instruction.src[0].input_modifier.neg = sdwa.src0_neg; + m_instruction.src[0].input_modifier.abs = sdwa.src0_abs; + m_instruction.src[0].input_modifier.sext = sdwa.src0_sext; + + m_instruction.src[1].field = + sdwa.s1 == 0 ? OperandField::VectorGPR : getOperandField(m_instruction.src[1].code); + m_instruction.src[1].sdwa_sel = SdwaSelector(sdwa.src1_sel); + + m_instruction.src[1].input_modifier.neg = sdwa.src1_neg; + m_instruction.src[1].input_modifier.abs = sdwa.src1_abs; + m_instruction.src[1].input_modifier.sext = sdwa.src1_sext; + + m_instruction.dst[0].sdwa_sel = SdwaSelector(sdwa.dst_sel); + m_instruction.dst[0].sdwa_dst = SdwaDstUnused(sdwa.dst_u); + m_instruction.dst[0].output_modifier.clamp = sdwa.clamp; + + switch (sdwa.omod) { + case 0: + m_instruction.dst[0].output_modifier.multiplier = 0.f; + break; + case 1: + m_instruction.dst[0].output_modifier.multiplier = 2.0f; + break; + case 2: + m_instruction.dst[0].output_modifier.multiplier = 4.0f; + break; + case 3: + m_instruction.dst[0].output_modifier.multiplier = 0.5f; + break; + } + } else { + LOG_WARNING(Render_Recompiler, "illegal instruction: SDWA used outside VOP1/VOP2/VOPC"); + } + } +} + +void GcnDecodeContext::decodeDataParallelPrimitive(InstEncoding encoding, GcnCodeSlice& code) { + // Find if the instruction contains DPP + if (m_instruction.src[0].field == OperandField::Dpp) { + m_instruction.src[0].code = code.readu32(); + m_instruction.length += sizeof(u32); + + Dpp dpp = *reinterpret_cast(&m_instruction.src[0].code); + + m_instruction.src[0].field = OperandField::VectorGPR; + m_instruction.src[0].code = dpp.src0; + + if (dpp.src0_abs) { + m_instruction.src[0].input_modifier.abs = true; + } + if (dpp.src0_neg) { + m_instruction.src[0].input_modifier.neg = true; + } + if (dpp.src1_abs) { + m_instruction.src[1].input_modifier.abs = true; + } + if (dpp.src1_neg) { + m_instruction.src[1].input_modifier.neg = true; + } + + auto op = dpp.GetOperation(); + LOG_ERROR( + Render_Recompiler, + "unhandled DPP operation: {} ({:#x}), value {}, bc {}, row_mask {:#b}, bank_mask {:#b}", + magic_enum::enum_name(op.op), u32(op.op), op.value, bool(dpp.bc), u8(dpp.row_mask), + u8(dpp.bank_mask)); + + m_instruction.src[0].dpp = op; + } +} + +void GcnDecodeContext::decodeInstructionSOP1(u32 hexInstruction) { + u32 ssrc0 = bit::extract(hexInstruction, 7, 0); + u32 op = bit::extract(hexInstruction, 15, 8); + u32 sdst = bit::extract(hexInstruction, 22, 16); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_SOP1)); + + m_instruction.src[0].field = getOperandField(ssrc0); + m_instruction.src[0].code = ssrc0; + m_instruction.dst[0].field = getOperandField(sdst); + m_instruction.dst[0].code = sdst; + m_instruction.dst_count = 1; +} + +void GcnDecodeContext::decodeInstructionSOPP(u32 hexInstruction) { + u32 op = bit::extract(hexInstruction, 22, 16); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_SOPP)); + + m_instruction.control.sopp = *reinterpret_cast(&hexInstruction); +} + +void GcnDecodeContext::decodeInstructionSOPC(u32 hexInstruction) { + u32 ssrc0 = bit::extract(hexInstruction, 7, 0); + u32 ssrc1 = bit::extract(hexInstruction, 15, 8); + u32 op = bit::extract(hexInstruction, 22, 16); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_SOPC)); + + m_instruction.src[0].field = getOperandField(ssrc0); + m_instruction.src[0].code = ssrc0; + m_instruction.src[1].field = getOperandField(ssrc1); + m_instruction.src[1].code = ssrc1; +} + +void GcnDecodeContext::decodeInstructionSOPK(u32 hexInstruction) { + u32 sdst = bit::extract(hexInstruction, 22, 16); + u32 op = bit::extract(hexInstruction, 27, 23); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_SOPK)); + + m_instruction.dst[0].field = getOperandField(sdst); + m_instruction.dst[0].code = sdst; + m_instruction.dst_count = 1; + + m_instruction.control.sopk = *reinterpret_cast(&hexInstruction); +} + +void GcnDecodeContext::decodeInstructionSOP2(u32 hexInstruction) { + u32 ssrc0 = bit::extract(hexInstruction, 7, 0); + u32 ssrc1 = bit::extract(hexInstruction, 15, 8); + u32 sdst = bit::extract(hexInstruction, 22, 16); + u32 op = bit::extract(hexInstruction, 29, 23); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_SOP2)); + + m_instruction.src[0].field = getOperandField(ssrc0); + m_instruction.src[0].code = ssrc0; + m_instruction.src[1].field = getOperandField(ssrc1); + m_instruction.src[1].code = ssrc1; + m_instruction.dst[0].field = getOperandField(sdst); + m_instruction.dst[0].code = sdst; + m_instruction.dst_count = 1; +} + +void GcnDecodeContext::decodeInstructionVOP1(u32 hexInstruction) { + u32 src0 = bit::extract(hexInstruction, 8, 0); + u32 op = bit::extract(hexInstruction, 16, 9); + u32 vdst = bit::extract(hexInstruction, 24, 17); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_VOP1)); + + m_instruction.src[0].field = getOperandField(src0); + m_instruction.src[0].code = + m_instruction.src[0].field == OperandField::VectorGPR ? src0 - VectorGPRMin : src0; + m_instruction.dst[0].field = OperandField::VectorGPR; + m_instruction.dst[0].code = vdst; + m_instruction.dst_count = 1; + + OpcodeVOP1 vop1Op = static_cast(op); + if (vop1Op == OpcodeVOP1::V_READFIRSTLANE_B32) { + m_instruction.dst[0].field = getOperandField(vdst); + m_instruction.dst[0].type = ScalarType::Uint32; + } +} + +void GcnDecodeContext::decodeInstructionVOPC(u32 hexInstruction) { + u32 src0 = bit::extract(hexInstruction, 8, 0); + u32 vsrc1 = bit::extract(hexInstruction, 16, 9); + u32 op = bit::extract(hexInstruction, 24, 17); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_VOPC)); + + m_instruction.src[0].field = getOperandField(src0); + m_instruction.src[0].code = + m_instruction.src[0].field == OperandField::VectorGPR ? src0 - VectorGPRMin : src0; + m_instruction.src[1].field = OperandField::VectorGPR; + m_instruction.src[1].code = vsrc1; + // VOPC dst is forced to VCC. + // In order to be unified with VOP3 encoding, + // we store it to dst[1] + m_instruction.dst[1].field = OperandField::VccLo; + m_instruction.dst[1].type = ScalarType::Uint64; + m_instruction.dst[1].code = static_cast(OperandField::VccLo); +} + +void GcnDecodeContext::decodeInstructionVOP2(u32 hexInstruction) { + u32 src0 = bit::extract(hexInstruction, 8, 0); + u32 vsrc1 = bit::extract(hexInstruction, 16, 9); + u32 vdst = bit::extract(hexInstruction, 24, 17); + u32 op = bit::extract(hexInstruction, 30, 25); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_VOP2)); + + m_instruction.src[0].field = getOperandField(src0); + m_instruction.src[0].code = + m_instruction.src[0].field == OperandField::VectorGPR ? src0 - VectorGPRMin : src0; + m_instruction.src[1].field = OperandField::VectorGPR; + m_instruction.src[1].code = vsrc1; + m_instruction.dst[0].field = OperandField::VectorGPR; + m_instruction.dst[0].code = vdst; + m_instruction.dst_count = 1; + + OpcodeVOP2 vop2Op = static_cast(op); + if (vop2Op == OpcodeVOP2::V_READLANE_B32) { + // vsrc1 is scalar for lane instructions + m_instruction.src[1].field = getOperandField(vsrc1); + // dst is sgpr + m_instruction.dst[0].field = getOperandField(vdst); + m_instruction.dst[0].type = ScalarType::Uint32; + } else if (vop2Op == OpcodeVOP2::V_WRITELANE_B32) { + m_instruction.src[1].field = getOperandField(vsrc1); + // dst is vgpr, as normal + } else if (IsVop3BEncoding(m_instruction.opcode)) { + m_instruction.dst[1].field = OperandField::VccLo; + m_instruction.dst[1].type = ScalarType::Uint64; + m_instruction.dst[1].code = static_cast(OperandField::VccLo); + } +} + +void GcnDecodeContext::decodeInstructionSMRD(u32 hexInstruction) { + u32 sbase = bit::extract(hexInstruction, 14, 9); + u32 sdst = bit::extract(hexInstruction, 21, 15); + u32 op = bit::extract(hexInstruction, 26, 22); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_SMRD)); + + m_instruction.src[0].field = OperandField::ScalarGPR; + m_instruction.src[0].code = sbase; + m_instruction.dst[0].field = OperandField::ScalarGPR; + m_instruction.dst[0].code = sdst; + m_instruction.dst_count = 1; + + m_instruction.control.smrd = *reinterpret_cast(&hexInstruction); + + if (op <= static_cast(OpcodeSMRD::S_LOAD_DWORDX16)) { + m_instruction.control.smrd.count = 1 << op; + } else if (op >= static_cast(OpcodeSMRD::S_BUFFER_LOAD_DWORD) && + op <= static_cast(OpcodeSMRD::S_BUFFER_LOAD_DWORDX16)) { + m_instruction.control.smrd.count = 1 << (op - 8); + } + + if (m_instruction.control.smrd.imm == 0) { + u32 code = m_instruction.control.smrd.offset; + m_instruction.src[1].field = getOperandField(code); + m_instruction.src[1].type = ScalarType::Uint32; + m_instruction.src[1].code = code; + } +} + +void GcnDecodeContext::decodeInstructionVINTRP(u32 hexInstruction) { + u32 vsrc = bit::extract(hexInstruction, 7, 0); + u32 op = bit::extract(hexInstruction, 17, 16); + u32 vdst = bit::extract(hexInstruction, 25, 18); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_VINTRP)); + + m_instruction.src[0].field = OperandField::VectorGPR; + m_instruction.src[0].code = vsrc; + m_instruction.dst[0].field = OperandField::VectorGPR; + m_instruction.dst[0].code = vdst; + m_instruction.dst_count = 1; + + m_instruction.control.vintrp = *reinterpret_cast(&hexInstruction); +} + +void GcnDecodeContext::decodeInstructionVOP3(uint64_t hexInstruction) { + u32 vdst = bit::extract(hexInstruction, 7, 0); + u32 sdst = bit::extract(hexInstruction, 14, 8); // For VOP3B + u32 op = bit::extract(hexInstruction, 25, 17); + u32 op_msb = bit::extract(hexInstruction, 16, 16); + op = op + op_msb * (1 << 9); + u32 src0 = bit::extract(hexInstruction, 40, 32); + u32 src1 = bit::extract(hexInstruction, 49, 41); + u32 src2 = bit::extract(hexInstruction, 58, 50); + + if (op >= static_cast(OpcodeVOP3::V_CMP_F_F32) && + op <= static_cast(OpcodeVOP3::V_CMPX_T_U64)) { + // Map from VOP3 to VOPC + u32 vopcOp = op - static_cast(OpMapVOP3VOPX::VOP3_TO_VOPC); + m_instruction.opcode = + static_cast(vopcOp + static_cast(OpcodeMap::OP_MAP_VOPC)); + } else if (op >= static_cast(OpcodeVOP3::V_CNDMASK_B32) && + op <= static_cast(OpcodeVOP3::V_LDEXP_F16)) { + // Map from VOP3 to VOP2 + u32 vop2Op = op - static_cast(OpMapVOP3VOPX::VOP3_TO_VOP2); + m_instruction.opcode = + static_cast(vop2Op + static_cast(OpcodeMap::OP_MAP_VOP2)); + } else if (op >= static_cast(OpcodeVOP3::V_NOP) && + op <= static_cast(OpcodeVOP3::V_SQRT_F16)) { + // Map from VOP3 to VOP1 + u32 vop1Op = op - static_cast(OpMapVOP3VOPX::VOP3_TO_VOP1); + m_instruction.opcode = + static_cast(vop1Op + static_cast(OpcodeMap::OP_MAP_VOP1)); + } else { + // VOP3 encoding, do not map. + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_VOP3)); + } + + m_instruction.src[0].field = getOperandField(src0); + m_instruction.src[0].code = + m_instruction.src[0].field == OperandField::VectorGPR ? src0 - VectorGPRMin : src0; + m_instruction.src[1].field = getOperandField(src1); + m_instruction.src[1].code = + m_instruction.src[1].field == OperandField::VectorGPR ? src1 - VectorGPRMin : src1; + m_instruction.src[2].field = getOperandField(src2); + m_instruction.src[2].code = + m_instruction.src[2].field == OperandField::VectorGPR ? src2 - VectorGPRMin : src2; + m_instruction.dst[0].field = OperandField::VectorGPR; + m_instruction.dst[0].code = vdst; + + OpcodeVOP3 vop3Op = static_cast(op); + if (IsVop3BEncoding(m_instruction.opcode)) { + m_instruction.dst[1].field = getOperandField(sdst); + m_instruction.dst[1].type = ScalarType::Uint64; + m_instruction.dst[1].code = sdst; + } else { + if (vop3Op >= OpcodeVOP3::V_CMP_F_F32 && vop3Op <= OpcodeVOP3::V_CMPX_T_U64) { + m_instruction.dst[1].field = getOperandField(vdst); + m_instruction.dst[1].type = ScalarType::Uint64; + m_instruction.dst[1].code = vdst; + } else if (vop3Op == OpcodeVOP3::V_READLANE_B32 || + vop3Op == OpcodeVOP3::V_READFIRSTLANE_B32) { + m_instruction.dst[0].field = getOperandField(vdst); + m_instruction.dst[0].type = ScalarType::Uint32; + // WRITELANE can be decoded like other VOP3's + } + } + + if (op >= static_cast(OpcodeVOP3::V_ADD_I32) && + op <= static_cast(OpcodeVOP3::V_DIV_SCALE_F64)) { + // VOP3B has a sdst operand. + m_instruction.dst_count = 2; + } else { + m_instruction.dst_count = 1; + } + + m_instruction.control.vop3 = *reinterpret_cast(&hexInstruction); + + // update input modifier + auto& control = m_instruction.control.vop3; + + // update output modifier + auto& outputMod = m_instruction.dst[0].output_modifier; + + if (!IsVop3BEncoding(m_instruction.opcode)) { + for (u32 i = 0; i != 3; ++i) { + if (control.abs & (1u << i)) { + m_instruction.src[i].input_modifier.abs = true; + } + } + outputMod.clamp = static_cast(control.clmp); + } + for (u32 i = 0; i != 3; ++i) { + if (control.neg & (1u << i)) { + m_instruction.src[i].input_modifier.neg = true; + } + + if (control.op_sel & (1u << i)) { + m_instruction.src[i].op_sel.op_sel = true; + } + } + + m_instruction.dst[0].op_sel.op_sel = control.op_sel & (1u << 3); + + switch (control.omod) { + case 0: + outputMod.multiplier = 0.f; + break; + case 1: + outputMod.multiplier = 2.0f; + break; + case 2: + outputMod.multiplier = 4.0f; + break; + case 3: + outputMod.multiplier = 0.5f; + break; + } +} + +void GcnDecodeContext::decodeInstructionVOP3P(uint64_t hexInstruction) { + u32 vdst = bit::extract(hexInstruction, 7, 0); + u32 op = bit::extract(hexInstruction, 22, 16); + u32 src0 = bit::extract(hexInstruction, 40, 32); + u32 src1 = bit::extract(hexInstruction, 49, 41); + u32 src2 = bit::extract(hexInstruction, 58, 50); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_VOP3P)); + + m_instruction.src[0].field = getOperandField(src0); + m_instruction.src[0].code = + m_instruction.src[0].field == OperandField::VectorGPR ? src0 - VectorGPRMin : src0; + m_instruction.src[1].field = getOperandField(src1); + m_instruction.src[1].code = + m_instruction.src[1].field == OperandField::VectorGPR ? src1 - VectorGPRMin : src1; + m_instruction.src[2].field = getOperandField(src2); + m_instruction.src[2].code = + m_instruction.src[2].field == OperandField::VectorGPR ? src2 - VectorGPRMin : src2; + m_instruction.dst[0].field = OperandField::VectorGPR; + m_instruction.dst[0].code = vdst; + + m_instruction.control.vop3p = *reinterpret_cast(&hexInstruction); + + // update input modifier + auto& control = m_instruction.control.vop3p; + for (u32 i = 0; i != 3; ++i) { + if (control.neg & (1u << i)) { + m_instruction.src[i].input_modifier.neg = true; + } + + if (control.neg_hi & (1u << i)) { + m_instruction.src[i].input_modifier.neg_hi = true; + } + + if (control.op_sel & (1u << i)) { + m_instruction.src[i].op_sel.op_sel = true; + } + + if (control.get_op_sel_hi(i)) { + m_instruction.src[i].op_sel.op_sel_hi = true; + } + } + + // update output modifier + auto& outputMod = m_instruction.dst[0].output_modifier; + + outputMod.clamp = static_cast(control.clamp); +} + +void GcnDecodeContext::decodeInstructionMUBUF(uint64_t hexInstruction) { + u32 op = bit::extract(hexInstruction, 24, 18); + u32 vaddr = bit::extract(hexInstruction, 39, 32); + u32 vdata = bit::extract(hexInstruction, 47, 40); + u32 srsrc = bit::extract(hexInstruction, 52, 48); + u32 soffset = bit::extract(hexInstruction, 63, 56); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_MUBUF)); + + m_instruction.src[0].field = OperandField::VectorGPR; + m_instruction.src[0].code = vaddr; + m_instruction.src[1].field = OperandField::VectorGPR; + m_instruction.src[1].code = vdata; + m_instruction.src[2].field = OperandField::ScalarGPR; + m_instruction.src[2].code = srsrc; + m_instruction.src[3].field = getOperandField(soffset); + m_instruction.src[3].code = soffset; + + m_instruction.control.mubuf = *reinterpret_cast(&hexInstruction); + + if (op >= static_cast(OpcodeMUBUF::BUFFER_LOAD_FORMAT_X) && + op <= static_cast(OpcodeMUBUF::BUFFER_LOAD_FORMAT_XYZW)) { + m_instruction.control.mubuf.count = op + 1; + m_instruction.control.mubuf.size = (op + 1) * sizeof(u32); + } else if (op >= static_cast(OpcodeMUBUF::BUFFER_STORE_FORMAT_X) && + op <= static_cast(OpcodeMUBUF::BUFFER_STORE_FORMAT_XYZW)) { + m_instruction.control.mubuf.count = op - 3; + m_instruction.control.mubuf.size = (op - 3) * sizeof(u32); + } else if (op >= static_cast(OpcodeMUBUF::BUFFER_LOAD_DWORD) && + op <= static_cast(OpcodeMUBUF::BUFFER_LOAD_DWORDX3)) { + m_instruction.control.mubuf.count = + op == static_cast(OpcodeMUBUF::BUFFER_LOAD_DWORDX3) ? 3 : 1 << (op - 12); + m_instruction.control.mubuf.size = m_instruction.control.mubuf.count * sizeof(u32); + } else if (op >= static_cast(OpcodeMUBUF::BUFFER_STORE_DWORD) && + op <= static_cast(OpcodeMUBUF::BUFFER_STORE_DWORDX3)) { + m_instruction.control.mubuf.count = + op == static_cast(OpcodeMUBUF::BUFFER_STORE_DWORDX3) ? 3 : 1 << (op - 28); + m_instruction.control.mubuf.size = m_instruction.control.mubuf.count * sizeof(u32); + } else if (op >= static_cast(OpcodeMUBUF::BUFFER_LOAD_UBYTE) && + op <= static_cast(OpcodeMUBUF::BUFFER_LOAD_SSHORT)) { + m_instruction.control.mubuf.count = 1; + if (op >= static_cast(OpcodeMUBUF::BUFFER_LOAD_UBYTE) && + op <= static_cast(OpcodeMUBUF::BUFFER_LOAD_SBYTE)) { + m_instruction.control.mubuf.size = 1; + } else { + m_instruction.control.mubuf.size = 2; + } + } else if (op >= static_cast(OpcodeMUBUF::BUFFER_STORE_BYTE) && + op <= static_cast(OpcodeMUBUF::BUFFER_STORE_SHORT)) { + m_instruction.control.mubuf.count = 1; + if (op == static_cast(OpcodeMUBUF::BUFFER_STORE_BYTE)) { + m_instruction.control.mubuf.size = 1; + } else { + m_instruction.control.mubuf.size = 2; + } + } else if (op >= static_cast(OpcodeMUBUF::BUFFER_ATOMIC_SWAP) && + op <= static_cast(OpcodeMUBUF::BUFFER_ATOMIC_FMAX)) { + m_instruction.control.mubuf.count = 1; + m_instruction.control.mubuf.size = sizeof(u32); + } else if (op >= static_cast(OpcodeMUBUF::BUFFER_ATOMIC_SWAP_X2) && + op <= static_cast(OpcodeMUBUF::BUFFER_ATOMIC_FMAX_X2)) { + m_instruction.control.mubuf.count = 2; + m_instruction.control.mubuf.size = sizeof(u32) * 2; + } +} + +void GcnDecodeContext::decodeInstructionMTBUF(uint64_t hexInstruction) { + u32 op = bit::extract(hexInstruction, 18, 16); + u32 vaddr = bit::extract(hexInstruction, 39, 32); + u32 vdata = bit::extract(hexInstruction, 47, 40); + u32 srsrc = bit::extract(hexInstruction, 52, 48); + u32 soffset = bit::extract(hexInstruction, 63, 56); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_MTBUF)); + + m_instruction.src[0].field = OperandField::VectorGPR; + m_instruction.src[0].code = vaddr; + m_instruction.src[1].field = OperandField::VectorGPR; + m_instruction.src[1].code = vdata; + m_instruction.src[2].field = OperandField::ScalarGPR; + m_instruction.src[2].code = srsrc; + m_instruction.src[3].field = getOperandField(soffset); + m_instruction.src[3].code = soffset; + + m_instruction.control.mtbuf = *reinterpret_cast(&hexInstruction); + + if (op >= static_cast(OpcodeMTBUF::TBUFFER_LOAD_FORMAT_X) && + op <= static_cast(OpcodeMTBUF::TBUFFER_LOAD_FORMAT_XYZW)) { + m_instruction.control.mtbuf.count = op + 1; + } else if (op >= static_cast(OpcodeMTBUF::TBUFFER_STORE_FORMAT_X) && + op <= static_cast(OpcodeMTBUF::TBUFFER_STORE_FORMAT_XYZW)) { + m_instruction.control.mtbuf.count = op - 3; + } +} + +u32 GcnDecodeContext::getMimgModifier(Opcode opcode) { + MimgModifierFlags flags = {}; + + switch (opcode) { + case Opcode::IMAGE_SAMPLE: + break; + case Opcode::IMAGE_SAMPLE_CL: + flags.set(MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_D: + flags.set(MimgModifier::Derivative); + break; + case Opcode::IMAGE_SAMPLE_D_CL: + flags.set(MimgModifier::Derivative, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_L: + flags.set(MimgModifier::Lod); + break; + case Opcode::IMAGE_SAMPLE_B: + flags.set(MimgModifier::LodBias); + break; + case Opcode::IMAGE_SAMPLE_B_CL: + flags.set(MimgModifier::LodBias, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_LZ: + flags.set(MimgModifier::Level0); + break; + case Opcode::IMAGE_SAMPLE_C: + flags.set(MimgModifier::Pcf); + break; + case Opcode::IMAGE_SAMPLE_C_CL: + flags.set(MimgModifier::Pcf, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_C_D: + flags.set(MimgModifier::Pcf, MimgModifier::Derivative); + break; + case Opcode::IMAGE_SAMPLE_C_D_CL: + flags.set(MimgModifier::Pcf, MimgModifier::Derivative, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_C_L: + flags.set(MimgModifier::Pcf, MimgModifier::Lod); + break; + case Opcode::IMAGE_SAMPLE_C_B: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias); + break; + case Opcode::IMAGE_SAMPLE_C_B_CL: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_C_LZ: + flags.set(MimgModifier::Pcf, MimgModifier::Level0); + break; + case Opcode::IMAGE_SAMPLE_O: + flags.set(MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_CL_O: + flags.set(MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_D_O: + flags.set(MimgModifier::Derivative, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_D_CL_O: + flags.set(MimgModifier::Derivative, MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_L_O: + flags.set(MimgModifier::Lod, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_B_O: + flags.set(MimgModifier::LodBias, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_B_CL_O: + flags.set(MimgModifier::LodBias, MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_LZ_O: + flags.set(MimgModifier::Level0, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_O: + flags.set(MimgModifier::Pcf, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_CL_O: + flags.set(MimgModifier::Pcf, MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_D_O: + flags.set(MimgModifier::Pcf, MimgModifier::Derivative, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_D_CL_O: + flags.set(MimgModifier::Pcf, MimgModifier::Derivative, MimgModifier::LodClamp, + MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_L_O: + flags.set(MimgModifier::Pcf, MimgModifier::Lod, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_B_O: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_B_CL_O: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias, MimgModifier::LodClamp, + MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_LZ_O: + flags.set(MimgModifier::Pcf, MimgModifier::Level0, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4: + break; + case Opcode::IMAGE_GATHER4_CL: + flags.set(MimgModifier::LodClamp); + break; + case Opcode::IMAGE_GATHER4_L: + flags.set(MimgModifier::Lod); + break; + case Opcode::IMAGE_GATHER4_B: + flags.set(MimgModifier::LodBias); + break; + case Opcode::IMAGE_GATHER4_B_CL: + flags.set(MimgModifier::LodBias, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_GATHER4_LZ: + flags.set(MimgModifier::Level0); + break; + case Opcode::IMAGE_GATHER4_C: + flags.set(MimgModifier::Pcf); + break; + case Opcode::IMAGE_GATHER4_C_CL: + flags.set(MimgModifier::Pcf, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_GATHER4_C_L: + flags.set(MimgModifier::Pcf, MimgModifier::Lod); + break; + case Opcode::IMAGE_GATHER4_C_B: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias); + break; + case Opcode::IMAGE_GATHER4_C_B_CL: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_GATHER4_C_LZ: + flags.set(MimgModifier::Pcf, MimgModifier::Level0); + break; + case Opcode::IMAGE_GATHER4_O: + flags.set(MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_CL_O: + flags.set(MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_L_O: + flags.set(MimgModifier::Lod, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_B_O: + flags.set(MimgModifier::LodBias, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_B_CL_O: + flags.set(MimgModifier::LodBias, MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_LZ_O: + flags.set(MimgModifier::Level0, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_C_O: + flags.set(MimgModifier::Pcf, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_C_CL_O: + flags.set(MimgModifier::Pcf, MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_C_L_O: + flags.set(MimgModifier::Pcf, MimgModifier::Lod, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_C_B_O: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias, MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_C_B_CL_O: + flags.set(MimgModifier::Pcf, MimgModifier::LodBias, MimgModifier::LodClamp, + MimgModifier::Offset); + break; + case Opcode::IMAGE_GATHER4_C_LZ_O: + flags.set(MimgModifier::Pcf, MimgModifier::Level0, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_CD: + flags.set(MimgModifier::CoarseDerivative); + break; + case Opcode::IMAGE_SAMPLE_CD_CL: + flags.set(MimgModifier::CoarseDerivative, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_C_CD: + flags.set(MimgModifier::Pcf, MimgModifier::CoarseDerivative); + break; + case Opcode::IMAGE_SAMPLE_C_CD_CL: + flags.set(MimgModifier::Pcf, MimgModifier::CoarseDerivative, MimgModifier::LodClamp); + break; + case Opcode::IMAGE_SAMPLE_CD_O: + flags.set(MimgModifier::CoarseDerivative, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_CD_CL_O: + flags.set(MimgModifier::CoarseDerivative, MimgModifier::LodClamp, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_CD_O: + flags.set(MimgModifier::Pcf, MimgModifier::CoarseDerivative, MimgModifier::Offset); + break; + case Opcode::IMAGE_SAMPLE_C_CD_CL_O: + flags.set(MimgModifier::Pcf, MimgModifier::CoarseDerivative, MimgModifier::LodClamp, + MimgModifier::Offset); + break; + default: + break; + } + + return flags.raw(); +} + +void GcnDecodeContext::decodeInstructionMIMG(uint64_t hexInstruction) { + u32 op = bit::extract(hexInstruction, 24, 18); + u32 vaddr = bit::extract(hexInstruction, 39, 32); + u32 vdata = bit::extract(hexInstruction, 47, 40); + u32 srsrc = bit::extract(hexInstruction, 52, 48); + u32 ssamp = bit::extract(hexInstruction, 57, 53); + + m_instruction.opcode = static_cast(op + static_cast(OpcodeMap::OP_MAP_MIMG)); + + m_instruction.src[0].field = OperandField::VectorGPR; + m_instruction.src[0].code = vaddr; + m_instruction.src[2].field = OperandField::ScalarGPR; + m_instruction.src[2].code = srsrc; + m_instruction.src[3].field = OperandField::ScalarGPR; + m_instruction.src[3].code = ssamp; + m_instruction.dst[0].field = OperandField::VectorGPR; + m_instruction.dst[0].code = vdata; + + m_instruction.control.mimg = *reinterpret_cast(&hexInstruction); + m_instruction.control.mimg.mod = getMimgModifier(m_instruction.opcode); +} + +void GcnDecodeContext::decodeInstructionDS(uint64_t hexInstruction) { + OpcodeDS op = (OpcodeDS)bit::extract(hexInstruction, 25, 18); + u32 addr = bit::extract(hexInstruction, 39, 32); + u32 data0 = bit::extract(hexInstruction, 47, 40); + u32 data1 = bit::extract(hexInstruction, 55, 48); + u32 vdst = bit::extract(hexInstruction, 63, 56); + + m_instruction.opcode = static_cast(u32(op) + static_cast(OpcodeMap::OP_MAP_DS)); + + m_instruction.src[0].field = OperandField::VectorGPR; + m_instruction.src[0].code = addr; + m_instruction.src[1].field = OperandField::VectorGPR; + m_instruction.src[1].code = data0; + m_instruction.src[2].field = OperandField::VectorGPR; + m_instruction.src[2].code = data1; + m_instruction.dst[0].field = OperandField::VectorGPR; + m_instruction.dst[0].code = vdst; + m_instruction.dst_count = 1; + + m_instruction.control.ds = *reinterpret_cast(&hexInstruction); + + auto instFormat = InstructionFormat(InstEncoding::DS, (u32)op); + + m_instruction.control.ds.dual = + op == OpcodeDS::DS_WRITE2_B32 || op == OpcodeDS::DS_WRXCHG2_RTN_B32 || + op == OpcodeDS::DS_READ2_B32 || op == OpcodeDS::DS_WRITE2_B64 || + op == OpcodeDS::DS_WRXCHG2_RTN_B64 || op == OpcodeDS::DS_READ2_B64; + + m_instruction.control.ds.sign = instFormat.src_type == ScalarType::Sint32; + + m_instruction.control.ds.relative = + op >= OpcodeDS::DS_ADD_SRC2_U32 && op <= OpcodeDS::DS_MAX_SRC2_F64; + + m_instruction.control.ds.stride = + op == OpcodeDS::DS_WRITE2ST64_B32 || op == OpcodeDS::DS_WRXCHG2ST64_RTN_B32 || + op == OpcodeDS::DS_READ2ST64_B32 || op == OpcodeDS::DS_WRITE2ST64_B64 || + op == OpcodeDS::DS_WRXCHG2ST64_RTN_B64 || op == OpcodeDS::DS_READ2ST64_B64; + + if (op == OpcodeDS::DS_WRITE_B8 || op == OpcodeDS::DS_READ_I8 || op == OpcodeDS::DS_READ_U8) { + m_instruction.control.ds.size = 1; + } else if (op == OpcodeDS::DS_WRITE_B16 || op == OpcodeDS::DS_READ_I16 || + op == OpcodeDS::DS_READ_U16) { + m_instruction.control.ds.size = 2; + } else { + if (instFormat.src_type == ScalarType::Sint32 || + instFormat.src_type == ScalarType::Uint32) { + m_instruction.control.ds.size = 4; + } else if (instFormat.src_type == ScalarType::Sint64 || + instFormat.src_type == ScalarType::Uint64) { + m_instruction.control.ds.size = 8; + } else { + m_instruction.control.ds.size = 0; + } + } +} + +void GcnDecodeContext::decodeInstructionEXP(uint64_t hexInstruction) { + u32 vsrc0 = bit::extract(hexInstruction, 39, 32); + u32 vsrc1 = bit::extract(hexInstruction, 47, 40); + u32 vsrc2 = bit::extract(hexInstruction, 55, 48); + u32 vsrc3 = bit::extract(hexInstruction, 63, 56); + + m_instruction.opcode = Opcode::EXP; + + m_instruction.src[0].field = OperandField::VectorGPR; + m_instruction.src[0].code = vsrc0; + m_instruction.src[1].field = OperandField::VectorGPR; + m_instruction.src[1].code = vsrc1; + m_instruction.src[2].field = OperandField::VectorGPR; + m_instruction.src[2].code = vsrc2; + m_instruction.src[3].field = OperandField::VectorGPR; + m_instruction.src[3].code = vsrc3; + + m_instruction.control.exp = *reinterpret_cast(&hexInstruction); +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/decode.h b/gpu/shadps4/shader_recompiler/frontend/decode.h new file mode 100644 index 0000000..3b31d5a --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/decode.h @@ -0,0 +1,105 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/frontend/instruction.h" + +namespace Shader::Gcn { + +struct InstFormat { + InstClass inst_class = InstClass::Undefined; + InstCategory inst_category = InstCategory::Undefined; + u32 src_count = 0; + u32 dst_count = 0; + ScalarType src_type = ScalarType::Undefined; + ScalarType dst_type = ScalarType::Undefined; +}; + +InstEncoding GetInstructionEncoding(u32 token); + +u32 GetEncodingLength(InstEncoding encoding); + +InstFormat InstructionFormat(InstEncoding encoding, u32 opcode); + +Opcode DecodeOpcode(u32 token); + +class GcnCodeSlice { +public: + GcnCodeSlice(const u32* ptr, const u32* end) : m_ptr(ptr), m_end(end) {} + GcnCodeSlice(const GcnCodeSlice& other) = default; + ~GcnCodeSlice() = default; + + u32 at(u32 id) const { + return m_ptr[id]; + } + + u32 readu32() { + return *(m_ptr++); + } + + u64 readu64() { + const u64 value = *(u64*)m_ptr; + m_ptr += 2; + return value; + } + + bool atEnd() const { + return m_ptr == m_end; + } + + // bbport: current read position (fetch shader parse cache) + const u32* position() const { + return m_ptr; + } + +private: + const u32* m_ptr{}; + const u32* m_end{}; +}; + +class GcnDecodeContext { +public: + GcnInst decodeInstruction(GcnCodeSlice& code); + +private: + uint32_t getEncodingLength(InstEncoding encoding); + uint32_t getOpMapOffset(InstEncoding encoding); + uint32_t mapEncodingOp(InstEncoding encoding, Opcode opcode); + void updateInstructionMeta(InstEncoding encoding); + uint32_t getMimgModifier(Opcode opcode); + void repairOperandType(); + + OperandField getOperandField(uint32_t code); + + void decodeInstruction32(InstEncoding encoding, GcnCodeSlice& code); + void decodeInstruction64(InstEncoding encoding, GcnCodeSlice& code); + void decodeLiteralConstant(InstEncoding encoding, GcnCodeSlice& code); + void decodeSubDwordAddressing(InstEncoding encoding, GcnCodeSlice& code); + void decodeDataParallelPrimitive(InstEncoding encoding, GcnCodeSlice& code); + + // 32 bits encodings + void decodeInstructionSOP1(uint32_t hexInstruction); + void decodeInstructionSOPP(uint32_t hexInstruction); + void decodeInstructionSOPC(uint32_t hexInstruction); + void decodeInstructionSOPK(uint32_t hexInstruction); + void decodeInstructionSOP2(uint32_t hexInstruction); + void decodeInstructionVOP1(uint32_t hexInstruction); + void decodeInstructionVOPC(uint32_t hexInstruction); + void decodeInstructionVOP2(uint32_t hexInstruction); + void decodeInstructionSMRD(uint32_t hexInstruction); + void decodeInstructionVINTRP(uint32_t hexInstruction); + // 64 bits encodings + void decodeInstructionVOP3(uint64_t hexInstruction); + void decodeInstructionVOP3P(uint64_t hexInstruction); + void decodeInstructionMUBUF(uint64_t hexInstruction); + void decodeInstructionMTBUF(uint64_t hexInstruction); + void decodeInstructionMIMG(uint64_t hexInstruction); + void decodeInstructionDS(uint64_t hexInstruction); + void decodeInstructionEXP(uint64_t hexInstruction); + +private: + GcnInst m_instruction; +}; + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/fetch_shader.cpp b/gpu/shadps4/shader_recompiler/frontend/fetch_shader.cpp new file mode 100644 index 0000000..bced0b8 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/fetch_shader.cpp @@ -0,0 +1,137 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include "bbport_toggles.h" +#include "common/assert.h" +#include "shader_recompiler/frontend/decode.h" +#include "shader_recompiler/frontend/fetch_shader.h" + +namespace Shader::Gcn { + +/** + * s_load_dwordx4 s[8:11], s[2:3], 0x00 + * s_load_dwordx4 s[12:15], s[2:3], 0x04 + * s_load_dwordx4 s[16:19], s[2:3], 0x08 + * s_waitcnt lgkmcnt(0) + * buffer_load_format_xyzw v[4:7], v0, s[8:11], 0 idxen + * buffer_load_format_xyz v[8:10], v0, s[12:15], 0 idxen + * buffer_load_format_xy v[12:13], v0, s[16:19], 0 idxen + * s_waitcnt 0 + * s_setpc_b64 s[0:1] + + * s_load_dwordx4 s[4:7], s[2:3], 0x0 + * s_waitcnt lgkmcnt(0) + * buffer_load_format_xyzw v[4:7], v0, s[4:7], 0 idxen + * s_load_dwordx4 s[4:7], s[2:3], 0x8 + * s_waitcnt lgkmcnt(0) + * buffer_load_format_xyzw v[8:11], v0, s[4:7], 0 idxen + * s_waitcnt vmcnt(0) & expcnt(0) & lgkmcnt(0) + * s_setpc_b64 s[0:1] + + * A normal fetch shader looks like the above, the instructions are generated + * using input semantics on cpu side. Load instructions can either be separate or interleaved + * We take the reverse way, extract the original input semantics from these instructions. + **/ + +static bool IsTypedBufferLoad(const Gcn::GcnInst& inst) { + return inst.opcode == Opcode::TBUFFER_LOAD_FORMAT_X || + inst.opcode == Opcode::TBUFFER_LOAD_FORMAT_XY || + inst.opcode == Opcode::TBUFFER_LOAD_FORMAT_XYZ || + inst.opcode == Opcode::TBUFFER_LOAD_FORMAT_XYZW; +} + +const u32* GetFetchShaderCode(const Info& info, u32 sgpr_base) { + const u32* code; + std::memcpy(&code, &info.user_data[sgpr_base], sizeof(code)); + return code; +} + +std::optional ParseFetchShader(const Shader::Info& info) { + if (!info.has_fetch_shader) { + return std::nullopt; + } + + const auto* code = GetFetchShaderCode(info, info.fetch_shader_sgpr_base); + + // bbport: the pipeline cache parses the fetch shader on every draw. Results are cached + // per thread by code address and revalidated against a copy of the code, which is + // much cheaper than decoding it again. + struct CachedParse { + std::vector code; + FetchShaderData data; + }; + thread_local std::unordered_map cache; + if (const auto it = cache.find(code); + !BbToggle::Disabled(BbToggle::FetchShaderCache) && it != cache.end() && + std::memcmp(code, it->second.code.data(), it->second.code.size() * sizeof(u32)) == 0) { + return it->second.data; + } + + FetchShaderData data{}; + GcnCodeSlice code_slice(code, code + std::numeric_limits::max()); + GcnDecodeContext decoder; + + struct VsharpLoad { + u32 dword_offset{}; + u32 base_sgpr{}; + }; + std::array loads{}; + + u32 semantic_index = 0; + while (!code_slice.atEnd()) { + const auto inst = decoder.decodeInstruction(code_slice); + data.size += inst.length; + + if (inst.opcode == Opcode::S_SETPC_B64) { + break; + } + + if (inst.inst_class == InstClass::ScalarMemRd) { + loads[inst.dst[0].code] = VsharpLoad{inst.control.smrd.offset, inst.src[0].code * 2}; + continue; + } + + if (inst.opcode == Opcode::V_ADD_I32) { + const auto vgpr = inst.dst[0].code; + const auto sgpr = s8(inst.src[0].code); + switch (vgpr) { + case 0: // V0 is always the vertex offset + data.vertex_offset_sgpr = sgpr; + break; + case 3: // V3 is always the instance offset + data.instance_offset_sgpr = sgpr; + break; + default: + UNREACHABLE(); + } + } + + if (inst.inst_class == InstClass::VectorMemBufFmt) { + // SRSRC is in units of 4 SPGRs while SBASE is in pairs of SGPRs + const u32 base_sgpr = inst.src[2].code * 4; + auto& attrib = data.attributes.emplace_back(); + attrib.semantic = semantic_index++; + attrib.dest_vgpr = inst.src[1].code; + attrib.num_elements = inst.control.mubuf.count; + attrib.sgpr_base = loads[base_sgpr].base_sgpr; + attrib.dword_offset = loads[base_sgpr].dword_offset; + attrib.inst_offset = inst.control.mtbuf.offset; + attrib.instance_data = inst.src[0].code; + if (IsTypedBufferLoad(inst)) { + attrib.data_format = inst.control.mtbuf.dfmt; + attrib.num_format = inst.control.mtbuf.nfmt; + } + } + } + + if (cache.size() >= 4096) { + cache.clear(); + } + cache[code] = CachedParse{std::vector(code, code_slice.position()), data}; + return data; +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/fetch_shader.h b/gpu/shadps4/shader_recompiler/frontend/fetch_shader.h new file mode 100644 index 0000000..a57bbb0 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/fetch_shader.h @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" +#include "shader_recompiler/info.h" + +namespace Serialization { +struct Archive; +} + +namespace Shader::Gcn { + +struct VertexAttribute { + enum InstanceIdType : u8 { + None = 0, + OverStepRate0 = 1, + OverStepRate1 = 2, + Plain = 3, + }; + + u8 semantic; ///< Semantic index of the attribute + u8 dest_vgpr; ///< Destination VGPR to load first component. + u8 num_elements; ///< Number of components to load + u8 sgpr_base; ///< SGPR that contains the pointer to the list of vertex V# + u8 dword_offset; ///< The dword offset of the V# that describes this attribute. + u8 instance_data; ///< Indicates that the buffer will be accessed in instance rate + u8 inst_offset; ///< Instruction offset applied on the formatted buffer loads + u8 data_format{}; ///< Data format override when typed buffer loads are used + u8 num_format{}; ///< Number format override when typed buffer loads are used + + InstanceIdType GetStepRate() const { + return static_cast(instance_data); + } + + constexpr AmdGpu::Buffer GetSharp(const Shader::Info& info) const noexcept { + auto buffer = info.ReadUdReg(sgpr_base, dword_offset); + buffer.base_address += inst_offset; + if (data_format) { + buffer.data_format = data_format; + buffer.num_format = num_format; + } + return buffer; + } + + bool operator==(const VertexAttribute& other) const { + return semantic == other.semantic && dest_vgpr == other.dest_vgpr && + num_elements == other.num_elements && sgpr_base == other.sgpr_base && + dword_offset == other.dword_offset && instance_data == other.instance_data; + } +}; + +struct FetchShaderData { + u32 size = 0; + std::vector attributes; + s8 vertex_offset_sgpr = -1; ///< SGPR of vertex offset from VADDR + s8 instance_offset_sgpr = -1; ///< SGPR of instance offset from VADDR + + bool operator==(const FetchShaderData& other) const { + return attributes == other.attributes && vertex_offset_sgpr == other.vertex_offset_sgpr && + instance_offset_sgpr == other.instance_offset_sgpr; + } + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& buffer); +}; + +const u32* GetFetchShaderCode(const Info& info, u32 sgpr_base); + +std::optional ParseFetchShader(const Shader::Info& info); + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/format.cpp b/gpu/shadps4/shader_recompiler/frontend/format.cpp new file mode 100644 index 0000000..57a6d7f --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/format.cpp @@ -0,0 +1,4414 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "shader_recompiler/frontend/decode.h" + +namespace Shader::Gcn { + +constexpr std::array InstructionFormatSOP2 = {{ + // 0 = S_ADD_U32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 1 = S_SUB_U32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 2 = S_ADD_I32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 3 = S_SUB_I32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 4 = S_ADDC_U32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 5 = S_SUBB_U32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 6 = S_MIN_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 7 = S_MIN_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 8 = S_MAX_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 9 = S_MAX_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 10 = S_CSELECT_B32 + {InstClass::ScalarSelect, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 11 = S_CSELECT_B64 + {InstClass::ScalarSelect, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + {}, + {}, + // 14 = S_AND_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 15 = S_AND_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 16 = S_OR_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 17 = S_OR_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 18 = S_XOR_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 19 = S_XOR_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 20 = S_ANDN2_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 21 = S_ANDN2_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 22 = S_ORN2_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 23 = S_ORN2_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 24 = S_NAND_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 25 = S_NAND_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 26 = S_NOR_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 27 = S_NOR_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 28 = S_XNOR_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 29 = S_XNOR_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 30 = S_LSHL_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 31 = S_LSHL_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 32 = S_LSHR_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 33 = S_LSHR_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 34 = S_ASHR_I32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 35 = S_ASHR_I64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 36 = S_BFM_B32 + {InstClass::ScalarBitField, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 37 = S_BFM_B64 + {InstClass::ScalarBitField, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 38 = S_MUL_I32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 39 = S_BFE_U32 + {InstClass::ScalarBitField, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 40 = S_BFE_I32 + {InstClass::ScalarBitField, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 41 = S_BFE_U64 + {InstClass::ScalarBitField, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 42 = S_BFE_I64 + {InstClass::ScalarBitField, InstCategory::ScalarALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 43 = S_CBRANCH_G_FORK + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 2, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 44 = S_ABSDIFF_I32 + {InstClass::ScalarAbs, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, +}}; + +constexpr std::array InstructionFormatSOPK = {{ + // 0 = S_MOVK_I32 + {InstClass::ScalarMov, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + {}, + // 2 = S_CMOVK_I32 + {InstClass::ScalarMov, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 3 = S_CMPK_EQ_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 4 = S_CMPK_LI32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 5 = S_CMPK_GT_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 6 = S_CMPK_GE_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 7 = S_CMPK_LT_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 8 = S_CMPK_LE_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 9 = S_CMPK_EQ_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 10 = S_CMPK_LG_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 11 = S_CMPK_GT_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 12 = S_CMPK_GE_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 13 = S_CMPK_LT_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 14 = S_CMPK_LE_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 0, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 15 = S_ADDK_I32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 16 = S_MULK_I32 + {InstClass::ScalarArith, InstCategory::ScalarALU, 0, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 17 = S_CBRANCH_I_FORK + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 18 = S_GETREG_B32 + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 19 = S_SETREG_B32 + {InstClass::ScalarRegAccess, InstCategory::FlowControl, 0, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + // 21 = S_SETREIMM32_B32 + {InstClass::ScalarRegAccess, InstCategory::FlowControl, 0, 1, ScalarType::Uint32, + ScalarType::Uint32}, +}}; + +constexpr std::array InstructionFormatSOP1 = {{ + {}, + {}, + {}, + // 3 = S_MOV_B32 + {InstClass::ScalarMov, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 4 = S_MOV_B64 + {InstClass::ScalarMov, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 5 = S_CMOV_B32 + {InstClass::ScalarMov, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 6 = S_CMOV_B64 + {InstClass::ScalarMov, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 7 = S_NOT_B32 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 8 = S_NOT_B64 + {InstClass::ScalarBitLogic, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 9 = S_WQM_B32 + {InstClass::ScalarQuadMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 10 = S_WQM_B64 + {InstClass::ScalarQuadMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 11 = S_BREV_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 12 = S_BREV_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 13 = S_BCNT0_I32_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Sint32}, + // 14 = S_BCNT0_I32_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Sint32}, + // 15 = S_BCNT1_I32_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Sint32}, + // 16 = S_BCNT1_I32_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Sint32}, + // 17 = S_FF0_I32_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Sint32}, + // 18 = S_FF0_I32_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Sint32}, + // 19 = S_FF1_I32_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Sint32}, + // 20 = S_FF1_I32_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Sint32}, + // 21 = S_FLBIT_I32_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Sint32}, + // 22 = S_FLBIT_I32_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Sint32}, + // 23 = S_FLBIT_I32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 24 = S_FLBIT_I32_I64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Sint64, + ScalarType::Sint32}, + // 25 = S_SEXT_I32_I8 + {InstClass::ScalarConv, InstCategory::ScalarALU, 1, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 26 = S_SEXT_I32_I16 + {InstClass::ScalarConv, InstCategory::ScalarALU, 1, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 27 = S_BITSET0_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 28 = S_BITSET0_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 29 = S_BITSET1_B32 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 30 = S_BITSET1_B64 + {InstClass::ScalarBitManip, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 31 = S_GETPC_B64 + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 32 = S_SETPC_B64 + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 33 = S_SWAPPC_B64 + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 34 = S_RFE_B64 + {InstClass::Undefined, InstCategory::Undefined, 1, 1, ScalarType::Uint64, ScalarType::Uint64}, + {}, + // 36 = S_AND_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 37 = S_OR_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 38 = S_XOR_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 39 = S_ANDN2_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 40 = S_ORN2_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 41 = S_NAND_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 42 = S_NOR_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 43 = S_XNOR_SAVEEXEC_B64 + {InstClass::ScalarExecMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 44 = S_QUADMASK_B32 + {InstClass::ScalarQuadMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 45 = S_QUADMASK_B64 + {InstClass::ScalarQuadMask, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 46 = S_MOVRELS_B32 + {InstClass::ScalarMovRel, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 47 = S_MOVRELS_B64 + {InstClass::ScalarMovRel, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 48 = S_MOVRELD_B32 + {InstClass::ScalarMovRel, InstCategory::ScalarALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 49 = S_MOVRELD_B64 + {InstClass::ScalarMovRel, InstCategory::ScalarALU, 1, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 50 = S_CBRANCH_JOIN + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 1, 1, ScalarType::Undefined, + ScalarType::Undefined}, + {}, + // 52 = S_ABS_I32 + {InstClass::ScalarAbs, InstCategory::ScalarALU, 1, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 53 = S_MOV_FED_B32 + {InstClass::Undefined, InstCategory::Undefined, 1, 1, ScalarType::Uint32, ScalarType::Uint32}, +}}; + +constexpr std::array InstructionFormatSOPC = {{ + // 0 = S_CMP_EQ_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 1 = S_CMP_LI32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 2 = S_CMP_GT_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 3 = S_CMP_GE_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 4 = S_CMP_LT_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 5 = S_CMP_LE_I32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 6 = S_CMP_EQ_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 7 = S_CMP_LG_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 8 = S_CMP_GT_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 9 = S_CMP_GE_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 10 = S_CMP_LT_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 11 = S_CMP_LE_U32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 12 = S_BITCMP0_B32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 13 = S_BITCMP1_B32 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 14 = S_BITCMP0_B64 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 15 = S_BITCMP1_B64 + {InstClass::ScalarCmp, InstCategory::ScalarALU, 2, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 16 = S_SETVSKIP + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 2, 1, ScalarType::Undefined, + ScalarType::Undefined}, +}}; + +constexpr std::array InstructionFormatSOPP = {{ + // 0 = S_NOP + {InstClass::ScalarWait, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 1 = S_ENDPGM + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 2 = S_BRANCH + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + {}, + // 4 = S_CBRANCH_SCC0 + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 5 = S_CBRANCH_SCC1 + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 6 = S_CBRANCH_VCCZ + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 7 = S_CBRANCH_VCCNZ + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 8 = S_CBRANCH_EXECZ + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 9 = S_CBRANCH_EXECNZ + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 10 = S_BARRIER + {InstClass::ScalarSync, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + {}, + // 12 = S_WAITCNT + {InstClass::ScalarSync, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 13 = S_SETHALT + {InstClass::Undefined, InstCategory::Undefined, 0, 1, ScalarType::Any, ScalarType::Any}, + // 14 = S_SLEEP + {InstClass::ScalarSync, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 15 = S_SETPRIO + {InstClass::ScalarSync, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 16 = S_SENDMSG + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 17 = S_SENDMSGHALT + {InstClass::ScalarProgFlow, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 18 = S_TRAP + {InstClass::Undefined, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 19 = S_ICACHE_INV + {InstClass::ScalarCache, InstCategory::FlowControl, 0, 1, ScalarType::Any, ScalarType::Any}, + // 20 = S_INCPERFLEVEL + {InstClass::DbgProf, InstCategory::DebugProfile, 0, 1, ScalarType::Any, ScalarType::Any}, + // 21 = S_DECPERFLEVEL + {InstClass::DbgProf, InstCategory::DebugProfile, 0, 1, ScalarType::Any, ScalarType::Any}, + // 22 = S_TTRACEDATA + {InstClass::DbgProf, InstCategory::DebugProfile, 0, 1, ScalarType::Any, ScalarType::Any}, + // 23 = S_CBRANCH_CDBGSYS + {InstClass::Undefined, InstCategory::Undefined, 0, 1, ScalarType::Any, ScalarType::Any}, + // 24 = S_CBRANCH_CDBGUSER + {InstClass::Undefined, InstCategory::Undefined, 0, 1, ScalarType::Any, ScalarType::Any}, + // 25 = S_CBRANCH_CDBGSYS_OR_USER + {InstClass::Undefined, InstCategory::Undefined, 0, 1, ScalarType::Any, ScalarType::Any}, + // 26 = S_CBRANCH_CDBGSYS_AND_USER + {InstClass::Undefined, InstCategory::Undefined, 0, 1, ScalarType::Any, ScalarType::Any}, +}}; + +constexpr std::array InstructionFormatSMRD = {{ + // 0 = S_LOAD_DWORD + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 1 = S_LOAD_DWORDX2 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 2 = S_LOAD_DWORDX4 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 3 = S_LOAD_DWORDX8 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 4 = S_LOAD_DWORDX16 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + {}, + {}, + // 8 = S_BUFFER_LOAD_DWORD + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 9 = S_BUFFER_LOAD_DWORDX2 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 10 = S_BUFFER_LOAD_DWORDX4 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 11 = S_BUFFER_LOAD_DWORDX8 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 12 = S_BUFFER_LOAD_DWORDX16 + {InstClass::ScalarMemRd, InstCategory::ScalarMemory, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 29 = S_DCACHE_INV_VOL + {InstClass::ScalarMemUt, InstCategory::ScalarMemory, 1, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 30 = S_MEMTIME + {InstClass::ScalarMemUt, InstCategory::ScalarMemory, 0, 1, ScalarType::Any, ScalarType::Uint64}, + // 31 = S_DCACHE_INV + {InstClass::ScalarMemUt, InstCategory::ScalarMemory, 1, 1, ScalarType::Undefined, + ScalarType::Undefined}, +}}; + +constexpr std::array InstructionFormatVOP2 = {{ + // 0 = V_CNDMASK_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 1 = V_READLANE_B32 + {InstClass::VectorLane, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 2 = V_WRITELANE_B32 + {InstClass::VectorLane, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 3 = V_ADD_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 4 = V_SUB_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 5 = V_SUBREV_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 6 = V_MAC_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 7 = V_MUL_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 8 = V_MUL_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 9 = V_MUL_I32_I24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 10 = V_MUL_HI_I32_I24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 11 = V_MUL_U32_U24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 12 = V_MUL_HI_U32_U24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 13 = V_MIN_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 14 = V_MAX_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 15 = V_MIN_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 16 = V_MAX_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 17 = V_MIN_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 18 = V_MAX_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 19 = V_MIN_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 20 = V_MAX_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 21 = V_LSHR_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 22 = V_LSHRREV_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 23 = V_ASHR_I32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 24 = V_ASHRREV_I32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 25 = V_LSHL_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 26 = V_LSHLREV_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 27 = V_AND_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 28 = V_OR_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 29 = V_XOR_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 30 = V_BFM_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 31 = V_MAC_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 32 = V_MADMK_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 33 = V_MADAK_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 34 = V_BCNT_U32_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 35 = V_MBCNT_LO_U32_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 36 = V_MBCNT_HI_U32_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 37 = V_ADD_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 38 = V_SUB_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 39 = V_SUBREV_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 40 = V_ADDC_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 41 = V_SUBB_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 42 = V_SUBBREV_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 43 = V_LDEXP_F32 + {InstClass::VectorFpField32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 44 = V_CVT_PKACCUM_U8_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, ScalarType::Uint32}, + // 45 = V_CVT_PKNORM_I16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, ScalarType::Sint32}, + // 46 = V_CVT_PKNORM_U16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, ScalarType::Uint32}, + // 47 = V_CVT_PKRTZ_F16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, ScalarType::Uint32}, + // 48 = V_CVT_PK_U16_U32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 49 = V_CVT_PK_I16_I32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 50 = V_ADD_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 51 = V_SUB_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + // 53 = V_MUL_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + {}, + // 57 = V_MAX_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 58 = V_MIN_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, +}}; + +constexpr std::array InstructionFormatVOP3 = { + {// 0 = V_CMP_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 1 = V_CMP_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 2 = V_CMP_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 3 = V_CMP_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 4 = V_CMP_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 5 = V_CMP_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 6 = V_CMP_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 7 = V_CMP_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 8 = V_CMP_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 9 = V_CMP_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 10 = V_CMP_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 11 = V_CMP_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 12 = V_CMP_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 13 = V_CMP_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 14 = V_CMP_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 15 = V_CMP_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 16 = V_CMPX_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 17 = V_CMPX_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 18 = V_CMPX_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 19 = V_CMPX_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 20 = V_CMPX_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 21 = V_CMPX_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 22 = V_CMPX_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 23 = V_CMPX_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 24 = V_CMPX_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 25 = V_CMPX_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 26 = V_CMPX_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 27 = V_CMPX_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 28 = V_CMPX_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 29 = V_CMPX_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 30 = V_CMPX_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 31 = V_CMPX_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 32 = V_CMP_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 33 = V_CMP_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 34 = V_CMP_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 35 = V_CMP_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 36 = V_CMP_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 37 = V_CMP_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 38 = V_CMP_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 39 = V_CMP_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 40 = V_CMP_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 41 = V_CMP_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 42 = V_CMP_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 43 = V_CMP_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 44 = V_CMP_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 45 = V_CMP_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 46 = V_CMP_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 47 = V_CMP_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 48 = V_CMPX_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 49 = V_CMPX_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 50 = V_CMPX_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 51 = V_CMPX_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 52 = V_CMPX_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 53 = V_CMPX_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 54 = V_CMPX_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 55 = V_CMPX_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 56 = V_CMPX_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 57 = V_CMPX_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 58 = V_CMPX_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 59 = V_CMPX_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 60 = V_CMPX_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 61 = V_CMPX_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 62 = V_CMPX_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 63 = V_CMPX_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 64 = V_CMPS_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 65 = V_CMPS_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 66 = V_CMPS_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 67 = V_CMPS_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 68 = V_CMPS_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 69 = V_CMPS_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 70 = V_CMPS_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 71 = V_CMPS_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 72 = V_CMPS_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 73 = V_CMPS_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 74 = V_CMPS_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 75 = V_CMPS_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 76 = V_CMPS_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 77 = V_CMPS_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 78 = V_CMPS_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 79 = V_CMPS_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 80 = V_CMPSX_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 81 = V_CMPSX_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 82 = V_CMPSX_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 83 = V_CMPSX_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 84 = V_CMPSX_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 85 = V_CMPSX_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 86 = V_CMPSX_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 87 = V_CMPSX_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 88 = V_CMPSX_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 89 = V_CMPSX_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 90 = V_CMPSX_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 91 = V_CMPSX_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 92 = V_CMPSX_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 93 = V_CMPSX_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 94 = V_CMPSX_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 95 = V_CMPSX_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 96 = V_CMPS_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 97 = V_CMPS_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 98 = V_CMPS_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 99 = V_CMPS_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 100 = V_CMPS_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 101 = V_CMPS_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 102 = V_CMPS_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 103 = V_CMPS_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 104 = V_CMPS_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 105 = V_CMPS_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 106 = V_CMPS_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 107 = V_CMPS_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 108 = V_CMPS_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 109 = V_CMPS_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 110 = V_CMPS_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 111 = V_CMPS_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 112 = V_CMPSX_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 113 = V_CMPSX_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 114 = V_CMPSX_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 115 = V_CMPSX_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 116 = V_CMPSX_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 117 = V_CMPSX_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 118 = V_CMPSX_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 119 = V_CMPSX_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 120 = V_CMPSX_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 121 = V_CMPSX_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 122 = V_CMPSX_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 123 = V_CMPSX_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 124 = V_CMPSX_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 125 = V_CMPSX_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 126 = V_CMPSX_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 127 = V_CMPSX_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 128 = V_CMP_F_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 129 = V_CMP_LT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 130 = V_CMP_EQ_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 131 = V_CMP_LE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 132 = V_CMP_GT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 133 = V_CMP_NE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 134 = V_CMP_GE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 135 = V_CMP_T_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 136 = V_CMP_CLASS_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 137 = V_CMP_LT_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 138 = V_CMP_EQ_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 139 = V_CMP_LE_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 140 = V_CMP_GT_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 141 = V_CMP_NE_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 142 = V_CMP_GE_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + {}, + // 144 = V_CMPX_F_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 145 = V_CMPX_LT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 146 = V_CMPX_EQ_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 147 = V_CMPX_LE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 148 = V_CMPX_GT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 149 = V_CMPX_NE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 150 = V_CMPX_GE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 151 = V_CMPX_T_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 152 = V_CMPX_CLASS_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 160 = V_CMP_F_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 161 = V_CMP_LT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 162 = V_CMP_EQ_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 163 = V_CMP_LE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 164 = V_CMP_GT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 165 = V_CMP_NE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 166 = V_CMP_GE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 167 = V_CMP_T_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 168 = V_CMP_CLASS_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 176 = V_CMPX_F_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 177 = V_CMPX_LT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 178 = V_CMPX_EQ_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 179 = V_CMPX_LE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 180 = V_CMPX_GT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 181 = V_CMPX_NE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 182 = V_CMPX_GE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 183 = V_CMPX_T_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 184 = V_CMPX_CLASS_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 192 = V_CMP_F_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 193 = V_CMP_LT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 194 = V_CMP_EQ_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 195 = V_CMP_LE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 196 = V_CMP_GT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 197 = V_CMP_NE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 198 = V_CMP_GE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 199 = V_CMP_T_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 200 = V_CMP_F_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 201 = V_CMP_LT_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 202 = V_CMP_EQ_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 203 = V_CMP_LE_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 204 = V_CMP_GT_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 205 = V_CMP_LG_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 206 = V_CMP_GE_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 207 = V_CMP_O_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 208 = V_CMPX_F_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 209 = V_CMPX_LT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 210 = V_CMPX_EQ_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 211 = V_CMPX_LE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 212 = V_CMPX_GT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 213 = V_CMPX_NE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 214 = V_CMPX_GE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 215 = V_CMPX_T_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 224 = V_CMP_F_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 225 = V_CMP_LT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 226 = V_CMP_EQ_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 227 = V_CMP_LE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 228 = V_CMP_GT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 229 = V_CMP_NE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 230 = V_CMP_GE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 231 = V_CMP_T_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 240 = V_CMPX_F_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 241 = V_CMPX_LT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 242 = V_CMPX_EQ_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 243 = V_CMPX_LE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 244 = V_CMPX_GT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 245 = V_CMPX_NE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 246 = V_CMPX_GE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 247 = V_CMPX_T_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 256 = V_CNDMASK_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 257 = V_READLANE_B32 + {InstClass::VectorLane, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 258 = V_WRITELANE_B32 + {InstClass::VectorLane, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 259 = V_ADD_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 260 = V_SUB_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 261 = V_SUBREV_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 262 = V_MAC_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 263 = V_MUL_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 264 = V_MUL_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 265 = V_MUL_I32_I24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 266 = V_MUL_HI_I32_I24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 267 = V_MUL_U32_U24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 268 = V_MUL_HI_U32_U24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 269 = V_MIN_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 270 = V_MAX_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 271 = V_MIN_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 272 = V_MAX_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 273 = V_MIN_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 274 = V_MAX_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 275 = V_MIN_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 276 = V_MAX_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 277 = V_LSHR_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 278 = V_LSHRREV_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 279 = V_ASHR_I32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 280 = V_ASHRREV_I32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 281 = V_LSHL_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 282 = V_LSHLREV_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 283 = V_AND_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 284 = V_OR_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 285 = V_XOR_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 286 = V_BFM_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 287 = V_MAC_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 288 = V_MADMK_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 289 = V_MADAK_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 290 = V_BCNT_U32_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 291 = V_MBCNT_LO_U32_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 292 = V_MBCNT_HI_U32_B32 + {InstClass::VectorThreadMask, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 293 = V_ADD_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 294 = V_SUB_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 295 = V_SUBREV_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 296 = V_ADDC_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 297 = V_SUBB_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 298 = V_SUBBREV_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 299 = V_LDEXP_F32 + {InstClass::VectorFpField32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 300 = V_CVT_PKACCUM_U8_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Uint32}, + // 301 = V_CVT_PKNORM_I16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Sint32}, + // 302 = V_CVT_PKNORM_U16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Uint32}, + // 303 = V_CVT_PKRTZ_F16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Uint32}, + // 304 = V_CVT_PK_U16_U32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 305 = V_CVT_PK_I16_I32 + {InstClass::VectorConv, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 306 = V_ADD_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 307 = V_SUB_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 308 = V_SUBREV_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 309 = V_MUL_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + {}, + // 313 = V_MAX_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 314 = V_MIN_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 315 = V_LDEXP_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + {}, + {}, + // 320 = V_MAD_LEGACY_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 321 = V_MAD_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 322 = V_MAD_I32_I24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 323 = V_MAD_U32_U24 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 324 = V_CUBEID_F32 + {InstClass::VectorFpGraph32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 325 = V_CUBESC_F32 + {InstClass::VectorFpGraph32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 326 = V_CUBETC_F32 + {InstClass::VectorFpGraph32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 327 = V_CUBEMA_F32 + {InstClass::VectorFpGraph32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 328 = V_BFE_U32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 329 = V_BFE_I32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 330 = V_BFI_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 331 = V_FMA_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 332 = V_FMA_F64 + {InstClass::VectorFpArith64, InstCategory::VectorALU, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 333 = V_LERP_U8 + {InstClass::VectorIntGraph, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 334 = V_ALIGNBIT_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 335 = V_ALIGNBYTE_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 336 = V_MULLIT_F32 + {InstClass::VectorFpGraph32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 337 = V_MIN3_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 338 = V_MIN3_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 339 = V_MIN3_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 340 = V_MAX3_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 341 = V_MAX3_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 342 = V_MAX3_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 343 = V_MED3_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 344 = V_MED3_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 345 = V_MED3_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 346 = V_SAD_U8 + {InstClass::VectorIntGraph, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 347 = V_SAD_HI_U8 + {InstClass::VectorIntGraph, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 348 = V_SAD_U16 + {InstClass::VectorIntGraph, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 349 = V_SAD_U32 + {InstClass::VectorIntGraph, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 350 = V_CVT_PK_U8_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Uint32}, + // 351 = V_DIV_FIXUP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 352 = V_DIV_FIXUP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 353 = V_LSHL_B64 + {InstClass::VectorBitField64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 354 = V_LSHR_B64 + {InstClass::VectorBitField64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 355 = V_ASHR_I64 + {InstClass::VectorBitField64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 356 = V_ADD_F64 + {InstClass::VectorFpArith64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 357 = V_MUL_F64 + {InstClass::VectorFpArith64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 358 = V_MIN_F64 + {InstClass::VectorFpArith64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 359 = V_MAX_F64 + {InstClass::VectorFpArith64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 360 = V_LDEXP_F64 + {InstClass::VectorFpField64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 361 = V_MUL_LO_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 362 = V_MUL_HI_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 363 = V_MUL_LO_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 364 = V_MUL_HI_I32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 365 = V_DIV_SCALE_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 366 = V_DIV_SCALE_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 367 = V_DIV_FMAS_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 368 = V_DIV_FMAS_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 369 = V_MSAD_U8 + {InstClass::VectorIntGraph, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 370 = V_QSAD_U8 + {InstClass::Undefined, InstCategory::Undefined, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 371 = V_MQSAD_U8 + {InstClass::Undefined, InstCategory::Undefined, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 372 = V_TRIG_PREOP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 373 = V_MQSAD_U32_U8 + {InstClass::VectorIntGraph, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 374 = V_MAD_U64_U32 + {InstClass::VectorIntArith64, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint64}, + // 375 = V_MAD_I64_I32 + {InstClass::VectorIntArith64, InstCategory::VectorALU, 3, 1, ScalarType::Sint32, + ScalarType::Sint64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 384 = V_NOP + {InstClass::VectorMisc, InstCategory::VectorALU, 0, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 385 = V_MOV_B32 + {InstClass::VectorRegMov, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 386 = V_READFIRSTLANE_B32 + {InstClass::VectorLane, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 387 = V_CVT_I32_F64 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Sint32}, + // 388 = V_CVT_F64_I32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, + ScalarType::Float64}, + // 389 = V_CVT_F32_I32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, + ScalarType::Float32}, + // 390 = V_CVT_F32_U32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 391 = V_CVT_U32_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Uint32}, + // 392 = V_CVT_I32_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Sint32}, + // 393 = V_MOV_FED_B32 + {InstClass::Undefined, InstCategory::Undefined, 1, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 394 = V_CVT_F16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float16}, + // 395 = V_CVT_F32_F16 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float16, + ScalarType::Float32}, + // 396 = V_CVT_RPI_I32_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Sint32}, + // 397 = V_CVT_FLR_I32_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Sint32}, + // 398 = V_CVT_OFF_F32_I4 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, + ScalarType::Float32}, + // 399 = V_CVT_F32_F64 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float32}, + // 400 = V_CVT_F64_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float64}, + // 401 = V_CVT_F32_UBYTE0 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 402 = V_CVT_F32_UBYTE1 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 403 = V_CVT_F32_UBYTE2 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 404 = V_CVT_F32_UBYTE3 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 405 = V_CVT_U32_F64 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Uint32}, + // 406 = V_CVT_F64_U32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 416 = V_FRACT_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 417 = V_TRUNC_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 418 = V_CEIL_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 419 = V_RNDNE_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 420 = V_FLOOR_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 421 = V_EXP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 422 = V_LOG_CLAMP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 423 = V_LOG_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 424 = V_RCP_CLAMP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 425 = V_RCP_LEGACY_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 426 = V_RCP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 427 = V_RCP_IFLAG_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 428 = V_RSQ_CLAMP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 429 = V_RSQ_LEGACY_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 430 = V_RSQ_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 431 = V_RCP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 432 = V_RCP_CLAMP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 433 = V_RSQ_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 434 = V_RSQ_CLAMP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 435 = V_SQRT_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 436 = V_SQRT_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 437 = V_SIN_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 438 = V_COS_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 439 = V_NOT_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 440 = V_BFREV_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 441 = V_FFBH_U32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 442 = V_FFBL_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 443 = V_FFBH_I32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 444 = V_FREXP_EXP_I32_F64 + {InstClass::VectorFpField64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Sint32}, + // 445 = V_FREXP_MANT_F64 + {InstClass::VectorFpField64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 446 = V_FRACT_F64 + {InstClass::VectorFpRound64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 447 = V_FREXP_EXP_I32_F32 + {InstClass::VectorFpField32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Sint32}, + // 448 = V_FREXP_MANT_F32 + {InstClass::VectorFpField32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 449 = V_CLREXCP + {InstClass::Undefined, InstCategory::Undefined, 0, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 450 = V_MOVRELD_B32 + {InstClass::VectorMovRel, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 451 = V_MOVRELS_B32 + {InstClass::VectorMovRel, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 452 = V_MOVRELSD_B32 + {InstClass::VectorMovRel, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 84 = V_RCP_F16 + {InstClass::VectorFpTran16, InstCategory::VectorALU, 1, 1, ScalarType::Float16, + ScalarType::Float16}, + // 85 = V_SQRT_F16 + {InstClass::VectorFpTran16, InstCategory::VectorALU, 1, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 771 = V_ADD_NC_U16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + {}, + {}, + {}, + // 775 = V_LSHRREV_B16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 776 = V_ASHRREV_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + {}, + {}, + {}, + {}, + // 781 = V_ADD_NC_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 782 = V_SUB_NC_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + {}, + // 784 = V_SUB_CO_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + {}, + {}, + // 788 = V_LSHLREV_B16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 833 = V_MAD_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 3, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + {}, + {}, + // 838 = V_LSHL_ADD_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 839 = V_ADD_LSHL_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 849 = V_MIN3_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 3, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + // 852 = V_MAX3_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 3, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + // 855 = V_MED3_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 3, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + {}, + {}, + {}, + {}, + // 862 = V_MAD_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 3, 1, ScalarType::Sint16, + ScalarType::Sint16}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 877 = V_ADD3_U32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + // 879 = V_LSHL_OR_B32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + // 881 = V_AND_OR_B32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 882 = V_OR3_B32 + {InstClass::VectorIntArith32, InstCategory::VectorALU, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}}}; + +constexpr std::array InstructionFormatVOP3P = {{ + // 0 = V_PK_MAD_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 3, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 1 = V_PK_MUL_LO_U16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 2 = V_PK_ADD_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 3 = V_PK_SUB_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 4 = V_PK_LSHLREV_B16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 5 = V_PK_LSHRREV_B16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 6 = V_PK_ASHRREV_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Uint16}, + // 7 = V_PK_MAX_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 8 = V_PK_MIN_I16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 9 = V_PK_MAD_U16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 3, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 10 = V_PK_ADD_U16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 11 = V_PK_SUB_U16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 12 = V_PK_MAX_U16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 13 = V_PK_MIN_U16 + {InstClass::VectorIntArith16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 14 = V_PK_FMA_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 3, 1, ScalarType::Float16, + ScalarType::Float16}, + // 15 = V_PK_ADD_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 16 = V_PK_MUL_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 17 = V_PK_MIN_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 18 = V_PK_MAX_F16 + {InstClass::VectorFpArith16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 32 = V_MAD_MIX_F32 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 33 = V_MAD_MIXLO_F16 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 34 = V_MAD_MIXHI_F16 + {InstClass::VectorFpArith32, InstCategory::VectorALU, 3, 1, ScalarType::Float32, + ScalarType::Float32}, +}}; + +constexpr std::array InstructionFormatVOP1 = {{ + // 0 = V_NOP + {InstClass::VectorMisc, InstCategory::VectorALU, 0, 1, ScalarType::Any, ScalarType::Any}, + // 1 = V_MOV_B32 + {InstClass::VectorRegMov, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 2 = V_READFIRSTLANE_B32 + {InstClass::VectorLane, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 3 = V_CVT_I32_F64 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float64, ScalarType::Sint32}, + // 4 = V_CVT_F64_I32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, ScalarType::Float64}, + // 5 = V_CVT_F32_I32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, ScalarType::Float32}, + // 6 = V_CVT_F32_U32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Float32}, + // 7 = V_CVT_U32_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, ScalarType::Uint32}, + // 8 = V_CVT_I32_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, ScalarType::Sint32}, + // 9 = V_MOV_FED_B32 + {InstClass::Undefined, InstCategory::Undefined, 1, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 10 = V_CVT_F16_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float16}, + // 11 = V_CVT_F32_F16 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float16, + ScalarType::Float32}, + // 12 = V_CVT_RPI_I32_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, ScalarType::Sint32}, + // 13 = V_CVT_FLR_I32_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, ScalarType::Sint32}, + // 14 = V_CVT_OFF_F32_I4 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, ScalarType::Float32}, + // 15 = V_CVT_F32_F64 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float32}, + // 16 = V_CVT_F64_F32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float64}, + // 17 = V_CVT_F32_UBYTE0 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Float32}, + // 18 = V_CVT_F32_UBYTE1 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Float32}, + // 19 = V_CVT_F32_UBYTE2 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Float32}, + // 20 = V_CVT_F32_UBYTE3 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Float32}, + // 21 = V_CVT_U32_F64 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Float64, ScalarType::Uint32}, + // 22 = V_CVT_F64_U32 + {InstClass::VectorConv, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, ScalarType::Float64}, + // 23 = V_TRUNC_F64 + {InstClass::VectorFpRound64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 24 = V_CEIL_F64 + {InstClass::VectorFpRound64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 25 = V_RNDNE_F64 + {InstClass::VectorFpRound64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 26 = V_FLOOR_F64 + {InstClass::VectorFpRound64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + // 32 = V_FRACT_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 33 = V_TRUNC_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 34 = V_CEIL_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 35 = V_RNDNE_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 36 = V_FLOOR_F32 + {InstClass::VectorFpRound32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 37 = V_EXP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 38 = V_LOG_CLAMP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 39 = V_LOG_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 40 = V_RCP_CLAMP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 41 = V_RCP_LEGACY_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 42 = V_RCP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 43 = V_RCP_IFLAG_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 44 = V_RSQ_CLAMP_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 45 = V_RSQ_LEGACY_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 46 = V_RSQ_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 47 = V_RCP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 48 = V_RCP_CLAMP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 49 = V_RSQ_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 50 = V_RSQ_CLAMP_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 51 = V_SQRT_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 52 = V_SQRT_F64 + {InstClass::VectorFpTran64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 53 = V_SIN_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 54 = V_COS_F32 + {InstClass::VectorFpTran32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 55 = V_NOT_B32 + {InstClass::VectorBitLogic, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 56 = V_BFREV_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 57 = V_FFBH_U32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 58 = V_FFBL_B32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 59 = V_FFBH_I32 + {InstClass::VectorBitField32, InstCategory::VectorALU, 1, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 60 = V_FREXP_EXP_I32_F64 + {InstClass::VectorFpField64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Sint32}, + // 61 = V_FREXP_MANT_F64 + {InstClass::VectorFpField64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 62 = V_FRACT_F64 + {InstClass::VectorFpRound64, InstCategory::VectorALU, 1, 1, ScalarType::Float64, + ScalarType::Float64}, + // 63 = V_FREXP_EXP_I32_F32 + {InstClass::VectorFpField32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Sint32}, + // 64 = V_FREXP_MANT_F32 + {InstClass::VectorFpField32, InstCategory::VectorALU, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 65 = V_CLREXCP + {InstClass::Undefined, InstCategory::Undefined, 0, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 66 = V_MOVRELD_B32 + {InstClass::VectorMovRel, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 67 = V_MOVRELS_B32 + {InstClass::VectorMovRel, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 68 = V_MOVRELSD_B32 + {InstClass::VectorMovRel, InstCategory::VectorALU, 1, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 84 = V_RCP_F16 + {InstClass::VectorFpTran16, InstCategory::VectorALU, 1, 1, ScalarType::Float16, + ScalarType::Float16}, + // 85 = V_SQRT_F16 + {InstClass::VectorFpTran16, InstCategory::VectorALU, 1, 1, ScalarType::Float16, + ScalarType::Float16}, +}}; + +constexpr std::array InstructionFormatVOPC = {{ + // 0 = V_CMP_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 1 = V_CMP_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 2 = V_CMP_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 3 = V_CMP_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 4 = V_CMP_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 5 = V_CMP_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 6 = V_CMP_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 7 = V_CMP_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 8 = V_CMP_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 9 = V_CMP_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 10 = V_CMP_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 11 = V_CMP_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 12 = V_CMP_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 13 = V_CMP_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 14 = V_CMP_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 15 = V_CMP_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 16 = V_CMPX_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 17 = V_CMPX_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 18 = V_CMPX_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 19 = V_CMPX_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 20 = V_CMPX_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 21 = V_CMPX_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 22 = V_CMPX_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 23 = V_CMPX_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 24 = V_CMPX_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 25 = V_CMPX_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 26 = V_CMPX_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 27 = V_CMPX_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 28 = V_CMPX_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 29 = V_CMPX_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 30 = V_CMPX_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 31 = V_CMPX_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 32 = V_CMP_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 33 = V_CMP_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 34 = V_CMP_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 35 = V_CMP_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 36 = V_CMP_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 37 = V_CMP_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 38 = V_CMP_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 39 = V_CMP_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 40 = V_CMP_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 41 = V_CMP_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 42 = V_CMP_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 43 = V_CMP_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 44 = V_CMP_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 45 = V_CMP_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 46 = V_CMP_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 47 = V_CMP_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 48 = V_CMPX_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 49 = V_CMPX_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 50 = V_CMPX_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 51 = V_CMPX_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 52 = V_CMPX_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 53 = V_CMPX_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 54 = V_CMPX_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 55 = V_CMPX_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 56 = V_CMPX_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 57 = V_CMPX_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 58 = V_CMPX_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 59 = V_CMPX_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 60 = V_CMPX_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 61 = V_CMPX_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 62 = V_CMPX_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 63 = V_CMPX_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 64 = V_CMPS_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 65 = V_CMPS_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 66 = V_CMPS_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 67 = V_CMPS_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 68 = V_CMPS_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 69 = V_CMPS_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 70 = V_CMPS_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 71 = V_CMPS_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 72 = V_CMPS_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 73 = V_CMPS_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 74 = V_CMPS_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 75 = V_CMPS_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 76 = V_CMPS_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 77 = V_CMPS_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 78 = V_CMPS_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 79 = V_CMPS_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 80 = V_CMPSX_F_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 81 = V_CMPSX_LT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 82 = V_CMPSX_EQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 83 = V_CMPSX_LE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 84 = V_CMPSX_GT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 85 = V_CMPSX_LG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 86 = V_CMPSX_GE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 87 = V_CMPSX_O_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 88 = V_CMPSX_U_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 89 = V_CMPSX_NGE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 90 = V_CMPSX_NLG_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 91 = V_CMPSX_NGT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 92 = V_CMPSX_NLE_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 93 = V_CMPSX_NEQ_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 94 = V_CMPSX_NLT_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 95 = V_CMPSX_TRU_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 96 = V_CMPS_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 97 = V_CMPS_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 98 = V_CMPS_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 99 = V_CMPS_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 100 = V_CMPS_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 101 = V_CMPS_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 102 = V_CMPS_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 103 = V_CMPS_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 104 = V_CMPS_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 105 = V_CMPS_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 106 = V_CMPS_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 107 = V_CMPS_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 108 = V_CMPS_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 109 = V_CMPS_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 110 = V_CMPS_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 111 = V_CMPS_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 112 = V_CMPSX_F_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 113 = V_CMPSX_LT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 114 = V_CMPSX_EQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 115 = V_CMPSX_LE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 116 = V_CMPSX_GT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 117 = V_CMPSX_LG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 118 = V_CMPSX_GE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 119 = V_CMPSX_O_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 120 = V_CMPSX_U_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 121 = V_CMPSX_NGE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 122 = V_CMPSX_NLG_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 123 = V_CMPSX_NGT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 124 = V_CMPSX_NLE_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 125 = V_CMPSX_NEQ_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 126 = V_CMPSX_NLT_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 127 = V_CMPSX_TRU_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + // 128 = V_CMP_F_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 129 = V_CMP_LT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 130 = V_CMP_EQ_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 131 = V_CMP_LE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 132 = V_CMP_GT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 133 = V_CMP_NE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 134 = V_CMP_GE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 135 = V_CMP_T_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 136 = V_CMP_CLASS_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + // 137 = V_CMP_LT_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 138 = V_CMP_EQ_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 139 = V_CMP_LE_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 140 = V_CMP_GT_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 141 = V_CMP_NE_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + // 142 = V_CMP_GE_I16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Sint16, + ScalarType::Sint16}, + {}, + // 144 = V_CMPX_F_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 145 = V_CMPX_LT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 146 = V_CMPX_EQ_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 147 = V_CMPX_LE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 148 = V_CMPX_GT_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 149 = V_CMPX_NE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 150 = V_CMPX_GE_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 151 = V_CMPX_T_I32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 152 = V_CMPX_CLASS_F32 + {InstClass::VectorFpCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Float32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 160 = V_CMP_F_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 161 = V_CMP_LT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 162 = V_CMP_EQ_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 163 = V_CMP_LE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 164 = V_CMP_GT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 165 = V_CMP_NE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 166 = V_CMP_GE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 167 = V_CMP_T_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 168 = V_CMP_CLASS_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + // 170 = V_CMP_EQ_U16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 171 = V_CMP_LE_U16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 172 = V_CMP_GT_U16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 173 = V_CMP_NE_U16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + // 174 = V_CMP_GE_U16 + {InstClass::VectorIntCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Uint16, + ScalarType::Uint16}, + {}, + // 176 = V_CMPX_F_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 177 = V_CMPX_LT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 178 = V_CMPX_EQ_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 179 = V_CMPX_LE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 180 = V_CMPX_GT_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 181 = V_CMPX_NE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 182 = V_CMPX_GE_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 183 = V_CMPX_T_I64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 184 = V_CMPX_CLASS_F64 + {InstClass::VectorFpCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 192 = V_CMP_F_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 193 = V_CMP_LT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 194 = V_CMP_EQ_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 195 = V_CMP_LE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 196 = V_CMP_GT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 197 = V_CMP_NE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 198 = V_CMP_GE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 199 = V_CMP_T_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 200 = V_CMP_F_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 201 = V_CMP_LT_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 202 = V_CMP_EQ_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 203 = V_CMP_LE_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 204 = V_CMP_GT_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 205 = V_CMP_LG_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 206 = V_CMP_GE_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 207 = V_CMP_O_F16 + {InstClass::VectorFpCmp16, InstCategory::VectorALU, 2, 1, ScalarType::Float16, + ScalarType::Float16}, + // 208 = V_CMPX_F_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 209 = V_CMPX_LT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 210 = V_CMPX_EQ_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 211 = V_CMPX_LE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 212 = V_CMPX_GT_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 213 = V_CMPX_NE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 214 = V_CMPX_GE_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 215 = V_CMPX_T_U32 + {InstClass::VectorIntCmp32, InstCategory::VectorALU, 2, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 224 = V_CMP_F_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 225 = V_CMP_LT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 226 = V_CMP_EQ_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 227 = V_CMP_LE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 228 = V_CMP_GT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 229 = V_CMP_NE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 230 = V_CMP_GE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 231 = V_CMP_T_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 240 = V_CMPX_F_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 241 = V_CMPX_LT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 242 = V_CMPX_EQ_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 243 = V_CMPX_LE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 244 = V_CMPX_GT_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 245 = V_CMPX_NE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 246 = V_CMPX_GE_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 247 = V_CMPX_T_U64 + {InstClass::VectorIntCmp64, InstCategory::VectorALU, 2, 1, ScalarType::Uint64, + ScalarType::Uint64}, +}}; + +constexpr std::array InstructionFormatVINTRP = {{ + // 0 = V_INTERP_P1_F32 + {InstClass::VectorInterpFpCache, InstCategory::VectorInterpolation, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 1 = V_INTERP_P2_F32 + {InstClass::VectorInterpFpCache, InstCategory::VectorInterpolation, 1, 1, ScalarType::Float32, + ScalarType::Float32}, + // 2 = V_INTERP_MOV_F32 + {InstClass::VectorInterpFpCache, InstCategory::VectorInterpolation, 1, 1, ScalarType::Float32, + ScalarType::Float32}, +}}; + +constexpr std::array InstructionFormatDS = {{ + // 0 = DS_ADD_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 1 = DS_SUB_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 2 = DS_RSUB_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 3 = DS_INC_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 4 = DS_DEC_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 5 = DS_MIN_I32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 6 = DS_MAX_I32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 7 = DS_MIN_U32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 8 = DS_MAX_U32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 9 = DS_AND_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 10 = DS_OR_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 11 = DS_XOR_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 12 = DS_MSKOR_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 13 = DS_WRITE_B32 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 14 = DS_WRITE2_B32 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 15 = DS_WRITE2ST64_B32 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 16 = DS_CMPST_B32 + {InstClass::DsAtomicCmpSt32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 17 = DS_CMPST_F32 + {InstClass::DsAtomicCmpSt32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 18 = DS_MIN_F32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 19 = DS_MAX_F32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 20 = DS_NOP + {InstClass::DsDataShareMisc, InstCategory::DataShare, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + {}, + {}, + {}, + // 24 = DS_GWS_SEMA_RELEASE_ALL + {InstClass::GdsSync, InstCategory::DataShare, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 25 = DS_GWS_INIT + {InstClass::GdsSync, InstCategory::DataShare, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 26 = DS_GWS_SEMA_V + {InstClass::GdsSync, InstCategory::DataShare, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 27 = DS_GWS_SEMA_BR + {InstClass::GdsSync, InstCategory::DataShare, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 28 = DS_GWS_SEMA_P + {InstClass::GdsSync, InstCategory::DataShare, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 29 = DS_GWS_BARRIER + {InstClass::ScalarSync, InstCategory::FlowControl, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 30 = DS_WRITE_B8 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 31 = DS_WRITE_B16 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 32 = DS_ADD_RTN_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 33 = DS_SUB_RTN_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 34 = DS_RSUB_RTN_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 35 = DS_INC_RTN_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 36 = DS_DEC_RTN_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 37 = DS_MIN_RTN_I32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 38 = DS_MAX_RTN_I32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 39 = DS_MIN_RTN_U32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 40 = DS_MAX_RTN_U32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 41 = DS_AND_RTN_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 42 = DS_OR_RTN_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 43 = DS_XOR_RTN_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 44 = DS_MSKOR_RTN_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 45 = DS_WRXCHG_RTN_B32 + {InstClass::DsIdxWrXchg, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 46 = DS_WRXCHG2_RTN_B32 + {InstClass::DsIdxWrXchg, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 47 = DS_WRXCHG2ST64_RTN_B32 + {InstClass::DsIdxWrXchg, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 48 = DS_CMPST_RTN_B32 + {InstClass::DsAtomicCmpSt32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 49 = DS_CMPST_RTN_F32 + {InstClass::DsAtomicCmpSt32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 50 = DS_MIN_RTN_F32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 51 = DS_MAX_RTN_F32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 52 = DS_WRAP_RTN_B32 + {InstClass::DsIdxWrap, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 53 = DS_SWIZZLE_B32 + {InstClass::DsDataShareUt, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 54 = DS_READ_B32 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 55 = DS_READ2_B32 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 56 = DS_READ2ST64_B32 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 57 = DS_READ_I8 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 58 = DS_READ_U8 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 59 = DS_READ_I16 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Sint32, ScalarType::Sint32}, + // 60 = DS_READ_U16 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 61 = DS_CONSUME + {InstClass::DsAppendCon, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 62 = DS_APPEND + {InstClass::DsAppendCon, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 63 = DS_ORDERED_COUNT + {InstClass::GdsOrdCnt, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + // 64 = DS_ADD_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 65 = DS_SUB_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 66 = DS_RSUB_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 67 = DS_INC_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 68 = DS_DEC_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 69 = DS_MIN_I64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 70 = DS_MAX_I64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 71 = DS_MIN_U64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 72 = DS_MAX_U64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 73 = DS_AND_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 74 = DS_OR_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 75 = DS_XOR_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 76 = DS_MSKOR_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 77 = DS_WRITE_B64 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 78 = DS_WRITE2_B64 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 79 = DS_WRITE2ST64_B64 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 80 = DS_CMPST_B64 + {InstClass::DsAtomicCmpSt64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 81 = DS_CMPST_F64 + {InstClass::DsAtomicCmpSt64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 82 = DS_MIN_F64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 83 = DS_MAX_F64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 96 = DS_ADD_RTN_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 97 = DS_SUB_RTN_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 98 = DS_RSUB_RTN_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 99 = DS_INC_RTN_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 100 = DS_DEC_RTN_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 101 = DS_MIN_RTN_I64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 102 = DS_MAX_RTN_I64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 103 = DS_MIN_RTN_U64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 104 = DS_MAX_RTN_U64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 105 = DS_AND_RTN_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 106 = DS_OR_RTN_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 107 = DS_XOR_RTN_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 108 = DS_MSKOR_RTN_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 109 = DS_WRXCHG_RTN_B64 + {InstClass::DsIdxWrXchg, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 110 = DS_WRXCHG2_RTN_B64 + {InstClass::DsIdxWrXchg, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 111 = DS_WRXCHG2ST64_RTN_B64 + {InstClass::DsIdxWrXchg, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 112 = DS_CMPST_RTN_B64 + {InstClass::DsAtomicCmpSt64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 113 = DS_CMPST_RTN_F64 + {InstClass::DsAtomicCmpSt64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 114 = DS_MIN_RTN_F64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 115 = DS_MAX_RTN_F64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + // 118 = DS_READ_B64 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 119 = DS_READ2_B64 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + // 120 = DS_READ2ST64_B64 + {InstClass::DsIdxRd, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + {}, + {}, + {}, + {}, + {}, + // 126 = DS_CONDXCHG32_RTN_B64 + {InstClass::DsIdxCondXchg, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + {}, + // 128 = DS_ADD_SRC2_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 129 = DS_SUB_SRC2_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 130 = DS_RSUB_SRC2_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 131 = DS_INC_SRC2_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 132 = DS_DEC_SRC2_U32 + {InstClass::DsAtomicArith32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 133 = DS_MIN_SRC2_I32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 134 = DS_MAX_SRC2_I32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 135 = DS_MIN_SRC2_U32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 136 = DS_MAX_SRC2_U32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 137 = DS_AND_SRC2_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 138 = DS_OR_SRC2_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 139 = DS_XOR_SRC2_B32 + {InstClass::DsAtomicLogic32, InstCategory::DataShare, 3, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + // 141 = DS_WRITE_SRC2_B32 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32}, + {}, + {}, + {}, + {}, + // 146 = DS_MIN_SRC2_F32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + // 147 = DS_MAX_SRC2_F32 + {InstClass::DsAtomicMinMax32, InstCategory::DataShare, 3, 1, ScalarType::Float32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 192 = DS_ADD_SRC2_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 193 = DS_SUB_SRC2_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 194 = DS_RSUB_SRC2_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 195 = DS_INC_SRC2_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 196 = DS_DEC_SRC2_U64 + {InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 197 = DS_MIN_SRC2_I64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 198 = DS_MAX_SRC2_I64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Sint64, + ScalarType::Sint64}, + // 199 = DS_MIN_SRC2_U64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 200 = DS_MAX_SRC2_U64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 201 = DS_AND_SRC2_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 202 = DS_OR_SRC2_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + // 203 = DS_XOR_SRC2_B64 + {InstClass::DsAtomicLogic64, InstCategory::DataShare, 3, 1, ScalarType::Uint64, + ScalarType::Uint64}, + {}, + // 205 = DS_WRITE_SRC2_B64 + {InstClass::DsIdxWr, InstCategory::DataShare, 3, 1, ScalarType::Uint64, ScalarType::Uint64}, + {}, + {}, + {}, + {}, + // 210 = DS_MIN_SRC2_F64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + // 211 = DS_MAX_SRC2_F64 + {InstClass::DsAtomicMinMax64, InstCategory::DataShare, 3, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 222 = DS_WRITE_B96 + {InstClass::Undefined, InstCategory::Undefined, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 223 = DS_WRITE_B128 + {InstClass::Undefined, InstCategory::Undefined, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 253 = DS_CONDXCHG32_RTN_B128 + {InstClass::Undefined, InstCategory::Undefined, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 254 = DS_READ_B96 + {InstClass::Undefined, InstCategory::Undefined, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 255 = DS_READ_B128 + {InstClass::Undefined, InstCategory::Undefined, 3, 1, ScalarType::Undefined, + ScalarType::Undefined}, +}}; + +constexpr std::array InstructionFormatMUBUF = {{ + // 0 = BUFFER_LOAD_FORMAT_X + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 1 = BUFFER_LOAD_FORMAT_XY + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 2 = BUFFER_LOAD_FORMAT_XYZ + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 3 = BUFFER_LOAD_FORMAT_XYZW + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 4 = BUFFER_STORE_FORMAT_X + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 5 = BUFFER_STORE_FORMAT_XY + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 6 = BUFFER_STORE_FORMAT_XYZ + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 7 = BUFFER_STORE_FORMAT_XYZW + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 8 = BUFFER_LOAD_UBYTE + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 9 = BUFFER_LOAD_SBYTE + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 10 = BUFFER_LOAD_USHORT + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 11 = BUFFER_LOAD_SSHORT + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 12 = BUFFER_LOAD_DWORD + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 13 = BUFFER_LOAD_DWORDX2 + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 14 = BUFFER_LOAD_DWORDX4 + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 15 = BUFFER_LOAD_DWORDX3 + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 24 = BUFFER_STORE_BYTE + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + // 26 = BUFFER_STORE_SHORT + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + // 28 = BUFFER_STORE_DWORD + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 29 = BUFFER_STORE_DWORDX2 + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 30 = BUFFER_STORE_DWORDX4 + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 31 = BUFFER_STORE_DWORDX3 + {InstClass::VectorMemBufNoFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 48 = BUFFER_ATOMIC_SWAP + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 49 = BUFFER_ATOMIC_CMPSWAP + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 50 = BUFFER_ATOMIC_ADD + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 51 = BUFFER_ATOMIC_SUB + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + // 53 = BUFFER_ATOMIC_SMIN + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 54 = BUFFER_ATOMIC_UMIN + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 55 = BUFFER_ATOMIC_SMAX + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 56 = BUFFER_ATOMIC_UMAX + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 57 = BUFFER_ATOMIC_AND + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 58 = BUFFER_ATOMIC_OR + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 59 = BUFFER_ATOMIC_XOR + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 60 = BUFFER_ATOMIC_INC + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 61 = BUFFER_ATOMIC_DEC + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 62 = BUFFER_ATOMIC_FCMPSWAP + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 63 = BUFFER_ATOMIC_FMIN + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 64 = BUFFER_ATOMIC_FMAX + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 80 = BUFFER_ATOMIC_SWAP_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 81 = BUFFER_ATOMIC_CMPSWAP_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 82 = BUFFER_ATOMIC_ADD_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 83 = BUFFER_ATOMIC_SUB_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + {}, + // 85 = BUFFER_ATOMIC_SMIN_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 86 = BUFFER_ATOMIC_UMIN_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 87 = BUFFER_ATOMIC_SMAX_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 88 = BUFFER_ATOMIC_UMAX_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 89 = BUFFER_ATOMIC_AND_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 90 = BUFFER_ATOMIC_OR_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 91 = BUFFER_ATOMIC_XOR_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 92 = BUFFER_ATOMIC_INC_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 93 = BUFFER_ATOMIC_DEC_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Uint64, + ScalarType::Uint32}, + // 94 = BUFFER_ATOMIC_FCMPSWAP_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Float64, + ScalarType::Float64}, + // 95 = BUFFER_ATOMIC_FMIN_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Float64, + ScalarType::Float64}, + // 96 = BUFFER_ATOMIC_FMAX_X2 + {InstClass::VectorMemBufAtomic, InstCategory::VectorMemory, 4, 1, ScalarType::Float64, + ScalarType::Float64}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 112 = BUFFER_WBINVL1_SC + {InstClass::VectorMemL1Cache, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 113 = BUFFER_WBINVL1 + {InstClass::VectorMemL1Cache, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, +}}; + +constexpr std::array InstructionFormatMTBUF = {{ + // 0 = TBUFFER_LOAD_FORMAT_X + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 1 = TBUFFER_LOAD_FORMAT_XY + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 2 = TBUFFER_LOAD_FORMAT_XYZ + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 3 = TBUFFER_LOAD_FORMAT_XYZW + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 4 = TBUFFER_STORE_FORMAT_X + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 5 = TBUFFER_STORE_FORMAT_XY + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 6 = TBUFFER_STORE_FORMAT_XYZ + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 7 = TBUFFER_STORE_FORMAT_XYZW + {InstClass::VectorMemBufFmt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, +}}; + +constexpr std::array InstructionFormatMIMG = {{ + // 0 = IMAGE_LOAD + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 1 = IMAGE_LOAD_MIP + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 2 = IMAGE_LOAD_PCK + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 3 = IMAGE_LOAD_PCK_SGN + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 4 = IMAGE_LOAD_MIP_PCK + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 5 = IMAGE_LOAD_MIP_PCK_SGN + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + // 8 = IMAGE_STORE + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 9 = IMAGE_STORE_MIP + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 10 = IMAGE_STORE_PCK + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 11 = IMAGE_STORE_MIP_PCK + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + // 14 = IMAGE_GET_RESINFO + {InstClass::VectorMemImgUt, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 15 = IMAGE_ATOMIC_SWAP + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 16 = IMAGE_ATOMIC_CMPSWAP + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 17 = IMAGE_ATOMIC_ADD + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 18 = IMAGE_ATOMIC_SUB + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + {}, + // 20 = IMAGE_ATOMIC_SMIN + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 21 = IMAGE_ATOMIC_UMIN + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 22 = IMAGE_ATOMIC_SMAX + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Sint32, + ScalarType::Sint32}, + // 23 = IMAGE_ATOMIC_UMAX + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 24 = IMAGE_ATOMIC_AND + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 25 = IMAGE_ATOMIC_OR + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 26 = IMAGE_ATOMIC_XOR + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 27 = IMAGE_ATOMIC_INC + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 28 = IMAGE_ATOMIC_DEC + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Uint32}, + // 29 = IMAGE_ATOMIC_FCMPSWAP + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 30 = IMAGE_ATOMIC_FMIN + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 31 = IMAGE_ATOMIC_FMAX + {InstClass::VectorMemImgNoSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 32 = IMAGE_SAMPLE + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 33 = IMAGE_SAMPLE_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 34 = IMAGE_SAMPLE_D + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 35 = IMAGE_SAMPLE_D_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 36 = IMAGE_SAMPLE_L + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 37 = IMAGE_SAMPLE_B + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 38 = IMAGE_SAMPLE_B_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 39 = IMAGE_SAMPLE_LZ + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 40 = IMAGE_SAMPLE_C + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 41 = IMAGE_SAMPLE_C_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 42 = IMAGE_SAMPLE_C_D + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 43 = IMAGE_SAMPLE_C_D_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 44 = IMAGE_SAMPLE_C_L + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 45 = IMAGE_SAMPLE_C_B + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 46 = IMAGE_SAMPLE_C_B_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 47 = IMAGE_SAMPLE_C_LZ + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 48 = IMAGE_SAMPLE_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 49 = IMAGE_SAMPLE_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 50 = IMAGE_SAMPLE_D_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 51 = IMAGE_SAMPLE_D_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 52 = IMAGE_SAMPLE_L_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 53 = IMAGE_SAMPLE_B_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 54 = IMAGE_SAMPLE_B_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 55 = IMAGE_SAMPLE_LZ_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 56 = IMAGE_SAMPLE_C_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 57 = IMAGE_SAMPLE_C_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 58 = IMAGE_SAMPLE_C_D_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 59 = IMAGE_SAMPLE_C_D_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 60 = IMAGE_SAMPLE_C_L_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 61 = IMAGE_SAMPLE_C_B_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 62 = IMAGE_SAMPLE_C_B_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 63 = IMAGE_SAMPLE_C_LZ_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 64 = IMAGE_GATHER4 + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 65 = IMAGE_GATHER4_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + // 68 = IMAGE_GATHER4_L + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 69 = IMAGE_GATHER4_B + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 70 = IMAGE_GATHER4_B_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 71 = IMAGE_GATHER4_LZ + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 72 = IMAGE_GATHER4_C + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 73 = IMAGE_GATHER4_C_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + // 76 = IMAGE_GATHER4_C_L + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 77 = IMAGE_GATHER4_C_B + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 78 = IMAGE_GATHER4_C_B_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 79 = IMAGE_GATHER4_C_LZ + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 80 = IMAGE_GATHER4_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 81 = IMAGE_GATHER4_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + // 84 = IMAGE_GATHER4_L_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 85 = IMAGE_GATHER4_B_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 86 = IMAGE_GATHER4_B_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 87 = IMAGE_GATHER4_LZ_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 88 = IMAGE_GATHER4_C_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 89 = IMAGE_GATHER4_C_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + {}, + {}, + // 92 = IMAGE_GATHER4_C_L_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 93 = IMAGE_GATHER4_C_B_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 94 = IMAGE_GATHER4_C_B_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 95 = IMAGE_GATHER4_C_LZ_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32, + ScalarType::Float32}, + // 96 = IMAGE_GET_LOD + {InstClass::VectorMemImgUt, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + // 104 = IMAGE_SAMPLE_CD + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Float32, + ScalarType::Float32}, + // 105 = IMAGE_SAMPLE_CD_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 106 = IMAGE_SAMPLE_C_CD + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 107 = IMAGE_SAMPLE_C_CD_CL + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 108 = IMAGE_SAMPLE_CD_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 109 = IMAGE_SAMPLE_CD_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 110 = IMAGE_SAMPLE_C_CD_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, + // 111 = IMAGE_SAMPLE_C_CD_CL_O + {InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined, + ScalarType::Undefined}, +}}; + +constexpr std::array InstructionFormatEXP = {{ + {InstClass::Exp, InstCategory::Export, 4, 1, ScalarType::Float32, ScalarType::Any}, +}}; + +InstFormat InstructionFormat(InstEncoding encoding, uint32_t opcode) { + switch (encoding) { + case InstEncoding::SOP1: + return InstructionFormatSOP1[opcode]; + case InstEncoding::SOPP: + return InstructionFormatSOPP[opcode]; + case InstEncoding::SOPC: + return InstructionFormatSOPC[opcode]; + case InstEncoding::VOP1: + return InstructionFormatVOP1[opcode]; + case InstEncoding::VOPC: + return InstructionFormatVOPC[opcode]; + case InstEncoding::VOP3: + return InstructionFormatVOP3[opcode]; + case InstEncoding::VOP3P: + return InstructionFormatVOP3P[opcode]; + case InstEncoding::EXP: + return InstructionFormatEXP[opcode]; + case InstEncoding::VINTRP: + return InstructionFormatVINTRP[opcode]; + case InstEncoding::DS: + return InstructionFormatDS[opcode]; + case InstEncoding::MUBUF: + return InstructionFormatMUBUF[opcode]; + case InstEncoding::MTBUF: + return InstructionFormatMTBUF[opcode]; + case InstEncoding::MIMG: + return InstructionFormatMIMG[opcode]; + case InstEncoding::SMRD: + return InstructionFormatSMRD[opcode]; + case InstEncoding::SOPK: + return InstructionFormatSOPK[opcode]; + case InstEncoding::SOP2: + return InstructionFormatSOP2[opcode]; + case InstEncoding::VOP2: + return InstructionFormatVOP2[opcode]; + default: + UNREACHABLE(); + } + return {}; +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/instruction.cpp b/gpu/shadps4/shader_recompiler/frontend/instruction.cpp new file mode 100644 index 0000000..246c2b8 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/instruction.cpp @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "shader_recompiler/frontend/instruction.h" + +namespace Shader::Gcn { + +u32 GcnInst::BranchTarget(u32 pc) const { + const s32 simm = static_cast(control.sopp.simm) * 4; + const u32 target = pc + simm + 4; + return target; +} + +bool GcnInst::IsTerminateInstruction() const { + return IsUnconditionalBranch() || IsConditionalBranch() || IsFork() || + opcode == Opcode::S_ENDPGM; +} + +bool GcnInst::IsUnconditionalBranch() const { + return opcode == Opcode::S_BRANCH || opcode == Opcode::S_SETPC_B64; +} + +bool GcnInst::IsFork() const { + return opcode == Opcode::S_CBRANCH_I_FORK || opcode == Opcode::S_CBRANCH_G_FORK || + opcode == Opcode::S_CBRANCH_JOIN; +} + +bool GcnInst::IsConditionalBranch() const { + switch (opcode) { + case Opcode::S_CBRANCH_SCC0: + case Opcode::S_CBRANCH_SCC1: + case Opcode::S_CBRANCH_VCCZ: + case Opcode::S_CBRANCH_VCCNZ: + case Opcode::S_CBRANCH_EXECZ: + case Opcode::S_CBRANCH_EXECNZ: + return true; + case Opcode::S_CBRANCH_CDBGSYS: + case Opcode::S_CBRANCH_CDBGUSER: + case Opcode::S_CBRANCH_CDBGSYS_OR_USER: + case Opcode::S_CBRANCH_CDBGSYS_AND_USER: + UNIMPLEMENTED(); + return true; + default: + break; + } + return false; +} + +bool GcnInst::IsCmpx() const { + if ((opcode >= Opcode::V_CMPX_F_F32 && opcode <= Opcode::V_CMPX_T_F32) || + (opcode >= Opcode::V_CMPX_F_F64 && opcode <= Opcode::V_CMPX_T_F64) || + (opcode >= Opcode::V_CMPSX_F_F32 && opcode <= Opcode::V_CMPSX_T_F32) || + (opcode >= Opcode::V_CMPSX_F_F64 && opcode <= Opcode::V_CMPSX_T_F64) || + (opcode >= Opcode::V_CMPX_F_I32 && opcode <= Opcode::V_CMPX_CLASS_F32) || + (opcode >= Opcode::V_CMPX_F_I64 && opcode <= Opcode::V_CMPX_CLASS_F64) || + (opcode >= Opcode::V_CMPX_F_U32 && opcode <= Opcode::V_CMPX_T_U32) || + (opcode >= Opcode::V_CMPX_F_U64 && opcode <= Opcode::V_CMPX_T_U64)) { + return true; + } + return false; +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/instruction.h b/gpu/shadps4/shader_recompiler/frontend/instruction.h new file mode 100644 index 0000000..e3a65af --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/instruction.h @@ -0,0 +1,362 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "shader_recompiler/frontend/opcodes.h" + +namespace Shader::Gcn { + +constexpr u32 GcnMaxSrcCount = 4; +constexpr u32 GcnMaxDstCount = 2; + +enum OperandFieldRange { + ScalarGPRMin = 0, + ScalarGPRMax = 103, + SignedConstIntPosMin = 129, + SignedConstIntPosMax = 192, + SignedConstIntNegMin = 193, + SignedConstIntNegMax = 208, + ConstFloatMin = 240, + VectorGPRMin = 256, + VectorGPRMax = 511 +}; + +/// These are applied after loading an operand register. +struct InputModifiers { + bool neg = false; + bool neg_hi = false; + bool abs = false; + bool sext = false; +}; + +/// These are applied before storing an operand register. +struct OutputModifiers { + bool clamp = false; + float multiplier = 0.f; +}; + +struct OperandSelection { + bool op_sel = false; + bool op_sel_hi = false; +}; + +enum class SdwaSelector : u32 { + Byte0 = 0, + Byte1 = 1, + Byte2 = 2, + Byte3 = 3, + Word0 = 4, + Word1 = 5, + Dword = 6, + Invalid = 7, +}; + +enum class SdwaDstUnused : u32 { + Pad = 0, + Sext = 1, + Preserve = 2, + Invalid = 3, +}; + +enum class DppCtrl : u16 { + DppQuadPerm = 0, + DppRowShl = 0x101, + DppRowShr = 0x111, + DppRowRor = 0x121, + DppRowMirror = 0x140, + DppRowHalfMirror = 0x141, +}; + +struct DppOperation { + DppCtrl op; + u16 value; + bool bc; + u8 row_mask; + u8 bank_mask; +}; + +struct InstOperand { + OperandField field = OperandField::Undefined; + ScalarType type = ScalarType::Undefined; + InputModifiers input_modifier = {}; + OutputModifiers output_modifier = {}; + // only valid for packed 16bit operations + OperandSelection op_sel = {}; + SdwaDstUnused sdwa_dst = SdwaDstUnused::Invalid; + SdwaSelector sdwa_sel = SdwaSelector::Invalid; + std::optional dpp = {}; + u32 code = 0xFFFFFFFF; +}; + +struct Operand { + OperandField field = OperandField::Undefined; + ScalarType type = ScalarType::Undefined; + union { + InputModifiers input_modifier = {}; + OutputModifiers output_modifier; + }; + u32 code = 0xFFFFFFFF; +}; + +struct InstSOPK { + u16 simm; +}; + +struct InstSOPP { + u16 simm; +}; + +struct InstVOP3 { + Operand vdst; + Operand src0; + Operand src1; + Operand src2; +}; + +struct SMRD { + u8 offset; + bool imm; + u8 sbase; +}; + +struct InstControlSOPK { + s16 simm; +}; + +struct InstControlSOPP { + s16 simm; +}; + +struct InstControlVOP3 { + u64 : 8; + u64 abs : 3; + u64 clmp : 1; + u64 op_sel : 4; + u64 : 43; + u64 omod : 2; + u64 neg : 3; +}; + +struct InstControlVOP3P { + u64 : 8; + u64 neg_hi : 3; + u64 op_sel : 3; + u64 op_sel_hi_2 : 1; + u64 clamp : 1; + u64 : 43; + u64 op_sel_hi_01 : 2; + u64 neg : 3; + + bool get_op_sel_hi(int idx) const { + switch (idx) { + case 0: + return (op_sel_hi_01 & 1) == 1; + case 1: + return ((op_sel_hi_01 >> 1) & 1) == 1; + case 2: + return (op_sel_hi_2 & 1) == 1; + default: + UNREACHABLE_MSG("get_op_sel_hi: {}", idx); + } + } +}; + +static_assert(sizeof(InstControlVOP3P) == 8); + +struct InstControlSMRD { + u32 offset : 8; + u32 imm : 1; + u32 count : 5; + u32 : 18; +}; + +struct InstControlMUBUF { + u64 offset : 12; + u64 offen : 1; + u64 idxen : 1; + u64 glc : 1; + u64 addr64 : 1; + u64 lds : 1; + u64 : 37; + u64 slc : 1; + u64 tfe : 1; + u64 count : 3; + u64 size : 5; +}; + +struct InstControlMTBUF { + u64 offset : 12; + u64 offen : 1; + u64 idxen : 1; + u64 glc : 1; + u64 addr64 : 1; + u64 : 3; + u64 dfmt : 4; + u64 nfmt : 3; + u64 : 28; + u64 slc : 1; + u64 tfe : 1; + u64 count : 3; + u64 size : 5; +}; + +struct InstControlMIMG { + u64 : 8; + u64 dmask : 4; + u64 unrm : 1; + u64 glc : 1; + u64 da : 1; + u64 r128 : 1; + u64 tfe : 1; + u64 lwe : 1; + u64 : 7; + u64 slc : 1; + u64 mod : 32; + u64 : 6; +}; + +struct InstControlDS { + u64 offset0 : 8; + u64 offset1 : 8; + u64 : 1; + u64 gds : 1; + u64 dual : 1; + u64 sign : 1; + u64 relative : 1; + u64 stride : 1; + u64 size : 4; + u64 : 38; +}; + +struct InstControlVINTRP { + u32 : 8; + u32 chan : 2; + u32 attr : 6; + u32 : 16; +}; + +struct InstControlEXP { + u64 en : 4; + u64 target : 6; + u64 compr : 1; + u64 done : 1; + u64 vm : 1; + u64 reserved : 51; +}; + +union InstControl { + InstControlSOPK sopk; + InstControlSOPP sopp; + InstControlVOP3 vop3; + InstControlVOP3P vop3p; + InstControlSMRD smrd; + InstControlMUBUF mubuf; + InstControlMTBUF mtbuf; + InstControlMIMG mimg; + InstControlDS ds; + InstControlVINTRP vintrp; + InstControlEXP exp; +}; + +struct SdwaVop12 { + u32 src0 : 8; + u32 dst_sel : 3; + u32 dst_u : 2; + u32 clamp : 1; + u32 omod : 2; + u32 src0_sel : 3; + u32 src0_sext : 1; + u32 src0_neg : 1; + u32 src0_abs : 1; + u32 : 1; + u32 s0 : 1; + + u32 src1_sel : 3; + u32 src1_sext : 1; + u32 src1_neg : 1; + u32 src1_abs : 1; + u32 : 1; + u32 s1 : 1; +}; + +struct SdwaVopc { + u32 src0 : 8; + u32 sdst : 7; + u32 sd : 1; + u32 src0_sel : 3; + u32 src0_sext : 1; + u32 src0_neg : 1; + u32 src0_abs : 1; + u32 : 1; + u32 s0 : 1; + + u32 src1_sel : 3; + u32 src1_sext : 1; + u32 src1_neg : 1; + u32 src1_abs : 1; + u32 : 1; + u32 s1 : 1; +}; + +union Sdwa { + SdwaVopc vopc; + SdwaVop12 vop12; +}; + +struct Dpp { + u32 src0 : 8; + u32 dpp_ctrl : 9; + u32 : 1; + u32 fi : 1; + u32 bc : 1; + u32 src0_neg : 1; + u32 src0_abs : 1; + u32 src1_neg : 1; + u32 src1_abs : 1; + u32 bank_mask : 4; + u32 row_mask : 4; + + DppOperation GetOperation() const { + if (dpp_ctrl >= u32(DppCtrl::DppQuadPerm) && dpp_ctrl < 0x100) { + return {DppCtrl::DppQuadPerm, u16(dpp_ctrl & 0xFF), bool(bc), u8(row_mask), + u8(bank_mask)}; + } else if (dpp_ctrl >= u32(DppCtrl::DppRowShl) && dpp_ctrl < 0x110) { + return {DppCtrl::DppRowShl, u16(dpp_ctrl & 0xF), bool(bc), u8(row_mask), u8(bank_mask)}; + } else if (dpp_ctrl >= u32(DppCtrl::DppRowShr) && dpp_ctrl < 0x120) { + return {DppCtrl::DppRowShr, u16(dpp_ctrl & 0xF), bool(bc), u8(row_mask), u8(bank_mask)}; + } else if (dpp_ctrl >= u32(DppCtrl::DppRowRor) && dpp_ctrl < 0x130) { + return {DppCtrl::DppRowRor, u16(dpp_ctrl & 0xF), bool(bc), u8(row_mask), u8(bank_mask)}; + } else if (dpp_ctrl == u32(DppCtrl::DppRowMirror)) { + return {DppCtrl::DppRowMirror, 0, bool(bc), u8(row_mask), u8(bank_mask)}; + } else if (dpp_ctrl == u32(DppCtrl::DppRowHalfMirror)) { + return {DppCtrl::DppRowHalfMirror, 0, bool(bc), u8(row_mask), u8(bank_mask)}; + } else { + UNREACHABLE_MSG("malformed dpp_ctrl"); + } + } +}; + +struct GcnInst { + Opcode opcode; + InstEncoding encoding; + InstClass inst_class; + InstCategory category; + InstControl control; + u32 length; + u32 src_count; + u32 dst_count; + std::array src; + std::array dst; + + u32 BranchTarget(u32 pc) const; + + bool IsTerminateInstruction() const; + bool IsUnconditionalBranch() const; + bool IsConditionalBranch() const; + bool IsFork() const; + bool IsCmpx() const; +}; + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/opcodes.h b/gpu/shadps4/shader_recompiler/frontend/opcodes.h new file mode 100644 index 0000000..64b20e1 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/opcodes.h @@ -0,0 +1,2708 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/enum.h" +#include "common/types.h" + +namespace Shader::Gcn { + +enum class OpcodeSOP2 : u32 { + S_ADD_U32 = 0, + S_SUB_U32 = 1, + S_ADD_I32 = 2, + S_SUB_I32 = 3, + S_ADDC_U32 = 4, + S_SUBB_U32 = 5, + S_MIN_I32 = 6, + S_MIN_U32 = 7, + S_MAX_I32 = 8, + S_MAX_U32 = 9, + S_CSELECT_B32 = 10, + S_CSELECT_B64 = 11, + S_AND_B32 = 14, + S_AND_B64 = 15, + S_OR_B32 = 16, + S_OR_B64 = 17, + S_XOR_B32 = 18, + S_XOR_B64 = 19, + S_ANDN2_B32 = 20, + S_ANDN2_B64 = 21, + S_ORN2_B32 = 22, + S_ORN2_B64 = 23, + S_NAND_B32 = 24, + S_NAND_B64 = 25, + S_NOR_B32 = 26, + S_NOR_B64 = 27, + S_XNOR_B32 = 28, + S_XNOR_B64 = 29, + S_LSHL_B32 = 30, + S_LSHL_B64 = 31, + S_LSHR_B32 = 32, + S_LSHR_B64 = 33, + S_ASHR_I32 = 34, + S_ASHR_I64 = 35, + S_BFM_B32 = 36, + S_BFM_B64 = 37, + S_MUL_I32 = 38, + S_BFE_U32 = 39, + S_BFE_I32 = 40, + S_BFE_U64 = 41, + S_BFE_I64 = 42, + S_CBRANCH_G_FORK = 43, + S_ABSDIFF_I32 = 44, + + OP_RANGE_SOP2 = S_ABSDIFF_I32 + 1, +}; + +enum class OpcodeSOPK : u32 { + S_MOVK_I32 = 0, + S_CMOVK_I32 = 2, + S_CMPK_EQ_I32 = 3, + S_CMPK_LG_I32 = 4, + S_CMPK_GT_I32 = 5, + S_CMPK_GE_I32 = 6, + S_CMPK_LT_I32 = 7, + S_CMPK_LE_I32 = 8, + S_CMPK_EQ_U32 = 9, + S_CMPK_LG_U32 = 10, + S_CMPK_GT_U32 = 11, + S_CMPK_GE_U32 = 12, + S_CMPK_LT_U32 = 13, + S_CMPK_LE_U32 = 14, + S_ADDK_I32 = 15, + S_MULK_I32 = 16, + S_CBRANCH_I_FORK = 17, + S_GETREG_B32 = 18, + S_SETREG_B32 = 19, + S_GETREG_REGRD_B32 = 20, + S_SETREG_IMM32_B32 = 21, + + OP_RANGE_SOPK = S_SETREG_IMM32_B32 + 1, +}; + +enum class OpcodeSOP1 : u32 { + S_MOV_B32 = 3, + S_MOV_B64 = 4, + S_CMOV_B32 = 5, + S_CMOV_B64 = 6, + S_NOT_B32 = 7, + S_NOT_B64 = 8, + S_WQM_B32 = 9, + S_WQM_B64 = 10, + S_BREV_B32 = 11, + S_BREV_B64 = 12, + S_BCNT0_I32_B32 = 13, + S_BCNT0_I32_B64 = 14, + S_BCNT1_I32_B32 = 15, + S_BCNT1_I32_B64 = 16, + S_FF0_I32_B32 = 17, + S_FF0_I32_B64 = 18, + S_FF1_I32_B32 = 19, + S_FF1_I32_B64 = 20, + S_FLBIT_I32_B32 = 21, + S_FLBIT_I32_B64 = 22, + S_FLBIT_I32 = 23, + S_FLBIT_I32_I64 = 24, + S_SEXT_I32_I8 = 25, + S_SEXT_I32_I16 = 26, + S_BITSET0_B32 = 27, + S_BITSET0_B64 = 28, + S_BITSET1_B32 = 29, + S_BITSET1_B64 = 30, + S_GETPC_B64 = 31, + S_SETPC_B64 = 32, + S_SWAPPC_B64 = 33, + S_RFE_B64 = 34, + S_AND_SAVEEXEC_B64 = 36, + S_OR_SAVEEXEC_B64 = 37, + S_XOR_SAVEEXEC_B64 = 38, + S_ANDN2_SAVEEXEC_B64 = 39, + S_ORN2_SAVEEXEC_B64 = 40, + S_NAND_SAVEEXEC_B64 = 41, + S_NOR_SAVEEXEC_B64 = 42, + S_XNOR_SAVEEXEC_B64 = 43, + S_QUADMASK_B32 = 44, + S_QUADMASK_B64 = 45, + S_MOVRELS_B32 = 46, + S_MOVRELS_B64 = 47, + S_MOVRELD_B32 = 48, + S_MOVRELD_B64 = 49, + S_CBRANCH_JOIN = 50, + S_MOV_REGRD_B32 = 51, + S_ABS_I32 = 52, + S_MOV_FED_B32 = 53, + + OP_RANGE_SOP1 = S_MOV_FED_B32 + 1, +}; + +enum class OpcodeSOPC : u32 { + S_CMP_EQ_I32 = 0, + S_CMP_LG_I32 = 1, + S_CMP_GT_I32 = 2, + S_CMP_GE_I32 = 3, + S_CMP_LT_I32 = 4, + S_CMP_LE_I32 = 5, + S_CMP_EQ_U32 = 6, + S_CMP_LG_U32 = 7, + S_CMP_GT_U32 = 8, + S_CMP_GE_U32 = 9, + S_CMP_LT_U32 = 10, + S_CMP_LE_U32 = 11, + S_BITCMP0_B32 = 12, + S_BITCMP1_B32 = 13, + S_BITCMP0_B64 = 14, + S_BITCMP1_B64 = 15, + S_SETVSKIP = 16, + + OP_RANGE_SOPC = S_SETVSKIP + 1, +}; + +enum class OpcodeSOPP : u32 { + S_NOP = 0, + S_ENDPGM = 1, + S_BRANCH = 2, + S_CBRANCH_SCC0 = 4, + S_CBRANCH_SCC1 = 5, + S_CBRANCH_VCCZ = 6, + S_CBRANCH_VCCNZ = 7, + S_CBRANCH_EXECZ = 8, + S_CBRANCH_EXECNZ = 9, + S_BARRIER = 10, + S_SETKILL = 11, + S_WAITCNT = 12, + S_SETHALT = 13, + S_SLEEP = 14, + S_SETPRIO = 15, + S_SENDMSG = 16, + S_SENDMSGHALT = 17, + S_TRAP = 18, + S_ICACHE_INV = 19, + S_INCPERFLEVEL = 20, + S_DECPERFLEVEL = 21, + S_TTRACEDATA = 22, + S_CBRANCH_CDBGSYS = 23, + S_CBRANCH_CDBGUSER = 24, + S_CBRANCH_CDBGSYS_OR_USER = 25, + S_CBRANCH_CDBGSYS_AND_USER = 26, + + OP_RANGE_SOPP = S_CBRANCH_CDBGSYS_AND_USER + 1, +}; + +enum class OpcodeSMRD : u32 { + S_LOAD_DWORD = 0, + S_LOAD_DWORDX2 = 1, + S_LOAD_DWORDX4 = 2, + S_LOAD_DWORDX8 = 3, + S_LOAD_DWORDX16 = 4, + S_BUFFER_LOAD_DWORD = 8, + S_BUFFER_LOAD_DWORDX2 = 9, + S_BUFFER_LOAD_DWORDX4 = 10, + S_BUFFER_LOAD_DWORDX8 = 11, + S_BUFFER_LOAD_DWORDX16 = 12, + S_DCACHE_INV_VOL = 29, + S_MEMTIME = 30, + S_DCACHE_INV = 31, + + OP_RANGE_SMRD = S_DCACHE_INV + 1, +}; + +enum class OpcodeVOP2 : u32 { + V_CNDMASK_B32 = 0, + V_READLANE_B32 = 1, + V_WRITELANE_B32 = 2, + V_ADD_F32 = 3, + V_SUB_F32 = 4, + V_SUBREV_F32 = 5, + V_MAC_LEGACY_F32 = 6, + V_MUL_LEGACY_F32 = 7, + V_MUL_F32 = 8, + V_MUL_I32_I24 = 9, + V_MUL_HI_I32_I24 = 10, + V_MUL_U32_U24 = 11, + V_MUL_HI_U32_U24 = 12, + V_MIN_LEGACY_F32 = 13, + V_MAX_LEGACY_F32 = 14, + V_MIN_F32 = 15, + V_MAX_F32 = 16, + V_MIN_I32 = 17, + V_MAX_I32 = 18, + V_MIN_U32 = 19, + V_MAX_U32 = 20, + V_LSHR_B32 = 21, + V_LSHRREV_B32 = 22, + V_ASHR_I32 = 23, + V_ASHRREV_I32 = 24, + V_LSHL_B32 = 25, + V_LSHLREV_B32 = 26, + V_AND_B32 = 27, + V_OR_B32 = 28, + V_XOR_B32 = 29, + V_BFM_B32 = 30, + V_MAC_F32 = 31, + V_MADMK_F32 = 32, + V_MADAK_F32 = 33, + V_BCNT_U32_B32 = 34, + V_MBCNT_LO_U32_B32 = 35, + V_MBCNT_HI_U32_B32 = 36, + V_ADD_I32 = 37, + V_SUB_I32 = 38, + V_SUBREV_I32 = 39, + V_ADDC_U32 = 40, + V_SUBB_U32 = 41, + V_SUBBREV_U32 = 42, + V_LDEXP_F32 = 43, + V_CVT_PKACCUM_U8_F32 = 44, + V_CVT_PKNORM_I16_F32 = 45, + V_CVT_PKNORM_U16_F32 = 46, + V_CVT_PKRTZ_F16_F32 = 47, + V_CVT_PK_U16_U32 = 48, + V_CVT_PK_I16_I32 = 49, + V_ADD_F16 = 50, + V_SUB_F16 = 51, + V_SUBREV_F16 = 52, + V_MUL_F16 = 53, + V_MAX_F16 = 57, + V_MIN_F16 = 58, + V_LDEXP_F16 = 59, + + OP_RANGE_VOP2 = V_LDEXP_F16 + 1, +}; + +enum class OpcodeVOP3 : u32 { + V_CMP_F_F32 = 0, + V_CMP_LT_F32 = 1, + V_CMP_EQ_F32 = 2, + V_CMP_LE_F32 = 3, + V_CMP_GT_F32 = 4, + V_CMP_LG_F32 = 5, + V_CMP_GE_F32 = 6, + V_CMP_O_F32 = 7, + V_CMP_U_F32 = 8, + V_CMP_NGE_F32 = 9, + V_CMP_NLG_F32 = 10, + V_CMP_NGT_F32 = 11, + V_CMP_NLE_F32 = 12, + V_CMP_NEQ_F32 = 13, + V_CMP_NLT_F32 = 14, + V_CMP_TRU_F32 = 15, + V_CMP_T_F32 = 15, + V_CMPX_F_F32 = 16, + V_CMPX_LT_F32 = 17, + V_CMPX_EQ_F32 = 18, + V_CMPX_LE_F32 = 19, + V_CMPX_GT_F32 = 20, + V_CMPX_LG_F32 = 21, + V_CMPX_GE_F32 = 22, + V_CMPX_O_F32 = 23, + V_CMPX_U_F32 = 24, + V_CMPX_NGE_F32 = 25, + V_CMPX_NLG_F32 = 26, + V_CMPX_NGT_F32 = 27, + V_CMPX_NLE_F32 = 28, + V_CMPX_NEQ_F32 = 29, + V_CMPX_NLT_F32 = 30, + V_CMPX_TRU_F32 = 31, + V_CMPX_T_F32 = 31, + V_CMP_F_F64 = 32, + V_CMP_LT_F64 = 33, + V_CMP_EQ_F64 = 34, + V_CMP_LE_F64 = 35, + V_CMP_GT_F64 = 36, + V_CMP_LG_F64 = 37, + V_CMP_GE_F64 = 38, + V_CMP_O_F64 = 39, + V_CMP_U_F64 = 40, + V_CMP_NGE_F64 = 41, + V_CMP_NLG_F64 = 42, + V_CMP_NGT_F64 = 43, + V_CMP_NLE_F64 = 44, + V_CMP_NEQ_F64 = 45, + V_CMP_NLT_F64 = 46, + V_CMP_TRU_F64 = 47, + V_CMP_T_F64 = 47, + V_CMPX_F_F64 = 48, + V_CMPX_LT_F64 = 49, + V_CMPX_EQ_F64 = 50, + V_CMPX_LE_F64 = 51, + V_CMPX_GT_F64 = 52, + V_CMPX_LG_F64 = 53, + V_CMPX_GE_F64 = 54, + V_CMPX_O_F64 = 55, + V_CMPX_U_F64 = 56, + V_CMPX_NGE_F64 = 57, + V_CMPX_NLG_F64 = 58, + V_CMPX_NGT_F64 = 59, + V_CMPX_NLE_F64 = 60, + V_CMPX_NEQ_F64 = 61, + V_CMPX_NLT_F64 = 62, + V_CMPX_TRU_F64 = 63, + V_CMPX_T_F64 = 63, + V_CMPS_F_F32 = 64, + V_CMPS_LT_F32 = 65, + V_CMPS_EQ_F32 = 66, + V_CMPS_LE_F32 = 67, + V_CMPS_GT_F32 = 68, + V_CMPS_LG_F32 = 69, + V_CMPS_GE_F32 = 70, + V_CMPS_O_F32 = 71, + V_CMPS_U_F32 = 72, + V_CMPS_NGE_F32 = 73, + V_CMPS_NLG_F32 = 74, + V_CMPS_NGT_F32 = 75, + V_CMPS_NLE_F32 = 76, + V_CMPS_NEQ_F32 = 77, + V_CMPS_NLT_F32 = 78, + V_CMPS_TRU_F32 = 79, + V_CMPS_T_F32 = 79, + V_CMPSX_F_F32 = 80, + V_CMPSX_LT_F32 = 81, + V_CMPSX_EQ_F32 = 82, + V_CMPSX_LE_F32 = 83, + V_CMPSX_GT_F32 = 84, + V_CMPSX_LG_F32 = 85, + V_CMPSX_GE_F32 = 86, + V_CMPSX_O_F32 = 87, + V_CMPSX_U_F32 = 88, + V_CMPSX_NGE_F32 = 89, + V_CMPSX_NLG_F32 = 90, + V_CMPSX_NGT_F32 = 91, + V_CMPSX_NLE_F32 = 92, + V_CMPSX_NEQ_F32 = 93, + V_CMPSX_NLT_F32 = 94, + V_CMPSX_TRU_F32 = 95, + V_CMPSX_T_F32 = 95, + V_CMPS_F_F64 = 96, + V_CMPS_LT_F64 = 97, + V_CMPS_EQ_F64 = 98, + V_CMPS_LE_F64 = 99, + V_CMPS_GT_F64 = 100, + V_CMPS_LG_F64 = 101, + V_CMPS_GE_F64 = 102, + V_CMPS_O_F64 = 103, + V_CMPS_U_F64 = 104, + V_CMPS_NGE_F64 = 105, + V_CMPS_NLG_F64 = 106, + V_CMPS_NGT_F64 = 107, + V_CMPS_NLE_F64 = 108, + V_CMPS_NEQ_F64 = 109, + V_CMPS_NLT_F64 = 110, + V_CMPS_TRU_F64 = 111, + V_CMPS_T_F64 = 111, + V_CMPSX_F_F64 = 112, + V_CMPSX_LT_F64 = 113, + V_CMPSX_EQ_F64 = 114, + V_CMPSX_LE_F64 = 115, + V_CMPSX_GT_F64 = 116, + V_CMPSX_LG_F64 = 117, + V_CMPSX_GE_F64 = 118, + V_CMPSX_O_F64 = 119, + V_CMPSX_U_F64 = 120, + V_CMPSX_NGE_F64 = 121, + V_CMPSX_NLG_F64 = 122, + V_CMPSX_NGT_F64 = 123, + V_CMPSX_NLE_F64 = 124, + V_CMPSX_NEQ_F64 = 125, + V_CMPSX_NLT_F64 = 126, + V_CMPSX_TRU_F64 = 127, + V_CMPSX_T_F64 = 127, + V_CMP_F_I32 = 128, + V_CMP_LT_I32 = 129, + V_CMP_EQ_I32 = 130, + V_CMP_LE_I32 = 131, + V_CMP_GT_I32 = 132, + V_CMP_LG_I32 = 133, + V_CMP_NE_I32 = 133, + V_CMP_GE_I32 = 134, + V_CMP_TRU_I32 = 135, + V_CMP_T_I32 = 135, + V_CMP_CLASS_F32 = 136, + V_CMP_LT_I16 = 137, + V_CMP_EQ_I16 = 138, + V_CMP_LE_I16 = 139, + V_CMP_GT_I16 = 140, + V_CMP_NE_I16 = 141, + V_CMP_GE_I16 = 142, + V_CMPX_F_I32 = 144, + V_CMPX_LT_I32 = 145, + V_CMPX_EQ_I32 = 146, + V_CMPX_LE_I32 = 147, + V_CMPX_GT_I32 = 148, + V_CMPX_LG_I32 = 149, + V_CMPX_NE_I32 = 149, + V_CMPX_GE_I32 = 150, + V_CMPX_TRU_I32 = 151, + V_CMPX_T_I32 = 151, + V_CMPX_CLASS_F32 = 152, + V_CMP_F_I64 = 160, + V_CMP_LT_I64 = 161, + V_CMP_EQ_I64 = 162, + V_CMP_LE_I64 = 163, + V_CMP_GT_I64 = 164, + V_CMP_LG_I64 = 165, + V_CMP_NE_I64 = 165, + V_CMP_GE_I64 = 166, + V_CMP_TRU_I64 = 167, + V_CMP_T_I64 = 167, + V_CMP_CLASS_F64 = 168, + V_CMP_LT_U16 = 169, + V_CMP_EQ_U16 = 170, + V_CMP_LE_U16 = 171, + V_CMP_GT_U16 = 172, + V_CMP_NE_U16 = 173, + V_CMP_GE_U16 = 174, + V_CMPX_F_I64 = 176, + V_CMPX_LT_I64 = 177, + V_CMPX_EQ_I64 = 178, + V_CMPX_LE_I64 = 179, + V_CMPX_GT_I64 = 180, + V_CMPX_LG_I64 = 181, + V_CMPX_NE_I64 = 181, + V_CMPX_GE_I64 = 182, + V_CMPX_TRU_I64 = 183, + V_CMPX_T_I64 = 183, + V_CMPX_CLASS_F64 = 184, + V_CMP_F_U32 = 192, + V_CMP_LT_U32 = 193, + V_CMP_EQ_U32 = 194, + V_CMP_LE_U32 = 195, + V_CMP_GT_U32 = 196, + V_CMP_LG_U32 = 197, + V_CMP_NE_U32 = 197, + V_CMP_GE_U32 = 198, + V_CMP_TRU_U32 = 199, + V_CMP_T_U32 = 199, + V_CMP_F_F16 = 200, + V_CMP_LT_F16 = 201, + V_CMP_EQ_F16 = 202, + V_CMP_LE_F16 = 203, + V_CMP_GT_F16 = 204, + V_CMP_LG_F16 = 205, + V_CMP_GE_F16 = 206, + V_CMP_O_F16 = 207, + V_CMPX_F_U32 = 208, + V_CMPX_LT_U32 = 209, + V_CMPX_EQ_U32 = 210, + V_CMPX_LE_U32 = 211, + V_CMPX_GT_U32 = 212, + V_CMPX_LG_U32 = 213, + V_CMPX_NE_U32 = 213, + V_CMPX_GE_U32 = 214, + V_CMPX_TRU_U32 = 215, + V_CMPX_T_U32 = 215, + V_CMP_F_U64 = 224, + V_CMP_LT_U64 = 225, + V_CMP_EQ_U64 = 226, + V_CMP_LE_U64 = 227, + V_CMP_GT_U64 = 228, + V_CMP_LG_U64 = 229, + V_CMP_NE_U64 = 229, + V_CMP_GE_U64 = 230, + V_CMP_TRU_U64 = 231, + V_CMP_T_U64 = 231, + V_CMPX_F_U64 = 240, + V_CMPX_LT_U64 = 241, + V_CMPX_EQ_U64 = 242, + V_CMPX_LE_U64 = 243, + V_CMPX_GT_U64 = 244, + V_CMPX_LG_U64 = 245, + V_CMPX_NE_U64 = 245, + V_CMPX_GE_U64 = 246, + V_CMPX_TRU_U64 = 247, + V_CMPX_T_U64 = 247, + V_CNDMASK_B32 = 256, + V_READLANE_B32 = 257, + V_WRITELANE_B32 = 258, + V_ADD_F32 = 259, + V_SUB_F32 = 260, + V_SUBREV_F32 = 261, + V_MAC_LEGACY_F32 = 262, + V_MUL_LEGACY_F32 = 263, + V_MUL_F32 = 264, + V_MUL_I32_I24 = 265, + V_MUL_HI_I32_I24 = 266, + V_MUL_U32_U24 = 267, + V_MUL_HI_U32_U24 = 268, + V_MIN_LEGACY_F32 = 269, + V_MAX_LEGACY_F32 = 270, + V_MIN_F32 = 271, + V_MAX_F32 = 272, + V_MIN_I32 = 273, + V_MAX_I32 = 274, + V_MIN_U32 = 275, + V_MAX_U32 = 276, + V_LSHR_B32 = 277, + V_LSHRREV_B32 = 278, + V_ASHR_I32 = 279, + V_ASHRREV_I32 = 280, + V_LSHL_B32 = 281, + V_LSHLREV_B32 = 282, + V_AND_B32 = 283, + V_OR_B32 = 284, + V_XOR_B32 = 285, + V_BFM_B32 = 286, + V_MAC_F32 = 287, + V_MADMK_F32 = 288, + V_MADAK_F32 = 289, + V_BCNT_U32_B32 = 290, + V_MBCNT_LO_U32_B32 = 291, + V_MBCNT_HI_U32_B32 = 292, + V_ADD_I32 = 293, + V_SUB_I32 = 294, + V_SUBREV_I32 = 295, + V_ADDC_U32 = 296, + V_SUBB_U32 = 297, + V_SUBBREV_U32 = 298, + V_LDEXP_F32 = 299, + V_CVT_PKACCUM_U8_F32 = 300, + V_CVT_PKNORM_I16_F32 = 301, + V_CVT_PKNORM_U16_F32 = 302, + V_CVT_PKRTZ_F16_F32 = 303, + V_CVT_PK_U16_U32 = 304, + V_CVT_PK_I16_I32 = 305, + V_ADD_F16 = 306, + V_SUB_F16 = 307, + V_SUBREV_F16 = 308, + V_MUL_F16 = 309, + V_MAX_F16 = 313, + V_MIN_F16 = 314, + V_LDEXP_F16 = 315, + V_MAD_LEGACY_F32 = 320, + V_MAD_F32 = 321, + V_MAD_I32_I24 = 322, + V_MAD_U32_U24 = 323, + V_CUBEID_F32 = 324, + V_CUBESC_F32 = 325, + V_CUBETC_F32 = 326, + V_CUBEMA_F32 = 327, + V_BFE_U32 = 328, + V_BFE_I32 = 329, + V_BFI_B32 = 330, + V_FMA_F32 = 331, + V_FMA_F64 = 332, + V_LERP_U8 = 333, + V_ALIGNBIT_B32 = 334, + V_ALIGNBYTE_B32 = 335, + V_MULLIT_F32 = 336, + V_MIN3_F32 = 337, + V_MIN3_I32 = 338, + V_MIN3_U32 = 339, + V_MAX3_F32 = 340, + V_MAX3_I32 = 341, + V_MAX3_U32 = 342, + V_MED3_F32 = 343, + V_MED3_I32 = 344, + V_MED3_U32 = 345, + V_SAD_U8 = 346, + V_SAD_HI_U8 = 347, + V_SAD_U16 = 348, + V_SAD_U32 = 349, + V_CVT_PK_U8_F32 = 350, + V_DIV_FIXUP_F32 = 351, + V_DIV_FIXUP_F64 = 352, + V_LSHL_B64 = 353, + V_LSHR_B64 = 354, + V_ASHR_I64 = 355, + V_ADD_F64 = 356, + V_MUL_F64 = 357, + V_MIN_F64 = 358, + V_MAX_F64 = 359, + V_LDEXP_F64 = 360, + V_MUL_LO_U32 = 361, + V_MUL_HI_U32 = 362, + V_MUL_LO_I32 = 363, + V_MUL_HI_I32 = 364, + V_DIV_SCALE_F32 = 365, + V_DIV_SCALE_F64 = 366, + V_DIV_FMAS_F32 = 367, + V_DIV_FMAS_F64 = 368, + V_MSAD_U8 = 369, + V_QSAD_U8 = 370, + V_QSAD_PK_U16_U8 = 370, + V_MQSAD_U8 = 371, + V_MQSAD_PK_U16_U8 = 371, + V_TRIG_PREOP_F64 = 372, + V_MQSAD_U32_U8 = 373, + V_MAD_U64_U32 = 374, + V_MAD_I64_I32 = 375, + V_NOP = 384, + V_MOV_B32 = 385, + V_READFIRSTLANE_B32 = 386, + V_CVT_I32_F64 = 387, + V_CVT_F64_I32 = 388, + V_CVT_F32_I32 = 389, + V_CVT_F32_U32 = 390, + V_CVT_U32_F32 = 391, + V_CVT_I32_F32 = 392, + V_MOV_FED_B32 = 393, + V_CVT_F16_F32 = 394, + V_CVT_F32_F16 = 395, + V_CVT_RPI_I32_F32 = 396, + V_CVT_FLR_I32_F32 = 397, + V_CVT_OFF_F32_I4 = 398, + V_CVT_F32_F64 = 399, + V_CVT_F64_F32 = 400, + V_CVT_F32_UBYTE0 = 401, + V_CVT_F32_UBYTE1 = 402, + V_CVT_F32_UBYTE2 = 403, + V_CVT_F32_UBYTE3 = 404, + V_CVT_U32_F64 = 405, + V_CVT_F64_U32 = 406, + V_TRUNC_F64 = 407, + V_CEIL_F64 = 408, + V_RNDNE_F64 = 409, + V_FLOOR_F64 = 410, + V_FRACT_F32 = 416, + V_TRUNC_F32 = 417, + V_CEIL_F32 = 418, + V_RNDNE_F32 = 419, + V_FLOOR_F32 = 420, + V_EXP_F32 = 421, + V_LOG_CLAMP_F32 = 422, + V_LOG_F32 = 423, + V_RCP_CLAMP_F32 = 424, + V_RCP_LEGACY_F32 = 425, + V_RCP_F32 = 426, + V_RCP_IFLAG_F32 = 427, + V_RSQ_CLAMP_F32 = 428, + V_RSQ_LEGACY_F32 = 429, + V_RSQ_F32 = 430, + V_RCP_F64 = 431, + V_RCP_CLAMP_F64 = 432, + V_RSQ_F64 = 433, + V_RSQ_CLAMP_F64 = 434, + V_SQRT_F32 = 435, + V_SQRT_F64 = 436, + V_SIN_F32 = 437, + V_COS_F32 = 438, + V_NOT_B32 = 439, + V_BFREV_B32 = 440, + V_FFBH_U32 = 441, + V_FFBL_B32 = 442, + V_FFBH_I32 = 443, + V_FREXP_EXP_I32_F64 = 444, + V_FREXP_MANT_F64 = 445, + V_FRACT_F64 = 446, + V_FREXP_EXP_I32_F32 = 447, + V_FREXP_MANT_F32 = 448, + V_CLREXCP = 449, + V_MOVRELD_B32 = 450, + V_MOVRELS_B32 = 451, + V_MOVRELSD_B32 = 452, + V_LOG_LEGACY_F32 = 453, + V_EXP_LEGACY_F32 = 454, + V_RCP_F16 = 468, + V_SQRT_F16 = 469, + + V_ADD_NC_U16 = 771, + V_LSHRREV_B16 = 775, + V_ASHRREV_I16 = 776, + V_ADD_NC_I16 = 781, + V_SUB_NC_I16 = 782, + V_SUB_CO_U32 = 784, + V_LSHLREV_B16 = 788, + V_MAD_F16 = 833, + V_LSHL_ADD_U32 = 838, + V_ADD_LSHL_U32 = 839, + V_MIN3_F16 = 849, + V_MAX3_F16 = 852, + V_MED3_F16 = 855, + V_MAD_I16 = 862, + V_ADD3_U32 = 877, + V_LSHL_OR_B32 = 879, + V_AND_OR_B32 = 881, + V_OR3_B32 = 882, + + OP_RANGE_VOP3 = 1024, // in neo mode, VOP3 gets an additional bit for OP so round up +}; + +enum class OpcodeVOP3P : u32 { + V_PK_MAD_I16 = 0, + V_PK_MUL_LO_U16 = 1, + V_PK_ADD_I16 = 2, + V_PK_SUB_I16 = 3, + V_PK_LSHLREV_B16 = 4, + V_PK_LSHRREV_B16 = 5, + V_PK_ASHRREV_I16 = 6, + V_PK_MAX_I16 = 7, + V_PK_MIN_I16 = 8, + V_PK_MAD_U16 = 9, + V_PK_ADD_U16 = 10, + V_PK_SUB_U16 = 11, + V_PK_MAX_U16 = 12, + V_PK_MIN_U16 = 13, + V_PK_FMA_F16 = 14, + V_PK_ADD_F16 = 15, + V_PK_MUL_F16 = 16, + V_PK_MIN_F16 = 17, + V_PK_MAX_F16 = 18, + V_MAD_MIX_F32 = 32, + V_MAD_MIXLO_F16 = 33, + V_MAD_MIXHI_F16 = 34, + + OP_RANGE_VOP3P = V_MAD_MIXHI_F16 + 1, +}; + +enum class OpcodeVOP1 : u32 { + V_NOP = 0, + V_MOV_B32 = 1, + V_READFIRSTLANE_B32 = 2, + V_CVT_I32_F64 = 3, + V_CVT_F64_I32 = 4, + V_CVT_F32_I32 = 5, + V_CVT_F32_U32 = 6, + V_CVT_U32_F32 = 7, + V_CVT_I32_F32 = 8, + V_MOV_FED_B32 = 9, + V_CVT_F16_F32 = 10, + V_CVT_F32_F16 = 11, + V_CVT_RPI_I32_F32 = 12, + V_CVT_FLR_I32_F32 = 13, + V_CVT_OFF_F32_I4 = 14, + V_CVT_F32_F64 = 15, + V_CVT_F64_F32 = 16, + V_CVT_F32_UBYTE0 = 17, + V_CVT_F32_UBYTE1 = 18, + V_CVT_F32_UBYTE2 = 19, + V_CVT_F32_UBYTE3 = 20, + V_CVT_U32_F64 = 21, + V_CVT_F64_U32 = 22, + V_TRUNC_F64 = 23, + V_CEIL_F64 = 24, + V_RNDNE_F64 = 25, + V_FLOOR_F64 = 26, + V_FRACT_F32 = 32, + V_TRUNC_F32 = 33, + V_CEIL_F32 = 34, + V_RNDNE_F32 = 35, + V_FLOOR_F32 = 36, + V_EXP_F32 = 37, + V_LOG_CLAMP_F32 = 38, + V_LOG_F32 = 39, + V_RCP_CLAMP_F32 = 40, + V_RCP_LEGACY_F32 = 41, + V_RCP_F32 = 42, + V_RCP_IFLAG_F32 = 43, + V_RSQ_CLAMP_F32 = 44, + V_RSQ_LEGACY_F32 = 45, + V_RSQ_F32 = 46, + V_RCP_F64 = 47, + V_RCP_CLAMP_F64 = 48, + V_RSQ_F64 = 49, + V_RSQ_CLAMP_F64 = 50, + V_SQRT_F32 = 51, + V_SQRT_F64 = 52, + V_SIN_F32 = 53, + V_COS_F32 = 54, + V_NOT_B32 = 55, + V_BFREV_B32 = 56, + V_FFBH_U32 = 57, + V_FFBL_B32 = 58, + V_FFBH_I32 = 59, + V_FREXP_EXP_I32_F64 = 60, + V_FREXP_MANT_F64 = 61, + V_FRACT_F64 = 62, + V_FREXP_EXP_I32_F32 = 63, + V_FREXP_MANT_F32 = 64, + V_CLREXCP = 65, + V_MOVRELD_B32 = 66, + V_MOVRELS_B32 = 67, + V_MOVRELSD_B32 = 68, + V_LOG_LEGACY_F32 = 69, + V_EXP_LEGACY_F32 = 70, + V_RCP_F16 = 84, + V_SQRT_F16 = 85, + + OP_RANGE_VOP1 = V_SQRT_F16 + 1, +}; + +enum class OpcodeVOPC : u32 { + V_CMP_F_F32 = 0, + V_CMP_LT_F32 = 1, + V_CMP_EQ_F32 = 2, + V_CMP_LE_F32 = 3, + V_CMP_GT_F32 = 4, + V_CMP_LG_F32 = 5, + V_CMP_GE_F32 = 6, + V_CMP_O_F32 = 7, + V_CMP_U_F32 = 8, + V_CMP_NGE_F32 = 9, + V_CMP_NLG_F32 = 10, + V_CMP_NGT_F32 = 11, + V_CMP_NLE_F32 = 12, + V_CMP_NEQ_F32 = 13, + V_CMP_NLT_F32 = 14, + V_CMP_TRU_F32 = 15, + V_CMP_T_F32 = 15, + V_CMPX_F_F32 = 16, + V_CMPX_LT_F32 = 17, + V_CMPX_EQ_F32 = 18, + V_CMPX_LE_F32 = 19, + V_CMPX_GT_F32 = 20, + V_CMPX_LG_F32 = 21, + V_CMPX_GE_F32 = 22, + V_CMPX_O_F32 = 23, + V_CMPX_U_F32 = 24, + V_CMPX_NGE_F32 = 25, + V_CMPX_NLG_F32 = 26, + V_CMPX_NGT_F32 = 27, + V_CMPX_NLE_F32 = 28, + V_CMPX_NEQ_F32 = 29, + V_CMPX_NLT_F32 = 30, + V_CMPX_TRU_F32 = 31, + V_CMPX_T_F32 = 31, + V_CMP_F_F64 = 32, + V_CMP_LT_F64 = 33, + V_CMP_EQ_F64 = 34, + V_CMP_LE_F64 = 35, + V_CMP_GT_F64 = 36, + V_CMP_LG_F64 = 37, + V_CMP_GE_F64 = 38, + V_CMP_O_F64 = 39, + V_CMP_U_F64 = 40, + V_CMP_NGE_F64 = 41, + V_CMP_NLG_F64 = 42, + V_CMP_NGT_F64 = 43, + V_CMP_NLE_F64 = 44, + V_CMP_NEQ_F64 = 45, + V_CMP_NLT_F64 = 46, + V_CMP_TRU_F64 = 47, + V_CMP_T_F64 = 47, + V_CMPX_F_F64 = 48, + V_CMPX_LT_F64 = 49, + V_CMPX_EQ_F64 = 50, + V_CMPX_LE_F64 = 51, + V_CMPX_GT_F64 = 52, + V_CMPX_LG_F64 = 53, + V_CMPX_GE_F64 = 54, + V_CMPX_O_F64 = 55, + V_CMPX_U_F64 = 56, + V_CMPX_NGE_F64 = 57, + V_CMPX_NLG_F64 = 58, + V_CMPX_NGT_F64 = 59, + V_CMPX_NLE_F64 = 60, + V_CMPX_NEQ_F64 = 61, + V_CMPX_NLT_F64 = 62, + V_CMPX_TRU_F64 = 63, + V_CMPX_T_F64 = 63, + V_CMPS_F_F32 = 64, + V_CMPS_LT_F32 = 65, + V_CMPS_EQ_F32 = 66, + V_CMPS_LE_F32 = 67, + V_CMPS_GT_F32 = 68, + V_CMPS_LG_F32 = 69, + V_CMPS_GE_F32 = 70, + V_CMPS_O_F32 = 71, + V_CMPS_U_F32 = 72, + V_CMPS_NGE_F32 = 73, + V_CMPS_NLG_F32 = 74, + V_CMPS_NGT_F32 = 75, + V_CMPS_NLE_F32 = 76, + V_CMPS_NEQ_F32 = 77, + V_CMPS_NLT_F32 = 78, + V_CMPS_TRU_F32 = 79, + V_CMPS_T_F32 = 79, + V_CMPSX_F_F32 = 80, + V_CMPSX_LT_F32 = 81, + V_CMPSX_EQ_F32 = 82, + V_CMPSX_LE_F32 = 83, + V_CMPSX_GT_F32 = 84, + V_CMPSX_LG_F32 = 85, + V_CMPSX_GE_F32 = 86, + V_CMPSX_O_F32 = 87, + V_CMPSX_U_F32 = 88, + V_CMPSX_NGE_F32 = 89, + V_CMPSX_NLG_F32 = 90, + V_CMPSX_NGT_F32 = 91, + V_CMPSX_NLE_F32 = 92, + V_CMPSX_NEQ_F32 = 93, + V_CMPSX_NLT_F32 = 94, + V_CMPSX_TRU_F32 = 95, + V_CMPSX_T_F32 = 95, + V_CMPS_F_F64 = 96, + V_CMPS_LT_F64 = 97, + V_CMPS_EQ_F64 = 98, + V_CMPS_LE_F64 = 99, + V_CMPS_GT_F64 = 100, + V_CMPS_LG_F64 = 101, + V_CMPS_GE_F64 = 102, + V_CMPS_O_F64 = 103, + V_CMPS_U_F64 = 104, + V_CMPS_NGE_F64 = 105, + V_CMPS_NLG_F64 = 106, + V_CMPS_NGT_F64 = 107, + V_CMPS_NLE_F64 = 108, + V_CMPS_NEQ_F64 = 109, + V_CMPS_NLT_F64 = 110, + V_CMPS_TRU_F64 = 111, + V_CMPS_T_F64 = 111, + V_CMPSX_F_F64 = 112, + V_CMPSX_LT_F64 = 113, + V_CMPSX_EQ_F64 = 114, + V_CMPSX_LE_F64 = 115, + V_CMPSX_GT_F64 = 116, + V_CMPSX_LG_F64 = 117, + V_CMPSX_GE_F64 = 118, + V_CMPSX_O_F64 = 119, + V_CMPSX_U_F64 = 120, + V_CMPSX_NGE_F64 = 121, + V_CMPSX_NLG_F64 = 122, + V_CMPSX_NGT_F64 = 123, + V_CMPSX_NLE_F64 = 124, + V_CMPSX_NEQ_F64 = 125, + V_CMPSX_NLT_F64 = 126, + V_CMPSX_TRU_F64 = 127, + V_CMPSX_T_F64 = 127, + V_CMP_F_I32 = 128, + V_CMP_LT_I32 = 129, + V_CMP_EQ_I32 = 130, + V_CMP_LE_I32 = 131, + V_CMP_GT_I32 = 132, + V_CMP_LG_I32 = 133, + V_CMP_NE_I32 = 133, + V_CMP_GE_I32 = 134, + V_CMP_TRU_I32 = 135, + V_CMP_T_I32 = 135, + V_CMP_CLASS_F32 = 136, + V_CMP_LT_I16 = 137, + V_CMP_EQ_I16 = 138, + V_CMP_LE_I16 = 139, + V_CMP_GT_I16 = 140, + V_CMP_NE_I16 = 141, + V_CMP_GE_I16 = 142, + V_CMPX_F_I32 = 144, + V_CMPX_LT_I32 = 145, + V_CMPX_EQ_I32 = 146, + V_CMPX_LE_I32 = 147, + V_CMPX_GT_I32 = 148, + V_CMPX_LG_I32 = 149, + V_CMPX_NE_I32 = 149, + V_CMPX_GE_I32 = 150, + V_CMPX_TRU_I32 = 151, + V_CMPX_T_I32 = 151, + V_CMPX_CLASS_F32 = 152, + V_CMP_F_I64 = 160, + V_CMP_LT_I64 = 161, + V_CMP_EQ_I64 = 162, + V_CMP_LE_I64 = 163, + V_CMP_GT_I64 = 164, + V_CMP_LG_I64 = 165, + V_CMP_NE_I64 = 165, + V_CMP_GE_I64 = 166, + V_CMP_TRU_I64 = 167, + V_CMP_T_I64 = 167, + V_CMP_CLASS_F64 = 168, + V_CMP_LT_U16 = 169, + V_CMP_EQ_U16 = 170, + V_CMP_LE_U16 = 171, + V_CMP_GT_U16 = 172, + V_CMP_NE_U16 = 173, + V_CMP_GE_U16 = 174, + V_CMPX_F_I64 = 176, + V_CMPX_LT_I64 = 177, + V_CMPX_EQ_I64 = 178, + V_CMPX_LE_I64 = 179, + V_CMPX_GT_I64 = 180, + V_CMPX_LG_I64 = 181, + V_CMPX_NE_I64 = 181, + V_CMPX_GE_I64 = 182, + V_CMPX_TRU_I64 = 183, + V_CMPX_T_I64 = 183, + V_CMPX_CLASS_F64 = 184, + V_CMP_F_U32 = 192, + V_CMP_LT_U32 = 193, + V_CMP_EQ_U32 = 194, + V_CMP_LE_U32 = 195, + V_CMP_GT_U32 = 196, + V_CMP_LG_U32 = 197, + V_CMP_NE_U32 = 197, + V_CMP_GE_U32 = 198, + V_CMP_TRU_U32 = 199, + V_CMP_T_U32 = 199, + V_CMP_F_F16 = 200, + V_CMP_LT_F16 = 201, + V_CMP_EQ_F16 = 202, + V_CMP_LE_F16 = 203, + V_CMP_GT_F16 = 204, + V_CMP_LG_F16 = 205, + V_CMP_GE_F16 = 206, + V_CMP_O_F16 = 207, + V_CMPX_F_U32 = 208, + V_CMPX_LT_U32 = 209, + V_CMPX_EQ_U32 = 210, + V_CMPX_LE_U32 = 211, + V_CMPX_GT_U32 = 212, + V_CMPX_LG_U32 = 213, + V_CMPX_NE_U32 = 213, + V_CMPX_GE_U32 = 214, + V_CMPX_TRU_U32 = 215, + V_CMPX_T_U32 = 215, + V_CMP_F_U64 = 224, + V_CMP_LT_U64 = 225, + V_CMP_EQ_U64 = 226, + V_CMP_LE_U64 = 227, + V_CMP_GT_U64 = 228, + V_CMP_LG_U64 = 229, + V_CMP_NE_U64 = 229, + V_CMP_GE_U64 = 230, + V_CMP_TRU_U64 = 231, + V_CMP_T_U64 = 231, + V_CMPX_F_U64 = 240, + V_CMPX_LT_U64 = 241, + V_CMPX_EQ_U64 = 242, + V_CMPX_LE_U64 = 243, + V_CMPX_GT_U64 = 244, + V_CMPX_LG_U64 = 245, + V_CMPX_NE_U64 = 245, + V_CMPX_GE_U64 = 246, + V_CMPX_TRU_U64 = 247, + V_CMPX_T_U64 = 247, + + OP_RANGE_VOPC = V_CMPX_T_U64 + 1, +}; + +enum class OpcodeVINTRP : u32 { + V_INTERP_P1_F32 = 0, + V_INTERP_P2_F32 = 1, + V_INTERP_MOV_F32 = 2, + + OP_RANGE_VINTRP = V_INTERP_MOV_F32 + 1, +}; + +enum class OpcodeDS : u32 { + DS_ADD_U32 = 0, + DS_SUB_U32 = 1, + DS_RSUB_U32 = 2, + DS_INC_U32 = 3, + DS_DEC_U32 = 4, + DS_MIN_I32 = 5, + DS_MAX_I32 = 6, + DS_MIN_U32 = 7, + DS_MAX_U32 = 8, + DS_AND_B32 = 9, + DS_OR_B32 = 10, + DS_XOR_B32 = 11, + DS_MSKOR_B32 = 12, + DS_WRITE_B32 = 13, + DS_WRITE2_B32 = 14, + DS_WRITE2ST64_B32 = 15, + DS_CMPST_B32 = 16, + DS_CMPST_F32 = 17, + DS_MIN_F32 = 18, + DS_MAX_F32 = 19, + DS_NOP = 20, + DS_GWS_SEMA_RELEASE_ALL = 24, + DS_GWS_INIT = 25, + DS_GWS_SEMA_V = 26, + DS_GWS_SEMA_BR = 27, + DS_GWS_SEMA_P = 28, + DS_GWS_BARRIER = 29, + DS_WRITE_B8 = 30, + DS_WRITE_B16 = 31, + DS_ADD_RTN_U32 = 32, + DS_SUB_RTN_U32 = 33, + DS_RSUB_RTN_U32 = 34, + DS_INC_RTN_U32 = 35, + DS_DEC_RTN_U32 = 36, + DS_MIN_RTN_I32 = 37, + DS_MAX_RTN_I32 = 38, + DS_MIN_RTN_U32 = 39, + DS_MAX_RTN_U32 = 40, + DS_AND_RTN_B32 = 41, + DS_OR_RTN_B32 = 42, + DS_XOR_RTN_B32 = 43, + DS_MSKOR_RTN_B32 = 44, + DS_WRXCHG_RTN_B32 = 45, + DS_WRXCHG2_RTN_B32 = 46, + DS_WRXCHG2ST64_RTN_B32 = 47, + DS_CMPST_RTN_B32 = 48, + DS_CMPST_RTN_F32 = 49, + DS_MIN_RTN_F32 = 50, + DS_MAX_RTN_F32 = 51, + DS_WRAP_RTN_B32 = 52, + DS_SWIZZLE_B32 = 53, + DS_READ_B32 = 54, + DS_READ2_B32 = 55, + DS_READ2ST64_B32 = 56, + DS_READ_I8 = 57, + DS_READ_U8 = 58, + DS_READ_I16 = 59, + DS_READ_U16 = 60, + DS_CONSUME = 61, + DS_APPEND = 62, + DS_ORDERED_COUNT = 63, + DS_ADD_U64 = 64, + DS_SUB_U64 = 65, + DS_RSUB_U64 = 66, + DS_INC_U64 = 67, + DS_DEC_U64 = 68, + DS_MIN_I64 = 69, + DS_MAX_I64 = 70, + DS_MIN_U64 = 71, + DS_MAX_U64 = 72, + DS_AND_B64 = 73, + DS_OR_B64 = 74, + DS_XOR_B64 = 75, + DS_MSKOR_B64 = 76, + DS_WRITE_B64 = 77, + DS_WRITE2_B64 = 78, + DS_WRITE2ST64_B64 = 79, + DS_CMPST_B64 = 80, + DS_CMPST_F64 = 81, + DS_MIN_F64 = 82, + DS_MAX_F64 = 83, + DS_ADD_RTN_U64 = 96, + DS_SUB_RTN_U64 = 97, + DS_RSUB_RTN_U64 = 98, + DS_INC_RTN_U64 = 99, + DS_DEC_RTN_U64 = 100, + DS_MIN_RTN_I64 = 101, + DS_MAX_RTN_I64 = 102, + DS_MIN_RTN_U64 = 103, + DS_MAX_RTN_U64 = 104, + DS_AND_RTN_B64 = 105, + DS_OR_RTN_B64 = 106, + DS_XOR_RTN_B64 = 107, + DS_MSKOR_RTN_B64 = 108, + DS_WRXCHG_RTN_B64 = 109, + DS_WRXCHG2_RTN_B64 = 110, + DS_WRXCHG2ST64_RTN_B64 = 111, + DS_CMPST_RTN_B64 = 112, + DS_CMPST_RTN_F64 = 113, + DS_MIN_RTN_F64 = 114, + DS_MAX_RTN_F64 = 115, + DS_READ_B64 = 118, + DS_READ2_B64 = 119, + DS_READ2ST64_B64 = 120, + DS_CONDXCHG32_RTN_B64 = 126, + DS_ADD_SRC2_U32 = 128, + DS_SUB_SRC2_U32 = 129, + DS_RSUB_SRC2_U32 = 130, + DS_INC_SRC2_U32 = 131, + DS_DEC_SRC2_U32 = 132, + DS_MIN_SRC2_I32 = 133, + DS_MAX_SRC2_I32 = 134, + DS_MIN_SRC2_U32 = 135, + DS_MAX_SRC2_U32 = 136, + DS_AND_SRC2_B32 = 137, + DS_OR_SRC2_B32 = 138, + DS_XOR_SRC2_B32 = 139, + DS_WRITE_SRC2_B32 = 141, + DS_MIN_SRC2_F32 = 146, + DS_MAX_SRC2_F32 = 147, + DS_ADD_SRC2_U64 = 192, + DS_SUB_SRC2_U64 = 193, + DS_RSUB_SRC2_U64 = 194, + DS_INC_SRC2_U64 = 195, + DS_DEC_SRC2_U64 = 196, + DS_MIN_SRC2_I64 = 197, + DS_MAX_SRC2_I64 = 198, + DS_MIN_SRC2_U64 = 199, + DS_MAX_SRC2_U64 = 200, + DS_AND_SRC2_B64 = 201, + DS_OR_SRC2_B64 = 202, + DS_XOR_SRC2_B64 = 203, + DS_WRITE_SRC2_B64 = 205, + DS_MIN_SRC2_F64 = 210, + DS_MAX_SRC2_F64 = 211, + DS_WRITE_B96 = 222, + DS_WRITE_B128 = 223, + DS_CONDXCHG32_RTN_B128 = 253, + DS_READ_B96 = 254, + DS_READ_B128 = 255, + + OP_RANGE_DS = DS_READ_B128 + 1, +}; + +enum class OpcodeMUBUF : u32 { + BUFFER_LOAD_FORMAT_X = 0, + BUFFER_LOAD_FORMAT_XY = 1, + BUFFER_LOAD_FORMAT_XYZ = 2, + BUFFER_LOAD_FORMAT_XYZW = 3, + BUFFER_STORE_FORMAT_X = 4, + BUFFER_STORE_FORMAT_XY = 5, + BUFFER_STORE_FORMAT_XYZ = 6, + BUFFER_STORE_FORMAT_XYZW = 7, + BUFFER_LOAD_UBYTE = 8, + BUFFER_LOAD_SBYTE = 9, + BUFFER_LOAD_USHORT = 10, + BUFFER_LOAD_SSHORT = 11, + BUFFER_LOAD_DWORD = 12, + BUFFER_LOAD_DWORDX2 = 13, + BUFFER_LOAD_DWORDX4 = 14, + BUFFER_LOAD_DWORDX3 = 15, + BUFFER_STORE_BYTE = 24, + BUFFER_STORE_SHORT = 26, + BUFFER_STORE_DWORD = 28, + BUFFER_STORE_DWORDX2 = 29, + BUFFER_STORE_DWORDX4 = 30, + BUFFER_STORE_DWORDX3 = 31, + BUFFER_ATOMIC_SWAP = 48, + BUFFER_ATOMIC_CMPSWAP = 49, + BUFFER_ATOMIC_ADD = 50, + BUFFER_ATOMIC_SUB = 51, + BUFFER_ATOMIC_SMIN = 53, + BUFFER_ATOMIC_UMIN = 54, + BUFFER_ATOMIC_SMAX = 55, + BUFFER_ATOMIC_UMAX = 56, + BUFFER_ATOMIC_AND = 57, + BUFFER_ATOMIC_OR = 58, + BUFFER_ATOMIC_XOR = 59, + BUFFER_ATOMIC_INC = 60, + BUFFER_ATOMIC_DEC = 61, + BUFFER_ATOMIC_FCMPSWAP = 62, + BUFFER_ATOMIC_FMIN = 63, + BUFFER_ATOMIC_FMAX = 64, + BUFFER_ATOMIC_SWAP_X2 = 80, + BUFFER_ATOMIC_CMPSWAP_X2 = 81, + BUFFER_ATOMIC_ADD_X2 = 82, + BUFFER_ATOMIC_SUB_X2 = 83, + BUFFER_ATOMIC_SMIN_X2 = 85, + BUFFER_ATOMIC_UMIN_X2 = 86, + BUFFER_ATOMIC_SMAX_X2 = 87, + BUFFER_ATOMIC_UMAX_X2 = 88, + BUFFER_ATOMIC_AND_X2 = 89, + BUFFER_ATOMIC_OR_X2 = 90, + BUFFER_ATOMIC_XOR_X2 = 91, + BUFFER_ATOMIC_INC_X2 = 92, + BUFFER_ATOMIC_DEC_X2 = 93, + BUFFER_ATOMIC_FCMPSWAP_X2 = 94, + BUFFER_ATOMIC_FMIN_X2 = 95, + BUFFER_ATOMIC_FMAX_X2 = 96, + BUFFER_WBINVL1_SC = 112, + BUFFER_WBINVL1 = 113, + + OP_RANGE_MUBUF = BUFFER_WBINVL1 + 1, +}; + +enum class OpcodeMTBUF : u32 { + TBUFFER_LOAD_FORMAT_X = 0, + TBUFFER_LOAD_FORMAT_XY = 1, + TBUFFER_LOAD_FORMAT_XYZ = 2, + TBUFFER_LOAD_FORMAT_XYZW = 3, + TBUFFER_STORE_FORMAT_X = 4, + TBUFFER_STORE_FORMAT_XY = 5, + TBUFFER_STORE_FORMAT_XYZ = 6, + TBUFFER_STORE_FORMAT_XYZW = 7, + + OP_RANGE_MTBUF = TBUFFER_STORE_FORMAT_XYZW + 1, +}; + +enum class OpcodeMIMG : u32 { + IMAGE_LOAD = 0, + IMAGE_LOAD_MIP = 1, + IMAGE_LOAD_PCK = 2, + IMAGE_LOAD_PCK_SGN = 3, + IMAGE_LOAD_MIP_PCK = 4, + IMAGE_LOAD_MIP_PCK_SGN = 5, + IMAGE_STORE = 8, + IMAGE_STORE_MIP = 9, + IMAGE_STORE_PCK = 10, + IMAGE_STORE_MIP_PCK = 11, + IMAGE_GET_RESINFO = 14, + IMAGE_ATOMIC_SWAP = 15, + IMAGE_ATOMIC_CMPSWAP = 16, + IMAGE_ATOMIC_ADD = 17, + IMAGE_ATOMIC_SUB = 18, + IMAGE_ATOMIC_SMIN = 20, + IMAGE_ATOMIC_UMIN = 21, + IMAGE_ATOMIC_SMAX = 22, + IMAGE_ATOMIC_UMAX = 23, + IMAGE_ATOMIC_AND = 24, + IMAGE_ATOMIC_OR = 25, + IMAGE_ATOMIC_XOR = 26, + IMAGE_ATOMIC_INC = 27, + IMAGE_ATOMIC_DEC = 28, + IMAGE_ATOMIC_FCMPSWAP = 29, + IMAGE_ATOMIC_FMIN = 30, + IMAGE_ATOMIC_FMAX = 31, + IMAGE_SAMPLE = 32, + IMAGE_SAMPLE_CL = 33, + IMAGE_SAMPLE_D = 34, + IMAGE_SAMPLE_D_CL = 35, + IMAGE_SAMPLE_L = 36, + IMAGE_SAMPLE_B = 37, + IMAGE_SAMPLE_B_CL = 38, + IMAGE_SAMPLE_LZ = 39, + IMAGE_SAMPLE_C = 40, + IMAGE_SAMPLE_C_CL = 41, + IMAGE_SAMPLE_C_D = 42, + IMAGE_SAMPLE_C_D_CL = 43, + IMAGE_SAMPLE_C_L = 44, + IMAGE_SAMPLE_C_B = 45, + IMAGE_SAMPLE_C_B_CL = 46, + IMAGE_SAMPLE_C_LZ = 47, + IMAGE_SAMPLE_O = 48, + IMAGE_SAMPLE_CL_O = 49, + IMAGE_SAMPLE_D_O = 50, + IMAGE_SAMPLE_D_CL_O = 51, + IMAGE_SAMPLE_L_O = 52, + IMAGE_SAMPLE_B_O = 53, + IMAGE_SAMPLE_B_CL_O = 54, + IMAGE_SAMPLE_LZ_O = 55, + IMAGE_SAMPLE_C_O = 56, + IMAGE_SAMPLE_C_CL_O = 57, + IMAGE_SAMPLE_C_D_O = 58, + IMAGE_SAMPLE_C_D_CL_O = 59, + IMAGE_SAMPLE_C_L_O = 60, + IMAGE_SAMPLE_C_B_O = 61, + IMAGE_SAMPLE_C_B_CL_O = 62, + IMAGE_SAMPLE_C_LZ_O = 63, + IMAGE_GATHER4 = 64, + IMAGE_GATHER4_CL = 65, + IMAGE_GATHER4_L = 68, + IMAGE_GATHER4_B = 69, + IMAGE_GATHER4_B_CL = 70, + IMAGE_GATHER4_LZ = 71, + IMAGE_GATHER4_C = 72, + IMAGE_GATHER4_C_CL = 73, + IMAGE_GATHER4_C_L = 76, + IMAGE_GATHER4_C_B = 77, + IMAGE_GATHER4_C_B_CL = 78, + IMAGE_GATHER4_C_LZ = 79, + IMAGE_GATHER4_O = 80, + IMAGE_GATHER4_CL_O = 81, + IMAGE_GATHER4_L_O = 84, + IMAGE_GATHER4_B_O = 85, + IMAGE_GATHER4_B_CL_O = 86, + IMAGE_GATHER4_LZ_O = 87, + IMAGE_GATHER4_C_O = 88, + IMAGE_GATHER4_C_CL_O = 89, + IMAGE_GATHER4_C_L_O = 92, + IMAGE_GATHER4_C_B_O = 93, + IMAGE_GATHER4_C_B_CL_O = 94, + IMAGE_GATHER4_C_LZ_O = 95, + IMAGE_GET_LOD = 96, + IMAGE_SAMPLE_CD = 104, + IMAGE_SAMPLE_CD_CL = 105, + IMAGE_SAMPLE_C_CD = 106, + IMAGE_SAMPLE_C_CD_CL = 107, + IMAGE_SAMPLE_CD_O = 108, + IMAGE_SAMPLE_CD_CL_O = 109, + IMAGE_SAMPLE_C_CD_O = 110, + IMAGE_SAMPLE_C_CD_CL_O = 111, + + OP_RANGE_MIMG = IMAGE_SAMPLE_C_CD_CL_O + 1, +}; + +enum class OpcodeEXP : u32 { + EXP = 0, + + OP_RANGE_EXP = EXP + 1, +}; + +// Use to map VOP3 opcodes into VOP1, VOP2, VOPC +enum class OpMapVOP3VOPX : u32 { + VOP3_TO_VOPC = 0, + VOP3_TO_VOP2 = 256, + VOP3_TO_VOP1 = 384, +}; + +// Use to map all opcodes into a single enum +enum class OpcodeMap : u32 { + OP_MAP_SOP2 = 0, + OP_MAP_SOPK = OP_MAP_SOP2 + (u32)OpcodeSOP2::OP_RANGE_SOP2, + OP_MAP_SOP1 = OP_MAP_SOPK + (u32)OpcodeSOPK::OP_RANGE_SOPK, + OP_MAP_SOPC = OP_MAP_SOP1 + (u32)OpcodeSOP1::OP_RANGE_SOP1, + OP_MAP_SOPP = OP_MAP_SOPC + (u32)OpcodeSOPC::OP_RANGE_SOPC, + OP_MAP_VOPC = OP_MAP_SOPP + (u32)OpcodeSOPP::OP_RANGE_SOPP, + OP_MAP_VOP2 = OP_MAP_VOPC + (u32)OpcodeVOPC::OP_RANGE_VOPC, + OP_MAP_VOP1 = OP_MAP_VOP2 + (u32)OpcodeVOP2::OP_RANGE_VOP2, + OP_MAP_VOP3 = OP_MAP_VOP1 + (u32)OpcodeVOP1::OP_RANGE_VOP1, + OP_MAP_VINTRP = OP_MAP_VOP3 + (u32)OpcodeVOP3::OP_RANGE_VOP3, + OP_MAP_SMRD = OP_MAP_VINTRP + (u32)OpcodeVINTRP::OP_RANGE_VINTRP, + OP_MAP_DS = OP_MAP_SMRD + (u32)OpcodeSMRD::OP_RANGE_SMRD, + OP_MAP_MUBUF = OP_MAP_DS + (u32)OpcodeDS::OP_RANGE_DS, + OP_MAP_MTBUF = OP_MAP_MUBUF + (u32)OpcodeMUBUF::OP_RANGE_MUBUF, + OP_MAP_MIMG = OP_MAP_MTBUF + (u32)OpcodeMTBUF::OP_RANGE_MTBUF, + OP_MAP_EXP = OP_MAP_MIMG + (u32)OpcodeMIMG::OP_RANGE_MIMG, + OP_MAP_VOP3P = OP_MAP_EXP + (u32)OpcodeEXP::OP_RANGE_EXP, +}; + +enum class Opcode : u32 { + // SOP2 + S_ADD_U32 = 0 + (u32)OpcodeMap::OP_MAP_SOP2, + S_SUB_U32 = 1 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ADD_I32 = 2 + (u32)OpcodeMap::OP_MAP_SOP2, + S_SUB_I32 = 3 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ADDC_U32 = 4 + (u32)OpcodeMap::OP_MAP_SOP2, + S_SUBB_U32 = 5 + (u32)OpcodeMap::OP_MAP_SOP2, + S_MIN_I32 = 6 + (u32)OpcodeMap::OP_MAP_SOP2, + S_MIN_U32 = 7 + (u32)OpcodeMap::OP_MAP_SOP2, + S_MAX_I32 = 8 + (u32)OpcodeMap::OP_MAP_SOP2, + S_MAX_U32 = 9 + (u32)OpcodeMap::OP_MAP_SOP2, + S_CSELECT_B32 = 10 + (u32)OpcodeMap::OP_MAP_SOP2, + S_CSELECT_B64 = 11 + (u32)OpcodeMap::OP_MAP_SOP2, + S_AND_B32 = 14 + (u32)OpcodeMap::OP_MAP_SOP2, + S_AND_B64 = 15 + (u32)OpcodeMap::OP_MAP_SOP2, + S_OR_B32 = 16 + (u32)OpcodeMap::OP_MAP_SOP2, + S_OR_B64 = 17 + (u32)OpcodeMap::OP_MAP_SOP2, + S_XOR_B32 = 18 + (u32)OpcodeMap::OP_MAP_SOP2, + S_XOR_B64 = 19 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ANDN2_B32 = 20 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ANDN2_B64 = 21 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ORN2_B32 = 22 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ORN2_B64 = 23 + (u32)OpcodeMap::OP_MAP_SOP2, + S_NAND_B32 = 24 + (u32)OpcodeMap::OP_MAP_SOP2, + S_NAND_B64 = 25 + (u32)OpcodeMap::OP_MAP_SOP2, + S_NOR_B32 = 26 + (u32)OpcodeMap::OP_MAP_SOP2, + S_NOR_B64 = 27 + (u32)OpcodeMap::OP_MAP_SOP2, + S_XNOR_B32 = 28 + (u32)OpcodeMap::OP_MAP_SOP2, + S_XNOR_B64 = 29 + (u32)OpcodeMap::OP_MAP_SOP2, + S_LSHL_B32 = 30 + (u32)OpcodeMap::OP_MAP_SOP2, + S_LSHL_B64 = 31 + (u32)OpcodeMap::OP_MAP_SOP2, + S_LSHR_B32 = 32 + (u32)OpcodeMap::OP_MAP_SOP2, + S_LSHR_B64 = 33 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ASHR_I32 = 34 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ASHR_I64 = 35 + (u32)OpcodeMap::OP_MAP_SOP2, + S_BFM_B32 = 36 + (u32)OpcodeMap::OP_MAP_SOP2, + S_BFM_B64 = 37 + (u32)OpcodeMap::OP_MAP_SOP2, + S_MUL_I32 = 38 + (u32)OpcodeMap::OP_MAP_SOP2, + S_BFE_U32 = 39 + (u32)OpcodeMap::OP_MAP_SOP2, + S_BFE_I32 = 40 + (u32)OpcodeMap::OP_MAP_SOP2, + S_BFE_U64 = 41 + (u32)OpcodeMap::OP_MAP_SOP2, + S_BFE_I64 = 42 + (u32)OpcodeMap::OP_MAP_SOP2, + S_CBRANCH_G_FORK = 43 + (u32)OpcodeMap::OP_MAP_SOP2, + S_ABSDIFF_I32 = 44 + (u32)OpcodeMap::OP_MAP_SOP2, + // SOPK + S_MOVK_I32 = 0 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMOVK_I32 = 2 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_EQ_I32 = 3 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_LG_I32 = 4 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_GT_I32 = 5 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_GE_I32 = 6 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_LT_I32 = 7 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_LE_I32 = 8 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_EQ_U32 = 9 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_LG_U32 = 10 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_GT_U32 = 11 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_GE_U32 = 12 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_LT_U32 = 13 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CMPK_LE_U32 = 14 + (u32)OpcodeMap::OP_MAP_SOPK, + S_ADDK_I32 = 15 + (u32)OpcodeMap::OP_MAP_SOPK, + S_MULK_I32 = 16 + (u32)OpcodeMap::OP_MAP_SOPK, + S_CBRANCH_I_FORK = 17 + (u32)OpcodeMap::OP_MAP_SOPK, + S_GETREG_B32 = 18 + (u32)OpcodeMap::OP_MAP_SOPK, + S_SETREG_B32 = 19 + (u32)OpcodeMap::OP_MAP_SOPK, + S_GETREG_REGRD_B32 = 20 + (u32)OpcodeMap::OP_MAP_SOPK, + S_SETREG_IMM32_B32 = 21 + (u32)OpcodeMap::OP_MAP_SOPK, + // SOP1 + S_MOV_B32 = 3 + (u32)OpcodeMap::OP_MAP_SOP1, + S_MOV_B64 = 4 + (u32)OpcodeMap::OP_MAP_SOP1, + S_CMOV_B32 = 5 + (u32)OpcodeMap::OP_MAP_SOP1, + S_CMOV_B64 = 6 + (u32)OpcodeMap::OP_MAP_SOP1, + S_NOT_B32 = 7 + (u32)OpcodeMap::OP_MAP_SOP1, + S_NOT_B64 = 8 + (u32)OpcodeMap::OP_MAP_SOP1, + S_WQM_B32 = 9 + (u32)OpcodeMap::OP_MAP_SOP1, + S_WQM_B64 = 10 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BREV_B32 = 11 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BREV_B64 = 12 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BCNT0_I32_B32 = 13 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BCNT0_I32_B64 = 14 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BCNT1_I32_B32 = 15 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BCNT1_I32_B64 = 16 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FF0_I32_B32 = 17 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FF0_I32_B64 = 18 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FF1_I32_B32 = 19 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FF1_I32_B64 = 20 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FLBIT_I32_B32 = 21 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FLBIT_I32_B64 = 22 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FLBIT_I32 = 23 + (u32)OpcodeMap::OP_MAP_SOP1, + S_FLBIT_I32_I64 = 24 + (u32)OpcodeMap::OP_MAP_SOP1, + S_SEXT_I32_I8 = 25 + (u32)OpcodeMap::OP_MAP_SOP1, + S_SEXT_I32_I16 = 26 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BITSET0_B32 = 27 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BITSET0_B64 = 28 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BITSET1_B32 = 29 + (u32)OpcodeMap::OP_MAP_SOP1, + S_BITSET1_B64 = 30 + (u32)OpcodeMap::OP_MAP_SOP1, + S_GETPC_B64 = 31 + (u32)OpcodeMap::OP_MAP_SOP1, + S_SETPC_B64 = 32 + (u32)OpcodeMap::OP_MAP_SOP1, + S_SWAPPC_B64 = 33 + (u32)OpcodeMap::OP_MAP_SOP1, + S_RFE_B64 = 34 + (u32)OpcodeMap::OP_MAP_SOP1, + S_AND_SAVEEXEC_B64 = 36 + (u32)OpcodeMap::OP_MAP_SOP1, + S_OR_SAVEEXEC_B64 = 37 + (u32)OpcodeMap::OP_MAP_SOP1, + S_XOR_SAVEEXEC_B64 = 38 + (u32)OpcodeMap::OP_MAP_SOP1, + S_ANDN2_SAVEEXEC_B64 = 39 + (u32)OpcodeMap::OP_MAP_SOP1, + S_ORN2_SAVEEXEC_B64 = 40 + (u32)OpcodeMap::OP_MAP_SOP1, + S_NAND_SAVEEXEC_B64 = 41 + (u32)OpcodeMap::OP_MAP_SOP1, + S_NOR_SAVEEXEC_B64 = 42 + (u32)OpcodeMap::OP_MAP_SOP1, + S_XNOR_SAVEEXEC_B64 = 43 + (u32)OpcodeMap::OP_MAP_SOP1, + S_QUADMASK_B32 = 44 + (u32)OpcodeMap::OP_MAP_SOP1, + S_QUADMASK_B64 = 45 + (u32)OpcodeMap::OP_MAP_SOP1, + S_MOVRELS_B32 = 46 + (u32)OpcodeMap::OP_MAP_SOP1, + S_MOVRELS_B64 = 47 + (u32)OpcodeMap::OP_MAP_SOP1, + S_MOVRELD_B32 = 48 + (u32)OpcodeMap::OP_MAP_SOP1, + S_MOVRELD_B64 = 49 + (u32)OpcodeMap::OP_MAP_SOP1, + S_CBRANCH_JOIN = 50 + (u32)OpcodeMap::OP_MAP_SOP1, + S_MOV_REGRD_B32 = 51 + (u32)OpcodeMap::OP_MAP_SOP1, + S_ABS_I32 = 52 + (u32)OpcodeMap::OP_MAP_SOP1, + S_MOV_FED_B32 = 53 + (u32)OpcodeMap::OP_MAP_SOP1, + // SOPC + S_CMP_EQ_I32 = 0 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_LG_I32 = 1 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_GT_I32 = 2 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_GE_I32 = 3 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_LT_I32 = 4 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_LE_I32 = 5 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_EQ_U32 = 6 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_LG_U32 = 7 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_GT_U32 = 8 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_GE_U32 = 9 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_LT_U32 = 10 + (u32)OpcodeMap::OP_MAP_SOPC, + S_CMP_LE_U32 = 11 + (u32)OpcodeMap::OP_MAP_SOPC, + S_BITCMP0_B32 = 12 + (u32)OpcodeMap::OP_MAP_SOPC, + S_BITCMP1_B32 = 13 + (u32)OpcodeMap::OP_MAP_SOPC, + S_BITCMP0_B64 = 14 + (u32)OpcodeMap::OP_MAP_SOPC, + S_BITCMP1_B64 = 15 + (u32)OpcodeMap::OP_MAP_SOPC, + S_SETVSKIP = 16 + (u32)OpcodeMap::OP_MAP_SOPC, + // SOPP + S_NOP = 0 + (u32)OpcodeMap::OP_MAP_SOPP, + S_ENDPGM = 1 + (u32)OpcodeMap::OP_MAP_SOPP, + S_BRANCH = 2 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_SCC0 = 4 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_SCC1 = 5 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_VCCZ = 6 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_VCCNZ = 7 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_EXECZ = 8 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_EXECNZ = 9 + (u32)OpcodeMap::OP_MAP_SOPP, + S_BARRIER = 10 + (u32)OpcodeMap::OP_MAP_SOPP, + S_SETKILL = 11 + (u32)OpcodeMap::OP_MAP_SOPP, + S_WAITCNT = 12 + (u32)OpcodeMap::OP_MAP_SOPP, + S_SETHALT = 13 + (u32)OpcodeMap::OP_MAP_SOPP, + S_SLEEP = 14 + (u32)OpcodeMap::OP_MAP_SOPP, + S_SETPRIO = 15 + (u32)OpcodeMap::OP_MAP_SOPP, + S_SENDMSG = 16 + (u32)OpcodeMap::OP_MAP_SOPP, + S_SENDMSGHALT = 17 + (u32)OpcodeMap::OP_MAP_SOPP, + S_TRAP = 18 + (u32)OpcodeMap::OP_MAP_SOPP, + S_ICACHE_INV = 19 + (u32)OpcodeMap::OP_MAP_SOPP, + S_INCPERFLEVEL = 20 + (u32)OpcodeMap::OP_MAP_SOPP, + S_DECPERFLEVEL = 21 + (u32)OpcodeMap::OP_MAP_SOPP, + S_TTRACEDATA = 22 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_CDBGSYS = 23 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_CDBGUSER = 24 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_CDBGSYS_OR_USER = 25 + (u32)OpcodeMap::OP_MAP_SOPP, + S_CBRANCH_CDBGSYS_AND_USER = 26 + (u32)OpcodeMap::OP_MAP_SOPP, + // VOPC + V_CMP_F_F32 = 0 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_F32 = 1 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_F32 = 2 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_F32 = 3 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_F32 = 4 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LG_F32 = 5 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_F32 = 6 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_O_F32 = 7 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_U_F32 = 8 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NGE_F32 = 9 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NLG_F32 = 10 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NGT_F32 = 11 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NLE_F32 = 12 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NEQ_F32 = 13 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NLT_F32 = 14 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_TRU_F32 = 15 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_T_F32 = 15 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_F_F32 = 16 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LT_F32 = 17 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_EQ_F32 = 18 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LE_F32 = 19 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GT_F32 = 20 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LG_F32 = 21 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GE_F32 = 22 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_O_F32 = 23 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_U_F32 = 24 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NGE_F32 = 25 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NLG_F32 = 26 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NGT_F32 = 27 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NLE_F32 = 28 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NEQ_F32 = 29 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NLT_F32 = 30 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_TRU_F32 = 31 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_T_F32 = 31 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_F_F64 = 32 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_F64 = 33 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_F64 = 34 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_F64 = 35 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_F64 = 36 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LG_F64 = 37 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_F64 = 38 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_O_F64 = 39 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_U_F64 = 40 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NGE_F64 = 41 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NLG_F64 = 42 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NGT_F64 = 43 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NLE_F64 = 44 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NEQ_F64 = 45 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NLT_F64 = 46 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_TRU_F64 = 47 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_T_F64 = 47 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_F_F64 = 48 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LT_F64 = 49 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_EQ_F64 = 50 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LE_F64 = 51 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GT_F64 = 52 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LG_F64 = 53 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GE_F64 = 54 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_O_F64 = 55 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_U_F64 = 56 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NGE_F64 = 57 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NLG_F64 = 58 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NGT_F64 = 59 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NLE_F64 = 60 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NEQ_F64 = 61 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NLT_F64 = 62 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_TRU_F64 = 63 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_T_F64 = 63 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_F_F32 = 64 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_LT_F32 = 65 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_EQ_F32 = 66 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_LE_F32 = 67 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_GT_F32 = 68 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_LG_F32 = 69 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_GE_F32 = 70 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_O_F32 = 71 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_U_F32 = 72 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NGE_F32 = 73 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NLG_F32 = 74 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NGT_F32 = 75 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NLE_F32 = 76 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NEQ_F32 = 77 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NLT_F32 = 78 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_TRU_F32 = 79 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_T_F32 = 79 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_F_F32 = 80 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_LT_F32 = 81 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_EQ_F32 = 82 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_LE_F32 = 83 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_GT_F32 = 84 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_LG_F32 = 85 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_GE_F32 = 86 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_O_F32 = 87 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_U_F32 = 88 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NGE_F32 = 89 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NLG_F32 = 90 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NGT_F32 = 91 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NLE_F32 = 92 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NEQ_F32 = 93 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NLT_F32 = 94 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_TRU_F32 = 95 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_T_F32 = 95 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_F_F64 = 96 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_LT_F64 = 97 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_EQ_F64 = 98 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_LE_F64 = 99 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_GT_F64 = 100 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_LG_F64 = 101 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_GE_F64 = 102 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_O_F64 = 103 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_U_F64 = 104 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NGE_F64 = 105 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NLG_F64 = 106 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NGT_F64 = 107 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NLE_F64 = 108 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NEQ_F64 = 109 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_NLT_F64 = 110 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_TRU_F64 = 111 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPS_T_F64 = 111 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_F_F64 = 112 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_LT_F64 = 113 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_EQ_F64 = 114 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_LE_F64 = 115 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_GT_F64 = 116 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_LG_F64 = 117 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_GE_F64 = 118 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_O_F64 = 119 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_U_F64 = 120 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NGE_F64 = 121 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NLG_F64 = 122 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NGT_F64 = 123 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NLE_F64 = 124 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NEQ_F64 = 125 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_NLT_F64 = 126 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_TRU_F64 = 127 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPSX_T_F64 = 127 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_F_I32 = 128 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_I32 = 129 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_I32 = 130 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_I32 = 131 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_I32 = 132 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NE_I32 = 133 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_I32 = 134 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_TRU_I32 = 135 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_T_I32 = 135 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_CLASS_F32 = 136 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_I16 = 137 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_I16 = 138 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_I16 = 139 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_I16 = 140 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NE_I16 = 141 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_I16 = 142 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_F_I32 = 144 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LT_I32 = 145 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_EQ_I32 = 146 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LE_I32 = 147 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GT_I32 = 148 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LG_I32 = 149 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NE_I32 = 149 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GE_I32 = 150 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_TRU_I32 = 151 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_T_I32 = 151 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_CLASS_F32 = 152 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_F_I64 = 160 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_I64 = 161 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_I64 = 162 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_I64 = 163 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_I64 = 164 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LG_I64 = 165 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NE_I64 = 165 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_I64 = 166 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_TRU_I64 = 167 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_T_I64 = 167 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_CLASS_F64 = 168 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_U16 = 169 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_U16 = 170 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_U16 = 171 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_U16 = 172 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NE_U16 = 173 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_U16 = 174 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_F_I64 = 176 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LT_I64 = 177 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_EQ_I64 = 178 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LE_I64 = 179 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GT_I64 = 180 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LG_I64 = 181 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NE_I64 = 181 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GE_I64 = 182 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_TRU_I64 = 183 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_T_I64 = 183 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_CLASS_F64 = 184 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_F_U32 = 192 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_U32 = 193 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_U32 = 194 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_U32 = 195 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_U32 = 196 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NE_U32 = 197 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_U32 = 198 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_TRU_U32 = 199 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_T_U32 = 199 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_F_F16 = 200 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_F16 = 201 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_F16 = 202 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_F16 = 203 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_F16 = 204 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LG_F16 = 205 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_F16 = 206 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_O_F16 = 207 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_F_U32 = 208 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LT_U32 = 209 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_EQ_U32 = 210 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LE_U32 = 211 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GT_U32 = 212 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NE_U32 = 213 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GE_U32 = 214 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_TRU_U32 = 215 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_T_U32 = 215 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_F_U64 = 224 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LT_U64 = 225 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_EQ_U64 = 226 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LE_U64 = 227 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GT_U64 = 228 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_LG_U64 = 229 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_NE_U64 = 229 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_GE_U64 = 230 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_TRU_U64 = 231 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMP_T_U64 = 231 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_F_U64 = 240 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LT_U64 = 241 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_EQ_U64 = 242 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LE_U64 = 243 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GT_U64 = 244 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_LG_U64 = 245 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_NE_U64 = 245 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_GE_U64 = 246 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_TRU_U64 = 247 + (u32)OpcodeMap::OP_MAP_VOPC, + V_CMPX_T_U64 = 247 + (u32)OpcodeMap::OP_MAP_VOPC, + // VOP2 + V_CNDMASK_B32 = 0 + (u32)OpcodeMap::OP_MAP_VOP2, + V_READLANE_B32 = 1 + (u32)OpcodeMap::OP_MAP_VOP2, + V_WRITELANE_B32 = 2 + (u32)OpcodeMap::OP_MAP_VOP2, + V_ADD_F32 = 3 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUB_F32 = 4 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUBREV_F32 = 5 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MAC_LEGACY_F32 = 6 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MUL_LEGACY_F32 = 7 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MUL_F32 = 8 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MUL_I32_I24 = 9 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MUL_HI_I32_I24 = 10 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MUL_U32_U24 = 11 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MUL_HI_U32_U24 = 12 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MIN_LEGACY_F32 = 13 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MAX_LEGACY_F32 = 14 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MIN_F32 = 15 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MAX_F32 = 16 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MIN_I32 = 17 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MAX_I32 = 18 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MIN_U32 = 19 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MAX_U32 = 20 + (u32)OpcodeMap::OP_MAP_VOP2, + V_LSHR_B32 = 21 + (u32)OpcodeMap::OP_MAP_VOP2, + V_LSHRREV_B32 = 22 + (u32)OpcodeMap::OP_MAP_VOP2, + V_ASHR_I32 = 23 + (u32)OpcodeMap::OP_MAP_VOP2, + V_ASHRREV_I32 = 24 + (u32)OpcodeMap::OP_MAP_VOP2, + V_LSHL_B32 = 25 + (u32)OpcodeMap::OP_MAP_VOP2, + V_LSHLREV_B32 = 26 + (u32)OpcodeMap::OP_MAP_VOP2, + V_AND_B32 = 27 + (u32)OpcodeMap::OP_MAP_VOP2, + V_OR_B32 = 28 + (u32)OpcodeMap::OP_MAP_VOP2, + V_XOR_B32 = 29 + (u32)OpcodeMap::OP_MAP_VOP2, + V_BFM_B32 = 30 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MAC_F32 = 31 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MADMK_F32 = 32 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MADAK_F32 = 33 + (u32)OpcodeMap::OP_MAP_VOP2, + V_BCNT_U32_B32 = 34 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MBCNT_LO_U32_B32 = 35 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MBCNT_HI_U32_B32 = 36 + (u32)OpcodeMap::OP_MAP_VOP2, + V_ADD_I32 = 37 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUB_I32 = 38 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUBREV_I32 = 39 + (u32)OpcodeMap::OP_MAP_VOP2, + V_ADDC_U32 = 40 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUBB_U32 = 41 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUBBREV_U32 = 42 + (u32)OpcodeMap::OP_MAP_VOP2, + V_LDEXP_F32 = 43 + (u32)OpcodeMap::OP_MAP_VOP2, + V_CVT_PKACCUM_U8_F32 = 44 + (u32)OpcodeMap::OP_MAP_VOP2, + V_CVT_PKNORM_I16_F32 = 45 + (u32)OpcodeMap::OP_MAP_VOP2, + V_CVT_PKNORM_U16_F32 = 46 + (u32)OpcodeMap::OP_MAP_VOP2, + V_CVT_PKRTZ_F16_F32 = 47 + (u32)OpcodeMap::OP_MAP_VOP2, + V_CVT_PK_U16_U32 = 48 + (u32)OpcodeMap::OP_MAP_VOP2, + V_CVT_PK_I16_I32 = 49 + (u32)OpcodeMap::OP_MAP_VOP2, + V_ADD_F16 = 50 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUB_F16 = 51 + (u32)OpcodeMap::OP_MAP_VOP2, + V_SUBREV_F16 = 52 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MUL_F16 = 53 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MAX_F16 = 57 + (u32)OpcodeMap::OP_MAP_VOP2, + V_MIN_F16 = 58 + (u32)OpcodeMap::OP_MAP_VOP2, + V_LDEXP_F16 = 59 + (u32)OpcodeMap::OP_MAP_VOP2, + // VOP1 + V_NOP = 0 + (u32)OpcodeMap::OP_MAP_VOP1, + V_MOV_B32 = 1 + (u32)OpcodeMap::OP_MAP_VOP1, + V_READFIRSTLANE_B32 = 2 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_I32_F64 = 3 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F64_I32 = 4 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_I32 = 5 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_U32 = 6 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_U32_F32 = 7 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_I32_F32 = 8 + (u32)OpcodeMap::OP_MAP_VOP1, + V_MOV_FED_B32 = 9 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F16_F32 = 10 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_F16 = 11 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_RPI_I32_F32 = 12 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_FLR_I32_F32 = 13 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_OFF_F32_I4 = 14 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_F64 = 15 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F64_F32 = 16 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_UBYTE0 = 17 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_UBYTE1 = 18 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_UBYTE2 = 19 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F32_UBYTE3 = 20 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_U32_F64 = 21 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CVT_F64_U32 = 22 + (u32)OpcodeMap::OP_MAP_VOP1, + V_TRUNC_F64 = 23 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CEIL_F64 = 24 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RNDNE_F64 = 25 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FLOOR_F64 = 26 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FRACT_F32 = 32 + (u32)OpcodeMap::OP_MAP_VOP1, + V_TRUNC_F32 = 33 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CEIL_F32 = 34 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RNDNE_F32 = 35 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FLOOR_F32 = 36 + (u32)OpcodeMap::OP_MAP_VOP1, + V_EXP_F32 = 37 + (u32)OpcodeMap::OP_MAP_VOP1, + V_LOG_CLAMP_F32 = 38 + (u32)OpcodeMap::OP_MAP_VOP1, + V_LOG_F32 = 39 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RCP_CLAMP_F32 = 40 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RCP_LEGACY_F32 = 41 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RCP_F32 = 42 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RCP_IFLAG_F32 = 43 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RSQ_CLAMP_F32 = 44 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RSQ_LEGACY_F32 = 45 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RSQ_F32 = 46 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RCP_F64 = 47 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RCP_CLAMP_F64 = 48 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RSQ_F64 = 49 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RSQ_CLAMP_F64 = 50 + (u32)OpcodeMap::OP_MAP_VOP1, + V_SQRT_F32 = 51 + (u32)OpcodeMap::OP_MAP_VOP1, + V_SQRT_F64 = 52 + (u32)OpcodeMap::OP_MAP_VOP1, + V_SIN_F32 = 53 + (u32)OpcodeMap::OP_MAP_VOP1, + V_COS_F32 = 54 + (u32)OpcodeMap::OP_MAP_VOP1, + V_NOT_B32 = 55 + (u32)OpcodeMap::OP_MAP_VOP1, + V_BFREV_B32 = 56 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FFBH_U32 = 57 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FFBL_B32 = 58 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FFBH_I32 = 59 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FREXP_EXP_I32_F64 = 60 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FREXP_MANT_F64 = 61 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FRACT_F64 = 62 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FREXP_EXP_I32_F32 = 63 + (u32)OpcodeMap::OP_MAP_VOP1, + V_FREXP_MANT_F32 = 64 + (u32)OpcodeMap::OP_MAP_VOP1, + V_CLREXCP = 65 + (u32)OpcodeMap::OP_MAP_VOP1, + V_MOVRELD_B32 = 66 + (u32)OpcodeMap::OP_MAP_VOP1, + V_MOVRELS_B32 = 67 + (u32)OpcodeMap::OP_MAP_VOP1, + V_MOVRELSD_B32 = 68 + (u32)OpcodeMap::OP_MAP_VOP1, + V_LOG_LEGACY_F32 = 69 + (u32)OpcodeMap::OP_MAP_VOP1, + V_EXP_LEGACY_F32 = 70 + (u32)OpcodeMap::OP_MAP_VOP1, + V_RCP_F16 = 84 + (u32)OpcodeMap::OP_MAP_VOP1, + V_SQRT_F16 = 85 + (u32)OpcodeMap::OP_MAP_VOP1, + // VOP3 + V_MAD_LEGACY_F32 = 320 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAD_F32 = 321 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAD_I32_I24 = 322 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAD_U32_U24 = 323 + (u32)OpcodeMap::OP_MAP_VOP3, + V_CUBEID_F32 = 324 + (u32)OpcodeMap::OP_MAP_VOP3, + V_CUBESC_F32 = 325 + (u32)OpcodeMap::OP_MAP_VOP3, + V_CUBETC_F32 = 326 + (u32)OpcodeMap::OP_MAP_VOP3, + V_CUBEMA_F32 = 327 + (u32)OpcodeMap::OP_MAP_VOP3, + V_BFE_U32 = 328 + (u32)OpcodeMap::OP_MAP_VOP3, + V_BFE_I32 = 329 + (u32)OpcodeMap::OP_MAP_VOP3, + V_BFI_B32 = 330 + (u32)OpcodeMap::OP_MAP_VOP3, + V_FMA_F32 = 331 + (u32)OpcodeMap::OP_MAP_VOP3, + V_FMA_F64 = 332 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LERP_U8 = 333 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ALIGNBIT_B32 = 334 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ALIGNBYTE_B32 = 335 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MULLIT_F32 = 336 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MIN3_F32 = 337 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MIN3_I32 = 338 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MIN3_U32 = 339 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAX3_F32 = 340 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAX3_I32 = 341 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAX3_U32 = 342 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MED3_F32 = 343 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MED3_I32 = 344 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MED3_U32 = 345 + (u32)OpcodeMap::OP_MAP_VOP3, + V_SAD_U8 = 346 + (u32)OpcodeMap::OP_MAP_VOP3, + V_SAD_HI_U8 = 347 + (u32)OpcodeMap::OP_MAP_VOP3, + V_SAD_U16 = 348 + (u32)OpcodeMap::OP_MAP_VOP3, + V_SAD_U32 = 349 + (u32)OpcodeMap::OP_MAP_VOP3, + V_CVT_PK_U8_F32 = 350 + (u32)OpcodeMap::OP_MAP_VOP3, + V_DIV_FIXUP_F32 = 351 + (u32)OpcodeMap::OP_MAP_VOP3, + V_DIV_FIXUP_F64 = 352 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LSHL_B64 = 353 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LSHR_B64 = 354 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ASHR_I64 = 355 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ADD_F64 = 356 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MUL_F64 = 357 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MIN_F64 = 358 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAX_F64 = 359 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LDEXP_F64 = 360 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MUL_LO_U32 = 361 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MUL_HI_U32 = 362 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MUL_LO_I32 = 363 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MUL_HI_I32 = 364 + (u32)OpcodeMap::OP_MAP_VOP3, + V_DIV_SCALE_F32 = 365 + (u32)OpcodeMap::OP_MAP_VOP3, + V_DIV_SCALE_F64 = 366 + (u32)OpcodeMap::OP_MAP_VOP3, + V_DIV_FMAS_F32 = 367 + (u32)OpcodeMap::OP_MAP_VOP3, + V_DIV_FMAS_F64 = 368 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MSAD_U8 = 369 + (u32)OpcodeMap::OP_MAP_VOP3, + V_QSAD_U8 = 370 + (u32)OpcodeMap::OP_MAP_VOP3, + V_QSAD_PK_U16_U8 = 370 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MQSAD_U8 = 371 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MQSAD_PK_U16_U8 = 371 + (u32)OpcodeMap::OP_MAP_VOP3, + V_TRIG_PREOP_F64 = 372 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MQSAD_U32_U8 = 373 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAD_U64_U32 = 374 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAD_I64_I32 = 375 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ADD_NC_U16 = 771 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LSHRREV_B16 = 775 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ASHRREV_I16 = 776 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ADD_NC_I16 = 781 + (u32)OpcodeMap::OP_MAP_VOP3, + V_SUB_NC_I16 = 782 + (u32)OpcodeMap::OP_MAP_VOP3, + V_SUB_CO_U32 = 784 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LSHLREV_B16 = 788 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAD_F16 = 833 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LSHL_ADD_U32 = 838 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ADD_LSHL_U32 = 839 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MIN3_F16 = 849 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAX3_F16 = 852 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MED3_F16 = 855 + (u32)OpcodeMap::OP_MAP_VOP3, + V_MAD_I16 = 862 + (u32)OpcodeMap::OP_MAP_VOP3, + V_ADD3_U32 = 877 + (u32)OpcodeMap::OP_MAP_VOP3, + V_LSHL_OR_B32 = 879 + (u32)OpcodeMap::OP_MAP_VOP3, + V_AND_OR_B32 = 881 + (u32)OpcodeMap::OP_MAP_VOP3, + V_OR3_B32 = 882 + (u32)OpcodeMap::OP_MAP_VOP3, + // VINTRP + V_INTERP_P1_F32 = 0 + (u32)OpcodeMap::OP_MAP_VINTRP, + V_INTERP_P2_F32 = 1 + (u32)OpcodeMap::OP_MAP_VINTRP, + V_INTERP_MOV_F32 = 2 + (u32)OpcodeMap::OP_MAP_VINTRP, + // SMRD + S_LOAD_DWORD = 0 + (u32)OpcodeMap::OP_MAP_SMRD, + S_LOAD_DWORDX2 = 1 + (u32)OpcodeMap::OP_MAP_SMRD, + S_LOAD_DWORDX4 = 2 + (u32)OpcodeMap::OP_MAP_SMRD, + S_LOAD_DWORDX8 = 3 + (u32)OpcodeMap::OP_MAP_SMRD, + S_LOAD_DWORDX16 = 4 + (u32)OpcodeMap::OP_MAP_SMRD, + S_BUFFER_LOAD_DWORD = 8 + (u32)OpcodeMap::OP_MAP_SMRD, + S_BUFFER_LOAD_DWORDX2 = 9 + (u32)OpcodeMap::OP_MAP_SMRD, + S_BUFFER_LOAD_DWORDX4 = 10 + (u32)OpcodeMap::OP_MAP_SMRD, + S_BUFFER_LOAD_DWORDX8 = 11 + (u32)OpcodeMap::OP_MAP_SMRD, + S_BUFFER_LOAD_DWORDX16 = 12 + (u32)OpcodeMap::OP_MAP_SMRD, + S_MEMTIME = 30 + (u32)OpcodeMap::OP_MAP_SMRD, + S_DCACHE_INV = 31 + (u32)OpcodeMap::OP_MAP_SMRD, + // DS + DS_ADD_U32 = 0 + (u32)OpcodeMap::OP_MAP_DS, + DS_SUB_U32 = 1 + (u32)OpcodeMap::OP_MAP_DS, + DS_RSUB_U32 = 2 + (u32)OpcodeMap::OP_MAP_DS, + DS_INC_U32 = 3 + (u32)OpcodeMap::OP_MAP_DS, + DS_DEC_U32 = 4 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_I32 = 5 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_I32 = 6 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_U32 = 7 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_U32 = 8 + (u32)OpcodeMap::OP_MAP_DS, + DS_AND_B32 = 9 + (u32)OpcodeMap::OP_MAP_DS, + DS_OR_B32 = 10 + (u32)OpcodeMap::OP_MAP_DS, + DS_XOR_B32 = 11 + (u32)OpcodeMap::OP_MAP_DS, + DS_MSKOR_B32 = 12 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_B32 = 13 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE2_B32 = 14 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE2ST64_B32 = 15 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_B32 = 16 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_F32 = 17 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_F32 = 18 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_F32 = 19 + (u32)OpcodeMap::OP_MAP_DS, + DS_NOP = 20 + (u32)OpcodeMap::OP_MAP_DS, + DS_GWS_SEMA_RELEASE_ALL = 24 + (u32)OpcodeMap::OP_MAP_DS, + DS_GWS_INIT = 25 + (u32)OpcodeMap::OP_MAP_DS, + DS_GWS_SEMA_V = 26 + (u32)OpcodeMap::OP_MAP_DS, + DS_GWS_SEMA_BR = 27 + (u32)OpcodeMap::OP_MAP_DS, + DS_GWS_SEMA_P = 28 + (u32)OpcodeMap::OP_MAP_DS, + DS_GWS_BARRIER = 29 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_B8 = 30 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_B16 = 31 + (u32)OpcodeMap::OP_MAP_DS, + DS_ADD_RTN_U32 = 32 + (u32)OpcodeMap::OP_MAP_DS, + DS_SUB_RTN_U32 = 33 + (u32)OpcodeMap::OP_MAP_DS, + DS_RSUB_RTN_U32 = 34 + (u32)OpcodeMap::OP_MAP_DS, + DS_INC_RTN_U32 = 35 + (u32)OpcodeMap::OP_MAP_DS, + DS_DEC_RTN_U32 = 36 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_RTN_I32 = 37 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_RTN_I32 = 38 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_RTN_U32 = 39 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_RTN_U32 = 40 + (u32)OpcodeMap::OP_MAP_DS, + DS_AND_RTN_B32 = 41 + (u32)OpcodeMap::OP_MAP_DS, + DS_OR_RTN_B32 = 42 + (u32)OpcodeMap::OP_MAP_DS, + DS_XOR_RTN_B32 = 43 + (u32)OpcodeMap::OP_MAP_DS, + DS_MSKOR_RTN_B32 = 44 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRXCHG_RTN_B32 = 45 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRXCHG2_RTN_B32 = 46 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRXCHG2ST64_RTN_B32 = 47 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_RTN_B32 = 48 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_RTN_F32 = 49 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_RTN_F32 = 50 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_RTN_F32 = 51 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRAP_RTN_B32 = 52 + (u32)OpcodeMap::OP_MAP_DS, + DS_SWIZZLE_B32 = 53 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_B32 = 54 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ2_B32 = 55 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ2ST64_B32 = 56 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_I8 = 57 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_U8 = 58 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_I16 = 59 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_U16 = 60 + (u32)OpcodeMap::OP_MAP_DS, + DS_CONSUME = 61 + (u32)OpcodeMap::OP_MAP_DS, + DS_APPEND = 62 + (u32)OpcodeMap::OP_MAP_DS, + DS_ORDERED_COUNT = 63 + (u32)OpcodeMap::OP_MAP_DS, + DS_ADD_U64 = 64 + (u32)OpcodeMap::OP_MAP_DS, + DS_SUB_U64 = 65 + (u32)OpcodeMap::OP_MAP_DS, + DS_RSUB_U64 = 66 + (u32)OpcodeMap::OP_MAP_DS, + DS_INC_U64 = 67 + (u32)OpcodeMap::OP_MAP_DS, + DS_DEC_U64 = 68 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_I64 = 69 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_I64 = 70 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_U64 = 71 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_U64 = 72 + (u32)OpcodeMap::OP_MAP_DS, + DS_AND_B64 = 73 + (u32)OpcodeMap::OP_MAP_DS, + DS_OR_B64 = 74 + (u32)OpcodeMap::OP_MAP_DS, + DS_XOR_B64 = 75 + (u32)OpcodeMap::OP_MAP_DS, + DS_MSKOR_B64 = 76 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_B64 = 77 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE2_B64 = 78 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE2ST64_B64 = 79 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_B64 = 80 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_F64 = 81 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_F64 = 82 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_F64 = 83 + (u32)OpcodeMap::OP_MAP_DS, + DS_ADD_RTN_U64 = 96 + (u32)OpcodeMap::OP_MAP_DS, + DS_SUB_RTN_U64 = 97 + (u32)OpcodeMap::OP_MAP_DS, + DS_RSUB_RTN_U64 = 98 + (u32)OpcodeMap::OP_MAP_DS, + DS_INC_RTN_U64 = 99 + (u32)OpcodeMap::OP_MAP_DS, + DS_DEC_RTN_U64 = 100 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_RTN_I64 = 101 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_RTN_I64 = 102 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_RTN_U64 = 103 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_RTN_U64 = 104 + (u32)OpcodeMap::OP_MAP_DS, + DS_AND_RTN_B64 = 105 + (u32)OpcodeMap::OP_MAP_DS, + DS_OR_RTN_B64 = 106 + (u32)OpcodeMap::OP_MAP_DS, + DS_XOR_RTN_B64 = 107 + (u32)OpcodeMap::OP_MAP_DS, + DS_MSKOR_RTN_B64 = 108 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRXCHG_RTN_B64 = 109 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRXCHG2_RTN_B64 = 110 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRXCHG2ST64_RTN_B64 = 111 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_RTN_B64 = 112 + (u32)OpcodeMap::OP_MAP_DS, + DS_CMPST_RTN_F64 = 113 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_RTN_F64 = 114 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_RTN_F64 = 115 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_B64 = 118 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ2_B64 = 119 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ2ST64_B64 = 120 + (u32)OpcodeMap::OP_MAP_DS, + DS_CONDXCHG32_RTN_B64 = 126 + (u32)OpcodeMap::OP_MAP_DS, + DS_ADD_SRC2_U32 = 128 + (u32)OpcodeMap::OP_MAP_DS, + DS_SUB_SRC2_U32 = 129 + (u32)OpcodeMap::OP_MAP_DS, + DS_RSUB_SRC2_U32 = 130 + (u32)OpcodeMap::OP_MAP_DS, + DS_INC_SRC2_U32 = 131 + (u32)OpcodeMap::OP_MAP_DS, + DS_DEC_SRC2_U32 = 132 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_SRC2_I32 = 133 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_SRC2_I32 = 134 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_SRC2_U32 = 135 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_SRC2_U32 = 136 + (u32)OpcodeMap::OP_MAP_DS, + DS_AND_SRC2_B32 = 137 + (u32)OpcodeMap::OP_MAP_DS, + DS_OR_SRC2_B32 = 138 + (u32)OpcodeMap::OP_MAP_DS, + DS_XOR_SRC2_B32 = 139 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_SRC2_B32 = 141 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_SRC2_F32 = 146 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_SRC2_F32 = 147 + (u32)OpcodeMap::OP_MAP_DS, + DS_ADD_SRC2_U64 = 192 + (u32)OpcodeMap::OP_MAP_DS, + DS_SUB_SRC2_U64 = 193 + (u32)OpcodeMap::OP_MAP_DS, + DS_RSUB_SRC2_U64 = 194 + (u32)OpcodeMap::OP_MAP_DS, + DS_INC_SRC2_U64 = 195 + (u32)OpcodeMap::OP_MAP_DS, + DS_DEC_SRC2_U64 = 196 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_SRC2_I64 = 197 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_SRC2_I64 = 198 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_SRC2_U64 = 199 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_SRC2_U64 = 200 + (u32)OpcodeMap::OP_MAP_DS, + DS_AND_SRC2_B64 = 201 + (u32)OpcodeMap::OP_MAP_DS, + DS_OR_SRC2_B64 = 202 + (u32)OpcodeMap::OP_MAP_DS, + DS_XOR_SRC2_B64 = 203 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_SRC2_B64 = 205 + (u32)OpcodeMap::OP_MAP_DS, + DS_MIN_SRC2_F64 = 210 + (u32)OpcodeMap::OP_MAP_DS, + DS_MAX_SRC2_F64 = 211 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_B96 = 222 + (u32)OpcodeMap::OP_MAP_DS, + DS_WRITE_B128 = 223 + (u32)OpcodeMap::OP_MAP_DS, + DS_CONDXCHG32_RTN_B128 = 253 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_B96 = 254 + (u32)OpcodeMap::OP_MAP_DS, + DS_READ_B128 = 255 + (u32)OpcodeMap::OP_MAP_DS, + // MUBUF + BUFFER_LOAD_FORMAT_X = 0 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_FORMAT_XY = 1 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_FORMAT_XYZ = 2 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_FORMAT_XYZW = 3 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_FORMAT_X = 4 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_FORMAT_XY = 5 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_FORMAT_XYZ = 6 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_FORMAT_XYZW = 7 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_UBYTE = 8 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_SBYTE = 9 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_USHORT = 10 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_SSHORT = 11 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_DWORD = 12 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_DWORDX2 = 13 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_DWORDX4 = 14 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_LOAD_DWORDX3 = 15 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_BYTE = 24 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_SHORT = 26 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_DWORD = 28 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_DWORDX2 = 29 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_DWORDX4 = 30 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_STORE_DWORDX3 = 31 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SWAP = 48 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_CMPSWAP = 49 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_ADD = 50 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SUB = 51 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SMIN = 53 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_UMIN = 54 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SMAX = 55 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_UMAX = 56 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_AND = 57 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_OR = 58 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_XOR = 59 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_INC = 60 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_DEC = 61 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_FCMPSWAP = 62 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_FMIN = 63 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_FMAX = 64 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SWAP_X2 = 80 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_CMPSWAP_X2 = 81 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_ADD_X2 = 82 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SUB_X2 = 83 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SMIN_X2 = 85 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_UMIN_X2 = 86 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_SMAX_X2 = 87 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_UMAX_X2 = 88 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_AND_X2 = 89 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_OR_X2 = 90 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_XOR_X2 = 91 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_INC_X2 = 92 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_DEC_X2 = 93 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_FCMPSWAP_X2 = 94 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_FMIN_X2 = 95 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_ATOMIC_FMAX_X2 = 96 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_WBINVL1_SC = 112 + (u32)OpcodeMap::OP_MAP_MUBUF, + BUFFER_WBINVL1 = 113 + (u32)OpcodeMap::OP_MAP_MUBUF, + // MTBUF + TBUFFER_LOAD_FORMAT_X = 0 + (u32)OpcodeMap::OP_MAP_MTBUF, + TBUFFER_LOAD_FORMAT_XY = 1 + (u32)OpcodeMap::OP_MAP_MTBUF, + TBUFFER_LOAD_FORMAT_XYZ = 2 + (u32)OpcodeMap::OP_MAP_MTBUF, + TBUFFER_LOAD_FORMAT_XYZW = 3 + (u32)OpcodeMap::OP_MAP_MTBUF, + TBUFFER_STORE_FORMAT_X = 4 + (u32)OpcodeMap::OP_MAP_MTBUF, + TBUFFER_STORE_FORMAT_XY = 5 + (u32)OpcodeMap::OP_MAP_MTBUF, + TBUFFER_STORE_FORMAT_XYZ = 6 + (u32)OpcodeMap::OP_MAP_MTBUF, + TBUFFER_STORE_FORMAT_XYZW = 7 + (u32)OpcodeMap::OP_MAP_MTBUF, + // MIMG + IMAGE_LOAD = 0 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_LOAD_MIP = 1 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_LOAD_PCK = 2 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_LOAD_PCK_SGN = 3 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_LOAD_MIP_PCK = 4 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_LOAD_MIP_PCK_SGN = 5 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_STORE = 8 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_STORE_MIP = 9 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_STORE_PCK = 10 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_STORE_MIP_PCK = 11 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GET_RESINFO = 14 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_SWAP = 15 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_CMPSWAP = 16 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_ADD = 17 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_SUB = 18 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_SMIN = 20 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_UMIN = 21 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_SMAX = 22 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_UMAX = 23 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_AND = 24 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_OR = 25 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_XOR = 26 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_INC = 27 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_DEC = 28 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_FCMPSWAP = 29 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_FMIN = 30 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_ATOMIC_FMAX = 31 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE = 32 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_CL = 33 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_D = 34 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_D_CL = 35 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_L = 36 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_B = 37 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_B_CL = 38 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_LZ = 39 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C = 40 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_CL = 41 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_D = 42 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_D_CL = 43 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_L = 44 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_B = 45 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_B_CL = 46 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_LZ = 47 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_O = 48 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_CL_O = 49 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_D_O = 50 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_D_CL_O = 51 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_L_O = 52 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_B_O = 53 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_B_CL_O = 54 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_LZ_O = 55 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_O = 56 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_CL_O = 57 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_D_O = 58 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_D_CL_O = 59 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_L_O = 60 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_B_O = 61 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_B_CL_O = 62 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_LZ_O = 63 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4 = 64 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_CL = 65 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_L = 68 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_B = 69 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_B_CL = 70 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_LZ = 71 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C = 72 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_CL = 73 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_L = 76 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_B = 77 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_B_CL = 78 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_LZ = 79 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_O = 80 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_CL_O = 81 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_L_O = 84 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_B_O = 85 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_B_CL_O = 86 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_LZ_O = 87 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_O = 88 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_CL_O = 89 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_L_O = 92 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_B_O = 93 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_B_CL_O = 94 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GATHER4_C_LZ_O = 95 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_GET_LOD = 96 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_CD = 104 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_CD_CL = 105 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_CD = 106 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_CD_CL = 107 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_CD_O = 108 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_CD_CL_O = 109 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_CD_O = 110 + (u32)OpcodeMap::OP_MAP_MIMG, + IMAGE_SAMPLE_C_CD_CL_O = 111 + (u32)OpcodeMap::OP_MAP_MIMG, + // EXP + EXP = 0 + (u32)OpcodeMap::OP_MAP_EXP, + // VOP3P + V_PK_MAD_I16 = 0 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MUL_LO_U16 = 1 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_ADD_I16 = 2 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_SUB_I16 = 3 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_LSHLREV_B16 = 4 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_LSHRREV_B16 = 5 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_ASHRREV_I16 = 6 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MAX_I16 = 7 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MIN_I16 = 8 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MAD_U16 = 9 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_ADD_U16 = 10 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_SUB_U16 = 11 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MAX_U16 = 12 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MIN_U16 = 13 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_FMA_F16 = 14 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_ADD_F16 = 15 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MUL_F16 = 16 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MIN_F16 = 17 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_PK_MAX_F16 = 18 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_MAD_MIX_F32 = 32 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_MAD_MIXLO_F16 = 33 + (u32)OpcodeMap::OP_MAP_VOP3P, + V_MAD_MIXHI_F16 = 34 + (u32)OpcodeMap::OP_MAP_VOP3P, +}; + +enum class EncodingMask : u32 { + MASK_9bit = 0x000001FFULL << 23, + MASK_7bit = 0x0000007FULL << 25, + MASK_6bit = 0x0000003FULL << 26, + MASK_5bit = 0x0000001FULL << 27, + MASK_4bit = 0x0000000FULL << 28, + MASK_2bit = 0x00000003ULL << 30, + MASK_1bit = 0x00000001ULL << 31 +}; + +enum class InstEncoding : u32 { + /// InstructionEncodingMask_9bit + /// bits [31:23] - (1 0 1 1 1 1 1 0 1) + SOP1 = 0x0000017Du << 23, + /// bits [31:23] - (1 0 1 1 1 1 1 1 1) + SOPP = 0x0000017Fu << 23, + /// bits [31:23] - (1 0 1 1 1 1 1 1 0) + SOPC = 0x0000017Eu << 23, + /// InstructionEncodingMask_7bit + /// bits [31:25] - (0 1 1 1 1 1 1) + VOP1 = 0x0000003Fu << 25, + /// bits [31:25] - (0 1 1 1 1 1 0) + VOPC = 0x0000003Eu << 25, + /// InstructionEncodingMask_6bit + /// bits [31:26] - (1 1 0 1 0 0) + VOP3 = 0x00000034u << 26, + /// bits [31:26] - (1 1 1 1 1 0) + EXP = 0x0000003Eu << 26, + /// bits [31:26] - (1 1 0 0 1 1) + VOP3P = 0x00000033u << 26, + /// bits [31:26] - (1 1 0 0 1 0) + VINTRP = 0x00000032u << 26, + /// bits [31:26] - (1 1 0 1 1 0) + DS = 0x00000036u << 26, + /// bits [31:26] - (1 1 1 0 0 0) + MUBUF = 0x00000038u << 26, + /// bits [31:26] - (1 1 1 0 1 0) + MTBUF = 0x0000003Au << 26, + /// bits [31:26] - (1 1 1 1 0 0) + MIMG = 0x0000003Cu << 26, + /// InstructionEncodingMask_5bit + /// bits [31:27] - (1 1 0 0 0) + SMRD = 0x00000018u << 27, + /// InstructionEncodingMask_4bit + /// bits [31:28] - (1 0 1 1) + SOPK = 0x0000000Bu << 28, + /// InstructionEncodingMask_2bit + /// bits [31:30] - (1 0) + SOP2 = 0x00000002u << 30, + /// InstructionEncodingMask_1bit + /// bits [31:31] - (0) + VOP2 = 0x00000000u << 31, + + ILLEGAL +}; + +enum class InstClass : u32 { + Undefined, + + ScalarArith, + ScalarAbs, + ScalarMov, + ScalarMovRel, + ScalarCmp, + ScalarSelect, + ScalarBitLogic, + ScalarBitManip, + ScalarBitField, + ScalarConv, + ScalarExecMask, + ScalarQuadMask, + + VectorRegMov, + VectorMovRel, + VectorLane, + VectorBitLogic, + VectorBitField32, + VectorThreadMask, + VectorBitField64, + VectorFpArith16, + VectorFpArith32, + VectorFpRound32, + VectorFpField32, + VectorFpTran16, + VectorFpTran32, + VectorFpCmp16, + VectorFpCmp32, + VectorFpArith64, + VectorFpRound64, + VectorFpField64, + VectorFpTran64, + VectorFpCmp64, + VectorIntArith16, + VectorIntArith32, + VectorIntArith64, + VectorIntCmp16, + VectorIntCmp32, + VectorIntCmp64, + VectorConv, + VectorFpGraph32, + VectorIntGraph, + VectorMisc, + + ScalarProgFlow, + ScalarSync, + ScalarWait, + ScalarCache, + ScalarPrior, + ScalarRegAccess, + ScalarMsg, + + ScalarMemRd, + ScalarMemUt, + + VectorMemBufNoFmt, + VectorMemBufFmt, + VectorMemBufAtomic, + VectorMemImgNoSmp, + VectorMemImgSmp, + VectorMemImgUt, + VectorMemL1Cache, + + DsIdxRd, + DsIdxWr, + DsIdxWrXchg, + DsIdxCondXchg, + DsIdxWrap, + DsAtomicArith32, + DsAtomicArith64, + DsAtomicMinMax32, + DsAtomicMinMax64, + DsAtomicCmpSt32, + DsAtomicCmpSt64, + DsAtomicLogic32, + DsAtomicLogic64, + DsAppendCon, + DsDataShareUt, + DsDataShareMisc, + GdsSync, + GdsOrdCnt, + + VectorInterpFpCache, + + Exp, + + DbgProf +}; + +enum class InstCategory : u32 { + Undefined, + /// Scalar ALU Operation + ScalarALU, + /// Scalar Instruction Memory + ScalarMemory, + /// Vector ALU Operation + VectorALU, + /// Vector Instruction Memory Read + VectorMemory, + /// Scalar Program Flow Control and Special Operations + FlowControl, + /// LDS and GDS + DataShare, + /// Vector Interpolation Operations + VectorInterpolation, + /// Export + Export, + /// Debug and Profiling Operations + DebugProfile, +}; + +enum class ScalarType : u32 { + Undefined, + Any, + Uint16, + Uint32, + Uint64, + Sint16, + Sint32, + Sint64, + Float16, + Float32, + Float64, + Bool, +}; + +/// Instruction's action when GPU thread is not active. +enum class DivergentAction : u32 { Nop, ZeroScalar, Execute }; + +enum class OperandField : u32 { + ScalarGPR = 0, + VccLo = 106, + VccHi, + M0 = 124, + ExecLo = 126, + ExecHi, + ConstZero, + SignedConstIntPos = 129, + SignedConstIntNeg = 193, + ConstFloatPos_0_5 = 240, + ConstFloatNeg_0_5, + ConstFloatPos_1_0, + ConstFloatNeg_1_0, + ConstFloatPos_2_0, + ConstFloatNeg_2_0, + ConstFloatPos_4_0, + ConstFloatNeg_4_0, + Inv2Pi, + Sdwa, + Dpp, + VccZ = 251, + ExecZ = 252, + Scc = 253, + LdsDirect = 254, + LiteralConst = 255, + VectorGPR, + + Undefined = 0xFFFFFFFF, +}; + +enum class SystemValue : u32 { + None = 0, + Position = 1, + ClipDistance = 2, + CullDistance = 3, + RenderTargetId = 4, + ViewportId = 5, + VertexId = 6, + PrimitiveId = 7, + InstanceId = 8, + IsFrontFace = 9, + SampleIndex = 10, + FinalQuadUeq0EdgeTessFactor = 11, + FinalQuadVeq0EdgeTessFactor = 12, + FinalQuadUeq1EdgeTessFactor = 13, + FinalQuadVeq1EdgeTessFactor = 14, + FinalQuadUInsideTessFactor = 15, + FinalQuadVInsideTessFactor = 16, + FinalTriUeq0EdgeTessFactor = 17, + FinalTriVeq0EdgeTessFactor = 18, + FinalTriWeq0EdgeTessFactor = 19, + FinalTriInsideTessFactor = 20, + FinalLineDetailTessFactor = 21, + FinalLineDensityTessFactor = 22, + GlobalInvocationId = 23, + WorkgroupId = 24, + LocalInvocationId = 25, + LocalInvocationIndex = 26, + Target = 64, + Depth = 65, + Coverage = 66, + DepthGe = 67, + DepthLe = 68, + NumSubgroups = 70, + SubgroupID = 71, + SubgroupSize = 72, + SubgroupInvocationID = 73, + SubgroupEqMask = 74, + SubgroupGeMask = 75, + SubgroupGtMask = 76, + SubgroupLeMask = 77, + SubgroupLtMask = 78, +}; + +enum class InterpolationMode : u32 { + Undefined = 0, + Constant = 1, + Linear = 2, + LinearCentroid = 3, + LinearNoPerspective = 4, + LinearNoPerspectiveCentroid = 5, + LinearSample = 6, + LinearNoPerspectiveSample = 7, +}; + +enum class MimgModifier : u32 { + Lod, /// LOD is used instead of TA computed LOD. + LodBias, /// Add this BIAS to the LOD TA computes. + LodClamp, /// Clamp the LOD to be no larger than this value. + Derivative, /// Send dx/dv, dx/dy, etc. slopes to TA for it to used in LOD computation. + CoarseDerivative, /// Send dx/dv, dx/dy, etc. slopes to TA for it to used in LOD computation. + Level0, /// Force use of MIP level 0. + Pcf, /// Percentage closer filtering. + Offset /// Send X, Y, Z integer offsets (packed into 1 Dword) to offset XYZ address. +}; +using MimgModifierFlags = Common::Flags; + +enum class ImageResComponent : u32 { Width, Height, Depth, MipCount }; +using ImageResFlags = Common::Flags; + +enum class ImageAddrComponent : u32 { + Offsets, + Bias, + Zpcf, + DxDh, + DyDh, + DzDh, + DxDv, + DyDv, + DzDv, + X, + Y, + Z, + Slice, + FaceId, + FragId, + Lod, + Clamp, +}; + +struct SendMsgSimm { + enum class Message : u32 { + Interrupt = 1, + Gs = 2, + GsDone = 3, + System = 15, + }; + + enum class GsOp : u32 { + Nop = 0, + Cut = 1, + Emit = 2, + EmitCut = 3, + }; + + Message msg : 4; + GsOp op : 2; +}; + +} // namespace Shader::Gcn + +template <> +struct magic_enum::customize::enum_range { + static constexpr int min = static_cast(Shader::Gcn::Opcode::S_ADD_U32); + static constexpr int max = static_cast(Shader::Gcn::Opcode::V_MAD_MIXHI_F16); +}; diff --git a/gpu/shadps4/shader_recompiler/frontend/structured_control_flow.cpp b/gpu/shadps4/shader_recompiler/frontend/structured_control_flow.cpp new file mode 100644 index 0000000..057be14 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/structured_control_flow.cpp @@ -0,0 +1,812 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "shader_recompiler/frontend/structured_control_flow.h" +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/recompiler.h" + +namespace Shader::Gcn { + +namespace { + +struct Statement; + +// Use normal_link because we are not guaranteed to destroy the tree in order +using ListBaseHook = + boost::intrusive::list_base_hook>; + +using Tree = boost::intrusive::list, + // Avoid linear complexity on splice, size is never called + boost::intrusive::constant_time_size>; +using Node = Tree::iterator; + +enum class StatementType { + Code, + Goto, + Label, + If, + Loop, + Break, + Return, + Unreachable, + Function, + Identity, + Not, + Or, + SetVariable, + Variable, +}; + +bool HasChildren(StatementType type) { + switch (type) { + case StatementType::If: + case StatementType::Loop: + case StatementType::Function: + return true; + default: + return false; + } +} + +struct Goto {}; +struct Label {}; +struct If {}; +struct Loop {}; +struct Break {}; +struct Return {}; +struct Kill {}; +struct Unreachable {}; +struct FunctionTag {}; +struct Identity {}; +struct Not {}; +struct Or {}; +struct SetVariable {}; +struct Variable {}; + +struct Statement : ListBaseHook { + Statement(const Block* block_, Statement* up_) + : block{block_}, up{up_}, type{StatementType::Code} {} + Statement(Goto, Statement* cond_, Node label_, Statement* up_) + : label{label_}, cond{cond_}, up{up_}, type{StatementType::Goto} {} + Statement(Label, u32 id_, Statement* up_) : id{id_}, up{up_}, type{StatementType::Label} {} + Statement(If, Statement* cond_, Tree&& children_, Statement* up_) + : children{std::move(children_)}, cond{cond_}, up{up_}, type{StatementType::If} {} + Statement(Loop, Statement* cond_, Tree&& children_, Statement* up_) + : children{std::move(children_)}, cond{cond_}, up{up_}, type{StatementType::Loop} {} + Statement(Break, Statement* cond_, Statement* up_) + : cond{cond_}, up{up_}, type{StatementType::Break} {} + Statement(Return, Statement* up_) : up{up_}, type{StatementType::Return} {} + Statement(Unreachable, Statement* up_) : up{up_}, type{StatementType::Unreachable} {} + Statement(FunctionTag) : children{}, type{StatementType::Function} {} + Statement(Identity, IR::Value cond_ref_, IR::Condition guest_cond_, Statement* up_) + : cond_ref{cond_ref_}, guest_cond{guest_cond_}, up{up_}, type{StatementType::Identity} {} + Statement(Not, Statement* op_, Statement* up_) : op{op_}, up{up_}, type{StatementType::Not} {} + Statement(Or, Statement* op_a_, Statement* op_b_, Statement* up_) + : op_a{op_a_}, op_b{op_b_}, up{up_}, type{StatementType::Or} {} + Statement(SetVariable, u32 id_, Statement* op_, Statement* up_) + : op{op_}, id{id_}, up{up_}, type{StatementType::SetVariable} {} + Statement(Variable, u32 id_, Statement* up_) + : id{id_}, up{up_}, type{StatementType::Variable} {} + + ~Statement() { + if (HasChildren(type)) { + std::destroy_at(&children); + } + } + + union { + const Block* block; + Node label; + Tree children; + IR::U1 cond_ref; + Statement* op; + Statement* op_a; + u32 location; + s32 branch_offset; + }; + union { + Statement* cond; + Statement* op_b; + u32 id; + IR::Condition guest_cond; + }; + Statement* up{}; + StatementType type; +}; + +std::string DumpExpr(const Statement* stmt) { + switch (stmt->type) { + case StatementType::Identity: + return fmt::format("{}", stmt->guest_cond); + case StatementType::Not: + return fmt::format("!{}", DumpExpr(stmt->op)); + case StatementType::Or: + return fmt::format("{} || {}", DumpExpr(stmt->op_a), DumpExpr(stmt->op_b)); + case StatementType::Variable: + return fmt::format("goto_L{}", stmt->id); + default: + return ""; + } +} + +[[maybe_unused]] std::string DumpTree(const Tree& tree, u32 indentation = 0) { + std::string ret; + std::string indent(indentation, ' '); + for (const auto& stmt : tree) { + switch (stmt.type) { + case StatementType::Code: + ret += fmt::format("{} Block {:04x} -> {:04x} (0x{:016x});\n", indent, + stmt.block->begin, stmt.block->end, + reinterpret_cast(stmt.block)); + break; + case StatementType::Goto: + ret += fmt::format("{} if ({}) goto L{};\n", indent, DumpExpr(stmt.cond), + stmt.label->id); + break; + case StatementType::Label: + ret += fmt::format("{}L{}:\n", indent, stmt.id); + break; + case StatementType::If: + ret += fmt::format("{} if ({}) {{\n", indent, DumpExpr(stmt.cond)); + ret += DumpTree(stmt.children, indentation + 4); + ret += fmt::format("{} }}\n", indent); + break; + case StatementType::Loop: + ret += fmt::format("{} do {{\n", indent); + ret += DumpTree(stmt.children, indentation + 4); + ret += fmt::format("{} }} while ({});\n", indent, DumpExpr(stmt.cond)); + break; + case StatementType::Break: + ret += fmt::format("{} if ({}) break;\n", indent, DumpExpr(stmt.cond)); + break; + case StatementType::Return: + ret += fmt::format("{} return;\n", indent); + break; + case StatementType::Unreachable: + ret += fmt::format("{} unreachable;\n", indent); + break; + case StatementType::SetVariable: + ret += fmt::format("{} goto_L{} = {};\n", indent, stmt.id, DumpExpr(stmt.op)); + break; + case StatementType::Function: + case StatementType::Identity: + case StatementType::Not: + case StatementType::Or: + case StatementType::Variable: + UNREACHABLE_MSG("Statement can't be printed"); + } + } + return ret; +} + +void SanitizeNoBreaks(const Tree& tree) { + if (std::ranges::find(tree, StatementType::Break, &Statement::type) != tree.end()) { + UNREACHABLE_MSG("Capturing statement with break nodes"); + } +} + +size_t Level(Node stmt) { + size_t level{0}; + Statement* node{stmt->up}; + while (node) { + ++level; + node = node->up; + } + return level; +} + +bool IsDirectlyRelated(Node goto_stmt, Node label_stmt) { + const size_t goto_level{Level(goto_stmt)}; + const size_t label_level{Level(label_stmt)}; + size_t min_level; + size_t max_level; + Node min; + Node max; + if (label_level < goto_level) { + min_level = label_level; + max_level = goto_level; + min = label_stmt; + max = goto_stmt; + } else { // goto_level < label_level + min_level = goto_level; + max_level = label_level; + min = goto_stmt; + max = label_stmt; + } + while (max_level > min_level) { + --max_level; + max = max->up; + } + return min->up == max->up; +} + +bool IsIndirectlyRelated(Node goto_stmt, Node label_stmt) { + return goto_stmt->up != label_stmt->up && !IsDirectlyRelated(goto_stmt, label_stmt); +} + +[[maybe_unused]] bool AreSiblings(Node goto_stmt, Node label_stmt) noexcept { + Node it{goto_stmt}; + do { + if (it == label_stmt) { + return true; + } + --it; + } while (it != goto_stmt->up->children.begin()); + while (it != goto_stmt->up->children.end()) { + if (it == label_stmt) { + return true; + } + ++it; + } + return false; +} + +Node SiblingFromNephew(Node uncle, Node nephew) noexcept { + Statement* const parent{uncle->up}; + Statement* it{&*nephew}; + while (it->up != parent) { + it = it->up; + } + return Tree::s_iterator_to(*it); +} + +bool AreOrdered(Node left_sibling, Node right_sibling) noexcept { + const Node end{right_sibling->up->children.end()}; + for (auto it = right_sibling; it != end; ++it) { + if (it == left_sibling) { + return false; + } + } + return true; +} + +bool NeedsLift(Node goto_stmt, Node label_stmt) noexcept { + const Node sibling{SiblingFromNephew(goto_stmt, label_stmt)}; + return AreOrdered(sibling, goto_stmt); +} + +/** + * The algorithm used here is from: + * Taming Control Flow: A Structured Approach to Eliminating Goto Statements. + * Ana M. Erosa and Laurie J. Hendren + * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.42.1485&rep=rep1&type=pdf + */ +class GotoPass { +public: + explicit GotoPass(CFG& cfg, Common::ObjectPool& stmt_pool) : pool{stmt_pool} { + std::vector gotos{BuildTree(cfg)}; + const auto end{gotos.rend()}; + for (auto goto_stmt = gotos.rbegin(); goto_stmt != end; ++goto_stmt) { + RemoveGoto(*goto_stmt); + } + } + + Statement& RootStatement() noexcept { + return root_stmt; + } + +private: + void RemoveGoto(Node goto_stmt) { + // Force goto_stmt and label_stmt to be directly related + const Node label_stmt{goto_stmt->label}; + if (IsIndirectlyRelated(goto_stmt, label_stmt)) { + // Move goto_stmt out using outward-movement transformation until it becomes + // directly related to label_stmt + while (!IsDirectlyRelated(goto_stmt, label_stmt)) { + goto_stmt = MoveOutward(goto_stmt); + } + } + // Force goto_stmt and label_stmt to be siblings + if (IsDirectlyRelated(goto_stmt, label_stmt)) { + const size_t label_level{Level(label_stmt)}; + size_t goto_level{Level(goto_stmt)}; + if (goto_level > label_level) { + // Move goto_stmt out of its level using outward-movement transformations + while (goto_level > label_level) { + goto_stmt = MoveOutward(goto_stmt); + --goto_level; + } + } else { // Level(goto_stmt) < Level(label_stmt) + if (NeedsLift(goto_stmt, label_stmt)) { + // Lift goto_stmt to above stmt containing label_stmt using goto-lifting + // transformations + goto_stmt = Lift(goto_stmt); + } + // Move goto_stmt into label_stmt's level using inward-movement transformation + while (goto_level < label_level) { + goto_stmt = MoveInward(goto_stmt); + ++goto_level; + } + } + } + // Expensive operation: + // if (!AreSiblings(goto_stmt, label_stmt)) { + // UNREACHABLE_MSG("Goto is not a sibling with the label"); + //} + // goto_stmt and label_stmt are guaranteed to be siblings, eliminate + if (std::next(goto_stmt) == label_stmt) { + // Simply eliminate the goto if the label is next to it + goto_stmt->up->children.erase(goto_stmt); + } else if (AreOrdered(goto_stmt, label_stmt)) { + // Eliminate goto_stmt with a conditional + EliminateAsConditional(goto_stmt, label_stmt); + } else { + // Eliminate goto_stmt with a loop + EliminateAsLoop(goto_stmt, label_stmt); + } + } + + std::vector BuildTree(CFG& cfg) { + u32 label_id{0}; + std::vector gotos; + BuildTree(cfg, label_id, gotos, root_stmt.children.end(), std::nullopt); + return gotos; + } + + void BuildTree(CFG& cfg, u32& label_id, std::vector& gotos, Node function_insert_point, + std::optional return_label) { + Statement* const false_stmt{ + pool.Create(Identity{}, IR::Value{false}, IR::Condition::False, &root_stmt)}; + Tree& root{root_stmt.children}; + std::unordered_map local_labels; + local_labels.reserve(cfg.blocks.size()); + + for (Block& block : cfg.blocks) { + Statement* const label{pool.Create(Label{}, label_id, &root_stmt)}; + const Node label_it{root.insert(function_insert_point, *label)}; + local_labels.emplace(&block, label_it); + ++label_id; + } + for (Block& block : cfg.blocks) { + const Node label{local_labels.at(&block)}; + // Insertion point + const Node ip{std::next(label)}; + + // Reset goto variables before the first block and after its respective label + const auto make_reset_variable{[&]() -> Statement& { + return *pool.Create(SetVariable{}, label->id, false_stmt, &root_stmt); + }}; + root.push_front(make_reset_variable()); + root.insert(ip, make_reset_variable()); + root.insert(ip, *pool.Create(&block, &root_stmt)); + + switch (block.end_class) { + case EndClass::Branch: { + Statement* const always_cond{ + pool.Create(Identity{}, IR::Value{true}, IR::Condition::True, &root_stmt)}; + if (block.cond == IR::Condition::True) { + const Node true_label{local_labels.at(block.branch_true)}; + gotos.push_back( + root.insert(ip, *pool.Create(Goto{}, always_cond, true_label, &root_stmt))); + } else if (block.cond == IR::Condition::False) { + const Node false_label{local_labels.at(block.branch_false)}; + gotos.push_back(root.insert( + ip, *pool.Create(Goto{}, always_cond, false_label, &root_stmt))); + } else { + const IR::Value value = block.ir_block->branch_cond; + ASSERT(!value.IsEmpty()); + IR::Inst* cond_ref = value.Inst(); + const Node true_label{local_labels.at(block.branch_true)}; + const Node false_label{local_labels.at(block.branch_false)}; + Statement* const true_cond{ + pool.Create(Identity{}, cond_ref->Arg(0), block.cond, &root_stmt)}; + cond_ref->Invalidate(); + gotos.push_back( + root.insert(ip, *pool.Create(Goto{}, true_cond, true_label, &root_stmt))); + gotos.push_back(root.insert( + ip, *pool.Create(Goto{}, always_cond, false_label, &root_stmt))); + } + break; + } + case EndClass::Exit: + root.insert(ip, *pool.Create(Return{}, &root_stmt)); + break; + } + } + } + + void UpdateTreeUp(Statement* tree) { + for (Statement& stmt : tree->children) { + stmt.up = tree; + } + } + + void EliminateAsConditional(Node goto_stmt, Node label_stmt) { + Tree& body{goto_stmt->up->children}; + Tree if_body; + if_body.splice(if_body.begin(), body, std::next(goto_stmt), label_stmt); + Statement* const cond{pool.Create(Not{}, goto_stmt->cond, &root_stmt)}; + Statement* const if_stmt{pool.Create(If{}, cond, std::move(if_body), goto_stmt->up)}; + UpdateTreeUp(if_stmt); + body.insert(goto_stmt, *if_stmt); + body.erase(goto_stmt); + } + + void EliminateAsLoop(Node goto_stmt, Node label_stmt) { + Tree& body{goto_stmt->up->children}; + Tree loop_body; + loop_body.splice(loop_body.begin(), body, label_stmt, goto_stmt); + Statement* const cond{goto_stmt->cond}; + Statement* const loop{pool.Create(Loop{}, cond, std::move(loop_body), goto_stmt->up)}; + UpdateTreeUp(loop); + body.insert(goto_stmt, *loop); + body.erase(goto_stmt); + } + + [[nodiscard]] Node MoveOutward(Node goto_stmt) { + switch (goto_stmt->up->type) { + case StatementType::If: + return MoveOutwardIf(goto_stmt); + case StatementType::Loop: + return MoveOutwardLoop(goto_stmt); + default: + UNREACHABLE_MSG("Invalid outward movement"); + } + } + + [[nodiscard]] Node MoveInward(Node goto_stmt) { + Statement* const parent{goto_stmt->up}; + Tree& body{parent->children}; + const Node label{goto_stmt->label}; + const Node label_nested_stmt{SiblingFromNephew(goto_stmt, label)}; + const u32 label_id{label->id}; + + Statement* const goto_cond{goto_stmt->cond}; + Statement* const set_var{pool.Create(SetVariable{}, label_id, goto_cond, parent)}; + body.insert(goto_stmt, *set_var); + + Tree if_body; + if_body.splice(if_body.begin(), body, std::next(goto_stmt), label_nested_stmt); + Statement* const variable{pool.Create(Variable{}, label_id, &root_stmt)}; + Statement* const neg_var{pool.Create(Not{}, variable, &root_stmt)}; + if (!if_body.empty()) { + Statement* const if_stmt{pool.Create(If{}, neg_var, std::move(if_body), parent)}; + UpdateTreeUp(if_stmt); + body.insert(goto_stmt, *if_stmt); + } + body.erase(goto_stmt); + + switch (label_nested_stmt->type) { + case StatementType::If: + // Update nested if condition + label_nested_stmt->cond = + pool.Create(Or{}, variable, label_nested_stmt->cond, &root_stmt); + break; + case StatementType::Loop: + break; + default: + UNREACHABLE_MSG("Invalid inward movement"); + } + Tree& nested_tree{label_nested_stmt->children}; + Statement* const new_goto{pool.Create(Goto{}, variable, label, &*label_nested_stmt)}; + return nested_tree.insert(nested_tree.begin(), *new_goto); + } + + [[nodiscard]] Node Lift(Node goto_stmt) { + Statement* const parent{goto_stmt->up}; + Tree& body{parent->children}; + const Node label{goto_stmt->label}; + const u32 label_id{label->id}; + const Node label_nested_stmt{SiblingFromNephew(goto_stmt, label)}; + + Tree loop_body; + loop_body.splice(loop_body.begin(), body, label_nested_stmt, goto_stmt); + SanitizeNoBreaks(loop_body); + Statement* const variable{pool.Create(Variable{}, label_id, &root_stmt)}; + Statement* const loop_stmt{pool.Create(Loop{}, variable, std::move(loop_body), parent)}; + UpdateTreeUp(loop_stmt); + body.insert(goto_stmt, *loop_stmt); + + Statement* const new_goto{pool.Create(Goto{}, variable, label, loop_stmt)}; + loop_stmt->children.push_front(*new_goto); + const Node new_goto_node{loop_stmt->children.begin()}; + + Statement* const set_var{pool.Create(SetVariable{}, label_id, goto_stmt->cond, loop_stmt)}; + loop_stmt->children.push_back(*set_var); + + body.erase(goto_stmt); + return new_goto_node; + } + + Node MoveOutwardIf(Node goto_stmt) { + const Node parent{Tree::s_iterator_to(*goto_stmt->up)}; + Tree& body{parent->children}; + const u32 label_id{goto_stmt->label->id}; + Statement* const goto_cond{goto_stmt->cond}; + Statement* const set_goto_var{pool.Create(SetVariable{}, label_id, goto_cond, &*parent)}; + body.insert(goto_stmt, *set_goto_var); + + Tree if_body; + if_body.splice(if_body.begin(), body, std::next(goto_stmt), body.end()); + if_body.pop_front(); + Statement* const cond{pool.Create(Variable{}, label_id, &root_stmt)}; + Statement* const neg_cond{pool.Create(Not{}, cond, &root_stmt)}; + Statement* const if_stmt{pool.Create(If{}, neg_cond, std::move(if_body), &*parent)}; + UpdateTreeUp(if_stmt); + body.insert(goto_stmt, *if_stmt); + + body.erase(goto_stmt); + + Statement* const new_cond{pool.Create(Variable{}, label_id, &root_stmt)}; + Statement* const new_goto{pool.Create(Goto{}, new_cond, goto_stmt->label, parent->up)}; + Tree& parent_tree{parent->up->children}; + return parent_tree.insert(std::next(parent), *new_goto); + } + + Node MoveOutwardLoop(Node goto_stmt) { + Statement* const parent{goto_stmt->up}; + Tree& body{parent->children}; + const u32 label_id{goto_stmt->label->id}; + Statement* const goto_cond{goto_stmt->cond}; + Statement* const set_goto_var{pool.Create(SetVariable{}, label_id, goto_cond, parent)}; + Statement* const cond{pool.Create(Variable{}, label_id, &root_stmt)}; + Statement* const break_stmt{pool.Create(Break{}, cond, parent)}; + body.insert(goto_stmt, *set_goto_var); + body.insert(goto_stmt, *break_stmt); + body.erase(goto_stmt); + + const Node loop{Tree::s_iterator_to(*goto_stmt->up)}; + Statement* const new_goto_cond{pool.Create(Variable{}, label_id, &root_stmt)}; + Statement* const new_goto{pool.Create(Goto{}, new_goto_cond, goto_stmt->label, loop->up)}; + Tree& parent_tree{loop->up->children}; + return parent_tree.insert(std::next(loop), *new_goto); + } + + Common::ObjectPool& pool; + Statement root_stmt{FunctionTag{}}; +}; + +[[nodiscard]] Statement* TryFindForwardBlock(Node forward_node, Node end) { + while (forward_node != end && !HasChildren(forward_node->type)) { + if (forward_node->type == StatementType::Code) { + return &*forward_node; + } + ++forward_node; + } + return nullptr; +} + +[[nodiscard]] IR::U1 VisitExpr(IR::IREmitter& ir, const Statement& stmt) { + switch (stmt.type) { + case StatementType::Identity: + return stmt.cond_ref; + case StatementType::Not: + return ir.LogicalNot(VisitExpr(ir, *stmt.op)); + case StatementType::Or: + return ir.LogicalOr(VisitExpr(ir, *stmt.op_a), VisitExpr(ir, *stmt.op_b)); + case StatementType::Variable: + return ir.GetGotoVariable(stmt.id); + default: + UNREACHABLE_MSG("Statement type {}", u32(stmt.type)); + } +} + +class TranslatePass { +public: + TranslatePass(Common::ObjectPool& inst_pool_, + Common::ObjectPool& block_pool_, + Common::ObjectPool& stmt_pool_, Statement& root_stmt, + IR::AbstractSyntaxList& syntax_list_) + : stmt_pool{stmt_pool_}, inst_pool{inst_pool_}, block_pool{block_pool_}, + syntax_list{syntax_list_} { + Visit(root_stmt, nullptr, nullptr); + } + +private: + void Visit(Statement& parent, IR::Block* break_block, IR::Block* fallthrough_block) { + IR::Block* current_block{}; + IR::Block::iterator insert_point{}; + Tree& tree{parent.children}; + // Try to find the first code block for insertion + Statement* code_stmt{TryFindForwardBlock(tree.begin(), tree.end())}; + if (!code_stmt) { + current_block = block_pool.Create(inst_pool); + insert_point = current_block->end(); + auto& node{syntax_list.emplace_back()}; + node.type = IR::AbstractSyntaxNode::Type::Block; + node.data.block = current_block; + } else { + current_block = code_stmt->block->ir_block; + insert_point = current_block->begin(); + } + for (auto& child : tree) { + Statement& stmt{child}; + switch (stmt.type) { + case StatementType::Label: + // Labels can be ignored + break; + case StatementType::Code: { + current_block = stmt.block->ir_block; + insert_point = current_block->end(); + for (auto& node : syntax_list) { + if (node.type == IR::AbstractSyntaxNode::Type::Block) { + ASSERT(node.data.block != current_block); + } + } + auto& node{syntax_list.emplace_back()}; + node.type = IR::AbstractSyntaxNode::Type::Block; + node.data.block = current_block; + break; + } + case StatementType::SetVariable: { + IR::IREmitter ir{*current_block, insert_point}; + ir.SetGotoVariable(stmt.id, VisitExpr(ir, *stmt.op)); + break; + } + case StatementType::If: { + IR::Block* const merge_block{MergeBlock(parent, stmt)}; + + // Implement if header block + IR::IREmitter ir{*current_block, insert_point}; + const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; + + const size_t if_node_index{syntax_list.size()}; + syntax_list.emplace_back(); + + // Visit children + const size_t then_block_index{syntax_list.size()}; + Visit(stmt, break_block, merge_block); + + IR::Block* const then_block{syntax_list.at(then_block_index).data.block}; + current_block->AddBranch(then_block); + current_block->AddBranch(merge_block); + current_block = merge_block; + insert_point = current_block->begin(); + + auto& if_node{syntax_list[if_node_index]}; + if_node.type = IR::AbstractSyntaxNode::Type::If; + if_node.data.if_node.cond = cond; + if_node.data.if_node.body = then_block; + if_node.data.if_node.merge = merge_block; + + auto& endif_node{syntax_list.emplace_back()}; + endif_node.type = IR::AbstractSyntaxNode::Type::EndIf; + endif_node.data.end_if.merge = merge_block; + break; + } + case StatementType::Loop: { + IR::Block* const loop_header_block{block_pool.Create(inst_pool)}; + if (current_block) { + current_block->AddBranch(loop_header_block); + } + auto& header_node{syntax_list.emplace_back()}; + header_node.type = IR::AbstractSyntaxNode::Type::Block; + header_node.data.block = loop_header_block; + + IR::Block* const continue_block{block_pool.Create(inst_pool)}; + IR::Block* const merge_block{MergeBlock(parent, stmt)}; + + const size_t loop_node_index{syntax_list.size()}; + syntax_list.emplace_back(); + + // Visit children + const size_t body_block_index{syntax_list.size()}; + Visit(stmt, merge_block, continue_block); + + // The continue block is located at the end of the loop + IR::IREmitter ir{*continue_block}; + const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; + + IR::Block* const body_block{syntax_list.at(body_block_index).data.block}; + loop_header_block->AddBranch(body_block); + + continue_block->AddBranch(loop_header_block); + continue_block->AddBranch(merge_block); + + current_block = merge_block; + insert_point = current_block->begin(); + + auto& loop{syntax_list[loop_node_index]}; + loop.type = IR::AbstractSyntaxNode::Type::Loop; + loop.data.loop.body = body_block; + loop.data.loop.continue_block = continue_block; + loop.data.loop.merge = merge_block; + + auto& continue_block_node{syntax_list.emplace_back()}; + continue_block_node.type = IR::AbstractSyntaxNode::Type::Block; + continue_block_node.data.block = continue_block; + + auto& repeat{syntax_list.emplace_back()}; + repeat.type = IR::AbstractSyntaxNode::Type::Repeat; + repeat.data.repeat.cond = cond; + repeat.data.repeat.loop_header = loop_header_block; + repeat.data.repeat.merge = merge_block; + break; + } + case StatementType::Break: { + IR::Block* const skip_block{MergeBlock(parent, stmt)}; + + IR::IREmitter ir{*current_block, insert_point}; + const IR::U1 cond{ir.ConditionRef(VisitExpr(ir, *stmt.cond))}; + current_block->AddBranch(break_block); + current_block->AddBranch(skip_block); + current_block = skip_block; + insert_point = current_block->end(); + + auto& break_node{syntax_list.emplace_back()}; + break_node.type = IR::AbstractSyntaxNode::Type::Break; + break_node.data.break_node.cond = cond; + break_node.data.break_node.merge = break_block; + break_node.data.break_node.skip = skip_block; + break; + } + case StatementType::Return: { + IR::Block* return_block{block_pool.Create(inst_pool)}; + IR::IREmitter{*return_block}.Epilogue(); + current_block->AddBranch(return_block); + + auto& merge{syntax_list.emplace_back()}; + merge.type = IR::AbstractSyntaxNode::Type::Block; + merge.data.block = return_block; + + current_block = nullptr; + insert_point = {}; + syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Return; + break; + } + case StatementType::Unreachable: { + current_block = nullptr; + insert_point = {}; + syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Unreachable; + break; + } + default: + UNREACHABLE_MSG("Statement type {}", u32(stmt.type)); + } + } + if (current_block) { + if (fallthrough_block) { + current_block->AddBranch(fallthrough_block); + } else { + syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Unreachable; + } + } + } + + IR::Block* MergeBlock(Statement& parent, Statement& stmt) const { + Tree& tree{stmt.up->children}; + const Node end{tree.end()}; + Node forward_node{std::next(Tree::s_iterator_to(stmt))}; + Statement* merge_stmt{TryFindForwardBlock(forward_node, end)}; + if (!merge_stmt) { + // Create a merge block we can visit later + Block* dummy_flow_block = new Block{.is_dummy = true}; + auto* ir_block = block_pool.Create(inst_pool); + dummy_flow_block->ir_block = ir_block; + ir_block->cfg_block = dummy_flow_block; + merge_stmt = stmt_pool.Create(dummy_flow_block, &parent); + parent.children.insert(std::next(Tree::s_iterator_to(stmt)), *merge_stmt); + } + return merge_stmt->block->ir_block; + } + + Common::ObjectPool& stmt_pool; + Common::ObjectPool& inst_pool; + Common::ObjectPool& block_pool; + IR::AbstractSyntaxList& syntax_list; +}; + +} // Anonymous namespace + +IR::AbstractSyntaxList BuildASL(Pools& pools, CFG& cfg, Info& info) { + Common::ObjectPool stmt_pool{64}; + GotoPass goto_pass{cfg, stmt_pool}; + Statement& root{goto_pass.RootStatement()}; + IR::AbstractSyntaxList syntax_list; + TranslatePass{pools.inst_pool, pools.block_pool, stmt_pool, root, syntax_list}; + return syntax_list; +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/structured_control_flow.h b/gpu/shadps4/shader_recompiler/frontend/structured_control_flow.h new file mode 100644 index 0000000..a9c8391 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/structured_control_flow.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/frontend/control_flow_graph.h" +#include "shader_recompiler/ir/abstract_syntax_list.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader { +struct Info; +struct Profile; +struct RuntimeInfo; +struct Pools; +} // namespace Shader + +namespace Shader::Gcn { + +[[nodiscard]] IR::AbstractSyntaxList BuildASL(Pools& pools, CFG& cfg, Info& info); + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/tessellation.h b/gpu/shadps4/shader_recompiler/frontend/tessellation.h new file mode 100644 index 0000000..bfcaa4f --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/tessellation.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Shader { + +struct TessellationDataConstantBuffer { + u32 ls_stride; + u32 hs_cp_stride; // HullStateConstants::m_cpStride != 0 ? HullStateConstants::m_cpStride : + // ls_stride + u32 num_patches; // num patches submitted in threadgroup + u32 hs_output_base; // HullStateConstants::m_numInputCP::m_cpStride != 0 ? + // HullStateConstants::m_numInputCP * ls_stride * num_patches : 0 + // basically 0 when passthrough + u32 patch_const_size; // 16 * num_patch_attrs + u32 patch_const_base; // hs_output_base + patch_output_size + u32 patch_output_size; // output_cp_stride * num_output_cp_per_patch + f32 off_chip_tessellation_factor_threshold; + u32 first_edge_tess_factor_index; +}; + +// Assign names to dword fields of TessellationDataConstantBuffer +enum class TessConstantAttribute : u32 { + LsStride, + HsCpStride, + HsNumPatch, + HsOutputBase, + PatchConstSize, + PatchConstBase, + PatchOutputSize, + OffChipTessellationFactorThreshold, + FirstEdgeTessFactorIndex, +}; + +} // namespace Shader \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/data_share.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/data_share.cpp new file mode 100644 index 0000000..4962c20 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/data_share.cpp @@ -0,0 +1,353 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::Gcn { + +void Translator::EmitDataShare(const GcnInst& inst) { + switch (inst.opcode) { + // DS + case Opcode::DS_ADD_U32: + return DS_OP(inst, AtomicOp::Add, false); + case Opcode::DS_ADD_U64: + return DS_OP(inst, AtomicOp::Add, false); + case Opcode::DS_SUB_U32: + return DS_OP(inst, AtomicOp::Sub, false); + case Opcode::DS_INC_U32: + return DS_OP(inst, AtomicOp::Inc, false); + case Opcode::DS_DEC_U32: + return DS_OP(inst, AtomicOp::Dec, false); + case Opcode::DS_MIN_I32: + return DS_OP(inst, AtomicOp::Smin, false); + case Opcode::DS_MAX_I32: + return DS_OP(inst, AtomicOp::Smax, false); + case Opcode::DS_MIN_U32: + return DS_OP(inst, AtomicOp::Umin, false); + case Opcode::DS_MAX_U32: + return DS_OP(inst, AtomicOp::Umax, false); + case Opcode::DS_AND_B32: + return DS_OP(inst, AtomicOp::And, false); + case Opcode::DS_OR_B32: + return DS_OP(inst, AtomicOp::Or, false); + case Opcode::DS_XOR_B32: + return DS_OP(inst, AtomicOp::Xor, false); + case Opcode::DS_WRITE_B32: + return DS_WRITE(32, false, false, false, inst); + case Opcode::DS_WRITE2_B32: + return DS_WRITE(32, false, true, false, inst); + case Opcode::DS_WRITE2ST64_B32: + return DS_WRITE(32, false, true, true, inst); + case Opcode::DS_ADD_RTN_U32: + return DS_OP(inst, AtomicOp::Add, true); + case Opcode::DS_SUB_RTN_U32: + return DS_OP(inst, AtomicOp::Sub, true); + case Opcode::DS_MIN_RTN_U32: + return DS_OP(inst, AtomicOp::Umin, true); + case Opcode::DS_MAX_RTN_U32: + return DS_OP(inst, AtomicOp::Umax, true); + case Opcode::DS_AND_RTN_B32: + return DS_OP(inst, AtomicOp::And, true); + case Opcode::DS_OR_RTN_B32: + return DS_OP(inst, AtomicOp::Or, true); + case Opcode::DS_XOR_RTN_B32: + return DS_OP(inst, AtomicOp::Xor, true); + case Opcode::DS_CMPST_B32: + return DS_CMPST(32, false, inst); + case Opcode::DS_CMPST_RTN_B32: + return DS_CMPST(32, true, inst); + case Opcode::DS_CMPST_B64: + return DS_CMPST(64, false, inst); + case Opcode::DS_CMPST_RTN_B64: + return DS_CMPST(64, true, inst); + case Opcode::DS_SWIZZLE_B32: + return DS_SWIZZLE_B32(inst); + case Opcode::DS_READ_B32: + return DS_READ(32, false, false, false, inst); + case Opcode::DS_READ2_B32: + return DS_READ(32, false, true, false, inst); + case Opcode::DS_READ2ST64_B32: + return DS_READ(32, false, true, true, inst); + case Opcode::DS_READ_U16: + return DS_READ(16, false, false, false, inst); + case Opcode::DS_CONSUME: + return DS_CONSUME(inst); + case Opcode::DS_APPEND: + return DS_APPEND(inst); + case Opcode::DS_WRITE_B16: + return DS_WRITE(16, false, false, false, inst); + case Opcode::DS_WRITE_B64: + return DS_WRITE(64, false, false, false, inst); + case Opcode::DS_WRITE2_B64: + return DS_WRITE(64, false, true, false, inst); + case Opcode::DS_WRITE2ST64_B64: + return DS_WRITE(64, false, true, true, inst); + case Opcode::DS_READ_B64: + return DS_READ(64, false, false, false, inst); + case Opcode::DS_READ2_B64: + return DS_READ(64, false, true, false, inst); + case Opcode::DS_READ2ST64_B64: + return DS_READ(64, false, true, true, inst); + default: + LogMissingOpcode(inst); + } +} + +// VOP2 + +void Translator::V_READFIRSTLANE_B32(const GcnInst& inst) { + const IR::U32 value{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ReadFirstLane(value)); +} + +void Translator::V_READLANE_B32(const GcnInst& inst) { + ASSERT(inst.src[0].field == OperandField::VectorGPR); + const IR::U32 value{GetSrc(inst.src[0])}; + const IR::U32 lane{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ReadLane(value, lane)); +} + +void Translator::V_WRITELANE_B32(const GcnInst& inst) { + const IR::VectorReg dst{inst.dst[0].code}; + const IR::U32 value{GetSrc(inst.src[0])}; + const IR::U32 lane{GetSrc(inst.src[1])}; + const IR::U32 old_value{GetSrc(inst.dst[0])}; + ir.SetVectorReg(dst, ir.WriteLane(old_value, value, lane)); +} + +// DS + +template +void Translator::DS_OP(const GcnInst& inst, AtomicOp op, bool rtn) { + const bool is_gds = inst.control.ds.gds; + const IR::U32 addr{GetSrc(inst.src[0])}; + const T data = [&] { + if (op == AtomicOp::Inc || op == AtomicOp::Dec) { + return T{}; + } + if constexpr (std::is_same_v) { + return GetSrc(inst.src[1]); + } else { + return GetSrc64(inst.src[1]); + } + }(); + const IR::U32 offset = + ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0)); + const IR::U32 addr_offset = ir.IAdd(addr, offset); + const T original_val = [&] -> T { + switch (op) { + case AtomicOp::Add: + return ir.SharedAtomicIAdd(addr_offset, data, is_gds); + case AtomicOp::Umin: + return ir.SharedAtomicIMin(addr_offset, data, false, is_gds); + case AtomicOp::Smin: + return ir.SharedAtomicIMin(addr_offset, data, true, is_gds); + case AtomicOp::Umax: + return ir.SharedAtomicIMax(addr_offset, data, false, is_gds); + case AtomicOp::Smax: + return ir.SharedAtomicIMax(addr_offset, data, true, is_gds); + case AtomicOp::And: + return ir.SharedAtomicAnd(addr_offset, data, is_gds); + case AtomicOp::Or: + return ir.SharedAtomicOr(addr_offset, data, is_gds); + case AtomicOp::Xor: + return ir.SharedAtomicXor(addr_offset, data, is_gds); + case AtomicOp::Sub: + return ir.SharedAtomicISub(addr_offset, data, is_gds); + case AtomicOp::Inc: + return ir.SharedAtomicInc(addr_offset, is_gds); + case AtomicOp::Dec: + return ir.SharedAtomicDec(addr_offset, is_gds); + default: + UNREACHABLE(); + } + }(); + if (rtn) { + if constexpr (std::is_same_v) { + SetDst(inst.dst[0], original_val); + } else { + SetDst64(inst.dst[0], original_val); + } + } +} + +void Translator::DS_CMPST(int bit_size, bool rtn, const GcnInst& inst) { + const bool is_gds = inst.control.ds.gds; + const IR::U32 addr{GetSrc(inst.src[0])}; + const IR::U32 offset = + ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0)); + const IR::U32 addr_offset = ir.IAdd(addr, offset); + if (bit_size == 64) { + const IR::U64 cmp_value{GetSrc64(inst.src[1])}; + const IR::U64 write_value{GetSrc64(inst.src[2])}; + const IR::U64 original_val = + ir.SharedAtomicCmpSwap(addr_offset, write_value, cmp_value, is_gds); + if (rtn) { + SetDst64(inst.dst[0], original_val); + } + } else { + const IR::U32 cmp_value{GetSrc(inst.src[1])}; + const IR::U32 write_value{GetSrc(inst.src[2])}; + const IR::U32 original_val = + ir.SharedAtomicCmpSwap(addr_offset, write_value, cmp_value, is_gds); + if (rtn) { + SetDst(inst.dst[0], original_val); + } + } +} + +void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool stride64, + const GcnInst& inst) { + const bool is_gds = inst.control.ds.gds; + const IR::U32 addr{ir.GetVectorReg(IR::VectorReg(inst.src[0].code))}; + const IR::VectorReg data0{inst.src[1].code}; + const IR::VectorReg data1{inst.src[2].code}; + const u32 offset = (inst.control.ds.offset1 << 8u) + inst.control.ds.offset0; + if (info.hw_stage == HwStage::Fragment) { + ASSERT_MSG(!is_pair && bit_size == 32 && offset % 256 == 0, + "Unexpected shared memory offset alignment: {}", offset); + ir.SetVectorReg(GetScratchVgpr(offset), ir.GetVectorReg(data0)); + return; + } + if (is_pair) { + const u32 adj = (bit_size == 32 ? 4 : 8) * (stride64 ? 64 : 1); + const IR::U32 addr0 = ir.IAdd(addr, ir.Imm32(u32(inst.control.ds.offset0 * adj))); + if (bit_size == 64) { + ir.WriteShared(64, + ir.PackUint2x32(ir.CompositeConstruct(ir.GetVectorReg(data0), + ir.GetVectorReg(data0 + 1))), + addr0, is_gds); + } else if (bit_size == 32) { + ir.WriteShared(32, ir.GetVectorReg(data0), addr0, is_gds); + } else if (bit_size == 16) { + ir.WriteShared(16, ir.UConvert(16, ir.GetVectorReg(data0)), addr0, is_gds); + } + const IR::U32 addr1 = ir.IAdd(addr, ir.Imm32(u32(inst.control.ds.offset1 * adj))); + if (bit_size == 64) { + ir.WriteShared(64, + ir.PackUint2x32(ir.CompositeConstruct(ir.GetVectorReg(data1), + ir.GetVectorReg(data1 + 1))), + addr1, is_gds); + } else if (bit_size == 32) { + ir.WriteShared(32, ir.GetVectorReg(data1), addr1, is_gds); + } else if (bit_size == 16) { + ir.WriteShared(16, ir.UConvert(16, ir.GetVectorReg(data1)), addr1, is_gds); + } + } else { + const IR::U32 addr0 = ir.IAdd(addr, ir.Imm32(offset)); + if (bit_size == 64) { + const IR::Value data = + ir.CompositeConstruct(ir.GetVectorReg(data0), ir.GetVectorReg(data0 + 1)); + ir.WriteShared(bit_size, ir.PackUint2x32(data), addr0, is_gds); + } else if (bit_size == 32) { + ir.WriteShared(bit_size, ir.GetVectorReg(data0), addr0, is_gds); + } else if (bit_size == 16) { + ir.WriteShared(bit_size, ir.UConvert(16, ir.GetVectorReg(data0)), addr0, is_gds); + } + } +} + +void Translator::DS_READ(int bit_size, bool is_signed, bool is_pair, bool stride64, + const GcnInst& inst) { + const bool is_gds = inst.control.ds.gds; + const IR::U32 addr{ir.GetVectorReg(IR::VectorReg(inst.src[0].code))}; + IR::VectorReg dst_reg{inst.dst[0].code}; + const u32 offset = (inst.control.ds.offset1 << 8u) + inst.control.ds.offset0; + if (info.hw_stage == HwStage::Fragment) { + ASSERT_MSG(!is_pair && bit_size == 32 && offset % 256 == 0, + "Unexpected shared memory offset alignment: {}", offset); + ir.SetVectorReg(dst_reg, ir.GetVectorReg(GetScratchVgpr(offset))); + return; + } + if (is_pair) { + // Pair loads are either 32 or 64-bit + const u32 adj = (bit_size == 32 ? 4 : 8) * (stride64 ? 64 : 1); + const IR::U32 addr0 = ir.IAdd(addr, ir.Imm32(u32(inst.control.ds.offset0 * adj))); + const IR::Value data0 = ir.LoadShared(bit_size, is_signed, addr0, is_gds); + if (bit_size == 64) { + const auto vector = ir.UnpackUint2x32(IR::U64{data0}); + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(vector, 0)}); + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(vector, 1)}); + } else if (bit_size == 32) { + ir.SetVectorReg(dst_reg++, IR::U32{data0}); + } else if (bit_size == 16) { + ir.SetVectorReg(dst_reg++, IR::U32{ir.UConvert(32, IR::U16{data0})}); + } + const IR::U32 addr1 = ir.IAdd(addr, ir.Imm32(u32(inst.control.ds.offset1 * adj))); + const IR::Value data1 = ir.LoadShared(bit_size, is_signed, addr1, is_gds); + if (bit_size == 64) { + const auto vector = ir.UnpackUint2x32(IR::U64{data1}); + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(vector, 0)}); + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(vector, 1)}); + } else if (bit_size == 32) { + ir.SetVectorReg(dst_reg++, IR::U32{data1}); + } else if (bit_size == 16) { + ir.SetVectorReg(dst_reg++, IR::U32{ir.UConvert(32, IR::U16{data1})}); + } + } else { + const IR::U32 addr0 = ir.IAdd(addr, ir.Imm32(offset)); + const IR::Value data = ir.LoadShared(bit_size, is_signed, addr0, is_gds); + if (bit_size == 64) { + const auto vector = ir.UnpackUint2x32(IR::U64{data}); + ir.SetVectorReg(dst_reg, IR::U32{ir.CompositeExtract(vector, 0)}); + ir.SetVectorReg(dst_reg + 1, IR::U32{ir.CompositeExtract(vector, 1)}); + } else if (bit_size == 32) { + ir.SetVectorReg(dst_reg, IR::U32{data}); + } else if (bit_size == 16) { + ir.SetVectorReg(dst_reg++, IR::U32{ir.UConvert(32, IR::U16{data})}); + } + } +} + +void Translator::DS_SWIZZLE_B32(const GcnInst& inst) { + const u8 offset0 = inst.control.ds.offset0; + const u8 offset1 = inst.control.ds.offset1; + const IR::U32 src{GetSrc(inst.src[0])}; + if (offset1 & 0x80) { + if (offset0 == 0x0 || offset0 == 0x55 || offset0 == 0xAA || offset0 == 0xFF) { + SetDst(inst.dst[0], ir.QuadBroadcast(src, ir.Imm32(offset0 & 3))); + } else { + const IR::U32 lane_id = ir.LaneId(); + const IR::U32 id_in_quad = ir.BitwiseAnd(lane_id, ir.Imm32(3)); + const IR::U32 base = ir.ShiftLeftLogical(id_in_quad, ir.Imm32(1)); + const IR::U32 sel = ir.BitFieldExtract(ir.Imm32(offset0), base, ir.Imm32(2)); + const IR::U32 quad_base = ir.BitwiseAnd(lane_id, ir.Imm32(~3u)); + SetDst(inst.dst[0], ir.Shuffle(src, ir.BitwiseOr(quad_base, sel))); + } + } else { + const u8 and_mask = (offset0 & 0x1f) | (~u8{0} << 5); + const u8 or_mask = (offset0 >> 5) | ((offset1 & 0x3) << 3); + const u8 xor_mask = offset1 >> 2; + if (or_mask == 0u && and_mask == 255u) { + SetDst(inst.dst[0], ir.ShuffleXor(src, ir.Imm32(xor_mask))); + } else { + const IR::U32 lane_id = ir.LaneId(); + const IR::U32 local = ir.BitwiseAnd(lane_id, ir.Imm32(31u)); + const IR::U32 half = ir.BitwiseAnd(lane_id, ir.Imm32(~31u)); + const IR::U32 index = ir.BitwiseXor( + ir.BitwiseOr(ir.BitwiseAnd(local, ir.Imm32(and_mask)), ir.Imm32(or_mask)), + ir.Imm32(xor_mask)); + SetDst(inst.dst[0], ir.Shuffle(src, ir.BitwiseOr(index, half))); + } + } +} + +void Translator::DS_APPEND(const GcnInst& inst) { + const u32 inst_offset = (u32(inst.control.ds.offset1) << 8u) + inst.control.ds.offset0; + const IR::U32 base = ir.BitFieldExtract(ir.GetM0(), ir.Imm32(16), ir.Imm32(16)); + const IR::U32 gds_offset = ir.IAdd(base, ir.Imm32(inst_offset)); + const IR::U32 prev = ir.DataAppend(ir.ShiftRightLogical(gds_offset, ir.Imm32(2u))); + SetDst(inst.dst[0], prev); +} + +void Translator::DS_CONSUME(const GcnInst& inst) { + const u32 inst_offset = (u32(inst.control.ds.offset1) << 8u) + inst.control.ds.offset0; + const IR::U32 base = ir.BitFieldExtract(ir.GetM0(), ir.Imm32(16), ir.Imm32(16)); + const IR::U32 gds_offset = ir.IAdd(base, ir.Imm32(inst_offset)); + const IR::U32 prev = ir.DataConsume(ir.ShiftRightLogical(gds_offset, ir.Imm32(2u))); + SetDst(inst.dst[0], prev); +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/export.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/export.cpp new file mode 100644 index 0000000..616c7c6 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/export.cpp @@ -0,0 +1,200 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/ir/position.h" +#include "shader_recompiler/ir/reinterpret.h" +#include "shader_recompiler/profile.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::Gcn { + +static AmdGpu::NumberFormat NumberFormatCompressed(AmdGpu::ShaderExportFormat export_format) { + switch (export_format) { + case AmdGpu::ShaderExportFormat::ABGR_FP16: + return AmdGpu::NumberFormat::Float; + case AmdGpu::ShaderExportFormat::ABGR_UNORM16: + return AmdGpu::NumberFormat::Unorm; + case AmdGpu::ShaderExportFormat::ABGR_SNORM16: + return AmdGpu::NumberFormat::Snorm; + case AmdGpu::ShaderExportFormat::ABGR_UINT16: + return AmdGpu::NumberFormat::Uint; + case AmdGpu::ShaderExportFormat::ABGR_SINT16: + return AmdGpu::NumberFormat::Sint; + default: + UNREACHABLE_MSG("Unimplemented compressed export format {}", + static_cast(export_format)); + } +} + +static u32 MaskFromExportFormat(u8 mask, AmdGpu::ShaderExportFormat export_format) { + switch (export_format) { + case AmdGpu::ShaderExportFormat::R_32: + // Red only + return mask & 1; + case AmdGpu::ShaderExportFormat::GR_32: + // Red and Green only + return mask & 3; + case AmdGpu::ShaderExportFormat::AR_32: + // Red and Alpha only + return mask & 9; + case AmdGpu::ShaderExportFormat::ABGR_32: + // All components + return mask; + default: + UNREACHABLE_MSG("Unimplemented uncompressed export format {}", + static_cast(export_format)); + } +} + +void Translator::ExportRenderTarget(const GcnInst& inst) { + const auto& exp = inst.control.exp; + const IR::Attribute mrt{exp.target}; + info.mrt_mask |= 1u << static_cast(mrt); + + // Dual source blending uses MRT1 for exporting src1 + u32 color_buffer_idx = static_cast(mrt) - static_cast(IR::Attribute::RenderTarget0); + if (runtime_info.hw.fs.dual_source_blending && mrt == IR::Attribute::RenderTarget1) { + color_buffer_idx = 0; + } + + const auto color_buffer = runtime_info.hw.fs.color_buffers[color_buffer_idx]; + if (color_buffer.export_format == AmdGpu::ShaderExportFormat::Zero || exp.en == 0) { + // No export + return; + } + + std::array components{}; + if (exp.compr) { + // Components are float16 packed into a VGPR + const auto num_format = NumberFormatCompressed(color_buffer.export_format); + // Export R, G + if (exp.en & 1) { + const IR::Value unpacked_value = + ir.Unpack2x16(num_format, ir.GetVectorReg(IR::VectorReg(inst.src[0].code))); + components[0] = IR::F32{ir.CompositeExtract(unpacked_value, 0)}; + components[1] = IR::F32{ir.CompositeExtract(unpacked_value, 1)}; + } + // Export B, A + if ((exp.en >> 2) & 1) { + const IR::Value unpacked_value = + ir.Unpack2x16(num_format, ir.GetVectorReg(IR::VectorReg(inst.src[1].code))); + components[2] = IR::F32{ir.CompositeExtract(unpacked_value, 0)}; + components[3] = IR::F32{ir.CompositeExtract(unpacked_value, 1)}; + } + } else { + // Components are float32 into separate VGPRS + u32 mask = MaskFromExportFormat(exp.en, color_buffer.export_format); + for (u32 i = 0; i < 4; i++, mask >>= 1) { + if ((mask & 1) == 0) { + continue; + } + components[i] = ir.GetVectorReg(IR::VectorReg(inst.src[i].code)); + } + } + + // Metal seems to have an issue where 8-bit unorm/snorm/sRGB outputs to render target + // need a bias applied to round correctly; detect and set the flag for that here. + const auto needs_unorm_fixup = profile.needs_unorm_fixup && + (color_buffer.num_format == AmdGpu::NumberFormat::Unorm || + color_buffer.num_format == AmdGpu::NumberFormat::Snorm || + color_buffer.num_format == AmdGpu::NumberFormat::Srgb) && + (color_buffer.data_format == AmdGpu::DataFormat::Format8 || + color_buffer.data_format == AmdGpu::DataFormat::Format8_8 || + color_buffer.data_format == AmdGpu::DataFormat::Format8_8_8_8); + + // Swizzle components and export + for (u32 i = 0; i < 4; ++i) { + const auto swizzled_comp = components[color_buffer.swizzle.Map(i)]; + if (swizzled_comp.IsEmpty()) { + continue; + } + auto converted = ApplyWriteNumberConversion(ir, swizzled_comp, color_buffer.num_conversion); + if (needs_unorm_fixup) { + // FIXME: Fix-up for GPUs where float-to-unorm rounding is off from expected. + converted = ir.FPSub(converted, ir.Imm32(1.f / 127500.f)); + } + ir.SetAttribute(mrt, converted, i); + } +} + +void Translator::ExportDepth(const GcnInst& inst) { + const auto& exp = inst.control.exp; + if (exp.en == 0) { + // No export + return; + } + + std::array components{}; + if (exp.compr) { + // Components are float16 packed into a VGPR + const auto num_format = NumberFormatCompressed(runtime_info.hw.fs.z_export_format); + // Export R, G + if (exp.en & 1) { + const IR::Value unpacked_value = + ir.Unpack2x16(num_format, ir.GetVectorReg(IR::VectorReg(inst.src[0].code))); + components[0] = IR::F32{ir.CompositeExtract(unpacked_value, 0)}; + components[1] = IR::F32{ir.CompositeExtract(unpacked_value, 1)}; + } + // Export B, A + if ((exp.en >> 2) & 1) { + const IR::Value unpacked_value = + ir.Unpack2x16(num_format, ir.GetVectorReg(IR::VectorReg(inst.src[1].code))); + components[2] = IR::F32{ir.CompositeExtract(unpacked_value, 0)}; + // components[3] = IR::F32{ir.CompositeExtract(unpacked_value, 1)}; + } + } else { + // Components are float32 into separate VGPRS + u32 mask = MaskFromExportFormat(exp.en & runtime_info.hw.fs.mrtz_mask, + runtime_info.hw.fs.z_export_format); + for (u32 i = 0; i < 4; i++, mask >>= 1) { + if ((mask & 1) == 0) { + continue; + } + components[i] = ir.GetVectorReg(IR::VectorReg(inst.src[i].code)); + } + } + + static constexpr std::array MrtzBuiltins = {IR::Attribute::Depth, IR::Attribute::StencilRef, + IR::Attribute::SampleMask, IR::Attribute::Null}; + for (u32 i = 0; i < 4; ++i) { + if (components[i].IsEmpty()) { + continue; + } + ir.SetAttribute(MrtzBuiltins[i], components[i]); + } +} + +void Translator::EmitExport(const GcnInst& inst) { + if (info.hw_stage == HwStage::Fragment && inst.control.exp.vm) { + ir.Discard(ir.LogicalNot(ir.GetExec())); + } + + const IR::Attribute attrib{inst.control.exp.target}; + if (IR::IsMrt(attrib)) { + return ExportRenderTarget(inst); + } + if (attrib == IR::Attribute::Depth) { + return ExportDepth(inst); + } + + ASSERT_MSG(!inst.control.exp.compr, "Compressed exports only supported for render targets"); + + const bool tess_emulated_primitive = + info.sw_stage == SwStage::Vertex && runtime_info.sw.vs.tess_emulated_primitive; + + u32 mask = inst.control.exp.en; + for (u32 i = 0; i < 4; i++, mask >>= 1) { + if ((mask & 1) == 0) { + continue; + } + const auto value = ir.GetVectorReg(IR::VectorReg(inst.src[i].code)); + if (IsPosition(attrib)) { + IR::ExportPosition(ir, runtime_info.hw.vs, tess_emulated_primitive, attrib, i, value); + } else { + ir.SetAttribute(attrib, value, i); + } + } +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/scalar_alu.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/scalar_alu.cpp new file mode 100644 index 0000000..9fd532a --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -0,0 +1,676 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "shader_recompiler/frontend/translate/translate.h" + +namespace Shader::Gcn { + +void Translator::EmitScalarAlu(const GcnInst& inst) { + switch (inst.encoding) { + case InstEncoding::SOPC: { + EmitSOPC(inst); + break; + } + case InstEncoding::SOPK: { + EmitSOPK(inst); + break; + } + default: + switch (inst.opcode) { + // SOP2 + case Opcode::S_ADD_U32: + return S_ADD_U32(inst); + case Opcode::S_SUB_U32: + return S_SUB_U32(inst); + case Opcode::S_ADD_I32: + return S_ADD_I32(inst); + case Opcode::S_SUB_I32: + return S_SUB_I32(inst); + case Opcode::S_ADDC_U32: + return S_ADDC_U32(inst); + case Opcode::S_SUBB_U32: + return S_SUBB_U32(inst); + case Opcode::S_MIN_I32: + return S_MIN_U32(true, inst); + case Opcode::S_MIN_U32: + return S_MIN_U32(false, inst); + case Opcode::S_MAX_I32: + return S_MAX_U32(true, inst); + case Opcode::S_MAX_U32: + return S_MAX_U32(false, inst); + case Opcode::S_CSELECT_B32: + return S_CSELECT_B32(inst); + case Opcode::S_CSELECT_B64: + return S_CSELECT_B64(inst); + case Opcode::S_AND_B32: + return S_AND_B32(NegateMode::None, inst); + case Opcode::S_AND_B64: + return S_AND_B64(NegateMode::None, inst); + case Opcode::S_OR_B32: + return S_OR_B32(inst); + case Opcode::S_OR_B64: + return S_OR_B64(NegateMode::None, false, inst); + case Opcode::S_XOR_B32: + return S_XOR_B32(inst); + case Opcode::S_NOT_B32: + return S_NOT_B32(inst); + case Opcode::S_XOR_B64: + return S_OR_B64(NegateMode::None, true, inst); + case Opcode::S_ANDN2_B32: + return S_AND_B32(NegateMode::Src1, inst); + case Opcode::S_ANDN2_B64: + return S_AND_B64(NegateMode::Src1, inst); + case Opcode::S_ORN2_B64: + return S_OR_B64(NegateMode::Src1, false, inst); + case Opcode::S_NAND_B32: + return S_AND_B32(NegateMode::Result, inst); + case Opcode::S_NAND_B64: + return S_AND_B64(NegateMode::Result, inst); + case Opcode::S_NOR_B64: + return S_OR_B64(NegateMode::Result, false, inst); + case Opcode::S_XNOR_B64: + return S_OR_B64(NegateMode::Result, true, inst); + case Opcode::S_LSHL_B32: + return S_LSHL_B32(inst); + case Opcode::S_LSHL_B64: + return S_LSHL_B64(inst); + case Opcode::S_LSHR_B32: + return S_LSHR_B32(inst); + case Opcode::S_ASHR_I32: + return S_ASHR_I32(inst); + case Opcode::S_ASHR_I64: + return S_ASHR_I64(inst); + case Opcode::S_BFM_B32: + return S_BFM_B32(inst); + case Opcode::S_MUL_I32: + return S_MUL_I32(inst); + case Opcode::S_BFE_I32: + return S_BFE(inst, true); + case Opcode::S_BFE_U32: + return S_BFE(inst, false); + case Opcode::S_ABSDIFF_I32: + return S_ABSDIFF_I32(inst); + + // SOP1 + case Opcode::S_MOV_B32: + return S_MOV(inst); + case Opcode::S_MOV_B64: + return S_MOV_B64(inst); + case Opcode::S_NOT_B64: + return S_NOT_B64(inst); + case Opcode::S_WQM_B64: + break; + case Opcode::S_BREV_B32: + return S_BREV_B32(inst); + case Opcode::S_BCNT1_I32_B32: + return S_BCNT1_I32_B32(inst); + case Opcode::S_BCNT1_I32_B64: + return S_BCNT1_I32_B64(inst); + case Opcode::S_FF1_I32_B32: + return S_FF1_I32_B32(inst); + case Opcode::S_FF1_I32_B64: + return S_FF1_I32_B64(inst); + case Opcode::S_FLBIT_I32_B32: + return S_FLBIT_I32_B32(inst); + case Opcode::S_FLBIT_I32_B64: + return S_FLBIT_I32_B64(inst); + case Opcode::S_BITSET0_B32: + return S_BITSET_B32(inst, 0); + case Opcode::S_BITSET1_B32: + return S_BITSET_B32(inst, 1); + case Opcode::S_BITSET0_B64: + return S_BITSET_B64(inst, 0); + case Opcode::S_BITSET1_B64: + return S_BITSET_B64(inst, 1); + case Opcode::S_AND_SAVEEXEC_B64: + return S_SAVEEXEC_B64(NegateMode::None, false, inst); + case Opcode::S_ORN2_SAVEEXEC_B64: + return S_SAVEEXEC_B64(NegateMode::Src1, true, inst); + case Opcode::S_ABS_I32: + return S_ABS_I32(inst); + default: + LogMissingOpcode(inst); + } + break; + } +} + +void Translator::EmitSOPC(const GcnInst& inst) { + switch (inst.opcode) { + case Opcode::S_CMP_EQ_I32: + return S_CMP(ConditionOp::EQ, true, inst); + case Opcode::S_CMP_LG_I32: + return S_CMP(ConditionOp::LG, true, inst); + case Opcode::S_CMP_GT_I32: + return S_CMP(ConditionOp::GT, true, inst); + case Opcode::S_CMP_GE_I32: + return S_CMP(ConditionOp::GE, true, inst); + case Opcode::S_CMP_LT_I32: + return S_CMP(ConditionOp::LT, true, inst); + case Opcode::S_CMP_LE_I32: + return S_CMP(ConditionOp::LE, true, inst); + + case Opcode::S_CMP_EQ_U32: + return S_CMP(ConditionOp::EQ, false, inst); + case Opcode::S_CMP_LG_U32: + return S_CMP(ConditionOp::LG, false, inst); + case Opcode::S_CMP_GT_U32: + return S_CMP(ConditionOp::GT, false, inst); + case Opcode::S_CMP_GE_U32: + return S_CMP(ConditionOp::GE, false, inst); + case Opcode::S_CMP_LT_U32: + return S_CMP(ConditionOp::LT, false, inst); + case Opcode::S_CMP_LE_U32: + return S_CMP(ConditionOp::LE, false, inst); + + case Opcode::S_BITCMP0_B32: + return S_BITCMP(false, 32, inst); + case Opcode::S_BITCMP1_B32: + return S_BITCMP(true, 32, inst); + case Opcode::S_BITCMP0_B64: + return S_BITCMP(false, 64, inst); + case Opcode::S_BITCMP1_B64: + return S_BITCMP(true, 64, inst); + + default: + LogMissingOpcode(inst); + } +} + +void Translator::EmitSOPK(const GcnInst& inst) { + switch (inst.opcode) { + // SOPK + case Opcode::S_MOVK_I32: + return S_MOVK(inst, false); + case Opcode::S_CMOVK_I32: + return S_MOVK(inst, true); + case Opcode::S_CMPK_EQ_I32: + return S_CMPK(ConditionOp::EQ, true, inst); + case Opcode::S_CMPK_LG_I32: + return S_CMPK(ConditionOp::LG, true, inst); + case Opcode::S_CMPK_GT_I32: + return S_CMPK(ConditionOp::GT, true, inst); + case Opcode::S_CMPK_GE_I32: + return S_CMPK(ConditionOp::GE, true, inst); + case Opcode::S_CMPK_LT_I32: + return S_CMPK(ConditionOp::LT, true, inst); + case Opcode::S_CMPK_LE_I32: + return S_CMPK(ConditionOp::LE, true, inst); + + case Opcode::S_CMPK_EQ_U32: + return S_CMPK(ConditionOp::EQ, false, inst); + case Opcode::S_CMPK_LG_U32: + return S_CMPK(ConditionOp::LG, false, inst); + case Opcode::S_CMPK_GT_U32: + return S_CMPK(ConditionOp::GT, false, inst); + case Opcode::S_CMPK_GE_U32: + return S_CMPK(ConditionOp::GE, false, inst); + case Opcode::S_CMPK_LT_U32: + return S_CMPK(ConditionOp::LT, false, inst); + case Opcode::S_CMPK_LE_U32: + return S_CMPK(ConditionOp::LE, false, inst); + + case Opcode::S_ADDK_I32: + return S_ADDK_I32(inst); + case Opcode::S_MULK_I32: + return S_MULK_I32(inst); + default: + LogMissingOpcode(inst); + } +} + +// SOP2 + +void Translator::S_ADD_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.IAdd(src0, src1)}; + SetDst(inst.dst[0], result); + + // SCC = tmp >= 0x100000000ULL ? 1'1U : 1'0U; + // The above assumes tmp is a 64-bit value. + // It should be enough however to test that the truncated result is less than at least one + // of the operands. In unsigned addition the result is always bigger than both the operands, + // except in the case of overflow where the truncated result is less than both. + ir.SetScc(ir.ILessThan(result, src0, false)); +} + +void Translator::S_SUB_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ISub(src0, src1)); + + // SCC = S1.u > S0.u ? 1'1U : 1'0U; + ir.SetScc(ir.IGreaterThan(src1, src0, false)); +} + +void Translator::S_SUBB_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 borrow{ir.Select(ir.GetScc(), ir.Imm32(1U), ir.Imm32(0U))}; + const IR::U32 result{ir.ISub(ir.ISub(src0, src1), borrow)}; + SetDst(inst.dst[0], result); + + const IR::U32 sum_with_borrow{ir.IAdd(src1, borrow)}; + ir.SetScc(ir.ILessThan(src0, sum_with_borrow, false)); +} + +void Translator::S_ADD_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.IAdd(src0, src1)}; + SetDst(inst.dst[0], result); + + // SCC = ((S0.u[31] == S1.u[31]) && (S0.u[31] != Result.u[31])); + const IR::U32 shift{ir.Imm32(31)}; + const IR::U32 sign0{ir.ShiftRightLogical(src0, shift)}; + const IR::U32 sign1{ir.ShiftRightLogical(src1, shift)}; + const IR::U32 signr{ir.ShiftRightLogical(result, shift)}; + ir.SetScc(ir.LogicalAnd(ir.IEqual(sign0, sign1), ir.INotEqual(sign0, signr))); +} + +void Translator::S_SUB_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.ISub(src0, src1)}; + SetDst(inst.dst[0], result); + + // SCC = ((S0.u[31] != S1.u[31]) && (S0.u[31] != tmp.u[31])); + const IR::U32 shift{ir.Imm32(31)}; + const IR::U32 sign0{ir.ShiftRightLogical(src0, shift)}; + const IR::U32 sign1{ir.ShiftRightLogical(src1, shift)}; + const IR::U32 signr{ir.ShiftRightLogical(result, shift)}; + ir.SetScc(ir.LogicalAnd(ir.INotEqual(sign0, sign1), ir.INotEqual(sign0, signr))); +} + +void Translator::S_ADDC_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 carry{ir.Select(ir.GetScc(), ir.Imm32(1U), ir.Imm32(0U))}; + SetDst(inst.dst[0], ir.IAdd(ir.IAdd(src0, src1), carry)); +} + +void Translator::S_MIN_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result = ir.IMin(src0, src1, is_signed); + SetDst(inst.dst[0], result); + ir.SetScc(ir.IEqual(result, src0)); +} + +void Translator::S_MAX_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result = ir.IMax(src0, src1, is_signed); + SetDst(inst.dst[0], result); + ir.SetScc(ir.IEqual(result, src0)); +} + +void Translator::S_CSELECT_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], IR::U32{ir.Select(ir.GetScc(), src0, src1)}); +} + +void Translator::S_CSELECT_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + const IR::U64 result{ir.Select(ir.GetScc(), src0, src1)}; + SetDst64(inst.dst[0], result); +} + +void Translator::S_AND_B32(NegateMode negate, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + IR::U32 src1{GetSrc(inst.src[1])}; + if (negate == NegateMode::Src1) { + src1 = ir.BitwiseNot(src1); + } + IR::U32 result{ir.BitwiseAnd(src0, src1)}; + if (negate == NegateMode::Result) { + result = ir.BitwiseNot(result); + } + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_AND_B64(NegateMode negate, const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + IR::U64 src1{GetSrc64(inst.src[1])}; + if (negate == NegateMode::Src1) { + src1 = ir.BitwiseNot(src1); + } + IR::U64 result = ir.BitwiseAnd(src0, src1); + if (negate == NegateMode::Result) { + result = ir.BitwiseNot(result); + } + ir.SetScc(ir.InverseBallot(result)); + SetDst64(inst.dst[0], result); +} + +void Translator::S_OR_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.BitwiseOr(src0, src1)}; + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_OR_B64(NegateMode negate, bool is_xor, const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + IR::U64 src1{GetSrc64(inst.src[1])}; + if (negate == NegateMode::Src1) { + src1 = ir.BitwiseNot(src1); + } + IR::U64 result = is_xor ? ir.BitwiseXor(src0, src1) : ir.BitwiseOr(src0, src1); + if (negate == NegateMode::Result) { + result = ir.BitwiseNot(result); + } + ir.SetScc(ir.InverseBallot(result)); + SetDst64(inst.dst[0], result); +} + +void Translator::S_XOR_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.BitwiseXor(src0, src1)}; + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_NOT_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 result{ir.BitwiseNot(src0)}; + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_LSHL_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result = ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm32(0x1F))); + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_LSHL_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + const IR::U64 result = ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F)))); + SetDst64(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm64(u64(0)))); +} + +void Translator::S_LSHR_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 shift_amt = ir.BitwiseAnd(src1, ir.Imm32(0x1F)); + const IR::U32 result = ir.ShiftRightLogical(src0, shift_amt); + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_ASHR_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.ShiftRightArithmetic(src0, ir.BitwiseAnd(src1, ir.Imm32(0x1F)))}; + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_ASHR_I64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + const IR::U64 result{ir.ShiftRightArithmetic(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F))))}; + SetDst64(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm64(u64(0)))); +} + +void Translator::S_BFM_B32(const GcnInst& inst) { + const IR::U32 src0{ir.BitwiseAnd(GetSrc(inst.src[0]), ir.Imm32(0x1F))}; + const IR::U32 src1{ir.BitwiseAnd(GetSrc(inst.src[1]), ir.Imm32(0x1F))}; + const IR::U32 mask{ir.ISub(ir.ShiftLeftLogical(ir.Imm32(1u), src0), ir.Imm32(1))}; + SetDst(inst.dst[0], ir.ShiftLeftLogical(mask, src1)); +} + +void Translator::S_MUL_I32(const GcnInst& inst) { + SetDst(inst.dst[0], ir.IMul(GetSrc(inst.src[0]), GetSrc(inst.src[1]))); +} + +void Translator::S_BFE(const GcnInst& inst, bool is_signed) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 offset{ir.BitwiseAnd(src1, ir.Imm32(0x1F))}; + const IR::U32 count{ir.BitFieldExtract(src1, ir.Imm32(16), ir.Imm32(7))}; + const IR::U32 result{ir.BitFieldExtract(src0, offset, count, is_signed)}; + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_ABSDIFF_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.IAbs(ir.ISub(src0, src1))}; + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +// SOPK + +void Translator::S_MOVK(const GcnInst& inst, bool is_conditional) { + const s16 simm16 = inst.control.sopk.simm; + // do the sign extension + const s32 simm32 = static_cast(simm16); + IR::U32 val = ir.Imm32(simm32); + if (is_conditional) { + // if !SCC its a NOP + val = IR::U32{ir.Select(ir.GetScc(), val, GetSrc(inst.dst[0]))}; + } + SetDst(inst.dst[0], val); +} + +void Translator::S_CMPK(ConditionOp cond, bool is_signed, const GcnInst& inst) { + const s32 simm16 = inst.control.sopk.simm; + const IR::U32 lhs = GetSrc(inst.dst[0]); + const IR::U32 rhs = ir.Imm32(simm16); + const IR::U1 result = [&] { + switch (cond) { + case ConditionOp::EQ: + return ir.IEqual(lhs, rhs); + case ConditionOp::LG: + return ir.INotEqual(lhs, rhs); + case ConditionOp::GT: + return ir.IGreaterThan(lhs, rhs, is_signed); + case ConditionOp::GE: + return ir.IGreaterThanEqual(lhs, rhs, is_signed); + case ConditionOp::LT: + return ir.ILessThan(lhs, rhs, is_signed); + case ConditionOp::LE: + return ir.ILessThanEqual(lhs, rhs, is_signed); + default: + UNREACHABLE(); + } + }(); + ir.SetScc(result); +} + +void Translator::S_ADDK_I32(const GcnInst& inst) { + const s32 simm16 = inst.control.sopk.simm; + const IR::U32 src0{GetSrc(inst.dst[0])}; + const IR::U32 src1{ir.Imm32(simm16)}; + const IR::U32 result{ir.IAdd(src0, src1)}; + SetDst(inst.dst[0], result); + + const IR::U32 shift{ir.Imm32(31)}; + const IR::U32 sign0{ir.ShiftRightLogical(src0, shift)}; + const IR::U32 sign1{ir.ShiftRightLogical(src1, shift)}; + const IR::U32 signr{ir.ShiftRightLogical(result, shift)}; + ir.SetScc(ir.LogicalAnd(ir.IEqual(sign0, sign1), ir.INotEqual(sign0, signr))); +} + +void Translator::S_MULK_I32(const GcnInst& inst) { + const s32 simm16 = inst.control.sopk.simm; + SetDst(inst.dst[0], ir.IMul(GetSrc(inst.dst[0]), ir.Imm32(simm16))); +} + +// SOP1 + +void Translator::S_MOV(const GcnInst& inst) { + SetDst(inst.dst[0], GetSrc(inst.src[0])); +} + +void Translator::S_MOV_B64(const GcnInst& inst) { + SetDst64(inst.dst[0], GetSrc64(inst.src[0])); +} + +void Translator::S_NOT_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 result = ir.BitwiseNot(src0); + ir.SetScc(ir.InverseBallot(result)); + SetDst64(inst.dst[0], result); +} + +void Translator::S_BREV_B32(const GcnInst& inst) { + SetDst(inst.dst[0], ir.BitReverse(GetSrc(inst.src[0]))); +} + +void Translator::S_BCNT1_I32_B32(const GcnInst& inst) { + const IR::U32 result = ir.BitCount(GetSrc(inst.src[0])); + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_BCNT1_I32_B64(const GcnInst& inst) { + const IR::U32 result = ir.BitCount(GetSrc64(inst.src[0])); + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +void Translator::S_FF1_I32_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 result{ir.FindILsb(src0)}; + SetDst(inst.dst[0], result); +} + +void Translator::S_FF1_I32_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + SetDst(inst.dst[0], ir.BallotFindLsb(src0)); +} + +void Translator::S_FLBIT_I32_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + // Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB) + // position + const IR::U32 msb_pos = ir.FindUMsb(src0); + const IR::U32 pos_from_left = ir.ISub(ir.Imm32(31), msb_pos); + // Select 0xFFFFFFFF if src0 was 0 + const IR::U1 cond = ir.INotEqual(src0, ir.Imm32(0)); + SetDst(inst.dst[0], IR::U32{ir.Select(cond, pos_from_left, ir.Imm32(~0U))}); +} + +void Translator::S_FLBIT_I32_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + // Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB) + // position + const IR::U32 msb_pos = ir.FindUMsb(src0); + const IR::U32 pos_from_left = ir.ISub(ir.Imm32(63), msb_pos); + // Select 0xFFFFFFFF if src0 was 0 + const IR::U1 cond = ir.INotEqual(src0, ir.Imm64(u64(0u))); + SetDst(inst.dst[0], IR::U32{ir.Select(cond, pos_from_left, ir.Imm32(~0U))}); +} + +void Translator::S_BITSET_B32(const GcnInst& inst, u32 bit_value) { + const IR::U32 old_value{GetSrc(inst.dst[0])}; + const IR::U32 offset{ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0U), ir.Imm32(5U))}; + const IR::U32 result{ir.BitFieldInsert(old_value, ir.Imm32(bit_value), offset, ir.Imm32(1U))}; + SetDst(inst.dst[0], result); +} + +void Translator::S_BITSET_B64(const GcnInst& inst, u32 bit_value) { + const IR::U64 old_value{GetSrc64(inst.dst[0])}; + const IR::U32 offset{ir.BitwiseAnd(GetSrc(inst.src[0]), ir.Imm32(0x3F))}; + const IR::U64 result{ + ir.BitFieldInsert(old_value, ir.Imm64(u64(bit_value)), offset, ir.Imm32(1U))}; + SetDst64(inst.dst[0], result); +} + +void Translator::S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst) { + IR::U64 exec{ir.Ballot(ir.GetExec())}; + const IR::U64 src{GetSrc64(inst.src[0])}; + SetDst64(inst.dst[0], exec); + + // Update EXEC. + if (negate == NegateMode::Src1) { + exec = ir.BitwiseNot(exec); + } + IR::U64 result = is_or ? ir.BitwiseOr(exec, src) : ir.BitwiseAnd(exec, src); + if (negate == NegateMode::Result) { + result = ir.BitwiseNot(result); + } + const IR::U1 result_u1 = ir.InverseBallot(result); + ir.SetExec(result_u1); + ir.SetScc(result_u1); +} + +void Translator::S_ABS_I32(const GcnInst& inst) { + const auto result = ir.IAbs(GetSrc(inst.src[0])); + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + +// SOPC + +void Translator::S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst) { + const IR::U32 lhs = GetSrc(inst.src[0]); + const IR::U32 rhs = GetSrc(inst.src[1]); + const IR::U1 result = [&] { + switch (cond) { + case ConditionOp::EQ: + return ir.IEqual(lhs, rhs); + case ConditionOp::LG: + return ir.INotEqual(lhs, rhs); + case ConditionOp::GT: + return ir.IGreaterThan(lhs, rhs, is_signed); + case ConditionOp::GE: + return ir.IGreaterThanEqual(lhs, rhs, is_signed); + case ConditionOp::LT: + return ir.ILessThan(lhs, rhs, is_signed); + case ConditionOp::LE: + return ir.ILessThanEqual(lhs, rhs, is_signed); + default: + UNREACHABLE(); + } + }(); + ir.SetScc(result); +} + +void Translator::S_BITCMP(bool compare_mode, u32 bits, const GcnInst& inst) { + const IR::U1 result = [&] { + const IR::U32 src1 = GetSrc(inst.src[1]); + const IR::U32 mask = ir.Imm32(bits == 64 ? 0x3f : 0x1f); + const IR::U32 bitpos{ir.BitwiseAnd(src1, mask)}; + const IR::U32 bittest = [&]() -> IR::U32 { + if (bits == 64) { + const IR::U64 src0 = GetSrc64(inst.src[0]); + const IR::U64 bit{ + ir.BitwiseAnd(ir.ShiftRightLogical(src0, bitpos), ir.Imm64(u64(1)))}; + return ir.UConvert(32, bit); + } + if (bits != 32) { + UNREACHABLE(); + } + const IR::U32 src0 = GetSrc(inst.src[0]); + return ir.BitwiseAnd(ir.ShiftRightLogical(src0, bitpos), ir.Imm32(1)); + }(); + + if (!compare_mode) { + return ir.IEqual(bittest, ir.Imm32(0)); + } else { + return ir.IEqual(bittest, ir.Imm32(1)); + } + }(); + ir.SetScc(result); +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/scalar_flow.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/scalar_flow.cpp new file mode 100644 index 0000000..8e0cbb8 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/scalar_flow.cpp @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/opcodes.h" +#include "shader_recompiler/frontend/translate/translate.h" + +namespace Shader::Gcn { + +void Translator::EmitFlowControl(const GcnInst& inst) { + switch (inst.opcode) { + case Opcode::S_BARRIER: + return S_BARRIER(); + case Opcode::S_TTRACEDATA: + LOG_WARNING(Render_Vulkan, "S_TTRACEDATA instruction!"); + return; + case Opcode::S_SETPRIO: + LOG_WARNING(Render_Vulkan, "S_SETPRIO instruction!"); + return; + case Opcode::S_TRAP: + LOG_WARNING(Render_Vulkan, "S_TRAP instruction!"); + return; + case Opcode::S_GETPC_B64: + return S_GETPC_B64(inst); + case Opcode::S_SETPC_B64: + case Opcode::S_WAITCNT: + case Opcode::S_NOP: + case Opcode::S_ENDPGM: + case Opcode::S_CBRANCH_EXECZ: + case Opcode::S_CBRANCH_SCC0: + case Opcode::S_CBRANCH_SCC1: + case Opcode::S_CBRANCH_VCCNZ: + case Opcode::S_CBRANCH_VCCZ: + case Opcode::S_CBRANCH_EXECNZ: + case Opcode::S_BRANCH: + return; + case Opcode::S_SENDMSG: + S_SENDMSG(inst); + return; + default: + UNREACHABLE(); + } +} + +void Translator::S_BARRIER() { + ir.Barrier(); +} + +void Translator::S_GETPC_B64(const GcnInst& inst) { + const IR::ScalarReg dst{inst.dst[0].code}; + ir.SetScalarReg(dst, ir.GetPcLo(ir.Imm32(pc))); + ir.SetScalarReg(dst + 1, ir.Imm32(0)); +} + +void Translator::S_SENDMSG(const GcnInst& inst) { + const auto& simm = reinterpret_cast(inst.control.sopp.simm); + switch (simm.msg) { + case SendMsgSimm::Message::Gs: { + switch (simm.op) { + case SendMsgSimm::GsOp::Nop: + break; + case SendMsgSimm::GsOp::Cut: + ir.EmitPrimitive(); + break; + case SendMsgSimm::GsOp::Emit: + ir.EmitVertex(); + break; + default: + UNREACHABLE(); + } + break; + } + case SendMsgSimm::Message::GsDone: { + break; + } + default: + UNREACHABLE(); + } +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/scalar_memory.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/scalar_memory.cpp new file mode 100644 index 0000000..235ca33 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/scalar_memory.cpp @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/translate/translate.h" + +namespace Shader::Gcn { + +static constexpr u32 SQ_SRC_LITERAL = 0xFF; + +void Translator::EmitScalarMemory(const GcnInst& inst) { + switch (inst.opcode) { + // SMRD + case Opcode::S_LOAD_DWORD: + return S_LOAD_DWORD(1, inst); + case Opcode::S_LOAD_DWORDX2: + return S_LOAD_DWORD(2, inst); + case Opcode::S_LOAD_DWORDX4: + return S_LOAD_DWORD(4, inst); + case Opcode::S_LOAD_DWORDX8: + return S_LOAD_DWORD(8, inst); + case Opcode::S_LOAD_DWORDX16: + return S_LOAD_DWORD(16, inst); + case Opcode::S_BUFFER_LOAD_DWORD: + return S_BUFFER_LOAD_DWORD(1, inst); + case Opcode::S_BUFFER_LOAD_DWORDX2: + return S_BUFFER_LOAD_DWORD(2, inst); + case Opcode::S_BUFFER_LOAD_DWORDX4: + return S_BUFFER_LOAD_DWORD(4, inst); + case Opcode::S_BUFFER_LOAD_DWORDX8: + return S_BUFFER_LOAD_DWORD(8, inst); + case Opcode::S_BUFFER_LOAD_DWORDX16: + return S_BUFFER_LOAD_DWORD(16, inst); + case Opcode::S_MEMTIME: + return S_MEMTIME(inst); + default: + LogMissingOpcode(inst); + } +} + +// SMRD + +void Translator::S_LOAD_DWORD(int num_dwords, const GcnInst& inst) { + const auto& smrd = inst.control.smrd; + const IR::ScalarReg sbase{inst.src[0].code * 2}; + const IR::U32 dword_offset = [&] -> IR::U32 { + if (smrd.imm) { + return ir.Imm32(smrd.offset); + } + if (smrd.offset == SQ_SRC_LITERAL) { + return ir.Imm32(inst.src[1].code); + } + return ir.ShiftRightLogical(ir.GetScalarReg(IR::ScalarReg(smrd.offset)), ir.Imm32(2)); + }(); + const IR::Value base = + ir.CompositeConstruct(ir.GetScalarReg(sbase), ir.GetScalarReg(sbase + 1)); + IR::ScalarReg dst_reg{inst.dst[0].code}; + for (u32 i = 0; i < num_dwords; i++) { + IR::U32 index = ir.IAdd(dword_offset, ir.Imm32(i)); + ir.SetScalarReg(dst_reg + i, ir.ReadConst(base, index)); + } +} + +void Translator::S_BUFFER_LOAD_DWORD(int num_dwords, const GcnInst& inst) { + const auto& smrd = inst.control.smrd; + const IR::ScalarReg sbase{inst.src[0].code * 2}; + const IR::U32 dword_offset = [&] -> IR::U32 { + if (smrd.imm) { + return ir.Imm32(smrd.offset); + } + if (smrd.offset == SQ_SRC_LITERAL) { + return ir.Imm32(inst.src[1].code); + } + return ir.ShiftRightLogical(ir.GetScalarReg(IR::ScalarReg(smrd.offset)), ir.Imm32(2)); + }(); + + IR::BufferInstInfo buffer_info{}; + buffer_info.pc.Assign(pc); + + const IR::Value vsharp = + ir.CompositeConstruct(ir.GetScalarReg(sbase), ir.GetScalarReg(sbase + 1), + ir.GetScalarReg(sbase + 2), ir.GetScalarReg(sbase + 3)); + IR::ScalarReg dst_reg{inst.dst[0].code}; + for (u32 i = 0; i < num_dwords; i++) { + const IR::U32 index = ir.IAdd(dword_offset, ir.Imm32(i)); + ir.SetScalarReg(dst_reg + i, ir.ReadConstBuffer(vsharp, index, buffer_info)); + } +} + +void Translator::S_MEMTIME(const GcnInst& inst) { + SetDst64(inst.dst[0], ir.Memtime()); +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/translate.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/translate.cpp new file mode 100644 index 0000000..49befa7 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/translate.cpp @@ -0,0 +1,1257 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/io_file.h" +#include "common/path_util.h" +#include "core/emulator_settings.h" +#include "shader_recompiler/frontend/fetch_shader.h" +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/condition.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/reinterpret.h" +#include "shader_recompiler/profile.h" +#include "shader_recompiler/runtime_info.h" +#include "video_core/amdgpu/resource.h" + +#include +#include +#include + +namespace Shader::Gcn { + +static IR::VectorReg IterateBarycentrics(const RuntimeInfo& runtime_info, auto&& set_attribute) { + if (runtime_info.hw_stage != HwStage::Fragment) { + return IR::VectorReg::V0; + } + u32 dst_vreg{}; + const auto addr_flags = runtime_info.hw.fs.addr_flags; + if (addr_flags.persp_sample_ena) { + set_attribute(dst_vreg++, IR::Attribute::BaryCoordSmoothSample, 0); // I + set_attribute(dst_vreg++, IR::Attribute::BaryCoordSmoothSample, 1); // J + } + if (addr_flags.persp_center_ena) { + set_attribute(dst_vreg++, IR::Attribute::BaryCoordSmooth, 0); // I + set_attribute(dst_vreg++, IR::Attribute::BaryCoordSmooth, 1); // J + } + if (addr_flags.persp_centroid_ena) { + set_attribute(dst_vreg++, IR::Attribute::BaryCoordSmoothCentroid, 0); // I + set_attribute(dst_vreg++, IR::Attribute::BaryCoordSmoothCentroid, 1); // J + } + if (addr_flags.persp_pull_model_ena) { + set_attribute(dst_vreg++, IR::Attribute::BaryCoordPullModel, 0); // I/W + set_attribute(dst_vreg++, IR::Attribute::BaryCoordPullModel, 1); // J/W + set_attribute(dst_vreg++, IR::Attribute::BaryCoordPullModel, 2); // 1/W + } + if (addr_flags.linear_sample_ena) { + set_attribute(dst_vreg++, IR::Attribute::BaryCoordNoPerspSample, 0); // I + set_attribute(dst_vreg++, IR::Attribute::BaryCoordNoPerspSample, 1); // J + } + if (addr_flags.linear_center_ena) { + set_attribute(dst_vreg++, IR::Attribute::BaryCoordNoPersp, 0); // I + set_attribute(dst_vreg++, IR::Attribute::BaryCoordNoPersp, 1); // J + } + if (addr_flags.linear_centroid_ena) { + set_attribute(dst_vreg++, IR::Attribute::BaryCoordNoPerspCentroid, 0); // I + set_attribute(dst_vreg++, IR::Attribute::BaryCoordNoPerspCentroid, 1); // J + } + if (addr_flags.line_stipple_tex_ena) { + ++dst_vreg; + } + return IR::VectorReg(dst_vreg); +} + +static s8 UdRegFromShOffset(u16 sgpr_offset, HwStage hw_stage) { + static constexpr std::array indirect_sgpr_offsets{0u, 0x4cu, 0u, 0xccu, 0u, 0x14cu}; + if (sgpr_offset) { + const u32 ud_reg = sgpr_offset - indirect_sgpr_offsets[u32(hw_stage)]; + ASSERT_MSG(ud_reg < 16, "Out of bounds indirect SGPR copy"); + return ud_reg; + } + return -1; +} + +Translator::Translator(Info& info_, const RuntimeInfo& runtime_info_, const Profile& profile_) + : info{info_}, runtime_info{runtime_info_}, profile{profile_}, + next_vgpr_num{runtime_info.props.num_allocated_vgprs} { + IterateBarycentrics(runtime_info, [this](u32 vreg, IR::Attribute attrib, u32) { + vgpr_to_interp[vreg] = attrib; + }); +} + +void Translator::EmitPrologue(IR::Block* first_block) { + ir = IR::IREmitter(*first_block, first_block->begin()); + + ir.Prologue(); + ir.SetExec(ir.Imm1(true)); + + // Initialize user data. + IR::ScalarReg dst_sreg = IR::ScalarReg::S0; + for (u32 i = 0; i < runtime_info.props.num_user_data; i++) { + ir.SetScalarReg(dst_sreg, ir.GetUserData(dst_sreg)); + ++dst_sreg; + } + + IR::VectorReg dst_vreg = IR::VectorReg::V0; + switch (info.sw_stage) { + case SwStage::Vertex: { + const s8 base_vertex_sgpr = + UdRegFromShOffset(runtime_info.sw.vs.vertex_sgpr_offset, info.hw_stage); + if (base_vertex_sgpr != -1) { + ir.SetScalarReg(IR::ScalarReg(base_vertex_sgpr), + ir.GetAttributeU32(IR::Attribute::BaseVertex)); + } + const s8 base_instance_sgpr = + UdRegFromShOffset(runtime_info.sw.vs.instance_sgpr_offset, info.hw_stage); + if (base_instance_sgpr != -1) { + ir.SetScalarReg(IR::ScalarReg(base_instance_sgpr), + ir.GetAttributeU32(IR::Attribute::BaseInstance)); + } + + // v0: vertex ID, always present + IR::U32 vertex_id = ir.GetAttributeU32(IR::Attribute::VertexId); + if (base_vertex_sgpr != -1) { + if (!fetch_data || fetch_data->vertex_offset_sgpr == -1) { + vertex_id = ir.ISub(vertex_id, ir.GetAttributeU32(IR::Attribute::BaseVertex)); + } else { + ASSERT_MSG(fetch_data->vertex_offset_sgpr == base_vertex_sgpr, + "Fetch shader in indirect draw uses wrong base vertex"); + } + } + ir.SetVectorReg(dst_vreg++, vertex_id); + + if (info.hw_stage == HwStage::Local) { + // v1: rel patch ID + if (runtime_info.props.num_input_vgprs > 0) { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0)); + } + // v2: unknown + if (runtime_info.props.num_input_vgprs > 1) { + ++dst_vreg; + } + } else { + // v1: instance ID, step rate 0 + if (runtime_info.props.num_input_vgprs > 0) { + if (runtime_info.sw.vs.step_rate_0 != 0) { + ir.SetVectorReg(dst_vreg++, + ir.IDiv(ir.GetAttributeU32(IR::Attribute::InstanceId), + ir.Imm32(runtime_info.sw.vs.step_rate_0))); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0)); + } + } + // v2: instance ID, step rate 1 + if (runtime_info.props.num_input_vgprs > 1) { + if (runtime_info.sw.vs.step_rate_1 != 0) { + ir.SetVectorReg(dst_vreg++, + ir.IDiv(ir.GetAttributeU32(IR::Attribute::InstanceId), + ir.Imm32(runtime_info.sw.vs.step_rate_1))); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0)); + } + } + } + + // v3: instance ID, plain + if (runtime_info.props.num_input_vgprs > 2) { + IR::U32 instance_id = ir.GetAttributeU32(IR::Attribute::InstanceId); + if (base_instance_sgpr != -1) { + if (!fetch_data || fetch_data->instance_offset_sgpr == -1) { + instance_id = + ir.ISub(instance_id, ir.GetAttributeU32(IR::Attribute::BaseInstance)); + } else { + ASSERT_MSG(fetch_data->instance_offset_sgpr == base_instance_sgpr, + "Fetch shader in indirect draw uses wrong base instance"); + } + } + ir.SetVectorReg(dst_vreg++, instance_id); + } + break; + } + case SwStage::Fragment: { + dst_vreg = + IterateBarycentrics(runtime_info, [this](u32 vreg, IR::Attribute attrib, u32 comp) { + if (profile.supports_amd_shader_explicit_vertex_parameter || + profile.supports_fragment_shader_barycentric) { + ir.SetVectorReg(IR::VectorReg(vreg), ir.GetAttribute(attrib, comp)); + } + }); + const auto addr_flags = runtime_info.hw.fs.addr_flags; + const auto en_flags = runtime_info.hw.fs.en_flags; + if (addr_flags.pos_x_float_ena) { + if (en_flags.pos_x_float_ena) { + ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 0)); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f)); + } + } + if (addr_flags.pos_y_float_ena) { + if (en_flags.pos_y_float_ena) { + ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 1)); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f)); + } + } + if (addr_flags.pos_z_float_ena) { + if (en_flags.pos_z_float_ena) { + ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 2)); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f)); + } + } + if (addr_flags.pos_w_float_ena) { + if (en_flags.pos_w_float_ena) { + ir.SetVectorReg(dst_vreg++, + ir.FPRecip(ir.GetAttribute(IR::Attribute::FragCoord, 3))); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f)); + } + } + if (addr_flags.front_face_ena) { + if (en_flags.front_face_ena) { + const IR::U1 front_face = ir.GetAttributeU1(IR::Attribute::IsFrontFace); + if (runtime_info.hw.fs.front_face_all_bits) { + ir.SetVectorReg(dst_vreg++, + IR::U32{ir.Select(front_face, ir.Imm32(1), ir.Imm32(0))}); + } else { + ir.SetVectorReg(dst_vreg++, IR::F32{ir.Select(front_face, ir.Imm32(1.0f), + ir.Imm32(-1.0f))}); + } + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0)); + } + } + if (addr_flags.ancillary_ena) { + if (en_flags.ancillary_ena) { + ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::PackedAncillary)); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0)); + } + } + if (addr_flags.sample_coverage_ena) { + if (en_flags.sample_coverage_ena) { + const u32 num_samples = std::clamp(runtime_info.hw.fs.num_samples, 1U, 16U); + IR::U32 coverage = ir.Imm32(1U); + if (num_samples > 1) { + const u32 valid_samples = (1U << num_samples) - 1U; + coverage = ir.BitwiseAnd(ir.GetAttributeU32(IR::Attribute::SampleMask), + ir.Imm32(valid_samples)); + } + const IR::U1 is_helper = ir.GetAttributeU1(IR::Attribute::IsHelperInvocation); + ir.SetVectorReg(dst_vreg++, IR::U32{ir.Select(is_helper, ir.Imm32(0U), coverage)}); + } else { + ir.SetVectorReg(dst_vreg++, ir.Imm32(0)); + } + } + break; + } + case SwStage::TessellationControl: { + ir.SetVectorReg(IR::VectorReg::V0, ir.GetAttributeU32(IR::Attribute::PrimitiveId)); + // Should be laid out like: + // [0:8]: patch id within VGT + // [8:12]: output control point id + ir.SetVectorReg(IR::VectorReg::V1, + ir.GetAttributeU32(IR::Attribute::PackedHullInvocationInfo)); + + if (runtime_info.sw.tcs.offchip_lds_enable) { + // No off-chip tessellation has been observed yet. If this survives dead code elim, + // revisit + ir.SetScalarReg(dst_sreg++, ir.GetAttributeU32(IR::Attribute::OffChipLdsBase)); + } + ir.SetScalarReg(dst_sreg++, ir.GetAttributeU32(IR::Attribute::TessFactorsBufferBase)); + + break; + } + case SwStage::TessellationEval: + ir.SetVectorReg(IR::VectorReg::V0, + ir.GetAttribute(IR::Attribute::TessellationEvaluationPointU)); + ir.SetVectorReg(IR::VectorReg::V1, + ir.GetAttribute(IR::Attribute::TessellationEvaluationPointV)); + // V2 is similar to PrimitiveID but not the same. It seems to only be used in + // compiler-generated address calculations. Its probably the patch id within the + // patches running locally on a given VGT (or CU, whichever is the granularity of LDS + // memory) + // Set to 0. See explanation in comment describing hull/domain passes + ir.SetVectorReg(IR::VectorReg::V2, ir.Imm32(0u)); + // V3 is the actual PrimitiveID as intended by the shader author. + ir.SetVectorReg(IR::VectorReg::V3, ir.GetAttributeU32(IR::Attribute::PrimitiveId)); + break; + case SwStage::Compute: + ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::LocalInvocationId, 0)); + ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::LocalInvocationId, 1)); + ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::LocalInvocationId, 2)); + + if (runtime_info.hw.cs.tgid_enable[0]) { + ir.SetScalarReg(dst_sreg++, ir.GetAttributeU32(IR::Attribute::WorkgroupId, 0)); + } + if (runtime_info.hw.cs.tgid_enable[1]) { + ir.SetScalarReg(dst_sreg++, ir.GetAttributeU32(IR::Attribute::WorkgroupId, 1)); + } + if (runtime_info.hw.cs.tgid_enable[2]) { + ir.SetScalarReg(dst_sreg++, ir.GetAttributeU32(IR::Attribute::WorkgroupId, 2)); + } + break; + case SwStage::Geometry: + // The GS wave receives one ES vertex offset per input primitive vertex in V0-V6, with + // the primitive id in V2. The offset count is a property of the input primitive type; + // adjacency primitives carry up to 6 vertices. + switch (runtime_info.hw.gs.in_primitive) { + case AmdGpu::PrimitiveType::AdjTriangleList: + case AmdGpu::PrimitiveType::AdjTriangleStrip: + ir.SetVectorReg(IR::VectorReg::V6, ir.Imm32(5u)); // vertex 5 + ir.SetVectorReg(IR::VectorReg::V5, ir.Imm32(4u)); // vertex 4 + [[fallthrough]]; + case AmdGpu::PrimitiveType::AdjLineList: + case AmdGpu::PrimitiveType::AdjLineStrip: + ir.SetVectorReg(IR::VectorReg::V4, ir.Imm32(3u)); // vertex 3 + [[fallthrough]]; + case AmdGpu::PrimitiveType::TriangleList: + case AmdGpu::PrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::RectList: + ir.SetVectorReg(IR::VectorReg::V3, ir.Imm32(2u)); // vertex 2 + [[fallthrough]]; + case AmdGpu::PrimitiveType::LineList: + case AmdGpu::PrimitiveType::LineStrip: + ir.SetVectorReg(IR::VectorReg::V1, ir.Imm32(1u)); // vertex 1 + [[fallthrough]]; + default: + ir.SetVectorReg(IR::VectorReg::V0, ir.Imm32(0u)); // vertex 0 + break; + } + ir.SetVectorReg(IR::VectorReg::V2, ir.GetAttributeU32(IR::Attribute::PrimitiveId)); + break; + default: + UNREACHABLE_MSG("Unknown shader stage"); + } +} + +IR::VectorReg Translator::GetScratchVgpr(u32 offset) { + const auto [it, is_new] = vgpr_map.try_emplace(offset); + if (is_new) { + ASSERT_MSG(next_vgpr_num < 256, "Out of VGPRs"); + const auto new_vgpr = static_cast(next_vgpr_num++); + it->second = new_vgpr; + } + return it->second; +} + +template +T Translator::GetSrc(const InstOperand& operand) { + constexpr bool is_float = std::is_same_v; + + const auto get_imm = [&](auto value) -> T { + if constexpr (is_float) { + return ir.Imm32(std::bit_cast(value)); + } else { + return ir.Imm32(std::bit_cast(value)); + } + }; + + T value{}; + switch (operand.field) { + case OperandField::ScalarGPR: + value = ir.GetScalarReg(IR::ScalarReg(operand.code)); + break; + case OperandField::VectorGPR: + value = ir.GetVectorReg(IR::VectorReg(operand.code)); + break; + case OperandField::ConstZero: + value = get_imm(0U); + break; + case OperandField::SignedConstIntPos: + value = get_imm(operand.code - SignedConstIntPosMin + 1); + break; + case OperandField::SignedConstIntNeg: + value = get_imm(-s32(operand.code) + SignedConstIntNegMin - 1); + break; + case OperandField::LiteralConst: + value = get_imm(operand.code); + break; + case OperandField::ConstFloatPos_1_0: + value = get_imm(1.f); + break; + case OperandField::ConstFloatPos_0_5: + value = get_imm(0.5f); + break; + case OperandField::ConstFloatPos_2_0: + value = get_imm(2.0f); + break; + case OperandField::ConstFloatPos_4_0: + value = get_imm(4.0f); + break; + case OperandField::ConstFloatNeg_0_5: + value = get_imm(-0.5f); + break; + case OperandField::ConstFloatNeg_1_0: + value = get_imm(-1.0f); + break; + case OperandField::ConstFloatNeg_2_0: + value = get_imm(-2.0f); + break; + case OperandField::ConstFloatNeg_4_0: + value = get_imm(-4.0f); + break; + case OperandField::Inv2Pi: + value = get_imm(static_cast(1.0f / (2.0f * std::numbers::pi))); + break; + case OperandField::Sdwa: + UNREACHABLE_MSG("unhandled SDWA"); + case OperandField::Dpp: + UNREACHABLE_MSG("unhandled DPP"); + case OperandField::VccLo: + if constexpr (is_float) { + value = ir.BitCast(ir.GetVccLo()); + } else { + value = ir.GetVccLo(); + } + break; + case OperandField::VccHi: + if constexpr (is_float) { + value = ir.BitCast(ir.GetVccHi()); + } else { + value = ir.GetVccHi(); + } + break; + case OperandField::M0: + if constexpr (is_float) { + value = ir.BitCast(ir.GetM0()); + } else { + value = ir.GetM0(); + } + break; + case OperandField::Scc: + if constexpr (is_float) { + UNREACHABLE(); + } else { + value = IR::U32{ir.Select(ir.GetScc(), ir.Imm32(1u), ir.Imm32(0u))}; + } + break; + case OperandField::ExecLo: + if constexpr (is_float) { + value = ir.BitCast( + IR::U32{ir.CompositeExtract(ir.UnpackUint2x32(ir.Ballot(ir.GetExec())), 0)}); + } else { + value = IR::U32{ir.CompositeExtract(ir.UnpackUint2x32(ir.Ballot(ir.GetExec())), 0)}; + } + break; + case OperandField::ExecHi: + if constexpr (is_float) { + value = ir.BitCast( + IR::U32{ir.CompositeExtract(ir.UnpackUint2x32(ir.Ballot(ir.GetExec())), 1)}); + } else { + value = IR::U32{ir.CompositeExtract(ir.UnpackUint2x32(ir.Ballot(ir.GetExec())), 1)}; + } + break; + default: + UNREACHABLE_MSG("Unexpected operand: {}", std::to_underlying(operand.field)); + } + + if constexpr (is_float) { + if (operand.input_modifier.abs) { + value = ir.FPAbs(value); + } + if (operand.input_modifier.neg) { + value = ir.FPNeg(value); + } + } else { + if (operand.input_modifier.abs) { + value = ir.BitwiseAnd(value, ir.Imm32(0x7FFFFFFFu)); + } + if (operand.input_modifier.neg) { + value = ir.BitwiseXor(value, ir.Imm32(0x80000000u)); + } + } + return value; +} + +template IR::U32 Translator::GetSrc(const InstOperand&); +template IR::F32 Translator::GetSrc(const InstOperand&); + +template +T Translator::GetSrc16(const InstOperand& operand) { + constexpr bool is_float = std::is_same_v; + + const auto get_imm = [&](auto value) -> T { + if constexpr (is_float) { + return ir.Imm32(std::bit_cast(value)); + } else { + return ir.Imm32(std::bit_cast(value)); + } + }; + + const auto number_format = []() -> AmdGpu::NumberFormat { + if constexpr (is_float) { + return AmdGpu::NumberFormat::Float; + } else { + return AmdGpu::NumberFormat::Uint; + } + }(); + + const auto bitcast_to_u = [&](auto value) -> IR::U32 { + if constexpr (is_float) { + return ir.BitCast(value); + } else { + return value; + } + }; + + const auto cast = [&](auto value) -> T { + if constexpr (is_float) { + return value; + } else { + return ir.BitFieldExtract(ir.BitCast(value), ir.Imm32(0), ir.Imm32(16), + is_signed); + } + }; + + const auto op_sel = operand.op_sel.op_sel; + + T value{}; + switch (operand.field) { + case OperandField::ScalarGPR: { + const auto f = ir.GetScalarReg(IR::ScalarReg(operand.code)); + value = cast(IR::F32{ + ir.CompositeExtract(ir.Unpack2x16(number_format, bitcast_to_u(f)), op_sel ? 1 : 0)}); + break; + } + case OperandField::VectorGPR: { + const auto v = ir.GetVectorReg(IR::VectorReg(operand.code)); + value = cast(IR::F32{ + ir.CompositeExtract(ir.Unpack2x16(number_format, bitcast_to_u(v)), op_sel ? 1 : 0)}); + break; + } + case OperandField::ConstZero: + value = get_imm(0U); + break; + case OperandField::SignedConstIntPos: + value = get_imm(operand.code - SignedConstIntPosMin + 1); + break; + case OperandField::SignedConstIntNeg: + value = get_imm(-s32(operand.code) + SignedConstIntNegMin - 1); + break; + case OperandField::LiteralConst: + value = get_imm(operand.code); + break; + case OperandField::ConstFloatPos_1_0: + value = get_imm(1.f); + break; + case OperandField::ConstFloatPos_0_5: + value = get_imm(0.5f); + break; + case OperandField::ConstFloatPos_2_0: + value = get_imm(2.0f); + break; + case OperandField::ConstFloatPos_4_0: + value = get_imm(4.0f); + break; + case OperandField::ConstFloatNeg_0_5: + value = get_imm(-0.5f); + break; + case OperandField::ConstFloatNeg_1_0: + value = get_imm(-1.0f); + break; + case OperandField::ConstFloatNeg_2_0: + value = get_imm(-2.0f); + break; + case OperandField::ConstFloatNeg_4_0: + value = get_imm(-4.0f); + break; + case OperandField::Inv2Pi: + value = get_imm(static_cast(1.0f / (2.0f * std::numbers::pi))); + break; + case OperandField::Sdwa: + LOG_ERROR(Render_Recompiler, "unhandled SDWA"); + value = get_imm(0U); + break; + case OperandField::Dpp: + LOG_ERROR(Render_Recompiler, "unhandled DPP"); + value = get_imm(0U); + break; + case OperandField::VccLo: + if constexpr (is_float) { + value = IR::F32{ + ir.CompositeExtract(ir.Unpack2x16(number_format, ir.GetVccLo()), op_sel ? 1 : 0)}; + } else { + value = cast(IR::F32{ir.CompositeExtract( + ir.Unpack2x16(number_format, bitcast_to_u(ir.GetVccLo())), op_sel ? 1 : 0)}); + } + break; + default: + UNREACHABLE_MSG("Unexpected operand: {}", std::to_underlying(operand.field)); + } + + if constexpr (is_float) { + if (operand.input_modifier.abs) { + value = ir.FPAbs(value); + } + if (operand.input_modifier.neg) { + value = ir.FPNeg(value); + } + } else { + if (operand.input_modifier.abs) { + value = ir.BitwiseAnd(value, ir.Imm32(0x7FFFFFFFu)); + } + if (operand.input_modifier.neg) { + value = ir.BitwiseXor(value, ir.Imm32(0x80000000u)); + } + } + return value; +} + +template IR::U32 Translator::GetSrc16(const InstOperand&); +template IR::U32 Translator::GetSrc16(const InstOperand&); +template IR::F32 Translator::GetSrc16(const InstOperand&); + +IR::F32 Translator::GetSrcMix(const InstOperand& operand) { + const auto get_imm = [&](auto value) -> IR::F32 { + return ir.Imm32(std::bit_cast(value)); + }; + + const auto extract = [&](auto value) -> IR::F32 { + const auto getter_u = [&]() { + if constexpr (std::same_as) { + return ir.GetScalarReg(value); + } else { + return ir.GetVectorReg(value); + } + }(); + if (!operand.op_sel.op_sel_hi) { + if constexpr (std::same_as) { + return ir.GetScalarReg(value); + } else { + return ir.GetVectorReg(value); + } + } else if (operand.op_sel.op_sel) { + return IR::F32{ + ir.CompositeExtract(ir.Unpack2x16(AmdGpu::NumberFormat::Float, getter_u), 1)}; + } else { + return IR::F32{ + ir.CompositeExtract(ir.Unpack2x16(AmdGpu::NumberFormat::Float, getter_u), 0)}; + } + }; + + IR::F32 value{}; + switch (operand.field) { + case OperandField::ScalarGPR: + value = extract(IR::ScalarReg(operand.code)); + break; + case OperandField::VectorGPR: + value = extract(IR::VectorReg(operand.code)); + break; + case OperandField::ConstZero: + value = get_imm(0U); + break; + case OperandField::SignedConstIntPos: + value = get_imm(operand.code - SignedConstIntPosMin + 1); + break; + case OperandField::SignedConstIntNeg: + value = get_imm(-s32(operand.code) + SignedConstIntNegMin - 1); + break; + case OperandField::LiteralConst: + value = get_imm(operand.code); + break; + case OperandField::ConstFloatPos_1_0: + value = get_imm(1.f); + break; + case OperandField::ConstFloatPos_0_5: + value = get_imm(0.5f); + break; + case OperandField::ConstFloatPos_2_0: + value = get_imm(2.0f); + break; + case OperandField::ConstFloatPos_4_0: + value = get_imm(4.0f); + break; + case OperandField::ConstFloatNeg_0_5: + value = get_imm(-0.5f); + break; + case OperandField::ConstFloatNeg_1_0: + value = get_imm(-1.0f); + break; + case OperandField::ConstFloatNeg_2_0: + value = get_imm(-2.0f); + break; + case OperandField::ConstFloatNeg_4_0: + value = get_imm(-4.0f); + break; + case OperandField::VccLo: { + if (!operand.op_sel.op_sel_hi) { + value = ir.BitCast(ir.GetVccLo()); + } else if (operand.op_sel.op_sel) { + value = IR::F32{ + ir.CompositeExtract(ir.Unpack2x16(AmdGpu::NumberFormat::Float, ir.GetVccLo()), 1)}; + } else { + value = IR::F32{ + ir.CompositeExtract(ir.Unpack2x16(AmdGpu::NumberFormat::Float, ir.GetVccLo()), 0)}; + } + break; + } + case OperandField::VccHi: + UNREACHABLE(); + break; + case OperandField::M0: + UNREACHABLE(); + break; + case OperandField::Scc: + UNREACHABLE(); + break; + case OperandField::Inv2Pi: + value = get_imm(static_cast(1.0f / (2.0f * std::numbers::pi))); + break; + default: + UNREACHABLE_MSG("Unexpected operand: {}", std::to_underlying(operand.field)); + } + + if (operand.input_modifier.neg_hi) { + value = ir.FPAbs(value); + } + if (operand.input_modifier.neg) { + value = ir.FPNeg(value); + } + return value; +} + +template +T Translator::GetSrc64(const InstOperand& operand) { + constexpr bool is_float = std::is_same_v; + + const auto get_imm = [&](auto value) -> T { + if constexpr (is_float) { + return ir.Imm64(std::bit_cast(value)); + } else { + return ir.Imm64(std::bit_cast(value)); + } + }; + + T value{}; + switch (operand.field) { + case OperandField::ScalarGPR: { + const auto value_lo = ir.GetScalarReg(IR::ScalarReg(operand.code)); + const auto value_hi = ir.GetScalarReg(IR::ScalarReg(operand.code + 1)); + if constexpr (is_float) { + value = ir.PackDouble2x32(ir.CompositeConstruct(value_lo, value_hi)); + } else { + value = ir.PackUint2x32(ir.CompositeConstruct(value_lo, value_hi)); + } + break; + } + case OperandField::VectorGPR: { + const auto value_lo = ir.GetVectorReg(IR::VectorReg(operand.code)); + const auto value_hi = ir.GetVectorReg(IR::VectorReg(operand.code + 1)); + if constexpr (is_float) { + value = ir.PackDouble2x32(ir.CompositeConstruct(value_lo, value_hi)); + } else { + value = ir.PackUint2x32(ir.CompositeConstruct(value_lo, value_hi)); + } + break; + } + case OperandField::ConstZero: + value = get_imm(0ULL); + break; + case OperandField::SignedConstIntPos: + value = get_imm(s64(operand.code) - SignedConstIntPosMin + 1); + break; + case OperandField::SignedConstIntNeg: + value = get_imm(-s64(operand.code) + SignedConstIntNegMin - 1); + break; + case OperandField::LiteralConst: + value = get_imm(u64(operand.code)); + break; + case OperandField::ConstFloatPos_1_0: + value = get_imm(1.0); + break; + case OperandField::ConstFloatPos_0_5: + value = get_imm(0.5); + break; + case OperandField::ConstFloatPos_2_0: + value = get_imm(2.0); + break; + case OperandField::ConstFloatPos_4_0: + value = get_imm(4.0); + break; + case OperandField::ConstFloatNeg_0_5: + value = get_imm(-0.5); + break; + case OperandField::ConstFloatNeg_1_0: + value = get_imm(-1.0); + break; + case OperandField::ConstFloatNeg_2_0: + value = get_imm(-2.0); + break; + case OperandField::ConstFloatNeg_4_0: + value = get_imm(-4.0); + break; + case OperandField::VccLo: + if constexpr (is_float) { + value = ir.PackDouble2x32(ir.CompositeConstruct(ir.GetVccLo(), ir.GetVccHi())); + } else { + value = ir.PackUint2x32(ir.CompositeConstruct(ir.GetVccLo(), ir.GetVccHi())); + } + break; + case OperandField::ExecLo: + if constexpr (is_float) { + UNREACHABLE(); + } else { + value = ir.Ballot(ir.GetExec()); + } + break; + default: + UNREACHABLE_MSG("Unexpected operand: {}", std::to_underlying(operand.field)); + } + + if constexpr (is_float) { + if (operand.input_modifier.abs) { + value = ir.FPAbs(value); + } + if (operand.input_modifier.neg) { + value = ir.FPNeg(value); + } + } else { + // GCN VOP3 abs/neg modifier bits operate on the sign bit (bit 63 for + // 64-bit values). Unpack, modify the high dword's bit 31, repack. + if (operand.input_modifier.abs) { + const auto unpacked = ir.UnpackUint2x32(value); + const auto lo = IR::U32{ir.CompositeExtract(unpacked, 0)}; + const auto hi = IR::U32{ir.CompositeExtract(unpacked, 1)}; + const auto hi_abs = ir.BitwiseAnd(hi, ir.Imm32(0x7FFFFFFFu)); + value = ir.PackUint2x32(ir.CompositeConstruct(lo, hi_abs)); + } + if (operand.input_modifier.neg) { + const auto unpacked = ir.UnpackUint2x32(value); + const auto lo = IR::U32{ir.CompositeExtract(unpacked, 0)}; + const auto hi = IR::U32{ir.CompositeExtract(unpacked, 1)}; + const auto hi_neg = ir.BitwiseXor(hi, ir.Imm32(0x80000000u)); + value = ir.PackUint2x32(ir.CompositeConstruct(lo, hi_neg)); + } + } + return value; +} + +template IR::U64 Translator::GetSrc64(const InstOperand&); +template IR::F64 Translator::GetSrc64(const InstOperand&); + +template +pk_type Translator::GetSrcPk(const InstOperand& operand) { + constexpr bool is_float = std::is_same_v; + + const auto get_imm = [&](auto value) -> pk_type { + if constexpr (is_float) { + auto imm = ir.Imm32(std::bit_cast(value)); + return {operand.op_sel.op_sel ? ir.Imm32(0.f) : imm, + operand.op_sel.op_sel_hi ? ir.Imm32(0.f) : imm}; + } else { + auto imm = ir.Imm32(std::bit_cast(value)); + return {operand.op_sel.op_sel ? ir.Imm32(0U) : imm, + operand.op_sel.op_sel_hi ? ir.Imm32(0U) : imm}; + } + }; + + constexpr auto number_format = [&]() { + if constexpr (is_float) { + return AmdGpu::NumberFormat::Float; + } else { + return AmdGpu::NumberFormat::Uint; + } + }(); + + const auto cast = [&](auto value) -> T { + if constexpr (is_float) { + return value; + } else { + return ir.BitFieldExtract(ir.BitCast(value), ir.Imm32(0), ir.Imm32(16), + is_signed); + } + }; + + const auto extract = [&](auto value) -> pk_type { + auto v_unpacked = ir.Unpack2x16(number_format, value); + return {cast(IR::F32{ir.CompositeExtract(v_unpacked, operand.op_sel.op_sel)}), + cast(IR::F32{ir.CompositeExtract(v_unpacked, operand.op_sel.op_sel_hi)})}; + }; + + pk_type value{}; + switch (operand.field) { + case OperandField::ScalarGPR: { + value = extract(ir.GetScalarReg(IR::ScalarReg(operand.code))); + break; + } + case OperandField::VectorGPR: { + value = extract(ir.GetVectorReg(IR::VectorReg(operand.code))); + break; + } + case OperandField::ConstZero: { + value = get_imm(0U); + break; + } + case OperandField::SignedConstIntPos: { + value = get_imm(operand.code - SignedConstIntPosMin + 1); + break; + } + case OperandField::SignedConstIntNeg: { + value = get_imm(-s32(operand.code) + SignedConstIntNegMin - 1); + break; + } + case OperandField::LiteralConst: { + value = get_imm(operand.code); + break; + } + case OperandField::ConstFloatPos_1_0: { + value = get_imm(1.f); + break; + } + case OperandField::ConstFloatPos_0_5: { + value = get_imm(0.5f); + break; + } + case OperandField::ConstFloatPos_2_0: { + value = get_imm(2.0f); + break; + } + case OperandField::ConstFloatPos_4_0: { + value = get_imm(4.0f); + break; + } + case OperandField::ConstFloatNeg_0_5: { + value = get_imm(-0.5f); + break; + } + case OperandField::ConstFloatNeg_1_0: { + value = get_imm(-1.0f); + break; + } + case OperandField::ConstFloatNeg_2_0: { + value = get_imm(-2.0f); + break; + } + case OperandField::ConstFloatNeg_4_0: { + value = get_imm(-4.0f); + break; + } + case OperandField::Inv2Pi: { + value = get_imm(1.0f / (2.0f * std::numbers::pi_v)); + break; + } + case OperandField::VccLo: + value = extract(ir.GetVccLo()); + break; + default: + UNREACHABLE_MSG("Unexpected operand: {}", std::to_underlying(operand.field)); + } + + if constexpr (is_float) { + if (operand.input_modifier.neg) { + value.first = ir.FPNeg(value.first); + } + if (operand.input_modifier.neg_hi) { + value.second = ir.FPNeg(value.second); + } + } else { + if (operand.input_modifier.neg) { + value.first = ir.INeg(value.first); + } + if (operand.input_modifier.neg_hi) { + value.second = ir.INeg(value.second); + } + } + return value; +} + +template pk_type Translator::GetSrcPk(const InstOperand&); +template pk_type Translator::GetSrcPk(const InstOperand&); +template pk_type Translator::GetSrcPk(const InstOperand&); + +void Translator::SetDst(const InstOperand& operand, const IR::U32F32& value) { + IR::U32F32 result = value; + if (value.Type() == IR::Type::F32) { + if (operand.output_modifier.multiplier != 0.f) { + result = ir.FPMul(result, ir.Imm32(operand.output_modifier.multiplier)); + } + if (operand.output_modifier.clamp) { + result = ir.FPSaturate(result); + } + } + + switch (operand.field) { + case OperandField::ScalarGPR: + return ir.SetScalarReg(IR::ScalarReg(operand.code), result); + case OperandField::VectorGPR: + return ir.SetVectorReg(IR::VectorReg(operand.code), result); + case OperandField::VccLo: + return ir.SetVccLo(result); + case OperandField::VccHi: + return ir.SetVccHi(result); + case OperandField::M0: + return ir.SetM0(result); + default: + UNREACHABLE_MSG("Unknown field {}", u32(operand.field)); + } +} + +template +void Translator::SetDst16(const InstOperand& operand, const IR::U32F32& value) { + IR::U32F32 result = value; + if (value.Type() == IR::Type::F32) { + if (operand.output_modifier.multiplier != 0.f) { + result = ir.FPMul(result, ir.Imm32(operand.output_modifier.multiplier)); + } + if (operand.output_modifier.clamp) { + result = ir.FPSaturate(result); + } + } else { + if (operand.output_modifier.clamp) { + if constexpr (is_signed) { + result = ir.SClamp(result, ir.Imm32(-32768), ir.Imm32(32767)); + } else { + result = ir.UMin(result, ir.Imm32(0xFFFF)); + } + } + } + + const auto cast = [&](auto value) -> IR::U32 { + if (value.Type() == IR::Type::F32) { + return ir.UConvert(32, ir.BitCast(IR::F16{ir.FPConvert(16, value)})); + } else if (value.Type() == IR::Type::U32) { + return value; + } else { + UNREACHABLE(); + } + }; + + const auto op_sel = operand.op_sel.op_sel; + + switch (operand.field) { + case OperandField::ScalarGPR: { + const auto prev_dst = ir.GetScalarReg(IR::ScalarReg(operand.code)); + const auto result_16 = cast(result); + const auto new_dst = + ir.BitFieldInsert(prev_dst, result_16, ir.Imm32(op_sel ? 16 : 0), ir.Imm32(16)); + return ir.SetScalarReg(IR::ScalarReg(operand.code), new_dst); + } + case OperandField::VectorGPR: { + const auto prev_dst = ir.GetVectorReg(IR::VectorReg(operand.code)); + const auto result_16 = cast(result); + const auto new_dst = + ir.BitFieldInsert(prev_dst, result_16, ir.Imm32(op_sel ? 16 : 0), ir.Imm32(16)); + return ir.SetVectorReg(IR::VectorReg(operand.code), new_dst); + } + default: + UNREACHABLE_MSG("Unexpected operand: {}", std::to_underlying(operand.field)); + } +} + +template void Translator::SetDst16(const InstOperand&, const IR::U32F32& value); +template void Translator::SetDst16(const InstOperand&, const IR::U32F32& value); + +void Translator::SetDst64(const InstOperand& operand, const IR::U64F64& value_raw) { + IR::U64F64 value_untyped = value_raw; + + const bool is_float = value_raw.Type() == IR::Type::F64 || value_raw.Type() == IR::Type::F32; + if (is_float) { + if (operand.output_modifier.multiplier != 0.f) { + value_untyped = + ir.FPMul(value_untyped, ir.Imm64(f64(operand.output_modifier.multiplier))); + } + if (operand.output_modifier.clamp) { + value_untyped = ir.FPSaturate(value_untyped); + } + } + + const auto split = [&] -> std::pair { + const IR::Value unpacked{is_float ? ir.UnpackDouble2x32(IR::F64{value_untyped}) + : ir.UnpackUint2x32(IR::U64{value_untyped})}; + const IR::U32 lo{ir.CompositeExtract(unpacked, 0U)}; + const IR::U32 hi{ir.CompositeExtract(unpacked, 1U)}; + return {lo, hi}; + }; + switch (operand.field) { + case OperandField::ScalarGPR: { + const auto [lo, hi] = split(); + ir.SetScalarReg(IR::ScalarReg(operand.code + 1), hi); + ir.SetScalarReg(IR::ScalarReg(operand.code), lo); + break; + } + case OperandField::VectorGPR: { + const auto [lo, hi] = split(); + ir.SetVectorReg(IR::VectorReg(operand.code + 1), hi); + ir.SetVectorReg(IR::VectorReg(operand.code), lo); + break; + } + case OperandField::VccLo: { + const auto [lo, hi] = split(); + ir.SetVccLo(lo); + ir.SetVccHi(hi); + break; + } + case OperandField::ExecLo: + ir.SetExec(ir.InverseBallot(value_untyped)); + break; + default: + UNREACHABLE_MSG("Unexpected operand: {}", std::to_underlying(operand.field)); + } +} + +template +void Translator::SetDstPk(const InstOperand& operand, const pk_type& value) { + pk_type v = value; + + if constexpr (std::is_same_v) { + if (operand.output_modifier.clamp) { + v = {ir.FPSaturate(v.first), ir.FPSaturate(v.second)}; + } + } else { + if (operand.output_modifier.clamp) { + if constexpr (is_signed) { + auto lower = ir.Imm32(-32768); + auto upper = ir.Imm32(32767); + v = {ir.SClamp(v.first, lower, upper), ir.SClamp(v.second, lower, upper)}; + } else { + auto imm = ir.Imm32(0xFFFF); + v = {ir.UMin(v.first, imm), ir.UMin(v.second, imm)}; + } + } + } + + IR::U32 value_raw{}; + if constexpr (std::is_same_v) { + value_raw = + ir.Pack2x16(AmdGpu::NumberFormat::Float, ir.CompositeConstruct(v.first, v.second)); + } else { + value_raw = ir.Pack2x16(AmdGpu::NumberFormat::Uint, + ir.CompositeConstruct(ir.BitCast(v.first), + ir.BitCast(v.second))); + } + SetDst(operand, value_raw); +} + +template void Translator::SetDstPk(const InstOperand& operand, + const pk_type& value); +template void Translator::SetDstPk(const InstOperand& operand, + const pk_type& value); +template void Translator::SetDstPk(const InstOperand& operand, + const pk_type& value); + +void Translator::EmitFetch(const GcnInst& inst) { + const auto code_sgpr_base = inst.src[0].code; + +#if 0 + // Translate fetch shader inline using regular buffer bindings; useful for debugging. + const auto* code = GetFetchShaderCode(info, code_sgpr_base); + GcnCodeSlice slice(code, code + std::numeric_limits::max()); + GcnDecodeContext decoder; + + // Decode and save instructions + while (!slice.atEnd()) { + const auto sub_inst = decoder.decodeInstruction(slice); + if (sub_inst.opcode == Opcode::S_SETPC_B64) { + // Assume we're swapping back to the main shader. + break; + } + TranslateInstruction(sub_inst); + } + return; +#endif + + info.has_fetch_shader = true; + info.fetch_shader_sgpr_base = code_sgpr_base; + + fetch_data = ParseFetchShader(info); + ASSERT(fetch_data.has_value()); + + if (EmulatorSettings.IsDumpShaders()) { + using namespace Common::FS; + const auto dump_dir = GetUserPath(PathType::ShaderDir) / "dumps"; + if (!std::filesystem::exists(dump_dir)) { + std::filesystem::create_directories(dump_dir); + } + const auto filename = fmt::format("vs_{:#018x}.fetch.bin", info.pgm_hash); + const auto file = IOFile{dump_dir / filename, FileAccessMode::Create}; + const auto* code = GetFetchShaderCode(info, code_sgpr_base); + file.WriteRaw(code, fetch_data->size); + } + + for (const auto& attrib : fetch_data->attributes) { + const IR::Attribute attr{IR::Attribute::Param0 + attrib.semantic}; + IR::VectorReg dst_reg{attrib.dest_vgpr}; + + // Read the V# of the attribute to figure out component number and type. + const auto buffer = attrib.GetSharp(info); + const auto values = + ir.CompositeConstruct(ir.GetAttribute(attr, 0), ir.GetAttribute(attr, 1), + ir.GetAttribute(attr, 2), ir.GetAttribute(attr, 3)); + const auto converted = + IR::ApplyReadNumberConversionVec4(ir, values, buffer.GetNumberConversion()); + const auto swizzled = ApplySwizzle(ir, converted, buffer.DstSelect()); + for (u32 i = 0; i < 4; i++) { + ir.SetVectorReg(dst_reg++, IR::F32{ir.CompositeExtract(swizzled, i)}); + } + } +} + +void Translator::LogMissingOpcode(const GcnInst& inst) { + LOG_ERROR(Render_Recompiler, "Unknown opcode {} ({}, category = {})", + magic_enum::enum_name(inst.opcode), u32(inst.opcode), + magic_enum::enum_name(inst.category)); + info.translation_failed = true; +} + +void Translator::Translate(IR::Block* block, u32 start_pc, IR::Condition cond, + std::span inst_list) { + if (inst_list.empty()) { + return; + } + ir = IR::IREmitter{*block, block->begin()}; + pc = start_pc; + for (const auto& inst : inst_list) { + pc += inst.length; + + // Special case for emitting fetch shader. + if (inst.opcode == Opcode::S_SWAPPC_B64) { + ASSERT(info.hw_stage == HwStage::Vertex || info.hw_stage == HwStage::Export || + info.hw_stage == HwStage::Local); + EmitFetch(inst); + continue; + } + + TranslateInstruction(inst); + } + if (cond != IR::Condition::True && cond != IR::Condition::False) { + block->branch_cond = ir.ConditionRef(ir.Condition(cond)); + } +} + +void Translator::TranslateInstruction(const GcnInst& inst) { + // Emit instructions for each category. + switch (inst.category) { + case InstCategory::DataShare: + EmitDataShare(inst); + break; + case InstCategory::VectorInterpolation: + EmitVectorInterpolation(inst); + break; + case InstCategory::ScalarMemory: + EmitScalarMemory(inst); + break; + case InstCategory::VectorMemory: + EmitVectorMemory(inst); + break; + case InstCategory::Export: + EmitExport(inst); + break; + case InstCategory::FlowControl: + EmitFlowControl(inst); + break; + case InstCategory::ScalarALU: + EmitScalarAlu(inst); + break; + case InstCategory::VectorALU: + EmitVectorAlu(inst); + break; + case InstCategory::DebugProfile: + break; + default: + UNREACHABLE(); + } +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/translate.h b/gpu/shadps4/shader_recompiler/frontend/translate/translate.h new file mode 100644 index 0000000..92c1379 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/translate.h @@ -0,0 +1,401 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "shader_recompiler/frontend/fetch_shader.h" +#include "shader_recompiler/frontend/instruction.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/condition.h" +#include "shader_recompiler/ir/ir_emitter.h" + +namespace Shader { +struct Info; +struct Profile; +} // namespace Shader + +namespace Shader::Gcn { + +enum class ConditionOp : u32 { + F, + EQ, + LG, // NE + GT, + GE, + LT, + LE, + TRU, + U, +}; + +enum class AtomicOp : u32 { + Swap, + CmpSwap, + Add, + Sub, + Smin, + Umin, + Smax, + Umax, + And, + Or, + Xor, + Inc, + Dec, + FCmpSwap, + Fmin, + Fmax, +}; + +enum class NegateMode : u32 { + None, + Src1, + Result, +}; + +template +using pk_type = std::pair; + +static constexpr size_t MaxInterpVgpr = 16; + +class Translator { +public: + explicit Translator(Info& info, const RuntimeInfo& runtime_info, const Profile& profile); + + void Translate(IR::Block* block, u32 pc, IR::Condition cond, + std::span inst_list); + void TranslateInstruction(const GcnInst& inst); + + // Instruction categories + void EmitPrologue(IR::Block* first_block); + void EmitFetch(const GcnInst& inst); + void EmitExport(const GcnInst& inst); + void EmitFlowControl(const GcnInst& inst); + void EmitScalarAlu(const GcnInst& inst); + void EmitScalarMemory(const GcnInst& inst); + void EmitVectorAlu(const GcnInst& inst); + void EmitVectorInterpolation(const GcnInst& inst); + void EmitDataShare(const GcnInst& inst); + void EmitVectorMemory(const GcnInst& inst); + + // Instruction encodings + void EmitSOPC(const GcnInst& inst); + void EmitSOPK(const GcnInst& inst); + + // Scalar ALU + // SOP2 + void S_ADD_U32(const GcnInst& inst); + void S_SUB_U32(const GcnInst& inst); + void S_SUBB_U32(const GcnInst& inst); + void S_ADD_I32(const GcnInst& inst); + void S_SUB_I32(const GcnInst& inst); + void S_ADDC_U32(const GcnInst& inst); + void S_MIN_U32(bool is_signed, const GcnInst& inst); + void S_MAX_U32(bool is_signed, const GcnInst& inst); + void S_CSELECT_B32(const GcnInst& inst); + void S_CSELECT_B64(const GcnInst& inst); + void S_AND_B32(NegateMode negate, const GcnInst& inst); + void S_AND_B64(NegateMode negate, const GcnInst& inst); + void S_OR_B32(const GcnInst& inst); + void S_OR_B64(NegateMode negate, bool is_xor, const GcnInst& inst); + void S_XOR_B32(const GcnInst& inst); + void S_LSHL_B32(const GcnInst& inst); + void S_LSHL_B64(const GcnInst& inst); + void S_LSHR_B32(const GcnInst& inst); + void S_ASHR_I32(const GcnInst& inst); + void S_ASHR_I64(const GcnInst& inst); + void S_BFM_B32(const GcnInst& inst); + void S_MUL_I32(const GcnInst& inst); + void S_BFE(const GcnInst& inst, bool is_signed); + void S_BFE_I32(const GcnInst& inst); + void S_ABSDIFF_I32(const GcnInst& inst); + void S_NOT_B32(const GcnInst& inst); + + // SOPK + void S_MOVK(const GcnInst& inst, bool is_conditional); + void S_CMPK(ConditionOp cond, bool is_signed, const GcnInst& inst); + void S_ADDK_I32(const GcnInst& inst); + void S_MULK_I32(const GcnInst& inst); + + // SOP1 + void S_MOV(const GcnInst& inst); + void S_MOV_B64(const GcnInst& inst); + void S_NOT_B64(const GcnInst& inst); + void S_BREV_B32(const GcnInst& inst); + void S_BCNT1_I32_B32(const GcnInst& inst); + void S_BCNT1_I32_B64(const GcnInst& inst); + void S_FF1_I32_B32(const GcnInst& inst); + void S_FF1_I32_B64(const GcnInst& inst); + void S_FLBIT_I32_B32(const GcnInst& inst); + void S_FLBIT_I32_B64(const GcnInst& inst); + void S_BITSET_B32(const GcnInst& inst, u32 bit_value); + void S_BITSET_B64(const GcnInst& inst, u32 bit_value); + void S_GETPC_B64(const GcnInst& inst); + void S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst); + void S_ABS_I32(const GcnInst& inst); + + // SOPC + void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst); + void S_BITCMP(bool compare_mode, u32 bits, const GcnInst& inst); + + // SOPP + void S_BARRIER(); + void S_SENDMSG(const GcnInst& inst); + + // Scalar Memory + // SMRD + void S_LOAD_DWORD(int num_dwords, const GcnInst& inst); + void S_BUFFER_LOAD_DWORD(int num_dwords, const GcnInst& inst); + void S_MEMTIME(const GcnInst& inst); + + // Vector ALU + // VOP2 + void V_CNDMASK_B32(const GcnInst& inst); + void V_READLANE_B32(const GcnInst& inst); + void V_WRITELANE_B32(const GcnInst& inst); + void V_ADD_F32(const GcnInst& inst); + void V_ADD_F64(const GcnInst& inst); + void V_SUB_F32(const GcnInst& inst); + void V_SUBREV_F32(const GcnInst& inst); + void V_MUL_F32(const GcnInst& inst); + void V_MUL_LEGACY_F32(const GcnInst& inst); + void V_MUL_I32_I24(const GcnInst& inst, bool is_signed); + void V_MIN_F32(const GcnInst& inst, bool is_legacy = false); + void V_MAX_F32(const GcnInst& inst, bool is_legacy = false); + void V_MIN_I32(const GcnInst& inst); + void V_MIN_U32(const GcnInst& inst); + void V_MAX_U32(bool is_signed, const GcnInst& inst); + void V_LSHR_B32(const GcnInst& inst); + void V_LSHRREV_B32(const GcnInst& inst); + void V_ASHR_I32(const GcnInst& inst); + void V_ASHRREV_I32(const GcnInst& inst); + void V_LSHL_B32(const GcnInst& inst); + void V_LSHLREV_B32(const GcnInst& inst); + void V_AND_B32(const GcnInst& inst); + void V_OR_B32(bool is_xor, const GcnInst& inst); + void V_BFM_B32(const GcnInst& inst); + void V_MAC_F32(const GcnInst& inst); + void V_MADMK_F32(const GcnInst& inst); + void V_BCNT_U32_B32(const GcnInst& inst); + void V_MBCNT_U32_B32(bool hi, const GcnInst& inst); + void V_ADD_I32(const GcnInst& inst); + void V_SUB_I32(const GcnInst& inst); + void V_SUBREV_I32(const GcnInst& inst); + void V_ADDC_U32(const GcnInst& inst); + void V_SUBB_U32(const GcnInst& inst); + void V_SUBBREV_U32(const GcnInst& inst); + void V_LDEXP_F32(const GcnInst& inst); + void V_CVT_PKNORM_U16_F32(const GcnInst& inst); + void V_CVT_PKNORM_I16_F32(const GcnInst& inst); + void V_CVT_PKRTZ_F16_F32(const GcnInst& inst); + void V_ADD_F16(const GcnInst& inst); + void V_SUB_F16(const GcnInst& inst); + void V_MUL_F16(const GcnInst& inst); + void V_MAX_F16(const GcnInst& inst); + void V_MIN_F16(const GcnInst& inst); + + // VOP1 + void V_MOV(const GcnInst& inst); + void V_READFIRSTLANE_B32(const GcnInst& inst); + void V_CVT_I32_F64(const GcnInst& inst); + void V_CVT_F64_I32(const GcnInst& inst); + void V_CVT_F64_U32(const GcnInst& inst); + void V_CVT_F32_I32(const GcnInst& inst); + void V_CVT_F32_U32(const GcnInst& inst); + void V_CVT_U32_F32(const GcnInst& inst); + void V_CVT_I32_F32(const GcnInst& inst); + void V_CVT_F16_F32(const GcnInst& inst); + void V_CVT_F32_F16(const GcnInst& inst); + void V_CVT_RPI_I32_F32(const GcnInst& inst); + void V_CVT_FLR_I32_F32(const GcnInst& inst); + void V_CVT_OFF_F32_I4(const GcnInst& inst); + void V_CVT_F32_F64(const GcnInst& inst); + void V_CVT_F64_F32(const GcnInst& inst); + void V_CVT_F32_UBYTE(u32 index, const GcnInst& inst); + void V_FLOOR_F64(const GcnInst& inst); + void V_FRACT_F32(const GcnInst& inst); + void V_TRUNC_F32(const GcnInst& inst); + void V_CEIL_F32(const GcnInst& inst); + void V_RNDNE_F32(const GcnInst& inst); + void V_FLOOR_F32(const GcnInst& inst); + void V_EXP_F32(const GcnInst& inst); + void V_LOG_F32(const GcnInst& inst); + void V_RCP_F32(const GcnInst& inst); + void V_RCP_LEGACY_F32(const GcnInst& inst); + void V_RCP_F64(const GcnInst& inst); + void V_RSQ_F32(const GcnInst& inst); + void V_SQRT_F32(const GcnInst& inst); + void V_SIN_F32(const GcnInst& inst); + void V_COS_F32(const GcnInst& inst); + void V_NOT_B32(const GcnInst& inst); + void V_BFREV_B32(const GcnInst& inst); + void V_FFBH_U32(const GcnInst& inst); + void V_FFBH_I32(const GcnInst& inst); + void V_FFBL_B32(const GcnInst& inst); + void V_FREXP_EXP_I32_F64(const GcnInst& inst); + void V_FREXP_MANT_F64(const GcnInst& inst); + void V_FRACT_F64(const GcnInst& inst); + void V_FREXP_EXP_I32_F32(const GcnInst& inst); + void V_FREXP_MANT_F32(const GcnInst& inst); + void V_MOVRELD_B32(const GcnInst& inst); + void V_MOVRELS_B32(const GcnInst& inst); + void V_MOVRELSD_B32(const GcnInst& inst); + + // VOPC + void V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst); + void V_CMP_F64(ConditionOp op, bool set_exec, const GcnInst& inst); + void V_CMP_U32(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst); + void V_CMP_U64(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst); + void V_CMP_CLASS_F32(const GcnInst& inst); + + // VOP3a + void V_MAD_F32(const GcnInst& inst); + void V_MAD_I32_I24(const GcnInst& inst, bool is_signed = true); + void V_MAD_U32_U24(const GcnInst& inst); + void V_CUBEID_F32(const GcnInst& inst); + void V_CUBESC_F32(const GcnInst& inst); + void V_CUBETC_F32(const GcnInst& inst); + void V_CUBEMA_F32(const GcnInst& inst); + void V_BFE_U32(bool is_signed, const GcnInst& inst); + void V_BFI_B32(const GcnInst& inst); + void V_FMA_F32(const GcnInst& inst); + void V_FMA_F64(const GcnInst& inst); + void V_MIN3_F32(const GcnInst& inst); + void V_MIN3_U32(bool is_signed, const GcnInst& inst); + void V_MAX3_F32(const GcnInst& inst); + void V_MAX3_U32(bool is_signed, const GcnInst& inst); + void V_MED3_F32(const GcnInst& inst); + void V_MED3_U32(bool is_signed, const GcnInst& inst); + void V_SAD(const GcnInst& inst); + void V_SAD_U32(const GcnInst& inst); + void V_CVT_PK_U16_U32(const GcnInst& inst); + void V_CVT_PK_I16_I32(const GcnInst& inst); + void V_CVT_PK_U8_F32(const GcnInst& inst); + void V_LSHL_B64(const GcnInst& inst); + void V_LSHR_B64(const GcnInst& inst); + void V_ASHR_I64(const GcnInst& inst); + void V_ALIGNBIT_B32(const GcnInst& inst); + void V_ALIGNBYTE_B32(const GcnInst& inst); + void V_MUL_F64(const GcnInst& inst); + void V_MAX_F64(const GcnInst& inst); + void V_MUL_LO_U32(const GcnInst& inst); + void V_MUL_HI_U32(bool is_signed, const GcnInst& inst); + void V_MAD_U64_U32(const GcnInst& inst); + void V_LSHRREV_B16(const GcnInst& inst); + void V_ASHRREV_I16(const GcnInst& inst); + void V_LSHLREV_B16(const GcnInst& inst); + void V_LSHL_ADD_U32(const GcnInst& inst); + void V_ADD_LSHL_U32(const GcnInst& inst); + void V_MIN3_F16(const GcnInst& inst); + void V_MAX3_F16(const GcnInst& inst); + void V_MED3_F16(const GcnInst& inst); + void V_ADD3_U32(const GcnInst& inst); + void V_LSHL_OR_B32(const GcnInst& inst); + void V_AND_OR_B32(const GcnInst& inst); + void V_OR3_B32(const GcnInst& inst); + + // VOP3P + void V_PK_MUL_LO_U16(const GcnInst& inst); + void V_PK_ADD_I16(const GcnInst& inst); + void V_PK_SUB_I16(const GcnInst& inst); + void V_PK_LSHLREV_B16(const GcnInst& inst); + void V_PK_LSHRREV_B16(const GcnInst& inst); + void V_PK_MAD_U16(const GcnInst& inst); + void V_PK_ADD_U16(const GcnInst& inst); + void V_PK_SUB_U16(const GcnInst& inst); + void V_PK_MAX_U16(const GcnInst& inst); + void V_PK_MIN_U16(const GcnInst& inst); + void V_PK_FMA_F16(const GcnInst& inst); + void V_PK_ADD_F16(const GcnInst& inst); + void V_PK_MUL_F16(const GcnInst& inst); + void V_PK_MIN_F16(const GcnInst& inst); + void V_PK_MAX_F16(const GcnInst& inst); + void V_MAD_MIX_F32(const GcnInst& inst); + void V_MAD_MIXLO_F16(const GcnInst& inst); + void V_MAD_MIXHI_F16(const GcnInst& inst); + + // Vector interpolation + // VINTRP + void V_INTERP_P1_F32(const GcnInst& inst); + void V_INTERP_P2_F32(const GcnInst& inst); + void V_INTERP_MOV_F32(const GcnInst& inst); + + // Data share + // DS + template + void DS_OP(const GcnInst& inst, AtomicOp op, bool rtn); + void DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool stride64, const GcnInst& inst); + void DS_READ(int bit_size, bool is_signed, bool is_pair, bool stride64, const GcnInst& inst); + void DS_SWIZZLE_B32(const GcnInst& inst); + void DS_APPEND(const GcnInst& inst); + void DS_CONSUME(const GcnInst& inst); + void DS_CMPST(int bit_size, bool rtn, const GcnInst& inst); + + // Buffer Memory + // MUBUF / MTBUF + void BUFFER_LOAD(u32 num_dwords, bool is_inst_typed, bool is_buffer_typed, const GcnInst& inst, + u32 scalar_width = 32, bool is_signed = false); + void BUFFER_STORE(u32 num_dwords, bool is_inst_typed, bool is_buffer_typed, const GcnInst& inst, + u32 scalar_width = 32); + template + void BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst); + + // Image Memory + // MIMG + void IMAGE_LOAD(bool has_mip, const GcnInst& inst); + void IMAGE_STORE(bool has_mip, const GcnInst& inst); + void IMAGE_GET_RESINFO(const GcnInst& inst); + void IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst); + void IMAGE_SAMPLE(const GcnInst& inst); + void IMAGE_GATHER(const GcnInst& inst); + void IMAGE_GET_LOD(const GcnInst& inst); + +private: + template + [[nodiscard]] T GetSrc(const InstOperand& operand); + template + [[nodiscard]] T GetSrc16(const InstOperand& operand); + template + [[nodiscard]] T GetSrc64(const InstOperand& operand); + [[nodiscard]] IR::F32 GetSrcMix(const InstOperand& operand); + template + [[nodiscard]] pk_type GetSrcPk(const InstOperand& operand); + void SetDst(const InstOperand& operand, const IR::U32F32& value); + template + void SetDst16(const InstOperand& operand, const IR::U32F32& value); + void SetDst64(const InstOperand& operand, const IR::U64F64& value_raw); + template + void SetDstPk(const InstOperand& operand, const pk_type& value); + + // Vector ALU Helpers + IR::U32 GetCarryIn(const GcnInst& inst); + void SetCarryOut(const GcnInst& inst, const IR::U1& carry); + IR::U32 VMovRelSHelper(u32 src_vgprno, const IR::U32 m0); + void VMovRelDHelper(u32 dst_vgprno, const IR::U32 src_val, const IR::U32 m0); + + IR::F32 SelectCubeResult(const IR::F32& x, const IR::F32& y, const IR::F32& z, + const IR::F32& x_res, const IR::F32& y_res, const IR::F32& z_res); + + void ExportRenderTarget(const GcnInst& inst); + void ExportDepth(const GcnInst& inst); + void LogMissingOpcode(const GcnInst& inst); + + IR::VectorReg GetScratchVgpr(u32 offset); + +private: + IR::IREmitter ir; + Info& info; + const RuntimeInfo& runtime_info; + const Profile& profile; + u32 next_vgpr_num; + std::unordered_map vgpr_map; + std::array vgpr_to_interp{}; + std::optional fetch_data{}; + bool opcode_missing = false; + u32 pc{}; +}; + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/vector_alu.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/vector_alu.cpp new file mode 100644 index 0000000..def1363 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/vector_alu.cpp @@ -0,0 +1,2005 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/opcodes.h" +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Gcn { + +void Translator::EmitVectorAlu(const GcnInst& inst) { + switch (inst.opcode) { + // VOP2 + case Opcode::V_CNDMASK_B32: + return V_CNDMASK_B32(inst); + case Opcode::V_READLANE_B32: + return V_READLANE_B32(inst); + case Opcode::V_WRITELANE_B32: + return V_WRITELANE_B32(inst); + case Opcode::V_ADD_F32: + return V_ADD_F32(inst); + case Opcode::V_SUB_F32: + return V_SUB_F32(inst); + case Opcode::V_SUBREV_F32: + return V_SUBREV_F32(inst); + case Opcode::V_MAC_LEGACY_F32: + return V_MAC_F32(inst); + case Opcode::V_MUL_LEGACY_F32: + return V_MUL_LEGACY_F32(inst); + case Opcode::V_MUL_F32: + return V_MUL_F32(inst); + case Opcode::V_MUL_I32_I24: + return V_MUL_I32_I24(inst, true); + case Opcode::V_MUL_U32_U24: + return V_MUL_I32_I24(inst, false); + case Opcode::V_MIN_LEGACY_F32: + return V_MIN_F32(inst, true); + case Opcode::V_MAX_LEGACY_F32: + return V_MAX_F32(inst, true); + case Opcode::V_MIN_F32: + return V_MIN_F32(inst, false); + case Opcode::V_MAX_F32: + return V_MAX_F32(inst); + case Opcode::V_MIN_I32: + return V_MIN_I32(inst); + case Opcode::V_MAX_I32: + return V_MAX_U32(true, inst); + case Opcode::V_MIN_U32: + return V_MIN_U32(inst); + case Opcode::V_MAX_U32: + return V_MAX_U32(false, inst); + case Opcode::V_LSHR_B32: + return V_LSHR_B32(inst); + case Opcode::V_LSHRREV_B32: + return V_LSHRREV_B32(inst); + case Opcode::V_ASHR_I32: + return V_ASHR_I32(inst); + case Opcode::V_ASHRREV_I32: + return V_ASHRREV_I32(inst); + case Opcode::V_LSHL_B32: + return V_LSHL_B32(inst); + case Opcode::V_LSHLREV_B32: + return V_LSHLREV_B32(inst); + case Opcode::V_AND_B32: + return V_AND_B32(inst); + case Opcode::V_OR_B32: + return V_OR_B32(false, inst); + case Opcode::V_XOR_B32: + return V_OR_B32(true, inst); + case Opcode::V_BFM_B32: + return V_BFM_B32(inst); + case Opcode::V_MAC_F32: + return V_MAC_F32(inst); + case Opcode::V_MADMK_F32: + return V_MADMK_F32(inst); + case Opcode::V_MADAK_F32: + return V_FMA_F32(inst); + case Opcode::V_BCNT_U32_B32: + return V_BCNT_U32_B32(inst); + case Opcode::V_MBCNT_LO_U32_B32: + return V_MBCNT_U32_B32(false, inst); + case Opcode::V_MBCNT_HI_U32_B32: + return V_MBCNT_U32_B32(true, inst); + case Opcode::V_ADD_I32: + return V_ADD_I32(inst); + case Opcode::V_SUB_I32: + return V_SUB_I32(inst); + case Opcode::V_SUBREV_I32: + return V_SUBREV_I32(inst); + case Opcode::V_ADDC_U32: + return V_ADDC_U32(inst); + case Opcode::V_SUBB_U32: + return V_SUBB_U32(inst); + case Opcode::V_SUBBREV_U32: + return V_SUBBREV_U32(inst); + case Opcode::V_LDEXP_F32: + return V_LDEXP_F32(inst); + case Opcode::V_CVT_PKNORM_U16_F32: + return V_CVT_PKNORM_U16_F32(inst); + case Opcode::V_CVT_PKNORM_I16_F32: + return V_CVT_PKNORM_I16_F32(inst); + case Opcode::V_CVT_PKRTZ_F16_F32: + return V_CVT_PKRTZ_F16_F32(inst); + case Opcode::V_ADD_F16: + return V_ADD_F16(inst); + case Opcode::V_SUB_F16: + return V_SUB_F16(inst); + case Opcode::V_MUL_F16: + return V_MUL_F16(inst); + case Opcode::V_MAX_F16: + return V_MAX_F16(inst); + case Opcode::V_MIN_F16: + return V_MIN_F16(inst); + + // VOP1 + case Opcode::V_MOV_B32: + return V_MOV(inst); + case Opcode::V_READFIRSTLANE_B32: + return V_READFIRSTLANE_B32(inst); + case Opcode::V_CVT_I32_F64: + return V_CVT_I32_F64(inst); + case Opcode::V_CVT_F64_I32: + return V_CVT_F64_I32(inst); + case Opcode::V_CVT_F64_U32: + return V_CVT_F64_U32(inst); + case Opcode::V_CVT_F32_I32: + return V_CVT_F32_I32(inst); + case Opcode::V_CVT_F32_U32: + return V_CVT_F32_U32(inst); + case Opcode::V_CVT_U32_F32: + return V_CVT_U32_F32(inst); + case Opcode::V_CVT_I32_F32: + return V_CVT_I32_F32(inst); + case Opcode::V_CVT_F16_F32: + return V_CVT_F16_F32(inst); + case Opcode::V_CVT_F32_F16: + return V_CVT_F32_F16(inst); + case Opcode::V_CVT_FLR_I32_F32: + return V_CVT_FLR_I32_F32(inst); + case Opcode::V_CVT_F32_F64: + return V_CVT_F32_F64(inst); + case Opcode::V_CVT_F64_F32: + return V_CVT_F64_F32(inst); + case Opcode::V_CVT_RPI_I32_F32: + return V_CVT_RPI_I32_F32(inst); + case Opcode::V_CVT_OFF_F32_I4: + return V_CVT_OFF_F32_I4(inst); + case Opcode::V_CVT_F32_UBYTE0: + return V_CVT_F32_UBYTE(0, inst); + case Opcode::V_CVT_F32_UBYTE1: + return V_CVT_F32_UBYTE(1, inst); + case Opcode::V_CVT_F32_UBYTE2: + return V_CVT_F32_UBYTE(2, inst); + case Opcode::V_CVT_F32_UBYTE3: + return V_CVT_F32_UBYTE(3, inst); + case Opcode::V_FLOOR_F64: + return V_FLOOR_F64(inst); + case Opcode::V_FRACT_F32: + return V_FRACT_F32(inst); + case Opcode::V_TRUNC_F32: + return V_TRUNC_F32(inst); + case Opcode::V_CEIL_F32: + return V_CEIL_F32(inst); + case Opcode::V_RNDNE_F32: + return V_RNDNE_F32(inst); + case Opcode::V_FLOOR_F32: + return V_FLOOR_F32(inst); + case Opcode::V_EXP_F32: + return V_EXP_F32(inst); + case Opcode::V_LOG_CLAMP_F32: + return V_LOG_F32(inst); + case Opcode::V_LOG_F32: + return V_LOG_F32(inst); + case Opcode::V_RCP_F32: + return V_RCP_F32(inst); + case Opcode::V_RCP_LEGACY_F32: + return V_RCP_LEGACY_F32(inst); + case Opcode::V_RCP_F64: + return V_RCP_F64(inst); + case Opcode::V_RCP_IFLAG_F32: + return V_RCP_F32(inst); + case Opcode::V_RCP_CLAMP_F32: + return V_RCP_F32(inst); + case Opcode::V_RSQ_CLAMP_F32: + return V_RSQ_F32(inst); + case Opcode::V_RSQ_LEGACY_F32: + return V_RSQ_F32(inst); + case Opcode::V_RSQ_F32: + return V_RSQ_F32(inst); + case Opcode::V_SQRT_F32: + return V_SQRT_F32(inst); + case Opcode::V_SIN_F32: + return V_SIN_F32(inst); + case Opcode::V_COS_F32: + return V_COS_F32(inst); + case Opcode::V_NOT_B32: + return V_NOT_B32(inst); + case Opcode::V_BFREV_B32: + return V_BFREV_B32(inst); + case Opcode::V_FFBH_U32: + return V_FFBH_U32(inst); + case Opcode::V_FFBL_B32: + return V_FFBL_B32(inst); + case Opcode::V_FFBH_I32: + return V_FFBH_I32(inst); + case Opcode::V_FREXP_EXP_I32_F64: + return V_FREXP_EXP_I32_F64(inst); + case Opcode::V_FREXP_MANT_F64: + return V_FREXP_MANT_F64(inst); + case Opcode::V_FRACT_F64: + return V_FRACT_F64(inst); + case Opcode::V_FREXP_EXP_I32_F32: + return V_FREXP_EXP_I32_F32(inst); + case Opcode::V_FREXP_MANT_F32: + return V_FREXP_MANT_F32(inst); + case Opcode::V_MOVRELD_B32: + return V_MOVRELD_B32(inst); + case Opcode::V_MOVRELS_B32: + return V_MOVRELS_B32(inst); + case Opcode::V_MOVRELSD_B32: + return V_MOVRELSD_B32(inst); + + // VOPC + // V_CMP_{OP16}_F32 + case Opcode::V_CMP_F_F32: + return V_CMP_F32(ConditionOp::F, false, inst); + case Opcode::V_CMP_LT_F32: + return V_CMP_F32(ConditionOp::LT, false, inst); + case Opcode::V_CMP_EQ_F32: + return V_CMP_F32(ConditionOp::EQ, false, inst); + case Opcode::V_CMP_LE_F32: + return V_CMP_F32(ConditionOp::LE, false, inst); + case Opcode::V_CMP_GT_F32: + return V_CMP_F32(ConditionOp::GT, false, inst); + case Opcode::V_CMP_LG_F32: + return V_CMP_F32(ConditionOp::LG, false, inst); + case Opcode::V_CMP_GE_F32: + return V_CMP_F32(ConditionOp::GE, false, inst); + case Opcode::V_CMP_U_F32: + return V_CMP_F32(ConditionOp::U, false, inst); + case Opcode::V_CMP_NGE_F32: + return V_CMP_F32(ConditionOp::LT, false, inst); + case Opcode::V_CMP_NGT_F32: + return V_CMP_F32(ConditionOp::LE, false, inst); + case Opcode::V_CMP_NLE_F32: + return V_CMP_F32(ConditionOp::GT, false, inst); + case Opcode::V_CMP_NEQ_F32: + return V_CMP_F32(ConditionOp::LG, false, inst); + case Opcode::V_CMP_NLT_F32: + return V_CMP_F32(ConditionOp::GE, false, inst); + + // V_CMPX_{OP16}_F32 + case Opcode::V_CMPX_F_F32: + return V_CMP_F32(ConditionOp::F, true, inst); + case Opcode::V_CMPX_LT_F32: + return V_CMP_F32(ConditionOp::LT, true, inst); + case Opcode::V_CMPX_EQ_F32: + return V_CMP_F32(ConditionOp::EQ, true, inst); + case Opcode::V_CMPX_LE_F32: + return V_CMP_F32(ConditionOp::LE, true, inst); + case Opcode::V_CMPX_GT_F32: + return V_CMP_F32(ConditionOp::GT, true, inst); + case Opcode::V_CMPX_LG_F32: + return V_CMP_F32(ConditionOp::LG, true, inst); + case Opcode::V_CMPX_GE_F32: + return V_CMP_F32(ConditionOp::GE, true, inst); + case Opcode::V_CMPX_NGE_F32: + return V_CMP_F32(ConditionOp::LT, true, inst); + case Opcode::V_CMPX_NLG_F32: + return V_CMP_F32(ConditionOp::EQ, true, inst); + case Opcode::V_CMPX_NGT_F32: + return V_CMP_F32(ConditionOp::LE, true, inst); + case Opcode::V_CMPX_NLE_F32: + return V_CMP_F32(ConditionOp::GT, true, inst); + case Opcode::V_CMPX_NEQ_F32: + return V_CMP_F32(ConditionOp::LG, true, inst); + case Opcode::V_CMPX_NLT_F32: + return V_CMP_F32(ConditionOp::GE, true, inst); + case Opcode::V_CMPX_TRU_F32: + return V_CMP_F32(ConditionOp::TRU, true, inst); + + // V_CMP_{OP16}_F64 + case Opcode::V_CMP_F_F64: + return V_CMP_F64(ConditionOp::F, false, inst); + case Opcode::V_CMP_LT_F64: + return V_CMP_F64(ConditionOp::LT, false, inst); + case Opcode::V_CMP_EQ_F64: + return V_CMP_F64(ConditionOp::EQ, false, inst); + case Opcode::V_CMP_LE_F64: + return V_CMP_F64(ConditionOp::LE, false, inst); + case Opcode::V_CMP_GT_F64: + return V_CMP_F64(ConditionOp::GT, false, inst); + case Opcode::V_CMP_LG_F64: + return V_CMP_F64(ConditionOp::LG, false, inst); + case Opcode::V_CMP_GE_F64: + return V_CMP_F64(ConditionOp::GE, false, inst); + case Opcode::V_CMP_U_F64: + return V_CMP_F64(ConditionOp::U, false, inst); + case Opcode::V_CMP_NGE_F64: + return V_CMP_F64(ConditionOp::LT, false, inst); + case Opcode::V_CMP_NGT_F64: + return V_CMP_F64(ConditionOp::LE, false, inst); + case Opcode::V_CMP_NLE_F64: + return V_CMP_F64(ConditionOp::GT, false, inst); + case Opcode::V_CMP_NEQ_F64: + return V_CMP_F64(ConditionOp::LG, false, inst); + case Opcode::V_CMP_NLT_F64: + return V_CMP_F64(ConditionOp::GE, false, inst); + + // V_CMP_{OP8}_I32 + case Opcode::V_CMP_LT_I32: + return V_CMP_U32(ConditionOp::LT, true, false, inst); + case Opcode::V_CMP_EQ_I32: + return V_CMP_U32(ConditionOp::EQ, true, false, inst); + case Opcode::V_CMP_LE_I32: + return V_CMP_U32(ConditionOp::LE, true, false, inst); + case Opcode::V_CMP_GT_I32: + return V_CMP_U32(ConditionOp::GT, true, false, inst); + case Opcode::V_CMP_NE_I32: + return V_CMP_U32(ConditionOp::LG, true, false, inst); + case Opcode::V_CMP_GE_I32: + return V_CMP_U32(ConditionOp::GE, true, false, inst); + case Opcode::V_CMPX_LE_I32: + return V_CMP_U32(ConditionOp::LE, true, true, inst); + + // V_CMPX_{OP8}_I32 + case Opcode::V_CMPX_LT_I32: + return V_CMP_U32(ConditionOp::LT, true, true, inst); + case Opcode::V_CMPX_EQ_I32: + return V_CMP_U32(ConditionOp::EQ, true, true, inst); + case Opcode::V_CMPX_GT_I32: + return V_CMP_U32(ConditionOp::GT, true, true, inst); + case Opcode::V_CMPX_LG_I32: + return V_CMP_U32(ConditionOp::LG, true, true, inst); + case Opcode::V_CMPX_GE_I32: + return V_CMP_U32(ConditionOp::GE, true, true, inst); + + // V_CMP_{OP8}_U32 + case Opcode::V_CMP_F_U32: + return V_CMP_U32(ConditionOp::F, false, false, inst); + case Opcode::V_CMP_LT_U32: + return V_CMP_U32(ConditionOp::LT, false, false, inst); + case Opcode::V_CMP_EQ_U32: + return V_CMP_U32(ConditionOp::EQ, false, false, inst); + case Opcode::V_CMP_LE_U32: + return V_CMP_U32(ConditionOp::LE, false, false, inst); + case Opcode::V_CMP_GT_U32: + return V_CMP_U32(ConditionOp::GT, false, false, inst); + case Opcode::V_CMP_NE_U32: + return V_CMP_U32(ConditionOp::LG, false, false, inst); + case Opcode::V_CMP_GE_U32: + return V_CMP_U32(ConditionOp::GE, false, false, inst); + case Opcode::V_CMP_TRU_U32: + return V_CMP_U32(ConditionOp::TRU, false, false, inst); + + // V_CMPX_{OP8}_U32 + case Opcode::V_CMPX_F_U32: + return V_CMP_U32(ConditionOp::F, false, true, inst); + case Opcode::V_CMPX_LT_U32: + return V_CMP_U32(ConditionOp::LT, false, true, inst); + case Opcode::V_CMPX_EQ_U32: + return V_CMP_U32(ConditionOp::EQ, false, true, inst); + case Opcode::V_CMPX_LE_U32: + return V_CMP_U32(ConditionOp::LE, false, true, inst); + case Opcode::V_CMPX_GT_U32: + return V_CMP_U32(ConditionOp::GT, false, true, inst); + case Opcode::V_CMPX_NE_U32: + return V_CMP_U32(ConditionOp::LG, false, true, inst); + case Opcode::V_CMPX_GE_U32: + return V_CMP_U32(ConditionOp::GE, false, true, inst); + case Opcode::V_CMPX_TRU_U32: + return V_CMP_U32(ConditionOp::TRU, false, true, inst); + + // V_CMP_{OP8}_I64 + case Opcode::V_CMP_F_I64: + return V_CMP_U64(ConditionOp::F, true, false, inst); + case Opcode::V_CMP_LT_I64: + return V_CMP_U64(ConditionOp::LT, true, false, inst); + case Opcode::V_CMP_EQ_I64: + return V_CMP_U64(ConditionOp::EQ, true, false, inst); + case Opcode::V_CMP_LE_I64: + return V_CMP_U64(ConditionOp::LE, true, false, inst); + case Opcode::V_CMP_GT_I64: + return V_CMP_U64(ConditionOp::GT, true, false, inst); + case Opcode::V_CMP_NE_I64: + return V_CMP_U64(ConditionOp::LG, true, false, inst); + case Opcode::V_CMP_GE_I64: + return V_CMP_U64(ConditionOp::GE, true, false, inst); + case Opcode::V_CMP_TRU_I64: + return V_CMP_U64(ConditionOp::TRU, true, false, inst); + + // V_CMPX_{OP8}_I64 + case Opcode::V_CMPX_EQ_I64: + return V_CMP_U64(ConditionOp::EQ, true, true, inst); + + // V_CMP_{OP8}_U64 + case Opcode::V_CMP_EQ_U64: + return V_CMP_U64(ConditionOp::EQ, false, false, inst); + case Opcode::V_CMP_NE_U64: + return V_CMP_U64(ConditionOp::LG, false, false, inst); + case Opcode::V_CMP_GT_U64: + return V_CMP_U64(ConditionOp::GT, false, false, inst); + case Opcode::V_CMP_LT_U64: + return V_CMP_U64(ConditionOp::LT, false, false, inst); + + // V_CMPX_{OP8}_U64 + case Opcode::V_CMPX_EQ_U64: + return V_CMP_U64(ConditionOp::EQ, false, true, inst); + case Opcode::V_CMPX_LG_U64: + return V_CMP_U64(ConditionOp::LG, false, true, inst); + + case Opcode::V_CMP_CLASS_F32: + return V_CMP_CLASS_F32(inst); + + // VOP3a + case Opcode::V_MAD_LEGACY_F32: + return V_MAD_F32(inst); + case Opcode::V_MAD_F32: + return V_MAD_F32(inst); + case Opcode::V_MAD_I32_I24: + return V_MAD_I32_I24(inst); + case Opcode::V_MAD_U32_U24: + return V_MAD_U32_U24(inst); + case Opcode::V_CUBEID_F32: + return V_CUBEID_F32(inst); + case Opcode::V_CUBESC_F32: + return V_CUBESC_F32(inst); + case Opcode::V_CUBETC_F32: + return V_CUBETC_F32(inst); + case Opcode::V_CUBEMA_F32: + return V_CUBEMA_F32(inst); + case Opcode::V_BFE_U32: + return V_BFE_U32(false, inst); + case Opcode::V_BFE_I32: + return V_BFE_U32(true, inst); + case Opcode::V_BFI_B32: + return V_BFI_B32(inst); + case Opcode::V_FMA_F32: + return V_FMA_F32(inst); + case Opcode::V_FMA_F64: + return V_FMA_F64(inst); + case Opcode::V_MIN3_F32: + return V_MIN3_F32(inst); + case Opcode::V_MIN3_I32: + return V_MIN3_U32(true, inst); + case Opcode::V_MIN3_U32: + return V_MIN3_U32(false, inst); + case Opcode::V_MAX3_F32: + return V_MAX3_F32(inst); + case Opcode::V_MAX3_I32: + return V_MAX3_U32(true, inst); + case Opcode::V_MAX3_U32: + return V_MAX3_U32(false, inst); + case Opcode::V_MED3_F32: + return V_MED3_F32(inst); + case Opcode::V_MED3_I32: + return V_MED3_U32(true, inst); + case Opcode::V_MED3_U32: + return V_MED3_U32(false, inst); + case Opcode::V_SAD_U32: + return V_SAD_U32(inst); + case Opcode::V_CVT_PK_U16_U32: + return V_CVT_PK_U16_U32(inst); + case Opcode::V_CVT_PK_I16_I32: + return V_CVT_PK_I16_I32(inst); + case Opcode::V_CVT_PK_U8_F32: + return V_CVT_PK_U8_F32(inst); + case Opcode::V_LSHL_B64: + return V_LSHL_B64(inst); + case Opcode::V_LSHR_B64: + return V_LSHR_B64(inst); + case Opcode::V_ASHR_I64: + return V_ASHR_I64(inst); + case Opcode::V_ADD_F64: + return V_ADD_F64(inst); + case Opcode::V_ALIGNBIT_B32: + return V_ALIGNBIT_B32(inst); + case Opcode::V_ALIGNBYTE_B32: + return V_ALIGNBYTE_B32(inst); + case Opcode::V_MUL_F64: + return V_MUL_F64(inst); + case Opcode::V_MAX_F64: + return V_MAX_F64(inst); + case Opcode::V_MUL_LO_U32: + return V_MUL_LO_U32(inst); + case Opcode::V_MUL_HI_U32: + return V_MUL_HI_U32(false, inst); + case Opcode::V_MUL_LO_I32: + return V_MUL_LO_U32(inst); + case Opcode::V_MUL_HI_I32: + return V_MUL_HI_U32(true, inst); + case Opcode::V_MAD_U64_U32: + return V_MAD_U64_U32(inst); + case Opcode::V_LSHRREV_B16: + return V_LSHRREV_B16(inst); + case Opcode::V_ASHRREV_I16: + return V_ASHRREV_I16(inst); + case Opcode::V_LSHLREV_B16: + return V_LSHLREV_B16(inst); + case Opcode::V_ADD_LSHL_U32: + return V_ADD_LSHL_U32(inst); + case Opcode::V_LSHL_ADD_U32: + return V_LSHL_ADD_U32(inst); + case Opcode::V_MIN3_F16: + return V_MIN3_F16(inst); + case Opcode::V_MAX3_F16: + return V_MAX3_F16(inst); + case Opcode::V_MED3_F16: + return V_MED3_F16(inst); + case Opcode::V_ADD3_U32: + return V_ADD3_U32(inst); + case Opcode::V_LSHL_OR_B32: + return V_LSHL_OR_B32(inst); + case Opcode::V_AND_OR_B32: + return V_AND_OR_B32(inst); + case Opcode::V_OR3_B32: + return V_OR3_B32(inst); + case Opcode::V_NOP: + return; + + // VOP3P + case Opcode::V_PK_MUL_LO_U16: + return V_PK_MUL_LO_U16(inst); + case Opcode::V_PK_ADD_I16: + return V_PK_ADD_I16(inst); + case Opcode::V_PK_SUB_I16: + return V_PK_SUB_I16(inst); + case Opcode::V_PK_LSHRREV_B16: + return V_PK_LSHRREV_B16(inst); + case Opcode::V_PK_LSHLREV_B16: + return V_PK_LSHLREV_B16(inst); + case Opcode::V_PK_MAD_U16: + return V_PK_MAD_U16(inst); + case Opcode::V_PK_ADD_U16: + return V_PK_ADD_U16(inst); + case Opcode::V_PK_SUB_U16: + return V_PK_SUB_U16(inst); + case Opcode::V_PK_MAX_U16: + return V_PK_MAX_U16(inst); + case Opcode::V_PK_MIN_U16: + return V_PK_MIN_U16(inst); + case Opcode::V_PK_FMA_F16: + return V_PK_FMA_F16(inst); + case Opcode::V_PK_ADD_F16: + return V_PK_ADD_F16(inst); + case Opcode::V_PK_MUL_F16: + return V_PK_MUL_F16(inst); + case Opcode::V_PK_MIN_F16: + return V_PK_MIN_F16(inst); + case Opcode::V_PK_MAX_F16: + return V_PK_MAX_F16(inst); + case Opcode::V_MAD_MIX_F32: + return V_MAD_MIX_F32(inst); + case Opcode::V_MAD_MIXLO_F16: + return V_MAD_MIXLO_F16(inst); + case Opcode::V_MAD_MIXHI_F16: + return V_MAD_MIXHI_F16(inst); + + default: + LogMissingOpcode(inst); + } +} + +// VOP2 + +void Translator::V_CNDMASK_B32(const GcnInst& inst) { + IR::U64 mask; + if (inst.src[2].field == OperandField::Undefined) { + mask = ir.PackUint2x32(ir.CompositeConstruct(ir.GetVccLo(), ir.GetVccHi())); + } else { + mask = GetSrc64(inst.src[2]); + } + const IR::Value result = ir.Select(ir.InverseBallot(mask), GetSrc(inst.src[1]), + GetSrc(inst.src[0])); + SetDst(inst.dst[0], IR::U32F32{result}); +} + +void Translator::V_ADD_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.FPAdd(src0, src1)); +} + +void Translator::V_ADD_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + const IR::F64 src1{GetSrc64(inst.src[1])}; + SetDst64(inst.dst[0], ir.FPAdd(src0, src1)); +} + +void Translator::V_SUB_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.FPSub(src0, src1)); +} + +void Translator::V_SUBREV_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.FPSub(src1, src0)); +} + +void Translator::V_MUL_F32(const GcnInst& inst) { + SetDst(inst.dst[0], ir.FPMul(GetSrc(inst.src[0]), GetSrc(inst.src[1]))); +} + +void Translator::V_MUL_LEGACY_F32(const GcnInst& inst) { + // GCN V_MUL_LEGACY_F32: if either source is zero, the result is +0.0 + // regardless of the other operand (even if NaN or Inf). + // Standard IEEE multiply would produce NaN for 0 * Inf. + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::F32 zero{ir.Imm32(0.0f)}; + const IR::U1 src0_zero{ir.FPEqual(src0, zero)}; + const IR::U1 src1_zero{ir.FPEqual(src1, zero)}; + const IR::U1 either_zero{ir.LogicalOr(src0_zero, src1_zero)}; + SetDst(inst.dst[0], IR::F32{ir.Select(either_zero, zero, ir.FPMul(src0, src1))}); +} + +void Translator::V_MUL_I32_I24(const GcnInst& inst, bool is_signed) { + const IR::U32 src0{ + ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0), ir.Imm32(24), is_signed)}; + const IR::U32 src1{ + ir.BitFieldExtract(GetSrc(inst.src[1]), ir.Imm32(0), ir.Imm32(24), is_signed)}; + SetDst(inst.dst[0], ir.IMul(src0, src1)); +} + +void Translator::V_MIN_F32(const GcnInst& inst, bool is_legacy) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + + const IR::F32 fpmin = ir.FPMin(src0, src1); + const IR::F32 result = + is_legacy + ? IR::F32{ir.Select(ir.LogicalOr(ir.FPIsNan(src0), ir.FPIsNan(src1)), src1, fpmin)} + : fpmin; + SetDst(inst.dst[0], result); +} + +void Translator::V_MAX_F32(const GcnInst& inst, bool is_legacy) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + + const IR::F32 fpmax = ir.FPMax(src0, src1); + const IR::F32 result = + is_legacy + ? IR::F32{ir.Select(ir.LogicalOr(ir.FPIsNan(src0), ir.FPIsNan(src1)), src1, fpmax)} + : fpmax; + SetDst(inst.dst[0], result); +} + +void Translator::V_MIN_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.SMin(src0, src1)); +} + +void Translator::V_MIN_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.IMin(src0, src1, false)); +} + +void Translator::V_MAX_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.IMax(src0, src1, is_signed)); +} + +void Translator::V_LSHR_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ShiftRightLogical(src0, ir.BitwiseAnd(src1, ir.Imm32(0x1F)))); +} + +void Translator::V_LSHRREV_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ShiftRightLogical(src1, ir.BitwiseAnd(src0, ir.Imm32(0x1F)))); +} + +void Translator::V_ASHR_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ShiftRightArithmetic(src0, ir.BitwiseAnd(src1, ir.Imm32(0x1F)))); +} + +void Translator::V_ASHRREV_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ShiftRightArithmetic(src1, ir.BitwiseAnd(src0, ir.Imm32(0x1F)))); +} + +void Translator::V_LSHL_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm32(0x1F)))); +} + +void Translator::V_LSHLREV_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.ShiftLeftLogical(src1, ir.BitwiseAnd(src0, ir.Imm32(0x1F)))); +} + +void Translator::V_AND_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.BitwiseAnd(src0, src1)); +} + +void Translator::V_OR_B32(bool is_xor, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], + is_xor ? IR::U32{ir.BitwiseXor(src0, src1)} : IR::U32{ir.BitwiseOr(src0, src1)}); +} + +void Translator::V_BFM_B32(const GcnInst& inst) { + // bitmask width + const IR::U32 src0{ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0), ir.Imm32(4))}; + // bitmask offset + const IR::U32 src1{ir.BitFieldExtract(GetSrc(inst.src[1]), ir.Imm32(0), ir.Imm32(4))}; + const IR::U32 ones = ir.ISub(ir.ShiftLeftLogical(ir.Imm32(1), src0), ir.Imm32(1)); + SetDst(inst.dst[0], ir.ShiftLeftLogical(ones, src1)); +} + +void Translator::V_MAC_F32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto dst0 = GetSrc(inst.dst[0]); + SetDst(inst.dst[0], ir.FPAdd(ir.FPMul(src0, src1), dst0)); +} + +void Translator::V_MADMK_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::F32 k{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.FPAdd(ir.FPMul(src0, k), src1)); +} + +void Translator::V_BCNT_U32_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.IAdd(ir.BitCount(src0), src1)); +} + +void Translator::V_MBCNT_U32_B32(bool hi, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.MaskedBitCount(src0, src1, hi)); +} + +void Translator::V_ADD_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.IAdd(src0, src1)}; + SetDst(inst.dst[0], result); + + SetCarryOut(inst, ir.ILessThan(result, src0, false)); +} + +void Translator::V_SUB_I32(const GcnInst& inst) { + // Unsigned components + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.ISub(src0, src1)}; + SetDst(inst.dst[0], result); + + const IR::U1 did_underflow{ir.IGreaterThan(src1, src0, false)}; + SetCarryOut(inst, did_underflow); +} + +void Translator::V_SUBREV_I32(const GcnInst& inst) { + // Unsigned components + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result{ir.ISub(src1, src0)}; + SetDst(inst.dst[0], result); + + const IR::U1 did_underflow{ir.IGreaterThan(src0, src1, false)}; + SetCarryOut(inst, did_underflow); +} + +void Translator::V_ADDC_U32(const GcnInst& inst) { + // Unsigned components + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 carry{GetCarryIn(inst)}; + const IR::Value tmp1{ir.IAddCarry(src0, src1)}; + const IR::U32 result1{ir.CompositeExtract(tmp1, 0)}; + const IR::U32 carry_out1{ir.CompositeExtract(tmp1, 1)}; + const IR::Value tmp2{ir.IAddCarry(result1, carry)}; + const IR::U32 result2{ir.CompositeExtract(tmp2, 0)}; + const IR::U32 carry_out2{ir.CompositeExtract(tmp2, 1)}; + SetDst(inst.dst[0], result2); + + const IR::U1 did_overflow{ir.INotEqual(ir.BitwiseOr(carry_out1, carry_out2), ir.Imm32(0))}; + SetCarryOut(inst, did_overflow); +} + +void Translator::V_SUBB_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 carry{GetCarryIn(inst)}; + const IR::U32 result{ir.ISub(ir.ISub(src0, src1), carry)}; + SetDst(inst.dst[0], result); + + const IR::U1 underflow{ir.IGreaterThan(src1, src0, false)}; + const IR::U32 difference{ir.ISub(src0, src1)}; + const IR::U1 borrow_underflow{ir.IGreaterThan(carry, difference, false)}; + SetCarryOut(inst, ir.LogicalOr(underflow, borrow_underflow)); +} + +void Translator::V_SUBBREV_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 carry{GetCarryIn(inst)}; + const IR::U32 result{ir.ISub(ir.ISub(src1, src0), carry)}; + SetDst(inst.dst[0], result); + + const IR::U1 underflow{ir.IGreaterThan(src0, src1, false)}; + const IR::U32 difference{ir.ISub(src1, src0)}; + const IR::U1 borrow_underflow{ir.IGreaterThan(carry, difference, false)}; + SetCarryOut(inst, ir.LogicalOr(underflow, borrow_underflow)); +} + +void Translator::V_LDEXP_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.FPLdexp(src0, src1)); +} + +void Translator::V_CVT_PKNORM_U16_F32(const GcnInst& inst) { + const IR::Value vec_f32 = + ir.CompositeConstruct(GetSrc(inst.src[0]), GetSrc(inst.src[1])); + SetDst(inst.dst[0], ir.Pack2x16(AmdGpu::NumberFormat::Unorm, vec_f32)); +} + +void Translator::V_CVT_PKNORM_I16_F32(const GcnInst& inst) { + const IR::Value vec_f32 = + ir.CompositeConstruct(GetSrc(inst.src[0]), GetSrc(inst.src[1])); + SetDst(inst.dst[0], ir.Pack2x16(AmdGpu::NumberFormat::Snorm, vec_f32)); +} + +void Translator::V_CVT_PKRTZ_F16_F32(const GcnInst& inst) { + const IR::Value vec_f32 = + ir.CompositeConstruct(GetSrc(inst.src[0]), GetSrc(inst.src[1])); + SetDst(inst.dst[0], ir.Pack2x16(AmdGpu::NumberFormat::Float, vec_f32)); +} + +void Translator::V_ADD_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + + const auto result = ir.FPAdd(src0, src1); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_SUB_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + + const auto result = ir.FPSub(src0, src1); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_MUL_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + + const auto result = ir.FPMul(src0, src1); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_MAX_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + + const auto result = ir.FPMax(src0, src1); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_MIN_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + + const auto result = ir.FPMin(src0, src1); + + SetDst16(inst.dst[0], result); +} + +// VOP1 + +void Translator::V_MOV(const GcnInst& inst) { + SetDst(inst.dst[0], GetSrc(inst.src[0])); +} + +void Translator::V_CVT_I32_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertFToS(32, src0)); +} + +void Translator::V_CVT_F64_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst64(inst.dst[0], ir.ConvertSToF(64, 32, src0)); +} + +void Translator::V_CVT_F64_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst64(inst.dst[0], ir.ConvertUToF(64, 32, src0)); +} + +void Translator::V_CVT_F32_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertSToF(32, 32, src0)); +} + +void Translator::V_CVT_F32_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertUToF(32, 32, src0)); +} + +void Translator::V_CVT_U32_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertFToU(32, src0)); +} + +void Translator::V_CVT_I32_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertFToS(32, src0)); +} + +void Translator::V_CVT_F16_F32(const GcnInst& inst) { + const IR::F32 src0 = GetSrc(inst.src[0]); + + IR::U32 src0fp16; + if (profile.support_float16) { + const IR::F16 converted = ir.FPConvert(16, src0); + src0fp16 = ir.UConvert(32, ir.BitCast(converted)); + } else { + const IR::U32 packed = + ir.Pack2x16(AmdGpu::NumberFormat::Float, ir.CompositeConstruct(src0, ir.Imm32(0.f))); + src0fp16 = ir.BitFieldExtract(packed, ir.Imm32(0U), ir.Imm32(16U)); + } + + SetDst(inst.dst[0], src0fp16); +} + +void Translator::V_CVT_F32_F16(const GcnInst& inst) { + const IR::U32 src0 = GetSrc(inst.src[0]); + + IR::F32 src0l; + if (profile.support_float16) { + const IR::U16 converted = ir.UConvert(16, src0); + src0l = ir.FPConvert(32, ir.BitCast(converted)); + } else { + const IR::Value unpacked = ir.Unpack2x16(AmdGpu::NumberFormat::Float, src0); + src0l = IR::F32{ir.CompositeExtract(unpacked, 0)}; + } + + SetDst(inst.dst[0], src0l); +} + +void Translator::V_CVT_RPI_I32_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertFToI(32, true, ir.FPFloor(ir.FPAdd(src0, ir.Imm32(0.5f))))); +} + +void Translator::V_CVT_FLR_I32_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertFToI(32, true, ir.FPFloor(src0))); +} + +void Translator::V_CVT_OFF_F32_I4(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + ASSERT(src0.IsImmediate()); + static constexpr std::array IntToFloat = { + 0.0f, 0.0625f, 0.1250f, 0.1875f, 0.2500f, 0.3125f, 0.3750f, 0.4375f, + -0.5000f, -0.4375f, -0.3750f, -0.3125f, -0.2500f, -0.1875f, -0.1250f, -0.0625f}; + SetDst(inst.dst[0], ir.Imm32(IntToFloat[src0.U32() & 0xF])); +} + +void Translator::V_CVT_F32_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst(inst.dst[0], ir.FPConvert(32, src0)); +} + +void Translator::V_CVT_F64_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst64(inst.dst[0], ir.FPConvert(64, src0)); +} + +void Translator::V_CVT_F32_UBYTE(u32 index, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 byte = ir.BitFieldExtract(src0, ir.Imm32(8 * index), ir.Imm32(8)); + SetDst(inst.dst[0], ir.ConvertUToF(32, 32, byte)); +} + +void Translator::V_FLOOR_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst64(inst.dst[0], ir.FPFloor(src0)); +} + +void Translator::V_FRACT_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPFract(src0)); +} + +void Translator::V_TRUNC_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPTrunc(src0)); +} + +void Translator::V_CEIL_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPCeil(src0)); +} + +void Translator::V_RNDNE_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPRoundEven(src0)); +} + +void Translator::V_FLOOR_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPFloor(src0)); +} + +void Translator::V_EXP_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPExp2(src0)); +} + +void Translator::V_LOG_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPLog2(src0)); +} + +void Translator::V_RCP_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPRecip(src0)); +} + +void Translator::V_RCP_LEGACY_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const auto result = ir.FPRecip(src0); + const auto inf = ir.FPIsInf(result); + + const auto raw_result = ir.ConvertFToU(32, result); + const auto sign_bit = ir.ShiftRightLogical(raw_result, ir.Imm32(31u)); + const auto sign_bit_set = ir.INotEqual(sign_bit, ir.Imm32(0u)); + const IR::F32 inf_result{ir.Select(sign_bit_set, ir.Imm32(-0.0f), ir.Imm32(0.0f))}; + const IR::F32 val{ir.Select(inf, inf_result, result)}; + + SetDst(inst.dst[0], val); +} + +void Translator::V_RCP_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst64(inst.dst[0], ir.FPRecip(src0)); +} + +void Translator::V_RSQ_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPRecipSqrt(src0)); +} + +void Translator::V_SQRT_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPSqrt(src0)); +} + +void Translator::V_SIN_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPSin(src0)); +} + +void Translator::V_COS_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPCos(src0)); +} + +void Translator::V_NOT_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.BitwiseNot(src0)); +} + +void Translator::V_BFREV_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.BitReverse(src0)); +} + +void Translator::V_FFBH_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + // Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB) + // position + const IR::U32 msb_pos = ir.FindUMsb(src0); + const IR::U32 pos_from_left = ir.ISub(ir.Imm32(31), msb_pos); + // Select 0xFFFFFFFF if src0 was 0 + const IR::U1 cond = ir.INotEqual(src0, ir.Imm32(0)); + SetDst(inst.dst[0], IR::U32{ir.Select(cond, pos_from_left, ir.Imm32(~0U))}); +} + +void Translator::V_FFBL_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FindILsb(src0)); +} + +void Translator::V_FFBH_I32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + // Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB) + // position + const IR::U32 msb_pos = ir.FindSMsb(src0); + const IR::U32 pos_from_left = ir.ISub(ir.Imm32(31), msb_pos); + // Select 0xFFFFFFFF if src0 was 0 or -1 + const IR::U32 minusOne = ir.Imm32(~0U); + const IR::U1 cond = + ir.LogicalAnd(ir.INotEqual(src0, ir.Imm32(0)), ir.INotEqual(src0, minusOne)); + SetDst(inst.dst[0], IR::U32{ir.Select(cond, pos_from_left, minusOne)}); +} + +void Translator::V_FREXP_EXP_I32_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst(inst.dst[0], ir.FPFrexpExp(src0)); +} + +void Translator::V_FREXP_MANT_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst64(inst.dst[0], ir.FPFrexpSig(src0)); +} + +void Translator::V_FRACT_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst64(inst.dst[0], ir.FPFract(src0)); +} + +void Translator::V_FREXP_EXP_I32_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPFrexpExp(src0)); +} + +void Translator::V_FREXP_MANT_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.FPFrexpSig(src0)); +} + +void Translator::V_MOVRELD_B32(const GcnInst& inst) { + const IR::U32 src_val{GetSrc(inst.src[0])}; + u32 dst_vgprno = inst.dst[0].code - static_cast(IR::VectorReg::V0); + IR::U32 m0 = ir.GetM0(); + + VMovRelDHelper(dst_vgprno, src_val, m0); +} + +void Translator::V_MOVRELS_B32(const GcnInst& inst) { + u32 src_vgprno = inst.src[0].code - static_cast(IR::VectorReg::V0); + const IR::U32 m0 = ir.GetM0(); + + const IR::U32 src_val = VMovRelSHelper(src_vgprno, m0); + SetDst(inst.dst[0], src_val); +} + +void Translator::V_MOVRELSD_B32(const GcnInst& inst) { + u32 src_vgprno = inst.src[0].code - static_cast(IR::VectorReg::V0); + u32 dst_vgprno = inst.dst[0].code - static_cast(IR::VectorReg::V0); + IR::U32 m0 = ir.GetM0(); + + const IR::U32 src_val = VMovRelSHelper(src_vgprno, m0); + VMovRelDHelper(dst_vgprno, src_val, m0); +} + +// VOPC + +void Translator::V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::U1 result = [&] { + switch (op) { + case ConditionOp::F: + return ir.Imm1(false); + case ConditionOp::EQ: + return ir.FPEqual(src0, src1); + case ConditionOp::LG: + return ir.FPNotEqual(src0, src1); + case ConditionOp::GT: + return ir.FPGreaterThan(src0, src1); + case ConditionOp::LT: + return ir.FPLessThan(src0, src1); + case ConditionOp::LE: + return ir.FPLessThanEqual(src0, src1); + case ConditionOp::GE: + return ir.FPGreaterThanEqual(src0, src1); + case ConditionOp::U: + return ir.LogicalOr(ir.FPIsNan(src0), ir.FPIsNan(src1)); + default: + UNREACHABLE(); + } + }(); + if (set_exec) { + // V_CMPX evaluates on active lanes only; hardware writes exec & result to both EXEC + // and the VCC/SDST destination, zeroing inactive lanes' bits. + const IR::U1 masked{ir.LogicalAnd(ir.GetExec(), result)}; + ir.SetExec(masked); + SetDst64(inst.dst[1], ir.Ballot(masked)); + return; + } + SetDst64(inst.dst[1], ir.Ballot(result)); +} + +void Translator::V_CMP_F64(ConditionOp op, bool set_exec, const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + const IR::F64 src1{GetSrc64(inst.src[1])}; + const IR::U1 result = [&] { + switch (op) { + case ConditionOp::F: + return ir.Imm1(false); + case ConditionOp::EQ: + return ir.FPEqual(src0, src1); + case ConditionOp::LG: + return ir.FPNotEqual(src0, src1); + case ConditionOp::GT: + return ir.FPGreaterThan(src0, src1); + case ConditionOp::LT: + return ir.FPLessThan(src0, src1); + case ConditionOp::LE: + return ir.FPLessThanEqual(src0, src1); + case ConditionOp::GE: + return ir.FPGreaterThanEqual(src0, src1); + case ConditionOp::U: + return ir.LogicalOr(ir.FPIsNan(src0), ir.FPIsNan(src1)); + default: + UNREACHABLE(); + } + }(); + if (set_exec) { + // See the V_CMPX note in V_CMP_F32. + const IR::U1 masked{ir.LogicalAnd(ir.GetExec(), result)}; + ir.SetExec(masked); + SetDst64(inst.dst[1], ir.Ballot(masked)); + return; + } + SetDst64(inst.dst[1], ir.Ballot(result)); +} + +void Translator::V_CMP_U32(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U1 result = [&] { + switch (op) { + case ConditionOp::F: + return ir.Imm1(false); + case ConditionOp::TRU: + return ir.Imm1(true); + case ConditionOp::EQ: + return ir.IEqual(src0, src1); + case ConditionOp::LG: + return ir.INotEqual(src0, src1); + case ConditionOp::GT: + return ir.IGreaterThan(src0, src1, is_signed); + case ConditionOp::LT: + return ir.ILessThan(src0, src1, is_signed); + case ConditionOp::LE: + return ir.ILessThanEqual(src0, src1, is_signed); + case ConditionOp::GE: + return ir.IGreaterThanEqual(src0, src1, is_signed); + default: + UNREACHABLE(); + } + }(); + if (set_exec) { + // See the V_CMPX note in V_CMP_F32. + const IR::U1 masked{ir.LogicalAnd(ir.GetExec(), result)}; + ir.SetExec(masked); + SetDst64(inst.dst[1], ir.Ballot(masked)); + return; + } + SetDst64(inst.dst[1], ir.Ballot(result)); +} + +void Translator::V_CMP_U64(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + const IR::U1 result = [&] { + switch (op) { + case ConditionOp::F: + return ir.Imm1(false); + case ConditionOp::TRU: + return ir.Imm1(true); + case ConditionOp::EQ: + return ir.IEqual(src0, src1); + case ConditionOp::LG: + return ir.INotEqual(src0, src1); + case ConditionOp::GT: + return ir.IGreaterThan(src0, src1, is_signed); + case ConditionOp::LT: + return ir.ILessThan(src0, src1, is_signed); + case ConditionOp::LE: + return ir.ILessThanEqual(src0, src1, is_signed); + case ConditionOp::GE: + return ir.IGreaterThanEqual(src0, src1, is_signed); + default: + UNREACHABLE(); + } + }(); + if (set_exec) { + // See the V_CMPX note in V_CMP_F32. + const IR::U1 masked{ir.LogicalAnd(ir.GetExec(), result)}; + ir.SetExec(masked); + SetDst64(inst.dst[1], ir.Ballot(masked)); + return; + } + SetDst64(inst.dst[1], ir.Ballot(result)); +} + +void Translator::V_CMP_CLASS_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + IR::U1 value; + if (src1.IsImmediate()) { + const auto class_mask = static_cast(src1.U32()); + if ((class_mask & IR::FloatClassFunc::NaN) == IR::FloatClassFunc::NaN) { + value = ir.FPIsNan(src0); + } else if ((class_mask & IR::FloatClassFunc::Infinity) == IR::FloatClassFunc::Infinity) { + value = ir.FPIsInf(src0); + } else if ((class_mask & IR::FloatClassFunc::Negative) == IR::FloatClassFunc::Negative) { + value = ir.FPLessThanEqual(src0, ir.Imm32(-0.f)); + } else { + UNREACHABLE_MSG("Unsupported float class mask: {:#x}", static_cast(class_mask)); + } + } else { + // We don't know the type yet, delay its resolution. + value = ir.FPCmpClass32(src0, src1); + } + SetDst64(inst.dst[1], ir.Ballot(value)); +} + +// VOP3a + +void Translator::V_MAD_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::F32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.FPAdd(ir.FPMul(src0, src1), src2)); +} + +void Translator::V_MAD_I32_I24(const GcnInst& inst, bool is_signed) { + const IR::U32 src0{ + ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0), ir.Imm32(24), is_signed)}; + const IR::U32 src1{ + ir.BitFieldExtract(GetSrc(inst.src[1]), ir.Imm32(0), ir.Imm32(24), is_signed)}; + const IR::U32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.IAdd(ir.IMul(src0, src1), src2)); +} + +void Translator::V_MAD_U32_U24(const GcnInst& inst) { + V_MAD_I32_I24(inst, false); +} + +IR::F32 Translator::SelectCubeResult(const IR::F32& x, const IR::F32& y, const IR::F32& z, + const IR::F32& x_res, const IR::F32& y_res, + const IR::F32& z_res) { + const auto abs_x = ir.FPAbs(x); + const auto abs_y = ir.FPAbs(y); + const auto abs_z = ir.FPAbs(z); + + const auto z_face_cond{ + ir.LogicalAnd(ir.FPGreaterThanEqual(abs_z, abs_x), ir.FPGreaterThanEqual(abs_z, abs_y))}; + const auto y_face_cond{ir.FPGreaterThanEqual(abs_y, abs_x)}; + + return IR::F32{ir.Select(z_face_cond, z_res, ir.Select(y_face_cond, y_res, x_res))}; +} + +void Translator::V_CUBEID_F32(const GcnInst& inst) { + const auto x = GetSrc(inst.src[0]); + const auto y = GetSrc(inst.src[1]); + const auto z = GetSrc(inst.src[2]); + + IR::F32 result; + if (profile.supports_native_cube_calc) { + result = ir.CubeFaceIndex(ir.CompositeConstruct(x, y, z)); + } else { + const auto x_neg_cond{ir.FPLessThan(x, ir.Imm32(0.f))}; + const auto y_neg_cond{ir.FPLessThan(y, ir.Imm32(0.f))}; + const auto z_neg_cond{ir.FPLessThan(z, ir.Imm32(0.f))}; + const IR::F32 x_face{ir.Select(x_neg_cond, ir.Imm32(1.f), ir.Imm32(0.f))}; + const IR::F32 y_face{ir.Select(y_neg_cond, ir.Imm32(3.f), ir.Imm32(2.f))}; + const IR::F32 z_face{ir.Select(z_neg_cond, ir.Imm32(5.f), ir.Imm32(4.f))}; + + result = SelectCubeResult(x, y, z, x_face, y_face, z_face); + } + SetDst(inst.dst[0], result); +} + +void Translator::V_CUBESC_F32(const GcnInst& inst) { + const auto x = GetSrc(inst.src[0]); + const auto y = GetSrc(inst.src[1]); + const auto z = GetSrc(inst.src[2]); + + const auto x_neg_cond{ir.FPLessThan(x, ir.Imm32(0.f))}; + const auto z_neg_cond{ir.FPLessThan(z, ir.Imm32(0.f))}; + const IR::F32 x_sc{ir.Select(x_neg_cond, z, ir.FPNeg(z))}; + const IR::F32 y_sc{x}; + const IR::F32 z_sc{ir.Select(z_neg_cond, ir.FPNeg(x), x)}; + + const auto result{SelectCubeResult(x, y, z, x_sc, y_sc, z_sc)}; + SetDst(inst.dst[0], result); +} + +void Translator::V_CUBETC_F32(const GcnInst& inst) { + const auto x = GetSrc(inst.src[0]); + const auto y = GetSrc(inst.src[1]); + const auto z = GetSrc(inst.src[2]); + + const auto y_neg_cond{ir.FPLessThan(y, ir.Imm32(0.f))}; + const IR::F32 x_z_tc{ir.FPNeg(y)}; + const IR::F32 y_tc{ir.Select(y_neg_cond, ir.FPNeg(z), z)}; + + const auto result{SelectCubeResult(x, y, z, x_z_tc, y_tc, x_z_tc)}; + SetDst(inst.dst[0], result); +} + +void Translator::V_CUBEMA_F32(const GcnInst& inst) { + const auto x = GetSrc(inst.src[0]); + const auto y = GetSrc(inst.src[1]); + const auto z = GetSrc(inst.src[2]); + + const auto two{ir.Imm32(2.f)}; + const IR::F32 x_major_axis{ir.FPMul(x, two)}; + const IR::F32 y_major_axis{ir.FPMul(y, two)}; + const IR::F32 z_major_axis{ir.FPMul(z, two)}; + + const auto result{SelectCubeResult(x, y, z, x_major_axis, y_major_axis, z_major_axis)}; + SetDst(inst.dst[0], result); +} + +void Translator::V_BFE_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + IR::U32 src1{GetSrc(inst.src[1])}; + IR::U32 src2{GetSrc(inst.src[2])}; + if (!src1.IsImmediate()) { + src1 = ir.BitwiseAnd(src1, ir.Imm32(0x1F)); + } + if (!src2.IsImmediate()) { + src2 = ir.BitwiseAnd(src2, ir.Imm32(0x1F)); + } + SetDst(inst.dst[0], ir.BitFieldExtract(src0, src1, src2, is_signed)); +} + +void Translator::V_BFI_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], + ir.BitwiseOr(ir.BitwiseAnd(src0, src1), ir.BitwiseAnd(ir.BitwiseNot(src0), src2))); +} + +void Translator::V_FMA_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::F32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.FPFma(src0, src1, src2)); +} + +void Translator::V_FMA_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + const IR::F64 src1{GetSrc64(inst.src[1])}; + const IR::F64 src2{GetSrc64(inst.src[2])}; + SetDst64(inst.dst[0], ir.FPFma(src0, src1, src2)); +} + +void Translator::V_MIN3_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::F32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.FPMinTri(src0, src1, src2)); +} + +void Translator::V_MIN3_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.IMinTri(src0, src1, src2, is_signed)); +} + +void Translator::V_MAX3_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::F32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.FPMaxTri(src0, src1, src2)); +} + +void Translator::V_MAX3_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.IMaxTri(src0, src1, src2, is_signed)); +} + +void Translator::V_MED3_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::F32 src1{GetSrc(inst.src[1])}; + const IR::F32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.FPMedTri(src0, src1, src2)); +} + +void Translator::V_MED3_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{GetSrc(inst.src[2])}; + SetDst(inst.dst[0], ir.IMedTri(src0, src1, src2, is_signed)); +} + +void Translator::V_SAD(const GcnInst& inst) { + const IR::U32 abs_diff = ir.IAbs(ir.ISub(GetSrc(inst.src[0]), GetSrc(inst.src[1]))); + SetDst(inst.dst[0], ir.IAdd(abs_diff, GetSrc(inst.src[2]))); +} + +void Translator::V_SAD_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{GetSrc(inst.src[2])}; + IR::U32 result; + if (src0.IsImmediate() && src0.U32() == 0U) { + result = src1; + } else if (src1.IsImmediate() && src1.U32() == 0U) { + result = src0; + } else { + const IR::U32 max{ir.IMax(src0, src1, false)}; + const IR::U32 min{ir.IMin(src0, src1, false)}; + result = ir.ISub(max, min); + } + SetDst(inst.dst[0], ir.IAdd(result, src2)); +} + +void Translator::V_CVT_PK_U16_U32(const GcnInst& inst) { + const IR::Value vec_u32 = + ir.CompositeConstruct(ir.BitCast(GetSrc(inst.src[0])), + ir.BitCast(GetSrc(inst.src[1]))); + SetDst(inst.dst[0], ir.Pack2x16(AmdGpu::NumberFormat::Uint, vec_u32)); +} + +void Translator::V_CVT_PK_I16_I32(const GcnInst& inst) { + const IR::Value vec_u32 = + ir.CompositeConstruct(ir.BitCast(GetSrc(inst.src[0])), + ir.BitCast(GetSrc(inst.src[1]))); + SetDst(inst.dst[0], ir.Pack2x16(AmdGpu::NumberFormat::Sint, vec_u32)); +} + +void Translator::V_CVT_PK_U8_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{GetSrc(inst.src[2])}; + + const IR::U32 value_uint = ir.ConvertFToU(32, src0); + const IR::U32 offset = ir.ShiftLeftLogical(src1, ir.Imm32(3)); + SetDst(inst.dst[0], ir.BitFieldInsert(src2, value_uint, offset, ir.Imm32(8))); +} + +void Translator::V_LSHL_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + SetDst64(inst.dst[0], ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F))))); +} + +void Translator::V_LSHR_B64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + SetDst64(inst.dst[0], ir.ShiftRightLogical(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F))))); +} + +void Translator::V_ASHR_I64(const GcnInst& inst) { + const IR::U64 src0{GetSrc64(inst.src[0])}; + const IR::U64 src1{GetSrc64(inst.src[1])}; + SetDst64(inst.dst[0], ir.ShiftRightArithmetic(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F))))); +} + +void Translator::V_ALIGNBIT_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{ir.BitwiseAnd(GetSrc(inst.src[2]), ir.Imm32(0x1F))}; + const IR::U32 lo{ir.ShiftRightLogical(src1, src2)}; + const IR::U32 hi{ir.ShiftLeftLogical(src0, ir.ISub(ir.Imm32(32), src2))}; + SetDst(inst.dst[0], ir.BitwiseOr(lo, hi)); +} + +void Translator::V_ALIGNBYTE_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 src2{ir.BitwiseAnd(GetSrc(inst.src[2]), ir.Imm32(0x3))}; + const IR::U32 shift{ir.ShiftLeftLogical(src2, ir.Imm32(3))}; + const IR::U32 lo{ir.ShiftRightLogical(src1, shift)}; + const IR::U32 hi{ir.ShiftLeftLogical(src0, ir.ISub(ir.Imm32(32), shift))}; + SetDst(inst.dst[0], ir.BitwiseOr(lo, hi)); +} + +void Translator::V_MUL_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + const IR::F64 src1{GetSrc64(inst.src[1])}; + SetDst64(inst.dst[0], ir.FPMul(src0, src1)); +} + +void Translator::V_MAX_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + const IR::F64 src1{GetSrc64(inst.src[1])}; + SetDst64(inst.dst[0], ir.FPMax(src0, src1)); +} + +void Translator::V_MUL_LO_U32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + SetDst(inst.dst[0], ir.IMul(src0, src1)); +} + +void Translator::V_MUL_HI_U32(bool is_signed, const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 hi{ir.IMulHi(src0, src1, is_signed)}; + SetDst(inst.dst[0], hi); +} + +void Translator::V_MAD_U64_U32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto src2 = GetSrc64(inst.src[2]); + + const IR::U64 mul_result = ir.IMul(ir.UConvert(64, src0), ir.UConvert(64, src1)); + const IR::U64 sum_result = ir.IAdd(mul_result, src2); + + SetDst64(inst.dst[0], sum_result); + + const IR::U1 less_src0 = ir.ILessThan(sum_result, mul_result, false); + const IR::U1 less_src1 = ir.ILessThan(sum_result, src2, false); + const IR::U1 did_overflow = ir.LogicalOr(less_src0, less_src1); + + const auto unpacked = ir.UnpackUint2x32(ir.Ballot(did_overflow)); + const IR::U32 lo{ir.CompositeExtract(unpacked, 0U)}; + const IR::U32 hi{ir.CompositeExtract(unpacked, 1U)}; + ir.SetVccLo(lo); + ir.SetVccHi(hi); +} + +void Translator::V_LSHLREV_B16(const GcnInst& inst) { + const auto shift = GetSrc16(inst.src[0]); + const auto src = GetSrc16(inst.src[1]); + + const auto result = ir.ShiftLeftLogical(src, ir.BitwiseAnd(shift, ir.Imm32(0xF))); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_LSHRREV_B16(const GcnInst& inst) { + const auto shift = GetSrc16(inst.src[0]); + const auto src = GetSrc16(inst.src[1]); + + const auto result = ir.ShiftRightLogical(src, ir.BitwiseAnd(shift, ir.Imm32(0xF))); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_ASHRREV_I16(const GcnInst& inst) { + const auto shift = GetSrc16(inst.src[0]); + const auto src = GetSrc16(inst.src[1]); + + const auto result = ir.ShiftRightArithmetic(src, ir.BitwiseAnd(shift, ir.Imm32(0xF))); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_ADD_LSHL_U32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto src2 = GetSrc(inst.src[2]); + + const auto shift = ir.BitwiseAnd(src2, ir.Imm32(0x1F)); + + const auto result = ir.ShiftLeftLogical(ir.IAdd(src0, src1), shift); + + SetDst(inst.dst[0], result); +} + +void Translator::V_LSHL_ADD_U32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto src2 = GetSrc(inst.src[2]); + + const auto shift = ir.BitwiseAnd(src1, ir.Imm32(0x1F)); + + const auto result = ir.IAdd(ir.ShiftLeftLogical(src0, shift), src2); + + SetDst(inst.dst[0], result); +} + +void Translator::V_MIN3_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + const auto src2 = GetSrc16(inst.src[2]); + + const auto result = ir.FPMinTri(src0, src1, src2); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_MAX3_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + const auto src2 = GetSrc16(inst.src[2]); + + const auto result = ir.FPMaxTri(src0, src1, src2); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_MED3_F16(const GcnInst& inst) { + const auto src0 = GetSrc16(inst.src[0]); + const auto src1 = GetSrc16(inst.src[1]); + const auto src2 = GetSrc16(inst.src[2]); + + const auto result = ir.FPMedTri(src0, src1, src2); + + SetDst16(inst.dst[0], result); +} + +void Translator::V_ADD3_U32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto src2 = GetSrc(inst.src[2]); + + SetDst(inst.dst[0], ir.IAdd(src0, ir.IAdd(src1, src2))); +} + +void Translator::V_PK_MUL_LO_U16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.IMul(src0.first, src1.first); + const auto result_hi = ir.IMul(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_ADD_I16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.IAdd(src0.first, src1.first); + const auto result_hi = ir.IAdd(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_SUB_I16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.ISub(src0.first, src1.first); + const auto result_hi = ir.ISub(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_LSHLREV_B16(const GcnInst& inst) { + const auto shift = GetSrcPk(inst.src[0]); + const auto src = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.ShiftLeftLogical(src.first, shift.first); + const auto result_hi = ir.ShiftLeftLogical(src.second, shift.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_LSHRREV_B16(const GcnInst& inst) { + const auto shift = GetSrcPk(inst.src[0]); + const auto src = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.ShiftRightLogical(src.first, shift.first); + const auto result_hi = ir.ShiftRightLogical(src.second, shift.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_MAD_U16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + const auto src2 = GetSrcPk(inst.src[2]); + + const auto result_lo = ir.IAdd(ir.IMul(src0.first, src1.first), src2.first); + const auto result_hi = ir.IAdd(ir.IMul(src0.second, src1.second), src2.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_ADD_U16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.IAdd(src0.first, src1.first); + const auto result_hi = ir.IAdd(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_SUB_U16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.ISub(src0.first, src1.first); + const auto result_hi = ir.ISub(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_MAX_U16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.UMax(src0.first, src1.first); + const auto result_hi = ir.UMax(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_MIN_U16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.UMin(src0.first, src1.first); + const auto result_hi = ir.UMin(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_FMA_F16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + const auto src2 = GetSrcPk(inst.src[2]); + + const auto result_lo = ir.FPFma(src0.first, src1.first, src2.first); + const auto result_hi = ir.FPFma(src0.second, src1.second, src2.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_ADD_F16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.FPAdd(src0.first, src1.first); + const auto result_hi = ir.FPAdd(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_MUL_F16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.FPMul(src0.first, src1.first); + const auto result_hi = ir.FPMul(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_MIN_F16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.FPMin(src0.first, src1.first); + const auto result_hi = ir.FPMin(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_PK_MAX_F16(const GcnInst& inst) { + const auto src0 = GetSrcPk(inst.src[0]); + const auto src1 = GetSrcPk(inst.src[1]); + + const auto result_lo = ir.FPMax(src0.first, src1.first); + const auto result_hi = ir.FPMax(src0.second, src1.second); + + SetDstPk(inst.dst[0], {result_lo, result_hi}); +} + +void Translator::V_LSHL_OR_B32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto src2 = GetSrc(inst.src[2]); + + const auto shift = ir.BitwiseAnd(src1, ir.Imm32(0x1F)); + + const auto result = ir.BitwiseOr(ir.ShiftLeftLogical(src0, shift), src2); + + SetDst(inst.dst[0], result); +} + +void Translator::V_AND_OR_B32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto src2 = GetSrc(inst.src[2]); + + const auto result = ir.BitwiseOr(ir.BitwiseAnd(src0, src1), src2); + + SetDst(inst.dst[0], result); +} + +void Translator::V_OR3_B32(const GcnInst& inst) { + const auto src0 = GetSrc(inst.src[0]); + const auto src1 = GetSrc(inst.src[1]); + const auto src2 = GetSrc(inst.src[2]); + + const auto result = ir.BitwiseOr(ir.BitwiseOr(src0, src1), src2); + + SetDst(inst.dst[0], result); +} + +void Translator::V_MAD_MIX_F32(const GcnInst& inst) { + const auto src0 = GetSrcMix(inst.src[0]); + const auto src1 = GetSrcMix(inst.src[1]); + const auto src2 = GetSrcMix(inst.src[2]); + + const IR::F32 result = ir.FPAdd(ir.FPMul(src0, src1), src2); + + SetDst(inst.dst[0], result); +} + +void Translator::V_MAD_MIXLO_F16(const GcnInst& inst) { + const auto src0 = GetSrcMix(inst.src[0]); + const auto src1 = GetSrcMix(inst.src[1]); + const auto src2 = GetSrcMix(inst.src[2]); + + const IR::F32 result = ir.FPAdd(ir.FPMul(src0, src1), src2); + const IR::F16 result_f16 = ir.FPConvert(16, result); + const IR::U16 result_f16_u16 = ir.BitCast(result_f16); + + const IR::U32 old_value{GetSrc(inst.dst[0])}; + const IR::U32 new_value{ + ir.BitFieldInsert(old_value, ir.UConvert(32, result_f16_u16), ir.Imm32(0U), ir.Imm32(16U))}; + SetDst(inst.dst[0], new_value); +} + +void Translator::V_MAD_MIXHI_F16(const GcnInst& inst) { + const auto src0 = GetSrcMix(inst.src[0]); + const auto src1 = GetSrcMix(inst.src[1]); + const auto src2 = GetSrcMix(inst.src[2]); + + const IR::F32 result = ir.FPAdd(ir.FPMul(src0, src1), src2); + const IR::F16 result_f16 = ir.FPConvert(16, result); + const IR::U16 result_f16_u16 = ir.BitCast(result_f16); + + const IR::U32 old_value{GetSrc(inst.dst[0])}; + const IR::U32 new_value{ir.BitFieldInsert(old_value, ir.UConvert(32, result_f16_u16), + ir.Imm32(16U), ir.Imm32(16U))}; + SetDst(inst.dst[0], new_value); +} + +IR::U32 Translator::GetCarryIn(const GcnInst& inst) { + IR::U64 carry; + if (inst.src_count == 3) { // VOP3 + carry = GetSrc64(inst.src[2]); + } else { // VOP2 + carry = ir.PackUint2x32(ir.CompositeConstruct(ir.GetVccLo(), ir.GetVccHi())); + } + + return IR::U32{ir.Select(ir.InverseBallot(carry), ir.Imm32(1), ir.Imm32(0))}; +} + +void Translator::SetCarryOut(const GcnInst& inst, const IR::U1& carry) { + if (inst.dst_count == 2) { // VOP3 + SetDst64(inst.dst[1], ir.Ballot(carry)); + } else { // VOP2 + const auto unpacked = ir.UnpackUint2x32(ir.Ballot(carry)); + const IR::U32 lo{ir.CompositeExtract(unpacked, 0U)}; + const IR::U32 hi{ir.CompositeExtract(unpacked, 1U)}; + ir.SetVccLo(lo); + ir.SetVccHi(hi); + } +} + +// TODO: add range analysis pass to hopefully put an upper bound on m0, and only select one of +// [src_vgprno, src_vgprno + max_m0]. Same for dst regs we may write back to + +IR::U32 Translator::VMovRelSHelper(u32 src_vgprno, const IR::U32 m0) { + // Read from VGPR0 by default when src_vgprno + m0 > num_allocated_vgprs + IR::U32 src_val = ir.GetVectorReg(IR::VectorReg::V0); + for (u32 i = src_vgprno; i < runtime_info.props.num_allocated_vgprs; i++) { + const IR::U1 cond = ir.IEqual(m0, ir.Imm32(i - src_vgprno)); + src_val = + IR::U32{ir.Select(cond, ir.GetVectorReg(IR::VectorReg::V0 + i), src_val)}; + } + return src_val; +} + +void Translator::VMovRelDHelper(u32 dst_vgprno, const IR::U32 src_val, const IR::U32 m0) { + for (u32 i = dst_vgprno; i < runtime_info.props.num_allocated_vgprs; i++) { + const IR::U1 cond = ir.IEqual(m0, ir.Imm32(i - dst_vgprno)); + const IR::U32 dst_val = + IR::U32{ir.Select(cond, src_val, ir.GetVectorReg(IR::VectorReg::V0 + i))}; + ir.SetVectorReg(IR::VectorReg::V0 + i, dst_val); + } +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/vector_interpolation.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/vector_interpolation.cpp new file mode 100644 index 0000000..c2d75f8 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/vector_interpolation.cpp @@ -0,0 +1,116 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Gcn { + +using Interpolation = Info::Interpolation; + +static Interpolation GetInterpolation(IR::Attribute attribute) { + switch (attribute) { + case IR::Attribute::BaryCoordNoPersp: + return {Qualifier::NoPerspective, Qualifier::None}; + case IR::Attribute::BaryCoordNoPerspCentroid: + return {Qualifier::NoPerspective, Qualifier::Centroid}; + case IR::Attribute::BaryCoordNoPerspSample: + return {Qualifier::NoPerspective, Qualifier::Sample}; + case IR::Attribute::BaryCoordSmooth: + return {Qualifier::Smooth, Qualifier::None}; + case IR::Attribute::BaryCoordSmoothCentroid: + return {Qualifier::Smooth, Qualifier::Centroid}; + case IR::Attribute::BaryCoordSmoothSample: + return {Qualifier::Smooth, Qualifier::Sample}; + case IR::Attribute::BaryCoordPullModel: + return {Qualifier::Smooth, Qualifier::None}; + default: + UNREACHABLE_MSG("Unhandled barycentric attribute {}", NameOf(attribute)); + } +} + +static constexpr std::array DefaultValTable = { + std::array{0.0f, 0.0f, 0.0f, 0.0f}, + std::array{0.0f, 0.0f, 0.0f, 1.0f}, + std::array{1.0f, 1.0f, 1.0f, 0.0f}, + std::array{1.0f, 1.0f, 1.0f, 1.0f}, +}; + +void Translator::EmitVectorInterpolation(const GcnInst& inst) { + switch (inst.opcode) { + // VINTRP + case Opcode::V_INTERP_P1_F32: + return V_INTERP_P1_F32(inst); + case Opcode::V_INTERP_P2_F32: + return V_INTERP_P2_F32(inst); + case Opcode::V_INTERP_MOV_F32: + return V_INTERP_MOV_F32(inst); + default: + LogMissingOpcode(inst); + } +} + +// VINTRP + +void Translator::V_INTERP_P1_F32(const GcnInst& inst) { + if (!profile.needs_manual_interpolation) { + return; + } + const u32 attr_index = inst.control.vintrp.attr; + const auto& attr = runtime_info.hw.fs.inputs[attr_index]; + if (attr.IsDefault()) { + return; + } + // VDST = P10 * VSRC + P0 + const IR::Attribute attrib = IR::Attribute::Param0 + attr_index; + const IR::F32 p0 = ir.GetAttribute(attrib, inst.control.vintrp.chan, 0); + const IR::F32 p1 = ir.GetAttribute(attrib, inst.control.vintrp.chan, 1); + const IR::F32 i = GetSrc(inst.src[0]); + const IR::F32 result = ir.FPFma(ir.FPSub(p1, p0), i, p0); + SetDst(inst.dst[0], result); +} + +void Translator::V_INTERP_P2_F32(const GcnInst& inst) { + const u32 attr_index = inst.control.vintrp.attr; + const IR::Attribute attrib = IR::Attribute::Param0 + attr_index; + const auto& attr = runtime_info.hw.fs.inputs[attr_index]; + auto& interp = info.fs_interpolation[attr_index]; + if (attr.IsDefault()) { + SetDst(inst.dst[0], + ir.Imm32(DefaultValTable[attr.default_value][inst.control.vintrp.chan])); + return; + } + ASSERT(!attr.is_flat); + if (!profile.needs_manual_interpolation) { + interp = GetInterpolation(vgpr_to_interp[inst.src[0].code]); + SetDst(inst.dst[0], ir.GetAttribute(attrib, inst.control.vintrp.chan)); + return; + } + // VDST = P20 * VSRC + VDST + const IR::F32 p0 = ir.GetAttribute(attrib, inst.control.vintrp.chan, 0); + const IR::F32 p2 = ir.GetAttribute(attrib, inst.control.vintrp.chan, 2); + const IR::F32 j = GetSrc(inst.src[0]); + const IR::F32 result = ir.FPFma(ir.FPSub(p2, p0), j, GetSrc(inst.dst[0])); + interp.primary = Qualifier::PerVertex; + SetDst(inst.dst[0], result); +} + +void Translator::V_INTERP_MOV_F32(const GcnInst& inst) { + const u32 attr_index = inst.control.vintrp.attr; + const IR::Attribute attrib = IR::Attribute::Param0 + attr_index; + const auto& attr = runtime_info.hw.fs.inputs[attr_index]; + auto& interp = info.fs_interpolation[attr_index]; + ASSERT(attr.is_flat || inst.src[0].code == 2); + if (profile.supports_amd_shader_explicit_vertex_parameter || + profile.supports_fragment_shader_barycentric) { + // VSRC 0=P10, 1=P20, 2=P0 + interp.primary = Qualifier::PerVertex; + SetDst(inst.dst[0], + ir.GetAttribute(attrib, inst.control.vintrp.chan, (inst.src[0].code + 1) % 3)); + } else { + interp.primary = Qualifier::Flat; + SetDst(inst.dst[0], ir.GetAttribute(attrib, inst.control.vintrp.chan)); + } +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/frontend/translate/vector_memory.cpp b/gpu/shadps4/shader_recompiler/frontend/translate/vector_memory.cpp new file mode 100644 index 0000000..ef15672 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/frontend/translate/vector_memory.cpp @@ -0,0 +1,767 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/frontend/translate/translate.h" + +namespace Shader::Gcn { + +void Translator::EmitVectorMemory(const GcnInst& inst) { + switch (inst.opcode) { + // MUBUF / MTBUF + + // Buffer load operations + case Opcode::TBUFFER_LOAD_FORMAT_X: + return BUFFER_LOAD(1, true, false, inst); + case Opcode::TBUFFER_LOAD_FORMAT_XY: + return BUFFER_LOAD(2, true, false, inst); + case Opcode::TBUFFER_LOAD_FORMAT_XYZ: + return BUFFER_LOAD(3, true, false, inst); + case Opcode::TBUFFER_LOAD_FORMAT_XYZW: + return BUFFER_LOAD(4, true, false, inst); + + case Opcode::BUFFER_LOAD_FORMAT_X: + return BUFFER_LOAD(1, false, true, inst); + case Opcode::BUFFER_LOAD_FORMAT_XY: + return BUFFER_LOAD(2, false, true, inst); + case Opcode::BUFFER_LOAD_FORMAT_XYZ: + return BUFFER_LOAD(3, false, true, inst); + case Opcode::BUFFER_LOAD_FORMAT_XYZW: + return BUFFER_LOAD(4, false, true, inst); + + case Opcode::BUFFER_LOAD_UBYTE: + return BUFFER_LOAD(1, false, false, inst, 8, false); + case Opcode::BUFFER_LOAD_SBYTE: + return BUFFER_LOAD(1, false, false, inst, 8, true); + case Opcode::BUFFER_LOAD_USHORT: + return BUFFER_LOAD(1, false, false, inst, 16, false); + case Opcode::BUFFER_LOAD_SSHORT: + return BUFFER_LOAD(1, false, false, inst, 16, true); + + case Opcode::BUFFER_LOAD_DWORD: + return BUFFER_LOAD(1, false, false, inst); + case Opcode::BUFFER_LOAD_DWORDX2: + return BUFFER_LOAD(2, false, false, inst); + case Opcode::BUFFER_LOAD_DWORDX3: + return BUFFER_LOAD(3, false, false, inst); + case Opcode::BUFFER_LOAD_DWORDX4: + return BUFFER_LOAD(4, false, false, inst); + + // Buffer store operations + case Opcode::BUFFER_STORE_FORMAT_X: + return BUFFER_STORE(1, false, true, inst); + case Opcode::BUFFER_STORE_FORMAT_XY: + return BUFFER_STORE(2, false, true, inst); + case Opcode::BUFFER_STORE_FORMAT_XYZ: + return BUFFER_STORE(3, false, true, inst); + case Opcode::BUFFER_STORE_FORMAT_XYZW: + return BUFFER_STORE(4, false, true, inst); + + case Opcode::TBUFFER_STORE_FORMAT_X: + return BUFFER_STORE(1, true, false, inst); + case Opcode::TBUFFER_STORE_FORMAT_XY: + return BUFFER_STORE(2, true, false, inst); + case Opcode::TBUFFER_STORE_FORMAT_XYZ: + return BUFFER_STORE(3, true, false, inst); + case Opcode::TBUFFER_STORE_FORMAT_XYZW: + return BUFFER_STORE(4, true, false, inst); + + case Opcode::BUFFER_STORE_BYTE: + return BUFFER_STORE(1, false, false, inst, 8); + case Opcode::BUFFER_STORE_SHORT: + return BUFFER_STORE(1, false, false, inst, 16); + + case Opcode::BUFFER_STORE_DWORD: + return BUFFER_STORE(1, false, false, inst); + case Opcode::BUFFER_STORE_DWORDX2: + return BUFFER_STORE(2, false, false, inst); + case Opcode::BUFFER_STORE_DWORDX3: + return BUFFER_STORE(3, false, false, inst); + case Opcode::BUFFER_STORE_DWORDX4: + return BUFFER_STORE(4, false, false, inst); + + // Buffer atomic operations + case Opcode::BUFFER_ATOMIC_ADD: + return BUFFER_ATOMIC(AtomicOp::Add, inst); + case Opcode::BUFFER_ATOMIC_SWAP: + return BUFFER_ATOMIC(AtomicOp::Swap, inst); + case Opcode::BUFFER_ATOMIC_CMPSWAP: + return BUFFER_ATOMIC(AtomicOp::CmpSwap, inst); + case Opcode::BUFFER_ATOMIC_SMIN: + return BUFFER_ATOMIC(AtomicOp::Smin, inst); + case Opcode::BUFFER_ATOMIC_SMIN_X2: + return BUFFER_ATOMIC(AtomicOp::Smin, inst); + case Opcode::BUFFER_ATOMIC_UMIN: + return BUFFER_ATOMIC(AtomicOp::Umin, inst); + case Opcode::BUFFER_ATOMIC_UMIN_X2: + return BUFFER_ATOMIC(AtomicOp::Umin, inst); + case Opcode::BUFFER_ATOMIC_SMAX: + return BUFFER_ATOMIC(AtomicOp::Smax, inst); + case Opcode::BUFFER_ATOMIC_SMAX_X2: + return BUFFER_ATOMIC(AtomicOp::Smax, inst); + case Opcode::BUFFER_ATOMIC_UMAX: + return BUFFER_ATOMIC(AtomicOp::Umax, inst); + case Opcode::BUFFER_ATOMIC_UMAX_X2: + return BUFFER_ATOMIC(AtomicOp::Umax, inst); + case Opcode::BUFFER_ATOMIC_AND: + return BUFFER_ATOMIC(AtomicOp::And, inst); + case Opcode::BUFFER_ATOMIC_OR: + return BUFFER_ATOMIC(AtomicOp::Or, inst); + case Opcode::BUFFER_ATOMIC_XOR: + return BUFFER_ATOMIC(AtomicOp::Xor, inst); + case Opcode::BUFFER_ATOMIC_INC: + return BUFFER_ATOMIC(AtomicOp::Inc, inst); + case Opcode::BUFFER_ATOMIC_DEC: + return BUFFER_ATOMIC(AtomicOp::Dec, inst); + case Opcode::BUFFER_ATOMIC_FMIN: + return BUFFER_ATOMIC(AtomicOp::Fmin, inst); + case Opcode::BUFFER_ATOMIC_FMAX: + return BUFFER_ATOMIC(AtomicOp::Fmax, inst); + case Opcode::BUFFER_ATOMIC_FCMPSWAP: + return BUFFER_ATOMIC(AtomicOp::FCmpSwap, inst); + + // MIMG + // Image load operations + case Opcode::IMAGE_LOAD: + return IMAGE_LOAD(false, inst); + case Opcode::IMAGE_LOAD_MIP: + return IMAGE_LOAD(true, inst); + + // Buffer store operations + case Opcode::IMAGE_STORE: + return IMAGE_STORE(false, inst); + case Opcode::IMAGE_STORE_MIP: + return IMAGE_STORE(true, inst); + + // Image misc operations + case Opcode::IMAGE_GET_RESINFO: + return IMAGE_GET_RESINFO(inst); + + // Image atomic operations + case Opcode::IMAGE_ATOMIC_SWAP: + return IMAGE_ATOMIC(AtomicOp::Swap, inst); + case Opcode::IMAGE_ATOMIC_CMPSWAP: + return IMAGE_ATOMIC(AtomicOp::CmpSwap, inst); + case Opcode::IMAGE_ATOMIC_ADD: + return IMAGE_ATOMIC(AtomicOp::Add, inst); + case Opcode::IMAGE_ATOMIC_SMIN: + return IMAGE_ATOMIC(AtomicOp::Smin, inst); + case Opcode::IMAGE_ATOMIC_UMIN: + return IMAGE_ATOMIC(AtomicOp::Umin, inst); + case Opcode::IMAGE_ATOMIC_FMIN: + return IMAGE_ATOMIC(AtomicOp::Fmin, inst); + case Opcode::IMAGE_ATOMIC_SMAX: + return IMAGE_ATOMIC(AtomicOp::Smax, inst); + case Opcode::IMAGE_ATOMIC_FMAX: + return IMAGE_ATOMIC(AtomicOp::Fmax, inst); + case Opcode::IMAGE_ATOMIC_UMAX: + return IMAGE_ATOMIC(AtomicOp::Umax, inst); + case Opcode::IMAGE_ATOMIC_AND: + return IMAGE_ATOMIC(AtomicOp::And, inst); + case Opcode::IMAGE_ATOMIC_OR: + return IMAGE_ATOMIC(AtomicOp::Or, inst); + case Opcode::IMAGE_ATOMIC_XOR: + return IMAGE_ATOMIC(AtomicOp::Xor, inst); + case Opcode::IMAGE_ATOMIC_INC: + return IMAGE_ATOMIC(AtomicOp::Inc, inst); + case Opcode::IMAGE_ATOMIC_DEC: + return IMAGE_ATOMIC(AtomicOp::Dec, inst); + + case Opcode::IMAGE_SAMPLE: + case Opcode::IMAGE_SAMPLE_D: + case Opcode::IMAGE_SAMPLE_L: + case Opcode::IMAGE_SAMPLE_B: + case Opcode::IMAGE_SAMPLE_LZ: + case Opcode::IMAGE_SAMPLE_C: + case Opcode::IMAGE_SAMPLE_C_LZ: + case Opcode::IMAGE_SAMPLE_O: + case Opcode::IMAGE_SAMPLE_D_O: + case Opcode::IMAGE_SAMPLE_L_O: + case Opcode::IMAGE_SAMPLE_B_O: + case Opcode::IMAGE_SAMPLE_LZ_O: + case Opcode::IMAGE_SAMPLE_C_O: + case Opcode::IMAGE_SAMPLE_C_LZ_O: + case Opcode::IMAGE_SAMPLE_CD: + return IMAGE_SAMPLE(inst); + + // Image gather operations + case Opcode::IMAGE_GATHER4: + case Opcode::IMAGE_GATHER4_L: + case Opcode::IMAGE_GATHER4_LZ: + case Opcode::IMAGE_GATHER4_C: + case Opcode::IMAGE_GATHER4_O: + case Opcode::IMAGE_GATHER4_C_O: + case Opcode::IMAGE_GATHER4_C_LZ: + case Opcode::IMAGE_GATHER4_LZ_O: + case Opcode::IMAGE_GATHER4_C_LZ_O: + return IMAGE_GATHER(inst); + + // Image misc operations + case Opcode::IMAGE_GET_LOD: + return IMAGE_GET_LOD(inst); + + default: + LogMissingOpcode(inst); + } +} + +void Translator::BUFFER_LOAD(u32 num_dwords, bool is_inst_typed, bool is_buffer_typed, + const GcnInst& inst, u32 scalar_width, bool is_signed) { + const auto& mubuf = inst.control.mubuf; + const IR::VectorReg vaddr{inst.src[0].code}; + const IR::ScalarReg sharp{inst.src[2].code * 4}; + + const IR::U32 index = mubuf.idxen ? ir.GetVectorReg(vaddr) : ir.Imm32(0); + const IR::VectorReg voffset_vgpr = mubuf.idxen ? vaddr + 1 : vaddr; + const IR::U32 voffset = mubuf.offen ? ir.GetVectorReg(voffset_vgpr) : ir.Imm32(0); + const IR::U32 soffset{GetSrc(inst.src[3])}; + const IR::Value address = ir.CompositeConstruct(index, voffset, soffset); + + IR::BufferInstInfo buffer_info{}; + buffer_info.index_enable.Assign(mubuf.idxen); + buffer_info.voffset_enable.Assign(mubuf.offen); + buffer_info.inst_offset.Assign(mubuf.offset); + buffer_info.globally_coherent.Assign(mubuf.glc); + buffer_info.system_coherent.Assign(mubuf.slc); + buffer_info.typed.Assign(is_inst_typed || is_buffer_typed); + if (is_inst_typed) { + const auto& mtbuf = inst.control.mtbuf; + buffer_info.inst_data_fmt.Assign(static_cast(mtbuf.dfmt)); + buffer_info.inst_num_fmt.Assign(static_cast(mtbuf.nfmt)); + } else { + buffer_info.inst_data_fmt.Assign(AmdGpu::DataFormat::FormatInvalid); + } + buffer_info.pc.Assign(pc); + + const IR::Value handle = + ir.CompositeConstruct(ir.GetScalarReg(sharp), ir.GetScalarReg(sharp + 1), + ir.GetScalarReg(sharp + 2), ir.GetScalarReg(sharp + 3)); + const IR::VectorReg dst_reg{inst.src[1].code}; + if (buffer_info.typed) { + const IR::Value value = ir.LoadBufferFormat(handle, address, buffer_info); + for (u32 i = 0; i < num_dwords; i++) { + ir.SetVectorReg(dst_reg + i, IR::F32{ir.CompositeExtract(value, i)}); + } + } else { + IR::Value value; + switch (scalar_width) { + case 8: { + IR::U8 byte_val = ir.LoadBufferU8(handle, address, buffer_info); + value = is_signed ? ir.SConvert(32, byte_val) : ir.UConvert(32, byte_val); + break; + } + case 16: { + IR::U16 short_val = ir.LoadBufferU16(handle, address, buffer_info); + value = is_signed ? ir.SConvert(32, short_val) : ir.UConvert(32, short_val); + break; + } + case 32: + value = ir.LoadBufferU32(num_dwords, handle, address, buffer_info); + break; + + default: + UNREACHABLE(); + } + + if (num_dwords == 1) { + ir.SetVectorReg(dst_reg, IR::U32{value}); + return; + } + for (u32 i = 0; i < num_dwords; i++) { + ir.SetVectorReg(dst_reg + i, IR::U32{ir.CompositeExtract(value, i)}); + } + } +} + +void Translator::BUFFER_STORE(u32 num_dwords, bool is_inst_typed, bool is_buffer_typed, + const GcnInst& inst, u32 scalar_width) { + const auto& mubuf = inst.control.mubuf; + const IR::VectorReg vaddr{inst.src[0].code}; + const IR::ScalarReg sharp{inst.src[2].code * 4}; + + const IR::U32 index = mubuf.idxen ? ir.GetVectorReg(vaddr) : ir.Imm32(0); + const IR::VectorReg voffset_vgpr = mubuf.idxen ? vaddr + 1 : vaddr; + const IR::U32 voffset = mubuf.offen ? ir.GetVectorReg(voffset_vgpr) : ir.Imm32(0); + const IR::U32 soffset{GetSrc(inst.src[3])}; + const IR::Value address = ir.CompositeConstruct(index, voffset, soffset); + + IR::BufferInstInfo buffer_info{}; + buffer_info.index_enable.Assign(mubuf.idxen); + buffer_info.voffset_enable.Assign(mubuf.offen); + buffer_info.inst_offset.Assign(mubuf.offset); + buffer_info.globally_coherent.Assign(mubuf.glc); + buffer_info.system_coherent.Assign(mubuf.slc); + buffer_info.typed.Assign(is_inst_typed || is_buffer_typed); + if (is_inst_typed) { + const auto& mtbuf = inst.control.mtbuf; + buffer_info.inst_data_fmt.Assign(static_cast(mtbuf.dfmt)); + buffer_info.inst_num_fmt.Assign(static_cast(mtbuf.nfmt)); + } else { + buffer_info.inst_data_fmt.Assign(AmdGpu::DataFormat::FormatInvalid); + } + buffer_info.pc.Assign(pc); + + const IR::Value handle = + ir.CompositeConstruct(ir.GetScalarReg(sharp), ir.GetScalarReg(sharp + 1), + ir.GetScalarReg(sharp + 2), ir.GetScalarReg(sharp + 3)); + const IR::VectorReg src_reg{inst.src[1].code}; + + boost::container::static_vector comps; + for (u32 i = 0; i < num_dwords; i++) { + const auto src_reg_i = src_reg + i; + if (buffer_info.typed) { + comps.push_back(ir.GetVectorReg(src_reg_i)); + } else { + comps.push_back(ir.GetVectorReg(src_reg_i)); + } + } + if (buffer_info.typed) { + for (u32 i = num_dwords; i < 4; i++) { + comps.push_back(ir.Imm32(0.f)); + } + ir.StoreBufferFormat(handle, address, ir.CompositeConstruct(comps), buffer_info); + } else { + IR::Value value = num_dwords == 1 ? comps[0] : ir.CompositeConstruct(comps); + if (scalar_width != 32) { + value = ir.UConvert(scalar_width, IR::U32{value}); + } + switch (scalar_width) { + case 8: + ir.StoreBufferU8(handle, address, IR::U8{value}, buffer_info); + break; + case 16: + ir.StoreBufferU16(handle, address, IR::U16{value}, buffer_info); + break; + case 32: + ir.StoreBufferU32(num_dwords, handle, address, value, buffer_info); + break; + default: + UNREACHABLE(); + } + } +} + +template +void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) { + const auto& mubuf = inst.control.mubuf; + const IR::VectorReg vaddr{inst.src[0].code}; + const IR::VectorReg vdata{inst.src[1].code}; + const IR::ScalarReg srsrc{inst.src[2].code * 4}; + const IR::U32 index = mubuf.idxen ? ir.GetVectorReg(vaddr) : ir.Imm32(0); + const IR::VectorReg voffset_vgpr = mubuf.idxen ? vaddr + 1 : vaddr; + const IR::U32 voffset = mubuf.offen ? ir.GetVectorReg(voffset_vgpr) : ir.Imm32(0); + const IR::U32 soffset{GetSrc(inst.src[3])}; + const IR::Value address = ir.CompositeConstruct(index, voffset, soffset); + + IR::BufferInstInfo buffer_info{}; + buffer_info.index_enable.Assign(mubuf.idxen); + buffer_info.voffset_enable.Assign(mubuf.offen); + buffer_info.inst_offset.Assign(mubuf.offset); + buffer_info.globally_coherent.Assign(mubuf.glc); + buffer_info.system_coherent.Assign(mubuf.slc); + buffer_info.pc.Assign(pc); + + IR::Value vdata_val = [&] { + if constexpr (std::is_same_v) { + return ir.GetVectorReg(vdata); + } else if constexpr (std::is_same_v) { + return ir.GetVectorReg(vdata); + } else if constexpr (std::is_same_v) { + return ir.PackUint2x32( + ir.CompositeConstruct(ir.GetVectorReg(vdata), + ir.GetVectorReg(vdata + 1))); + } else { + static_assert(false, "buffer_atomic: type not supported"); + } + }(); + const IR::Value handle = + ir.CompositeConstruct(ir.GetScalarReg(srsrc), ir.GetScalarReg(srsrc + 1), + ir.GetScalarReg(srsrc + 2), ir.GetScalarReg(srsrc + 3)); + + const IR::Value original_val = [&] { + switch (op) { + case AtomicOp::Swap: + return ir.BufferAtomicSwap(handle, address, vdata_val, buffer_info); + case AtomicOp::CmpSwap: { + const IR::Value cmp_val = ir.GetVectorReg(vdata + 1); + return ir.BufferAtomicCmpSwap(handle, address, vdata_val, cmp_val, buffer_info); + } + case AtomicOp::FCmpSwap: { + const IR::Value cmp_val = ir.GetVectorReg(vdata + 1); + return ir.BufferAtomicFCmpSwap(handle, address, vdata_val, cmp_val, buffer_info); + } + case AtomicOp::Add: + return ir.BufferAtomicIAdd(handle, address, vdata_val, buffer_info); + case AtomicOp::Smin: + return ir.BufferAtomicIMin(handle, address, vdata_val, true, buffer_info); + case AtomicOp::Umin: + return ir.BufferAtomicIMin(handle, address, vdata_val, false, buffer_info); + case AtomicOp::Smax: + return ir.BufferAtomicIMax(handle, address, vdata_val, true, buffer_info); + case AtomicOp::Umax: + return ir.BufferAtomicIMax(handle, address, vdata_val, false, buffer_info); + case AtomicOp::And: + return ir.BufferAtomicAnd(handle, address, vdata_val, buffer_info); + case AtomicOp::Or: + return ir.BufferAtomicOr(handle, address, vdata_val, buffer_info); + case AtomicOp::Xor: + return ir.BufferAtomicXor(handle, address, vdata_val, buffer_info); + case AtomicOp::Inc: + return ir.BufferAtomicInc(handle, address, buffer_info); + case AtomicOp::Dec: + return ir.BufferAtomicDec(handle, address, buffer_info); + case AtomicOp::Fmin: + return ir.BufferAtomicFMin(handle, address, vdata_val, buffer_info); + case AtomicOp::Fmax: + return ir.BufferAtomicFMax(handle, address, vdata_val, buffer_info); + default: + UNREACHABLE(); + } + }(); + + if (mubuf.glc) { + if constexpr (std::is_same_v) { + UNREACHABLE(); + } else { + ir.SetVectorReg(vdata, T{original_val}); + } + } +} + +// Image Memory +// MIMG + +void Translator::IMAGE_LOAD(bool has_mip, const GcnInst& inst) { + const auto& mimg = inst.control.mimg; + IR::VectorReg addr_reg{inst.src[0].code}; + IR::VectorReg dest_reg{inst.dst[0].code}; + const IR::ScalarReg tsharp_reg{inst.src[2].code * 4}; + + const IR::Value tsharp_low = + ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(tsharp_reg + 1), + ir.GetScalarReg(tsharp_reg + 2), ir.GetScalarReg(tsharp_reg + 3)); + const IR::Value tsharp_high = mimg.r128 + ? IR::Value{} + : ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg + 4), + ir.GetScalarReg(tsharp_reg + 5), + ir.GetScalarReg(tsharp_reg + 6), + ir.GetScalarReg(tsharp_reg + 7)); + const IR::Value body = + ir.CompositeConstruct(ir.GetVectorReg(addr_reg), ir.GetVectorReg(addr_reg + 1), + ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3)); + + IR::TextureInstInfo info{}; + info.has_lod.Assign(has_mip); + info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); + const IR::Value texel = + ir.ImageRead(ir.ImageHandle(tsharp_low, tsharp_high), body, {}, {}, info); + + for (u32 i = 0; i < 4; i++) { + if (((mimg.dmask >> i) & 1) == 0) { + continue; + } + IR::F32 value = IR::F32{ir.CompositeExtract(texel, i)}; + ir.SetVectorReg(dest_reg++, value); + } +} + +void Translator::IMAGE_STORE(bool has_mip, const GcnInst& inst) { + const auto& mimg = inst.control.mimg; + IR::VectorReg addr_reg{inst.src[0].code}; + IR::VectorReg data_reg{inst.dst[0].code}; + const IR::ScalarReg tsharp_reg{inst.src[2].code * 4}; + + const IR::Value tsharp_low = + ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(tsharp_reg + 1), + ir.GetScalarReg(tsharp_reg + 2), ir.GetScalarReg(tsharp_reg + 3)); + const IR::Value tsharp_high = mimg.r128 + ? IR::Value{} + : ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg + 4), + ir.GetScalarReg(tsharp_reg + 5), + ir.GetScalarReg(tsharp_reg + 6), + ir.GetScalarReg(tsharp_reg + 7)); + const IR::Value body = + ir.CompositeConstruct(ir.GetVectorReg(addr_reg), ir.GetVectorReg(addr_reg + 1), + ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3)); + + IR::TextureInstInfo info{}; + info.has_lod.Assign(has_mip); + info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); + + boost::container::static_vector comps; + for (u32 i = 0; i < 4; i++) { + if (((mimg.dmask >> i) & 1) == 0) { + comps.push_back(ir.Imm32(0.f)); + continue; + } + comps.push_back(ir.GetVectorReg(data_reg++)); + } + const IR::Value value = ir.CompositeConstruct(comps[0], comps[1], comps[2], comps[3]); + ir.ImageWrite(ir.ImageHandle(tsharp_low, tsharp_high), body, {}, {}, value, info); +} + +void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) { + const auto& mimg = inst.control.mimg; + IR::VectorReg dst_reg{inst.dst[0].code}; + const IR::ScalarReg tsharp_reg{inst.src[2].code * 4}; + const auto flags = ImageResFlags(inst.control.mimg.dmask); + const bool has_mips = flags.test(ImageResComponent::MipCount); + const IR::U32 lod = ir.GetVectorReg(IR::VectorReg(inst.src[0].code)); + const IR::Value tsharp_low = + ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(tsharp_reg + 1), + ir.GetScalarReg(tsharp_reg + 2), ir.GetScalarReg(tsharp_reg + 3)); + const IR::Value tsharp_high = mimg.r128 + ? IR::Value{} + : ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg + 4), + ir.GetScalarReg(tsharp_reg + 5), + ir.GetScalarReg(tsharp_reg + 6), + ir.GetScalarReg(tsharp_reg + 7)); + + IR::TextureInstInfo info{}; + info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); + + const IR::Value size = ir.ImageQueryDimension(ir.ImageHandle(tsharp_low, tsharp_high), lod, + ir.Imm1(has_mips), info); + + if (flags.test(ImageResComponent::Width)) { + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 0)}); + } + if (flags.test(ImageResComponent::Height)) { + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 1)}); + } + if (flags.test(ImageResComponent::Depth)) { + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 2)}); + } + if (has_mips) { + ir.SetVectorReg(dst_reg++, IR::U32{ir.CompositeExtract(size, 3)}); + } +} + +void Translator::IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst) { + const auto& mimg = inst.control.mimg; + IR::VectorReg val_reg{inst.dst[0].code}; + IR::VectorReg addr_reg{inst.src[0].code}; + const IR::ScalarReg tsharp_reg{inst.src[2].code * 4}; + + IR::TextureInstInfo info{}; + info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); + + const IR::Value value = ir.GetVectorReg(val_reg); + const IR::Value tsharp_low = + ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(tsharp_reg + 1), + ir.GetScalarReg(tsharp_reg + 2), ir.GetScalarReg(tsharp_reg + 3)); + const IR::Value tsharp_high = mimg.r128 + ? IR::Value{} + : ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg + 4), + ir.GetScalarReg(tsharp_reg + 5), + ir.GetScalarReg(tsharp_reg + 6), + ir.GetScalarReg(tsharp_reg + 7)); + const IR::Value handle = ir.ImageHandle(tsharp_low, tsharp_high); + const IR::Value body = + ir.CompositeConstruct(ir.GetVectorReg(addr_reg), ir.GetVectorReg(addr_reg + 1), + ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3)); + const IR::Value prev = [&] { + switch (op) { + case AtomicOp::Swap: + return ir.ImageAtomicExchange(handle, body, value, {}); + case AtomicOp::CmpSwap: { + const IR::Value cmp_val = ir.GetVectorReg(val_reg + 1); + return ir.ImageAtomicCmpSwap(handle, body, value, cmp_val, info); + } + case AtomicOp::Add: + return ir.ImageAtomicIAdd(handle, body, value, info); + case AtomicOp::Smin: + return ir.ImageAtomicIMin(handle, body, value, true, info); + case AtomicOp::Umin: + return ir.ImageAtomicUMin(handle, body, value, info); + case AtomicOp::Smax: + return ir.ImageAtomicIMax(handle, body, value, true, info); + case AtomicOp::Umax: + return ir.ImageAtomicUMax(handle, body, value, info); + case AtomicOp::Fmax: + return ir.ImageAtomicFMax(handle, body, value, info); + case AtomicOp::Fmin: + return ir.ImageAtomicFMin(handle, body, value, info); + case AtomicOp::And: + return ir.ImageAtomicAnd(handle, body, value, info); + case AtomicOp::Or: + return ir.ImageAtomicOr(handle, body, value, info); + case AtomicOp::Xor: + return ir.ImageAtomicXor(handle, body, value, info); + case AtomicOp::Inc: + return ir.ImageAtomicInc(handle, body, value, info); + case AtomicOp::Dec: + return ir.ImageAtomicDec(handle, body, value, info); + default: + UNREACHABLE(); + } + }(); + if (mimg.glc) { + ir.SetVectorReg(val_reg, IR::U32{prev}); + } +} + +IR::Value EmitImageSample(IR::IREmitter& ir, const GcnInst& inst, const IR::ScalarReg tsharp_reg, + const IR::ScalarReg sampler_reg, const IR::VectorReg addr_reg, + bool gather, u32 pc) { + const auto& mimg = inst.control.mimg; + const auto flags = MimgModifierFlags(mimg.mod); + + IR::TextureInstInfo info{}; + info.is_depth.Assign(flags.test(MimgModifier::Pcf)); + info.has_bias.Assign(flags.test(MimgModifier::LodBias)); + info.has_lod_clamp.Assign(flags.test(MimgModifier::LodClamp)); + info.force_level0.Assign(flags.test(MimgModifier::Level0)); + info.has_offset.Assign(flags.test(MimgModifier::Offset)); + info.has_lod.Assign(flags.any(MimgModifier::Lod)); + info.is_array.Assign(mimg.da); + info.is_unnormalized.Assign(mimg.unrm); + info.is_r128.Assign(mimg.r128); + info.pc.Assign(pc); + + if (gather) { + info.gather_comp.Assign(std::bit_width(mimg.dmask) - 1); + info.is_gather.Assign(true); + } else { + info.has_derivatives.Assign(flags.test(MimgModifier::Derivative)); + } + + // Load all dwords of T# and S#. We will use them as the handle that will guide + // resource tracking pass where to read the sharps. This will later also get patched to the + // backend texture binding index. + const IR::Value tsharp_low = + ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(tsharp_reg + 1), + ir.GetScalarReg(tsharp_reg + 2), ir.GetScalarReg(tsharp_reg + 3)); + const IR::Value tsharp_high = mimg.r128 + ? IR::Value{} + : ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg + 4), + ir.GetScalarReg(tsharp_reg + 5), + ir.GetScalarReg(tsharp_reg + 6), + ir.GetScalarReg(tsharp_reg + 7)); + const IR::Value image_handle = ir.ImageHandle(tsharp_low, tsharp_high); + const IR::Value sampler_handle = + ir.CompositeConstruct(ir.GetScalarReg(sampler_reg), ir.GetScalarReg(sampler_reg + 1), + ir.GetScalarReg(sampler_reg + 2), ir.GetScalarReg(sampler_reg + 3)); + + // Determine how many address registers need to be passed. + // The image type is unknown, so add all 4 possible base registers and resolve later. + int num_addr_regs = 4; + if (info.has_offset) { + ++num_addr_regs; + } + if (info.has_bias) { + ++num_addr_regs; + } + if (info.is_depth) { + ++num_addr_regs; + } + if (info.has_derivatives) { + // The image type is unknown, so add all 6 possible derivative registers and resolve later. + num_addr_regs += 6; + } + + // Fetch all the address registers to pass in the IR instruction. There can be up to 13 + // registers. + const auto get_addr_reg = [&](int index) -> IR::F32 { + if (index >= num_addr_regs) { + return ir.Imm32(0.f); + } + return ir.GetVectorReg(addr_reg + index); + }; + const IR::Value address1 = + ir.CompositeConstruct(get_addr_reg(0), get_addr_reg(1), get_addr_reg(2), get_addr_reg(3)); + const IR::Value address2 = + ir.CompositeConstruct(get_addr_reg(4), get_addr_reg(5), get_addr_reg(6), get_addr_reg(7)); + const IR::Value address3 = + ir.CompositeConstruct(get_addr_reg(8), get_addr_reg(9), get_addr_reg(10), get_addr_reg(11)); + const IR::Value address4 = get_addr_reg(12); + + // Issue the placeholder IR instruction. + IR::Value texel = ir.ImageSampleRaw(image_handle, sampler_handle, address1, address2, address3, + address4, info); + if (info.is_depth && !gather) { + // For non-gather depth sampling, only return a single value. + texel = ir.CompositeExtract(texel, 0); + } + return texel; +} + +void Translator::IMAGE_SAMPLE(const GcnInst& inst) { + const auto& mimg = inst.control.mimg; + IR::VectorReg addr_reg{inst.src[0].code}; + IR::VectorReg dest_reg{inst.dst[0].code}; + const IR::ScalarReg tsharp_reg{inst.src[2].code * 4}; + const IR::ScalarReg sampler_reg{inst.src[3].code * 4}; + const auto flags = MimgModifierFlags(mimg.mod); + + const IR::Value texel = EmitImageSample(ir, inst, tsharp_reg, sampler_reg, addr_reg, false, pc); + for (u32 i = 0; i < 4; i++) { + if (((mimg.dmask >> i) & 1) == 0) { + continue; + } + IR::F32 value; + if (flags.test(MimgModifier::Pcf)) { + value = i < 3 ? IR::F32{texel} : ir.Imm32(1.0f); + } else { + value = IR::F32{ir.CompositeExtract(texel, i)}; + } + ir.SetVectorReg(dest_reg++, value); + } +} + +void Translator::IMAGE_GATHER(const GcnInst& inst) { + const auto& mimg = inst.control.mimg; + IR::VectorReg addr_reg{inst.src[0].code}; + IR::VectorReg dest_reg{inst.dst[0].code}; + const IR::ScalarReg tsharp_reg{inst.src[2].code * 4}; + const IR::ScalarReg sampler_reg{inst.src[3].code * 4}; + const auto flags = MimgModifierFlags(mimg.mod); + + // For gather4 instructions dmask selects which component to read and must have + // only one bit set to 1 + ASSERT_MSG(std::popcount(mimg.dmask) == 1, "Unexpected bits in gather dmask"); + // should be always 1st (R) component for depth + ASSERT(!flags.test(MimgModifier::Pcf) || mimg.dmask & 1); + + const IR::Value texel = EmitImageSample(ir, inst, tsharp_reg, sampler_reg, addr_reg, true, pc); + for (u32 i = 0; i < 4; i++) { + const IR::F32 value = IR::F32{ir.CompositeExtract(texel, i)}; + ir.SetVectorReg(dest_reg++, value); + } +} + +void Translator::IMAGE_GET_LOD(const GcnInst& inst) { + const auto& mimg = inst.control.mimg; + IR::VectorReg dst_reg{inst.dst[0].code}; + IR::VectorReg addr_reg{inst.src[0].code}; + const IR::ScalarReg tsharp_reg{inst.src[2].code * 4}; + + IR::TextureInstInfo info{}; + info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); + + const IR::Value tsharp_low = + ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(tsharp_reg + 1), + ir.GetScalarReg(tsharp_reg + 2), ir.GetScalarReg(tsharp_reg + 3)); + const IR::Value tsharp_high = mimg.r128 + ? IR::Value{} + : ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg + 4), + ir.GetScalarReg(tsharp_reg + 5), + ir.GetScalarReg(tsharp_reg + 6), + ir.GetScalarReg(tsharp_reg + 7)); + const IR::Value body = ir.CompositeConstruct( + ir.GetVectorReg(addr_reg), ir.GetVectorReg(addr_reg + 1), + ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3)); + const IR::Value lod = ir.ImageQueryLod(ir.ImageHandle(tsharp_low, tsharp_high), body, info); + if (mimg.dmask & 1) { + ir.SetVectorReg(dst_reg++, IR::F32{ir.CompositeExtract(lod, 0)}); + } + if (mimg.dmask & 2) { + ir.SetVectorReg(dst_reg++, IR::F32{ir.CompositeExtract(lod, 1)}); + } +} + +} // namespace Shader::Gcn diff --git a/gpu/shadps4/shader_recompiler/info.h b/gpu/shadps4/shader_recompiler/info.h new file mode 100644 index 0000000..5d246cb --- /dev/null +++ b/gpu/shadps4/shader_recompiler/info.h @@ -0,0 +1,219 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include "common/assert.h" +#include "common/types.h" +#include "shader_recompiler/backend/bindings.h" +#include "shader_recompiler/frontend/copy_shader.h" +#include "shader_recompiler/frontend/tessellation.h" +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/passes/srt.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/type.h" +#include "shader_recompiler/params.h" +#include "shader_recompiler/resource.h" +#include "shader_recompiler/runtime_info.h" + +namespace Serialization { +struct Archive; +} + +namespace Shader { + +enum class Qualifier : u8 { + None, + Smooth, + NoPerspective, + PerVertex, + Flat, + Centroid, + Sample, +}; + +/** + * Contains general information generated by the shader recompiler for an input program. + */ +struct InfoPersistent { + BufferResourceList buffers; + ImageResourceList images; + SamplerResourceList samplers; + FMaskResourceList fmasks; + + struct UserDataMask { + void Set(IR::ScalarReg reg) noexcept { + mask |= 1 << static_cast(reg); + } + + u32 Index(IR::ScalarReg reg) const noexcept { + const u32 reg_mask = (1 << static_cast(reg)) - 1; + return std::popcount(mask & reg_mask); + } + + u32 NumRegs() const noexcept { + return std::popcount(mask); + } + + u32 mask; + }; + UserDataMask ud_mask{}; + u32 fetch_shader_sgpr_base{}; + u32 shared_memory_scratch_size{}; + + u64 pgm_hash{}; + + s32 tess_consts_dword_offset = -1; + IR::ScalarReg tess_consts_ptr_base = IR::ScalarReg::Max; + HwStage hw_stage; + SwStage sw_stage; + + u8 mrt_mask{}; + bool has_fetch_shader{}; + bool has_bitwise_xor{}; + bool uses_dma{}; + + InfoPersistent() = default; + InfoPersistent(HwStage hw_stage_, SwStage sw_stage_, u64 pgm_hash_) + : hw_stage{hw_stage_}, sw_stage{sw_stage_}, pgm_hash{pgm_hash_} {} +}; + +struct Info : InfoPersistent { + struct AttributeFlags { + bool Get(IR::Attribute attrib, u32 comp = 0) const { + return flags[Index(attrib)] & (1 << comp); + } + + bool GetAny(IR::Attribute attrib) const { + return flags[Index(attrib)]; + } + + void Set(IR::Attribute attrib, u32 comp = 0) { + flags[Index(attrib)] |= (1 << comp); + } + + u32 NumComponents(IR::Attribute attrib) const { + return 4; + } + + static size_t Index(IR::Attribute attrib) { + return static_cast(attrib); + } + + std::array flags; + }; + + enum class ReadConstType { + None = 0, + Immediate = 1 << 0, + Dynamic = 1 << 1, + }; + + struct Interpolation { + Qualifier primary; + Qualifier auxiliary; + }; + + std::span user_data; + std::vector flattened_ud_buf; + PersistentSrtInfo srt_info; + + AttributeFlags loads{}; + AttributeFlags stores{}; + + ReadConstType readconst_types{}; + CopyShaderData gs_copy_data; + u32 uses_patches{}; + + VAddr pgm_base; + bool has_storage_images{}; + bool has_discard{}; + bool has_image_gather{}; + bool has_image_query{}; + bool has_readconst{}; + bool uses_buffer_atomic_float_min_max{}; + bool uses_image_atomic_float_min_max{}; + bool uses_lane_id{}; + bool uses_shader_clock{}; + bool uses_group_quad{}; + bool uses_group_shuffle{}; + bool uses_group_ballot{}; + IR::Type shared_types{}; + bool uses_fp16{}; + bool uses_fp64{}; + bool uses_pack_10_11_11{}; + bool uses_unpack_10_11_11{}; + bool uses_buffer_int64_atomics{}; + bool uses_shared_int64_atomics{}; + bool stores_tess_level_outer{}; + bool stores_tess_level_inner{}; + bool translation_failed{}; + + std::array fs_interpolation{}; + + Info() = default; + Info(HwStage stage_, SwStage l_stage_, ShaderParams params) + : InfoPersistent(stage_, l_stage_, params.hash), pgm_base{params.Base()}, + user_data{params.user_data} {} + + template + inline T ReadUdSharp(u32 sharp_idx) const noexcept { + return *reinterpret_cast(&flattened_ud_buf[sharp_idx]); + } + + template + T ReadUdReg(u32 ptr_index, u32 dword_offset) const noexcept { + T data; + const u32* base = user_data.data(); + if (ptr_index != IR::NumScalarRegs) { + std::memcpy(&base, &user_data[ptr_index], sizeof(base)); + base = reinterpret_cast(VAddr(base) & 0xFFFFFFFFFFFFULL); + } + std::memcpy(&data, base + dword_offset, sizeof(T)); + return data; + } + + void PushUd(Backend::Bindings& bnd, PushData& push) const { + u32 mask = ud_mask.mask; + while (mask) { + const u32 index = std::countr_zero(mask); + ASSERT(bnd.user_data < NUM_USER_DATA_REGS && index < NUM_USER_DATA_REGS); + mask &= ~(1U << index); + push.ud_regs[bnd.user_data++] = user_data[index]; + } + } + + void AddBindings(Backend::Bindings& bnd) const { + bnd.buffer += buffers.size(); + bnd.unified += buffers.size() + images.size() + samplers.size(); + bnd.user_data += ud_mask.NumRegs(); + } + + void RefreshFlatBuf() { + flattened_ud_buf.resize(srt_info.flattened_bufsize_dw); + ASSERT(user_data.size() <= NUM_USER_DATA_REGS); + std::memcpy(flattened_ud_buf.data(), user_data.data(), user_data.size_bytes()); + if (srt_info.walker_func) { + srt_info.walker_func(user_data.data(), flattened_ud_buf.data()); + } + } + + void ReadTessConstantBuffer(TessellationDataConstantBuffer& tess_constants) const { + ASSERT(tess_consts_dword_offset >= 0); // We've already tracked the V# UD + auto buf = ReadUdReg(static_cast(tess_consts_ptr_base), + static_cast(tess_consts_dword_offset)); + VAddr tess_constants_addr = buf.base_address; + memcpy(&tess_constants, + reinterpret_cast(tess_constants_addr), + sizeof(tess_constants)); + } + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& ar); +}; +DECLARE_ENUM_FLAG_OPERATORS(Info::ReadConstType); + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/ir/abstract_syntax_list.cpp b/gpu/shadps4/shader_recompiler/ir/abstract_syntax_list.cpp new file mode 100644 index 0000000..0d967ac --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/abstract_syntax_list.cpp @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "abstract_syntax_list.h" + +namespace Shader::IR { + +std::string DumpASLNode(const AbstractSyntaxNode& node, + const std::map& block_to_index, + const std::map& inst_to_index) { + switch (node.type) { + case AbstractSyntaxNode::Type::Block: + return fmt::format("Block: ${}", block_to_index.at(node.data.block)); + case AbstractSyntaxNode::Type::If: + return fmt::format("If: cond = %{}, body = ${}, merge = ${}", + inst_to_index.at(node.data.if_node.cond.Inst()), + block_to_index.at(node.data.if_node.body), + block_to_index.at(node.data.if_node.merge)); + case AbstractSyntaxNode::Type::EndIf: + return fmt::format("EndIf: merge = ${}", block_to_index.at(node.data.end_if.merge)); + case AbstractSyntaxNode::Type::Loop: + return fmt::format("Loop: body = ${}, continue = ${}, merge = ${}", + block_to_index.at(node.data.loop.body), + block_to_index.at(node.data.loop.continue_block), + block_to_index.at(node.data.loop.merge)); + case AbstractSyntaxNode::Type::Repeat: + return fmt::format("Repeat: cond = %{}, header = ${}, merge = ${}", + inst_to_index.at(node.data.repeat.cond.Inst()), + block_to_index.at(node.data.repeat.loop_header), + block_to_index.at(node.data.repeat.merge)); + case AbstractSyntaxNode::Type::Break: + return fmt::format("Break: cond = %{}, merge = ${}, skip = ${}", + inst_to_index.at(node.data.break_node.cond.Inst()), + block_to_index.at(node.data.break_node.merge), + block_to_index.at(node.data.break_node.skip)); + case AbstractSyntaxNode::Type::Return: + return "Return"; + case AbstractSyntaxNode::Type::Unreachable: + return "Unreachable"; + }; + UNREACHABLE(); +} + +} // namespace Shader::IR \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/abstract_syntax_list.h b/gpu/shadps4/shader_recompiler/ir/abstract_syntax_list.h new file mode 100644 index 0000000..a620bac --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/abstract_syntax_list.h @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +class Block; + +struct AbstractSyntaxNode { + enum class Type { + Block, + If, + EndIf, + Loop, + Repeat, + Break, + Return, + Unreachable, + }; + union Data { + Block* block; + struct { + U1 cond; + Block* body; + Block* merge; + } if_node; + struct { + Block* merge; + } end_if; + struct { + Block* body; + Block* continue_block; + Block* merge; + } loop; + struct { + U1 cond; + Block* loop_header; + Block* merge; + } repeat; + struct { + U1 cond; + Block* merge; + Block* skip; + } break_node; + }; + + Data data{}; + Type type{}; +}; +using AbstractSyntaxList = std::vector; + +std::string DumpASLNode(const AbstractSyntaxNode& node, + const std::map& block_to_index, + const std::map& inst_to_index); + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/attribute.cpp b/gpu/shadps4/shader_recompiler/ir/attribute.cpp new file mode 100644 index 0000000..3f07855 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/attribute.cpp @@ -0,0 +1,183 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "shader_recompiler/ir/attribute.h" + +namespace Shader::IR { + +std::string NameOf(Attribute attribute) { + switch (attribute) { + case Attribute::RenderTarget0: + return "RenderTarget0"; + case Attribute::RenderTarget1: + return "RenderTarget1"; + case Attribute::RenderTarget2: + return "RenderTarget2"; + case Attribute::RenderTarget3: + return "RenderTarget3"; + case Attribute::RenderTarget4: + return "RenderTarget4"; + case Attribute::RenderTarget5: + return "RenderTarget5"; + case Attribute::RenderTarget6: + return "RenderTarget6"; + case Attribute::RenderTarget7: + return "RenderTarget7"; + case Attribute::Depth: + return "Depth"; + case Attribute::Null: + return "Null"; + case Attribute::Position0: + return "Position0"; + case Attribute::Position1: + return "Position1"; + case Attribute::Position2: + return "Position2"; + case Attribute::Position3: + return "Position3"; + case Attribute::Param0: + return "Param0"; + case Attribute::Param1: + return "Param1"; + case Attribute::Param2: + return "Param2"; + case Attribute::Param3: + return "Param3"; + case Attribute::Param4: + return "Param4"; + case Attribute::Param5: + return "Param5"; + case Attribute::Param6: + return "Param6"; + case Attribute::Param7: + return "Param7"; + case Attribute::Param8: + return "Param8"; + case Attribute::Param9: + return "Param9"; + case Attribute::Param10: + return "Param10"; + case Attribute::Param11: + return "Param11"; + case Attribute::Param12: + return "Param12"; + case Attribute::Param13: + return "Param13"; + case Attribute::Param14: + return "Param14"; + case Attribute::Param15: + return "Param15"; + case Attribute::Param16: + return "Param16"; + case Attribute::Param17: + return "Param17"; + case Attribute::Param18: + return "Param18"; + case Attribute::Param19: + return "Param19"; + case Attribute::Param20: + return "Param20"; + case Attribute::Param21: + return "Param21"; + case Attribute::Param22: + return "Param22"; + case Attribute::Param23: + return "Param23"; + case Attribute::Param24: + return "Param24"; + case Attribute::Param25: + return "Param25"; + case Attribute::Param26: + return "Param26"; + case Attribute::Param27: + return "Param27"; + case Attribute::Param28: + return "Param28"; + case Attribute::Param29: + return "Param29"; + case Attribute::Param30: + return "Param30"; + case Attribute::Param31: + return "Param31"; + case Attribute::ClipDistance: + return "ClipDistance"; + case Attribute::CullDistance: + return "CullDistance"; + case Attribute::RenderTargetIndex: + return "RenderTargetIndex"; + case Attribute::ViewportIndex: + return "ViewportIndex"; + case Attribute::VertexId: + return "VertexId"; + case Attribute::PrimitiveId: + return "PrimitiveId"; + case Attribute::InstanceId: + return "InstanceId"; + case Attribute::IsFrontFace: + return "IsFrontFace"; + case Attribute::SampleIndex: + return "SampleIndex"; + case Attribute::GlobalInvocationId: + return "GlobalInvocationId"; + case Attribute::WorkgroupId: + return "WorkgroupId"; + case Attribute::WorkgroupIndex: + return "WorkgroupIndex"; + case Attribute::LocalInvocationId: + return "LocalInvocationId"; + case Attribute::LocalInvocationIndex: + return "LocalInvocationIndex"; + case Attribute::FragCoord: + return "FragCoord"; + case Attribute::BaryCoordNoPersp: + return "BaryCoordNoPersp"; + case Attribute::BaryCoordNoPerspCentroid: + return "BaryCoordNoPerspCentroid"; + case Attribute::BaryCoordNoPerspSample: + return "BaryCoordNoPerspSample"; + case Attribute::BaryCoordSmooth: + return "BaryCoordSmooth"; + case Attribute::BaryCoordSmoothCentroid: + return "BaryCoordSmoothCentroid"; + case Attribute::BaryCoordSmoothSample: + return "BaryCoordSmoothSample"; + case Attribute::BaryCoordPullModel: + return "BaryCoordPullModel"; + case Attribute::InvocationId: + return "InvocationId"; + case Attribute::PatchVertices: + return "PatchVertices"; + case Attribute::TessellationEvaluationPointU: + return "TessellationEvaluationPointU"; + case Attribute::TessellationEvaluationPointV: + return "TessellationEvaluationPointV"; + case Attribute::PackedHullInvocationInfo: + return "PackedHullInvocationInfo"; + case Attribute::OffChipLdsBase: + return "OffChipLdsBase"; + case Attribute::TessFactorsBufferBase: + return "TessFactorsBufferBase"; + case Attribute::PointSize: + return "PointSize"; + case Attribute::StencilRef: + return "StencilRef"; + case Attribute::SampleMask: + return "SampleMask"; + case Attribute::PackedAncillary: + return "PackedAncillary"; + case Attribute::SubgroupLtMask: + return "SubgroupLtMask"; + case Attribute::BaseVertex: + return "BaseVertex"; + case Attribute::BaseInstance: + return "BaseInstance"; + case Attribute::IsHelperInvocation: + return "IsHelperInvocation"; + default: + break; + } + return fmt::format("", static_cast(attribute)); +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/attribute.h b/gpu/shadps4/shader_recompiler/ir/attribute.h new file mode 100644 index 0000000..79f6809 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/attribute.h @@ -0,0 +1,150 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/assert.h" +#include "common/types.h" + +namespace Shader::IR { + +enum class Attribute : u64 { + // Export targets + RenderTarget0 = 0, + RenderTarget1 = 1, + RenderTarget2 = 2, + RenderTarget3 = 3, + RenderTarget4 = 4, + RenderTarget5 = 5, + RenderTarget6 = 6, + RenderTarget7 = 7, + Depth = 8, + Null = 9, + Position0 = 12, + Position1 = 13, + Position2 = 14, + Position3 = 15, + Param0 = 32, + Param1 = 33, + Param2 = 34, + Param3 = 35, + Param4 = 36, + Param5 = 37, + Param6 = 38, + Param7 = 39, + Param8 = 40, + Param9 = 41, + Param10 = 42, + Param11 = 43, + Param12 = 44, + Param13 = 45, + Param14 = 46, + Param15 = 47, + Param16 = 48, + Param17 = 49, + Param18 = 50, + Param19 = 51, + Param20 = 52, + Param21 = 53, + Param22 = 54, + Param23 = 55, + Param24 = 56, + Param25 = 57, + Param26 = 58, + Param27 = 59, + Param28 = 60, + Param29 = 61, + Param30 = 62, + Param31 = 63, + // System values + ClipDistance = 64, + CullDistance = 65, + RenderTargetIndex = 66, + ViewportIndex = 67, + VertexId = 68, + PrimitiveId = 69, + InstanceId = 70, + IsFrontFace = 71, + SampleIndex = 72, + GlobalInvocationId = 73, + WorkgroupId = 74, + WorkgroupIndex = 75, + LocalInvocationId = 76, + LocalInvocationIndex = 77, + FragCoord = 78, + BaryCoordNoPersp = 79, + BaryCoordNoPerspCentroid = 80, + BaryCoordNoPerspSample = 81, + BaryCoordSmooth = 82, + BaryCoordSmoothCentroid = 83, + BaryCoordSmoothSample = 84, + BaryCoordPullModel = 85, + InvocationId = 86, // TCS id in output patch and instanced geometry shader id + PatchVertices = 87, + TessellationEvaluationPointU = 88, + TessellationEvaluationPointV = 89, + PackedHullInvocationInfo = 90, // contains patch id within the VGT and invocation ID + OffChipLdsBase = 91, + TessFactorsBufferBase = 92, + PointSize = 93, + StencilRef = 94, + SampleMask = 95, + PackedAncillary = 96, + SubgroupLtMask = 97, + BaseVertex = 98, + BaseInstance = 99, + IsHelperInvocation = 100, + Max, +}; + +constexpr size_t NumAttributes = static_cast(Attribute::Max); +constexpr size_t NumRenderTargets = 8; +constexpr size_t NumParams = 32; + +constexpr bool IsPosition(Attribute attribute) noexcept { + return attribute >= Attribute::Position0 && attribute <= Attribute::Position3; +} + +constexpr bool IsTessCoord(Attribute attribute) noexcept { + return attribute >= Attribute::TessellationEvaluationPointU && + attribute <= Attribute::TessellationEvaluationPointV; +} + +constexpr bool IsParam(Attribute attribute) noexcept { + return attribute >= Attribute::Param0 && attribute <= Attribute::Param31; +} + +constexpr bool IsMrt(Attribute attribute) noexcept { + return attribute >= Attribute::RenderTarget0 && attribute <= Attribute::RenderTarget7; +} + +constexpr bool IsBarycentricCoord(Attribute attribute) noexcept { + return attribute >= Attribute::BaryCoordNoPersp && + attribute <= Attribute::BaryCoordSmoothSample; +} + +[[nodiscard]] std::string NameOf(Attribute attribute); + +[[nodiscard]] constexpr Attribute operator+(Attribute attr, int num) { + const int result{static_cast(attr) + num}; + if (result > static_cast(Attribute::Param31)) { + UNREACHABLE_MSG("Overflow on register arithmetic"); + } + if (result < static_cast(Attribute::RenderTarget0)) { + UNREACHABLE_MSG("Underflow on register arithmetic"); + } + return static_cast(result); +} + +} // namespace Shader::IR + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(const Shader::IR::Attribute attribute, format_context& ctx) const { + return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(attribute)); + } +}; diff --git a/gpu/shadps4/shader_recompiler/ir/basic_block.cpp b/gpu/shadps4/shader_recompiler/ir/basic_block.cpp new file mode 100644 index 0000000..b5b514d --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/basic_block.cpp @@ -0,0 +1,205 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +Block::Block(Common::ObjectPool& inst_pool_) : inst_pool{&inst_pool_} {} + +Block::~Block() = default; + +void Block::AppendNewInst(Opcode op, std::initializer_list args) { + PrependNewInst(end(), op, args); +} + +Block::iterator Block::PrependNewInst(iterator insertion_point, const Inst& base_inst) { + Inst* const inst{inst_pool->Create(base_inst)}; + inst->SetParent(this); + return instructions.insert(insertion_point, *inst); +} + +Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode op, + std::initializer_list args, u32 flags) { + Inst* const inst{inst_pool->Create(op, flags)}; + inst->SetParent(this); + const auto result_it{instructions.insert(insertion_point, *inst)}; + + if (inst->NumArgs() != args.size()) { + UNREACHABLE_MSG("Invalid number of arguments {} in {}", args.size(), op); + } + std::ranges::for_each(args, [inst, index = size_t{0}](const Value& arg) mutable { + inst->SetArg(index, arg); + ++index; + }); + return result_it; +} + +void Block::AddBranch(Block* block) { + if (std::ranges::find(imm_successors, block) != imm_successors.end()) { + UNREACHABLE_MSG("Successor already inserted"); + } + if (std::ranges::find(block->imm_predecessors, this) != block->imm_predecessors.end()) { + UNREACHABLE_MSG("Predecessor already inserted"); + } + imm_successors.push_back(block); + block->imm_predecessors.push_back(this); +} + +static std::string BlockToIndex(const std::map& block_to_index, + Block* block) { + if (const auto it{block_to_index.find(block)}; it != block_to_index.end()) { + return fmt::format("{{Block ${}}}", it->second); + } + return fmt::format("$", reinterpret_cast(block)); +} + +static size_t InstIndex(std::map& inst_to_index, size_t& inst_index, + const Inst* inst) { + const auto [it, is_inserted]{inst_to_index.emplace(inst, inst_index + 1)}; + if (is_inserted) { + ++inst_index; + } + return it->second; +} + +static std::string ArgToIndex(std::map& inst_to_index, size_t& inst_index, + const Value& arg) { + if (arg.IsEmpty()) { + return ""; + } + if (!arg.IsImmediate()) { + return fmt::format("%{}", InstIndex(inst_to_index, inst_index, arg.Inst())); + } + switch (arg.Type()) { + case Type::U1: + return fmt::format("#{}", arg.U1() ? "true" : "false"); + case Type::U8: + return fmt::format("#{}", arg.U8()); + case Type::U16: + return fmt::format("#{}", arg.U16()); + case Type::U32: + return fmt::format("#{}", arg.U32()); + case Type::U64: + return fmt::format("#{}", arg.U64()); + case Type::F32: + return fmt::format("#{}", arg.F32()); + case Type::ScalarReg: + return fmt::format("{}", arg.ScalarReg()); + case Type::VectorReg: + return fmt::format("{}", arg.VectorReg()); + case Type::VirtualReg: + return fmt::format("{}", arg.VirtualReg()); + case Type::Attribute: + return fmt::format("{}", arg.Attribute()); + case Type::Patch: + return fmt::format("{}", arg.Patch()); + default: + return ""; + } +} + +static std::string RegTagInfo(const RegTag tag) { + switch (tag.type) { + case RegType::ScalarReg: + return fmt::format("{}", tag.sreg); + case RegType::VectorReg: + return fmt::format("{}", tag.vreg); + case RegType::VirtualReg: + return fmt::format("{}", tag.reg); + case RegType::GotoVariable: + return fmt::format("GOTO{}", tag.index); + case RegType::VccLo: + return "VCC_LO"; + case RegType::VccHi: + return "VCC_HI"; + case RegType::Exec: + return "EXEC"; + case RegType::Scc: + return "SCC"; + case RegType::M0: + return "M0"; + default: + UNREACHABLE(); + } +} + +std::string DumpBlock(const Block& block) { + size_t inst_index{0}; + std::map inst_to_index; + return DumpBlock(block, {}, inst_to_index, inst_index); +} + +std::string DumpBlock(const Block& block, const std::map& block_to_index, + std::map& inst_to_index, size_t& inst_index) { + std::string ret{"Block"}; + if (const auto it{block_to_index.find(&block)}; it != block_to_index.end()) { + ret += fmt::format(" ${}", it->second); + } + ret += " predecessors ["; + for (auto* block : block.ImmPredecessors()) { + const auto it{block_to_index.find(block)}; + ASSERT(it != block_to_index.end()); + ret += fmt::format("${}, ", it->second); + } + if (!block.ImmPredecessors().empty()) { + ret.pop_back(); + ret.pop_back(); + } + ret += "]\n"; + for (const Inst& inst : block) { + const Opcode op{inst.GetOpcode()}; + ret += fmt::format("[{:016x}] ", reinterpret_cast(&inst)); + if (TypeOf(op) != Type::Void) { + ret += fmt::format("%{:<5} = {}", InstIndex(inst_to_index, inst_index, &inst), op); + } else { + ret += fmt::format(" {}", op); // '%00000 = ' -> 1 + 5 + 3 = 9 spaces + } + + if (op == Opcode::ReadConst || op == Opcode::ImageSampleRaw) { + ret += fmt::format(" (flags={:#x}) ", inst.Flags()); + } else if (op == Opcode::ReadConstBuffer) { + const auto info = inst.Flags(); + ret += fmt::format(" (sharp_source={}, flatbuf_off_dw={:#x}) ", bool(info.sharp_source), + info.flatbuf_off_dw.Value()); + } + const size_t arg_count{inst.NumArgs()}; + for (size_t arg_index = 0; arg_index < arg_count; ++arg_index) { + const Value arg{inst.Arg(arg_index)}; + const std::string arg_str{ArgToIndex(inst_to_index, inst_index, arg)}; + ret += arg_index != 0 ? ", " : " "; + if (op == Opcode::Phi) { + ret += fmt::format("[ {}, {} ]", arg_str, + BlockToIndex(block_to_index, inst.PhiBlock(arg_index))); + } else { + ret += arg_str; + } + if (op != Opcode::Phi) { + const Type actual_type{arg.Type()}; + const Type expected_type{ArgTypeOf(op, arg_index)}; + if (!AreTypesCompatible(actual_type, expected_type)) { + ret += fmt::format("", actual_type, expected_type); + } + } + } + if (TypeOf(op) != Type::Void) { + ret += fmt::format(" (uses: {})", inst.UseCount()); + if (auto tag = inst.GetRegTag()) { + ret += fmt::format(" (tag: {})", RegTagInfo(tag)); + } + if (op == Opcode::Phi) { + ret += fmt::format(" (scc{})", inst.scc_index); + } + ret += '\n'; + } else { + ret += '\n'; + } + } + return ret; +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/basic_block.h b/gpu/shadps4/shader_recompiler/ir/basic_block.h new file mode 100644 index 0000000..5874bfe --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/basic_block.h @@ -0,0 +1,162 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include + +#include "common/object_pool.h" +#include "common/types.h" +#include "shader_recompiler/ir/microinstruction.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/ssa.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::Gcn { +struct Block; +} + +namespace Shader::IR { + +class Block { +public: + using InstructionList = boost::intrusive::list; + using size_type = InstructionList::size_type; + using iterator = InstructionList::iterator; + using const_iterator = InstructionList::const_iterator; + using reverse_iterator = InstructionList::reverse_iterator; + using const_reverse_iterator = InstructionList::const_reverse_iterator; + + explicit Block(Common::ObjectPool& inst_pool_); + ~Block(); + + Block(const Block&) = delete; + Block& operator=(const Block&) = delete; + + Block(Block&&) = default; + Block& operator=(Block&&) = default; + + void AppendNewInst(Opcode op, std::initializer_list args); + + iterator PrependNewInst(iterator insertion_point, const Inst& base_inst); + iterator PrependNewInst(iterator insertion_point, Opcode op, + std::initializer_list args = {}, u32 flags = 0); + + void AddBranch(Block* block); + + [[nodiscard]] InstructionList& Instructions() noexcept { + return instructions; + } + [[nodiscard]] const InstructionList& Instructions() const noexcept { + return instructions; + } + + [[nodiscard]] std::span ImmPredecessors() const noexcept { + return imm_predecessors; + } + [[nodiscard]] std::span ImmSuccessors() const noexcept { + return imm_successors; + } + + template + void SetDefinition(T def) { + definition = std::bit_cast(def); + } + + template + [[nodiscard]] T Definition() const noexcept { + return std::bit_cast(definition); + } + + [[nodiscard]] bool empty() const { + return instructions.empty(); + } + [[nodiscard]] size_type size() const { + return instructions.size(); + } + + [[nodiscard]] Inst& front() { + return instructions.front(); + } + [[nodiscard]] const Inst& front() const { + return instructions.front(); + } + + [[nodiscard]] Inst& back() { + return instructions.back(); + } + [[nodiscard]] const Inst& back() const { + return instructions.back(); + } + + [[nodiscard]] iterator begin() { + return instructions.begin(); + } + [[nodiscard]] const_iterator begin() const { + return instructions.cbegin(); + } + [[nodiscard]] iterator end() { + return instructions.end(); + } + [[nodiscard]] const_iterator end() const { + return instructions.cend(); + } + + [[nodiscard]] reverse_iterator rbegin() { + return instructions.rbegin(); + } + [[nodiscard]] const_reverse_iterator rbegin() const { + return instructions.rbegin(); + } + [[nodiscard]] reverse_iterator rend() { + return instructions.rend(); + } + [[nodiscard]] const_reverse_iterator rend() const { + return instructions.rend(); + } + + [[nodiscard]] const_iterator cbegin() const { + return instructions.cbegin(); + } + [[nodiscard]] const_iterator cend() const { + return instructions.cend(); + } + + [[nodiscard]] const_reverse_iterator crbegin() const { + return instructions.crbegin(); + } + [[nodiscard]] const_reverse_iterator crend() const { + return instructions.crend(); + } + + SsaState ssa_state; + const Shader::Gcn::Block* cfg_block{}; + U1 branch_cond{}; + + Common::ObjectPool* inst_pool; + InstructionList instructions; + + Block* immediate_dominator{}; + std::vector dominance_frontiers; + u32 po_index{}; + + std::vector imm_predecessors; + std::vector imm_successors; + + u32 definition{}; +}; + +using BlockList = std::vector; + +[[nodiscard]] std::string DumpBlock(const Block& block); + +[[nodiscard]] std::string DumpBlock(const Block& block, + const std::map& block_to_index, + std::map& inst_to_index, + size_t& inst_index); + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/breadth_first_search.h b/gpu/shadps4/shader_recompiler/ir/breadth_first_search.h new file mode 100644 index 0000000..8ff7e86 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/breadth_first_search.h @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +// Use typename Instruction so the function can be used to return either const or mutable +// Insts depending on the context. +template +auto BreadthFirstSearch(Instruction* inst, Pred&& pred) + -> std::invoke_result_t { + // Most often case the instruction is the desired already. + if (std::optional result = pred(inst)) { + return result; + } + + // Breadth-first search visiting the right most arguments first + boost::container::small_vector visited; + std::queue queue; + queue.push(inst); + + while (!queue.empty()) { + // Pop one instruction from the queue + Instruction* inst{queue.front()}; + queue.pop(); + if (std::optional result = pred(inst)) { + // This is the instruction we were looking for + return result; + } + // Visit the right most arguments first + for (size_t arg = inst->NumArgs(); arg--;) { + Value arg_value{inst->Arg(arg)}; + if (arg_value.IsImmediate()) { + continue; + } + // Queue instruction if it hasn't been visited + Instruction* arg_inst{arg_value.Inst()}; + if (std::ranges::find(visited, arg_inst) == visited.end()) { + visited.push_back(arg_inst); + queue.push(arg_inst); + } + } + } + // SSA tree has been traversed and the result hasn't been found + return std::nullopt; +} + +template +auto BreadthFirstSearch(const Value& value, Pred&& pred) + -> std::invoke_result_t { + if (value.IsImmediate()) { + // Nothing to do with immediates + return std::nullopt; + } + return BreadthFirstSearch(value.Inst(), pred); +} + +template +auto BreadthFirstSearch(Value value, Pred&& pred) -> std::invoke_result_t { + if (value.IsImmediate()) { + // Nothing to do with immediates + return std::nullopt; + } + return BreadthFirstSearch(value.Inst(), pred); +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/condition.h b/gpu/shadps4/shader_recompiler/ir/condition.h new file mode 100644 index 0000000..5ee6d15 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/condition.h @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace Shader::IR { + +enum class Condition : u32 { + False, + True, + Scc0, + Scc1, + Vccz, + Vccnz, + Execz, + Execnz, +}; + +constexpr std::string_view NameOf(Condition condition) { + switch (condition) { + case Condition::False: + return "False"; + case Condition::True: + return "True"; + case Condition::Scc0: + return "Scc0"; + case Condition::Scc1: + return "Scc1"; + case Condition::Vccz: + return "Vccz"; + case Condition::Vccnz: + return "Vccnz"; + case Condition::Execz: + return "Execz"; + case Condition::Execnz: + return "Execnz"; + default: + UNREACHABLE(); + } +} + +} // namespace Shader::IR + +template <> +struct fmt::formatter : formatter { + auto format(const Shader::IR::Condition cond, format_context& ctx) const { + return formatter::format(NameOf(cond), ctx); + } +}; diff --git a/gpu/shadps4/shader_recompiler/ir/debug_print.h b/gpu/shadps4/shader_recompiler/ir/debug_print.h new file mode 100644 index 0000000..a7a0c49 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/debug_print.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/bit_field.h" +#include "shader_recompiler/ir/opcodes.h" +#include "common/types.h" // bbport: include path + +#pragma once + +namespace Shader::IR { + +constexpr size_t DEBUGPRINT_NUM_FORMAT_ARGS = NumArgsOf(IR::Opcode::DebugPrint) - 1; + +union DebugPrintFlags { + u32 raw; + // For now, only flag is the number of variadic format args actually used + // So bitfield not really needed + BitField<0, 32, u32> num_args; +}; + +} // namespace Shader::IR \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/dominance.cpp b/gpu/shadps4/shader_recompiler/ir/dominance.cpp new file mode 100644 index 0000000..6743c19 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/dominance.cpp @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/dominance.h" + +namespace Shader::IR { + +// Those methods are an implementation of the algorithms on "A Simple, Fast Dominance Algorithm". +// https://hexrat.cc/data/pdf/optimization/opt3.pdf + +void ComputeDominators(const IR::BlockList& post_order) { + IR::Block* const entry = post_order.back(); + entry->immediate_dominator = entry; + + const auto intersect = [&](IR::Block* block1, IR::Block* block2) -> IR::Block* { + while (block1 != block2) { + while (block1->po_index < block2->po_index) { + block1 = block1->immediate_dominator; + } + while (block2->po_index < block1->po_index) { + block2 = block2->immediate_dominator; + } + } + return block1; + }; + + bool modified; + do { + modified = false; + for (auto it = post_order.rbegin() + 1; it != post_order.rend(); ++it) { + IR::Block* block{*it}; + IR::Block* new_idom{}; + + for (IR::Block* const pred : block->ImmPredecessors()) { + if (pred->immediate_dominator) { + new_idom = new_idom ? intersect(new_idom, pred) : pred; + } + } + + if (block->immediate_dominator != new_idom) { + block->immediate_dominator = new_idom; + modified = true; + } + } + } while (modified); +} + +void ComputeDominanceFrontiers(const IR::BlockList& post_order) { + for (IR::Block* block : post_order) { + if (block->ImmPredecessors().size() < 2) { + continue; + } + for (IR::Block* const pred : block->ImmPredecessors()) { + IR::Block* current = pred; + while (current != block->immediate_dominator) { + current->dominance_frontiers.push_back(block); + current = current->immediate_dominator; + } + } + } +} + +} // namespace Shader::IR \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/dominance.h b/gpu/shadps4/shader_recompiler/ir/dominance.h new file mode 100644 index 0000000..62fbf6f --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/dominance.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/ir/basic_block.h" + +namespace Shader::IR { + +void ComputeDominators(const IR::BlockList& post_order); + +void ComputeDominanceFrontiers(const IR::BlockList& post_order); + +inline bool Dominates(IR::Block* a, IR::Block* b) { + IR::Block* current = b; + while (current) { + if (current == a) { + return true; + } + if (current->immediate_dominator == current) { + break; + } + current = current->immediate_dominator; + } + return false; +} + +} // namespace Shader::IR \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/ir_emitter.cpp b/gpu/shadps4/shader_recompiler/ir/ir_emitter.cpp new file mode 100644 index 0000000..b309ee4 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/ir_emitter.cpp @@ -0,0 +1,2229 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include "common/assert.h" +#include "shader_recompiler/ir/debug_print.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { +namespace { +[[noreturn]] void ThrowInvalidType(Type type, + std::source_location loc = std::source_location::current()) { + const std::string functionName = loc.function_name(); + const int lineNumber = loc.line(); + UNREACHABLE_MSG("Invalid type = {}, functionName = {}, line = {}", u32(type), functionName, + lineNumber); +} +} // Anonymous namespace + +U1 IREmitter::Imm1(bool value) const { + return U1{Value{value}}; +} + +U8 IREmitter::Imm8(u8 value) const { + return U8{Value{value}}; +} + +U16 IREmitter::Imm16(u16 value) const { + return U16{Value{value}}; +} + +U32 IREmitter::Imm32(u32 value) const { + return U32{Value{value}}; +} + +U32 IREmitter::Imm32(s32 value) const { + return U32{Value{static_cast(value)}}; +} + +F32 IREmitter::Imm32(f32 value) const { + return F32{Value{value}}; +} + +U64 IREmitter::Imm64(u64 value) const { + return U64{Value{value}}; +} + +U64 IREmitter::Imm64(s64 value) const { + return U64{Value{static_cast(value)}}; +} + +F64 IREmitter::Imm64(f64 value) const { + return F64{Value{value}}; +} + +template <> +IR::U32 IREmitter::BitCast(const IR::U1& value) { + return IR::U32{Select(value, Imm32(1), Imm32(0))}; +} + +template <> +IR::U32 IREmitter::BitCast(const IR::F32& value) { + return Inst(Opcode::BitCastU32F32, value); +} + +template <> +IR::F32 IREmitter::BitCast(const IR::U32& value) { + return Inst(Opcode::BitCastF32U32, value); +} + +template <> +IR::U16 IREmitter::BitCast(const IR::F16& value) { + return Inst(Opcode::BitCastU16F16, value); +} + +template <> +IR::F16 IREmitter::BitCast(const IR::U16& value) { + return Inst(Opcode::BitCastF16U16, value); +} + +U1 IREmitter::ConditionRef(const U1& value) { + return Inst(Opcode::ConditionRef, value); +} + +void IREmitter::Prologue() { + Inst(Opcode::Prologue); +} + +void IREmitter::Epilogue() { + Inst(Opcode::Epilogue); +} + +void IREmitter::Discard() { + Inst(Opcode::Discard); +} + +void IREmitter::Discard(const U1& cond) { + Inst(Opcode::DiscardCond, cond); +} + +void IREmitter::Barrier() { + Inst(Opcode::Barrier); +} + +void IREmitter::WorkgroupMemoryBarrier() { + Inst(Opcode::WorkgroupMemoryBarrier); +} + +void IREmitter::DeviceMemoryBarrier() { + Inst(Opcode::DeviceMemoryBarrier); +} + +U32 IREmitter::GetUserData(IR::ScalarReg reg) { + ASSERT(static_cast(reg) < IR::NumScalarRegs); + return Inst(Opcode::GetUserData, reg); +} + +template <> +U32 IREmitter::GetScalarReg(IR::ScalarReg reg) { + ASSERT(static_cast(reg) < IR::NumScalarRegs); + return Inst(Opcode::GetScalarRegister, reg); +} + +template <> +F32 IREmitter::GetScalarReg(IR::ScalarReg reg) { + return BitCast(GetScalarReg(reg)); +} + +template <> +U32 IREmitter::GetVectorReg(IR::VectorReg reg) { + ASSERT(static_cast(reg) < IR::NumVectorRegs); + return Inst(Opcode::GetVectorRegister, reg); +} + +template <> +F32 IREmitter::GetVectorReg(IR::VectorReg reg) { + return BitCast(GetVectorReg(reg)); +} + +void IREmitter::SetScalarReg(IR::ScalarReg reg, const U32F32& value) { + ASSERT(reg < IR::ScalarReg::Max); + const U32 value_typed = value.Type() == Type::F32 ? BitCast(F32{value}) : U32{value}; + Inst(Opcode::SetScalarRegister, reg, value_typed); +} + +void IREmitter::SetVectorReg(IR::VectorReg reg, const U32F32& value) { + ASSERT(reg < IR::VectorReg::Max); + const U32 value_typed = value.Type() == Type::F32 ? BitCast(F32{value}) : U32{value}; + Inst(Opcode::SetVectorRegister, reg, value_typed); +} + +Value IREmitter::GetVirtualReg(IR::VirtualReg reg) { + return Inst(Opcode::GetVirtualRegister, reg); +} + +void IREmitter::SetVirtualReg(IR::VirtualReg reg, const Value& value) { + Inst(Opcode::SetVirtualRegister, reg, value); +} + +U1 IREmitter::GetGotoVariable(u32 id) { + return Inst(Opcode::GetGotoVariable, id); +} + +U1 IREmitter::Condition(IR::Condition cond) { + switch (cond) { + case IR::Condition::False: + return Imm1(false); + case IR::Condition::True: + return Imm1(true); + case IR::Condition::Scc0: + return LogicalNot(GetScc()); + case IR::Condition::Scc1: + return GetScc(); + case IR::Condition::Vccz: + return LogicalNot(InverseBallot(PackUint2x32(CompositeConstruct(GetVccLo(), GetVccHi())))); + case IR::Condition::Vccnz: + return InverseBallot(PackUint2x32(CompositeConstruct(GetVccLo(), GetVccHi()))); + case IR::Condition::Execz: + return LogicalNot(GetExec()); + case IR::Condition::Execnz: + return GetExec(); + default: + UNREACHABLE_MSG(""); + } +} + +void IREmitter::SetGotoVariable(u32 id, const U1& value) { + Inst(Opcode::SetGotoVariable, id, value); +} + +U1 IREmitter::GetScc() { + return Inst(Opcode::GetScc); +} + +U1 IREmitter::GetExec() { + return Inst(Opcode::GetExec); +} + +U32 IREmitter::GetVccLo() { + return Inst(Opcode::GetVccLo); +} + +U32 IREmitter::GetVccHi() { + return Inst(Opcode::GetVccHi); +} + +U32 IREmitter::GetM0() { + return Inst(Opcode::GetM0); +} + +void IREmitter::SetScc(const U1& value) { + Inst(Opcode::SetScc, value); +} + +void IREmitter::SetExec(const U1& value) { + Inst(Opcode::SetExec, value); +} + +void IREmitter::SetVccLo(const U32& value) { + Inst(Opcode::SetVccLo, value); +} + +void IREmitter::SetVccHi(const U32& value) { + Inst(Opcode::SetVccHi, value); +} + +void IREmitter::SetM0(const U32& value) { + Inst(Opcode::SetM0, value); +} + +F32 IREmitter::GetAttribute(IR::Attribute attribute, u32 comp, u32 index) { + return Inst(Opcode::GetAttribute, attribute, Imm32(comp), Imm32(index)); +} + +U1 IREmitter::GetAttributeU1(IR::Attribute attribute, u32 comp) { + return Inst(Opcode::GetAttributeU1, attribute, Imm32(comp)); +} + +U32 IREmitter::GetAttributeU32(IR::Attribute attribute, u32 comp) { + return Inst(Opcode::GetAttributeU32, attribute, Imm32(comp)); +} + +void IREmitter::SetAttribute(IR::Attribute attribute, const F32& value, u32 comp) { + Inst(Opcode::SetAttribute, attribute, value, Imm32(comp)); +} + +F32 IREmitter::GetTessGenericAttribute(const U32& vertex_index, const U32& attr_index, + const U32& comp_index) { + return Inst(IR::Opcode::GetTessGenericAttribute, vertex_index, attr_index, comp_index); +} + +void IREmitter::SetTcsGenericAttribute(const F32& value, const U32& attr_index, + const U32& comp_index) { + Inst(Opcode::SetTcsGenericAttribute, value, attr_index, comp_index); +} + +F32 IREmitter::ReadTcsGenericOuputAttribute(const U32& vertex_index, const U32& attr_index, + const U32& comp_index) { + return Inst(IR::Opcode::ReadTcsGenericOuputAttribute, vertex_index, attr_index, + comp_index); +} + +U32 IREmitter::GetPcLo(const U32& pc) { + return Inst(IR::Opcode::GetPcLo, pc); +} + +F32 IREmitter::GetPatch(Patch patch) { + return Inst(Opcode::GetPatch, patch); +} + +void IREmitter::SetPatch(Patch patch, const F32& value) { + Inst(Opcode::SetPatch, patch, value); +} + +Value IREmitter::LoadShared(int bit_size, bool is_signed, const U32& offset, bool is_gds) { + switch (bit_size) { + case 16: + return Inst(Opcode::LoadSharedU16, Flags{is_gds}, offset); + case 32: + return Inst(Opcode::LoadSharedU32, Flags{is_gds}, offset); + case 64: + return Inst(Opcode::LoadSharedU64, Flags{is_gds}, offset); + default: + UNREACHABLE_MSG("Invalid bit size {}", bit_size); + } +} + +void IREmitter::WriteShared(int bit_size, const Value& value, const U32& offset, bool is_gds) { + switch (bit_size) { + case 16: + Inst(Opcode::WriteSharedU16, Flags{is_gds}, offset, value); + break; + case 32: + Inst(Opcode::WriteSharedU32, Flags{is_gds}, offset, value); + break; + case 64: + Inst(Opcode::WriteSharedU64, Flags{is_gds}, offset, value); + break; + default: + UNREACHABLE_MSG("Invalid bit size {}", bit_size); + } +} + +U32U64 IREmitter::SharedAtomicIAdd(const U32& address, const U32U64& data, bool is_gds) { + switch (data.Type()) { + case Type::U32: + return Inst(Opcode::SharedAtomicIAdd32, Flags{is_gds}, address, data); + case Type::U64: + return Inst(Opcode::SharedAtomicIAdd64, Flags{is_gds}, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32U64 IREmitter::SharedAtomicIMin(const U32& address, const U32U64& data, bool is_signed, + bool is_gds) { + switch (data.Type()) { + case Type::U32: + return Inst(is_signed ? Opcode::SharedAtomicSMin32 : Opcode::SharedAtomicUMin32, + Flags{is_gds}, address, data); + case Type::U64: + return Inst(is_signed ? Opcode::SharedAtomicSMin64 : Opcode::SharedAtomicUMin64, + Flags{is_gds}, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32U64 IREmitter::SharedAtomicIMax(const U32& address, const U32U64& data, bool is_signed, + bool is_gds) { + switch (data.Type()) { + case Type::U32: + return Inst(is_signed ? Opcode::SharedAtomicSMax32 : Opcode::SharedAtomicUMax32, + Flags{is_gds}, address, data); + case Type::U64: + return Inst(is_signed ? Opcode::SharedAtomicSMax64 : Opcode::SharedAtomicUMax64, + Flags{is_gds}, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32U64 IREmitter::SharedAtomicAnd(const U32& address, const U32U64& data, bool is_gds) { + switch (data.Type()) { + case Type::U32: + return Inst(Opcode::SharedAtomicAnd32, Flags{is_gds}, address, data); + case Type::U64: + return Inst(Opcode::SharedAtomicAnd64, Flags{is_gds}, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32U64 IREmitter::SharedAtomicOr(const U32& address, const U32U64& data, bool is_gds) { + switch (data.Type()) { + case Type::U32: + return Inst(Opcode::SharedAtomicOr32, Flags{is_gds}, address, data); + case Type::U64: + return Inst(Opcode::SharedAtomicOr64, Flags{is_gds}, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32U64 IREmitter::SharedAtomicXor(const U32& address, const U32U64& data, bool is_gds) { + switch (data.Type()) { + case Type::U32: + return Inst(Opcode::SharedAtomicXor32, Flags{is_gds}, address, data); + case Type::U64: + return Inst(Opcode::SharedAtomicXor64, Flags{is_gds}, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32U64 IREmitter::SharedAtomicISub(const U32& address, const U32U64& data, bool is_gds) { + switch (data.Type()) { + case Type::U32: + return Inst(Opcode::SharedAtomicISub32, Flags{is_gds}, address, data); + case Type::U64: + return Inst(Opcode::SharedAtomicISub64, Flags{is_gds}, address, data); + default: + ThrowInvalidType(data.Type()); + } +} + +U32U64 IREmitter::SharedAtomicCmpSwap(const U32& address, const U32U64& value, + const U32U64& cmp_value, bool is_gds) { + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::SharedAtomicCmpSwap32, Flags{is_gds}, address, value, cmp_value); + case Type::U64: + return Inst(Opcode::SharedAtomicCmpSwap64, Flags{is_gds}, address, value, cmp_value); + default: + ThrowInvalidType(value.Type()); + } +} + +template <> +U32 IREmitter::SharedAtomicInc(const U32& address, bool is_gds) { + return Inst(Opcode::SharedAtomicInc32, Flags{is_gds}, address); +} + +template <> +U64 IREmitter::SharedAtomicInc(const U32& address, bool is_gds) { + return Inst(Opcode::SharedAtomicInc64, Flags{is_gds}, address); +} + +template <> +U32 IREmitter::SharedAtomicDec(const U32& address, bool is_gds) { + return Inst(Opcode::SharedAtomicDec32, Flags{is_gds}, address); +} + +template <> +U64 IREmitter::SharedAtomicDec(const U32& address, bool is_gds) { + return Inst(Opcode::SharedAtomicDec64, Flags{is_gds}, address); +} + +U32 IREmitter::ReadConst(const Value& base, const U32& offset) { + return Inst(Opcode::ReadConst, base, offset); +} + +U32 IREmitter::ReadConstBuffer(const Value& handle, const U32& index, BufferInstInfo info) { + return Inst(Opcode::ReadConstBuffer, Flags{info}, handle, index); +} + +U8 IREmitter::LoadBufferU8(const Value& handle, const Value& address, BufferInstInfo info) { + return Inst(Opcode::LoadBufferU8, Flags{info}, handle, address); +} + +U16 IREmitter::LoadBufferU16(const Value& handle, const Value& address, BufferInstInfo info) { + return Inst(Opcode::LoadBufferU16, Flags{info}, handle, address); +} + +Value IREmitter::LoadBufferU32(int num_dwords, const Value& handle, const Value& address, + BufferInstInfo info) { + switch (num_dwords) { + case 1: + return Inst(Opcode::LoadBufferU32, Flags{info}, handle, address); + case 2: + return Inst(Opcode::LoadBufferU32x2, Flags{info}, handle, address); + case 3: + return Inst(Opcode::LoadBufferU32x3, Flags{info}, handle, address); + case 4: + return Inst(Opcode::LoadBufferU32x4, Flags{info}, handle, address); + default: + UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords); + } +} + +U64 IREmitter::LoadBufferU64(const Value& handle, const Value& address, BufferInstInfo info) { + return Inst(Opcode::LoadBufferU64, Flags{info}, handle, address); +} + +Value IREmitter::LoadBufferF32(int num_dwords, const Value& handle, const Value& address, + BufferInstInfo info) { + switch (num_dwords) { + case 1: + return Inst(Opcode::LoadBufferF32, Flags{info}, handle, address); + case 2: + return Inst(Opcode::LoadBufferF32x2, Flags{info}, handle, address); + case 3: + return Inst(Opcode::LoadBufferF32x3, Flags{info}, handle, address); + case 4: + return Inst(Opcode::LoadBufferF32x4, Flags{info}, handle, address); + default: + UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords); + } +} + +Value IREmitter::LoadBufferFormat(const Value& handle, const Value& address, BufferInstInfo info) { + return Inst(Opcode::LoadBufferFormatF32, Flags{info}, handle, address); +} + +void IREmitter::StoreBufferU8(const Value& handle, const Value& address, const U8& data, + BufferInstInfo info) { + Inst(Opcode::StoreBufferU8, Flags{info}, handle, address, data); +} + +void IREmitter::StoreBufferU16(const Value& handle, const Value& address, const U16& data, + BufferInstInfo info) { + Inst(Opcode::StoreBufferU16, Flags{info}, handle, address, data); +} + +void IREmitter::StoreBufferU32(int num_dwords, const Value& handle, const Value& address, + const Value& data, BufferInstInfo info) { + switch (num_dwords) { + case 1: + Inst(Opcode::StoreBufferU32, Flags{info}, handle, address, data); + break; + case 2: + Inst(Opcode::StoreBufferU32x2, Flags{info}, handle, address, data); + break; + case 3: + Inst(Opcode::StoreBufferU32x3, Flags{info}, handle, address, data); + break; + case 4: + Inst(Opcode::StoreBufferU32x4, Flags{info}, handle, address, data); + break; + default: + UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords); + } +} + +void IREmitter::StoreBufferU64(const Value& handle, const Value& address, const U64& data, + BufferInstInfo info) { + Inst(Opcode::StoreBufferU64, Flags{info}, handle, address, data); +} + +void IREmitter::StoreBufferF32(int num_dwords, const Value& handle, const Value& address, + const Value& data, BufferInstInfo info) { + switch (num_dwords) { + case 1: + Inst(Opcode::StoreBufferF32, Flags{info}, handle, address, data); + break; + case 2: + Inst(Opcode::StoreBufferF32x2, Flags{info}, handle, address, data); + break; + case 3: + Inst(Opcode::StoreBufferF32x3, Flags{info}, handle, address, data); + break; + case 4: + Inst(Opcode::StoreBufferF32x4, Flags{info}, handle, address, data); + break; + default: + UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords); + } +} + +void IREmitter::StoreBufferFormat(const Value& handle, const Value& address, const Value& data, + BufferInstInfo info) { + Inst(Opcode::StoreBufferFormatF32, Flags{info}, handle, address, data); +} + +Value IREmitter::BufferAtomicIAdd(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::BufferAtomicIAdd32, Flags{info}, handle, address, value); + case Type::U64: + return Inst(Opcode::BufferAtomicIAdd64, Flags{info}, handle, address, value); + default: + ThrowInvalidType(value.Type()); + } +} + +Value IREmitter::BufferAtomicISub(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicISub32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicIMin(const Value& handle, const Value& address, const Value& value, + bool is_signed, BufferInstInfo info) { + switch (value.Type()) { + case Type::U32: + return is_signed ? Inst(Opcode::BufferAtomicSMin32, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMin32, Flags{info}, handle, address, value); + case Type::U64: + return is_signed ? Inst(Opcode::BufferAtomicSMin64, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMin64, Flags{info}, handle, address, value); + default: + ThrowInvalidType(value.Type()); + } +} + +Value IREmitter::BufferAtomicFMin(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicFMin32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicIMax(const Value& handle, const Value& address, const Value& value, + bool is_signed, BufferInstInfo info) { + switch (value.Type()) { + case Type::U32: + return is_signed ? Inst(Opcode::BufferAtomicSMax32, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMax32, Flags{info}, handle, address, value); + case Type::U64: + return is_signed ? Inst(Opcode::BufferAtomicSMax64, Flags{info}, handle, address, value) + : Inst(Opcode::BufferAtomicUMax64, Flags{info}, handle, address, value); + default: + ThrowInvalidType(value.Type()); + } +} + +Value IREmitter::BufferAtomicFMax(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicFMax32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicInc(const Value& handle, const Value& address, BufferInstInfo info) { + return Inst(Opcode::BufferAtomicInc32, Flags{info}, handle, address); +} + +Value IREmitter::BufferAtomicDec(const Value& handle, const Value& address, BufferInstInfo info) { + return Inst(Opcode::BufferAtomicDec32, Flags{info}, handle, address); +} + +Value IREmitter::BufferAtomicAnd(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicAnd32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicOr(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicOr32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicXor(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicXor32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicSwap(const Value& handle, const Value& address, const Value& value, + BufferInstInfo info) { + return Inst(Opcode::BufferAtomicSwap32, Flags{info}, handle, address, value); +} + +Value IREmitter::BufferAtomicCmpSwap(const Value& handle, const Value& address, const Value& vdata, + const Value& cmp_value, BufferInstInfo info) { + return Inst(Opcode::BufferAtomicCmpSwap32, Flags{info}, handle, address, vdata, cmp_value); +} + +Value IREmitter::BufferAtomicFCmpSwap(const Value& handle, const Value& address, const Value& vdata, + const Value& cmp_value, BufferInstInfo info) { + return Inst(Opcode::BufferAtomicFCmpSwap32, Flags{info}, handle, address, vdata, cmp_value); +} + +U32 IREmitter::DataAppend(const U32& gds_dw_offset) { + return Inst(Opcode::DataAppend, gds_dw_offset, GetExec()); +} + +U32 IREmitter::DataConsume(const U32& gds_dw_offset) { + return Inst(Opcode::DataConsume, gds_dw_offset, GetExec()); +} + +U32 IREmitter::LaneId() { + return Inst(Opcode::LaneId); +} + +U32 IREmitter::WarpId() { + return Inst(Opcode::WarpId); +} + +U32 IREmitter::QuadBroadcast(const U32& value, const U32& index) { + return Inst(Opcode::QuadBroadcast, value, index); +} + +U32 IREmitter::Shuffle(const U32& value, const U32& index) { + return Inst(Opcode::Shuffle, value, index); +} + +U32 IREmitter::ShuffleXor(const U32& value, const U32& mask) { + return Inst(Opcode::ShuffleXor, value, mask); +} + +U32 IREmitter::ReadFirstLane(const U32& value) { + return Inst(Opcode::ReadFirstLane, value); +} + +U32 IREmitter::ReadLane(const U32& value, const U32& lane) { + return Inst(Opcode::ReadLane, value, lane); +} + +U32 IREmitter::WriteLane(const U32& value, const U32& write_value, const U32& lane) { + return Inst(Opcode::WriteLane, value, write_value, lane); +} + +U64 IREmitter::Ballot(const U1& bit) { + return Inst(Opcode::Ballot, bit); +} + +U32 IREmitter::BallotFindLsb(const U64& mask) { + return Inst(Opcode::BallotFindLsb, mask); +} + +U1 IREmitter::InverseBallot(const U64& mask) { + return Inst(Opcode::InverseBallot, mask); +} + +U1 IREmitter::GroupAny(const U1& bit) { + return Inst(Opcode::GroupAny, bit); +} + +F32F64 IREmitter::FPAdd(const F32F64& a, const F32F64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::F32: + return Inst(Opcode::FPAdd32, a, b); + case Type::F64: + return Inst(Opcode::FPAdd64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +F32F64 IREmitter::FPSub(const F32F64& a, const F32F64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::F32: + return Inst(Opcode::FPSub32, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2) { + if (e1.Type() != e2.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", e1.Type(), e2.Type()); + } + switch (e1.Type()) { + case Type::U32: + return Inst(Opcode::CompositeConstructU32x2, e1, e2); + case Type::U32x2: + return Inst(Opcode::CompositeConstructU32x2x2, e1, e2); + case Type::F32: + return Inst(Opcode::CompositeConstructF32x2, e1, e2); + case Type::F32x2: + return Inst(Opcode::CompositeConstructF32x2x2, e1, e2); + default: + ThrowInvalidType(e1.Type()); + } +} + +Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Value& e3) { + if (e1.Type() != e2.Type() || e1.Type() != e3.Type()) { + UNREACHABLE_MSG("Mismatching types {}, {}, and {}", e1.Type(), e2.Type(), e3.Type()); + } + switch (e1.Type()) { + case Type::U32: + return Inst(Opcode::CompositeConstructU32x3, e1, e2, e3); + case Type::F32: + return Inst(Opcode::CompositeConstructF32x3, e1, e2, e3); + default: + ThrowInvalidType(e1.Type()); + } +} + +Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Value& e3, + const Value& e4) { + if (e1.Type() != e2.Type() || e1.Type() != e3.Type() || e1.Type() != e4.Type()) { + UNREACHABLE_MSG("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(), e3.Type(), + e4.Type()); + } + switch (e1.Type()) { + case Type::U32: + return Inst(Opcode::CompositeConstructU32x4, e1, e2, e3, e4); + case Type::F32: + return Inst(Opcode::CompositeConstructF32x4, e1, e2, e3, e4); + default: + ThrowInvalidType(e1.Type()); + } +} + +Value IREmitter::CompositeConstruct(std::span elements) { + switch (elements.size()) { + case 2: + return CompositeConstruct(elements[0], elements[1]); + case 3: + return CompositeConstruct(elements[0], elements[1], elements[2]); + case 4: + return CompositeConstruct(elements[0], elements[1], elements[2], elements[3]); + default: + UNREACHABLE_MSG("Composite construct with {} elements, only 2-4 are supported", + elements.size()); + } +} + +Value IREmitter::CompositeExtract(const Value& vector, size_t element) { + const auto read{[&](Opcode opcode, size_t limit) -> Value { + if (element >= limit) { + UNREACHABLE_MSG("Out of bounds element {}", element); + } + return Inst(opcode, vector, Value{static_cast(element)}); + }}; + switch (vector.Type()) { + case Type::U32x2: + return read(Opcode::CompositeExtractU32x2, 2); + case Type::U32x3: + return read(Opcode::CompositeExtractU32x3, 3); + case Type::U32x4: + return read(Opcode::CompositeExtractU32x4, 4); + case Type::F32x2: + return read(Opcode::CompositeExtractF32x2, 2); + case Type::F32x3: + return read(Opcode::CompositeExtractF32x3, 3); + case Type::F32x4: + return read(Opcode::CompositeExtractF32x4, 4); + default: + ThrowInvalidType(vector.Type()); + } +} + +Value IREmitter::CompositeInsert(const Value& vector, const Value& object, size_t element) { + const auto insert{[&](Opcode opcode, size_t limit) { + if (element >= limit) { + UNREACHABLE_MSG("Out of bounds element {}", element); + } + return Inst(opcode, vector, object, Value{static_cast(element)}); + }}; + switch (vector.Type()) { + case Type::U32x2: + return insert(Opcode::CompositeInsertU32x2, 2); + case Type::U32x3: + return insert(Opcode::CompositeInsertU32x3, 3); + case Type::U32x4: + return insert(Opcode::CompositeInsertU32x4, 4); + case Type::F32x2: + return insert(Opcode::CompositeInsertF32x2, 2); + case Type::F32x3: + return insert(Opcode::CompositeInsertF32x3, 3); + case Type::F32x4: + return insert(Opcode::CompositeInsertF32x4, 4); + default: + ThrowInvalidType(vector.Type()); + } +} + +Value IREmitter::CompositeShuffle(const Value& vector1, const Value& vector2, size_t comp0, + size_t comp1) { + if (vector1.Type() != vector2.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", vector1.Type(), vector2.Type()); + } + if (comp0 >= 4 || comp1 >= 4) { + UNREACHABLE_MSG("One or more out of bounds elements {}, {}", comp0, comp1); + } + const auto shuffle{[&](Opcode opcode) -> Value { + return Inst(opcode, vector1, vector2, Value{static_cast(comp0)}, + Value{static_cast(comp1)}); + }}; + switch (vector1.Type()) { + case Type::U32x4: + return shuffle(Opcode::CompositeShuffleU32x2); + case Type::F32x4: + return shuffle(Opcode::CompositeShuffleF32x2); + default: + ThrowInvalidType(vector1.Type()); + } +} + +Value IREmitter::CompositeShuffle(const Value& vector1, const Value& vector2, size_t comp0, + size_t comp1, size_t comp2) { + if (vector1.Type() != vector2.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", vector1.Type(), vector2.Type()); + } + if (comp0 >= 6 || comp1 >= 6 || comp2 >= 6) { + UNREACHABLE_MSG("One or more out of bounds elements {}, {}, {}", comp0, comp1, comp2); + } + const auto shuffle{[&](Opcode opcode) -> Value { + return Inst(opcode, vector1, vector2, Value{static_cast(comp0)}, + Value{static_cast(comp1)}, Value{static_cast(comp2)}); + }}; + switch (vector1.Type()) { + case Type::U32x4: + return shuffle(Opcode::CompositeShuffleU32x3); + case Type::F32x4: + return shuffle(Opcode::CompositeShuffleF32x3); + default: + ThrowInvalidType(vector1.Type()); + } +} + +Value IREmitter::CompositeShuffle(const Value& vector1, const Value& vector2, size_t comp0, + size_t comp1, size_t comp2, size_t comp3) { + if (vector1.Type() != vector2.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", vector1.Type(), vector2.Type()); + } + if (comp0 >= 8 || comp1 >= 8 || comp2 >= 8 || comp3 >= 8) { + UNREACHABLE_MSG("One or more out of bounds elements {}, {}, {}, {}", comp0, comp1, comp2, + comp3); + } + const auto shuffle{[&](Opcode opcode) -> Value { + return Inst(opcode, vector1, vector2, Value{static_cast(comp0)}, + Value{static_cast(comp1)}, Value{static_cast(comp2)}, + Value{static_cast(comp3)}); + }}; + switch (vector1.Type()) { + case Type::U32x4: + return shuffle(Opcode::CompositeShuffleU32x4); + case Type::F32x4: + return shuffle(Opcode::CompositeShuffleF32x4); + default: + ThrowInvalidType(vector1.Type()); + } +} + +Value IREmitter::Select(const U1& condition, const Value& true_value, const Value& false_value) { + if (true_value.Type() != false_value.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", true_value.Type(), false_value.Type()); + } + switch (true_value.Type()) { + case Type::U1: + return Inst(Opcode::SelectU1, condition, true_value, false_value); + case Type::U32: + return Inst(Opcode::SelectU32, condition, true_value, false_value); + case Type::F32: + return Inst(Opcode::SelectF32, condition, true_value, false_value); + case Type::U64: + return Inst(Opcode::SelectU64, condition, true_value, false_value); + default: + UNREACHABLE_MSG("Invalid type {}", true_value.Type()); + } +} + +U64 IREmitter::PackUint2x32(const Value& vector) { + return Inst(Opcode::PackUint2x32, vector); +} + +Value IREmitter::UnpackUint2x32(const U64& value) { + return Inst(Opcode::UnpackUint2x32, value); +} + +F64 IREmitter::PackDouble2x32(const Value& vector) { + return Inst(Opcode::PackDouble2x32, vector); +} + +Value IREmitter::UnpackDouble2x32(const F64& value) { + return Inst(Opcode::UnpackDouble2x32, value); +} + +U32 IREmitter::Pack2x16(const AmdGpu::NumberFormat number_format, const Value& vector) { + switch (number_format) { + case AmdGpu::NumberFormat::Unorm: + return Inst(Opcode::PackUnorm2x16, vector); + case AmdGpu::NumberFormat::Snorm: + return Inst(Opcode::PackSnorm2x16, vector); + case AmdGpu::NumberFormat::Uint: + return Inst(Opcode::PackUint2x16, vector); + case AmdGpu::NumberFormat::Sint: + return Inst(Opcode::PackSint2x16, vector); + case AmdGpu::NumberFormat::Float: + return Inst(Opcode::PackHalf2x16, vector); + default: + UNREACHABLE_MSG("Unsupported 2x16 number format: {}", number_format); + } +} + +Value IREmitter::Unpack2x16(const AmdGpu::NumberFormat number_format, const U32& value) { + switch (number_format) { + case AmdGpu::NumberFormat::Unorm: + return Inst(Opcode::UnpackUnorm2x16, value); + case AmdGpu::NumberFormat::Snorm: + return Inst(Opcode::UnpackSnorm2x16, value); + case AmdGpu::NumberFormat::Uint: + return Inst(Opcode::UnpackUint2x16, value); + case AmdGpu::NumberFormat::Sint: + return Inst(Opcode::UnpackSint2x16, value); + case AmdGpu::NumberFormat::Float: + return Inst(Opcode::UnpackHalf2x16, value); + default: + UNREACHABLE_MSG("Unsupported 2x16 number format: {}", number_format); + } +} + +U32 IREmitter::Pack4x8(const AmdGpu::NumberFormat number_format, const Value& vector) { + switch (number_format) { + case AmdGpu::NumberFormat::Unorm: + return Inst(Opcode::PackUnorm4x8, vector); + case AmdGpu::NumberFormat::Snorm: + return Inst(Opcode::PackSnorm4x8, vector); + case AmdGpu::NumberFormat::Uint: + return Inst(Opcode::PackUint4x8, vector); + case AmdGpu::NumberFormat::Sint: + return Inst(Opcode::PackSint4x8, vector); + default: + UNREACHABLE_MSG("Unsupported 4x8 number format: {}", number_format); + } +} + +Value IREmitter::Unpack4x8(const AmdGpu::NumberFormat number_format, const U32& value) { + switch (number_format) { + case AmdGpu::NumberFormat::Unorm: + return Inst(Opcode::UnpackUnorm4x8, value); + case AmdGpu::NumberFormat::Snorm: + return Inst(Opcode::UnpackSnorm4x8, value); + case AmdGpu::NumberFormat::Uint: + return Inst(Opcode::UnpackUint4x8, value); + case AmdGpu::NumberFormat::Sint: + return Inst(Opcode::UnpackSint4x8, value); + default: + UNREACHABLE_MSG("Unsupported 4x8 number format: {}", number_format); + } +} + +U32 IREmitter::Pack10_11_11(const AmdGpu::NumberFormat number_format, const Value& vector) { + switch (number_format) { + case AmdGpu::NumberFormat::Float: + return Inst(Opcode::PackUfloat10_11_11, vector); + default: + UNREACHABLE_MSG("Unsupported 10_11_11 number format: {}", number_format); + } +} + +U32 IREmitter::Pack2_10_10_10(const AmdGpu::NumberFormat number_format, const Value& vector) { + switch (number_format) { + case AmdGpu::NumberFormat::Unorm: + return Inst(Opcode::PackUnorm2_10_10_10, vector); + case AmdGpu::NumberFormat::Snorm: + return Inst(Opcode::PackSnorm2_10_10_10, vector); + case AmdGpu::NumberFormat::Uint: + return Inst(Opcode::PackUint2_10_10_10, vector); + case AmdGpu::NumberFormat::Sint: + return Inst(Opcode::PackSint2_10_10_10, vector); + default: + UNREACHABLE_MSG("Unsupported 2_10_10_10 number format: {}", number_format); + } +} + +Value IREmitter::Unpack2_10_10_10(const AmdGpu::NumberFormat number_format, const U32& value) { + switch (number_format) { + case AmdGpu::NumberFormat::Unorm: + return Inst(Opcode::UnpackUnorm2_10_10_10, value); + case AmdGpu::NumberFormat::Snorm: + return Inst(Opcode::UnpackSnorm2_10_10_10, value); + case AmdGpu::NumberFormat::Uint: + return Inst(Opcode::UnpackUint2_10_10_10, value); + case AmdGpu::NumberFormat::Sint: + return Inst(Opcode::UnpackSint2_10_10_10, value); + default: + UNREACHABLE_MSG("Unsupported 2_10_10_10 number format: {}", number_format); + } +} + +Value IREmitter::Unpack10_11_11(const AmdGpu::NumberFormat number_format, const U32& value) { + switch (number_format) { + case AmdGpu::NumberFormat::Float: + return Inst(Opcode::UnpackUfloat10_11_11, value); + default: + UNREACHABLE_MSG("Unsupported 10_11_11 number format: {}", number_format); + } +} + +F32F64 IREmitter::FPMul(const F32F64& a, const F32F64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::F32: + return Inst(Opcode::FPMul32, a, b); + case Type::F64: + return Inst(Opcode::FPMul64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +F32F64 IREmitter::FPDiv(const F32F64& a, const F32F64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::F32: + return Inst(Opcode::FPDiv32, a, b); + case Type::F64: + return Inst(Opcode::FPDiv64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +F32F64 IREmitter::FPFma(const F32F64& a, const F32F64& b, const F32F64& c) { + if (a.Type() != b.Type() || a.Type() != c.Type()) { + UNREACHABLE_MSG("Mismatching types {}, {}, and {}", a.Type(), b.Type(), c.Type()); + } + switch (a.Type()) { + case Type::F32: + return Inst(Opcode::FPFma32, a, b, c); + case Type::F64: + return Inst(Opcode::FPFma64, a, b, c); + default: + ThrowInvalidType(a.Type()); + } +} + +F32F64 IREmitter::FPAbs(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPAbs32, value); + case Type::F64: + return Inst(Opcode::FPAbs64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPNeg(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPNeg32, value); + case Type::F64: + return Inst(Opcode::FPNeg64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPAbsNeg(const F32F64& value, bool abs, bool neg) { + F32F64 result{value}; + if (abs) { + result = FPAbs(result); + } + if (neg) { + result = FPNeg(result); + } + return result; +} + +F32 IREmitter::FPCos(const F32& value) { + return Inst(Opcode::FPCos, value); +} + +F32 IREmitter::FPSin(const F32& value) { + return Inst(Opcode::FPSin, value); +} + +F32 IREmitter::FPExp2(const F32& value) { + return Inst(Opcode::FPExp2, value); +} + +F32 IREmitter::FPLdexp(const F32& value, const U32& exp) { + return Inst(Opcode::FPLdexp, value, exp); +} + +F32 IREmitter::FPLog2(const F32& value) { + return Inst(Opcode::FPLog2, value); +} + +F32 IREmitter::FPPow(const F32& x, const F32& y) { + return Inst(Opcode::FPPow, x, y); +} + +F32F64 IREmitter::FPRecip(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPRecip32, value); + case Type::F64: + return Inst(Opcode::FPRecip64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPRecipSqrt(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPRecipSqrt32, value); + case Type::F64: + return Inst(Opcode::FPRecipSqrt64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32 IREmitter::FPSqrt(const F32& value) { + return Inst(Opcode::FPSqrt, value); +} + +F32F64 IREmitter::FPSaturate(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPSaturate32, value); + case Type::F64: + return Inst(Opcode::FPSaturate64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPClamp(const F32F64& value, const F32F64& min_value, const F32F64& max_value) { + if (value.Type() != min_value.Type() || value.Type() != max_value.Type()) { + UNREACHABLE_MSG("Mismatching types {}, {}, and {}", value.Type(), min_value.Type(), + max_value.Type()); + } + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPClamp32, value, min_value, max_value); + case Type::F64: + return Inst(Opcode::FPClamp64, value, min_value, max_value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPRoundEven(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPRoundEven32, value); + case Type::F64: + return Inst(Opcode::FPRoundEven64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPFloor(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPFloor32, value); + case Type::F64: + return Inst(Opcode::FPFloor64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPCeil(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPCeil32, value); + case Type::F64: + return Inst(Opcode::FPCeil64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPTrunc(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPTrunc32, value); + case Type::F64: + return Inst(Opcode::FPTrunc64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPFract(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPFract32, value); + case Type::F64: + return Inst(Opcode::FPFract64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +F32F64 IREmitter::FPFrexpSig(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPFrexpSig32, value); + case Type::F64: + return Inst(Opcode::FPFrexpSig64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U32 IREmitter::FPFrexpExp(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPFrexpExp32, value); + case Type::F64: + return Inst(Opcode::FPFrexpExp64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U1 IREmitter::FPEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::F32: + return Inst(ordered ? Opcode::FPOrdEqual32 : Opcode::FPUnordEqual32, lhs, rhs); + case Type::F64: + return Inst(ordered ? Opcode::FPOrdEqual64 : Opcode::FPUnordEqual64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::FPNotEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::F32: + return Inst(ordered ? Opcode::FPOrdNotEqual32 : Opcode::FPUnordNotEqual32, lhs, rhs); + case Type::F64: + return Inst(ordered ? Opcode::FPOrdNotEqual64 : Opcode::FPUnordNotEqual64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::FPLessThan(const F32F64& lhs, const F32F64& rhs, bool ordered) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::F32: + return Inst(ordered ? Opcode::FPOrdLessThan32 : Opcode::FPUnordLessThan32, lhs, rhs); + case Type::F64: + return Inst(ordered ? Opcode::FPOrdLessThan64 : Opcode::FPUnordLessThan64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::FPGreaterThan(const F32F64& lhs, const F32F64& rhs, bool ordered) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::F32: + return Inst(ordered ? Opcode::FPOrdGreaterThan32 : Opcode::FPUnordGreaterThan32, lhs, + rhs); + case Type::F64: + return Inst(ordered ? Opcode::FPOrdGreaterThan64 : Opcode::FPUnordGreaterThan64, lhs, + rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::FPLessThanEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::F32: + return Inst(ordered ? Opcode::FPOrdLessThanEqual32 : Opcode::FPUnordLessThanEqual32, + lhs, rhs); + case Type::F64: + return Inst(ordered ? Opcode::FPOrdLessThanEqual64 : Opcode::FPUnordLessThanEqual64, + lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::FPGreaterThanEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::F32: + return Inst(ordered ? Opcode::FPOrdGreaterThanEqual32 + : Opcode::FPUnordGreaterThanEqual32, + lhs, rhs); + case Type::F64: + return Inst(ordered ? Opcode::FPOrdGreaterThanEqual64 + : Opcode::FPUnordGreaterThanEqual64, + lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::FPIsNan(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPIsNan32, value); + case Type::F64: + return Inst(Opcode::FPIsNan64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U1 IREmitter::FPIsInf(const F32F64& value) { + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::FPIsInf32, value); + case Type::F64: + return Inst(Opcode::FPIsInf64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U1 IREmitter::FPCmpClass32(const F32& value, const U32& op) { + return Inst(Opcode::FPCmpClass32, value, op); +} + +U1 IREmitter::FPOrdered(const F32F64& lhs, const F32F64& rhs) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + return LogicalAnd(LogicalNot(FPIsNan(lhs)), LogicalNot(FPIsNan(rhs))); +} + +U1 IREmitter::FPUnordered(const F32F64& lhs, const F32F64& rhs) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + return LogicalOr(FPIsNan(lhs), FPIsNan(rhs)); +} + +F32F64 IREmitter::FPMax(const F32F64& lhs, const F32F64& rhs) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + + switch (lhs.Type()) { + case Type::F32: + return Inst(Opcode::FPMax32, lhs, rhs); + case Type::F64: + return Inst(Opcode::FPMax64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +F32F64 IREmitter::FPMin(const F32F64& lhs, const F32F64& rhs) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::F32: + return Inst(Opcode::FPMin32, lhs, rhs); + case Type::F64: + return Inst(Opcode::FPMin64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +F32F64 IREmitter::FPMinTri(const F32F64& a, const F32F64& b, const F32F64& c) { + return Inst(Opcode::FPMinTri32, a, b, c); +} + +F32F64 IREmitter::FPMaxTri(const F32F64& a, const F32F64& b, const F32F64& c) { + return Inst(Opcode::FPMaxTri32, a, b, c); +} + +F32F64 IREmitter::FPMedTri(const F32F64& a, const F32F64& b, const F32F64& c) { + return Inst(Opcode::FPMedTri32, a, b, c); +} + +U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::IAdd32, a, b); + case Type::U64: + return Inst(Opcode::IAdd64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +Value IREmitter::IAddCarry(const U32& a, const U32& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::IAddCarry32, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +U32U64 IREmitter::ISub(const U32U64& a, const U32U64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::ISub32, a, b); + case Type::U64: + return Inst(Opcode::ISub64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +U32 IREmitter::IMulHi(const U32& a, const U32& b, bool is_signed) { + return Inst(is_signed ? Opcode::SMulHi : Opcode::UMulHi, a, b); +} + +U32U64 IREmitter::IMul(const U32U64& a, const U32U64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::IMul32, a, b); + case Type::U64: + return Inst(Opcode::IMul64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +U32 IREmitter::IDiv(const U32& a, const U32& b, bool is_signed) { + return Inst(is_signed ? Opcode::SDiv32 : Opcode::UDiv32, a, b); +} + +U32 IREmitter::IMod(const U32& a, const U32& b, bool is_signed) { + return Inst(is_signed ? Opcode::SMod32 : Opcode::UMod32, a, b); +} + +U32U64 IREmitter::INeg(const U32U64& value) { + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::INeg32, value); + case Type::U64: + return Inst(Opcode::INeg64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U32 IREmitter::IAbs(const U32& value) { + return Inst(Opcode::IAbs32, value); +} + +U32U64 IREmitter::ShiftLeftLogical(const U32U64& base, const U32& shift) { + if (shift.IsImmediate() && shift.U32() == 0) { + return base; + } + + switch (base.Type()) { + case Type::U32: + return Inst(Opcode::ShiftLeftLogical32, base, shift); + case Type::U64: + return Inst(Opcode::ShiftLeftLogical64, base, shift); + default: + ThrowInvalidType(base.Type()); + } +} + +U32U64 IREmitter::ShiftRightLogical(const U32U64& base, const U32& shift) { + if (shift.IsImmediate() && shift.U32() == 0) { + return base; + } + + switch (base.Type()) { + case Type::U32: + return Inst(Opcode::ShiftRightLogical32, base, shift); + case Type::U64: + return Inst(Opcode::ShiftRightLogical64, base, shift); + default: + ThrowInvalidType(base.Type()); + } +} + +U32U64 IREmitter::ShiftRightArithmetic(const U32U64& base, const U32& shift) { + if (shift.IsImmediate() && shift.U32() == 0) { + return base; + } + + switch (base.Type()) { + case Type::U32: + return Inst(Opcode::ShiftRightArithmetic32, base, shift); + case Type::U64: + return Inst(Opcode::ShiftRightArithmetic64, base, shift); + default: + ThrowInvalidType(base.Type()); + } +} + +U32U64 IREmitter::BitwiseAnd(const U32U64& a, const U32U64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::BitwiseAnd32, a, b); + case Type::U64: + return Inst(Opcode::BitwiseAnd64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +U32U64 IREmitter::BitwiseOr(const U32U64& a, const U32U64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::BitwiseOr32, a, b); + case Type::U64: + return Inst(Opcode::BitwiseOr64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +U32U64 IREmitter::BitwiseXor(const U32U64& a, const U32U64& b) { + if (a.Type() != b.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); + } + switch (a.Type()) { + case Type::U32: + return Inst(Opcode::BitwiseXor32, a, b); + case Type::U64: + return Inst(Opcode::BitwiseXor64, a, b); + default: + ThrowInvalidType(a.Type()); + } +} + +U32U64 IREmitter::BitFieldInsert(const U32U64& base, const U32U64& insert, const U32& offset, + const U32& count) { + if (base.Type() != insert.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", base.Type(), insert.Type()); + } + switch (base.Type()) { + case Type::U32: + return Inst(Opcode::BitFieldInsert32, base, insert, offset, count); + case Type::U64: + return Inst(Opcode::BitFieldInsert64, base, insert, offset, count); + default: + ThrowInvalidType(base.Type()); + } +} + +U32 IREmitter::BitFieldExtract(const U32& base, const U32& offset, const U32& count, + bool is_signed) { + return Inst(is_signed ? Opcode::BitFieldSExtract : Opcode::BitFieldUExtract, base, offset, + count); +} + +U32 IREmitter::BitReverse(const U32& value) { + return Inst(Opcode::BitReverse32, value); +} + +U32 IREmitter::BitCount(const U32U64& value) { + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::BitCount32, value); + case Type::U64: + return Inst(Opcode::BitCount64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U32U64 IREmitter::BitwiseNot(const U32U64& value) { + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::BitwiseNot32, value); + case Type::U64: + return Inst(Opcode::BitwiseNot64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U32 IREmitter::MaskedBitCount(const U32& value, const U32& addend, bool hi) { + return Inst(Opcode::MaskedBitCount32, value, addend, Imm1(hi)); +} + +U32 IREmitter::FindSMsb(const U32& value) { + return Inst(Opcode::FindSMsb32, value); +} + +U32 IREmitter::FindUMsb(const U32U64& value) { + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::FindUMsb32, value); + case Type::U64: + return Inst(Opcode::FindUMsb64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U32 IREmitter::FindILsb(const U32U64& value) { + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::FindILsb32, value); + case Type::U64: + return Inst(Opcode::FindILsb64, value); + default: + ThrowInvalidType(value.Type()); + } +} + +U32 IREmitter::SMin(const U32& a, const U32& b) { + return Inst(Opcode::SMin32, a, b); +} + +U32 IREmitter::UMin(const U32& a, const U32& b) { + return Inst(Opcode::UMin32, a, b); +} + +U32 IREmitter::IMin(const U32& a, const U32& b, bool is_signed) { + return is_signed ? SMin(a, b) : UMin(a, b); +} + +U32 IREmitter::SMax(const U32& a, const U32& b) { + return Inst(Opcode::SMax32, a, b); +} + +U32 IREmitter::UMax(const U32& a, const U32& b) { + return Inst(Opcode::UMax32, a, b); +} + +U32 IREmitter::IMax(const U32& a, const U32& b, bool is_signed) { + return is_signed ? SMax(a, b) : UMax(a, b); +} + +U32 IREmitter::SMinTri(const U32& a, const U32& b, const U32& c) { + return Inst(Opcode::SMinTri32, a, b, c); +} + +U32 IREmitter::UMinTri(const U32& a, const U32& b, const U32& c) { + return Inst(Opcode::UMinTri32, a, b, c); +} + +U32 IREmitter::IMinTri(const U32& a, const U32& b, const U32& c, bool is_signed) { + return is_signed ? SMinTri(a, b, c) : UMinTri(a, b, c); +} + +U32 IREmitter::SMaxTri(const U32& a, const U32& b, const U32& c) { + return Inst(Opcode::SMaxTri32, a, b, c); +} + +U32 IREmitter::UMaxTri(const U32& a, const U32& b, const U32& c) { + return Inst(Opcode::UMaxTri32, a, b, c); +} + +U32 IREmitter::IMaxTri(const U32& a, const U32& b, const U32& c, bool is_signed) { + return is_signed ? SMaxTri(a, b, c) : UMaxTri(a, b, c); +} + +U32 IREmitter::SMedTri(const U32& a, const U32& b, const U32& c) { + return Inst(Opcode::SMedTri32, a, b, c); +} + +U32 IREmitter::UMedTri(const U32& a, const U32& b, const U32& c) { + return Inst(Opcode::UMedTri32, a, b, c); +} + +U32 IREmitter::IMedTri(const U32& a, const U32& b, const U32& c, bool is_signed) { + return is_signed ? SMedTri(a, b, c) : UMedTri(a, b, c); +} + +U32 IREmitter::SClamp(const U32& value, const U32& min, const U32& max) { + return Inst(Opcode::SClamp32, value, min, max); +} + +U32 IREmitter::UClamp(const U32& value, const U32& min, const U32& max) { + return Inst(Opcode::UClamp32, value, min, max); +} + +U1 IREmitter::ILessThan(const U32U64& lhs, const U32U64& rhs, bool is_signed) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::U32: + return Inst(is_signed ? Opcode::SLessThan32 : Opcode::ULessThan32, lhs, rhs); + case Type::U64: + return Inst(is_signed ? Opcode::SLessThan64 : Opcode::ULessThan64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::IEqual(const U32U64& lhs, const U32U64& rhs) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::U32: + return Inst(Opcode::IEqual32, lhs, rhs); + case Type::U64: + return Inst(Opcode::IEqual64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::ILessThanEqual(const U32U64& lhs, const U32U64& rhs, bool is_signed) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::U32: + return Inst(is_signed ? Opcode::SLessThanEqual32 : Opcode::ULessThanEqual32, lhs, rhs); + case Type::U64: + return Inst(is_signed ? Opcode::SLessThanEqual64 : Opcode::ULessThanEqual64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::IGreaterThan(const U32U64& lhs, const U32U64& rhs, bool is_signed) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::U32: + return Inst(is_signed ? Opcode::SGreaterThan32 : Opcode::UGreaterThan32, lhs, rhs); + case Type::U64: + return Inst(is_signed ? Opcode::SGreaterThan64 : Opcode::UGreaterThan64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::INotEqual(const U32U64& lhs, const U32U64& rhs) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::U32: + return Inst(Opcode::INotEqual32, lhs, rhs); + case Type::U64: + return Inst(Opcode::INotEqual64, lhs, rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::IGreaterThanEqual(const U32U64& lhs, const U32U64& rhs, bool is_signed) { + if (lhs.Type() != rhs.Type()) { + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + } + switch (lhs.Type()) { + case Type::U32: + return Inst(is_signed ? Opcode::SGreaterThanEqual32 : Opcode::UGreaterThanEqual32, lhs, + rhs); + case Type::U64: + return Inst(is_signed ? Opcode::SGreaterThanEqual64 : Opcode::UGreaterThanEqual64, lhs, + rhs); + default: + ThrowInvalidType(lhs.Type()); + } +} + +U1 IREmitter::LogicalOr(const U1& a, const U1& b) { + return Inst(Opcode::LogicalOr, a, b); +} + +U1 IREmitter::LogicalAnd(const U1& a, const U1& b) { + return Inst(Opcode::LogicalAnd, a, b); +} + +U1 IREmitter::LogicalXor(const U1& a, const U1& b) { + return Inst(Opcode::LogicalXor, a, b); +} + +U1 IREmitter::LogicalNot(const U1& value) { + return Inst(Opcode::LogicalNot, value); +} + +U32U64 IREmitter::ConvertFToS(size_t bitsize, const F32F64& value) { + switch (bitsize) { + case 32: + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::ConvertS32F32, value); + case Type::F64: + return Inst(Opcode::ConvertS32F64, value); + default: + ThrowInvalidType(value.Type()); + } + default: + break; + } + UNREACHABLE_MSG("Invalid destination bitsize {}", bitsize); +} + +U32U64 IREmitter::ConvertFToU(size_t bitsize, const F32F64& value) { + switch (bitsize) { + case 32: + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::ConvertU32F32, value); + default: + ThrowInvalidType(value.Type()); + } + default: + UNREACHABLE_MSG("Invalid destination bitsize {}", bitsize); + } +} + +U32U64 IREmitter::ConvertFToI(size_t bitsize, bool is_signed, const F32F64& value) { + return is_signed ? ConvertFToS(bitsize, value) : ConvertFToU(bitsize, value); +} + +F32F64 IREmitter::ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) { + switch (dest_bitsize) { + case 32: + switch (src_bitsize) { + case 32: + return Inst(Opcode::ConvertF32S32, value); + default: + break; + } + case 64: + switch (src_bitsize) { + case 32: + return Inst(Opcode::ConvertF64S32, value); + default: + break; + } + default: + break; + } + UNREACHABLE_MSG("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize); +} + +F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) { + switch (dest_bitsize) { + case 32: + switch (src_bitsize) { + case 16: + return Inst(Opcode::ConvertF32U16, value); + case 32: + return Inst(Opcode::ConvertF32U32, value); + default: + break; + } + case 64: + switch (src_bitsize) { + case 32: + return Inst(Opcode::ConvertF64U32, value); + default: + break; + } + default: + break; + } + UNREACHABLE_MSG("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize); +} + +F32F64 IREmitter::ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, + const Value& value) { + return is_signed ? ConvertSToF(dest_bitsize, src_bitsize, value) + : ConvertUToF(dest_bitsize, src_bitsize, value); +} + +U8U16U32U64 IREmitter::UConvert(size_t result_bitsize, const U8U16U32U64& value) { + switch (result_bitsize) { + case 8: + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::ConvertU8U32, value); + default: + break; + } + case 16: + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::ConvertU16U32, value); + default: + break; + } + case 32: + switch (value.Type()) { + case Type::U8: + return Inst(Opcode::ConvertU32U8, value); + case Type::U16: + return Inst(Opcode::ConvertU32U16, value); + default: + break; + } + case 64: + switch (value.Type()) { + case Type::U32: + return Inst(Opcode::ConvertU64U32, value); + default: + break; + } + default: + break; + } + UNREACHABLE_MSG("Conversion from {} to {} bits", value.Type(), result_bitsize); +} + +U8U16U32U64 IR::IREmitter::SConvert(size_t result_bitsize, const U8U16U32U64& value) { + switch (result_bitsize) { + case 32: + switch (value.Type()) { + case Type::U8: + return Inst(Opcode::ConvertS32S8, value); + case Type::U16: + return Inst(Opcode::ConvertS32S16, value); + default: + break; + } + default: + break; + } + UNREACHABLE_MSG("Signed Conversion from {} to {} bits", value.Type(), result_bitsize); +} + +F16F32F64 IREmitter::FPConvert(size_t result_bitsize, const F16F32F64& value) { + switch (result_bitsize) { + case 16: + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::ConvertF16F32, value); + default: + break; + } + case 32: + switch (value.Type()) { + case Type::F16: + return Inst(Opcode::ConvertF32F16, value); + case Type::F64: + return Inst(Opcode::ConvertF32F64, value); + default: + break; + } + case 64: + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::ConvertF64F32, value); + default: + break; + } + default: + break; + } + UNREACHABLE_MSG("Conversion from {} to {} bits", value.Type(), result_bitsize); +} + +Value IREmitter::ImageAtomicIAdd(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicIAdd32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicSMin(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicSMin32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicUMin(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicUMin32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicIMin(const Value& handle, const Value& coords, const Value& value, + bool is_signed, TextureInstInfo info) { + return is_signed ? ImageAtomicSMin(handle, coords, value, info) + : ImageAtomicUMin(handle, coords, value, info); +} + +Value IREmitter::ImageAtomicSMax(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicSMax32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicUMax(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicUMax32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicFMax(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicFMax32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicFMin(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicFMin32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicIMax(const Value& handle, const Value& coords, const Value& value, + bool is_signed, TextureInstInfo info) { + return is_signed ? ImageAtomicSMax(handle, coords, value, info) + : ImageAtomicUMax(handle, coords, value, info); +} + +Value IREmitter::ImageAtomicInc(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicInc32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicDec(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicDec32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicAnd(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicAnd32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicOr(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicOr32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicXor(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicXor32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicExchange(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info) { + return Inst(Opcode::ImageAtomicExchange32, Flags{info}, handle, coords, value); +} + +Value IREmitter::ImageAtomicCmpSwap(const Value& handle, const Value& coords, const Value& value, + const Value& cmp_value, TextureInstInfo info) { + return Inst(Opcode::ImageAtomicCmpSwap32, Flags{info}, handle, coords, value, cmp_value); +} + +Value IREmitter::ImageHandle(const Value& tsharp_low, const Value& tsharp_high) { + return Inst(Opcode::ImageHandle, tsharp_low, tsharp_high); +} + +Value IREmitter::ImageSampleRaw(const Value& image_handle, const Value& sampler_handle, + const Value& address1, const Value& address2, const Value& address3, + const Value& address4, TextureInstInfo info) { + return Inst(Opcode::ImageSampleRaw, Flags{info}, image_handle, sampler_handle, address1, + address2, address3, address4); +} + +Value IREmitter::ImageSampleImplicitLod(const Value& handle, const Value& coords, const F32& bias, + const Value& offset, TextureInstInfo info) { + return Inst(Opcode::ImageSampleImplicitLod, Flags{info}, handle, coords, bias, offset); +} + +Value IREmitter::ImageSampleExplicitLod(const Value& handle, const Value& coords, const F32& lod, + const Value& offset, TextureInstInfo info) { + return Inst(Opcode::ImageSampleExplicitLod, Flags{info}, handle, coords, lod, offset); +} + +Value IREmitter::ImageSampleDrefImplicitLod(const Value& handle, const Value& coords, + const F32& dref, const F32& bias, const Value& offset, + TextureInstInfo info) { + return Inst(Opcode::ImageSampleDrefImplicitLod, Flags{info}, handle, coords, dref, bias, + offset); +} + +Value IREmitter::ImageSampleDrefExplicitLod(const Value& handle, const Value& coords, + const F32& dref, const F32& lod, const Value& offset, + TextureInstInfo info) { + return Inst(Opcode::ImageSampleDrefExplicitLod, Flags{info}, handle, coords, dref, lod, offset); +} + +Value IREmitter::ImageGather(const Value& handle, const Value& coords, const Value& offset, + TextureInstInfo info) { + return Inst(Opcode::ImageGather, Flags{info}, handle, coords, offset); +} + +Value IREmitter::ImageGatherDref(const Value& handle, const Value& coords, const Value& offset, + const F32& dref, TextureInstInfo info) { + return Inst(Opcode::ImageGatherDref, Flags{info}, handle, coords, offset, dref); +} + +Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod, + const IR::U1& skip_mips, TextureInstInfo info) { + return Inst(Opcode::ImageQueryDimensions, Flags{info}, handle, lod, skip_mips); +} + +Value IREmitter::ImageQueryLod(const Value& handle, const Value& coords, TextureInstInfo info) { + return Inst(Opcode::ImageQueryLod, Flags{info}, handle, coords); +} + +Value IREmitter::ImageGradient(const Value& handle, const Value& coords, + const Value& derivatives_dx, const Value& derivatives_dy, + const Value& offset, const F32& lod_clamp, TextureInstInfo info) { + return Inst(Opcode::ImageGradient, Flags{info}, handle, coords, derivatives_dx, derivatives_dy, + offset, lod_clamp); +} + +Value IREmitter::ImageRead(const Value& handle, const Value& coords, const U32& lod, + const U32& multisampling, TextureInstInfo info) { + return Inst(Opcode::ImageRead, Flags{info}, handle, coords, lod, multisampling); +} + +void IREmitter::ImageWrite(const Value& handle, const Value& coords, const U32& lod, + const U32& multisampling, const Value& color, TextureInstInfo info) { + Inst(Opcode::ImageWrite, Flags{info}, handle, coords, lod, multisampling, color); +} + +[[nodiscard]] F32 IREmitter::CubeFaceIndex(const Value& cube_coords) { + return Inst(Opcode::CubeFaceIndex, cube_coords); +} + +// Debug print maps to SPIRV's NonSemantic DebugPrintf instruction +// Renderdoc will hook in its own implementation of the SPIRV instruction +// Renderdoc accepts format specifiers, e.g. %u, listed here: +// https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/debug_printf.md +// +// fmt must be a string literal (pointer is shallow copied into a Value) +// Example usage: +// ir.DebugPrint("invocation xyz: (%u, %u, %u)", +// {ir.GetVectorReg(IR::VectorReg::V0), +// ir.GetVectorReg(IR::VectorReg::V1), +// ir.GetVectorReg(IR::VectorReg::V2)}); +void IREmitter::DebugPrint(const char* fmt, boost::container::small_vector format_args) { + std::array args; + + ASSERT_MSG(format_args.size() < DEBUGPRINT_NUM_FORMAT_ARGS, + "DebugPrint only supports up to {} format args", DEBUGPRINT_NUM_FORMAT_ARGS); + + for (int i = 0; i < format_args.size(); i++) { + args[i] = format_args[i]; + } + + for (int i = format_args.size(); i < DEBUGPRINT_NUM_FORMAT_ARGS; i++) { + args[i] = Inst(Opcode::Void); + } + + IR::Value fmt_val{fmt}; + + DebugPrintFlags flags; + flags.num_args.Assign(format_args.size()); + Inst(Opcode::DebugPrint, Flags{flags}, fmt_val, args[0], args[1], args[2], args[3]); +} + +void IREmitter::EmitVertex() { + Inst(Opcode::EmitVertex); +} + +void IREmitter::EmitPrimitive() { + Inst(Opcode::EmitPrimitive); +} + +U64 IREmitter::Memtime() { + return Inst(Opcode::Memtime); +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/ir_emitter.h b/gpu/shadps4/shader_recompiler/ir/ir_emitter.h new file mode 100644 index 0000000..3210558 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/ir_emitter.h @@ -0,0 +1,447 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/condition.h" +#include "shader_recompiler/ir/patch.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +class IREmitter { +public: + explicit IREmitter() = default; + explicit IREmitter(Block& block_) : block{&block_}, insertion_point{block->end()} {} + explicit IREmitter(Block& block_, Block::iterator insertion_point_) + : block{&block_}, insertion_point{insertion_point_} {} + + [[nodiscard]] U1 Imm1(bool value) const; + [[nodiscard]] U8 Imm8(u8 value) const; + [[nodiscard]] U16 Imm16(u16 value) const; + [[nodiscard]] U32 Imm32(u32 value) const; + [[nodiscard]] U32 Imm32(s32 value) const; + [[nodiscard]] F32 Imm32(f32 value) const; + [[nodiscard]] U64 Imm64(u64 value) const; + [[nodiscard]] U64 Imm64(s64 value) const; + [[nodiscard]] F64 Imm64(f64 value) const; + + template + [[nodiscard]] Dest BitCast(const Source& value); + + U1 ConditionRef(const U1& value); + + void Prologue(); + void Epilogue(); + void Discard(); + void Discard(const U1& cond); + void DebugPrint(const char* fmt, boost::container::small_vector args); + + void Barrier(); + void WorkgroupMemoryBarrier(); + void DeviceMemoryBarrier(); + + [[nodiscard]] U32 GetUserData(IR::ScalarReg reg); + + template + [[nodiscard]] T GetScalarReg(IR::ScalarReg reg); + template + [[nodiscard]] T GetVectorReg(IR::VectorReg reg); + void SetScalarReg(IR::ScalarReg reg, const U32F32& value); + void SetVectorReg(IR::VectorReg reg, const U32F32& value); + + [[nodiscard]] Value GetVirtualReg(IR::VirtualReg reg); + void SetVirtualReg(IR::VirtualReg reg, const Value& value); + + [[nodiscard]] U1 GetGotoVariable(u32 id); + void SetGotoVariable(u32 id, const U1& value); + + [[nodiscard]] U1 GetScc(); + [[nodiscard]] U1 GetExec(); + [[nodiscard]] U32 GetVccLo(); + [[nodiscard]] U32 GetVccHi(); + [[nodiscard]] U32 GetM0(); + void SetScc(const U1& value); + void SetExec(const U1& value); + void SetVccLo(const U32& value); + void SetVccHi(const U32& value); + void SetM0(const U32& value); + + [[nodiscard]] U1 Condition(IR::Condition cond); + + [[nodiscard]] F32 GetAttribute(Attribute attribute, u32 comp = 0, u32 index = 0); + [[nodiscard]] U1 GetAttributeU1(Attribute attribute, u32 comp = 0); + [[nodiscard]] U32 GetAttributeU32(Attribute attribute, u32 comp = 0); + void SetAttribute(Attribute attribute, const F32& value, u32 comp = 0); + + [[nodiscard]] F32 GetTessGenericAttribute(const U32& vertex_index, const U32& attr_index, + const U32& comp_index); + void SetTcsGenericAttribute(const F32& value, const U32& attr_index, const U32& comp_index); + + [[nodiscard]] F32 ReadTcsGenericOuputAttribute(const U32& vertex_index, const U32& attr_index, + const U32& comp_index); + + [[nodiscard]] U32 GetPcLo(const U32& pc); + + [[nodiscard]] F32 GetPatch(Patch patch); + void SetPatch(Patch patch, const F32& value); + + [[nodiscard]] Value LoadShared(int bit_size, bool is_signed, const U32& offset, + bool is_gds = false); + void WriteShared(int bit_size, const Value& value, const U32& offset, bool is_gds = false); + + [[nodiscard]] U32U64 SharedAtomicIAdd(const U32& address, const U32U64& data, bool is_gds); + [[nodiscard]] U32U64 SharedAtomicISub(const U32& address, const U32U64& data, bool is_gds); + [[nodiscard]] U32U64 SharedAtomicIMin(const U32& address, const U32U64& data, bool is_signed, + bool is_gds); + [[nodiscard]] U32U64 SharedAtomicIMax(const U32& address, const U32U64& data, bool is_signed, + bool is_gds); + [[nodiscard]] U32U64 SharedAtomicAnd(const U32& address, const U32U64& data, bool is_gds); + [[nodiscard]] U32U64 SharedAtomicOr(const U32& address, const U32U64& data, bool is_gds); + [[nodiscard]] U32U64 SharedAtomicXor(const U32& address, const U32U64& data, bool is_gds); + [[nodiscard]] U32U64 SharedAtomicCmpSwap(const U32& address, const U32U64& value, + const U32U64& cmp_value, bool is_gds); + + template + [[nodiscard]] T SharedAtomicInc(const U32& address, bool is_gds); + template + [[nodiscard]] T SharedAtomicDec(const U32& address, bool is_gds); + + [[nodiscard]] U32 ReadConst(const Value& base, const U32& offset); + [[nodiscard]] U32 ReadConstBuffer(const Value& handle, const U32& index, BufferInstInfo info); + + [[nodiscard]] U8 LoadBufferU8(const Value& handle, const Value& address, BufferInstInfo info); + [[nodiscard]] U16 LoadBufferU16(const Value& handle, const Value& address, BufferInstInfo info); + [[nodiscard]] Value LoadBufferU32(int num_dwords, const Value& handle, const Value& address, + BufferInstInfo info); + [[nodiscard]] U64 LoadBufferU64(const Value& handle, const Value& address, BufferInstInfo info); + [[nodiscard]] Value LoadBufferF32(int num_dwords, const Value& handle, const Value& address, + BufferInstInfo info); + [[nodiscard]] Value LoadBufferFormat(const Value& handle, const Value& address, + BufferInstInfo info); + void StoreBufferU8(const Value& handle, const Value& address, const U8& data, + BufferInstInfo info); + void StoreBufferU16(const Value& handle, const Value& address, const U16& data, + BufferInstInfo info); + void StoreBufferU32(int num_dwords, const Value& handle, const Value& address, + const Value& data, BufferInstInfo info); + void StoreBufferU64(const Value& handle, const Value& address, const U64& data, + BufferInstInfo info); + void StoreBufferF32(int num_dwords, const Value& handle, const Value& address, + const Value& data, BufferInstInfo info); + void StoreBufferFormat(const Value& handle, const Value& address, const Value& data, + BufferInstInfo info); + + [[nodiscard]] Value BufferAtomicIAdd(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicISub(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicIMin(const Value& handle, const Value& address, + const Value& value, bool is_signed, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicFMin(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicIMax(const Value& handle, const Value& address, + const Value& value, bool is_signed, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicFMax(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicInc(const Value& handle, const Value& address, + BufferInstInfo info); + [[nodiscard]] Value BufferAtomicDec(const Value& handle, const Value& address, + BufferInstInfo info); + [[nodiscard]] Value BufferAtomicAnd(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicOr(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicXor(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicSwap(const Value& handle, const Value& address, + const Value& value, BufferInstInfo info); + [[nodiscard]] Value BufferAtomicCmpSwap(const Value& handle, const Value& address, + const Value& value, const Value& cmp_value, + BufferInstInfo info); + [[nodiscard]] Value BufferAtomicFCmpSwap(const Value& handle, const Value& address, + const Value& value, const Value& cmp_value, + BufferInstInfo info); + + [[nodiscard]] U32 DataAppend(const U32& gds_dw_offset); + [[nodiscard]] U32 DataConsume(const U32& gds_dw_offset); + [[nodiscard]] U32 LaneId(); + [[nodiscard]] U32 WarpId(); + [[nodiscard]] U32 QuadBroadcast(const U32& value, const U32& index); + [[nodiscard]] U32 Shuffle(const U32& value, const U32& index); + [[nodiscard]] U32 ShuffleXor(const U32& value, const U32& mask); + [[nodiscard]] U32 ReadFirstLane(const U32& value); + [[nodiscard]] U32 ReadLane(const U32& value, const U32& lane); + [[nodiscard]] U32 WriteLane(const U32& value, const U32& write_value, const U32& lane); + [[nodiscard]] U64 Ballot(const U1& bit); + [[nodiscard]] U32 BallotFindLsb(const U64& mask); + [[nodiscard]] U1 InverseBallot(const U64& mask); + [[nodiscard]] U1 GroupAny(const U1& bit); + + [[nodiscard]] Value CompositeConstruct(const Value& e1, const Value& e2); + [[nodiscard]] Value CompositeConstruct(const Value& e1, const Value& e2, const Value& e3); + [[nodiscard]] Value CompositeConstruct(const Value& e1, const Value& e2, const Value& e3, + const Value& e4); + [[nodiscard]] Value CompositeConstruct(std::span values); + + [[nodiscard]] Value CompositeExtract(const Value& vector, size_t element); + [[nodiscard]] Value CompositeInsert(const Value& vector, const Value& object, size_t element); + + [[nodiscard]] Value CompositeShuffle(const Value& vector1, const Value& vector2, size_t comp0, + size_t comp1); + [[nodiscard]] Value CompositeShuffle(const Value& vector1, const Value& vector2, size_t comp0, + size_t comp1, size_t comp2); + [[nodiscard]] Value CompositeShuffle(const Value& vector1, const Value& vector2, size_t comp0, + size_t comp1, size_t comp2, size_t comp3); + + [[nodiscard]] Value Select(const U1& condition, const Value& true_value, + const Value& false_value); + + [[nodiscard]] U64 PackUint2x32(const Value& vector); + [[nodiscard]] Value UnpackUint2x32(const U64& value); + [[nodiscard]] F64 PackDouble2x32(const Value& vector); + [[nodiscard]] Value UnpackDouble2x32(const F64& value); + + [[nodiscard]] U32 Pack2x16(AmdGpu::NumberFormat number_format, const Value& vector); + [[nodiscard]] Value Unpack2x16(AmdGpu::NumberFormat number_format, const U32& value); + + [[nodiscard]] U32 Pack4x8(AmdGpu::NumberFormat number_format, const Value& vector); + [[nodiscard]] Value Unpack4x8(AmdGpu::NumberFormat number_format, const U32& value); + + [[nodiscard]] U32 Pack10_11_11(AmdGpu::NumberFormat number_format, const Value& vector); + [[nodiscard]] Value Unpack10_11_11(AmdGpu::NumberFormat number_format, const U32& value); + + [[nodiscard]] U32 Pack2_10_10_10(AmdGpu::NumberFormat number_format, const Value& vector); + [[nodiscard]] Value Unpack2_10_10_10(AmdGpu::NumberFormat number_format, const U32& value); + + [[nodiscard]] F32F64 FPAdd(const F32F64& a, const F32F64& b); + [[nodiscard]] F32F64 FPSub(const F32F64& a, const F32F64& b); + [[nodiscard]] F32F64 FPMul(const F32F64& a, const F32F64& b); + [[nodiscard]] F32F64 FPDiv(const F32F64& a, const F32F64& b); + [[nodiscard]] F32F64 FPFma(const F32F64& a, const F32F64& b, const F32F64& c); + + [[nodiscard]] F32F64 FPAbs(const F32F64& value); + [[nodiscard]] F32F64 FPNeg(const F32F64& value); + [[nodiscard]] F32F64 FPAbsNeg(const F32F64& value, bool abs, bool neg); + + [[nodiscard]] F32 FPCos(const F32& value); + [[nodiscard]] F32 FPSin(const F32& value); + [[nodiscard]] F32 FPExp2(const F32& value); + [[nodiscard]] F32 FPLog2(const F32& value); + [[nodiscard]] F32 FPPow(const F32& x, const F32& y); + [[nodiscard]] F32 FPLdexp(const F32& value, const U32& exp); + [[nodiscard]] F32F64 FPRecip(const F32F64& value); + [[nodiscard]] F32F64 FPRecipSqrt(const F32F64& value); + [[nodiscard]] F32 FPSqrt(const F32& value); + [[nodiscard]] F32F64 FPSaturate(const F32F64& value); + [[nodiscard]] F32F64 FPClamp(const F32F64& value, const F32F64& min_value, + const F32F64& max_value); + [[nodiscard]] F32F64 FPRoundEven(const F32F64& value); + [[nodiscard]] F32F64 FPFloor(const F32F64& value); + [[nodiscard]] F32F64 FPCeil(const F32F64& value); + [[nodiscard]] F32F64 FPTrunc(const F32F64& value); + [[nodiscard]] F32F64 FPFract(const F32F64& value); + [[nodiscard]] F32F64 FPFrexpSig(const F32F64& value); + [[nodiscard]] U32 FPFrexpExp(const F32F64& value); + + [[nodiscard]] U1 FPEqual(const F32F64& lhs, const F32F64& rhs, bool ordered = true); + [[nodiscard]] U1 FPNotEqual(const F32F64& lhs, const F32F64& rhs, bool ordered = true); + [[nodiscard]] U1 FPLessThanEqual(const F32F64& lhs, const F32F64& rhs, bool ordered = true); + [[nodiscard]] U1 FPGreaterThanEqual(const F32F64& lhs, const F32F64& rhs, bool ordered = true); + [[nodiscard]] U1 FPLessThan(const F32F64& lhs, const F32F64& rhs, bool ordered = true); + [[nodiscard]] U1 FPGreaterThan(const F32F64& lhs, const F32F64& rhs, bool ordered = true); + [[nodiscard]] U1 FPIsNan(const F32F64& value); + [[nodiscard]] U1 FPIsInf(const F32F64& value); + [[nodiscard]] U1 FPCmpClass32(const F32& value, const U32& op); + [[nodiscard]] U1 FPOrdered(const F32F64& lhs, const F32F64& rhs); + [[nodiscard]] U1 FPUnordered(const F32F64& lhs, const F32F64& rhs); + [[nodiscard]] F32F64 FPMax(const F32F64& lhs, const F32F64& rhs); + [[nodiscard]] F32F64 FPMin(const F32F64& lhs, const F32F64& rhs); + [[nodiscard]] F32F64 FPMinTri(const F32F64& a, const F32F64& b, const F32F64& c); + [[nodiscard]] F32F64 FPMaxTri(const F32F64& a, const F32F64& b, const F32F64& c); + [[nodiscard]] F32F64 FPMedTri(const F32F64& a, const F32F64& b, const F32F64& c); + + [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); + [[nodiscard]] Value IAddCarry(const U32& a, const U32& b); + [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); + [[nodiscard]] U32 IMulHi(const U32& a, const U32& b, bool is_signed = false); + [[nodiscard]] U32U64 IMul(const U32U64& a, const U32U64& b); + [[nodiscard]] U32 IDiv(const U32& a, const U32& b, bool is_signed = false); + [[nodiscard]] U32 IMod(const U32& a, const U32& b, bool is_signed = false); + [[nodiscard]] U32U64 INeg(const U32U64& value); + [[nodiscard]] U32 IAbs(const U32& value); + [[nodiscard]] U32U64 ShiftLeftLogical(const U32U64& base, const U32& shift); + [[nodiscard]] U32U64 ShiftRightLogical(const U32U64& base, const U32& shift); + [[nodiscard]] U32U64 ShiftRightArithmetic(const U32U64& base, const U32& shift); + [[nodiscard]] U32U64 BitwiseAnd(const U32U64& a, const U32U64& b); + [[nodiscard]] U32U64 BitwiseOr(const U32U64& a, const U32U64& b); + [[nodiscard]] U32U64 BitwiseXor(const U32U64& a, const U32U64& b); + [[nodiscard]] U32U64 BitFieldInsert(const U32U64& base, const U32U64& insert, const U32& offset, + const U32& count); + [[nodiscard]] U32 BitFieldExtract(const U32& base, const U32& offset, const U32& count, + bool is_signed = false); + [[nodiscard]] U32 BitReverse(const U32& value); + [[nodiscard]] U32 BitCount(const U32U64& value); + [[nodiscard]] U32U64 BitwiseNot(const U32U64& value); + [[nodiscard]] U32 MaskedBitCount(const U32& value, const U32& addend, bool hi); + + [[nodiscard]] U32 FindSMsb(const U32& value); + [[nodiscard]] U32 FindUMsb(const U32U64& value); + [[nodiscard]] U32 FindILsb(const U32U64& value); + [[nodiscard]] U32 SMin(const U32& a, const U32& b); + [[nodiscard]] U32 UMin(const U32& a, const U32& b); + [[nodiscard]] U32 IMin(const U32& a, const U32& b, bool is_signed); + [[nodiscard]] U32 SMax(const U32& a, const U32& b); + [[nodiscard]] U32 UMax(const U32& a, const U32& b); + [[nodiscard]] U32 IMax(const U32& a, const U32& b, bool is_signed); + [[nodiscard]] U32 SMinTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 UMinTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 IMinTri(const U32& a, const U32& b, const U32& c, bool is_signed); + [[nodiscard]] U32 SMaxTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 UMaxTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 IMaxTri(const U32& a, const U32& b, const U32& c, bool is_signed); + [[nodiscard]] U32 SMedTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 UMedTri(const U32& a, const U32& b, const U32& c); + [[nodiscard]] U32 IMedTri(const U32& a, const U32& b, const U32& c, bool is_signed); + [[nodiscard]] U32 SClamp(const U32& value, const U32& min, const U32& max); + [[nodiscard]] U32 UClamp(const U32& value, const U32& min, const U32& max); + + [[nodiscard]] U1 ILessThan(const U32U64& lhs, const U32U64& rhs, bool is_signed); + [[nodiscard]] U1 IEqual(const U32U64& lhs, const U32U64& rhs); + [[nodiscard]] U1 ILessThanEqual(const U32U64& lhs, const U32U64& rhs, bool is_signed); + [[nodiscard]] U1 IGreaterThan(const U32U64& lhs, const U32U64& rhs, bool is_signed); + [[nodiscard]] U1 INotEqual(const U32U64& lhs, const U32U64& rhs); + [[nodiscard]] U1 IGreaterThanEqual(const U32U64& lhs, const U32U64& rhs, bool is_signed); + + [[nodiscard]] U1 LogicalOr(const U1& a, const U1& b); + [[nodiscard]] U1 LogicalAnd(const U1& a, const U1& b); + [[nodiscard]] U1 LogicalXor(const U1& a, const U1& b); + [[nodiscard]] U1 LogicalNot(const U1& value); + + [[nodiscard]] U32U64 ConvertFToS(size_t bitsize, const F32F64& value); + [[nodiscard]] U32U64 ConvertFToU(size_t bitsize, const F32F64& value); + [[nodiscard]] U32U64 ConvertFToI(size_t bitsize, bool is_signed, const F32F64& value); + [[nodiscard]] F32F64 ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Value& value); + [[nodiscard]] F32F64 ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value); + [[nodiscard]] F32F64 ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, + const Value& value); + + [[nodiscard]] U8U16U32U64 UConvert(size_t result_bitsize, const U8U16U32U64& value); + [[nodiscard]] U8U16U32U64 SConvert(size_t result_bitsize, const U8U16U32U64& value); + [[nodiscard]] F16F32F64 FPConvert(size_t result_bitsize, const F16F32F64& value); + + [[nodiscard]] Value ImageAtomicIAdd(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicSMin(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicUMin(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicIMin(const Value& handle, const Value& coords, + const Value& value, bool is_signed, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicSMax(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicUMax(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicFMax(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicFMin(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicIMax(const Value& handle, const Value& coords, + const Value& value, bool is_signed, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicInc(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info); + [[nodiscard]] Value ImageAtomicDec(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info); + [[nodiscard]] Value ImageAtomicAnd(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info); + [[nodiscard]] Value ImageAtomicOr(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info); + [[nodiscard]] Value ImageAtomicXor(const Value& handle, const Value& coords, const Value& value, + TextureInstInfo info); + [[nodiscard]] Value ImageAtomicExchange(const Value& handle, const Value& coords, + const Value& value, TextureInstInfo info); + [[nodiscard]] Value ImageAtomicCmpSwap(const Value& handle, const Value& coords, + const Value& value, const Value& cmp_value, + TextureInstInfo info); + + [[nodiscard]] Value ImageHandle(const Value& tsharp_low, const Value& tsharp_high); + + [[nodiscard]] Value ImageSampleRaw(const Value& handle, const Value& sampler_handle, + const Value& address1, const Value& address2, + const Value& address3, const Value& address4, + TextureInstInfo info); + + [[nodiscard]] Value ImageSampleImplicitLod(const Value& handle, const Value& body, + const F32& bias, const Value& offset, + TextureInstInfo info); + + [[nodiscard]] Value ImageSampleExplicitLod(const Value& handle, const Value& body, + const F32& lod, const Value& offset, + TextureInstInfo info); + + [[nodiscard]] Value ImageSampleDrefImplicitLod(const Value& handle, const Value& body, + const F32& dref, const F32& bias, + const Value& offset, TextureInstInfo info); + + [[nodiscard]] Value ImageSampleDrefExplicitLod(const Value& handle, const Value& body, + const F32& dref, const F32& lod, + const Value& offset, TextureInstInfo info); + + [[nodiscard]] Value ImageQueryDimension(const Value& handle, const U32& lod, + const U1& skip_mips, TextureInstInfo info); + + [[nodiscard]] Value ImageQueryLod(const Value& handle, const Value& coords, + TextureInstInfo info); + [[nodiscard]] Value ImageGather(const Value& handle, const Value& coords, const Value& offset, + TextureInstInfo info); + [[nodiscard]] Value ImageGatherDref(const Value& handle, const Value& coords, + const Value& offset, const F32& dref, TextureInstInfo info); + [[nodiscard]] Value ImageGradient(const Value& handle, const Value& coords, + const Value& derivatives_dx, const Value& derivatives_dy, + const Value& offset, const F32& lod_clamp, + TextureInstInfo info); + [[nodiscard]] Value ImageRead(const Value& handle, const Value& coords, const U32& lod, + const U32& multisampling, TextureInstInfo info); + void ImageWrite(const Value& handle, const Value& coords, const U32& lod, + const U32& multisampling, const Value& color, TextureInstInfo info); + + [[nodiscard]] F32 CubeFaceIndex(const Value& cube_coords); + + void EmitVertex(); + void EmitPrimitive(); + U64 Memtime(); + +private: + Block* block; + IR::Block::iterator insertion_point; + + template + T Inst(Opcode op, Args... args) { + auto it{block->PrependNewInst(insertion_point, op, {Value{args}...})}; + return T{Value{&*it}}; + } + + template + requires(sizeof(T) <= sizeof(u64) && std::is_trivially_copyable_v) + struct Flags { + Flags() = default; + Flags(T proxy_) : proxy{proxy_} {} + + T proxy; + }; + + template + T Inst(Opcode op, Flags flags, Args... args) { + u64 raw_flags{}; + std::memcpy(&raw_flags, &flags.proxy, sizeof(flags.proxy)); + auto it{block->PrependNewInst(insertion_point, op, {Value{args}...}, raw_flags)}; + return T{Value{&*it}}; + } +}; + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/microinstruction.cpp b/gpu/shadps4/shader_recompiler/ir/microinstruction.cpp new file mode 100644 index 0000000..11692d8 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/microinstruction.cpp @@ -0,0 +1,251 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/type.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +Inst::Inst(IR::Opcode op_, u32 flags_) noexcept : op{op_}, flags{flags_} { + if (op == Opcode::Phi) { + std::construct_at(&phi_args); + } else { + std::construct_at(&args); + } +} + +Inst::Inst(const Inst& base) : op{base.op}, flags{base.flags} { + ASSERT_MSG(base.op != Opcode::Phi, "Copying phi node"); + std::construct_at(&args); + const size_t num_args{base.NumArgs()}; + for (size_t index = 0; index < num_args; ++index) { + SetArg(index, base.Arg(index)); + } +} + +Inst::~Inst() { + if (op == Opcode::Phi) { + std::destroy_at(&phi_args); + } else { + std::destroy_at(&args); + } +} + +bool Inst::MayHaveSideEffects() const noexcept { + switch (op) { + case Opcode::Barrier: + case Opcode::WorkgroupMemoryBarrier: + case Opcode::DeviceMemoryBarrier: + case Opcode::ConditionRef: + case Opcode::Prologue: + case Opcode::Epilogue: + case Opcode::Discard: + case Opcode::DiscardCond: + case Opcode::SetAttribute: + case Opcode::SetTcsGenericAttribute: + case Opcode::SetPatch: + case Opcode::StoreBufferU8: + case Opcode::StoreBufferU16: + case Opcode::StoreBufferU32: + case Opcode::StoreBufferU32x2: + case Opcode::StoreBufferU32x3: + case Opcode::StoreBufferU32x4: + case Opcode::StoreBufferU64: + case Opcode::StoreBufferF32: + case Opcode::StoreBufferF32x2: + case Opcode::StoreBufferF32x3: + case Opcode::StoreBufferF32x4: + case Opcode::StoreBufferFormatF32: + case Opcode::BufferAtomicIAdd32: + case Opcode::BufferAtomicIAdd64: + case Opcode::BufferAtomicISub32: + case Opcode::BufferAtomicSMin32: + case Opcode::BufferAtomicSMin64: + case Opcode::BufferAtomicUMin32: + case Opcode::BufferAtomicUMin64: + case Opcode::BufferAtomicFMin32: + case Opcode::BufferAtomicSMax32: + case Opcode::BufferAtomicSMax64: + case Opcode::BufferAtomicUMax32: + case Opcode::BufferAtomicUMax64: + case Opcode::BufferAtomicFMax32: + case Opcode::BufferAtomicInc32: + case Opcode::BufferAtomicDec32: + case Opcode::BufferAtomicAnd32: + case Opcode::BufferAtomicOr32: + case Opcode::BufferAtomicXor32: + case Opcode::BufferAtomicSwap32: + case Opcode::BufferAtomicCmpSwap32: + case Opcode::BufferAtomicFCmpSwap32: + case Opcode::WriteSharedU16: + case Opcode::WriteSharedU32: + case Opcode::WriteSharedU64: + case Opcode::SharedAtomicIAdd32: + case Opcode::SharedAtomicISub32: + case Opcode::SharedAtomicSMin32: + case Opcode::SharedAtomicUMin32: + case Opcode::SharedAtomicSMax32: + case Opcode::SharedAtomicUMax32: + case Opcode::SharedAtomicInc32: + case Opcode::SharedAtomicDec32: + case Opcode::SharedAtomicAnd32: + case Opcode::SharedAtomicOr32: + case Opcode::SharedAtomicXor32: + case Opcode::SharedAtomicIAdd64: + case Opcode::SharedAtomicISub64: + case Opcode::SharedAtomicSMin64: + case Opcode::SharedAtomicUMin64: + case Opcode::SharedAtomicSMax64: + case Opcode::SharedAtomicUMax64: + case Opcode::SharedAtomicInc64: + case Opcode::SharedAtomicDec64: + case Opcode::SharedAtomicAnd64: + case Opcode::SharedAtomicOr64: + case Opcode::SharedAtomicXor64: + case Opcode::SharedAtomicCmpSwap32: + case Opcode::SharedAtomicCmpSwap64: + case Opcode::ImageWrite: + case Opcode::ImageAtomicIAdd32: + case Opcode::ImageAtomicSMin32: + case Opcode::ImageAtomicUMin32: + case Opcode::ImageAtomicSMax32: + case Opcode::ImageAtomicUMax32: + case Opcode::ImageAtomicFMax32: + case Opcode::ImageAtomicFMin32: + case Opcode::ImageAtomicInc32: + case Opcode::ImageAtomicDec32: + case Opcode::ImageAtomicAnd32: + case Opcode::ImageAtomicOr32: + case Opcode::ImageAtomicXor32: + case Opcode::ImageAtomicExchange32: + case Opcode::ImageAtomicCmpSwap32: + case Opcode::DebugPrint: + case Opcode::EmitVertex: + case Opcode::EmitPrimitive: + return true; + default: + return false; + } +} + +bool Inst::AreAllArgsImmediates() const { + if (op == Opcode::Phi) { + UNREACHABLE_MSG("Testing for all arguments are immediates on phi instruction"); + } + return std::all_of(args.begin(), args.begin() + NumArgs(), + [](const IR::Value& value) { return value.IsImmediate(); }); +} + +IR::Type Inst::Type() const { + if (op == Opcode::Phi) { + // The type of a phi node is stored in its flags + return Flags(); + } + if (op == Opcode::GetVirtualRegister) { + // The type of a virtual register load depends on the register id + return Arg(0).VirtualReg().type; + } + return TypeOf(op); +} + +void Inst::SetArg(size_t index, Value value) { + if (index >= NumArgs()) { + UNREACHABLE_MSG("Out of bounds argument index {} in opcode {}", index, op); + } + const IR::Value arg{Arg(index)}; + if (auto* inst = arg.TryInst()) { + UndoUse(inst, index); + } + if (auto* inst = value.TryInst()) { + Use(inst, index); + } + if (op == Opcode::Phi) { + phi_args[index].second = value; + } else { + args[index] = value; + } +} + +Block* Inst::PhiBlock(size_t index) const { + if (op != Opcode::Phi) { + UNREACHABLE_MSG("{} is not a Phi instruction", op); + } + if (index >= phi_args.size()) { + UNREACHABLE_MSG("Out of bounds argument index {} in phi instruction", index); + } + return phi_args[index].first; +} + +void Inst::AddPhiOperand(Block* predecessor, const Value& value) { + if (auto* inst = value.TryInst()) { + Use(inst, phi_args.size()); + } + phi_args.emplace_back(predecessor, value); +} + +void Inst::Invalidate() { + ClearArgs(); + ReplaceOpcode(Opcode::Void); +} + +void Inst::ClearArgs() { + if (op == Opcode::Phi) { + for (auto i = 0; i < phi_args.size(); i++) { + auto& pair = phi_args[i]; + IR::Value& value{pair.second}; + if (auto* inst = value.TryInst()) { + UndoUse(inst, i); + } + } + phi_args.clear(); + } else { + for (auto i = 0; i < args.size(); i++) { + auto& value = args[i]; + if (auto* inst = value.TryInst()) { + UndoUse(inst, i); + } + } + // Reset arguments to null + // std::memset was measured to be faster on MSVC than std::ranges:fill + std::memset(reinterpret_cast(&args), 0, sizeof(args)); + } +} + +void Inst::ReplaceUsesWith(Value replacement, bool preserve) { + for (auto it = uses.begin(); it != uses.end();) { + auto [user, operand] = *it; + it = std::next(it); + DEBUG_ASSERT(user->Arg(operand).Inst() == this); + user->SetArg(operand, replacement); + } + Invalidate(); +} + +void Inst::ReplaceOpcode(IR::Opcode opcode) { + if (opcode == IR::Opcode::Phi) { + UNREACHABLE_MSG("Cannot transition into Phi"); + } + if (op == Opcode::Phi) { + // Transition out of phi arguments into non-phi + std::destroy_at(&phi_args); + std::construct_at(&args); + } + op = opcode; +} + +void Inst::Use(Inst* used, u32 operand) { + DEBUG_ASSERT(0 == std::count(used->uses.begin(), used->uses.end(), IR::Use(this, operand))); + used->uses.emplace_front(this, operand); +} + +void Inst::UndoUse(Inst* used, u32 operand) { + IR::Use use(this, operand); + DEBUG_ASSERT(1 == std::count(used->uses.begin(), used->uses.end(), use)); + used->uses.remove(use); +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/microinstruction.h b/gpu/shadps4/shader_recompiler/ir/microinstruction.h new file mode 100644 index 0000000..91c2e9d --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/microinstruction.h @@ -0,0 +1,161 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include +#include +#include + +#include "common/assert.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/ssa.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +struct Use { + Inst* user; + u32 operand; + + Use() = default; + Use(Inst* user_, u32 operand_) : user(user_), operand(operand_) {} + Use(const Use&) = default; + bool operator==(const Use&) const noexcept = default; +}; + +class Inst : public boost::intrusive::list_base_hook<> { +public: + explicit Inst(IR::Opcode op_, u32 flags_) noexcept; + explicit Inst(const Inst& base); + ~Inst(); + + Inst& operator=(const Inst&) = delete; + + Inst& operator=(Inst&&) = delete; + Inst(Inst&&) = delete; + + IR::Block* GetParent() const { + ASSERT(parent); + return parent; + } + void SetParent(IR::Block* block) { + parent = block; + } + + int UseCount() const noexcept { + return uses.size(); + } + + bool HasUses() const noexcept { + return uses.size() > 0; + } + + IR::Opcode GetOpcode() const noexcept { + return op; + } + + size_t NumArgs() const { + return op == IR::Opcode::Phi ? phi_args.size() : NumArgsOf(op); + } + + Value Arg(size_t index) const noexcept { + if (op == IR::Opcode::Phi) { + return phi_args[index].second; + } else { + return args[index]; + } + } + + void ReplaceUsesWithAndRemove(Value replacement) { + ReplaceUsesWith(replacement, false); + } + + void ReplaceUsesWith(Value replacement) { + ReplaceUsesWith(replacement, true); + } + + template + requires(sizeof(FlagsType) <= sizeof(u64) && std::is_trivially_copyable_v) + [[nodiscard]] FlagsType Flags() const noexcept { + FlagsType ret; + std::memcpy(reinterpret_cast(&ret), &flags, sizeof(ret)); + return ret; + } + + template + requires(sizeof(FlagsType) <= sizeof(u64) && std::is_trivially_copyable_v) + void SetFlags(FlagsType value) noexcept { + std::memcpy(&flags, &value, sizeof(value)); + } + + template + void SetDefinition(DefinitionType def) { + definition = std::bit_cast(def); + } + + template + [[nodiscard]] DefinitionType Definition() const noexcept { + return std::bit_cast(definition); + } + + const auto& Uses() const { + return uses; + } + + void SetRegTag(RegTag new_tag) { + reg_tag = new_tag; + } + + RegTag GetRegTag() const { + return reg_tag; + } + + bool MayHaveSideEffects() const noexcept; + bool AreAllArgsImmediates() const; + + IR::Type Type() const; + void ReplaceOpcode(IR::Opcode opcode); + void SetArg(size_t index, Value value); + + Block* PhiBlock(size_t index) const; + void AddPhiOperand(Block* predecessor, const Value& value); + + void Invalidate(); + void ClearArgs(); + + u32 scc_index{}; + +private: + struct NonTriviallyDummy { + NonTriviallyDummy() noexcept {} + }; + + void Use(Inst* used, u32 operand); + void UndoUse(Inst* used, u32 operand); + void ReplaceUsesWith(Value replacement, bool preserve); + + IR::Opcode op{}; + u32 definition{}; + u64 flags{}; + IR::Block* parent{}; + RegTag reg_tag{}; + union { + NonTriviallyDummy dummy{}; + boost::container::small_vector, 2> phi_args; + std::array args; + }; + + boost::container::list uses; +}; +static_assert(sizeof(Inst) <= 184, "Inst size unintentionally increased"); + +[[nodiscard]] inline bool IsPhi(const Inst& inst) { + return inst.GetOpcode() == Opcode::Phi; +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/opcodes.cpp b/gpu/shadps4/shader_recompiler/ir/opcodes.cpp new file mode 100644 index 0000000..18f82cb --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/opcodes.cpp @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/opcodes.h" + +namespace Shader::IR { + +std::string_view NameOf(Opcode op) { + return Detail::META_TABLE[static_cast(op)].name; +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/opcodes.h b/gpu/shadps4/shader_recompiler/ir/opcodes.h new file mode 100644 index 0000000..a3c85f7 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/opcodes.h @@ -0,0 +1,116 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include "common/types.h" +#include "shader_recompiler/ir/type.h" + +namespace Shader::IR { + +enum class Opcode { +#define OPCODE(name, ...) name, +#include "opcodes.inc" +#undef OPCODE +}; + +namespace Detail { +struct OpcodeMeta { + std::string_view name; + Type type; + std::array arg_types; +}; + +// using enum Type; +constexpr Type Void{Type::Void}; +constexpr Type Opaque{Type::Opaque}; +constexpr Type ScalarReg{Type::ScalarReg}; +constexpr Type VectorReg{Type::VectorReg}; +constexpr Type VirtualReg{Type::VirtualReg}; +constexpr Type Attribute{Type::Attribute}; +constexpr Type Patch{Type::Patch}; +constexpr Type U1{Type::U1}; +constexpr Type U8{Type::U8}; +constexpr Type U16{Type::U16}; +constexpr Type U32{Type::U32}; +constexpr Type U64{Type::U64}; +constexpr Type F16{Type::F16}; +constexpr Type F32{Type::F32}; +constexpr Type F64{Type::F64}; +constexpr Type U32x2{Type::U32x2}; +constexpr Type U32x3{Type::U32x3}; +constexpr Type U32x4{Type::U32x4}; +constexpr Type F16x2{Type::F16x2}; +constexpr Type F16x3{Type::F16x3}; +constexpr Type F16x4{Type::F16x4}; +constexpr Type F32x2{Type::F32x2}; +constexpr Type F32x3{Type::F32x3}; +constexpr Type F32x4{Type::F32x4}; +constexpr Type F64x2{Type::F64x2}; +constexpr Type F64x3{Type::F64x3}; +constexpr Type F64x4{Type::F64x4}; +constexpr Type StringLiteral{Type::StringLiteral}; + +constexpr OpcodeMeta META_TABLE[]{ +#define OPCODE(name_token, type_token, ...) \ + { \ + .name{#name_token}, \ + .type = type_token, \ + .arg_types{__VA_ARGS__}, \ + }, +#include "opcodes.inc" +#undef OPCODE +}; +constexpr size_t CalculateNumArgsOf(Opcode op) { + const auto& arg_types{META_TABLE[static_cast(op)].arg_types}; + return static_cast( + std::distance(arg_types.begin(), std::ranges::find(arg_types, Type::Void))); +} + +constexpr u8 NUM_ARGS[]{ +#define OPCODE(name_token, type_token, ...) static_cast(CalculateNumArgsOf(Opcode::name_token)), +#include "opcodes.inc" +#undef OPCODE +}; +} // namespace Detail + +/// Get return type of an opcode +[[nodiscard]] inline Type TypeOf(Opcode op) noexcept { + return Detail::META_TABLE[static_cast(op)].type; +} + +/// Get the number of arguments an opcode accepts +[[nodiscard]] constexpr inline size_t NumArgsOf(Opcode op) noexcept { + return static_cast(Detail::NUM_ARGS[static_cast(op)]); +} + +/// Get the required type of an argument of an opcode +[[nodiscard]] inline Type ArgTypeOf(Opcode op, size_t arg_index) noexcept { + return Detail::META_TABLE[static_cast(op)].arg_types[arg_index]; +} + +/// Get the name of an opcode +[[nodiscard]] std::string_view NameOf(Opcode op); + +} // namespace Shader::IR + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + template + auto format(const Shader::IR::Opcode op, FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(op)); + } +}; + +template <> +struct magic_enum::customize::enum_range { + static constexpr int min = static_cast(Shader::IR::Opcode::Phi); + static constexpr int max = static_cast(Shader::IR::Opcode::GroupAny); +}; \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/opcodes.inc b/gpu/shadps4/shader_recompiler/ir/opcodes.inc new file mode 100644 index 0000000..c978618 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/opcodes.inc @@ -0,0 +1,472 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// opcode name, return type, arg1 type, arg2 type, arg3 type, arg4 type, arg4 type, ... +OPCODE(Phi, Opaque, ) +OPCODE(Void, Void, ) +OPCODE(ConditionRef, U1, U1, ) + +// Special operations +OPCODE(Prologue, Void, ) +OPCODE(Epilogue, Void, ) +OPCODE(Discard, Void, ) +OPCODE(DiscardCond, Void, U1, ) +OPCODE(DebugPrint, Void, StringLiteral, Opaque, Opaque, Opaque, Opaque, ) + +// Constant memory operations +OPCODE(ReadConst, U32, U32x2, U32, ) +OPCODE(ReadConstBuffer, U32, Opaque, U32, ) + +// Barriers +OPCODE(Barrier, Void, ) +OPCODE(WorkgroupMemoryBarrier, Void, ) +OPCODE(DeviceMemoryBarrier, Void, ) + +// Geometry shader specific +OPCODE(EmitVertex, Void, ) +OPCODE(EmitPrimitive, Void, ) + +// Shared memory operations +OPCODE(LoadSharedU16, U16, U32, ) +OPCODE(LoadSharedU32, U32, U32, ) +OPCODE(LoadSharedU64, U64, U32, ) +OPCODE(WriteSharedU16, Void, U32, U16, ) +OPCODE(WriteSharedU32, Void, U32, U32, ) +OPCODE(WriteSharedU64, Void, U32, U64, ) + +// Shared atomic operations +OPCODE(SharedAtomicIAdd32, U32, U32, U32, ) +OPCODE(SharedAtomicIAdd64, U64, U32, U64, ) +OPCODE(SharedAtomicISub32, U32, U32, U32, ) +OPCODE(SharedAtomicISub64, U64, U32, U64, ) +OPCODE(SharedAtomicSMin32, U32, U32, U32, ) +OPCODE(SharedAtomicSMin64, U64, U32, U64, ) +OPCODE(SharedAtomicUMin32, U32, U32, U32, ) +OPCODE(SharedAtomicUMin64, U64, U32, U64, ) +OPCODE(SharedAtomicSMax32, U32, U32, U32, ) +OPCODE(SharedAtomicSMax64, U64, U32, U64, ) +OPCODE(SharedAtomicUMax32, U32, U32, U32, ) +OPCODE(SharedAtomicUMax64, U64, U32, U64, ) +OPCODE(SharedAtomicInc32, U32, U32, ) +OPCODE(SharedAtomicInc64, U64, U32, ) +OPCODE(SharedAtomicDec32, U32, U32, ) +OPCODE(SharedAtomicDec64, U64, U32, ) +OPCODE(SharedAtomicAnd32, U32, U32, U32, ) +OPCODE(SharedAtomicAnd64, U64, U32, U64, ) +OPCODE(SharedAtomicOr32, U32, U32, U32, ) +OPCODE(SharedAtomicOr64, U64, U32, U64, ) +OPCODE(SharedAtomicXor32, U32, U32, U32, ) +OPCODE(SharedAtomicXor64, U64, U32, U64, ) +OPCODE(SharedAtomicCmpSwap32, U32, U32, U32, U32, ) +OPCODE(SharedAtomicCmpSwap64, U64, U32, U64, U64, ) + +// Context getters/setters +OPCODE(GetUserData, U32, ScalarReg, ) +OPCODE(GetScalarRegister, U32, ScalarReg, ) +OPCODE(SetScalarRegister, Void, ScalarReg, U32, ) +OPCODE(GetVectorRegister, U32, VectorReg, ) +OPCODE(SetVectorRegister, Void, VectorReg, U32, ) +OPCODE(GetVirtualRegister, Opaque, VirtualReg, ) +OPCODE(SetVirtualRegister, Void, VirtualReg, Opaque, ) +OPCODE(GetGotoVariable, U1, U32, ) +OPCODE(SetGotoVariable, Void, U32, U1, ) +OPCODE(GetAttribute, F32, Attribute, U32, U32, ) +OPCODE(GetAttributeU1, U1, Attribute, U32, ) +OPCODE(GetAttributeU32, U32, Attribute, U32, ) +OPCODE(SetAttribute, Void, Attribute, F32, U32, ) +OPCODE(GetPatch, F32, Patch, ) +OPCODE(SetPatch, Void, Patch, F32, ) +OPCODE(GetTessGenericAttribute, F32, U32, U32, U32, ) +OPCODE(SetTcsGenericAttribute, Void, F32, U32, U32, ) +OPCODE(ReadTcsGenericOuputAttribute, F32, U32, U32, U32, ) +OPCODE(GetPcLo, U32, U32, ) + +// Flags +OPCODE(GetScc, U1, Void, ) +OPCODE(GetExec, U1, Void, ) +OPCODE(GetVcc, U1, Void, ) +OPCODE(GetVccLo, U32, Void, ) +OPCODE(GetVccHi, U32, Void, ) +OPCODE(GetM0, U32, Void, ) +OPCODE(SetScc, Void, U1, ) +OPCODE(SetExec, Void, U1, ) +OPCODE(SetVcc, Void, U1, ) +OPCODE(SetVccLo, Void, U32, ) +OPCODE(SetVccHi, Void, U32, ) +OPCODE(SetM0, Void, U32, ) + +// Undefined +OPCODE(UndefU1, U1, ) +OPCODE(UndefU8, U8, ) +OPCODE(UndefU16, U16, ) +OPCODE(UndefU32, U32, ) +OPCODE(UndefU32x2, U32x2, ) +OPCODE(UndefU32x3, U32x3, ) +OPCODE(UndefU32x4, U32x4, ) +OPCODE(UndefF32, F32, ) +OPCODE(UndefU64, U64, ) + +// Buffer operations +OPCODE(LoadBufferU8, U8, Opaque, Opaque, ) +OPCODE(LoadBufferU16, U16, Opaque, Opaque, ) +OPCODE(LoadBufferU32, U32, Opaque, Opaque, ) +OPCODE(LoadBufferU32x2, U32x2, Opaque, Opaque, ) +OPCODE(LoadBufferU32x3, U32x3, Opaque, Opaque, ) +OPCODE(LoadBufferU32x4, U32x4, Opaque, Opaque, ) +OPCODE(LoadBufferU64, U64, Opaque, Opaque, ) +OPCODE(LoadBufferF32, F32, Opaque, Opaque, ) +OPCODE(LoadBufferF32x2, F32x2, Opaque, Opaque, ) +OPCODE(LoadBufferF32x3, F32x3, Opaque, Opaque, ) +OPCODE(LoadBufferF32x4, F32x4, Opaque, Opaque, ) +OPCODE(LoadBufferFormatF32, F32x4, Opaque, Opaque, ) +OPCODE(StoreBufferU8, Void, Opaque, Opaque, U8, ) +OPCODE(StoreBufferU16, Void, Opaque, Opaque, U16, ) +OPCODE(StoreBufferU32, Void, Opaque, Opaque, U32, ) +OPCODE(StoreBufferU32x2, Void, Opaque, Opaque, U32x2, ) +OPCODE(StoreBufferU32x3, Void, Opaque, Opaque, U32x3, ) +OPCODE(StoreBufferU32x4, Void, Opaque, Opaque, U32x4, ) +OPCODE(StoreBufferU64, Void, Opaque, Opaque, U64, ) +OPCODE(StoreBufferF32, Void, Opaque, Opaque, F32, ) +OPCODE(StoreBufferF32x2, Void, Opaque, Opaque, F32x2, ) +OPCODE(StoreBufferF32x3, Void, Opaque, Opaque, F32x3, ) +OPCODE(StoreBufferF32x4, Void, Opaque, Opaque, F32x4, ) +OPCODE(StoreBufferFormatF32, Void, Opaque, Opaque, F32x4, ) + +// Buffer atomic operations +OPCODE(BufferAtomicIAdd32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicIAdd64, U64, Opaque, Opaque, U64 ) +OPCODE(BufferAtomicISub32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicSMin32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicSMin64, U64, Opaque, Opaque, U64 ) +OPCODE(BufferAtomicUMin32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicUMin64, U64, Opaque, Opaque, U64 ) +OPCODE(BufferAtomicFMin32, F32, Opaque, Opaque, F32 ) +OPCODE(BufferAtomicSMax32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicSMax64, U64, Opaque, Opaque, U64 ) +OPCODE(BufferAtomicUMax32, U32, Opaque, Opaque, U32 ) +OPCODE(BufferAtomicUMax64, U64, Opaque, Opaque, U64 ) +OPCODE(BufferAtomicFMax32, F32, Opaque, Opaque, F32 ) +OPCODE(BufferAtomicInc32, U32, Opaque, Opaque, ) +OPCODE(BufferAtomicDec32, U32, Opaque, Opaque, ) +OPCODE(BufferAtomicAnd32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicOr32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicXor32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicSwap32, U32, Opaque, Opaque, U32, ) +OPCODE(BufferAtomicCmpSwap32, U32, Opaque, Opaque, U32, U32, ) +OPCODE(BufferAtomicFCmpSwap32, F32, Opaque, Opaque, F32, F32, ) + +// Vector utility +OPCODE(CompositeConstructU32x2, U32x2, U32, U32, ) +OPCODE(CompositeConstructU32x3, U32x3, U32, U32, U32, ) +OPCODE(CompositeConstructU32x4, U32x4, U32, U32, U32, U32, ) +OPCODE(CompositeConstructU32x2x2, U32x4, U32x2, U32x2, ) +OPCODE(CompositeExtractU32x2, U32, U32x2, U32, ) +OPCODE(CompositeExtractU32x3, U32, U32x3, U32, ) +OPCODE(CompositeExtractU32x4, U32, U32x4, U32, ) +OPCODE(CompositeInsertU32x2, U32x2, U32x2, U32, U32, ) +OPCODE(CompositeInsertU32x3, U32x3, U32x3, U32, U32, ) +OPCODE(CompositeInsertU32x4, U32x4, U32x4, U32, U32, ) +OPCODE(CompositeShuffleU32x2, U32x2, U32x2, U32x2, U32, U32, ) +OPCODE(CompositeShuffleU32x3, U32x3, U32x3, U32x3, U32, U32, U32, ) +OPCODE(CompositeShuffleU32x4, U32x4, U32x4, U32x4, U32, U32, U32, U32, ) +OPCODE(CompositeConstructF32x2, F32x2, F32, F32, ) +OPCODE(CompositeConstructF32x3, F32x3, F32, F32, F32, ) +OPCODE(CompositeConstructF32x4, F32x4, F32, F32, F32, F32, ) +OPCODE(CompositeConstructF32x2x2, F32x4, F32x2, F32x2, ) +OPCODE(CompositeExtractF32x2, F32, F32x2, U32, ) +OPCODE(CompositeExtractF32x3, F32, F32x3, U32, ) +OPCODE(CompositeExtractF32x4, F32, F32x4, U32, ) +OPCODE(CompositeInsertF32x2, F32x2, F32x2, F32, U32, ) +OPCODE(CompositeInsertF32x3, F32x3, F32x3, F32, U32, ) +OPCODE(CompositeInsertF32x4, F32x4, F32x4, F32, U32, ) +OPCODE(CompositeShuffleF32x2, F32x2, F32x2, F32x2, U32, U32, ) +OPCODE(CompositeShuffleF32x3, F32x3, F32x3, F32x3, U32, U32, U32, ) +OPCODE(CompositeShuffleF32x4, F32x4, F32x4, F32x4, U32, U32, U32, U32, ) + +// Select operations +OPCODE(SelectU1, U1, U1, U1, U1, ) +OPCODE(SelectU32, U32, U1, U32, U32, ) +OPCODE(SelectF32, F32, U1, F32, F32, ) +OPCODE(SelectU64, U64, U1, U64, U64, ) + +// Bitwise conversions +OPCODE(BitCastU16F16, U16, F16, ) +OPCODE(BitCastU32F32, U32, F32, ) +OPCODE(BitCastF16U16, F16, U16, ) +OPCODE(BitCastF32U32, F32, U32, ) + +OPCODE(PackUint2x32, U64, U32x2, ) +OPCODE(UnpackUint2x32, U32x2, U64, ) +OPCODE(PackDouble2x32, F64, U32x2, ) +OPCODE(UnpackDouble2x32, U32x2, F64, ) + +OPCODE(PackUnorm2x16, U32, F32x2, ) +OPCODE(UnpackUnorm2x16, F32x2, U32, ) +OPCODE(PackSnorm2x16, U32, F32x2, ) +OPCODE(UnpackSnorm2x16, F32x2, U32, ) +OPCODE(PackUint2x16, U32, F32x2, ) +OPCODE(UnpackUint2x16, F32x2, U32, ) +OPCODE(PackSint2x16, U32, F32x2, ) +OPCODE(UnpackSint2x16, F32x2, U32, ) +OPCODE(PackHalf2x16, U32, F32x2, ) +OPCODE(UnpackHalf2x16, F32x2, U32, ) + +OPCODE(PackUnorm4x8, U32, F32x4, ) +OPCODE(UnpackUnorm4x8, F32x4, U32, ) +OPCODE(PackSnorm4x8, U32, F32x4, ) +OPCODE(UnpackSnorm4x8, F32x4, U32, ) +OPCODE(PackUint4x8, U32, F32x4, ) +OPCODE(UnpackUint4x8, F32x4, U32, ) +OPCODE(PackSint4x8, U32, F32x4, ) +OPCODE(UnpackSint4x8, F32x4, U32, ) + +OPCODE(PackUfloat10_11_11, U32, F32x3, ) +OPCODE(UnpackUfloat10_11_11, F32x3, U32, ) + +OPCODE(PackUnorm2_10_10_10, U32, F32x4, ) +OPCODE(UnpackUnorm2_10_10_10, F32x4, U32, ) +OPCODE(PackSnorm2_10_10_10, U32, F32x4, ) +OPCODE(UnpackSnorm2_10_10_10, F32x4, U32, ) +OPCODE(PackUint2_10_10_10, U32, F32x4, ) +OPCODE(UnpackUint2_10_10_10, F32x4, U32, ) +OPCODE(PackSint2_10_10_10, U32, F32x4, ) +OPCODE(UnpackSint2_10_10_10, F32x4, U32, ) + +// Floating-point operations +OPCODE(FPAbs32, F32, F32, ) +OPCODE(FPAbs64, F64, F64, ) +OPCODE(FPAdd32, F32, F32, F32, ) +OPCODE(FPAdd64, F64, F64, F64, ) +OPCODE(FPSub32, F32, F32, F32, ) +OPCODE(FPFma32, F32, F32, F32, F32, ) +OPCODE(FPFma64, F64, F64, F64, F64, ) +OPCODE(FPMax32, F32, F32, F32, ) +OPCODE(FPMax64, F64, F64, F64, ) +OPCODE(FPMin32, F32, F32, F32, ) +OPCODE(FPMin64, F64, F64, F64, ) +OPCODE(FPMinTri32, F32, F32, F32, F32, ) +OPCODE(FPMaxTri32, F32, F32, F32, F32, ) +OPCODE(FPMedTri32, F32, F32, F32, F32, ) +OPCODE(FPMul32, F32, F32, F32, ) +OPCODE(FPMul64, F64, F64, F64, ) +OPCODE(FPDiv32, F32, F32, F32, ) +OPCODE(FPDiv64, F64, F64, F64, ) +OPCODE(FPNeg32, F32, F32, ) +OPCODE(FPNeg64, F64, F64, ) +OPCODE(FPRecip32, F32, F32, ) +OPCODE(FPRecip64, F64, F64, ) +OPCODE(FPRecipSqrt32, F32, F32, ) +OPCODE(FPRecipSqrt64, F64, F64, ) +OPCODE(FPSqrt, F32, F32, ) +OPCODE(FPSin, F32, F32, ) +OPCODE(FPExp2, F32, F32, ) +OPCODE(FPPow, F32, F32, F32, ) +OPCODE(FPLdexp, F32, F32, U32, ) +OPCODE(FPCos, F32, F32, ) +OPCODE(FPLog2, F32, F32, ) +OPCODE(FPSaturate32, F32, F32, ) +OPCODE(FPSaturate64, F64, F64, ) +OPCODE(FPClamp32, F32, F32, F32, F32, ) +OPCODE(FPClamp64, F64, F64, F64, F64, ) +OPCODE(FPRoundEven32, F32, F32, ) +OPCODE(FPRoundEven64, F64, F64, ) +OPCODE(FPFloor32, F32, F32, ) +OPCODE(FPFloor64, F64, F64, ) +OPCODE(FPCeil32, F32, F32, ) +OPCODE(FPCeil64, F64, F64, ) +OPCODE(FPTrunc32, F32, F32, ) +OPCODE(FPTrunc64, F64, F64, ) +OPCODE(FPFract32, F32, F32, ) +OPCODE(FPFract64, F64, F64, ) +OPCODE(FPFrexpSig32, F32, F32, ) +OPCODE(FPFrexpSig64, F64, F64, ) +OPCODE(FPFrexpExp32, U32, F32, ) +OPCODE(FPFrexpExp64, U32, F64, ) + +OPCODE(FPOrdEqual32, U1, F32, F32, ) +OPCODE(FPOrdEqual64, U1, F64, F64, ) +OPCODE(FPUnordEqual32, U1, F32, F32, ) +OPCODE(FPUnordEqual64, U1, F64, F64, ) +OPCODE(FPOrdNotEqual32, U1, F32, F32, ) +OPCODE(FPOrdNotEqual64, U1, F64, F64, ) +OPCODE(FPUnordNotEqual32, U1, F32, F32, ) +OPCODE(FPUnordNotEqual64, U1, F64, F64, ) +OPCODE(FPOrdLessThan32, U1, F32, F32, ) +OPCODE(FPOrdLessThan64, U1, F64, F64, ) +OPCODE(FPUnordLessThan32, U1, F32, F32, ) +OPCODE(FPUnordLessThan64, U1, F64, F64, ) +OPCODE(FPOrdGreaterThan32, U1, F32, F32, ) +OPCODE(FPOrdGreaterThan64, U1, F64, F64, ) +OPCODE(FPUnordGreaterThan32, U1, F32, F32, ) +OPCODE(FPUnordGreaterThan64, U1, F64, F64, ) +OPCODE(FPOrdLessThanEqual32, U1, F32, F32, ) +OPCODE(FPOrdLessThanEqual64, U1, F64, F64, ) +OPCODE(FPUnordLessThanEqual32, U1, F32, F32, ) +OPCODE(FPUnordLessThanEqual64, U1, F64, F64, ) +OPCODE(FPOrdGreaterThanEqual32, U1, F32, F32, ) +OPCODE(FPOrdGreaterThanEqual64, U1, F64, F64, ) +OPCODE(FPUnordGreaterThanEqual32, U1, F32, F32, ) +OPCODE(FPUnordGreaterThanEqual64, U1, F64, F64, ) +OPCODE(FPIsNan32, U1, F32, ) +OPCODE(FPIsNan64, U1, F64, ) +OPCODE(FPIsInf32, U1, F32, ) +OPCODE(FPIsInf64, U1, F64, ) +OPCODE(FPCmpClass32, U1, F32, U32 ) + +// Integer operations +OPCODE(IAdd32, U32, U32, U32, ) +OPCODE(IAdd64, U64, U64, U64, ) +OPCODE(IAddCarry32, U32x2, U32, U32, ) +OPCODE(ISub32, U32, U32, U32, ) +OPCODE(ISub64, U64, U64, U64, ) +OPCODE(IMul32, U32, U32, U32, ) +OPCODE(IMul64, U64, U64, U64, ) +OPCODE(SMulHi, U32, U32, U32, ) +OPCODE(UMulHi, U32, U32, U32, ) +OPCODE(SDiv32, U32, U32, U32, ) +OPCODE(UDiv32, U32, U32, U32, ) +OPCODE(SMod32, U32, U32, U32, ) +OPCODE(UMod32, U32, U32, U32, ) +OPCODE(INeg32, U32, U32, ) +OPCODE(INeg64, U64, U64, ) +OPCODE(IAbs32, U32, U32, ) +OPCODE(ShiftLeftLogical32, U32, U32, U32, ) +OPCODE(ShiftLeftLogical64, U64, U64, U32, ) +OPCODE(ShiftRightLogical32, U32, U32, U32, ) +OPCODE(ShiftRightLogical64, U64, U64, U32, ) +OPCODE(ShiftRightArithmetic32, U32, U32, U32, ) +OPCODE(ShiftRightArithmetic64, U64, U64, U32, ) +OPCODE(BitwiseAnd32, U32, U32, U32, ) +OPCODE(BitwiseAnd64, U64, U64, U64, ) +OPCODE(BitwiseOr32, U32, U32, U32, ) +OPCODE(BitwiseOr64, U64, U64, U64, ) +OPCODE(BitwiseXor32, U32, U32, U32, ) +OPCODE(BitwiseXor64, U64, U64, U64, ) +OPCODE(BitFieldInsert32, U32, U32, U32, U32, U32, ) +OPCODE(BitFieldInsert64, U64, U64, U64, U32, U32, ) +OPCODE(BitFieldSExtract, U32, U32, U32, U32, ) +OPCODE(BitFieldUExtract, U32, U32, U32, U32, ) +OPCODE(BitReverse32, U32, U32, ) +OPCODE(BitCount32, U32, U32, ) +OPCODE(BitCount64, U32, U64, ) +OPCODE(BitwiseNot32, U32, U32, ) +OPCODE(BitwiseNot64, U64, U64, ) +OPCODE(MaskedBitCount32, U32, U32, U32, U1, ) + +OPCODE(FindSMsb32, U32, U32, ) +OPCODE(FindUMsb32, U32, U32, ) +OPCODE(FindUMsb64, U32, U64, ) +OPCODE(FindILsb32, U32, U32, ) +OPCODE(FindILsb64, U32, U64, ) +OPCODE(SMin32, U32, U32, U32, ) +OPCODE(UMin32, U32, U32, U32, ) +OPCODE(SMax32, U32, U32, U32, ) +OPCODE(UMax32, U32, U32, U32, ) +OPCODE(SMinTri32, U32, U32, U32, U32, ) +OPCODE(UMinTri32, U32, U32, U32, U32, ) +OPCODE(SMaxTri32, U32, U32, U32, U32, ) +OPCODE(UMaxTri32, U32, U32, U32, U32, ) +OPCODE(SMedTri32, U32, U32, U32, U32, ) +OPCODE(UMedTri32, U32, U32, U32, U32, ) +OPCODE(SClamp32, U32, U32, U32, U32, ) +OPCODE(UClamp32, U32, U32, U32, U32, ) +OPCODE(SLessThan32, U1, U32, U32, ) +OPCODE(SLessThan64, U1, U64, U64, ) +OPCODE(ULessThan32, U1, U32, U32, ) +OPCODE(ULessThan64, U1, U64, U64, ) +OPCODE(IEqual32, U1, U32, U32, ) +OPCODE(IEqual64, U1, U64, U64, ) +OPCODE(SLessThanEqual32, U1, U32, U32, ) +OPCODE(SLessThanEqual64, U1, U64, U64, ) +OPCODE(ULessThanEqual32, U1, U32, U32, ) +OPCODE(ULessThanEqual64, U1, U64, U64, ) +OPCODE(SGreaterThan32, U1, U32, U32, ) +OPCODE(SGreaterThan64, U1, U64, U64, ) +OPCODE(UGreaterThan32, U1, U32, U32, ) +OPCODE(UGreaterThan64, U1, U64, U64, ) +OPCODE(INotEqual32, U1, U32, U32, ) +OPCODE(INotEqual64, U1, U64, U64, ) +OPCODE(SGreaterThanEqual32, U1, U32, U32, ) +OPCODE(SGreaterThanEqual64, U1, U64, U64, ) +OPCODE(UGreaterThanEqual32, U1, U32, U32, ) +OPCODE(UGreaterThanEqual64, U1, U64, U64, ) + +// Logical operations +OPCODE(LogicalOr, U1, U1, U1, ) +OPCODE(LogicalAnd, U1, U1, U1, ) +OPCODE(LogicalXor, U1, U1, U1, ) +OPCODE(LogicalNot, U1, U1, ) + +// Conversion operations +OPCODE(ConvertS32F32, U32, F32, ) +OPCODE(ConvertS32F64, U32, F64, ) +OPCODE(ConvertU32F32, U32, F32, ) +OPCODE(ConvertF16F32, F16, F32, ) +OPCODE(ConvertF32F16, F32, F16, ) +OPCODE(ConvertF32F64, F32, F64, ) +OPCODE(ConvertF64F32, F64, F32, ) +OPCODE(ConvertF32S32, F32, U32, ) +OPCODE(ConvertF32U32, F32, U32, ) +OPCODE(ConvertF64S32, F64, U32, ) +OPCODE(ConvertF64U32, F64, U32, ) +OPCODE(ConvertF32U16, F32, U16, ) +OPCODE(ConvertU16U32, U16, U32, ) +OPCODE(ConvertU32U16, U32, U16, ) +OPCODE(ConvertU64U32, U64, U32, ) +OPCODE(ConvertU8U32, U8, U32, ) +OPCODE(ConvertU32U8, U32, U8, ) +OPCODE(ConvertS32S8, U32, U8, ) +OPCODE(ConvertS32S16, U32, U16, ) + +// Image operations +OPCODE(ImageHandle, Opaque, U32x4, U32x4, ) +OPCODE(ImageSampleRaw, F32x4, Opaque, Opaque, F32x4, F32x4, F32x4, F32, ) +OPCODE(ImageSampleImplicitLod, F32x4, Opaque, F32x4, F32, Opaque, ) +OPCODE(ImageSampleExplicitLod, F32x4, Opaque, Opaque, F32, Opaque, ) +OPCODE(ImageSampleDrefImplicitLod, F32x4, Opaque, Opaque, F32, F32, Opaque, ) +OPCODE(ImageSampleDrefExplicitLod, F32x4, Opaque, Opaque, F32, F32, Opaque, ) +OPCODE(ImageGather, F32x4, Opaque, Opaque, Opaque, ) +OPCODE(ImageGatherDref, F32x4, Opaque, Opaque, Opaque, F32, ) +OPCODE(ImageQueryDimensions, U32x4, Opaque, U32, U1, ) +OPCODE(ImageQueryLod, F32x4, Opaque, Opaque, ) +OPCODE(ImageGradient, F32x4, Opaque, Opaque, Opaque, Opaque, Opaque, F32, ) +OPCODE(ImageRead, F32x4, Opaque, Opaque, U32, U32, ) +OPCODE(ImageWrite, Void, Opaque, Opaque, U32, U32, F32x4, ) + +// Image atomic operations +OPCODE(ImageAtomicIAdd32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicSMin32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicUMin32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicSMax32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicUMax32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicFMax32, F32, Opaque, Opaque, F32, ) +OPCODE(ImageAtomicFMin32, F32, Opaque, Opaque, F32, ) +OPCODE(ImageAtomicInc32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicDec32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicAnd32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicOr32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicXor32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicExchange32, U32, Opaque, Opaque, U32, ) +OPCODE(ImageAtomicCmpSwap32, U32, Opaque, Opaque, U32, U32, ) + +// Cube operations - optional, usable if profile.supports_native_cube_calc +OPCODE(CubeFaceIndex, F32, F32x3, ) + +// Warp operations +OPCODE(LaneId, U32, ) +OPCODE(WarpId, U32, ) +OPCODE(QuadBroadcast, U32, U32, U32 ) +OPCODE(Shuffle, U32, U32, U32 ) +OPCODE(ShuffleXor, U32, U32, U32, ) +OPCODE(ReadFirstLane, U32, U32, ) +OPCODE(ReadLane, U32, U32, U32 ) +OPCODE(WriteLane, U32, U32, U32, U32 ) +OPCODE(Ballot, U64, U1, ) +OPCODE(BallotFindLsb, U32, U64, ) +OPCODE(InverseBallot, U1, U64, ) +OPCODE(DataAppend, U32, U32, U1 ) +OPCODE(DataConsume, U32, U32, U1 ) +OPCODE(GroupAny, U1, U1, ) + +// Time operations +OPCODE(Memtime, U64, ) diff --git a/gpu/shadps4/shader_recompiler/ir/operand_helper.h b/gpu/shadps4/shader_recompiler/ir/operand_helper.h new file mode 100644 index 0000000..36aa071 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/operand_helper.h @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// Some helpers to get operand indices of instructions by name to make it a bit safer. +// Just a start, not widely used + +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +// use namespaces. Enums would be better choice, but annoyingly need casting to size_t to use +// as indices + +namespace LoadBufferArgs { +static const size_t Handle = 0; +static const size_t Address = 1; +}; // namespace LoadBufferArgs + +namespace StoreBufferArgs { +static const size_t Handle = 0; +static const size_t Address = 1; +static const size_t Data = 2; +}; // namespace StoreBufferArgs + +static_assert(LoadBufferArgs::Handle == StoreBufferArgs::Handle); +static_assert(LoadBufferArgs::Address == StoreBufferArgs::Address); + +// Get certain components of buffer address argument, used in Load/StoreBuffer variants. +// We keep components separate as u32x3, before combining after sharp tracking +static inline IR::U32 GetBufferAddressComponent(const Inst* buffer_inst, u32 comp) { + Inst* address = buffer_inst->Arg(1).Inst(); + ASSERT(address->GetOpcode() == IR::Opcode::CompositeConstructU32x3); + return IR::U32{address->Arg(comp)}; +} + +static inline U32 GetBufferIndexArg(const Inst* buffer_inst) { + return GetBufferAddressComponent(buffer_inst, 0); +} + +static inline U32 GetBufferVOffsetArg(const Inst* buffer_inst) { + return GetBufferAddressComponent(buffer_inst, 1); +} + +static inline U32 GetBufferSOffsetArg(const Inst* buffer_inst) { + return GetBufferAddressComponent(buffer_inst, 2); +} + +} // namespace Shader::IR \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/passes/constant_propagation_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/constant_propagation_pass.cpp new file mode 100644 index 0000000..98b9a6b --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/constant_propagation_pass.cpp @@ -0,0 +1,615 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include "common/func_traits.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" + +namespace Shader::Optimization { + +template +[[nodiscard]] T Arg(const IR::Value& value) { + if constexpr (std::is_same_v) { + return value.U1(); + } else if constexpr (std::is_same_v) { + return value.U32(); + } else if constexpr (std::is_same_v) { + return static_cast(value.U32()); + } else if constexpr (std::is_same_v) { + return value.F32(); + } else if constexpr (std::is_same_v) { + return value.U64(); + } else if constexpr (std::is_same_v) { + return static_cast(value.U64()); + } +} + +template +IR::Value EvalImmediates(const IR::Inst& inst, Func&& func, std::index_sequence) { + using Traits = Common::LambdaTraits; + return IR::Value{func(Arg>(inst.Arg(I))...)}; +} + +template +bool FoldCommutative(IR::Inst& inst, ImmFn&& imm_fn) { + const IR::Value lhs{inst.Arg(0)}; + const IR::Value rhs{inst.Arg(1)}; + + const bool is_lhs_immediate{lhs.IsImmediate()}; + const bool is_rhs_immediate{rhs.IsImmediate()}; + + if (is_lhs_immediate && is_rhs_immediate) { + const auto result{imm_fn(Arg(lhs), Arg(rhs))}; + inst.ReplaceUsesWithAndRemove(IR::Value{result}); + return false; + } + if (is_lhs_immediate && !is_rhs_immediate) { + IR::Inst* const rhs_inst{rhs.Inst()}; + if (rhs_inst->GetOpcode() == inst.GetOpcode() && rhs_inst->Arg(1).IsImmediate()) { + const auto combined{imm_fn(Arg(lhs), Arg(rhs_inst->Arg(1)))}; + inst.SetArg(0, rhs_inst->Arg(0)); + inst.SetArg(1, IR::Value{combined}); + } else { + // Normalize + inst.SetArg(0, rhs); + inst.SetArg(1, lhs); + } + } + if (!is_lhs_immediate && is_rhs_immediate) { + const IR::Inst* const lhs_inst{lhs.Inst()}; + if (lhs_inst->GetOpcode() == inst.GetOpcode() && lhs_inst->Arg(1).IsImmediate()) { + const auto combined{imm_fn(Arg(rhs), Arg(lhs_inst->Arg(1)))}; + inst.SetArg(0, lhs_inst->Arg(0)); + inst.SetArg(1, IR::Value{combined}); + } + } + return true; +} + +template +bool FoldWhenAllImmediates(IR::Inst& inst, Func&& func) { + if (!inst.AreAllArgsImmediates() /*|| inst.HasAssociatedPseudoOperation()*/) { + return false; + } + using Indices = std::make_index_sequence::NUM_ARGS>; + inst.ReplaceUsesWithAndRemove(EvalImmediates(inst, func, Indices{})); + return true; +} + +template +void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) { + const IR::Value value{inst.Arg(0)}; + if (value.IsImmediate()) { + inst.ReplaceUsesWithAndRemove(IR::Value{std::bit_cast(Arg(value))}); + return; + } + IR::Inst* const arg_inst{value.Inst()}; + if (arg_inst->GetOpcode() == reverse) { + inst.ReplaceUsesWithAndRemove(arg_inst->Arg(0)); + return; + } +} + +std::optional FoldCompositeExtractImpl(IR::Value inst_value, IR::Opcode insert, + IR::Opcode construct, u32 first_index) { + IR::Inst* const inst{inst_value.Inst()}; + if (inst->GetOpcode() == construct) { + return inst->Arg(first_index); + } + if (inst->GetOpcode() != insert) { + return std::nullopt; + } + IR::Value value_index{inst->Arg(2)}; + if (!value_index.IsImmediate()) { + return std::nullopt; + } + const u32 second_index{value_index.U32()}; + if (first_index != second_index) { + IR::Value value_composite{inst->Arg(0)}; + if (value_composite.IsImmediate()) { + return std::nullopt; + } + return FoldCompositeExtractImpl(value_composite, insert, construct, first_index); + } + return inst->Arg(1); +} + +void FoldCompositeExtract(IR::Inst& inst, IR::Opcode construct, IR::Opcode insert) { + const IR::Value value_1{inst.Arg(0)}; + const IR::Value value_2{inst.Arg(1)}; + if (value_1.IsImmediate()) { + return; + } + if (!value_2.IsImmediate()) { + return; + } + const u32 first_index{value_2.U32()}; + const std::optional result{FoldCompositeExtractImpl(value_1, insert, construct, first_index)}; + if (!result) { + return; + } + inst.ReplaceUsesWithAndRemove(*result); +} + +void FoldCompositeConstruct(IR::Inst& inst, IR::Opcode extract) { + IR::Value result{}; + for (size_t i = 0; i < inst.NumArgs(); ++i) { + const IR::Value value{inst.Arg(i)}; + if (value.IsImmediate()) { + return; + } + IR::Inst* const inst = value.Inst(); + if (inst->GetOpcode() != extract || inst->Arg(1).U32() != i) { + return; + } + + if (result.IsEmpty()) { + result = inst->Arg(0); + } else if (result != inst->Arg(0)) { + return; + } + } + inst.ReplaceUsesWithAndRemove(result); +} + +void FoldConvert(IR::Inst& inst, IR::Opcode opposite) { + const IR::Value value{inst.Arg(0)}; + if (value.IsImmediate()) { + return; + } + IR::Inst* const producer{value.Inst()}; + if (producer->GetOpcode() == opposite) { + inst.ReplaceUsesWithAndRemove(producer->Arg(0)); + } +} + +void FoldLogicalAnd(IR::Inst& inst) { + if (!FoldCommutative(inst, [](bool a, bool b) { return a && b; })) { + return; + } + const IR::Value rhs{inst.Arg(1)}; + if (rhs.IsImmediate()) { + if (rhs.U1()) { + inst.ReplaceUsesWithAndRemove(inst.Arg(0)); + } else { + inst.ReplaceUsesWithAndRemove(IR::Value{false}); + } + } +} + +void FoldSelect(IR::Inst& inst) { + const IR::Value cond{inst.Arg(0)}; + if (cond.IsImmediate()) { + inst.ReplaceUsesWithAndRemove(cond.U1() ? inst.Arg(1) : inst.Arg(2)); + } + if (inst.GetOpcode() == IR::Opcode::SelectU1) { + if (inst.Arg(1).IsImmediate() && inst.Arg(1).U1() == true && inst.Arg(2).IsImmediate() && + inst.Arg(2).U1() == false) { + inst.ReplaceUsesWithAndRemove(cond); + } + } +} + +void FoldLogicalOr(IR::Inst& inst) { + if (!FoldCommutative(inst, [](bool a, bool b) { return a || b; })) { + return; + } + const IR::Value rhs{inst.Arg(1)}; + if (rhs.IsImmediate()) { + if (rhs.U1()) { + inst.ReplaceUsesWithAndRemove(IR::Value{true}); + } else { + inst.ReplaceUsesWithAndRemove(inst.Arg(0)); + } + } +} + +void FoldLogicalNot(IR::Inst& inst) { + const IR::U1 value{inst.Arg(0)}; + if (value.IsImmediate()) { + inst.ReplaceUsesWithAndRemove(IR::Value{!value.U1()}); + return; + } + IR::Inst* const arg{value.Inst()}; + if (arg->GetOpcode() == IR::Opcode::LogicalNot) { + inst.ReplaceUsesWithAndRemove(arg->Arg(0)); + } +} + +void FoldUnpack32x2(IR::Block& block, IR::Inst& inst, IR::Opcode reverse) { + const IR::Value value{inst.Arg(0)}; + if (value.IsImmediate()) { + IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; + const auto value_lo = ir.Imm32(static_cast(value.U64())); + const auto value_hi = ir.Imm32(static_cast(value.U64() >> 32)); + inst.ReplaceUsesWithAndRemove(ir.CompositeConstruct(value_lo, value_hi)); + return; + } + IR::Inst* const arg_inst{value.Inst()}; + if (arg_inst->GetOpcode() == reverse) { + inst.ReplaceUsesWithAndRemove(arg_inst->Arg(0)); + return; + } +} + +void FoldInverseBallot(IR::Inst& inst) { + const IR::Value value{inst.Arg(0)}; + if (value.IsImmediate()) { + if (value.U64() == 0ULL) { + inst.ReplaceUsesWithAndRemove(IR::Value{false}); + } else if (value.U64() == std::numeric_limits::max()) { + inst.ReplaceUsesWithAndRemove(IR::Value{true}); + } + return; + } + IR::Inst* const arg_inst{value.Inst()}; + if (arg_inst->GetOpcode() == IR::Opcode::Ballot) { + inst.ReplaceUsesWithAndRemove(arg_inst->Arg(0)); + return; + } +} + +void FoldInverseFunc(IR::Inst& inst, IR::Opcode reverse) { + const IR::Value value{inst.Arg(0)}; + if (value.IsImmediate()) { + return; + } + IR::Inst* const arg_inst{value.Inst()}; + if (arg_inst->GetOpcode() == reverse) { + inst.ReplaceUsesWithAndRemove(arg_inst->Arg(0)); + return; + } +} + +void FoldDiscardCond(IR::Inst& inst) { + const IR::U1 cond{inst.Arg(0)}; + if (!cond.IsImmediate()) { + return; + } + if (cond.U1()) { + inst.ReplaceOpcode(IR::Opcode::Discard); + } else { + inst.Invalidate(); + } +} + +template +void FoldAdd(IR::Block& block, IR::Inst& inst) { + if (!FoldCommutative(inst, [](T a, T b) { return a + b; })) { + return; + } + const IR::Value rhs{inst.Arg(1)}; + if (rhs.IsImmediate() && Arg(rhs) == 0) { + inst.ReplaceUsesWithAndRemove(inst.Arg(0)); + return; + } +} + +template +void FoldMul(IR::Block& block, IR::Inst& inst) { + if (!FoldCommutative(inst, [](T a, T b) { return a * b; })) { + return; + } + const IR::Value rhs{inst.Arg(1)}; + if (rhs.IsImmediate()) { + if (Arg(rhs) == 0) { + inst.ReplaceUsesWithAndRemove(IR::Value(0u)); + return; + } + if (Arg(rhs) == 1) { + inst.ReplaceUsesWithAndRemove(inst.Arg(0)); + return; + } + } +} + +void ConstantPropagation(IR::Block& block, IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::IAdd32: + return FoldAdd(block, inst); + case IR::Opcode::ISub32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a - b; }); + return; + case IR::Opcode::ConvertF32U32: + FoldWhenAllImmediates(inst, [](u32 a) { return static_cast(a); }); + return; + case IR::Opcode::IMul32: + FoldMul(block, inst); + return; + case IR::Opcode::UDiv32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { + ASSERT_MSG(b != 0, "Folding UDiv32 with divisor 0"); + return a / b; + }); + return; + case IR::Opcode::UMod32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { + ASSERT_MSG(b != 0, "Folding UMod32 with modulo 0"); + return a % b; + }); + return; + case IR::Opcode::ShiftLeftLogical32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return static_cast(a << b); }); + return; + case IR::Opcode::ShiftRightLogical32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return static_cast(a >> b); }); + return; + case IR::Opcode::ShiftRightArithmetic32: + FoldWhenAllImmediates(inst, [](s32 a, s32 b) { return static_cast(a >> b); }); + return; + case IR::Opcode::BitCastF32U32: + return FoldBitCast(inst, IR::Opcode::BitCastU32F32); + case IR::Opcode::BitCastU32F32: + return FoldBitCast(inst, IR::Opcode::BitCastF32U32); + case IR::Opcode::PackUint2x32: + return FoldInverseFunc(inst, IR::Opcode::UnpackUint2x32); + case IR::Opcode::UnpackUint2x32: + return FoldUnpack32x2(block, inst, IR::Opcode::PackUint2x32); + case IR::Opcode::PackDouble2x32: + return FoldInverseFunc(inst, IR::Opcode::UnpackDouble2x32); + case IR::Opcode::UnpackDouble2x32: + return FoldUnpack32x2(block, inst, IR::Opcode::PackDouble2x32); + case IR::Opcode::InverseBallot: + return FoldInverseBallot(inst); + // 2x16 + case IR::Opcode::PackUnorm2x16: + return FoldInverseFunc(inst, IR::Opcode::UnpackUnorm2x16); + case IR::Opcode::UnpackUnorm2x16: + return FoldInverseFunc(inst, IR::Opcode::PackUnorm2x16); + case IR::Opcode::PackSnorm2x16: + return FoldInverseFunc(inst, IR::Opcode::UnpackSnorm2x16); + case IR::Opcode::UnpackSnorm2x16: + return FoldInverseFunc(inst, IR::Opcode::PackSnorm2x16); + case IR::Opcode::PackUint2x16: + return FoldInverseFunc(inst, IR::Opcode::UnpackUint2x16); + case IR::Opcode::UnpackUint2x16: + return FoldInverseFunc(inst, IR::Opcode::PackUint2x16); + case IR::Opcode::PackSint2x16: + return FoldInverseFunc(inst, IR::Opcode::UnpackSint2x16); + case IR::Opcode::UnpackSint2x16: + return FoldInverseFunc(inst, IR::Opcode::PackSint2x16); + case IR::Opcode::PackHalf2x16: + return FoldInverseFunc(inst, IR::Opcode::UnpackHalf2x16); + case IR::Opcode::UnpackHalf2x16: + return FoldInverseFunc(inst, IR::Opcode::PackHalf2x16); + // 4x8 + case IR::Opcode::PackUnorm4x8: + return FoldInverseFunc(inst, IR::Opcode::UnpackUnorm4x8); + case IR::Opcode::UnpackUnorm4x8: + return FoldInverseFunc(inst, IR::Opcode::PackUnorm4x8); + case IR::Opcode::PackSnorm4x8: + return FoldInverseFunc(inst, IR::Opcode::UnpackSnorm4x8); + case IR::Opcode::UnpackSnorm4x8: + return FoldInverseFunc(inst, IR::Opcode::PackSnorm4x8); + case IR::Opcode::PackUint4x8: + return FoldInverseFunc(inst, IR::Opcode::UnpackUint4x8); + case IR::Opcode::UnpackUint4x8: + return FoldInverseFunc(inst, IR::Opcode::PackUint4x8); + case IR::Opcode::PackSint4x8: + return FoldInverseFunc(inst, IR::Opcode::UnpackSint4x8); + case IR::Opcode::UnpackSint4x8: + return FoldInverseFunc(inst, IR::Opcode::PackSint4x8); + // 10_11_11 + case IR::Opcode::PackUfloat10_11_11: + return FoldInverseFunc(inst, IR::Opcode::UnpackUfloat10_11_11); + case IR::Opcode::UnpackUfloat10_11_11: + return FoldInverseFunc(inst, IR::Opcode::PackUfloat10_11_11); + // 2_10_10_10 + case IR::Opcode::PackUnorm2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::UnpackUnorm2_10_10_10); + case IR::Opcode::UnpackUnorm2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::PackUnorm2_10_10_10); + case IR::Opcode::PackSnorm2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::UnpackSnorm2_10_10_10); + case IR::Opcode::UnpackSnorm2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::PackSnorm2_10_10_10); + case IR::Opcode::PackUint2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::UnpackUint2_10_10_10); + case IR::Opcode::UnpackUint2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::PackUint2_10_10_10); + case IR::Opcode::PackSint2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::UnpackSint2_10_10_10); + case IR::Opcode::UnpackSint2_10_10_10: + return FoldInverseFunc(inst, IR::Opcode::PackSint2_10_10_10); + case IR::Opcode::SelectU1: + case IR::Opcode::SelectU32: + case IR::Opcode::SelectF32: + return FoldSelect(inst); + case IR::Opcode::FPNeg32: + FoldWhenAllImmediates(inst, [](f32 a) { return -a; }); + return; + case IR::Opcode::LogicalAnd: + return FoldLogicalAnd(inst); + case IR::Opcode::LogicalOr: + return FoldLogicalOr(inst); + case IR::Opcode::LogicalNot: + return FoldLogicalNot(inst); + case IR::Opcode::UMin32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return (a > b ? b : a); }); + return; + case IR::Opcode::UMax32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return (a > b ? a : b); }); + return; + case IR::Opcode::SLessThan32: + FoldWhenAllImmediates(inst, [](s32 a, s32 b) { return a < b; }); + return; + case IR::Opcode::SLessThan64: + FoldWhenAllImmediates(inst, [](s64 a, s64 b) { return a < b; }); + return; + case IR::Opcode::ULessThan32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a < b; }); + return; + case IR::Opcode::ULessThan64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a < b; }); + return; + case IR::Opcode::SLessThanEqual32: + FoldWhenAllImmediates(inst, [](s32 a, s32 b) { return a <= b; }); + return; + case IR::Opcode::SLessThanEqual64: + FoldWhenAllImmediates(inst, [](s64 a, s64 b) { return a <= b; }); + return; + case IR::Opcode::ULessThanEqual32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a <= b; }); + return; + case IR::Opcode::ULessThanEqual64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a <= b; }); + return; + case IR::Opcode::SGreaterThan32: + FoldWhenAllImmediates(inst, [](s32 a, s32 b) { return a > b; }); + return; + case IR::Opcode::SGreaterThan64: + FoldWhenAllImmediates(inst, [](s64 a, s64 b) { return a > b; }); + return; + case IR::Opcode::UGreaterThan32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a > b; }); + return; + case IR::Opcode::UGreaterThan64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a > b; }); + return; + case IR::Opcode::SGreaterThanEqual32: + FoldWhenAllImmediates(inst, [](s32 a, s32 b) { return a >= b; }); + return; + case IR::Opcode::SGreaterThanEqual64: + FoldWhenAllImmediates(inst, [](s64 a, s64 b) { return a >= b; }); + return; + case IR::Opcode::UGreaterThanEqual32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a >= b; }); + return; + case IR::Opcode::UGreaterThanEqual64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a >= b; }); + return; + case IR::Opcode::IEqual32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a == b; }); + return; + case IR::Opcode::IEqual64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a == b; }); + return; + case IR::Opcode::INotEqual32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a != b; }); + return; + case IR::Opcode::INotEqual64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a != b; }); + return; + case IR::Opcode::BitwiseAnd32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a & b; }); + return; + case IR::Opcode::BitwiseAnd64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a & b; }); + return; + case IR::Opcode::BitwiseOr32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a | b; }); + return; + case IR::Opcode::BitwiseOr64: + FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a | b; }); + return; + case IR::Opcode::BitwiseXor32: + FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a ^ b; }); + return; + case IR::Opcode::BitwiseNot32: + FoldWhenAllImmediates(inst, [](u32 a) { return ~a; }); + return; + case IR::Opcode::BitReverse32: + FoldWhenAllImmediates(inst, [](u32 a) { + u32 res{}; + for (s32 i = 0; i < 32; i++, a >>= 1) { + res = (res << 1) | (a & 1); + } + return res; + }); + return; + case IR::Opcode::BitCount32: + FoldWhenAllImmediates(inst, [](u32 a) { return static_cast(std::popcount(a)); }); + return; + case IR::Opcode::BitCount64: + FoldWhenAllImmediates(inst, [](u64 a) { return static_cast(std::popcount(a)); }); + return; + case IR::Opcode::BitFieldUExtract: + FoldWhenAllImmediates(inst, [](u32 base, u32 shift, u32 count) { + if (static_cast(shift) + static_cast(count) > 32) { + UNREACHABLE_MSG("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldUExtract, + base, shift, count); + } + return (base >> shift) & ((1U << count) - 1); + }); + return; + case IR::Opcode::BitFieldSExtract: + FoldWhenAllImmediates(inst, [](s32 base, u32 shift, u32 count) { + const size_t back_shift{static_cast(shift) + static_cast(count)}; + const size_t left_shift{32 - back_shift}; + const size_t right_shift{static_cast(32 - count)}; + if (back_shift > 32 || left_shift >= 32 || right_shift >= 32) { + UNREACHABLE_MSG("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldSExtract, + base, shift, count); + } + return static_cast((base << left_shift) >> right_shift); + }); + return; + case IR::Opcode::BitFieldInsert32: + FoldWhenAllImmediates(inst, [](u32 base, u32 insert, u32 offset, u32 bits) { + if (bits >= 32 || offset >= 32) { + UNREACHABLE_MSG("Undefined result in {}({}, {}, {}, {})", + IR::Opcode::BitFieldInsert32, base, insert, offset, bits); + } + return (base & ~(~(~0u << bits) << offset)) | (insert << offset); + }); + return; + case IR::Opcode::BitFieldInsert64: + FoldWhenAllImmediates(inst, [](u64 base, u64 insert, u32 offset, u32 bits) { + if (bits >= 64 || offset >= 64) { + UNREACHABLE_MSG("Undefined result in {}({}, {}, {}, {})", + IR::Opcode::BitFieldInsert64, base, insert, offset, bits); + } + return (base & ~(~(~u64{0} << bits) << offset)) | (insert << offset); + }); + return; + case IR::Opcode::CompositeExtractU32x2: + return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructU32x2, + IR::Opcode::CompositeInsertU32x2); + case IR::Opcode::CompositeExtractU32x3: + return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructU32x3, + IR::Opcode::CompositeInsertU32x3); + case IR::Opcode::CompositeExtractU32x4: + return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructU32x4, + IR::Opcode::CompositeInsertU32x4); + case IR::Opcode::CompositeExtractF32x2: + return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructF32x2, + IR::Opcode::CompositeInsertF32x2); + case IR::Opcode::CompositeExtractF32x3: + return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructF32x3, + IR::Opcode::CompositeInsertF32x3); + case IR::Opcode::CompositeExtractF32x4: + return FoldCompositeExtract(inst, IR::Opcode::CompositeConstructF32x4, + IR::Opcode::CompositeInsertF32x4); + case IR::Opcode::CompositeConstructU32x2: + return FoldCompositeConstruct(inst, IR::Opcode::CompositeExtractU32x2); + case IR::Opcode::CompositeConstructU32x3: + return FoldCompositeConstruct(inst, IR::Opcode::CompositeExtractU32x3); + case IR::Opcode::CompositeConstructU32x4: + return FoldCompositeConstruct(inst, IR::Opcode::CompositeExtractU32x4); + case IR::Opcode::ConvertF32F16: + return FoldConvert(inst, IR::Opcode::ConvertF16F32); + case IR::Opcode::ConvertF16F32: + return FoldConvert(inst, IR::Opcode::ConvertF32F16); + case IR::Opcode::DiscardCond: + return FoldDiscardCond(inst); + default: + break; + } +} + +void ConstantPropagationPass(IR::BlockList& program) { + const auto end{program.rend()}; + for (auto it = program.rbegin(); it != end; ++it) { + IR::Block* const block{*it}; + for (IR::Inst& inst : block->Instructions()) { + ConstantPropagation(*block, inst); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/constant_propogation.h b/gpu/shadps4/shader_recompiler/ir/passes/constant_propogation.h new file mode 100644 index 0000000..313a3cc --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/constant_propogation.h @@ -0,0 +1,4 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/passes/dead_code_elimination_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/dead_code_elimination_pass.cpp new file mode 100644 index 0000000..c07c567 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/dead_code_elimination_pass.cpp @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "shader_recompiler/ir/program.h" + +namespace Shader::Optimization { + +void DeadCodeEliminationPass(IR::Program& program) { + // We iterate over the instructions in reverse order. + // This is because removing an instruction reduces the number of uses for earlier instructions. + std::unordered_set live; + std::queue worklist; + + for (IR::Block* block : program.post_order_blocks) { + auto it{block->end()}; + while (it != block->begin()) { + --it; + const bool has_side_effects = it->MayHaveSideEffects(); + if (!it->HasUses() && !has_side_effects) { + it->Invalidate(); + it = block->Instructions().erase(it); + } else if (has_side_effects) { + live.insert(&*it); + worklist.push(&*it); + } + } + } + + while (!worklist.empty()) { + IR::Inst* inst = worklist.front(); + worklist.pop(); + + for (size_t i = 0; i < inst->NumArgs(); i++) { + if (inst->Arg(i).IsImmediate()) { + continue; + } + IR::Inst* operand = inst->Arg(i).Inst(); + if (live.insert(operand).second) { + worklist.push(operand); + } + } + } + + for (IR::Block* block : program.post_order_blocks) { + for (auto it = block->begin(); it != block->end();) { + if (live.contains(&*it)) { + ++it; + } else { + it->Invalidate(); + it = block->Instructions().erase(it); + } + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/expression_elimination.h b/gpu/shadps4/shader_recompiler/ir/passes/expression_elimination.h new file mode 100644 index 0000000..17be2c0 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/expression_elimination.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/microinstruction.h" +#include "shader_recompiler/ir/opcodes.h" + +namespace Shader::Optimization { + +static bool IsAllowedInst(const IR::Inst& inst) { + return inst.GetOpcode() == IR::Opcode::Ballot || + inst.GetOpcode() == IR::Opcode::UnpackUint2x32 || + inst.GetOpcode() == IR::Opcode::BitCastU32F32 || + inst.GetOpcode() == IR::Opcode::BitCastF32U32; +} + +static bool IsIdenticalInst(const IR::Inst* a, const IR::Inst* b) { + if (a->GetOpcode() != b->GetOpcode()) { + return false; + } + for (size_t i = 0; i < a->NumArgs(); i++) { + if (a->Arg(i) != b->Arg(i)) { + return false; + } + } + return true; +} + +static void RunLocalCSE(IR::Block* block) { + boost::container::small_vector inst_list; + auto it = std::ranges::find_if_not(*block, IR::IsPhi); + for (; it != block->end(); ++it) { + IR::Inst& inst{*it}; + if (!IsAllowedInst(inst)) { + continue; + } + const auto it = std::ranges::find_if( + inst_list, [&](const IR::Inst* b) { return IsIdenticalInst(&inst, b); }); + if (it != inst_list.end()) { + inst.ReplaceUsesWithAndRemove(IR::Value{*it}); + } else { + inst_list.emplace_back(&inst); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp new file mode 100644 index 0000000..e80d4fe --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp @@ -0,0 +1,883 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include "common/arch.h" +#include "common/decoder.h" +#include "common/io_file.h" +#include "common/logging/log.h" +#include "common/path_util.h" +#include "common/signal_context.h" +#include "core/emulator_settings.h" +#include "core/signals.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/passes/srt.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/srt_gvn_table.h" +#include "shader_recompiler/ir/value.h" + +#ifdef ARCH_X86_64 + +using namespace Xbyak::util; + +static Xbyak::CodeGenerator g_srt_codegen(32_MB); +static const u8* g_srt_codegen_start = nullptr; + +namespace Shader { + +PFN_SrtWalker RegisterWalkerCode(const u8* ptr, size_t size) { + const auto func_addr = (PFN_SrtWalker)g_srt_codegen.getCurr(); + g_srt_codegen.db(ptr, size); + g_srt_codegen.ready(); + return func_addr; +} + +} // namespace Shader + +namespace { + +static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t codesize) { + using namespace Common::FS; + + const auto dump_dir = GetUserPath(PathType::ShaderDir) / "dumps"; + if (!std::filesystem::exists(dump_dir)) { + std::filesystem::create_directories(dump_dir); + } + const auto filename = fmt::format("{}_{:#018x}.srtprogram.txt", info.hw_stage, info.pgm_hash); + const auto file = IOFile{dump_dir / filename, FileAccessMode::Create, FileType::TextFile}; + + u64 address = reinterpret_cast(code); + u64 code_end = address + codesize; + ZydisDecodedInstruction instruction; + ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; + ZyanStatus status = ZYAN_STATUS_SUCCESS; + while (address < code_end && ZYAN_SUCCESS(Common::Decoder::Instance()->decodeInstruction( + instruction, operands, reinterpret_cast(address)))) { + std::string s = + Common::Decoder::Instance()->disassembleInst(instruction, operands, address); + s += "\n"; + file.WriteString(s); + address += instruction.length; + } +} + +static bool SrtWalkerSignalHandler(void* context, void* fault_address) { + // Only handle if the fault address is within the SRT code range + const u8* code_start = g_srt_codegen_start; + const u8* code_end = code_start + g_srt_codegen.getSize(); + const void* code = Common::GetRip(context); + if (code < code_start || code >= code_end) { + return false; // Not in SRT code range + } + + // Patch instruction to zero register + ZydisDecodedInstruction instruction; + ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]; + ZyanStatus status = Common::Decoder::Instance()->decodeInstruction(instruction, operands, + const_cast(code), 15); + + ASSERT(ZYAN_SUCCESS(status) && instruction.mnemonic == ZYDIS_MNEMONIC_MOV && + operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && + operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY); + + size_t len = instruction.length; + const size_t patch_size = 3; + u8* code_patch = const_cast(reinterpret_cast(code)); + + // We can only encounter rdi or r10d as the first operand in a + // fault memory access for SRT walker. + switch (operands[0].reg.value) { + case ZYDIS_REGISTER_RDI: + // mov rdi, [rdi + (off_dw << 2)] -> xor rdi, rdi + code_patch[0] = 0x48; + code_patch[1] = 0x31; + code_patch[2] = 0xFF; + break; + case ZYDIS_REGISTER_R10D: + // mov r10d, [rdi + (off_dw << 2)] -> xor r10d, r10d + code_patch[0] = 0x45; + code_patch[1] = 0x31; + code_patch[2] = 0xD2; + break; + default: + UNREACHABLE_MSG("Unsupported register for SRT walker patch"); + return false; + } + + // Fill nops + memset(code_patch + patch_size, 0x90, len - patch_size); + + LOG_WARNING(Render_Recompiler, "Patched SRT walker at {}, fault address {}", code, + fault_address); + + return true; +} + +using namespace Shader; + +struct PassInfo { + struct PointerListCompare { + bool operator()(const IR::Value& a, const IR::Value& b) const { + // Keep order with the following criteria: + // 1. If immediate, sort by immediate value + // 2. If not immediate, sort by instruction order + // 3. Immediates come first, then instructions + if (a.IsImmediate() && b.IsImmediate()) { + return a.U32() < b.U32(); + } else if (!a.IsImmediate() && !b.IsImmediate()) { + auto a_inst = a.Inst(); + auto b_inst = b.Inst(); + auto a_block = a_inst->GetParent(); + auto b_block = b_inst->GetParent(); + if (a_block != b_block) { + return a_block < b_block; // Sort by block address + } + + auto it = a_block->Instructions().iterator_to(*a_inst); + auto end = a_block->Instructions().end(); + for (; it != end; ++it) { + if (&*it == b_inst) { + return true; + } + } + return false; + } else { + return a.IsImmediate(); // Immediates come first + } + } + }; + + // map offset to inst + using PtrUserList = + boost::container::flat_map; + + Optimization::SrtGvnTable gvn_table; + // keys are GetUserData, ReadConst or ReadConstBuffer instructions that are used as pointers + std::unordered_map pointer_uses; + // GetUserData instructions corresponding to sgpr_base of SRT roots + boost::container::small_flat_map srt_roots; + + // pick a single inst for a given value number + std::unordered_map vn_to_inst; + + // Bumped during codegen to assign offsets to readconsts + u16 dst_off_dw; + + PtrUserList* GetUsesAsPointer(IR::Inst* inst) { + auto it = pointer_uses.find(inst); + if (it != pointer_uses.end()) { + return &it->second; + } + return nullptr; + } + + // Return a single instruction that this instruction is identical to, according + // to value number + // The "original" is arbitrary. Here it's the first instruction found for a given value number + IR::Inst* DeduplicateInstruction(IR::Inst* inst) { + auto it = vn_to_inst.try_emplace(gvn_table.GetValueNumber(inst), inst); + return it.first->second; + } +}; +} // namespace + +namespace Shader::Optimization { + +namespace { + +static inline u16 GetFlatbufOffset(const IR::Inst* inst) { + if (inst->GetOpcode() == IR::Opcode::ReadConstBuffer) { + auto inst_info = inst->Flags(); + return inst_info.flatbuf_off_dw; + } + if (inst->GetOpcode() == IR::Opcode::ReadConst) { + return inst->Flags(); + } + UNREACHABLE_MSG("Instruction not supported"); +} + +static inline void SetFlatbufOffset(IR::Inst* inst, u16 offset) { + if (inst->GetOpcode() == IR::Opcode::ReadConstBuffer) { + auto inst_info = inst->Flags(); + inst_info.flatbuf_off_dw.Assign(offset); + inst->SetFlags(inst_info); + return; + } + if (inst->GetOpcode() == IR::Opcode::ReadConst) { + inst->SetFlags(offset); + return; + } + UNREACHABLE_MSG("Instruction not supported"); +} + +static bool ComputeOffset(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, PassInfo& pass_info, + const IR::Value& off_dw); + +#define ABORT_ON_FAILURE(expr) \ + if (!(expr)) { \ + return false; \ + } + +#define POP_ABORT_ON_FAILURE(expr) \ + if (!(expr)) { \ + c.add(rsp, 8); \ + return false; \ + } + +static bool EmitComputeOffsetIAdd32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, PassInfo& pass_info, + IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.add(reg, inst->Arg(0).U32()); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.add(reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.add(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetISub32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, PassInfo& pass_info, + IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.neg(reg); + c.add(reg, inst->Arg(0).U32()); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.sub(reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.neg(reg); + c.add(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetIMul32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, PassInfo& pass_info, + IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.imul(reg, reg, inst->Arg(0).U32()); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.imul(reg, reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.imul(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetShiftLeftLogical32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, + PassInfo& pass_info, IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.shl(reg, inst->Arg(0).U32()); + c.mov(ecx, reg); + c.mov(reg, inst->Arg(0).U32()); + c.shl(reg, cl); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.shl(reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.pop(rcx); + c.shl(reg, cl); + } + return true; +} + +static bool EmitComputeOffsetShiftRightLogical32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, + PassInfo& pass_info, IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.mov(ecx, reg); + c.mov(reg, inst->Arg(0).U32()); + c.shr(reg, cl); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.shr(reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.pop(rcx); + c.shr(reg, cl); + } + return true; +} + +static bool EmitComputeOffsetBitwiseAnd32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, + PassInfo& pass_info, IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.and_(reg, inst->Arg(0).U32()); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.and_(reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.and_(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetBitwiseOr32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, + PassInfo& pass_info, IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.or_(reg, inst->Arg(0).U32()); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.or_(reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.or_(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetBitwiseXor32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, + PassInfo& pass_info, IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.xor_(reg, inst->Arg(0).U32()); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.xor_(reg, inst->Arg(1).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.xor_(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetBitwiseNot32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, + PassInfo& pass_info, IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.not_(reg); + return true; +} + +static bool EmitComputeOffsetUMin32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, PassInfo& pass_info, + IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.mov(ecx, inst->Arg(0).U32()); + c.cmp(reg, ecx); + c.cmova(reg, ecx); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.mov(ecx, inst->Arg(1).U32()); + c.cmp(reg, ecx); + c.cmova(reg, ecx); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.cmp(reg, dword[rsp]); + c.cmova(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetUMax32(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, PassInfo& pass_info, + IR::Inst* inst) { + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.mov(ecx, inst->Arg(0).U32()); + c.cmp(reg, ecx); + c.cmovb(reg, ecx); + } else if (inst->Arg(1).IsImmediate()) { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.mov(ecx, inst->Arg(1).U32()); + c.cmp(reg, ecx); + c.cmovb(reg, ecx); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + c.push(reg.cvt64()); + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.cmp(reg, dword[rsp]); + c.cmovb(reg, dword[rsp]); + c.add(rsp, 8); + } + return true; +} + +static bool EmitComputeOffsetBitFieldUExtract(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, + PassInfo& pass_info, IR::Inst* inst) { + // We asume that the count is always less than 32, Is this correct? + ASSERT(!inst->AreAllArgsImmediates()); + if (inst->Arg(0).IsImmediate()) { + c.mov(reg, inst->Arg(0).U32()); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(0))); + } + bool in_stack = false; + if (inst->Arg(1).IsImmediate()) { + c.shr(reg, inst->Arg(1).U32()); + } else { + c.push(reg.cvt64()); + in_stack = true; + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(1))); + c.mov(ecx, reg); + c.shr(dword[rsp], cl); + } + if (inst->Arg(2).IsImmediate()) { + if (in_stack) { + c.pop(reg.cvt64()); + } + c.and_(reg, (1U << inst->Arg(2).U32()) - 1); + } else { + if (!in_stack) { + c.push(reg.cvt64()); + } + POP_ABORT_ON_FAILURE(ComputeOffset(c, reg, pass_info, inst->Arg(2))); + c.mov(ecx, reg); + c.mov(edx, 1); + c.shl(edx, cl); + c.dec(edx); + c.and_(dword[rsp], edx); + c.pop(reg.cvt64()); + } + return true; +} + +static bool IsAllowedOffsetInstruction(const IR::Inst* inst) { + switch (inst->GetOpcode()) { + case IR::Opcode::GetUserData: + case IR::Opcode::ReadConst: + case IR::Opcode::ReadConstBuffer: + case IR::Opcode::IAdd32: + case IR::Opcode::ISub32: + case IR::Opcode::IMul32: + case IR::Opcode::ShiftLeftLogical32: + case IR::Opcode::ShiftRightLogical32: + case IR::Opcode::BitwiseAnd32: + case IR::Opcode::BitwiseOr32: + case IR::Opcode::BitwiseXor32: + case IR::Opcode::BitwiseNot32: + case IR::Opcode::UMin32: + case IR::Opcode::UMax32: + case IR::Opcode::BitFieldUExtract: + return true; + default: + return false; + } +} + +static bool ComputeOffset(Xbyak::CodeGenerator& c, Xbyak::Reg32 reg, PassInfo& pass_info, + const IR::Value& off_dw) { + ASSERT(reg != ecx && reg != edx); + auto inst = off_dw.Inst(); + switch (inst->GetOpcode()) { + case IR::Opcode::GetUserData: + c.mov(reg, ptr[rsi + (static_cast(inst->Arg(0).ScalarReg()) << 2)]); + return true; + case IR::Opcode::ReadConst: + case IR::Opcode::ReadConstBuffer: + if (u16 offset = GetFlatbufOffset(pass_info.DeduplicateInstruction(inst)); offset != 0) { + c.mov(reg, ptr[rsi + (offset << 2)]); + return true; + } + return false; + case IR::Opcode::IAdd32: + ABORT_ON_FAILURE(EmitComputeOffsetIAdd32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::ISub32: + ABORT_ON_FAILURE(EmitComputeOffsetISub32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::IMul32: + ABORT_ON_FAILURE(EmitComputeOffsetIMul32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::ShiftLeftLogical32: + ABORT_ON_FAILURE(EmitComputeOffsetShiftLeftLogical32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::ShiftRightLogical32: + ABORT_ON_FAILURE(EmitComputeOffsetShiftRightLogical32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::BitwiseAnd32: + ABORT_ON_FAILURE(EmitComputeOffsetBitwiseAnd32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::BitwiseOr32: + ABORT_ON_FAILURE(EmitComputeOffsetBitwiseOr32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::BitwiseXor32: + ABORT_ON_FAILURE(EmitComputeOffsetBitwiseXor32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::BitwiseNot32: + ABORT_ON_FAILURE(EmitComputeOffsetBitwiseNot32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::UMin32: + ABORT_ON_FAILURE(EmitComputeOffsetUMin32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::UMax32: + ABORT_ON_FAILURE(EmitComputeOffsetUMax32(c, reg, pass_info, inst)); + return true; + case IR::Opcode::BitFieldUExtract: + ABORT_ON_FAILURE(EmitComputeOffsetBitFieldUExtract(c, reg, pass_info, inst)); + return true; + default: + LOG_ERROR(Render_Recompiler, "Unexpected instruction for offset computation, {}", + magic_enum::enum_name(inst->GetOpcode())); + return false; + } +} + +static inline bool PushPtr(Xbyak::CodeGenerator& c, PassInfo& pass_info, const IR::Value& off_dw) { + c.push(rdi); + if (off_dw.IsImmediate()) { + c.mov(rdi, ptr[rdi + (off_dw.U32() << 2)]); + } else { + ABORT_ON_FAILURE(ComputeOffset(c, r10d, pass_info, off_dw)); + c.shl(r10d, 2); + c.mov(r10d, r10d); + c.mov(rdi, ptr[rdi + r10]); + } + c.mov(r10, 0xFFFFFFFFFFFFULL); + c.and_(rdi, r10); + return true; +} + +static inline void PopPtr(Xbyak::CodeGenerator& c) { + c.pop(rdi); +} + +static void VisitPointer(const IR::Value& off_dw, IR::Inst* subtree, PassInfo& pass_info, + Xbyak::CodeGenerator& c) { + if (subtree->GetOpcode() == IR::Opcode::ReadConst && subtree->Flags() == 0 || + subtree->GetOpcode() == IR::Opcode::ReadConstBuffer && + subtree->Flags().flatbuf_off_dw == 0) { + return; + } + + if (!PushPtr(c, pass_info, off_dw)) { + LOG_ERROR(Render_Recompiler, "Failed to compute offset for SRT walker"); + return; + } + PassInfo::PtrUserList* use_list = pass_info.GetUsesAsPointer(subtree); + ASSERT(use_list); + + // First copy all the src data from this tree level + // That way, all data that was contiguous in the guest SRT is also contiguous in the + // flattened buffer. + // TODO src and dst are contiguous. Optimize with wider loads/stores + // TODO if this subtree is dynamically indexed, don't compact it (keep it sparse) + for (auto [src_off_dw, use] : *use_list) { + if (src_off_dw.IsImmediate()) { + c.mov(r10d, ptr[rdi + (src_off_dw.U32() << 2)]); + } else { + if (!ComputeOffset(c, r10d, pass_info, src_off_dw)) { + LOG_ERROR(Render_Recompiler, "Failed to compute offset for SRT walker"); + continue; + } + c.shl(r10d, 2); + c.mov(r10d, r10d); + c.mov(r10d, dword[rdi + r10]); + } + c.mov(ptr[rsi + (pass_info.dst_off_dw << 2)], r10d); + + SetFlatbufOffset(use, pass_info.dst_off_dw); + pass_info.dst_off_dw++; + } + + // Then visit any children used as pointers + for (const auto [src_off_dw, use] : *use_list) { + if (pass_info.GetUsesAsPointer(use)) { + VisitPointer(src_off_dw, use, pass_info, c); + } + } + + PopPtr(c); +} + +static void GenerateSrtProgram(Info& info, PassInfo& pass_info) { + Xbyak::CodeGenerator& c = g_srt_codegen; + + if (pass_info.srt_roots.empty()) { + return; + } + + // Register the signal handler for SRT walker, if not already registered + if (g_srt_codegen_start == nullptr) { + g_srt_codegen_start = c.getCurr(); + auto* signals = Core::Signals::Instance(); + // Call after the memory invalidation handler + constexpr u32 priority = 1; + signals->RegisterAccessViolationHandler(SrtWalkerSignalHandler, priority); + } + + info.srt_info.walker_func = c.getCurr(); + pass_info.dst_off_dw = NUM_USER_DATA_REGS; + ASSERT(pass_info.dst_off_dw == info.srt_info.flattened_bufsize_dw); + + for (const auto& [sgpr_base, root] : pass_info.srt_roots) { + VisitPointer(IR::Value(static_cast(sgpr_base)), root, pass_info, c); + } + + c.ret(); + c.ready(); + + info.srt_info.walker_func_size = + c.getCurr() - reinterpret_cast(info.srt_info.walker_func); + + if (EmulatorSettings.IsDumpShaders()) { + DumpSrtProgram(info, reinterpret_cast(info.srt_info.walker_func), + info.srt_info.walker_func_size); + } + + info.srt_info.flattened_bufsize_dw = pass_info.dst_off_dw; +} + +static bool IsReadConstSource(const IR::Value base) { + auto* inst = base.TryInst(); + if (!inst) { + return false; + } + return inst->GetOpcode() == IR::Opcode::GetUserData || + inst->GetOpcode() == IR::Opcode::ReadConst || + inst->GetOpcode() == IR::Opcode::ReadConstBuffer; +} + +void SimplifyReadConstAddressAdd(IR::Inst& inst) { + // This handles the following pattern by combining the addition with the offset + // %82 = IAdd32 %65, #28816 + // %83 = ULessThan32 %82, %65 + // %84 = SelectU32 %83, #1, #0 + // %85 = IAdd32 %66, %84 + // %86 = CompositeConstructU32x2 %82, %85 + // %87 = ReadConst (flags=0x0) %86, #0 + if (inst.GetOpcode() != IR::Opcode::ReadConst) { + return; + } + IR::Inst* addr = inst.Arg(0).Inst(); + IR::Inst* hi = addr->Arg(1).TryInst(); + IR::Inst* lo = addr->Arg(0).TryInst(); + if (!hi || !lo) { + return; + } + + if (lo->GetOpcode() != IR::Opcode::IAdd32 || hi->GetOpcode() != IR::Opcode::IAdd32) { + return; + } + + IR::Value add_offset; + IR::Value base; + if (base = lo->Arg(0); IsReadConstSource(base)) { + add_offset = lo->Arg(1); + } else if (base = lo->Arg(1); IsReadConstSource(base)) { + add_offset = lo->Arg(0); + } else { + return; + } + + IR::Inst* sel = hi->Arg(1).TryInst(); + if (!sel || sel->GetOpcode() != IR::Opcode::SelectU32) { + return; + } + + IR::Value sel_true = sel->Arg(1); + IR::Value sel_false = sel->Arg(2); + if (!sel_true.IsImmediate() || !sel_false.IsImmediate() || sel_true.U32() != 1 || + sel_false.U32() != 0) { + return; + } + + addr->SetArg(0, base); + addr->SetArg(1, hi->Arg(0)); + for (auto [user, operand] : addr->Uses()) { + ASSERT(user->GetOpcode() == IR::Opcode::ReadConst && operand == 0); + IR::IREmitter ir{*user->GetParent(), IR::Block::InstructionList::s_iterator_to(*user)}; + IR::U32 offset = IR::U32{user->Arg(1)}; + IR::U32 dw_add_offset = + add_offset.IsImmediate() + ? ir.Imm32(add_offset.U32() >> 2u) + : IR::U32{ir.ShiftRightLogical(IR::U32{add_offset}, ir.Imm32(2u))}; + if (offset.IsImmediate() && dw_add_offset.IsImmediate()) { + user->SetArg(1, ir.Imm32(offset.U32() + dw_add_offset.U32())); + } else { + user->SetArg(1, ir.IAdd(offset, dw_add_offset)); + } + } +} + +} // Anonymous namespace + +void FlattenExtendedUserdataPass(IR::Program& program) { + auto& post_order = program.post_order_blocks; + PassInfo pass_info; + + // traverse at end and assign offsets to duplicate readconsts, using + // vn_to_inst as the source + boost::container::small_vector all_readconsts, visited; + std::queue queue; + + for (auto it = post_order.rbegin(); it != post_order.rend(); it++) { + IR::Block* block{*it}; + for (IR::Inst& inst : *block) { + if (inst.GetOpcode() != IR::Opcode::ReadConst && + inst.GetOpcode() != IR::Opcode::ReadConstBuffer) { + continue; + } + + if (inst.GetOpcode() == IR::Opcode::ReadConstBuffer) { + // Only flatten ReadConstBuffer if it was marked as a sharp source in the + // resource discovery pass + auto inst_info = inst.Flags(); + if (!inst_info.sharp_source) { + continue; + } + } + + SimplifyReadConstAddressAdd(inst); + + all_readconsts.push_back(&inst); + + auto offset = inst.Arg(1); + if (offset.IsImmediate()) { + continue; + } + + queue.push(offset.Inst()); + while (!queue.empty()) { + IR::Inst* inst{queue.front()}; + queue.pop(); + + if (inst->GetOpcode() == IR::Opcode::ReadConstBuffer) { + auto buffer_inst_info = inst->Flags(); + if (!buffer_inst_info.sharp_source.Value()) { + all_readconsts.push_back(inst); + auto offset = inst->Arg(1); + if (!offset.IsImmediate()) { + auto arg_inst = offset.Inst(); + if (std::ranges::find(visited, arg_inst) == visited.end()) { + visited.push_back(arg_inst); + queue.push(arg_inst); + } + } + } + continue; + } + if (inst->GetOpcode() == IR::Opcode::GetUserData || + inst->GetOpcode() == IR::Opcode::ReadConst || + !IsAllowedOffsetInstruction(inst)) { + continue; + } + for (size_t arg = inst->NumArgs(); arg--;) { + const IR::Value arg_value = inst->Arg(arg); + if (arg_value.IsImmediate()) { + continue; + } + IR::Inst* arg_inst = arg_value.Inst(); + if (std::ranges::find(visited, arg_inst) == visited.end()) { + visited.push_back(arg_inst); + queue.push(arg_inst); + } + } + } + } + } + + for (auto inst : all_readconsts) { + if (pass_info.DeduplicateInstruction(inst) != inst) { + // This is a duplicate of a readconst we've already visited + continue; + } + + IR::Inst* base = inst->Arg(0).Inst(); + if (auto* inst = base->Arg(0).TryInst(); + inst && inst->GetOpcode() == IR::Opcode::ReadFirstLane) { + continue; + } + ASSERT_MSG(IsReadConstSource(base->Arg(0)), "ReadConst base low not from constant memory"); + ASSERT_MSG(IsReadConstSource(base->Arg(1)), "ReadConst base high not from constant memory"); + + IR::Inst* ptr_lo = base->Arg(0).Inst(); + ptr_lo = pass_info.DeduplicateInstruction(ptr_lo); + + auto ptr_uses_kv = pass_info.pointer_uses.try_emplace(ptr_lo, PassInfo::PtrUserList{}); + PassInfo::PtrUserList& user_list = ptr_uses_kv.first->second; + + user_list[inst->Arg(1)] = inst; + + if (ptr_lo->GetOpcode() == IR::Opcode::GetUserData) { + IR::ScalarReg ud_reg = ptr_lo->Arg(0).ScalarReg(); + pass_info.srt_roots[ud_reg] = ptr_lo; + } + } + + GenerateSrtProgram(program.info, pass_info); + + // Assign offsets to duplicate readconsts + for (IR::Inst* readconst : all_readconsts) { + ASSERT(pass_info.vn_to_inst.contains(pass_info.gvn_table.GetValueNumber(readconst))); + IR::Inst* original = pass_info.DeduplicateInstruction(readconst); + SetFlatbufOffset(readconst, GetFlatbufOffset(original)); + } + + program.info.RefreshFlatBuf(); +} + +} // namespace Shader::Optimization + +#else + +namespace Shader { + +PFN_SrtWalker RegisterWalkerCode(const u8* ptr, size_t size) { + UNREACHABLE_MSG("RegisterWalkerCode unimplemented for target architecture."); +} + +namespace Optimization { + +void FlattenExtendedUserdataPass(IR::Program& program) { + UNREACHABLE_MSG("FlattenExtendedUserdataPass unimplemented for target architecture."); +} + +} // namespace Optimization + +} // namespace Shader + +#endif diff --git a/gpu/shadps4/shader_recompiler/ir/passes/hull_shader_transform.cpp b/gpu/shadps4/shader_recompiler/ir/passes/hull_shader_transform.cpp new file mode 100644 index 0000000..0cd2b2f --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/hull_shader_transform.cpp @@ -0,0 +1,760 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/breadth_first_search.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/operand_helper.h" +#include "shader_recompiler/ir/passes/ir_passes.h" +#include "shader_recompiler/ir/pattern_matching.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::Optimization { + +/** + * Tessellation shaders pass outputs to the next shader using LDS. + * The Hull shader stage receives input control points stored in LDS. + * + * These passes attempt to resolve LDS accesses to attribute accesses and correctly + * write to the tessellation factor tables. + * + * The LDS layout is: + * - TCS inputs for patch 0 + * - TCS inputs for patch 1 + * - TCS inputs for patch 2 + * - ... + * - TCS outputs for patch 0 + * - TCS outputs for patch 1 + * - TCS outputs for patch 2 + * - ... + * - PatchConst TCS outputs for patch 0 + * - PatchConst TCS outputs for patch 1 + * - PatchConst TCS outputs for patch 2 + * + * + * If the Hull stage does not write any new control points the driver will + * optimize LDS layout so input and output control point spaces overlap. + * (Passthrough) + * + * The gnm driver requires a V# holding special constants to be bound + * for reads by the shader. + * The Hull and Domain shaders read values from this buffer which + * contain size and offset information required to address input, output, + * or PatchConst attributes within the current patch. + * See the TessellationDataConstantBuffer struct to see the layout of this V#. + * + * Tessellation factors are stored to a special tessellation factor V# that is automatically bound + * by the driver. This is the input to the fixed function tessellator that actually subdivides the + * domain. We translate these to writes to SPIR-V builtins for tessellation factors in the Hull + * shader. + * The offset into the tess factor buffer determines which factor the shader is writing. + * Additionally, most hull shaders seem to redundantly write tess factors to PatchConst + * attributes, even if dead in the domain shader. We just treat these as generic PatchConst writes. + * + * LDS reads in the Hull shader can be from input control points, and in the the Domain shader can + * be hs output control points (output from the perspective of the Hull shader) and patchconst + * values. + * LDS stores in the Hull shader can either be output control point writes or per-patch + * (PatchConst) data writes. The Domain shader exports attributes using EXP instructions, unless its + * followed by the geometry stage (but we havent seen this yet), so nothing special there. + * The address calculations can vary significantly and can't be easily pattern matched. We are at + * the mercy of instruction selection the ps4 compiler wanted to use. + * Generally though, they could look something like this: + * Input control point: + * addr = PatchIdInVgt * input_cp_stride * #input_cp_per_patch + index * input_cp_stride + * + attr# * 16 + component + * Output control point: + * addr = #patches * input_cp_stride * #input_cp_per_patch + * + PatchIdInVgt * output_patch_stride + InvocationID * output_cp_stride + + attr# * 16 + component + * Per patch output: + * addr = #patches * input_cp_stride * #cp_per_input_patch + * + #patches * output_patch_stride + * + PatchIdInVgt * per_patch_output_stride + attr# * 16 + component + * + * output_patch_stride and output_cp_stride are usually compile time constants in the gcn + * + * Hull shaders can also read output control points corresponding to other threads. + * In HLSL style, this should only be possible in the Patch Constant function. + * TODO we may need to insert additional barriers if sync is free/more permissive + * on AMD LDS HW + + * They should also be able to read output PatchConst values, + * although not sure if this happens in practice. + * + * To determine which type of attribute (input, output, patchconst) we the check the users of + * TessConstants V# reads to deduce which type of attribute a given load/store to LDS + * is touching. + * + * In the Hull shader, both the PatchId within the VGT group (PatchIdInVgt) and the output control + * point id (InvocationId) are packed in VGPR1 by the driver like + * V1 = InvocationId << 8 | PatchIdInVgt + * The shader typically uses V_BFE_(U|S)32 to extract them. We use the starting bit_pos to determine + * which is which. + * + * This pass does not attempt to deduce the exact attribute referenced in a LDS load/store. + * Instead, it feeds the address in the LDS load/store to the get/set Insts we use for TCS in/out's, + * TES in's, and PatchConst in/out's. + * + * TCS/TES Input attributes: + * We define input attributes using an array in the shader roughly like this: + * // equivalent GLSL in TCS + * layout (location = 0) in vec4 in_attrs[][NUM_INPUT_ATTRIBUTES]; + * + * Here the NUM_INPUT_ATTRIBUTES is derived from the ls_stride member of the TessConstants V#. + * We take ALIGN_UP(ls_stride, 16) / 16 to get the number of vec4 attributes. + * For TES, NUM_INPUT_ATTRIBUTES is ALIGN_UP(hs_cp_stride, 16) / 16. + * The first (outer) dimension is unsized but corresponds to the number of vertices in the hs input + * patch (for Hull) or the hs output patch (for Domain). + * + * For input reads in TCS or TES, we emit SPIR-V like: + * float value = in_attrs[addr / ls_stride][(addr % ls_stride) >> 4][(addr % ls_stride) >> 2]; + * + * For output writes, we assume the control point index is InvocationId, since high level languages + * impose that restriction (although maybe it's technically possible on hardware). So SPIR-V looks + * like this: + * layout (location = 0) in vec4 in_attrs[][NUM_OUTPUT_ATTRIBUTES]; + * out_attrs[InvocationId][(addr % hs_cp_stride) >> 4][(addr % hs_cp_stride) >> 2] = value; + * + * NUM_OUTPUT_ATTRIBUTES is derived by ALIGN_UP(hs_cp_stride, 16) / 16, so it matches + * NUM_INPUT_ATTRIBUTES of the TES. + * + * Another challenge is the fact that the GCN shader needs to address attributes from LDS as a whole + * which contains the attributes from many patches. On the other hand, higher level shading + * languages restrict attribute access to the patch of the current thread, which is naturally a + * restriction in SPIR-V also. + * The addresses the ps4 compiler generates for loads/stores and the fact that LDS holds many + * patches' attributes are just implementation details of the ps4 driver/compiler. To deal with + * this, we can replace certain TessConstant V# reads with 0, which only contribute to the base + * address of the current patch's attributes in LDS and not the indexes within the local patch. + * + * (A perfect implementation might need emulation of the VGTs in mesh/compute, loading/storing + * attributes to buffers and not caring about whether they are hs input, hs output, or patchconst + * attributes) + * + */ + +namespace { + +using namespace Shader::Optimiation::PatternMatching; + +static void InitTessConstants(IR::ScalarReg sharp_ptr_base, s32 sharp_dword_offset, + Shader::Info& info, Shader::RuntimeInfo& runtime_info, + TessellationDataConstantBuffer& tess_constants) { + info.tess_consts_ptr_base = sharp_ptr_base; + info.tess_consts_dword_offset = sharp_dword_offset; + info.ReadTessConstantBuffer(tess_constants); + runtime_info.InitFromTessConstants(tess_constants); + return; +} + +struct TessSharpLocation { + IR::ScalarReg ptr_base; + u32 dword_off; +}; + +std::optional FindTessConstantSharp(IR::Inst* read_const_buffer) { + IR::Value sharp_ptr_base; + IR::Value sharp_dword_offset; + + IR::Value rv = IR::Value{read_const_buffer}; + IR::Value handle = read_const_buffer->Arg(0); + + if (M_COMPOSITECONSTRUCTU32X4(M_GETUSERDATA(MatchImm(sharp_dword_offset)), MatchIgnore(), + MatchIgnore(), MatchIgnore()) + .Match(handle)) { + return TessSharpLocation{.ptr_base = IR::ScalarReg::Max, + .dword_off = static_cast(sharp_dword_offset.ScalarReg())}; + } else if (M_COMPOSITECONSTRUCTU32X4( + M_READCONST(M_COMPOSITECONSTRUCTU32X2(M_GETUSERDATA(MatchImm(sharp_ptr_base)), + MatchIgnore()), + MatchImm(sharp_dword_offset)), + MatchIgnore(), MatchIgnore(), MatchIgnore()) + .Match(handle)) { + return TessSharpLocation{.ptr_base = sharp_ptr_base.ScalarReg(), + .dword_off = sharp_dword_offset.U32()}; + } + return {}; +} + +// Walker that helps deduce what type of attribute a DS instruction is reading +// or writing, which could be an input control point, output control point, +// or per-patch constant (PatchConst). +// For certain ReadConstBuffer instructions using the tess constants V#, we visit the users +// recursively and increment a counter on the Load/WriteShared users. +// Namely NumPatch (from m_hsNumPatch), HsOutputBase (m_hsOutputBase), +// and PatchConstBase (m_patchConstBase). +// In addr calculations, the term NumPatch * ls_stride * #input_cp_in_patch +// is used as an addend to skip the region for input control points, and similarly +// NumPatch * hs_cp_stride * #output_cp_in_patch is used to skip the region +// for output control points. +// +// TODO: this will break if AMD compiler used distributive property like +// TcsNumPatches * (ls_stride * #input_cp_in_patch + hs_cp_stride * #output_cp_in_patch) +// +// Assert if the region is ambiguous due to phi nodes in the addr calculation for a DS instruction, +class TessConstantUseWalker { +public: + void WalkUsersOfTessConstant(IR::Inst* read_const_buffer, TessConstantAttribute attr) { + u32 inc; + switch (attr) { + case TessConstantAttribute::HsNumPatch: + case TessConstantAttribute::HsOutputBase: + inc = 1; + break; + case TessConstantAttribute::PatchConstBase: + inc = 2; + break; + default: + UNREACHABLE(); + } + + for (IR::Use use : read_const_buffer->Uses()) { + WalkUsersOfTessConstantHelper(use, inc, false); + } + + ++seq_num; + } + +private: + struct PhiInfo { + u32 seq_num; + u32 unique_edge; + }; + + void WalkUsersOfTessConstantHelper(IR::Use use, u32 inc, bool propagateError) { + IR::Inst* inst = use.user; + + switch (use.user->GetOpcode()) { + case IR::Opcode::LoadSharedU32: + case IR::Opcode::LoadSharedU64: + case IR::Opcode::WriteSharedU32: + case IR::Opcode::WriteSharedU64: { + bool is_addr_operand = use.operand == 0; + if (is_addr_operand) { + u32 counter = inst->Flags(); + inst->SetFlags(counter + inc); + ASSERT_MSG(!propagateError, "LDS instruction {} accesses ambiguous attribute type", + fmt::ptr(use.user)); + // Stop here + return; + } + break; + } + case IR::Opcode::Phi: { + auto it = phi_infos.find(use.user); + // the point of seq_num is to tell us if we've already traversed this + // phi on the current walk to handle phi cycles + if (it == phi_infos.end()) { + // First time we've encountered this phi + // Mark the phi as having been traversed originally through this edge + phi_infos[inst] = {.seq_num = seq_num, + .unique_edge = static_cast(use.operand)}; + } else if (it->second.seq_num < seq_num) { + it->second.seq_num = seq_num; + // For now, assume we are visiting this phi via the same edge + // as on other walks. If not, some dataflow analysis might be necessary + if (it->second.unique_edge != use.operand) { + propagateError = true; + } + } else { + ASSERT(it->second.seq_num == seq_num); + // there's a cycle, and we've already been here on this walk + return; + } + break; + } + default: + break; + } + + for (IR::Use use : inst->Uses()) { + WalkUsersOfTessConstantHelper(use, inc, propagateError); + } + } + + std::unordered_map phi_infos; + u32 seq_num{1u}; +}; + +enum class AttributeRegion : u32 { InputCP, OutputCP, PatchConst }; + +static AttributeRegion GetAttributeRegionKind(IR::Inst* ring_access, const Shader::Info& info, + const Shader::RuntimeInfo& runtime_info) { + u32 count = ring_access->Flags(); + if (count == 0) { + return AttributeRegion::InputCP; + } else if (info.sw_stage == SwStage::TessellationControl && + runtime_info.sw.tcs.IsPassthrough()) { + ASSERT(count <= 1); + return AttributeRegion::PatchConst; + } else { + ASSERT(count <= 2); + return AttributeRegion(count); + } +} + +static bool IsDivisibleByStride(IR::Value term, u32 stride) { + IR::Value a, b; + if (MatchU32(stride).Match(term)) { + return true; + } else if (M_BITFIELDUEXTRACT(MatchValue(a), MatchU32(0), MatchU32(24)).Match(term) || + M_BITFIELDSEXTRACT(MatchValue(a), MatchU32(0), MatchU32(24)).Match(term)) { + return IsDivisibleByStride(a, stride); + } else if (M_IMUL32(MatchValue(a), MatchValue(b)).Match(term)) { + return IsDivisibleByStride(a, stride) || IsDivisibleByStride(b, stride); + } + return false; +} + +// Return true if we can eliminate any addends +static bool TryOptimizeAddendInModulo(IR::Value addend, u32 stride, std::vector& addends) { + IR::Value a, b; + if (M_IADD32(MatchValue(a), MatchValue(b)).Match(addend)) { + bool ret = false; + ret = TryOptimizeAddendInModulo(a, stride, addends); + ret |= TryOptimizeAddendInModulo(b, stride, addends); + return ret; + } else if (!IsDivisibleByStride(addend, stride)) { + addends.push_back(IR::U32{addend}); + return false; + } else { + return true; + } +} + +// In calculation (a + b + ...) % stride +// Use this fact +// (a + b) mod N = (a mod N + b mod N) mod N +// If any addend is divisible by stride, then we can replace it with 0 in the attribute +// or component index calculation +static IR::U32 TryOptimizeAddressModulo(IR::U32 addr, u32 stride, IR::IREmitter& ir) { + std::vector addends; + if (TryOptimizeAddendInModulo(addr, stride, addends)) { + addr = ir.Imm32(0); + for (auto& addend : addends) { + addr = ir.IAdd(addr, addend); + } + } + return addr; +} + +// TODO: can optimize div in control point index similarly to mod + +// Read a TCS input (InputCP region) or TES input (OutputCP region) +static IR::F32 ReadTessControlPointAttribute(IR::U32 addr, const u32 stride, IR::IREmitter& ir, + u32 off_dw, bool is_output_read_in_tcs) { + if (off_dw > 0) { + addr = ir.IAdd(addr, ir.Imm32(off_dw)); + } + const IR::U32 control_point_index = ir.IDiv(addr, ir.Imm32(stride)); + const IR::U32 opt_addr = TryOptimizeAddressModulo(addr, stride, ir); + const IR::U32 offset = ir.IMod(opt_addr, ir.Imm32(stride)); + const IR::U32 attr_index = ir.ShiftRightLogical(offset, ir.Imm32(4u)); + const IR::U32 comp_index = + ir.ShiftRightLogical(ir.BitwiseAnd(offset, ir.Imm32(0xFU)), ir.Imm32(2u)); + if (is_output_read_in_tcs) { + return ir.ReadTcsGenericOuputAttribute(control_point_index, attr_index, comp_index); + } else { + return ir.GetTessGenericAttribute(control_point_index, attr_index, comp_index); + } +} + +} // namespace + +void HullShaderTransform(IR::Program& program, const RuntimeInfo& runtime_info) { + const Info& info = program.info; + + for (IR::Block* block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + const auto opcode = inst.GetOpcode(); + switch (opcode) { + case IR::Opcode::StoreBufferU32: + case IR::Opcode::StoreBufferU32x2: + case IR::Opcode::StoreBufferU32x3: + case IR::Opcode::StoreBufferU32x4: { + IR::Value soffset = IR::GetBufferSOffsetArg(&inst); + if (!M_GETATTRIBUTEU32(MatchAttribute(IR::Attribute::TessFactorsBufferBase), + MatchIgnore()) + .Match(soffset)) { + break; + } + + const auto info = inst.Flags(); + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + + IR::Value voffset; + bool success = + M_COMPOSITECONSTRUCTU32X3(MatchU32(0), MatchImm(voffset), MatchIgnore()) + .Match(inst.Arg(IR::StoreBufferArgs::Address)); + ASSERT_MSG(success, "unhandled pattern in tess factor store"); + + const u32 gcn_factor_idx = (info.inst_offset.Value() + voffset.U32()) >> 2; + const IR::Value data = inst.Arg(IR::StoreBufferArgs::Data); + + const u32 num_dwords = u32(opcode) - u32(IR::Opcode::StoreBufferU32) + 1; + + const auto GetValue = [&](IR::Value data) -> IR::F32 { + if (auto* inst = data.TryInst(); + inst && inst->GetOpcode() == IR::Opcode::BitCastU32F32) { + return IR::F32{inst->Arg(0)}; + } + return ir.BitCast(IR::U32{data}); + }; + + auto get_factor_attr = [&](u32 gcn_factor_idx) -> IR::Patch { + // The hull outputs tess factors in different formats depending on the shader. + // For triangle domains, it seems to pack the entries into 4 consecutive floats, + // with the 3 edge factors followed by the 1 interior factor. + // For quads, it does 4 edge factors then 2 interior. + // There is a tess factor stride member of the GNMX hull constants struct in + // a hull program shader binary archive, but this doesn't seem to be + // communicated to the driver. + // The layout seems to be implied by the type of the abstract domain. + switch (runtime_info.sw.tcs.tess_type) { + case AmdGpu::TessellationType::Isoline: + ASSERT(gcn_factor_idx < 2); + return IR::PatchFactor(gcn_factor_idx); + case AmdGpu::TessellationType::Triangle: + ASSERT(gcn_factor_idx < 4); + if (gcn_factor_idx == 3) { + return IR::Patch::TessellationLodInteriorU; + } + return IR::PatchFactor(gcn_factor_idx); + case AmdGpu::TessellationType::Quad: + ASSERT(gcn_factor_idx < 6); + return IR::PatchFactor(gcn_factor_idx); + default: + UNREACHABLE(); + } + }; + + inst.Invalidate(); + if (num_dwords == 1) { + ir.SetPatch(get_factor_attr(gcn_factor_idx), GetValue(data)); + break; + } + auto* inst = data.TryInst(); + ASSERT(inst && (inst->GetOpcode() == IR::Opcode::CompositeConstructU32x2 || + inst->GetOpcode() == IR::Opcode::CompositeConstructU32x3 || + inst->GetOpcode() == IR::Opcode::CompositeConstructU32x4)); + for (s32 i = 0; i < num_dwords; i++) { + ir.SetPatch(get_factor_attr(gcn_factor_idx + i), GetValue(inst->Arg(i))); + } + break; + } + + case IR::Opcode::WriteSharedU32: + case IR::Opcode::WriteSharedU64: { + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + const u32 num_dwords = opcode == IR::Opcode::WriteSharedU32 ? 1 : 2; + const IR::U32 addr{inst.Arg(0)}; + const IR::Value data = + num_dwords == 2 ? ir.UnpackUint2x32(IR::U64{inst.Arg(1)}) : inst.Arg(1); + + const auto SetOutput = [&](IR::U32 addr, IR::U32 value, AttributeRegion output_kind, + u32 off_dw) { + const IR::F32 data_component = ir.BitCast(value); + + if (output_kind == AttributeRegion::OutputCP) { + if (off_dw > 0) { + addr = ir.IAdd(addr, ir.Imm32(off_dw)); + } + const u32 stride = runtime_info.sw.tcs.hs_output_cp_stride; + // Invocation ID array index is implicit, handled by SPIRV backend + const IR::U32 opt_addr = TryOptimizeAddressModulo(addr, stride, ir); + const IR::U32 offset = ir.IMod(opt_addr, ir.Imm32(stride)); + const IR::U32 attr_index = ir.ShiftRightLogical(offset, ir.Imm32(4u)); + const IR::U32 comp_index = ir.ShiftRightLogical( + ir.BitwiseAnd(offset, ir.Imm32(0xFU)), ir.Imm32(2u)); + ir.SetTcsGenericAttribute(data_component, attr_index, comp_index); + } else { + ASSERT(output_kind == AttributeRegion::PatchConst); + ASSERT_MSG(addr.IsImmediate(), "patch addr non imm, inst {}", + fmt::ptr(addr.Inst())); + ir.SetPatch(IR::PatchGeneric((addr.U32() >> 2) + off_dw), data_component); + } + }; + + AttributeRegion region = GetAttributeRegionKind(&inst, info, runtime_info); + if (num_dwords == 1) { + SetOutput(addr, IR::U32{data}, region, 0); + } else { + for (auto i = 0; i < num_dwords; i++) { + SetOutput(addr, IR::U32{ir.CompositeExtract(data, i)}, region, i); + } + } + inst.Invalidate(); + break; + } + + case IR::Opcode::LoadSharedU32: + case IR::Opcode::LoadSharedU64: { + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + const IR::U32 addr{inst.Arg(0)}; + const AttributeRegion region = GetAttributeRegionKind(&inst, info, runtime_info); + const u32 num_dwords = opcode == IR::Opcode::LoadSharedU32 ? 1 : 2; + ASSERT_MSG(region == AttributeRegion::InputCP || + region == AttributeRegion::OutputCP, + "Unhandled read of patchconst attribute in hull shader"); + const bool is_tcs_output_read = region == AttributeRegion::OutputCP; + const u32 stride = is_tcs_output_read ? runtime_info.sw.tcs.hs_output_cp_stride + : runtime_info.sw.tcs.ls_stride; + IR::Value attr_read; + if (num_dwords == 1) { + attr_read = ir.BitCast( + ReadTessControlPointAttribute(addr, stride, ir, 0, is_tcs_output_read)); + } else { + boost::container::static_vector read_components; + for (auto i = 0; i < num_dwords; i++) { + const IR::F32 component = + ReadTessControlPointAttribute(addr, stride, ir, i, is_tcs_output_read); + read_components.push_back(ir.BitCast(component)); + } + attr_read = ir.PackUint2x32(ir.CompositeConstruct(read_components)); + } + inst.ReplaceUsesWithAndRemove(attr_read); + break; + } + + default: + break; + } + } + } + + if (runtime_info.sw.tcs.IsPassthrough()) { + // Copy input attributes to output attributes, indexed by InvocationID + // Passthrough should imply that input and output patches have same number of vertices + IR::Block* entry_block = *program.blocks.begin(); + auto it = std::ranges::find_if(entry_block->Instructions(), [](IR::Inst& inst) { + return inst.GetOpcode() == IR::Opcode::Prologue; + }); + ASSERT(it != entry_block->end()); + ++it; + ASSERT(it != entry_block->end()); + ++it; + // Prologue + // SetExec #true + // <- insert here + // ... + IR::IREmitter ir{*entry_block, it}; + + u32 num_attributes = Common::AlignUp(runtime_info.sw.tcs.ls_stride, 16) >> 4; + const auto invocation_id = ir.GetAttributeU32(IR::Attribute::InvocationId); + for (u32 attr_no = 0; attr_no < num_attributes; attr_no++) { + for (u32 comp = 0; comp < 4; comp++) { + IR::F32 attr_read = + ir.GetTessGenericAttribute(invocation_id, ir.Imm32(attr_no), ir.Imm32(comp)); + // InvocationId is implicit index for output control point writes + ir.SetTcsGenericAttribute(attr_read, ir.Imm32(attr_no), ir.Imm32(comp)); + } + } + // We could wrap the rest of the program in an if stmt + // CopyInputAttrsToOutputs(); // psuedocode + // if (InvocationId == 0) { + // PatchConstFunction(); + // } + // But as long as we treat invocation ID as 0 for all threads, shouldn't matter functionally + } +} + +void DomainShaderTransform(const IR::Program& program, const RuntimeInfo& runtime_info) { + const Info& info = program.info; + + for (IR::Block* block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + const auto opcode = inst.GetOpcode(); + switch (inst.GetOpcode()) { + case IR::Opcode::LoadSharedU32: + case IR::Opcode::LoadSharedU64: { + const IR::U32 addr{inst.Arg(0)}; + AttributeRegion region = GetAttributeRegionKind(&inst, info, runtime_info); + const u32 num_dwords = opcode == IR::Opcode::LoadSharedU32 ? 1 : 2; + const auto GetInput = [&](IR::U32 addr, u32 off_dw) -> IR::F32 { + if (region == AttributeRegion::OutputCP) { + return ReadTessControlPointAttribute( + addr, runtime_info.sw.tcs.hs_output_cp_stride, ir, off_dw, false); + } else { + ASSERT(region == AttributeRegion::PatchConst); + return ir.GetPatch(IR::PatchGeneric((addr.U32() >> 2) + off_dw)); + } + }; + IR::Value attr_read; + if (num_dwords == 1) { + attr_read = ir.BitCast(GetInput(addr, 0)); + } else { + boost::container::static_vector read_components; + for (auto i = 0; i < num_dwords; i++) { + const IR::F32 component = GetInput(addr, i); + read_components.push_back(ir.BitCast(component)); + } + attr_read = ir.PackUint2x32(ir.CompositeConstruct(read_components)); + } + inst.ReplaceUsesWithAndRemove(attr_read); + break; + } + default: + break; + } + } + } +} + +// Run before either hull or domain transform +void TessellationPreprocess(IR::Program& program, RuntimeInfo& runtime_info) { + TessellationDataConstantBuffer tess_constants; + Shader::Info& info = program.info; + // Find the TessellationDataConstantBuffer V# + for (IR::Block* block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + auto found_tess_consts_sharp = [&]() -> bool { + switch (inst.GetOpcode()) { + case IR::Opcode::LoadSharedU32: + case IR::Opcode::LoadSharedU64: + case IR::Opcode::WriteSharedU32: + case IR::Opcode::WriteSharedU64: { + IR::Value addr = inst.Arg(0); + auto read_const_buffer = IR::BreadthFirstSearch( + addr, [](IR::Inst* maybe_tess_const) -> std::optional { + if (maybe_tess_const->GetOpcode() == IR::Opcode::ReadConstBuffer) { + return maybe_tess_const; + } + return std::nullopt; + }); + if (read_const_buffer) { + auto sharp_location = FindTessConstantSharp(read_const_buffer.value()); + if (sharp_location) { + if (info.tess_consts_dword_offset >= 0) { + // Its possible theres a readconstbuffer that contributes to an + // LDS address and isnt a TessConstant V# read. Could improve on + // this somehow + ASSERT_MSG(static_cast(sharp_location->dword_off) == + info.tess_consts_dword_offset && + sharp_location->ptr_base == + info.tess_consts_ptr_base, + "TessConstants V# is ambiguous"); + } + InitTessConstants(sharp_location->ptr_base, + static_cast(sharp_location->dword_off), info, + runtime_info, tess_constants); + return true; + } + UNREACHABLE_MSG("Failed to match tess constant sharp"); + } + return false; + } + default: + return false; + } + }(); + + if (found_tess_consts_sharp) { + break; + } + } + } + + ASSERT(info.tess_consts_dword_offset >= 0); + + TessConstantUseWalker walker; + + for (IR::Block* block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (inst.GetOpcode() == IR::Opcode::ReadConstBuffer) { + auto sharp_location = FindTessConstantSharp(&inst); + if (sharp_location && sharp_location->ptr_base == info.tess_consts_ptr_base && + sharp_location->dword_off == info.tess_consts_dword_offset) { + // The shader is reading from the TessConstants V# + IR::Value index = inst.Arg(1); + + ASSERT_MSG(index.IsImmediate(), + "Tessellation constant read with dynamic index"); + u32 off_dw = index.U32(); + ASSERT(off_dw <= + static_cast(TessConstantAttribute::FirstEdgeTessFactorIndex)); + + auto tess_const_attr = static_cast(off_dw); + switch (tess_const_attr) { + case TessConstantAttribute::LsStride: + // If not, we may need to make this runtime state for TES + ASSERT(info.sw_stage == SwStage::TessellationControl); + inst.ReplaceUsesWithAndRemove(IR::Value(tess_constants.ls_stride)); + break; + case TessConstantAttribute::HsCpStride: + inst.ReplaceUsesWithAndRemove(IR::Value(tess_constants.hs_cp_stride)); + break; + case TessConstantAttribute::HsNumPatch: + case TessConstantAttribute::HsOutputBase: + case TessConstantAttribute::PatchConstBase: + walker.WalkUsersOfTessConstant(&inst, tess_const_attr); + // We should be able to safely set these to 0 so that indexing happens only + // within the local patch in the recompiled Vulkan shader. This assumes + // these values only contribute to address calculations for in/out + // attributes in the original gcn shader. + // See the explanation for why we set V2 to 0 when emitting the prologue. + inst.ReplaceUsesWithAndRemove(IR::Value(0u)); + break; + case Shader::TessConstantAttribute::PatchConstSize: + case Shader::TessConstantAttribute::PatchOutputSize: + case Shader::TessConstantAttribute::OffChipTessellationFactorThreshold: + case Shader::TessConstantAttribute::FirstEdgeTessFactorIndex: + // May need to replace PatchConstSize and PatchOutputSize with 0 + break; + default: + UNREACHABLE_MSG("Read past end of TessConstantsBuffer"); + } + } + } + } + } + + // These pattern matching are neccessary for now unless we support dynamic indexing of + // PatchConst attributes and tess factors. PatchConst should be easy, turn those into a single + // vec4 array like in/out attrs. Not sure about tess factors. + if (info.sw_stage == SwStage::TessellationControl) { + // Replace the BFEs on V1 (packed with patch id within VGT and output cp id) + for (IR::Block* block : program.blocks) { + for (auto it = block->Instructions().begin(); it != block->Instructions().end(); it++) { + IR::Inst& inst = *it; + if (M_BITFIELDUEXTRACT( + M_GETATTRIBUTEU32(MatchAttribute(IR::Attribute::PackedHullInvocationInfo), + MatchIgnore()), + MatchU32(0), MatchU32(8)) + .Match(IR::Value{&inst})) { + IR::IREmitter emit(*block, it); + // This is the patch id within the VGT, not the actual PrimitiveId + // in the draw + IR::Value replacement(0u); + inst.ReplaceUsesWithAndRemove(replacement); + } else if (M_BITFIELDUEXTRACT( + M_GETATTRIBUTEU32( + MatchAttribute(IR::Attribute::PackedHullInvocationInfo), + MatchIgnore()), + MatchU32(8), MatchU32(5)) + .Match(IR::Value{&inst})) { + IR::IREmitter ir(*block, it); + IR::Value replacement; + if (runtime_info.sw.tcs.IsPassthrough()) { + // Deal with annoying pattern in BB where InvocationID use makes no + // sense (in addr calculation for patchconst or tess factor write) + replacement = ir.Imm32(0); + } else { + replacement = ir.GetAttributeU32(IR::Attribute::InvocationId); + } + inst.ReplaceUsesWithAndRemove(replacement); + } + } + } + } + + ConstantPropagationPass(program.post_order_blocks); +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/inject_clip_distance_attributes.cpp b/gpu/shadps4/shader_recompiler/ir/passes/inject_clip_distance_attributes.cpp new file mode 100644 index 0000000..08fa8b6 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/inject_clip_distance_attributes.cpp @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader { + +void InjectClipDistanceAttributes(IR::Program& program, RuntimeInfo& runtime_info) { + auto& info = runtime_info.hw.fs; + + if (!info.clip_distance_emulation || program.info.sw_stage != SwStage::Fragment) { + return; + } + + auto* first_block = *program.blocks.begin(); + auto it = std::ranges::find_if(first_block->Instructions(), [](const IR::Inst& inst) { + return inst.GetOpcode() == IR::Opcode::Prologue; + }); + ASSERT(it != first_block->end()); + ++it; + ASSERT(it != first_block->end()); + ++it; + + IR::IREmitter ir{*first_block, it}; + + // We don't know how many clip distances are exported by VS as it is not processed at this point + // yet. Here is an assumption that we will have not more than 4 of them (while max is 8) to save + // one attributes export slot. + const auto attrib = IR::Attribute::Param0 + info.num_inputs; + for (u32 comp = 0; comp < MaxEmulatedClipDistances; ++comp) { + const auto attr_read = ir.GetAttribute(attrib, comp); + const auto cond_id = ir.FPLessThan(attr_read, ir.Imm32(0.0f)); + ir.Discard(cond_id); + } + ++info.num_inputs; +} + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/ir/passes/inverse_ballot_elimination_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/inverse_ballot_elimination_pass.cpp new file mode 100644 index 0000000..dbf0881 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/inverse_ballot_elimination_pass.cpp @@ -0,0 +1,174 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/passes/expression_elimination.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader::Optimization { + +static void FoldCompositeConstruct(IR::Inst& inst, IR::Opcode extract) { + IR::Value result{}; + for (size_t i = 0; i < inst.NumArgs(); ++i) { + const IR::Value value{inst.Arg(i)}; + if (value.IsImmediate()) { + return; + } + IR::Inst* const inst = value.Inst(); + if (inst->GetOpcode() != extract || inst->Arg(1).U32() != i) { + return; + } + + if (result.IsEmpty()) { + result = inst->Arg(0); + } else if (result != inst->Arg(0)) { + return; + } + } + inst.ReplaceUsesWithAndRemove(result); +} + +static void FoldInverseFunc(IR::Inst& inst, IR::Opcode reverse) { + const IR::Value value{inst.Arg(0)}; + if (value.IsImmediate()) { + return; + } + IR::Inst* const arg_inst{value.Inst()}; + if (arg_inst->GetOpcode() == reverse) { + inst.ReplaceUsesWithAndRemove(arg_inst->Arg(0)); + return; + } +} + +static void TrySimplifyInst(IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::PackUint2x32: + return FoldInverseFunc(inst, IR::Opcode::UnpackUint2x32); + case IR::Opcode::CompositeConstructU32x2: + return FoldCompositeConstruct(inst, IR::Opcode::CompositeExtractU32x2); + case IR::Opcode::CompositeConstructU32x3: + return FoldCompositeConstruct(inst, IR::Opcode::CompositeExtractU32x3); + case IR::Opcode::CompositeConstructU32x4: + return FoldCompositeConstruct(inst, IR::Opcode::CompositeExtractU32x4); + default: + break; + } +} + +void InverseBallotEliminationPass(IR::Program& program) { + std::vector worklist; + for (IR::Block* const block : program.blocks) { + RunLocalCSE(block); + for (IR::Inst& inst : block->Instructions()) { + TrySimplifyInst(inst); + if (inst.GetOpcode() != IR::Opcode::InverseBallot) { + continue; + } + worklist.push_back(&inst); + } + } + std::unordered_map inst_map; + while (!worklist.empty()) { + IR::Inst* const inst = worklist.back(); + worklist.pop_back(); + + if (inst->GetOpcode() == IR::Opcode::Void) { + continue; + } + + IR::Value value{inst->Arg(0)}; + if (value.IsImmediate()) { + if (value.U64() == 0ull) { + inst->ReplaceUsesWithAndRemove(IR::Value{false}); + } else if (value.U64() == std::numeric_limits::max()) { + inst->ReplaceUsesWithAndRemove(IR::Value{true}); + } else { + UNREACHABLE_MSG("Unexpected immediate argument for InverseBallot {:#x}", + value.U64()); + } + continue; + } + + IR::Inst* const prod = value.Inst(); + if (prod->GetOpcode() == IR::Opcode::Ballot) { + inst->ReplaceUsesWithAndRemove(prod->Arg(0)); + continue; + } + + IR::Block* const block = prod->GetParent(); + if (prod->GetOpcode() == IR::Opcode::UndefU64) { + auto insert_point = IR::Block::InstructionList::s_iterator_to(*prod); + IR::Value const undef{&*block->PrependNewInst(insert_point, IR::Opcode::UndefU1)}; + inst->ReplaceUsesWithAndRemove(undef); + continue; + } + + if (prod->GetOpcode() != IR::Opcode::BitwiseAnd64 && + prod->GetOpcode() != IR::Opcode::BitwiseNot64 && + prod->GetOpcode() != IR::Opcode::BitwiseOr64 && + prod->GetOpcode() != IR::Opcode::BitwiseXor64 && + prod->GetOpcode() != IR::Opcode::SelectU64 && prod->GetOpcode() != IR::Opcode::Phi) { + continue; + } + + auto [it, is_new] = inst_map.try_emplace(prod); + if (is_new) { + auto insert_point = IR::Block::InstructionList::s_iterator_to(*prod); + IR::IREmitter ir{*block, insert_point}; + + if (prod->GetOpcode() == IR::Opcode::Phi) { + IR::Inst* const new_phi{&*block->PrependNewInst(insert_point, IR::Opcode::Phi)}; + new_phi->SetFlags(IR::Type::U1); + for (size_t arg_index = 0; arg_index < prod->NumArgs(); ++arg_index) { + IR::Block* const phi_block = prod->PhiBlock(arg_index); + IR::IREmitter ir{*phi_block}; + const IR::U1 new_arg = ir.InverseBallot(IR::U64{prod->Arg(arg_index)}); + worklist.push_back(new_arg.Inst()); + new_phi->AddPhiOperand(phi_block, new_arg); + } + it->second = IR::Value{new_phi}; + } else if (prod->GetOpcode() == IR::Opcode::SelectU64) { + const IR::U1 a = ir.InverseBallot(IR::U64{prod->Arg(1)}); + worklist.push_back(a.Inst()); + const IR::U1 b = ir.InverseBallot(IR::U64{prod->Arg(2)}); + worklist.push_back(b.Inst()); + it->second = ir.Select(IR::U1{prod->Arg(0)}, a, b); + } else { + const IR::U1 a = ir.InverseBallot(IR::U64{prod->Arg(0)}); + worklist.push_back(a.Inst()); + + if (prod->GetOpcode() == IR::Opcode::BitwiseNot64) { + it->second = ir.LogicalNot(a); + } else { + const IR::U1 b = ir.InverseBallot(IR::U64{prod->Arg(1)}); + worklist.push_back(b.Inst()); + switch (prod->GetOpcode()) { + case IR::Opcode::BitwiseAnd64: + it->second = ir.LogicalAnd(a, b); + break; + case IR::Opcode::BitwiseOr64: + it->second = ir.LogicalOr(a, b); + break; + case IR::Opcode::BitwiseXor64: + it->second = ir.LogicalXor(a, b); + break; + default: + break; + } + } + } + } + + auto uses = prod->Uses(); + for (auto [user, operand] : uses) { + if (user->GetOpcode() == IR::Opcode::InverseBallot) { + user->ReplaceUsesWithAndRemove(it->second); + } + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/ir_passes.h b/gpu/shadps4/shader_recompiler/ir/passes/ir_passes.h new file mode 100644 index 0000000..af41394 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/ir_passes.h @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/passes/resource_pass.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader { +struct Profile; +void InjectClipDistanceAttributes(IR::Program& program, RuntimeInfo& runtime_info); +} // namespace Shader + +namespace Shader::Optimization { + +void SsaRewritePass(IR::Program& program); +void SsaRepairPass(IR::Program& program); +void PhiSimplificationPass(IR::Program& program); +void InverseBallotEliminationPass(IR::Program& program); +void LowerWave64BallotPass(IR::Program& program, const RuntimeInfo& runtime_info, + const Profile& profile); +void LowerHardwareIntrinsics(IR::Program& program); +void LowerPhisToRegsPass(IR::Program& program); +void DeadCodeEliminationPass(IR::Program& program); +void ConstantPropagationPass(IR::BlockList& program); +void FlattenExtendedUserdataPass(IR::Program& program); +void ReadLaneEliminationPass(IR::Program& program); +ResourceDiscoveryList ResourceDiscoverPass(IR::Program& program, const Profile& profile); +void ResourcePatchingPass(Shader::Info& info, const ResourceDiscoveryList& sharp_usages, + const Profile& profile); +void CollectShaderInfoPass(IR::Program& program, const Profile& profile); +void LowerBufferFormatToRaw(IR::Program& program); +void LowerUserClipPlanes(IR::Program& program, const RuntimeInfo& runtime_info); +void LowerFp64ToFp32(IR::Program& program); +void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info); +void TessellationPreprocess(IR::Program& program, RuntimeInfo& runtime_info); +void HullShaderTransform(IR::Program& program, const RuntimeInfo& runtime_info); +void DomainShaderTransform(const IR::Program& program, const RuntimeInfo& runtime_info); +void SharedMemoryBarrierPass(IR::Program& program, const RuntimeInfo& runtime_info, + const Profile& profile); +void SharedMemorySimplifyPass(IR::Program& program, const Profile& profile); +void SharedMemoryToStoragePass(IR::Program& program, const RuntimeInfo& runtime_info, + const Profile& profile); + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/lower_buffer_format_to_raw.cpp b/gpu/shadps4/shader_recompiler/ir/passes/lower_buffer_format_to_raw.cpp new file mode 100644 index 0000000..c430b9a --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/lower_buffer_format_to_raw.cpp @@ -0,0 +1,247 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/reinterpret.h" +#include "video_core/amdgpu/resource.h" + +namespace Shader::Optimization { + +struct FormatInfo { + AmdGpu::DataFormat data_format; + AmdGpu::NumberFormat num_format; + AmdGpu::CompMapping swizzle; + AmdGpu::NumberConversion num_conversion; + u32 num_components; +}; + +static bool IsBufferFormatLoad(const IR::Inst& inst) { + return inst.GetOpcode() == IR::Opcode::LoadBufferFormatF32; +} + +static bool IsBufferFormatStore(const IR::Inst& inst) { + return inst.GetOpcode() == IR::Opcode::StoreBufferFormatF32; +} + +static IR::Value LoadBufferFormat(IR::IREmitter& ir, const IR::Value handle, const IR::U32 address, + const IR::BufferInstInfo info, const FormatInfo& format_info) { + IR::Value interpreted; + switch (format_info.data_format) { + case AmdGpu::DataFormat::FormatInvalid: + interpreted = ir.Imm32(0.f); + break; + case AmdGpu::DataFormat::Format8: { + const auto raw = ir.UConvert(32, ir.LoadBufferU8(handle, address, info)); + const auto unpacked = ir.Unpack4x8(format_info.num_format, raw); + interpreted = ir.CompositeExtract(unpacked, 0); + break; + } + case AmdGpu::DataFormat::Format8_8: { + const auto raw = ir.UConvert(32, ir.LoadBufferU16(handle, address, info)); + const auto unpacked = ir.Unpack4x8(format_info.num_format, raw); + interpreted = ir.CompositeConstruct(ir.CompositeExtract(unpacked, 0), + ir.CompositeExtract(unpacked, 1)); + break; + } + case AmdGpu::DataFormat::Format8_8_8_8: + interpreted = ir.Unpack4x8(format_info.num_format, + IR::U32{ir.LoadBufferU32(1, handle, address, info)}); + break; + case AmdGpu::DataFormat::Format16: { + const auto raw = ir.UConvert(32, ir.LoadBufferU16(handle, address, info)); + const auto unpacked = ir.Unpack2x16(format_info.num_format, raw); + interpreted = ir.CompositeExtract(unpacked, 0); + break; + } + case AmdGpu::DataFormat::Format16_16: + interpreted = ir.Unpack2x16(format_info.num_format, + IR::U32{ir.LoadBufferU32(1, handle, address, info)}); + break; + case AmdGpu::DataFormat::Format10_11_11: + interpreted = ir.Unpack10_11_11(format_info.num_format, + IR::U32{ir.LoadBufferU32(1, handle, address, info)}); + break; + case AmdGpu::DataFormat::Format2_10_10_10: + interpreted = ir.Unpack2_10_10_10(format_info.num_format, + IR::U32{ir.LoadBufferU32(1, handle, address, info)}); + break; + case AmdGpu::DataFormat::Format16_16_16_16: { + const auto raw = ir.LoadBufferU32(2, handle, address, info); + interpreted = ir.CompositeConstruct( + ir.Unpack2x16(format_info.num_format, IR::U32{ir.CompositeExtract(raw, 0)}), + ir.Unpack2x16(format_info.num_format, IR::U32{ir.CompositeExtract(raw, 1)})); + break; + } + case AmdGpu::DataFormat::Format32: + case AmdGpu::DataFormat::Format32_32: + case AmdGpu::DataFormat::Format32_32_32: + case AmdGpu::DataFormat::Format32_32_32_32: { + ASSERT(format_info.num_format == AmdGpu::NumberFormat::Uint || + format_info.num_format == AmdGpu::NumberFormat::Sint || + format_info.num_format == AmdGpu::NumberFormat::Float); + interpreted = ir.LoadBufferF32(format_info.num_components, handle, address, info); + break; + } + default: + UNREACHABLE_MSG("Unsupported buffer data format: {}", format_info.data_format); + } + + // Pad to 4 components and apply additional modifications. + boost::container::static_vector components; + for (u32 i = 0; i < 4; i++) { + if (i < format_info.num_components) { + const auto component = + IR::F32{format_info.num_components == 1 ? interpreted + : ir.CompositeExtract(interpreted, i)}; + components.push_back( + ApplyReadNumberConversion(ir, component, format_info.num_conversion)); + } else { + components.push_back(ir.Imm32(0.f)); + } + } + const auto swizzled = ApplySwizzle(ir, ir.CompositeConstruct(components), format_info.swizzle); + return swizzled; +} + +static void StoreBufferFormat(IR::IREmitter& ir, const IR::Value handle, const IR::U32 address, + const IR::Value& value, const IR::BufferInstInfo info, + const FormatInfo& format_info) { + // Extract actual number of components and apply additional modifications. + const auto swizzled = ApplySwizzle(ir, value, format_info.swizzle.Inverse()); + boost::container::static_vector components; + for (u32 i = 0; i < format_info.num_components; i++) { + const auto component = IR::F32{ir.CompositeExtract(swizzled, i)}; + components.push_back(ApplyWriteNumberConversion(ir, component, format_info.num_conversion)); + } + const auto real_value = + components.size() == 1 ? components[0] : ir.CompositeConstruct(components); + + switch (format_info.data_format) { + case AmdGpu::DataFormat::FormatInvalid: + break; + case AmdGpu::DataFormat::Format8: { + const auto packed = + ir.Pack4x8(format_info.num_format, ir.CompositeConstruct(real_value, ir.Imm32(0.f), + ir.Imm32(0.f), ir.Imm32(0.f))); + ir.StoreBufferU8(handle, address, ir.UConvert(8, packed), info); + break; + } + case AmdGpu::DataFormat::Format8_8: { + const auto packed = ir.Pack4x8(format_info.num_format, + ir.CompositeConstruct(ir.CompositeExtract(real_value, 0), + ir.CompositeExtract(real_value, 1), + ir.Imm32(0.f), ir.Imm32(0.f))); + ir.StoreBufferU16(handle, address, ir.UConvert(16, packed), info); + break; + } + case AmdGpu::DataFormat::Format8_8_8_8: { + auto packed = ir.Pack4x8(format_info.num_format, real_value); + ir.StoreBufferU32(1, handle, address, packed, info); + break; + } + case AmdGpu::DataFormat::Format16: { + const auto packed = + ir.Pack2x16(format_info.num_format, ir.CompositeConstruct(real_value, ir.Imm32(0.f))); + ir.StoreBufferU16(handle, address, ir.UConvert(16, packed), info); + break; + } + case AmdGpu::DataFormat::Format16_16: { + const auto packed = ir.Pack2x16(format_info.num_format, real_value); + ir.StoreBufferU32(1, handle, address, packed, info); + break; + } + case AmdGpu::DataFormat::Format10_11_11: { + const auto packed = ir.Pack10_11_11(format_info.num_format, real_value); + ir.StoreBufferU32(1, handle, address, packed, info); + break; + } + case AmdGpu::DataFormat::Format2_10_10_10: { + const auto packed = ir.Pack2_10_10_10(format_info.num_format, real_value); + ir.StoreBufferU32(1, handle, address, packed, info); + break; + } + case AmdGpu::DataFormat::Format16_16_16_16: { + const auto packed = ir.CompositeConstruct( + ir.Pack2x16(format_info.num_format, + ir.CompositeConstruct(ir.CompositeExtract(real_value, 0), + ir.CompositeExtract(real_value, 1))), + ir.Pack2x16(format_info.num_format, + ir.CompositeConstruct(ir.CompositeExtract(real_value, 2), + ir.CompositeExtract(real_value, 3)))); + ir.StoreBufferU32(2, handle, address, packed, info); + break; + } + case AmdGpu::DataFormat::Format32: + case AmdGpu::DataFormat::Format32_32: + case AmdGpu::DataFormat::Format32_32_32: + case AmdGpu::DataFormat::Format32_32_32_32: { + ASSERT(format_info.num_format == AmdGpu::NumberFormat::Uint || + format_info.num_format == AmdGpu::NumberFormat::Sint || + format_info.num_format == AmdGpu::NumberFormat::Float); + ir.StoreBufferF32(format_info.num_components, handle, address, real_value, info); + break; + } + default: + UNREACHABLE_MSG("Unsupported buffer data format: {}", format_info.data_format); + } +} + +static void LowerBufferFormatInst(IR::Block& block, IR::Inst& inst, Info& info) { + IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; + const auto flags = inst.Flags(); + const auto desc{info.buffers[inst.Arg(0).U32()]}; + const auto buffer{desc.GetSharp(info)}; + + const auto is_inst_typed = flags.inst_data_fmt != AmdGpu::DataFormat::FormatInvalid; + const auto data_format = + is_inst_typed ? AmdGpu::RemapDataFormat(flags.inst_data_fmt.Value()) : buffer.GetDataFmt(); + const auto format_info = FormatInfo{ + .data_format = data_format, + .num_format = is_inst_typed + ? AmdGpu::RemapNumberFormat(flags.inst_num_fmt.Value(), data_format) + : buffer.GetNumberFmt(), + .swizzle = is_inst_typed + ? AmdGpu::RemapSwizzle(flags.inst_data_fmt.Value(), AmdGpu::IdentityMapping) + : buffer.DstSelect(), + .num_conversion = is_inst_typed ? AmdGpu::MapNumberConversion(flags.inst_num_fmt.Value(), + flags.inst_data_fmt.Value()) + : buffer.GetNumberConversion(), + .num_components = AmdGpu::NumComponents(data_format), + }; + + if (data_format == AmdGpu::DataFormat::FormatInvalid) { + LOG_WARNING(Render_Recompiler, "Skipping lowering for null buffer sharp"); + if (IsBufferFormatLoad(inst)) { + inst.ReplaceUsesWithAndRemove( + ir.CompositeConstruct(ir.Imm32(0.f), ir.Imm32(0.f), ir.Imm32(0.f), ir.Imm32(0.f))); + } else { + inst.Invalidate(); + } + return; + } + + if (IsBufferFormatLoad(inst)) { + const auto interpreted = + LoadBufferFormat(ir, inst.Arg(0), IR::U32{inst.Arg(1)}, flags, format_info); + inst.ReplaceUsesWithAndRemove(interpreted); + } else if (IsBufferFormatStore(inst)) { + StoreBufferFormat(ir, inst.Arg(0), IR::U32{inst.Arg(1)}, inst.Arg(2), flags, format_info); + inst.Invalidate(); + } +} + +void LowerBufferFormatToRaw(IR::Program& program) { + auto& info = program.info; + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (IsBufferFormatLoad(inst) || IsBufferFormatStore(inst)) { + LowerBufferFormatInst(*block, inst, info); + } + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/lower_fp64_to_fp32.cpp b/gpu/shadps4/shader_recompiler/ir/passes/lower_fp64_to_fp32.cpp new file mode 100644 index 0000000..f65f810 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/lower_fp64_to_fp32.cpp @@ -0,0 +1,162 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader::Optimization { + +constexpr s32 F64ToF32Exp = +1023 - 127; +constexpr s32 F32ToF64Exp = +127 - 1023; + +static IR::F32 PackedF64ToF32(IR::IREmitter& ir, const IR::Value& packed) { + const IR::U32 lo{ir.CompositeExtract(packed, 0)}; + const IR::U32 hi{ir.CompositeExtract(packed, 1)}; + const IR::U32 sign{ir.BitFieldExtract(hi, ir.Imm32(31), ir.Imm32(1))}; + const IR::U32 exp{ir.BitFieldExtract(hi, ir.Imm32(20), ir.Imm32(11))}; + const IR::U32 mantissa_hi{ir.BitFieldExtract(hi, ir.Imm32(0), ir.Imm32(20))}; + const IR::U32 mantissa_lo{ir.BitFieldExtract(lo, ir.Imm32(29), ir.Imm32(3))}; + const IR::U32 mantissa{ + ir.BitwiseOr(ir.ShiftLeftLogical(mantissa_hi, ir.Imm32(3)), mantissa_lo)}; + const IR::U32 exp_if_subnorm{ + ir.Select(ir.IEqual(exp, ir.Imm32(0)), ir.Imm32(0), ir.IAdd(exp, ir.Imm32(F64ToF32Exp)))}; + const IR::U32 exp_if_infnan{ + ir.Select(ir.IEqual(exp, ir.Imm32(0x7ff)), ir.Imm32(0xff), exp_if_subnorm)}; + const IR::U32 result{ + ir.BitwiseOr(ir.ShiftLeftLogical(sign, ir.Imm32(31)), + ir.BitwiseOr(ir.ShiftLeftLogical(exp_if_infnan, ir.Imm32(23)), mantissa))}; + return ir.BitCast(result); +} + +IR::Value F32ToPackedF64(IR::IREmitter& ir, const IR::Value& raw) { + const IR::U32 value{ir.BitCast(IR::F32(raw))}; + const IR::U32 sign{ir.BitFieldExtract(value, ir.Imm32(31), ir.Imm32(1))}; + const IR::U32 exp{ir.BitFieldExtract(value, ir.Imm32(23), ir.Imm32(8))}; + const IR::U32 mantissa{ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(23))}; + const IR::U32 mantissa_hi{ir.BitFieldExtract(mantissa, ir.Imm32(3), ir.Imm32(20))}; + const IR::U32 mantissa_lo{ir.BitFieldExtract(mantissa, ir.Imm32(0), ir.Imm32(3))}; + const IR::U32 exp_if_subnorm{ + ir.Select(ir.IEqual(exp, ir.Imm32(0)), ir.Imm32(0), ir.IAdd(exp, ir.Imm32(F32ToF64Exp)))}; + const IR::U32 exp_if_infnan{ + ir.Select(ir.IEqual(exp, ir.Imm32(0xff)), ir.Imm32(0x7ff), exp_if_subnorm)}; + const IR::U32 lo{ir.ShiftLeftLogical(mantissa_lo, ir.Imm32(29))}; + const IR::U32 hi{ + ir.BitwiseOr(ir.ShiftLeftLogical(sign, ir.Imm32(31)), + ir.BitwiseOr(ir.ShiftLeftLogical(exp_if_infnan, ir.Imm32(20)), mantissa_hi))}; + return ir.CompositeConstruct(lo, hi); +} + +static IR::Opcode Replace(IR::Opcode op) { + switch (op) { + case IR::Opcode::FPAbs64: + return IR::Opcode::FPAbs32; + case IR::Opcode::FPAdd64: + return IR::Opcode::FPAdd32; + case IR::Opcode::FPFma64: + return IR::Opcode::FPFma32; + case IR::Opcode::FPMax64: + return IR::Opcode::FPMax32; + case IR::Opcode::FPMin64: + return IR::Opcode::FPMin32; + case IR::Opcode::FPMul64: + return IR::Opcode::FPMul32; + case IR::Opcode::FPDiv64: + return IR::Opcode::FPDiv32; + case IR::Opcode::FPNeg64: + return IR::Opcode::FPNeg32; + case IR::Opcode::FPRecip64: + return IR::Opcode::FPRecip32; + case IR::Opcode::FPRecipSqrt64: + return IR::Opcode::FPRecipSqrt32; + case IR::Opcode::FPSaturate64: + return IR::Opcode::FPSaturate32; + case IR::Opcode::FPClamp64: + return IR::Opcode::FPClamp32; + case IR::Opcode::FPRoundEven64: + return IR::Opcode::FPRoundEven32; + case IR::Opcode::FPFloor64: + return IR::Opcode::FPFloor32; + case IR::Opcode::FPCeil64: + return IR::Opcode::FPCeil32; + case IR::Opcode::FPTrunc64: + return IR::Opcode::FPTrunc32; + case IR::Opcode::FPFract64: + return IR::Opcode::FPFract32; + case IR::Opcode::FPFrexpSig64: + return IR::Opcode::FPFrexpSig32; + case IR::Opcode::FPFrexpExp64: + return IR::Opcode::FPFrexpExp32; + case IR::Opcode::FPOrdEqual64: + return IR::Opcode::FPOrdEqual32; + case IR::Opcode::FPUnordEqual64: + return IR::Opcode::FPUnordEqual32; + case IR::Opcode::FPOrdNotEqual64: + return IR::Opcode::FPOrdNotEqual32; + case IR::Opcode::FPUnordNotEqual64: + return IR::Opcode::FPUnordNotEqual32; + case IR::Opcode::FPOrdLessThan64: + return IR::Opcode::FPOrdLessThan32; + case IR::Opcode::FPUnordLessThan64: + return IR::Opcode::FPUnordLessThan32; + case IR::Opcode::FPOrdGreaterThan64: + return IR::Opcode::FPOrdGreaterThan32; + case IR::Opcode::FPUnordGreaterThan64: + return IR::Opcode::FPUnordGreaterThan32; + case IR::Opcode::FPOrdLessThanEqual64: + return IR::Opcode::FPOrdLessThanEqual32; + case IR::Opcode::FPUnordLessThanEqual64: + return IR::Opcode::FPUnordLessThanEqual32; + case IR::Opcode::FPOrdGreaterThanEqual64: + return IR::Opcode::FPOrdGreaterThanEqual32; + case IR::Opcode::FPUnordGreaterThanEqual64: + return IR::Opcode::FPUnordGreaterThanEqual32; + case IR::Opcode::FPIsNan64: + return IR::Opcode::FPIsNan32; + case IR::Opcode::FPIsInf64: + return IR::Opcode::FPIsInf32; + case IR::Opcode::ConvertS32F64: + return IR::Opcode::ConvertS32F32; + case IR::Opcode::ConvertF64S32: + return IR::Opcode::ConvertF32S32; + case IR::Opcode::ConvertF64U32: + return IR::Opcode::ConvertF32U32; + default: + return op; + } +} + +static void Lower(IR::Block& block, IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::PackDouble2x32: { + IR::IREmitter ir(block, IR::Block::InstructionList::s_iterator_to(inst)); + inst.ReplaceUsesWithAndRemove(PackedF64ToF32(ir, inst.Arg(0))); + break; + } + case IR::Opcode::UnpackDouble2x32: { + IR::IREmitter ir(block, IR::Block::InstructionList::s_iterator_to(inst)); + inst.ReplaceUsesWithAndRemove(F32ToPackedF64(ir, inst.Arg(0))); + break; + } + case IR::Opcode::ConvertF64F32: + case IR::Opcode::ConvertF32F64: { + IR::IREmitter ir(block, IR::Block::InstructionList::s_iterator_to(inst)); + inst.ReplaceUsesWithAndRemove(inst.Arg(0)); + break; + } + default: + inst.ReplaceOpcode(Replace(inst.GetOpcode())); + break; + } +} + +void LowerFp64ToFp32(IR::Program& program) { + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + Lower(*block, inst); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/lower_hardware_intrinsics.cpp b/gpu/shadps4/shader_recompiler/ir/passes/lower_hardware_intrinsics.cpp new file mode 100644 index 0000000..c359035 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/lower_hardware_intrinsics.cpp @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader::Optimization { + +static void LowerCmpClass(IR::Block& block, IR::Inst& inst) { + ASSERT_MSG(inst.Arg(1).IsImmediate(), "Unable to resolve compare operation"); + const auto class_mask = static_cast(inst.Arg(1).U32()); + if ((class_mask & IR::FloatClassFunc::NaN) == IR::FloatClassFunc::NaN) { + inst.ReplaceOpcode(IR::Opcode::FPIsNan32); + } else if ((class_mask & IR::FloatClassFunc::Infinity) == IR::FloatClassFunc::Infinity) { + inst.ReplaceOpcode(IR::Opcode::FPIsInf32); + } else if ((class_mask & IR::FloatClassFunc::Finite) == IR::FloatClassFunc::Finite) { + IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; + const IR::F32 value = IR::F32{inst.Arg(0)}; + inst.ReplaceUsesWithAndRemove( + ir.LogicalNot(ir.LogicalOr(ir.FPIsNan(value), ir.FPIsInf(value)))); + } else { + UNREACHABLE(); + } +} + +static void LowerPackedAncillary(IR::Block& block, IR::Inst& inst) { + if (inst.Arg(0).IsImmediate() || !inst.Arg(1).IsImmediate() || !inst.Arg(2).IsImmediate()) { + return; + } + IR::Inst* value = inst.Arg(0).Inst(); + if (value->GetOpcode() != IR::Opcode::GetAttributeU32 || + value->Arg(0).Attribute() != IR::Attribute::PackedAncillary) { + return; + } + const u32 offset = inst.Arg(1).U32(); + const u32 bits = inst.Arg(2).U32(); + IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; + if (offset >= 8 && offset + bits <= 12) { + const auto sample_index = ir.GetAttributeU32(IR::Attribute::SampleIndex); + if (offset == 8 && bits == 4) { + inst.ReplaceUsesWithAndRemove(sample_index); + } else { + inst.ReplaceUsesWithAndRemove( + ir.BitFieldExtract(sample_index, ir.Imm32(offset - 8), ir.Imm32(bits))); + } + } else if (offset >= 16 && offset + bits <= 27) { + const auto mrt_index = ir.GetAttributeU32(IR::Attribute::RenderTargetIndex); + if (offset == 16 && bits == 11) { + inst.ReplaceUsesWithAndRemove(mrt_index); + } else { + inst.ReplaceUsesWithAndRemove( + ir.BitFieldExtract(mrt_index, ir.Imm32(offset - 16), ir.Imm32(bits))); + } + } else { + UNREACHABLE_MSG("Unhandled bitfield extract from ancillary VGPR offset={}, bits={}", offset, + bits); + } + value->ReplaceUsesWithAndRemove(ir.Imm32(0U)); +} + +static void LowerMaskedBitCount(IR::Block& block, IR::Inst& inst) { + IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; + const IR::U32 thread_mask{ + ir.GetAttributeU32(IR::Attribute::SubgroupLtMask, inst.Arg(2).U1() ? 1 : 0)}; + const IR::U32 masked_value{ir.BitCount(ir.BitwiseAnd(IR::U32{inst.Arg(0)}, thread_mask))}; + inst.ReplaceUsesWithAndRemove(ir.IAdd(masked_value, IR::U32{inst.Arg(1)})); +} + +static void Lower(IR::Block& block, IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::FPCmpClass32: + return LowerCmpClass(block, inst); + case IR::Opcode::BitFieldUExtract: + return LowerPackedAncillary(block, inst); + case IR::Opcode::MaskedBitCount32: + return LowerMaskedBitCount(block, inst); + default: + break; + } +} + +void LowerHardwareIntrinsics(IR::Program& program) { + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + Lower(*block, inst); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/lower_phis_to_regs_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/lower_phis_to_regs_pass.cpp new file mode 100644 index 0000000..c310604 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/lower_phis_to_regs_pass.cpp @@ -0,0 +1,65 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::Optimization { + +static IR::Value LoadForRegType(IR::IREmitter& ir, IR::RegTag tag) { + switch (tag.type) { + case IR::RegType::ScalarReg: + return ir.GetScalarReg(tag.sreg); + case IR::RegType::VectorReg: + return ir.GetVectorReg(tag.vreg); + case IR::RegType::Scc: + return ir.GetScc(); + case IR::RegType::Exec: + return ir.GetExec(); + case IR::RegType::VccLo: + return ir.GetVccLo(); + case IR::RegType::VccHi: + return ir.GetVccHi(); + case IR::RegType::M0: + return ir.GetM0(); + case IR::RegType::VirtualReg: + return ir.GetVirtualReg(tag.reg); + default: + UNREACHABLE_MSG("Unknown reg type {}", u32(tag.type)); + } +} + +void LowerPhisToRegsPass(IR::Program& program) { + const auto end = program.post_order_blocks.rend(); + for (auto it1 = program.post_order_blocks.rbegin(); it1 != end; ++it1) { + IR::Block* block{*it1}; + for (auto it = block->begin(); it != block->end(); ++it) { + IR::Inst& inst{*it}; + if (inst.GetOpcode() == IR::Opcode::Void) { + continue; + } + if (inst.GetOpcode() != IR::Opcode::Phi) { + break; + } + + IR::IREmitter ir{*block, it}; + if (const auto tag = inst.GetRegTag()) { + inst.ReplaceUsesWithAndRemove(LoadForRegType(ir, tag)); + continue; + } + + const IR::VirtualReg reg{program.next_reg_index++, inst.Flags()}; + for (size_t arg_index = 0; arg_index < inst.NumArgs(); arg_index++) { + IR::IREmitter ir{*inst.PhiBlock(arg_index)}; + ir.SetVirtualReg(reg, inst.Arg(arg_index)); + } + inst.ReplaceUsesWithAndRemove(ir.GetVirtualReg(reg)); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/lower_user_clip_planes.cpp b/gpu/shadps4/shader_recompiler/ir/passes/lower_user_clip_planes.cpp new file mode 100644 index 0000000..7240293 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/lower_user_clip_planes.cpp @@ -0,0 +1,88 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/logging/log.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader::Optimization { + +static constexpr u32 NumUserClipPlanes = 6; + +// Lowers the fixed-function user clip planes in PA_CL_UCP_*, enabled by the UCP_ENA bits of +// PA_CL_CLIP_CNTL, to clip distances. Planes apply to the post-transform position and change per +// draw, so they are supplied through a per-draw uniform buffer. +void LowerUserClipPlanes(IR::Program& program, const RuntimeInfo& runtime_info) { + Info& info = program.info; + if (info.hw_stage != HwStage::Vertex) { + return; + } + + const u32 binding = static_cast(info.buffers.size()); + info.buffers.push_back(BufferResource{ + .used_types = IR::Type::F32, + .buffer_type = BufferType::ClipPlanes, + }); + + const u32 enabled_mask = runtime_info.hw.vs.user_clip_plane_mask; + if (enabled_mask == 0) { + return; + } + + // GCN clips against user planes and shader-exported distances independently, but both share + // the eight ClipDistance slots here, and the guest's exports own their indices. Lowering is + // skipped for such shaders, which restores the previous behavior of clipping by the exported + // distances alone. + for (u32 i = 0; i < runtime_info.hw.vs.num_outputs; ++i) { + for (const auto output : runtime_info.hw.vs.outputs[i]) { + if (output >= Output::ClipDist0 && output <= Output::ClipDist7) { + LOG_WARNING(Render_Vulkan, + "Skipping user clip plane lowering: shader {:#x} exports its own clip " + "distances", + info.pgm_hash); + return; + } + } + } + + // Clip distances are computed from the final exported position. + std::array position{}; + IR::Block* target_block{}; + IR::Block::iterator target_it{}; + for (IR::Block* const block : program.blocks) { + for (auto inst = block->begin(); inst != block->end(); ++inst) { + if (inst->GetOpcode() != IR::Opcode::SetAttribute || + inst->Arg(0).Attribute() != IR::Attribute::Position0) { + continue; + } + position[inst->Arg(2).U32()] = inst->Arg(1); + target_block = block; + target_it = std::next(inst); + } + } + if (std::ranges::any_of(position, [](const IR::Value& v) { return v.IsEmpty(); })) { + return; + } + + IR::IREmitter ir{*target_block, target_it}; + const IR::U32 handle = ir.Imm32(binding); + for (u32 plane = 0; plane < NumUserClipPlanes; ++plane) { + if (((enabled_mask >> plane) & 1) == 0) { + continue; + } + // Each plane equation is four consecutive dwords, matching the upload in BindBuffers. + const IR::Value equation = ir.LoadBufferF32(4, handle, ir.Imm32(plane * 4), {}); + IR::F32 distance{ir.FPMul(IR::F32{position[0]}, IR::F32{ir.CompositeExtract(equation, 0)})}; + for (u32 comp = 1; comp < 4; ++comp) { + distance = IR::F32{ir.FPFma(IR::F32{position[comp]}, + IR::F32{ir.CompositeExtract(equation, comp)}, distance)}; + } + ir.SetAttribute(IR::Attribute::ClipDistance, distance, plane); + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/lower_wave64_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/lower_wave64_pass.cpp new file mode 100644 index 0000000..6644474 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/lower_wave64_pass.cpp @@ -0,0 +1,176 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/classes.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/breadth_first_search.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Optimization { + +static bool IsDivergentCondition(const IR::U1& condition) { + if (condition.IsImmediate()) { + return false; + } + const IR::Inst* const condition_inst = condition.Inst(); + return IR::BreadthFirstSearch(condition_inst, + [](const IR::Inst* inst) -> std::optional { + switch (inst->GetOpcode()) { + case IR::Opcode::LaneId: + return true; + case IR::Opcode::GetAttributeU32: + if (inst->Arg(0).Attribute() == + IR::Attribute::LocalInvocationId) { + return true; + } + break; + default: + break; + } + return std::nullopt; + }) + .value_or(false); +} + +static std::vector FindUniformBlocks(const IR::Program& program) { + using Type = IR::AbstractSyntaxNode::Type; + + struct ConditionalScope { + const IR::Block* merge; + bool divergent; + }; + + std::vector blocks; + std::vector conditionals; + std::vector loops; + u32 divergence_depth{}; + for (const IR::AbstractSyntaxNode& node : program.syntax_list) { + switch (node.type) { + case Type::If: { + const bool divergent = IsDivergentCondition(node.data.if_node.cond); + conditionals.push_back({node.data.if_node.merge, divergent}); + divergence_depth += static_cast(divergent); + break; + } + case Type::EndIf: + ASSERT(!conditionals.empty() && conditionals.back().merge == node.data.end_if.merge); + divergence_depth -= static_cast(conditionals.back().divergent); + conditionals.pop_back(); + break; + case Type::Loop: + loops.push_back(node.data.loop.merge); + break; + case Type::Repeat: + if (loops.empty() || loops.back() != node.data.repeat.merge) { + return {}; + } + loops.pop_back(); + break; + case Type::Block: + if (divergence_depth == 0 && loops.empty()) { + blocks.push_back(node.data.block); + } + break; + default: + break; + } + } + if (!conditionals.empty() || !loops.empty()) { + return {}; + } + return blocks; +} + +void LowerWave64BallotPass(IR::Program& program, const RuntimeInfo& runtime_info, + const Profile& profile) { + if (program.info.hw_stage != HwStage::Compute || profile.subgroup_size == 64) { + return; + } + + const auto [size_x, size_y, size_z] = runtime_info.hw.cs.workgroup_size; + const u32 num_threads = size_x * size_y * size_z; + if (num_threads <= 32) { + return; + } + + std::vector worklist; + const auto uniform_blocks = FindUniformBlocks(program); + for (IR::Block* block : program.blocks) { + const bool is_uniform = std::ranges::contains(uniform_blocks, block); + const auto push_worklist = [&](IR::Inst& inst) { + if (is_uniform) { + worklist.push_back(&inst); + } else { + LOG_WARNING(Render_Recompiler, "{} instruction in non uniform control flow", + inst.GetOpcode()); + } + }; + for (IR::Inst& inst : block->Instructions()) { + if (inst.GetOpcode() == IR::Opcode::ReadLane && inst.Arg(1).IsImmediate()) { + push_worklist(inst); + } else if (inst.GetOpcode() == IR::Opcode::Ballot) { + const auto is_unpack = [](const IR::Use& use) { + return use.user->GetOpcode() == IR::Opcode::UnpackUint2x32; + }; + if (std::ranges::any_of(inst.Uses(), is_unpack)) { + push_worklist(inst); + } + } else if (inst.GetOpcode() == IR::Opcode::GetAttributeU32 && + inst.Arg(0).Attribute() == IR::Attribute::SubgroupLtMask) { + worklist.push_back(&inst); + } + } + } + if (worklist.empty()) { + return; + } + + const u32 scratch_base = Common::AlignUp(runtime_info.hw.cs.shared_memory_size, sizeof(u64)); + const u32 scratch_size = + (Common::AlignUp(num_threads, 64) / profile.subgroup_size) * sizeof(u32); + program.info.shared_memory_scratch_size = + scratch_base + scratch_size - runtime_info.hw.cs.shared_memory_size; + + for (IR::Inst* inst : worklist) { + LOG_INFO(Render_Recompiler, "Lowering {} instruction for wave64", inst->GetOpcode()); + IR::IREmitter ir{*inst->GetParent(), IR::Block::InstructionList::s_iterator_to(*inst)}; + const IR::U32 invocation_index = ir.GetAttributeU32(IR::Attribute::LocalInvocationIndex); + const IR::U32 subgroup_id = ir.ShiftRightLogical(invocation_index, ir.Imm32(5)); + if (inst->GetOpcode() == IR::Opcode::Ballot) { + const IR::U32 mask_low = + IR::U32{ir.CompositeExtract(ir.UnpackUint2x32(ir.Ballot(IR::U1{inst->Arg(0)})), 0)}; + const IR::U32 offset = + ir.IAdd(ir.Imm32(scratch_base), ir.ShiftLeftLogical(subgroup_id, ir.Imm32(2u))); + ir.WriteShared(32, mask_low, offset); + ir.Barrier(); + const IR::U64 mask = IR::U64{ir.LoadShared(64, false, offset)}; + ir.Barrier(); + inst->ReplaceUsesWithAndRemove(mask); + } else if (inst->GetOpcode() == IR::Opcode::ReadLane) { + const IR::U32 lane32 = ir.BitwiseAnd(IR::U32{inst->Arg(1)}, ir.Imm32(31)); + const IR::U32 half = ir.ShiftRightLogical(IR::U32{inst->Arg(1)}, ir.Imm32(5u)); + const IR::U32 offset = + ir.IAdd(ir.Imm32(scratch_base), ir.ShiftLeftLogical(subgroup_id, ir.Imm32(2u))); + ir.WriteShared(32, ir.ReadLane(IR::U32{inst->Arg(0)}, lane32), offset); + ir.Barrier(); + const IR::U32 value = + IR::U32{ir.LoadShared(32, false, + ir.IAdd(ir.BitwiseAnd(offset, ir.Imm32(~7u)), + ir.ShiftLeftLogical(half, ir.Imm32(2u))))}; + ir.Barrier(); + inst->ReplaceUsesWithAndRemove(value); + } else if (inst->GetOpcode() == IR::Opcode::GetAttributeU32 && + inst->Arg(0).Attribute() == IR::Attribute::SubgroupLtMask) { + const IR::U32 subgroup_invocation_id = ir.BitwiseAnd(invocation_index, ir.Imm32(63)); + const IR::U64 mask = ir.ISub( + ir.ShiftLeftLogical(ir.Imm64(u64{1}), subgroup_invocation_id), ir.Imm64(u64{1})); + inst->ReplaceUsesWithAndRemove( + ir.CompositeExtract(ir.UnpackUint2x32(mask), inst->Arg(1).U32())); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/phi_simplification_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/phi_simplification_pass.cpp new file mode 100644 index 0000000..e620691 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/phi_simplification_pass.cpp @@ -0,0 +1,426 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// The Phi simplfication pass works as follows: +// - Gather all Phi instructions in program and apply Tarjan's algorithm to find SCCs. +// - Queue all SCCs in a worklist and process them in order. +// If all external args have the same unary op move that operation to users. +// - The above transform can make can allow other SCCs to get folded so queue other SCCs, +// that use the def of at least 1 Phi of the processed SCC to worklist. +// - Repeat until the worklist is empty +// - Compute "structural hash" of each SCC and group them into buckets. +// Essentially two SCCs are in same group if they have same number of Phis, in same blocks and +// internal edges are also same. External args are not checked because its checked later. +// - Queue all non trivial groups in a worklist and attempt to dedup SCCs inside each group. +// This is accomplished by doing a full structural and SSA def equality check on external args. +// - Deduping an SCC can allow deduplication in other SCC groups so also queue user SCC groups that +// might be affected + +#include +#include +#include +#include + +#include "common/hash.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/passes/expression_elimination.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/ssa.h" + +namespace Shader::Optimization { + +static bool IsCompositeExtract(IR::Opcode opcode) { + switch (opcode) { + case IR::Opcode::CompositeExtractU32x2: + case IR::Opcode::CompositeExtractU32x3: + case IR::Opcode::CompositeExtractU32x4: + return true; + default: + return false; + } +} + +static bool IsDisallowedOp(IR::Opcode op) { + return op == IR::Opcode::InverseBallot; +} + +using InstList = boost::container::small_vector; + +struct CommonOp { + IR::Opcode op{IR::Opcode::Void}; + u32 extract_comp{}; +}; + +struct PhiScc { + bool queued{}; + bool dead{}; + u64 hash{}; + InstList phis; + + bool HasCommonOp(CommonOp& out) const noexcept { + out = {}; + for (const IR::Inst* phi : phis) { + for (size_t i = 0; i < phi->NumArgs(); ++i) { + if (phi->Arg(i).IsImmediate()) { + return false; + } + IR::Inst* arg = phi->Arg(i).Inst(); + if (arg->GetOpcode() == IR::Opcode::Phi) { + if (arg->scc_index == phi->scc_index) { + continue; + } + return false; + } + if (out.op == IR::Opcode::Void) { + out.op = arg->GetOpcode(); + if (IsCompositeExtract(out.op)) { + out.extract_comp = arg->Arg(1).U32(); + } else if (arg->NumArgs() != 1 || IsDisallowedOp(out.op)) { + return false; + } + } else if (arg->GetOpcode() != out.op) { + return false; + } else if (IsCompositeExtract(out.op) && arg->Arg(1).U32() != out.extract_comp) { + return false; + } + } + } + ASSERT(out.op != IR::Opcode::Void); + return true; + } + + InstList SccUses() const noexcept { + InstList uses; + for (const IR::Inst* phi : phis) { + for (auto [user, operand] : phi->Uses()) { + if (user->GetOpcode() == IR::Opcode::Phi && user->scc_index != phi->scc_index) { + uses.push_back(user); + } + } + } + return uses; + } + + void FoldCommonOp(CommonOp& common_op) noexcept { + const IR::Type new_type{IR::ArgTypeOf(common_op.op, 0)}; + for (IR::Inst* phi : phis) { + IR::Block* block = phi->GetParent(); + for (size_t i = 0; i < phi->NumArgs(); ++i) { + IR::Inst* arg = phi->Arg(i).Inst(); + if (arg->GetOpcode() == IR::Opcode::Phi) { + continue; + } + phi->SetArg(i, arg->Arg(0)); + } + phi->SetRegTag(IR::EMPTY_REG_TAG); + phi->SetFlags(new_type); + + IR::Inst* replacement{}; + auto& uses = phi->Uses(); + for (auto it = uses.begin(); it != uses.end();) { + auto [user, operand] = *it; + ++it; + if (user->GetOpcode() == IR::Opcode::Phi && user->scc_index == phi->scc_index) { + continue; + } + if (!replacement) { + const auto insert_point = + std::ranges::find_if_not(block->Instructions(), IR::IsPhi); + if (IsCompositeExtract(common_op.op)) { + replacement = &*block->PrependNewInst( + insert_point, common_op.op, + {IR::Value{phi}, IR::Value{common_op.extract_comp}}); + } else { + replacement = + &*block->PrependNewInst(insert_point, common_op.op, {IR::Value{phi}}); + } + } + user->SetArg(operand, IR::Value{replacement}); + } + } + } + + void ComputeStructureHash() noexcept { + hash = HashCombine(0ull, phis.size()); + for (const IR::Inst* phi : phis) { + hash = HashCombine(hash, reinterpret_cast(phi->GetParent())); + for (size_t i = 0; i < phi->NumArgs(); ++i) { + hash = HashCombine(hash, phi->Arg(i).IsImmediate()); + if (phi->Arg(i).IsImmediate()) { + hash = HashCombine(hash, phi->Arg(i).Hash()); + continue; + } + const IR::Inst* arg = phi->Arg(i).Inst(); + const bool is_scc_arg = + arg->GetOpcode() == IR::Opcode::Phi && arg->scc_index == phi->scc_index; + hash = HashCombine(hash, is_scc_arg); + if (is_scc_arg) { + const auto it = std::ranges::find(phis, arg); + hash = HashCombine(hash, std::distance(phis.begin(), it)); + } + } + } + } + + bool IsSameAs(const PhiScc& other) const noexcept { + if (phis.size() != other.phis.size()) { + return false; + } + for (size_t i = 0; i < phis.size(); ++i) { + const IR::Inst* phi_a = phis[i]; + const IR::Inst* phi_b = other.phis[i]; + if (phi_a->GetParent() != phi_b->GetParent()) { + return false; + } + for (size_t j = 0; j < phi_a->NumArgs(); ++j) { + if (phi_a->Arg(j).IsImmediate() != phi_b->Arg(j).IsImmediate()) { + return false; + } + if (phi_a->Arg(j).IsImmediate()) { + if (phi_a->Arg(j).Hash() != phi_b->Arg(j).Hash()) { + return false; + } + continue; + } + const IR::Inst* arg_a = phi_a->Arg(j).Inst(); + const IR::Inst* arg_b = phi_b->Arg(j).Inst(); + if (arg_a->GetOpcode() != arg_b->GetOpcode()) { + return false; + } + if (arg_a->GetOpcode() == IR::Opcode::Phi) { + if (arg_a->Flags() != arg_b->Flags()) { + return false; + } + const bool is_scc_phi_a = arg_a->scc_index == phi_a->scc_index; + const bool is_scc_phi_b = arg_b->scc_index == phi_b->scc_index; + if (is_scc_phi_a != is_scc_phi_b) { + return false; + } + if (is_scc_phi_a) { + const auto it_a = std::ranges::find(phis, arg_a); + const auto it_b = std::ranges::find(other.phis, arg_b); + if (std::distance(phis.begin(), it_a) != + std::distance(other.phis.begin(), it_b)) { + return false; + } + continue; + } + } + if (arg_a != arg_b) { + return false; + } + } + } + return true; + } +}; + +struct PhiSccFinder { + struct NodeInfo { + u32 index{std::numeric_limits::max()}; + u32 lowlink{std::numeric_limits::max()}; + bool on_stack{}; + }; + std::unordered_map nodes; + InstList stack; + std::vector sccs; + u32 index_counter{0}; + + explicit PhiSccFinder(std::span all_phis) { + nodes.reserve(all_phis.size()); + for (IR::Inst* phi : all_phis) { + if (nodes[phi].index == std::numeric_limits::max()) { + StrongConnect(phi); + } + } + for (u32 i = 0; i < sccs.size(); i++) { + for (IR::Inst* phi : sccs[i].phis) { + phi->scc_index = i; + } + } + } + +private: + void StrongConnect(IR::Inst* root) { + struct Frame { + IR::Inst* phi; + size_t arg_idx; + }; + boost::container::small_vector dfs; + + const auto push_phi = [&](IR::Inst* phi, NodeInfo& info) { + info.index = index_counter; + info.lowlink = index_counter++; + info.on_stack = true; + stack.push_back(phi); + dfs.emplace_back(phi, 0); + }; + + push_phi(root, nodes[root]); + + while (!dfs.empty()) { + auto& [phi, arg_idx] = dfs.back(); + auto& info = nodes[phi]; + bool pushed_child = false; + + for (; arg_idx < phi->NumArgs(); arg_idx++) { + if (phi->Arg(arg_idx).IsImmediate()) { + continue; + } + IR::Inst* arg = phi->Arg(arg_idx).Inst(); + if (arg->GetOpcode() != IR::Opcode::Phi) { + continue; + } + + auto& arg_info = nodes[arg]; + if (arg_info.index == std::numeric_limits::max()) { + arg_idx++; + push_phi(arg, arg_info); + pushed_child = true; + break; + } else if (arg_info.on_stack) { + info.lowlink = std::min(info.lowlink, arg_info.index); + } + } + if (pushed_child) { + continue; + } + + if (info.lowlink == info.index) { + auto& scc = sccs.emplace_back(); + IR::Inst* w; + do { + w = stack.back(); + stack.pop_back(); + nodes[w].on_stack = false; + scc.phis.push_back(w); + } while (w != phi); + } + + dfs.pop_back(); + if (!dfs.empty()) { + auto& parent_info = nodes[dfs.back().phi]; + parent_info.lowlink = std::min(parent_info.lowlink, info.lowlink); + } + } + } +}; + +static void FoldSccCommonOps(std::vector& sccs) { + std::vector worklist; + worklist.reserve(sccs.size()); + for (u32 i = 0; i < sccs.size(); i++) { + worklist.push_back(i); + sccs[i].queued = true; + } + + while (!worklist.empty()) { + const u32 scc_idx = worklist.back(); + worklist.pop_back(); + + auto& scc = sccs[scc_idx]; + scc.queued = false; + + CommonOp op; + if (!scc.HasCommonOp(op)) { + continue; + } + auto scc_uses = scc.SccUses(); + do { + scc.FoldCommonOp(op); + } while (scc.HasCommonOp(op)); + + for (IR::Inst* const user : scc_uses) { + if (!std::exchange(sccs[user->scc_index].queued, true)) { + worklist.push_back(user->scc_index); + } + } + } +} + +static void DeduplicateSccs(std::vector& sccs) { + struct SccGroup { + boost::container::small_vector sccs; + bool queued{}; + }; + std::unordered_map scc_groups; + for (size_t scc_idx = 0; scc_idx < sccs.size(); ++scc_idx) { + auto& scc = sccs[scc_idx]; + scc.ComputeStructureHash(); + scc_groups[scc.hash].sccs.emplace_back(scc_idx); + } + + std::vector worklist; + worklist.reserve(scc_groups.size()); + for (auto it = scc_groups.begin(); it != scc_groups.end(); ++it) { + auto& group = it->second; + if (group.sccs.size() > 1) { + worklist.push_back(&group); + group.queued = true; + } + } + + while (!worklist.empty()) { + auto* group = worklist.back(); + worklist.pop_back(); + group->queued = false; + + for (size_t i = 0; i < group->sccs.size(); ++i) { + auto& scc = sccs[group->sccs[i]]; + if (scc.dead) { + continue; + } + for (size_t j = i + 1; j < group->sccs.size(); ++j) { + const u32 remove_idx = group->sccs[j]; + auto& remove = sccs[remove_idx]; + if (remove.dead) { + continue; + } + if (!scc.IsSameAs(remove)) { + continue; + } + for (size_t k = 0; k < remove.phis.size(); k++) { + IR::Inst* old_phi = remove.phis[k]; + IR::Inst* new_phi = scc.phis[k]; + const auto uses = old_phi->Uses(); + for (const auto& [user, operand] : uses) { + if (user->GetOpcode() == IR::Opcode::Phi) { + if (user->scc_index == old_phi->scc_index) { + continue; + } + auto& user_scc = sccs[user->scc_index]; + auto& user_group = scc_groups[user_scc.hash]; + if (!std::exchange(user_group.queued, true)) { + worklist.push_back(&user_group); + } + } + if (user->GetOpcode() != IR::Opcode::Void) { + user->SetArg(operand, IR::Value{new_phi}); + RunLocalCSE(user->GetParent()); + } + } + } + remove.dead = true; + } + } + } +} + +void PhiSimplificationPass(IR::Program& program) { + std::vector all_phis; + for (IR::Block* block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (inst.GetOpcode() != IR::Opcode::Phi) { + break; + } + all_phis.push_back(&inst); + } + } + + PhiSccFinder finder{all_phis}; + auto& sccs = finder.sccs; + FoldSccCommonOps(sccs); + DeduplicateSccs(sccs); +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/readlane_elimination_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/readlane_elimination_pass.cpp new file mode 100644 index 0000000..697411f --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/readlane_elimination_pass.cpp @@ -0,0 +1,182 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "shader_recompiler/ir/program.h" + +namespace Shader::Optimization { + +static IR::Inst* SearchChain(IR::Inst* inst, u32 lane) { + while (inst->GetOpcode() == IR::Opcode::WriteLane) { + if (inst->Arg(2).U32() == lane) { + // We found a possible write lane source, return it. + return inst; + } + inst = inst->Arg(0).Inst(); + } + return inst; +} + +static bool IsPossibleToEliminate(IR::Inst* inst, u32 lane) { + // Breadth-first search visiting the right most arguments first + boost::container::small_vector visited; + std::queue queue; + queue.push(inst); + + while (!queue.empty()) { + // Pop one instruction from the queue + IR::Inst* inst{queue.front()}; + queue.pop(); + + // If it's a WriteLane search for possible candidates + if (inst = SearchChain(inst, lane); inst->GetOpcode() == IR::Opcode::WriteLane) { + // We found a possible write lane source, stop looking here. + continue; + } + // If there are other instructions in-between that use the value we can't eliminate. + if (inst->GetOpcode() != IR::Opcode::ReadLane && inst->GetOpcode() != IR::Opcode::Phi && + inst->GetOpcode() != IR::Opcode::UndefU32) { + return false; + } + for (size_t arg = inst->NumArgs(); arg--;) { + auto arg_value{inst->Arg(arg)}; + if (arg_value.IsImmediate()) { + continue; + } + // Queue instruction if it hasn't been visited + IR::Inst* arg_inst{arg_value.Inst()}; + if (std::ranges::find(visited, arg_inst) == visited.end()) { + visited.push_back(arg_inst); + queue.push(arg_inst); + } + } + } + return true; +} + +using PhiMap = std::unordered_map; + +static IR::Value GetRealValue(PhiMap& phi_map, IR::Inst* inst, u32 lane) { + // If this is a WriteLane op search the chain for a possible candidate. + if (inst = SearchChain(inst, lane); inst->GetOpcode() == IR::Opcode::WriteLane) { + return inst->Arg(1); + } + + // If this is a phi, duplicate it and populate its arguments with real values. + if (inst->GetOpcode() == IR::Opcode::Phi) { + // We are in a phi cycle, use the already duplicated phi. + const auto [it, is_new_phi] = phi_map.try_emplace(inst); + if (!is_new_phi) { + return it->second; + } + + // Create new phi and insert it right before the old one. + const auto insert_point = IR::Block::InstructionList::s_iterator_to(*inst); + IR::Block* block = inst->GetParent(); + IR::Inst* const new_phi{&*block->PrependNewInst(insert_point, IR::Opcode::Phi)}; + new_phi->SetFlags(IR::Type::U32); + it->second = IR::Value{new_phi}; + + // Gather all arguments. + boost::container::small_vector phi_args; + for (size_t arg_index = 0; arg_index < inst->NumArgs(); arg_index++) { + IR::Value arg = inst->Arg(arg_index); + if (!arg.IsImmediate()) { + arg = GetRealValue(phi_map, arg.Inst(), lane); + } + phi_args.push_back(arg); + } + for (size_t arg_index = 0; arg_index < inst->NumArgs(); arg_index++) { + new_phi->AddPhiOperand(inst->PhiBlock(arg_index), phi_args[arg_index]); + } + return IR::Value{new_phi}; + } + if (inst->GetOpcode() == IR::Opcode::UndefU32) { + return IR::Value{inst}; + } + UNREACHABLE(); +} + +void ReadLaneEliminationPass(IR::Program& program) { + PhiMap phi_map; + std::vector worklist; + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (inst.GetOpcode() != IR::Opcode::ReadLane) { + continue; + } + if (!inst.Arg(1).IsImmediate()) { + continue; + } + + const u32 lane = inst.Arg(1).U32(); + IR::Inst* prod = inst.Arg(0).Inst(); + IR::Value replacement{}; + + // Check simple case of no control flow and phis + if (prod = SearchChain(prod, lane); prod->GetOpcode() == IR::Opcode::WriteLane) { + replacement = prod->Arg(1); + } else if (prod->GetOpcode() == IR::Opcode::Phi && IsPossibleToEliminate(prod, lane)) { + replacement = GetRealValue(phi_map, prod, lane); + for (const auto& [_, phi_value] : phi_map) { + worklist.push_back(phi_value.Inst()); + } + phi_map.clear(); + } + if (replacement.IsEmpty()) { + continue; + } + + for (auto& [user, operand] : inst.Uses()) { + if (user->GetOpcode() == IR::Opcode::Phi) { + worklist.push_back(user); + } + } + inst.ReplaceUsesWith(replacement); + } + } + // Attempt to resolve phis that have become trivial + while (!worklist.empty()) { + IR::Inst* phi = worklist.back(); + worklist.pop_back(); + + if (phi->GetOpcode() == IR::Opcode::Void) { + continue; + } + + IR::Value same; + bool non_trivial = false; + for (size_t i = 0; i < phi->NumArgs(); ++i) { + const IR::Value op{phi->Arg(i)}; + if (op == same || op == IR::Value{phi}) { + // Unique value or self-reference + continue; + } + if (!same.IsEmpty()) { + // The phi merges at least two values: not trivial + non_trivial = true; + break; + } + same = op; + } + if (non_trivial) { + continue; + } + + IR::Block* block = phi->GetParent(); + ASSERT(!same.IsEmpty()); + + // Add phi users to worklist since they may have become trivial + for (const auto& [user, operand] : phi->Uses()) { + if (user->GetOpcode() == IR::Opcode::Phi && user != phi) { + worklist.push_back(user); + } + } + phi->ReplaceUsesWithAndRemove(same); + auto it = IR::Block::InstructionList::s_iterator_to(*phi); + block->Instructions().erase(it); + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/resource_discover_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/resource_discover_pass.cpp new file mode 100644 index 0000000..4f3e5b7 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/resource_discover_pass.cpp @@ -0,0 +1,370 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "shader_recompiler/ir/passes/ir_passes.h" +#include "shader_recompiler/ir/passes/resource_pass.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" +#include "shader_recompiler/resource.h" + +namespace Shader::Optimization { + +static bool IsSharpSource(const IR::Inst* inst) { + return inst->GetOpcode() == IR::Opcode::GetUserData || + inst->GetOpcode() == IR::Opcode::ReadConst || + inst->GetOpcode() == IR::Opcode::ReadConstBuffer; +} + +struct StridePatchResult { + IR::Value vsharp_dw1; + u32 dw1_mask; + bool found; +}; +StridePatchResult CheckStridePatchPattern(IR::Value value) { + // s_or_b32 s37, s101, 0x400000 + // s_mov_b32 s36, s100 + // s_mov_b32 s38, -1 + // s_mov_b32 s39, 0x2000c004 + // s_movk_i32 s0, 0x6d0 + // buffer_load_dwordx4 v[17:20], v59, s[36:39], s0 idxen + + auto* inst = value.TryInst(); + if (!inst) { + return {value, 0, false}; + } + if (inst->GetOpcode() != IR::Opcode::BitwiseOr32 || !inst->Arg(1).IsImmediate()) { + return {value, 0, false}; + } + return {inst->Arg(0), inst->Arg(1).U32(), true}; +} + +struct InlineCbufResult { + IR::Value vsharp_dw0; + bool found; +}; +InlineCbufResult CheckInlineCbufPattern(IR::Value value) { + // Assuming V# is in s[32:35] + // The next pattern: + // s_getpc_b64 s[32:33] + // s_add_u32 s32, , s32 + // s_addc_u32 s33, 0, s33 + // s_mov_b32 s35, + // s_movk_i32 s34, + // buffer_load_format_xyz v[8:10], v1, s[32:35], 0 ... + // is used to define an inline constant buffer + + auto* inst = value.TryInst(); + if (!inst) { + return {value, false}; + } + if (inst->GetOpcode() != IR::Opcode::IAdd32 || + inst->Arg(0).IsImmediate() == inst->Arg(1).IsImmediate()) { + return {value, false}; + } + const u32 offset = inst->Arg(0).IsImmediate() ? inst->Arg(0).U32() : inst->Arg(1).U32(); + auto* prod = inst->Arg(0).IsImmediate() ? inst->Arg(1).Inst() : inst->Arg(0).Inst(); + if (prod->GetOpcode() != IR::Opcode::GetPcLo) { + return {value, false}; + } + return {IR::Value{prod->Arg(0).U32() + offset}, true}; +} + +struct CubeTo2DArrayResult { + IR::Value tsharp_dw3; + IR::Value tsharp_dw4; + bool found; +}; +CubeTo2DArrayResult CheckCubeTo2DArrayPattern(IR::Value dword3, IR::Value dword4) { + // Assuming T# is in s[12:19] + // The next pattern: + // s_bfe_u32 vcc_lo, s16, 0xd0000 + // s_mul_i32 vcc_lo, vcc_lo, 6 + // s_add_i32 vcc_lo, vcc_lo, 5 + // s_and_b32 vcc_hi, 0x1fff, vcc_lo + // s_and_b32 vcc_lo, s16, 0xffffe000 + // s_or_b32 s16, vcc_hi, vcc_lo + // s_and_b32 vcc_lo, s15, 0xfffffff + // s_or_b32 s15, 0xd0000000, vcc_lo + // image_load_mip v[4:7], v[0:3], s[12:19] dmask:15 da + // is used to convert the resource from cubemap to 2d-array + + // Check pattern that forces type to Color2DArray + auto* dw3_inst = dword3.TryInst(); + if (!dw3_inst) { + return {dword3, dword4, false}; + } + + if (dw3_inst->GetOpcode() != IR::Opcode::BitwiseOr32 || dw3_inst->Arg(1).IsImmediate() || + !dw3_inst->Arg(0).IsImmediate() || dw3_inst->Arg(0).U32() != 0xd0000000u) { + return {dword3, dword4, false}; + } + + auto* dw3_and = dw3_inst->Arg(1).Inst(); + if (dw3_and->GetOpcode() != IR::Opcode::BitwiseAnd32 || !dw3_and->Arg(1).IsImmediate() || + dw3_and->Arg(1).U32() != 0xfffffffu) { + return {dword3, dword4, false}; + } + + // Check pattern that translates cubemap depth to slices + auto* dw4_inst = dword4.TryInst(); + if (!dw4_inst) { + return {dword3, dword4, false}; + } + + if (dw4_inst->GetOpcode() != IR::Opcode::BitwiseOr32 || dw4_inst->Arg(0).IsImmediate() || + dw4_inst->Arg(1).IsImmediate()) { + return {dword3, dword4, false}; + } + + auto* dw4_rhs = dw4_inst->Arg(1).Inst(); + if (dw4_rhs->GetOpcode() != IR::Opcode::BitwiseAnd32 || !dw4_rhs->Arg(1).IsImmediate() || + dw4_rhs->Arg(1).U32() != 0xffffe000u) { + return {dword3, dword4, false}; + } + + return {dw3_and->Arg(0), dw4_rhs->Arg(0), true}; +} + +struct AnisoLod0Result { + IR::Value ssharp_dw0; + IR::Value tsharp_dw3; + bool found; +}; +AnisoLod0Result CheckDisableAnisoLod0Pattern(IR::Value value) { + // Assuming S# is in s[12:15] and T# is in s[4:11] + // The next pattern: + // s_bfe_u32 s0, s7, $0x0008000c + // s_and_b32 s1, s12, $0xfffff1ff + // s_cmp_eq_u32 s0, 0 + // s_cselect_b32 s0, s1, s12 + // s_mov_b32 s12, s0 + // is used to disable anisotropy in the sampler if the sampled texture doesn't have mips + + auto* inst = value.TryInst(); + if (!inst) { + return {value, {}, false}; + } + + if (inst->GetOpcode() != IR::Opcode::SelectU32) { + return {value, {}, false}; + } + + // Select should be based on zero check + const auto* prod0 = inst->Arg(0).Inst(); + if (prod0->GetOpcode() != IR::Opcode::IEqual32 || + !(prod0->Arg(1).IsImmediate() && prod0->Arg(1).U32() == 0u)) { + return {value, {}, false}; + } + + auto* prod0_arg0 = prod0->Arg(0).Inst(); + ASSERT(prod0_arg0->GetOpcode() != IR::Opcode::Phi); + + // The bits range is for lods (note that constants are changed after constant propagation pass) + if (prod0_arg0->GetOpcode() != IR::Opcode::BitFieldUExtract || + !(prod0_arg0->Arg(1).IsImmediate() && prod0_arg0->Arg(1).U32() == 12) || + !(prod0_arg0->Arg(2).IsImmediate() && prod0_arg0->Arg(2).U32() == 8)) { + return {value, {}, false}; + } + + // Make sure mask is masking out anisotropy + const auto* prod1 = inst->Arg(1).Inst(); + if (prod1->GetOpcode() != IR::Opcode::BitwiseAnd32 || prod1->Arg(1).U32() != 0xfffff1ff) { + return {value, {}, false}; + } + + // We're working on the first dword of S# + auto* prod2 = inst->Arg(2).Inst(); + ASSERT(prod2->GetOpcode() != IR::Opcode::Phi); + return {inst->Arg(2), prod0_arg0->Arg(0), true}; +} + +struct SamplerPatchResult { + IR::Value ssharp_dw0; + bool found; +}; +SamplerPatchResult CheckForceClampToWrapPattern(IR::Value value) { + // s_and_b32 s12, 0xfffffe00, s12 + // is used to force clamp_x/y/z to wrap + + auto* inst = value.TryInst(); + if (!inst) { + return {value, false}; + } + + if (inst->GetOpcode() != IR::Opcode::BitwiseAnd32 || !inst->Arg(0).IsImmediate() || + inst->Arg(0).U32() != 0xfffffe00u) { + return {value, false}; + } + + return {inst->Arg(1), true}; +} + +SamplerPatchResult CheckForceClampToLastTexelPattern(IR::Value value) { + // s_and_b32 s12, 0xfffffe00, s12 + // s_or_b32 0x12, s12 + // is used to force clamp_x/y to last texel + + auto* inst = value.TryInst(); + if (!inst) { + return {value, false}; + } + + if (inst->GetOpcode() != IR::Opcode::BitwiseOr32 || inst->Arg(1).IsImmediate() || + !inst->Arg(0).IsImmediate() || inst->Arg(0).U32() != 0x12u) { + return {value, false}; + } + + auto* prod = inst->Arg(1).Inst(); + if (prod->GetOpcode() != IR::Opcode::BitwiseAnd32 || !prod->Arg(0).IsImmediate() || + prod->Arg(0).U32() != 0xfffffe00u) { + return {value, false}; + } + + return {prod->Arg(1), true}; +} + +SamplerPatchResult CheckClearAnisoRatioAndThresholdPattern(IR::Value value) { + // s_and_b32 s12, s12, 0xfff8f1ff + // is used to clear anisotropy ratio and threshold fields + + auto* inst = value.TryInst(); + if (!inst) { + return {value, false}; + } + + if (inst->GetOpcode() != IR::Opcode::BitwiseAnd32 || !inst->Arg(1).IsImmediate() || + inst->Arg(1).U32() != 0xfff8f1ffu) { + return {value, false}; + } + + return {inst->Arg(0), true}; +} + +IR::Inst* FindSharpSource(IR::Inst* handle) { + ASSERT(IsSharpSource(handle)); + return handle; +} + +void MarkReadConstBufferSharpSources(const SharpReference& sharp) { + // In cases of bindless sharp fetches mark all producer instructions + // so the extended userdata flattening pass will include them. + for (size_t i = 0; i < sharp.num_dwords; i++) { + IR::Inst* source = sharp.dwords[i].TryInst(); + if (!source) { + continue; + } + ASSERT(IsSharpSource(source)); + if (source->GetOpcode() == IR::Opcode::ReadConstBuffer) { + auto flags = source->Flags(); + flags.sharp_source.Assign(1u); + source->SetFlags(flags); + } + } +} + +void DiscoverBufferSharp(IR::Block& block, IR::Inst& inst, ResourceDiscoveryList& resources) { + IR::Inst* handle = inst.Arg(0).Inst(); + auto& resource = resources.emplace_back(&inst); + auto& vsharp = resource.sharps[0]; + + // Gather V# dwords + vsharp.num_dwords = handle->NumArgs(); + for (size_t i = 0; i < handle->NumArgs(); ++i) { + vsharp.dwords[i] = handle->Arg(i); + if (auto* inst = vsharp.dwords[i].TryInst(); + inst && inst->GetOpcode() == IR::Opcode::ReadFirstLane) { + vsharp.dwords[i] = inst->Arg(0); + } + } + + // Attempt to "see through" various V# access patterns and have binding reproduce them + if (auto [dword0, found] = CheckInlineCbufPattern(vsharp.dwords[0]); found) { + vsharp.post_op = SharpFetchPostOp::OffsetByProgramBase; + vsharp.dwords[0] = dword0; + vsharp.dwords[1] = IR::Value{0U}; + } else if (auto [dword1, mask, found] = CheckStridePatchPattern(handle->Arg(1)); found) { + vsharp.post_op = SharpFetchPostOp::BitwiseOrDw1WithImm; + vsharp.post_op_data.dw1_mask = mask; + vsharp.dwords[1] = dword1; + } + + MarkReadConstBufferSharpSources(vsharp); +} + +void DiscoverImageSharp(IR::Block& block, IR::Inst& inst, ResourceDiscoveryList& resources) { + IR::Inst* image_handle = inst.Arg(0).Inst(); + ASSERT(image_handle->GetOpcode() == IR::Opcode::ImageHandle); + auto& resource = resources.emplace_back(&inst); + auto& tsharp = resource.sharps[0]; + + // Gather T# dwords + IR::Inst* tsharp_low = image_handle->Arg(0).Inst(); + for (size_t i = 0; i < tsharp_low->NumArgs(); ++i) { + tsharp.dwords[tsharp.num_dwords++] = tsharp_low->Arg(i); + } + if (auto tsharp_high = image_handle->Arg(1).TryInst()) { + for (size_t i = 0; i < tsharp_high->NumArgs(); ++i) { + tsharp.dwords[tsharp.num_dwords++] = tsharp_high->Arg(i); + } + } + + if (auto [tsharp_dw3, tsharp_dw4, found] = + CheckCubeTo2DArrayPattern(tsharp.dwords[3], tsharp.dwords[4]); + found) { + tsharp.post_op = SharpFetchPostOp::ConvertCubeTo2DArray; + tsharp.dwords[3] = tsharp_dw3; + tsharp.dwords[4] = tsharp_dw4; + } + + MarkReadConstBufferSharpSources(tsharp); + + if (inst.GetOpcode() != IR::Opcode::ImageSampleRaw) { + return; + } + + // Gather S# dwords + const IR::Inst* sampler = inst.Arg(1).Inst(); + auto& ssharp = resource.sharps[1]; + for (size_t i = 0; i < sampler->NumArgs(); ++i) { + ssharp.dwords[ssharp.num_dwords++] = sampler->Arg(i); + } + if (auto [ssharp_dw0, tsharp_dw3, found] = CheckDisableAnisoLod0Pattern(ssharp.dwords[0]); + found) { + ssharp.post_op = SharpFetchPostOp::DisableAnisoIfSingleLod; + ssharp.post_op_data.lod_prod = tsharp_dw3; + ssharp.dwords[0] = ssharp_dw0; + } else if (auto [ssharp_dw0, found] = CheckForceClampToWrapPattern(ssharp.dwords[0]); found) { + ssharp.post_op = SharpFetchPostOp::ForceRepeatXyzClamp; + ssharp.dwords[0] = ssharp_dw0; + } else if (auto [ssharp_dw0, found] = CheckForceClampToLastTexelPattern(ssharp.dwords[0]); + found) { + ssharp.post_op = SharpFetchPostOp::ForceLastTexelXyClamp; + ssharp.dwords[0] = ssharp_dw0; + } else if (auto [ssharp_dw0, found] = CheckClearAnisoRatioAndThresholdPattern(ssharp.dwords[0]); + found) { + ssharp.post_op = SharpFetchPostOp::ClearAnisoRatioAndThreshold; + ssharp.dwords[0] = ssharp_dw0; + } + + MarkReadConstBufferSharpSources(ssharp); +} + +ResourceDiscoveryList ResourceDiscoverPass(IR::Program& program, const Profile& profile) { + ResourceDiscoveryList sharp_usages; + + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (IsBufferInstruction(inst)) { + DiscoverBufferSharp(*block, inst, sharp_usages); + } else if (IsImageInstruction(inst)) { + DiscoverImageSharp(*block, inst, sharp_usages); + } else if (IsDataRingInstruction(inst)) { + sharp_usages.emplace_back(&inst); + } + } + } + return sharp_usages; +} + +} // namespace Shader::Optimization \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/passes/resource_pass.h b/gpu/shadps4/shader_recompiler/ir/passes/resource_pass.h new file mode 100644 index 0000000..ec9b3c4 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/resource_pass.h @@ -0,0 +1,181 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader { +enum class SharpFetchPostOp : u8; +} + +namespace Shader::Optimization { + +union PostOpData { + u32 dw1_mask; + IR::Value lod_prod{}; +}; + +struct SharpReference { + std::array dwords{}; + u32 num_dwords{}; + SharpFetchPostOp post_op{}; + PostOpData post_op_data; +}; + +struct ResourceDiscovery { + IR::Inst* user{}; + std::array sharps; +}; +using ResourceDiscoveryList = boost::container::small_vector; + +inline bool IsBufferAtomic(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::BufferAtomicIAdd32: + case IR::Opcode::BufferAtomicIAdd64: + case IR::Opcode::BufferAtomicISub32: + case IR::Opcode::BufferAtomicSMin32: + case IR::Opcode::BufferAtomicSMin64: + case IR::Opcode::BufferAtomicUMin32: + case IR::Opcode::BufferAtomicUMin64: + case IR::Opcode::BufferAtomicFMin32: + case IR::Opcode::BufferAtomicSMax32: + case IR::Opcode::BufferAtomicSMax64: + case IR::Opcode::BufferAtomicUMax32: + case IR::Opcode::BufferAtomicUMax64: + case IR::Opcode::BufferAtomicFMax32: + case IR::Opcode::BufferAtomicInc32: + case IR::Opcode::BufferAtomicDec32: + case IR::Opcode::BufferAtomicAnd32: + case IR::Opcode::BufferAtomicOr32: + case IR::Opcode::BufferAtomicXor32: + case IR::Opcode::BufferAtomicSwap32: + case IR::Opcode::BufferAtomicCmpSwap32: + case IR::Opcode::BufferAtomicFCmpSwap32: + return true; + default: + return false; + } +} + +inline bool IsBufferStore(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::StoreBufferU8: + case IR::Opcode::StoreBufferU16: + case IR::Opcode::StoreBufferU32: + case IR::Opcode::StoreBufferU32x2: + case IR::Opcode::StoreBufferU32x3: + case IR::Opcode::StoreBufferU32x4: + case IR::Opcode::StoreBufferU64: + case IR::Opcode::StoreBufferF32: + case IR::Opcode::StoreBufferF32x2: + case IR::Opcode::StoreBufferF32x3: + case IR::Opcode::StoreBufferF32x4: + case IR::Opcode::StoreBufferFormatF32: + return true; + default: + return IsBufferAtomic(inst); + } +} + +inline bool IsDataRingInstruction(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::DataAppend: + case IR::Opcode::DataConsume: + return true; + case IR::Opcode::LoadSharedU16: + case IR::Opcode::LoadSharedU32: + case IR::Opcode::LoadSharedU64: + case IR::Opcode::WriteSharedU16: + case IR::Opcode::WriteSharedU32: + case IR::Opcode::WriteSharedU64: + case IR::Opcode::SharedAtomicIAdd32: + case IR::Opcode::SharedAtomicIAdd64: + case IR::Opcode::SharedAtomicUMin32: + case IR::Opcode::SharedAtomicUMin64: + case IR::Opcode::SharedAtomicSMin32: + case IR::Opcode::SharedAtomicSMin64: + case IR::Opcode::SharedAtomicUMax32: + case IR::Opcode::SharedAtomicUMax64: + case IR::Opcode::SharedAtomicSMax32: + case IR::Opcode::SharedAtomicSMax64: + case IR::Opcode::SharedAtomicAnd32: + case IR::Opcode::SharedAtomicAnd64: + case IR::Opcode::SharedAtomicOr32: + case IR::Opcode::SharedAtomicOr64: + case IR::Opcode::SharedAtomicXor32: + case IR::Opcode::SharedAtomicXor64: + case IR::Opcode::SharedAtomicISub32: + case IR::Opcode::SharedAtomicISub64: + case IR::Opcode::SharedAtomicInc32: + case IR::Opcode::SharedAtomicInc64: + case IR::Opcode::SharedAtomicDec32: + case IR::Opcode::SharedAtomicDec64: + case IR::Opcode::SharedAtomicCmpSwap32: + case IR::Opcode::SharedAtomicCmpSwap64: + return inst.Flags(); // is_gds + default: + return false; + } +} + +inline bool IsBufferInstruction(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::LoadBufferU8: + case IR::Opcode::LoadBufferU16: + case IR::Opcode::LoadBufferU32: + case IR::Opcode::LoadBufferU32x2: + case IR::Opcode::LoadBufferU32x3: + case IR::Opcode::LoadBufferU32x4: + case IR::Opcode::LoadBufferU64: + case IR::Opcode::LoadBufferF32: + case IR::Opcode::LoadBufferF32x2: + case IR::Opcode::LoadBufferF32x3: + case IR::Opcode::LoadBufferF32x4: + case IR::Opcode::LoadBufferFormatF32: + case IR::Opcode::ReadConstBuffer: + return true; + default: + return IsBufferStore(inst); + } +} + +inline bool IsImageAtomicInstruction(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::ImageAtomicIAdd32: + case IR::Opcode::ImageAtomicSMin32: + case IR::Opcode::ImageAtomicUMin32: + case IR::Opcode::ImageAtomicSMax32: + case IR::Opcode::ImageAtomicUMax32: + case IR::Opcode::ImageAtomicFMax32: + case IR::Opcode::ImageAtomicFMin32: + case IR::Opcode::ImageAtomicInc32: + case IR::Opcode::ImageAtomicDec32: + case IR::Opcode::ImageAtomicAnd32: + case IR::Opcode::ImageAtomicOr32: + case IR::Opcode::ImageAtomicXor32: + case IR::Opcode::ImageAtomicExchange32: + case IR::Opcode::ImageAtomicCmpSwap32: + return true; + default: + return false; + } +} + +inline bool IsImageInstruction(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::ImageRead: + case IR::Opcode::ImageWrite: + case IR::Opcode::ImageQueryDimensions: + case IR::Opcode::ImageQueryLod: + case IR::Opcode::ImageSampleRaw: + return true; + default: + return IsImageAtomicInstruction(inst); + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/resource_patching_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/resource_patching_pass.cpp new file mode 100644 index 0000000..8602816 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/resource_patching_pass.cpp @@ -0,0 +1,956 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/breadth_first_search.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/operand_helper.h" +#include "shader_recompiler/ir/passes/ir_passes.h" +#include "shader_recompiler/ir/passes/resource_pass.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/reinterpret.h" +#include "shader_recompiler/profile.h" +#include "video_core/amdgpu/resource.h" + +namespace Shader::Optimization { +namespace { + +IR::Type BufferDataType(const IR::Inst& inst, const Profile& profile) { + switch (inst.GetOpcode()) { + case IR::Opcode::LoadBufferU8: + case IR::Opcode::StoreBufferU8: + return IR::Type::U8; + case IR::Opcode::LoadBufferU16: + case IR::Opcode::StoreBufferU16: + return IR::Type::U16; + case IR::Opcode::LoadBufferU64: + case IR::Opcode::StoreBufferU64: + case IR::Opcode::BufferAtomicIAdd64: + case IR::Opcode::BufferAtomicSMax64: + case IR::Opcode::BufferAtomicSMin64: + case IR::Opcode::BufferAtomicUMax64: + case IR::Opcode::BufferAtomicUMin64: + return IR::Type::U64; + case IR::Opcode::BufferAtomicFMax32: + case IR::Opcode::BufferAtomicFMin32: + return profile.supports_buffer_fp32_atomic_min_max ? IR::Type::F32 : IR::Type::U32; + case IR::Opcode::LoadBufferFormatF32: + case IR::Opcode::StoreBufferFormatF32: + // Formatted buffer loads can use a variety of types. + return IR::Type::U32 | IR::Type::F32 | IR::Type::U16 | IR::Type::U8; + default: + return IR::Type::U32; + } +} + +u32 BufferAddressShift(const IR::Inst& inst, AmdGpu::DataFormat data_format) { + switch (inst.GetOpcode()) { + case IR::Opcode::LoadBufferU8: + case IR::Opcode::StoreBufferU8: + return 0; + case IR::Opcode::LoadBufferU16: + case IR::Opcode::StoreBufferU16: + return 1; + case IR::Opcode::LoadBufferU64: + case IR::Opcode::StoreBufferU64: + case IR::Opcode::BufferAtomicIAdd64: + case IR::Opcode::BufferAtomicSMax64: + case IR::Opcode::BufferAtomicSMin64: + case IR::Opcode::BufferAtomicUMax64: + case IR::Opcode::BufferAtomicUMin64: + return 3; + case IR::Opcode::LoadBufferFormatF32: + case IR::Opcode::StoreBufferFormatF32: { + switch (data_format) { + case AmdGpu::DataFormat::Format8: + return 0; + case AmdGpu::DataFormat::Format8_8: + case AmdGpu::DataFormat::Format16: + return 1; + case AmdGpu::DataFormat::Format8_8_8_8: + case AmdGpu::DataFormat::Format16_16: + case AmdGpu::DataFormat::Format10_11_11: + case AmdGpu::DataFormat::Format2_10_10_10: + case AmdGpu::DataFormat::Format16_16_16_16: + case AmdGpu::DataFormat::Format32: + case AmdGpu::DataFormat::Format32_32: + case AmdGpu::DataFormat::Format32_32_32: + case AmdGpu::DataFormat::Format32_32_32_32: + return 2; + default: + return 0; + } + break; + } + case IR::Opcode::ReadConstBuffer: + // Provided address is already in dwords + return 0; + default: + return 2; + } +} + +class Descriptors { +public: + explicit Descriptors(Info& info_) + : info{info_}, buffer_resources{info_.buffers}, image_resources{info_.images}, + sampler_resources{info_.samplers}, fmask_resources(info_.fmasks) {} + + u32 Add(const BufferResource& desc) { + const u32 index{Add(buffer_resources, desc, [&desc](const auto& existing) { + return desc.sharp_fetch == existing.sharp_fetch && desc.post_op == existing.post_op && + desc.post_op_dw1_mask == existing.post_op_dw1_mask && + desc.buffer_type == existing.buffer_type; + })}; + auto& buffer = buffer_resources[index]; + buffer.used_types |= desc.used_types; + buffer.is_written |= desc.is_written; + buffer.is_formatted |= desc.is_formatted; + return index; + } + + u32 Add(const ImageResource& desc) { + const u32 index{Add(image_resources, desc, [&desc](const auto& existing) { + return desc.sharp_fetch == existing.sharp_fetch && desc.is_array == existing.is_array && + desc.mip_fallback_mode == existing.mip_fallback_mode && + desc.constant_mip_index == existing.constant_mip_index && + desc.post_op == existing.post_op; + })}; + auto& image = image_resources[index]; + image.is_atomic |= desc.is_atomic; + image.is_written |= desc.is_written; + return index; + } + + u32 Add(const SamplerResource& desc) { + const u32 index{Add(sampler_resources, desc, [this, &desc](const auto& existing) { + return desc.sharp_fetch == existing.sharp_fetch && desc.post_op == existing.post_op && + desc.post_op_tsharp_dw3_off == existing.post_op_tsharp_dw3_off && + desc.is_depth == existing.is_depth; + })}; + return index; + } + + u32 Add(const FMaskResource& desc) { + u32 index = Add(fmask_resources, desc, [&desc](const auto& existing) { + return desc.sharp_idx == existing.sharp_idx; + }); + return index; + } + +private: + template + static u32 Add(Descriptors& descriptors, const Descriptor& desc, Func&& pred) { + const auto it{std::ranges::find_if(descriptors, pred)}; + if (it != descriptors.end()) { + return static_cast(std::distance(descriptors.begin(), it)); + } + descriptors.push_back(desc); + return static_cast(descriptors.size()) - 1; + } + + const Info& info; + BufferResourceList& buffer_resources; + ImageResourceList& image_resources; + SamplerResourceList& sampler_resources; + FMaskResourceList& fmask_resources; +}; + +} // Anonymous namespace + +using SharpSources = boost::container::small_vector; + +SharpLocation SharpLocationFromSource(const IR::Inst* inst) { + SharpLocation location{}; + if (inst->GetOpcode() == IR::Opcode::GetUserData) { + return static_cast(inst->Arg(0).ScalarReg()); + } else if (inst->GetOpcode() == IR::Opcode::ReadConstBuffer) { + location = inst->Flags().flatbuf_off_dw; + } else { + location = inst->Flags(); + } + if (location == 0) { + LOG_WARNING(Render_Recompiler, "Sharp source was not flatenned"); + return UNKNOWN_LOCATION; + } + return location; +} + +template +SharpFetch ConstructSharpFetch(const SharpReference& sharp) { + SharpFetch sharp_fetch{}; + for (u32 i = 0; i < sharp.num_dwords; i++) { + auto dword = sharp.dwords[i]; + if (dword.IsImmediate()) { + sharp_fetch.immediates[i] = dword.U32(); + } else { + sharp_fetch.offsets[i] = SharpLocationFromSource(dword.Inst()); + sharp_fetch.load_mask |= (1 << i); + } + } + return sharp_fetch; +} + +void PatchBufferSharp(const ResourceDiscovery& resource, Info& info, Descriptors& descriptors, + const Profile& profile) { + IR::Inst& inst = *resource.user; + + const u32 buffer_binding = descriptors.Add(BufferResource{ + .sharp_fetch = ConstructSharpFetch(resource.sharps[0]), + .used_types = BufferDataType(inst, profile), + .buffer_type = BufferType::Guest, + .is_written = IsBufferStore(inst), + .is_formatted = inst.GetOpcode() == IR::Opcode::LoadBufferFormatF32 || + inst.GetOpcode() == IR::Opcode::StoreBufferFormatF32, + .post_op = resource.sharps[0].post_op, + .post_op_dw1_mask = resource.sharps[0].post_op_data.dw1_mask, + }); + + // Replace handle with binding index in buffer resource list. + IR::IREmitter ir{*inst.GetParent(), IR::Block::InstructionList::s_iterator_to(inst)}; + inst.SetArg(0, ir.Imm32(buffer_binding)); +} + +void PatchImageSharp(const ResourceDiscovery& resource, Info& info, Descriptors& descriptors, + const Profile& profile) { + IR::Inst& inst = *resource.user; + + // Read image sharp. + const auto inst_info = inst.Flags(); + const bool is_atomic = IsImageAtomicInstruction(inst); + const bool is_written = inst.GetOpcode() == IR::Opcode::ImageWrite || is_atomic; + // ImageRead with !is_written gets emitted as OpImageFetch with LOD operand, doesn't + // need fallback (TODO is this 100% true?) + const bool needs_mip_storage_fallback = + inst_info.has_lod && is_written && !profile.supports_image_load_store_lod; + ImageResource image_res = { + .sharp_fetch = ConstructSharpFetch(resource.sharps[0]), + .is_depth = bool(inst_info.is_depth), + .is_atomic = is_atomic, + .is_array = bool(inst_info.is_array), + .is_written = is_written, + .is_r128 = bool(inst_info.is_r128), + .post_op = resource.sharps[0].post_op, + }; + + auto image = image_res.GetSharp(info); + ASSERT(image.GetType() != AmdGpu::ImageType::Invalid); + + if (needs_mip_storage_fallback) { + // If the mip level to IMAGE_(LOAD/STORE)_MIP is a constant, set up ImageResource + // so that we will only bind a single level. + // If index is dynamic, we will bind levels as an array + const auto view_type = image.GetViewType(image_res.is_array); + + IR::Inst* body = inst.Arg(1).Inst(); + const auto lod_arg = [&] -> IR::Value { + switch (view_type) { + case AmdGpu::ImageType::Color1D: // x, [lod] + return body->Arg(1); + case AmdGpu::ImageType::Color1DArray: // x, slice, [lod] + case AmdGpu::ImageType::Color2D: // x, y, [lod] + return body->Arg(2); + case AmdGpu::ImageType::Color2DArray: // x, y, slice, [lod] + case AmdGpu::ImageType::Color3D: // x, y, z, [lod] + return body->Arg(3); + case AmdGpu::ImageType::Color2DMsaa: + case AmdGpu::ImageType::Color2DMsaaArray: + default: + UNREACHABLE_MSG("Invalid image type {}", view_type); + } + }(); + + if (lod_arg.IsImmediate()) { + image_res.mip_fallback_mode = MipStorageFallbackMode::ConstantIndex; + image_res.constant_mip_index = lod_arg.U32(); + } else { + image_res.mip_fallback_mode = MipStorageFallbackMode::DynamicIndex; + } + } + + // Patch image instruction if image is FMask. + if (AmdGpu::IsFmask(image.GetDataFmt())) { + ASSERT_MSG(!is_written, "FMask storage instructions are not supported"); + + IR::IREmitter ir{*inst.GetParent(), IR::Block::InstructionList::s_iterator_to(inst)}; + switch (inst.GetOpcode()) { + case IR::Opcode::ImageRead: + case IR::Opcode::ImageSampleRaw: { + IR::F32 fmaskx = ir.BitCast(ir.Imm32(0x76543210)); + IR::F32 fmasky = ir.BitCast(ir.Imm32(0xfedcba98)); + inst.ReplaceUsesWith(ir.CompositeConstruct(fmaskx, fmasky)); + return; + } + case IR::Opcode::ImageQueryLod: + inst.ReplaceUsesWith(ir.Imm32(1)); + return; + case IR::Opcode::ImageQueryDimensions: { + IR::Value dims = ir.CompositeConstruct(ir.Imm32(static_cast(image.width)), // x + ir.Imm32(static_cast(image.height)), // y + ir.Imm32(1), ir.Imm32(1)); // depth, mip + inst.ReplaceUsesWith(dims); + + // Track FMask resource to do specialization. + descriptors.Add(FMaskResource{ + .sharp_idx = SharpLocationFromSource(resource.sharps[0].dwords[0].Inst()), + }); + return; + } + default: + UNREACHABLE_MSG("Can't patch fmask instruction {}", inst.GetOpcode()); + } + } + + u32 image_binding = descriptors.Add(image_res); + + IR::IREmitter ir{*inst.GetParent(), IR::Block::InstructionList::s_iterator_to(inst)}; + + if (inst.GetOpcode() == IR::Opcode::ImageSampleRaw) { + auto& lod_prod = resource.sharps[1].post_op_data.lod_prod; + const u32 sampler_binding = descriptors.Add(SamplerResource{ + .sharp_fetch = ConstructSharpFetch(resource.sharps[1]), + .post_op = resource.sharps[1].post_op, + .post_op_tsharp_dw3_off = + lod_prod.IsEmpty() ? UNKNOWN_LOCATION : SharpLocationFromSource(lod_prod.Inst()), + .is_depth = bool(inst_info.is_depth), // true for the _C (compare) opcodes + }); + inst.SetArg(0, ir.Imm32(image_binding | sampler_binding << 16)); + } else { + inst.SetArg(0, ir.Imm32(image_binding)); + } +} + +static IR::Value IsMbcntWithExec(IR::Value value, bool is_hi, IR::U1 exec) { + if (value.IsImmediate()) { + return {}; + } + const IR::Inst* inst = value.Inst(); + if (inst->GetOpcode() != IR::Opcode::MaskedBitCount32 || inst->Arg(0).IsImmediate() || + inst->Arg(2).U1() != is_hi) { + return {}; + } + IR::Inst* prod = inst->Arg(0).Inst(); + if (prod->GetOpcode() != IR::Opcode::CompositeExtractU32x2 || prod->Arg(0).IsImmediate() || + prod->Arg(1).U32() != is_hi) { + return {}; + } + prod = prod->Arg(0).Inst(); + if (prod->GetOpcode() != IR::Opcode::UnpackUint2x32 || prod->Arg(0).IsImmediate()) { + return {}; + } + prod = prod->Arg(0).Inst(); + if (prod->GetOpcode() != IR::Opcode::Ballot || (prod->Arg(0) != exec && !is_hi)) { + return {}; + } + return inst->Arg(1); +} + +static IR::Use FindUniqueUser(IR::Inst* inst, auto&& pred) { + IR::Use picked{}; + for (auto& use : inst->Uses()) { + if (pred(use.user)) { + ASSERT(!picked.user); + picked = use; + } + } + ASSERT(picked.user); + return picked; +} + +static void RemoveAppendBufferLaneOffset(IR::Inst& vx) { + // Attempt to detect either of the following patterns and + // remove the lane id addition/subtraction to ds instruction. + // + // ds_append vX gds + // v_mbcnt_hi_u32_b32 vY, exec_hi, vX + // v_mbcnt_lo_u32_b32 idx, exec_lo, vY + // + // v_mbcnt_hi_u32_b32 vY, exec_hi, 0 + // v_mbcnt_lo_u32_b32 vZ, exec_lo, vY + // ds_append vX gds + // v_add_i32 idx, vcc, vX, vZ + // + // ds_consume vX gds + // v_mbcnt_hi_u32_b32 vY, exec_hi, 0 + // v_mbcnt_lo_u32_b32 vZ, exec_lo, vY + // v_sub_i32 vK, vcc, vX, vZ + // v_subrev_i32 idx, vcc, 1, vK / v_add_i32 idx, vcc, -1, vK + // + // ds_consume vX gds + // v_mbcnt_hi_u32_b32 vY, exec_hi, 0 + // v_mbcnt_lo_u32_b32 vZ, exec_lo, vY + // v_add_i32 vK, vcc, -1, vX + // v_sub_i32 idx, vcc, vK, vZ + + IR::U1 exec{vx.Arg(1)}; + const auto uses = vx.Uses(); + for (auto use : uses) { + const auto& [user, operand] = use; + if (user->GetOpcode() == IR::Opcode::MaskedBitCount32) { + // First pattern + ASSERT(vx.GetOpcode() == IR::Opcode::DataAppend); + IR::Inst* vy = user; + auto vx_2 = IsMbcntWithExec(IR::Value{vy}, true, exec); + ASSERT(!vx_2.IsEmpty() && vx_2 == IR::Value{&vx}); + const auto [idx, operand] = FindUniqueUser(vy, [](const IR::Inst* inst) { + return inst->GetOpcode() == IR::Opcode::MaskedBitCount32; + }); + auto vy_2 = IsMbcntWithExec(IR::Value{idx}, false, exec); + ASSERT(!vy_2.IsEmpty() && vy_2 == IR::Value{vy}); + idx->ReplaceUsesWithAndRemove(IR::Value{&vx}); + continue; + } + if (user->GetOpcode() != IR::Opcode::IAdd32 && user->GetOpcode() != IR::Opcode::ISub32) { + continue; + } + const auto other = user->Arg(1 - operand); + if (other.IsImmediate()) { + ASSERT_MSG(other.U32() == 1u || other.U32() == std::numeric_limits::max() && + vx.GetOpcode() == IR::Opcode::DataConsume, + "Unexpected constant offset {} to DataConsume result", other.U32()); + use = FindUniqueUser(user, [](const IR::Inst* inst) { + return inst->GetOpcode() == IR::Opcode::IAdd32 || + inst->GetOpcode() == IR::Opcode::ISub32; + }); + } + + // Other patterns + auto vz = user->Arg(1 - operand); + auto vy = IsMbcntWithExec(vz, false, exec); + ASSERT(!vy.IsEmpty() && !vy.IsImmediate()); + auto zero_const = IsMbcntWithExec(vy, true, exec); + ASSERT(!zero_const.IsEmpty() && zero_const.IsImmediate() && zero_const.U32() == 0u); + vz.Inst()->ReplaceUsesWithAndRemove(IR::Value{u32{0u}}); + } +} + +void PatchGlobalDataShareAccess(IR::Inst& inst, Info& info, Descriptors& descriptors, + const Profile& profile) { + const u32 binding = descriptors.Add(BufferResource{ + .used_types = IR::Type::U32, + .buffer_type = BufferType::GdsBuffer, + .is_written = true, + }); + + IR::IREmitter ir{*inst.GetParent(), IR::Block::InstructionList::s_iterator_to(inst)}; + + if (inst.GetOpcode() == IR::Opcode::DataAppend || inst.GetOpcode() == IR::Opcode::DataConsume) { + RemoveAppendBufferLaneOffset(inst); + const IR::Value replacement = + inst.GetOpcode() == IR::Opcode::DataAppend + ? ir.BufferAtomicIAdd(ir.Imm32(binding), inst.Arg(0), ir.Imm32(1u), {}) + : ir.BufferAtomicISub(ir.Imm32(binding), inst.Arg(0), ir.Imm32(1u), {}); + inst.ReplaceUsesWithAndRemove(replacement); + return; + } + + // Convert shared memory opcode to storage buffer atomic to GDS buffer. + auto& buffer = info.buffers[binding]; + const IR::U32 offset = IR::U32{inst.Arg(0)}; + const IR::U32 address_words = ir.ShiftRightLogical(offset, ir.Imm32(1)); + const IR::U32 address_dwords = ir.ShiftRightLogical(offset, ir.Imm32(2)); + const IR::U32 address_qwords = ir.ShiftRightLogical(offset, ir.Imm32(3)); + const IR::U32 handle = ir.Imm32(binding); + switch (inst.GetOpcode()) { + case IR::Opcode::SharedAtomicIAdd32: + inst.ReplaceUsesWith(ir.BufferAtomicIAdd(handle, address_dwords, inst.Arg(1), {})); + break; + case IR::Opcode::SharedAtomicIAdd64: + inst.ReplaceUsesWith(ir.BufferAtomicIAdd(handle, address_qwords, IR::U64{inst.Arg(1)}, {})); + break; + case IR::Opcode::SharedAtomicISub32: + inst.ReplaceUsesWith(ir.BufferAtomicISub(handle, address_dwords, inst.Arg(1), {})); + break; + case IR::Opcode::SharedAtomicSMin32: + case IR::Opcode::SharedAtomicUMin32: { + const bool is_signed = inst.GetOpcode() == IR::Opcode::SharedAtomicSMin32; + inst.ReplaceUsesWith( + ir.BufferAtomicIMin(handle, address_dwords, inst.Arg(1), is_signed, {})); + break; + } + case IR::Opcode::SharedAtomicSMax32: + case IR::Opcode::SharedAtomicUMax32: { + const bool is_signed = inst.GetOpcode() == IR::Opcode::SharedAtomicSMax32; + inst.ReplaceUsesWith( + ir.BufferAtomicIMax(handle, address_dwords, inst.Arg(1), is_signed, {})); + break; + } + case IR::Opcode::SharedAtomicInc32: + inst.ReplaceUsesWith(ir.BufferAtomicInc(handle, address_dwords, {})); + break; + case IR::Opcode::SharedAtomicDec32: + inst.ReplaceUsesWith(ir.BufferAtomicDec(handle, address_dwords, {})); + break; + case IR::Opcode::SharedAtomicAnd32: + inst.ReplaceUsesWith(ir.BufferAtomicAnd(handle, address_dwords, inst.Arg(1), {})); + break; + case IR::Opcode::SharedAtomicOr32: + inst.ReplaceUsesWith(ir.BufferAtomicOr(handle, address_dwords, inst.Arg(1), {})); + break; + case IR::Opcode::SharedAtomicXor32: + inst.ReplaceUsesWith(ir.BufferAtomicXor(handle, address_dwords, inst.Arg(1), {})); + break; + case IR::Opcode::SharedAtomicCmpSwap32: + // Args are (address, value, cmp_value) + inst.ReplaceUsesWith( + ir.BufferAtomicCmpSwap(handle, address_dwords, inst.Arg(1), inst.Arg(2), {})); + break; + case IR::Opcode::LoadSharedU16: { + inst.ReplaceUsesWith(ir.LoadBufferU16(handle, address_words, {})); + buffer.used_types |= IR::Type::U16; + break; + } + case IR::Opcode::LoadSharedU32: + inst.ReplaceUsesWith(ir.LoadBufferU32(1, handle, address_dwords, {})); + break; + case IR::Opcode::LoadSharedU64: { + inst.ReplaceUsesWith(ir.LoadBufferU64(handle, address_qwords, {})); + buffer.used_types |= IR::Type::U64; + break; + } + case IR::Opcode::WriteSharedU16: { + ir.StoreBufferU16(handle, address_words, IR::U16{inst.Arg(1)}, {}); + inst.Invalidate(); + buffer.used_types |= IR::Type::U16; + break; + } + case IR::Opcode::WriteSharedU32: + ir.StoreBufferU32(1, handle, address_dwords, inst.Arg(1), {}); + inst.Invalidate(); + break; + case IR::Opcode::WriteSharedU64: { + ir.StoreBufferU64(handle, address_qwords, IR::U64{inst.Arg(1)}, {}); + inst.Invalidate(); + buffer.used_types |= IR::Type::U64; + break; + } + default: + UNREACHABLE_MSG("Unexpected opcode {}", inst.GetOpcode()); + } +} + +IR::U32 CalculateBufferAddress(IR::IREmitter& ir, const IR::Inst& inst, const Info& info, + const AmdGpu::Buffer& buffer, u32 stride) { + const auto inst_info = inst.Flags(); + const u32 inst_offset = inst_info.inst_offset.Value(); + const auto is_inst_typed = inst_info.inst_data_fmt != AmdGpu::DataFormat::FormatInvalid; + const auto data_format = is_inst_typed + ? AmdGpu::RemapDataFormat(inst_info.inst_data_fmt.Value()) + : buffer.GetDataFmt(); + const u32 shift = BufferAddressShift(inst, data_format); + const u32 mask = (1 << shift) - 1; + const IR::U32 soffset = IR::GetBufferSOffsetArg(&inst); + + // If address calculation is of the form "index * const_stride + offset" with offset constant + // and both const_stride and offset are divisible with the element size, apply shift directly. + if (inst_info.index_enable && !inst_info.voffset_enable && soffset.IsImmediate() && + !buffer.swizzle_enable && !buffer.add_tid_enable && (stride & mask) == 0) { + const u32 total_offset = soffset.U32() + inst_offset; + if ((total_offset & mask) == 0) { + // buffer_offset = index * (const_stride >> shift) + (offset >> shift) + const IR::U32 index = IR::GetBufferIndexArg(&inst); + return ir.IAdd(ir.IMul(index, ir.Imm32(stride >> shift)), + ir.Imm32(total_offset >> shift)); + } + } + + // index = (inst_idxen ? vgpr_index : 0) + (const_add_tid_enable ? thread_id[5:0] : 0) + IR::U32 index = ir.Imm32(0U); + if (inst_info.index_enable) { + const IR::U32 vgpr_index = IR::GetBufferIndexArg(&inst); + index = ir.IAdd(index, vgpr_index); + } + if (buffer.add_tid_enable) { + ASSERT_MSG(info.sw_stage == SwStage::Compute, + "Thread ID buffer addressing is not supported outside of compute."); + const IR::U32 thread_id{ir.LaneId()}; + index = ir.IAdd(index, thread_id); + } + // offset = (inst_offen ? vgpr_offset : 0) + inst_offset + IR::U32 offset = ir.Imm32(inst_offset); + offset = ir.IAdd(offset, soffset); + if (inst_info.voffset_enable) { + const IR::U32 voffset = IR::GetBufferVOffsetArg(&inst); + offset = ir.IAdd(offset, voffset); + } + const IR::U32 const_stride = ir.Imm32(stride); + IR::U32 buffer_offset; + if (buffer.swizzle_enable) { + const IR::U32 const_index_stride = ir.Imm32(buffer.GetIndexStride()); + const IR::U32 const_element_size = ir.Imm32(buffer.GetElementSize()); + // index_msb = index / const_index_stride + const IR::U32 index_msb{ir.IDiv(index, const_index_stride)}; + // index_lsb = index % const_index_stride + const IR::U32 index_lsb{ir.IMod(index, const_index_stride)}; + // offset_msb = offset / const_element_size + const IR::U32 offset_msb{ir.IDiv(offset, const_element_size)}; + // offset_lsb = offset % const_element_size + const IR::U32 offset_lsb{ir.IMod(offset, const_element_size)}; + // buffer_offset = + // (index_msb * const_stride + offset_msb * const_element_size) * const_index_stride + // + index_lsb * const_element_size + offset_lsb + const IR::U32 buffer_offset_msb = ir.IMul( + ir.IAdd(ir.IMul(index_msb, const_stride), ir.IMul(offset_msb, const_element_size)), + const_index_stride); + const IR::U32 buffer_offset_lsb = + ir.IAdd(ir.IMul(index_lsb, const_element_size), offset_lsb); + buffer_offset = ir.IAdd(buffer_offset_msb, buffer_offset_lsb); + } else { + // buffer_offset = index * const_stride + offset + buffer_offset = ir.IAdd(ir.IMul(index, const_stride), offset); + } + if (shift != 0) { + buffer_offset = ir.ShiftRightLogical(buffer_offset, ir.Imm32(shift)); + } + return buffer_offset; +} + +void PatchBufferArgs(IR::Inst& inst, Info& info) { + const auto handle = inst.Arg(0); + const auto buffer_res = info.buffers[handle.U32()]; + const auto buffer = buffer_res.GetSharp(info); + + // Address of constant buffer reads can be calculated at IR emission time. + if (inst.GetOpcode() == IR::Opcode::ReadConstBuffer) { + return; + } + + IR::IREmitter ir{*inst.GetParent(), IR::Block::InstructionList::s_iterator_to(inst)}; + inst.SetArg(IR::LoadBufferArgs::Address, + CalculateBufferAddress(ir, inst, info, buffer, buffer.stride)); +} + +IR::Value FixCubeCoords(IR::IREmitter& ir, const AmdGpu::Image& image, const IR::Value& x, + const IR::Value& y, const IR::Value& face) { + if (!image.IsCube()) { + return ir.CompositeConstruct(x, y, face); + } + // AMD cube math results in coordinates in the range [1.0, 2.0]. We need + // to convert this to the range [0.0, 1.0] to get correct results. + const auto fixed_x = ir.FPSub(IR::F32{x}, ir.Imm32(1.f)); + const auto fixed_y = ir.FPSub(IR::F32{y}, ir.Imm32(1.f)); + const auto fixed_face = + ir.FPFma(ir.FPFloor(ir.FPDiv(IR::F32{face}, ir.Imm32(8.f))), ir.Imm32(-2.f), IR::F32{face}); + return ir.CompositeConstruct(fixed_x, fixed_y, fixed_face); +} + +void PatchImageSampleArgs(IR::Inst& inst, Info& info, const ImageResource& image_res, + const AmdGpu::Image& image) { + const auto handle = inst.Arg(0); + const auto& sampler_res = info.samplers[(handle.U32() >> 16) & 0xFFFF]; + const auto sampler = sampler_res.GetSharp(info); + + IR::IREmitter ir{*inst.GetParent(), IR::Block::InstructionList::s_iterator_to(inst)}; + const auto inst_info = inst.Flags(); + const auto view_type = image.GetViewType(image_res.is_array); + + IR::Inst* body1 = inst.Arg(2).Inst(); + IR::Inst* body2 = inst.Arg(3).Inst(); + IR::Inst* body3 = inst.Arg(4).Inst(); + IR::F32 body4 = IR::F32{inst.Arg(5)}; + const auto get_addr_reg = [&](u32 index) -> IR::F32 { + if (index <= 3) { + return IR::F32{body1->Arg(index)}; + } + if (index >= 4 && index <= 7) { + return IR::F32{body2->Arg(index - 4)}; + } + if (index >= 8 && index <= 11) { + return IR::F32{body3->Arg(index - 8)}; + } + if (index == 12) { + return body4; + } + UNREACHABLE(); + }; + u32 addr_reg = 0; + + // Load first address components as denoted in 8.2.4 VGPR Usage Sea Islands Series Instruction + // Set Architecture + const IR::Value offset = [&] -> IR::Value { + if (!inst_info.has_offset) { + return IR::U32{}; + } + + // The offsets are six-bit signed integers: X=[5:0], Y=[13:8], and Z=[21:16]. + IR::Value arg = get_addr_reg(addr_reg++); + if (const IR::Inst* offset_inst = arg.TryInst()) { + ASSERT(offset_inst->GetOpcode() == IR::Opcode::BitCastF32U32); + arg = offset_inst->Arg(0); + } + + const auto read = [&](u32 off) -> IR::U32 { + if (arg.IsImmediate()) { + const u32 imm = + arg.Type() == IR::Type::F32 ? std::bit_cast(arg.F32()) : arg.U32(); + const u16 comp = (imm >> off) & 0x3F; + return ir.Imm32(s32(comp << 26) >> 26); + } + return ir.BitFieldExtract(IR::U32{arg}, ir.Imm32(off), ir.Imm32(6), true); + }; + + switch (view_type) { + case AmdGpu::ImageType::Color1D: + case AmdGpu::ImageType::Color1DArray: + return read(0); + case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color2DMsaa: + case AmdGpu::ImageType::Color2DArray: + return ir.CompositeConstruct(read(0), read(8)); + case AmdGpu::ImageType::Color3D: + return ir.CompositeConstruct(read(0), read(8), read(16)); + default: + UNREACHABLE(); + } + }(); + const IR::F32 bias = inst_info.has_bias ? get_addr_reg(addr_reg++) : IR::F32{}; + const IR::F32 dref = inst_info.is_depth ? get_addr_reg(addr_reg++) : IR::F32{}; + const auto [derivatives_dx, derivatives_dy] = [&] -> std::pair { + if (!inst_info.has_derivatives) { + return {}; + } + switch (view_type) { + case AmdGpu::ImageType::Color1D: + case AmdGpu::ImageType::Color1DArray: + // du/dx, du/dy + addr_reg = addr_reg + 2; + return {get_addr_reg(addr_reg - 2), get_addr_reg(addr_reg - 1)}; + case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color2DMsaa: + case AmdGpu::ImageType::Color2DArray: + // (du/dx, dv/dx), (du/dy, dv/dy) + addr_reg = addr_reg + 4; + return {ir.CompositeConstruct(get_addr_reg(addr_reg - 4), get_addr_reg(addr_reg - 3)), + ir.CompositeConstruct(get_addr_reg(addr_reg - 2), get_addr_reg(addr_reg - 1))}; + case AmdGpu::ImageType::Color3D: + // (du/dx, dv/dx, dw/dx), (du/dy, dv/dy, dw/dy) + addr_reg = addr_reg + 6; + return {ir.CompositeConstruct(get_addr_reg(addr_reg - 6), get_addr_reg(addr_reg - 5), + get_addr_reg(addr_reg - 4)), + ir.CompositeConstruct(get_addr_reg(addr_reg - 3), get_addr_reg(addr_reg - 2), + get_addr_reg(addr_reg - 1))}; + default: + UNREACHABLE(); + } + }(); + + const bool is_msaa = view_type == AmdGpu::ImageType::Color2DMsaa || + view_type == AmdGpu::ImageType::Color2DMsaaArray; + const bool unnormalized = sampler.force_unnormalized || inst_info.is_unnormalized; + const bool needs_dimentions = (!is_msaa && unnormalized) || (is_msaa && !unnormalized); + const auto dimensions = + needs_dimentions ? ir.ImageQueryDimension(handle, ir.Imm32(0u), ir.Imm1(false), inst_info) + : IR::Value{}; + const auto get_coord = [&](u32 coord_idx, u32 dim_idx) -> IR::Value { + const auto coord = get_addr_reg(coord_idx); + if (is_msaa) { + // For MSAA images preserve the unnormalized coord or manually unnormalize it + if (unnormalized) { + return ir.ConvertFToU(32, coord); + } else { + const auto dim = + ir.ConvertUToF(32, 32, IR::U32{ir.CompositeExtract(dimensions, dim_idx)}); + return ir.ConvertFToU(32, ir.FPMul(coord, dim)); + } + } + if (unnormalized) { + // Normalize the coordinate for sampling, dividing by its corresponding dimension. + const auto dim = + ir.ConvertUToF(32, 32, IR::U32{ir.CompositeExtract(dimensions, dim_idx)}); + return ir.FPDiv(coord, dim); + } + return coord; + }; + + // Now we can load body components as noted in Table 8.9 Image Opcodes with Sampler + const IR::Value coords = [&] -> IR::Value { + switch (view_type) { + case AmdGpu::ImageType::Color1D: // x + addr_reg = addr_reg + 1; + return get_coord(addr_reg - 1, 0); + case AmdGpu::ImageType::Color1DArray: // x, slice + case AmdGpu::ImageType::Color2D: // x, y + case AmdGpu::ImageType::Color2DMsaa: // x, y + addr_reg = addr_reg + 2; + return ir.CompositeConstruct(get_coord(addr_reg - 2, 0), get_coord(addr_reg - 1, 1)); + case AmdGpu::ImageType::Color2DArray: // x, y, slice + addr_reg = addr_reg + 3; + // Note we can use FixCubeCoords with fallthrough cases since it checks for image type. + return FixCubeCoords(ir, image, get_coord(addr_reg - 3, 0), get_coord(addr_reg - 2, 1), + get_addr_reg(addr_reg - 1)); + case AmdGpu::ImageType::Color3D: // x, y, z + addr_reg = addr_reg + 3; + return ir.CompositeConstruct(get_coord(addr_reg - 3, 0), get_coord(addr_reg - 2, 1), + get_coord(addr_reg - 1, 2)); + default: + UNREACHABLE(); + } + }(); + + ASSERT(!inst_info.has_lod || !inst_info.has_lod_clamp); + const bool explicit_lod = inst_info.has_lod || inst_info.force_level0; + const IR::F32 lod = inst_info.has_lod ? get_addr_reg(addr_reg++) + : inst_info.force_level0 ? ir.Imm32(0.0f) + : IR::F32{}; + const IR::F32 lod_clamp = inst_info.has_lod_clamp ? get_addr_reg(addr_reg++) : IR::F32{}; + + auto texel = [&] -> IR::Value { + if (is_msaa) { + return ir.ImageRead(handle, coords, {}, ir.Imm32(0U), inst_info); + } + if (inst_info.is_gather) { + if (inst_info.is_depth) { + return ir.ImageGatherDref(handle, coords, offset, dref, inst_info); + } + return ir.ImageGather(handle, coords, offset, inst_info); + } + if (inst_info.has_derivatives) { + return ir.ImageGradient(handle, coords, derivatives_dx, derivatives_dy, offset, + lod_clamp, inst_info); + } + if (inst_info.is_depth) { + if (explicit_lod) { + return ir.ImageSampleDrefExplicitLod(handle, coords, dref, lod, offset, inst_info); + } + return ir.ImageSampleDrefImplicitLod(handle, coords, dref, bias, offset, inst_info); + } + if (explicit_lod) { + return ir.ImageSampleExplicitLod(handle, coords, lod, offset, inst_info); + } + return ir.ImageSampleImplicitLod(handle, coords, bias, offset, inst_info); + }(); + + auto converted = ApplyReadNumberConversionVec4(ir, texel, image.GetNumberConversion()); + if (sampler.force_degamma && image.GetNumberFmt() != AmdGpu::NumberFormat::Srgb) { + converted = ApplyForceDegamma(ir, texel); + } + inst.ReplaceUsesWith(converted); +} + +void PatchImageArgs(IR::Inst& inst, Info& info) { + // Nothing to patch for dimension query. + if (inst.GetOpcode() == IR::Opcode::ImageQueryDimensions) { + return; + } + + const auto image_handle = inst.Arg(0); + const auto binding_index = image_handle.U32() & 0xFFFF; + const auto& image_res = info.images[binding_index]; + auto image = image_res.GetSharp(info); + + // Sample instructions must be handled separately using address register data. + if (inst.GetOpcode() == IR::Opcode::ImageSampleRaw) { + return PatchImageSampleArgs(inst, info, image_res, image); + } + + IR::IREmitter ir{*inst.GetParent(), IR::Block::InstructionList::s_iterator_to(inst)}; + auto inst_info = inst.Flags(); + const auto view_type = image.GetViewType(image_res.is_array); + + // Now that we know the image type, adjust texture coordinate vector. + IR::Inst* body = inst.Arg(1).Inst(); + const auto [coords, arg] = [&] -> std::pair { + switch (view_type) { + case AmdGpu::ImageType::Color1D: // x, [lod] + return {body->Arg(0), body->Arg(1)}; + case AmdGpu::ImageType::Color1DArray: // x, slice, [lod] + case AmdGpu::ImageType::Color2D: // x, y, [lod] + return {ir.CompositeConstruct(body->Arg(0), body->Arg(1)), body->Arg(2)}; + case AmdGpu::ImageType::Color2DMsaa: // x, y. (sample is passed on different argument) + { + auto skip_lod = false; + if (inst_info.has_lod) { + const auto mipid = body->Arg(2); + if (mipid.IsImmediate() && mipid.U32() == 0) { + // if image_x_mip refers to a MSAA image, and mipid is 0, it is safe to be + // skipped and fragid is taken from the next arg + LOG_WARNING(Render_Recompiler, "Encountered a _mip instruction with MSAA " + "image, and mipid is 0, skipping LoD"); + inst_info.has_lod.Assign(false); + skip_lod = true; + } else { + UNREACHABLE_MSG( + "Encountered a _mip instruction with MSAA image, and mipid is non-zero"); + } + } + return {ir.CompositeConstruct(body->Arg(0), body->Arg(1)), body->Arg(skip_lod ? 3 : 2)}; + } + case AmdGpu::ImageType::Color2DArray: // x, y, slice, [lod] + case AmdGpu::ImageType::Color2DMsaaArray: // x, y, slice. (sample is passed on different + // argument) + case AmdGpu::ImageType::Color3D: // x, y, z, [lod] + return {ir.CompositeConstruct(body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)}; + default: + UNREACHABLE_MSG("Unknown image type {}", view_type); + } + }(); + + const auto has_ms = view_type == AmdGpu::ImageType::Color2DMsaa || + view_type == AmdGpu::ImageType::Color2DMsaaArray; + ASSERT(!inst_info.has_lod || !has_ms); + // If we are binding a single mip level as fallback, drop the argument + const auto lod = + (inst_info.has_lod && image_res.mip_fallback_mode != MipStorageFallbackMode::ConstantIndex) + ? IR::U32{arg} + : IR::U32{}; + const auto ms = has_ms ? IR::U32{arg} : IR::U32{}; + + const auto is_storage = image_res.is_written; + if (inst.GetOpcode() == IR::Opcode::ImageRead) { + auto texel = ir.ImageRead(image_handle, coords, lod, ms, inst_info); + if (is_storage) { + // Storage image requires shader swizzle. + texel = ApplySwizzle(ir, texel, image.DstSelect()); + } + const auto converted = + ApplyReadNumberConversionVec4(ir, texel, image.GetNumberConversion()); + inst.ReplaceUsesWith(converted); + } else { + inst.SetArg(1, coords); + if (inst.GetOpcode() == IR::Opcode::ImageWrite) { + inst.SetArg(2, lod); + inst.SetArg(3, ms); + + auto texel = inst.Arg(4); + if (is_storage) { + // Storage image requires shader swizzle. + texel = ApplySwizzle(ir, texel, image.DstSelect().Inverse()); + } + const auto converted = + ApplyWriteNumberConversionVec4(ir, texel, image.GetNumberConversion()); + inst.SetArg(4, converted); + } + } +} + +void ResourcePatchingPass(Shader::Info& info, const ResourceDiscoveryList& resources, + const Profile& profile) { + // Iterate over discovered resources and patch them after finding the sharp. + // Pass 1: Track resource sharps + Descriptors descriptors{info}; + for (const auto& usage : resources) { + IR::Inst& inst = *usage.user; + if (IsBufferInstruction(inst)) { + PatchBufferSharp(usage, info, descriptors, profile); + } else if (IsImageInstruction(inst)) { + PatchImageSharp(usage, info, descriptors, profile); + } + } + + // Pass 2: Patch instruction args + for (const auto& usage : resources) { + IR::Inst& inst = *usage.user; + if (IsBufferInstruction(inst)) { + PatchBufferArgs(inst, info); + } else if (IsImageInstruction(inst)) { + PatchImageArgs(inst, info); + } else if (IsDataRingInstruction(inst)) { + PatchGlobalDataShareAccess(inst, info, descriptors, profile); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/ring_access_elimination.cpp b/gpu/shadps4/shader_recompiler/ir/passes/ring_access_elimination.cpp new file mode 100644 index 0000000..a58e921 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/ring_access_elimination.cpp @@ -0,0 +1,163 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/operand_helper.h" +#include "shader_recompiler/ir/position.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/recompiler.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::Optimization { + +void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info) { + auto& info = program.info; + + const auto& ForEachInstruction = [&](auto func) { + for (IR::Block* block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + func(ir, inst); + } + } + }; + + switch (program.info.hw_stage) { + case HwStage::Local: { + ForEachInstruction([=](IR::IREmitter& ir, IR::Inst& inst) { + const auto opcode = inst.GetOpcode(); + switch (opcode) { + case IR::Opcode::WriteSharedU64: + case IR::Opcode::WriteSharedU32: { + bool is_composite = opcode == IR::Opcode::WriteSharedU64; + u32 num_components = opcode == IR::Opcode::WriteSharedU32 ? 1 : 2; + + ASSERT(inst.Arg(0).IsImmediate()); + + u32 offset = inst.Arg(0).U32(); + IR::Value data = + is_composite ? ir.UnpackUint2x32(IR::U64{inst.Arg(1)}) : inst.Arg(1); + for (s32 i = 0; i < num_components; i++) { + const auto attrib = IR::Attribute::Param0 + (offset / 16); + const auto comp = (offset / 4) % 4; + const IR::U32 value = + IR::U32{is_composite ? ir.CompositeExtract(data, i) : data}; + ir.SetAttribute(attrib, ir.BitCast(value), comp); + offset += 4; + } + inst.Invalidate(); + break; + } + default: + break; + } + }); + break; + } + case HwStage::Export: { + ForEachInstruction([=](IR::IREmitter& ir, IR::Inst& inst) { + const auto opcode = inst.GetOpcode(); + switch (opcode) { + case IR::Opcode::StoreBufferU32: { + const auto info = inst.Flags(); + if (!info.system_coherent || !info.globally_coherent) { + break; + } + + const auto offset = inst.Flags().inst_offset.Value(); + ASSERT(offset < runtime_info.hw.es.vertex_data_size * 4); + const auto data = ir.BitCast(IR::U32{inst.Arg(2)}); + const auto attrib = + IR::Value{offset < 16 ? IR::Attribute::Position0 + : IR::Attribute::Param0 + (offset / 16 - 1)}; + const u32 comp = (offset / 4) % 4; + + inst.ReplaceOpcode(IR::Opcode::SetAttribute); + inst.ClearArgs(); + inst.SetArg(0, attrib); + inst.SetArg(1, data); + inst.SetArg(2, ir.Imm32(comp)); + break; + } + default: + break; + } + }); + break; + } + case HwStage::Geometry: { + const auto& gs_info = runtime_info.hw.gs; + info.gs_copy_data = Shader::ParseCopyShader(gs_info.vs_copy); + + u32 dwords_per_vertex = gs_info.out_vertex_data_size; + if (info.gs_copy_data.num_comps && info.gs_copy_data.num_comps > dwords_per_vertex) { + LOG_WARNING(Render_Vulkan, + "VERT_ITEMSIZE {} is different than actual number of dwords per vertex {}", + dwords_per_vertex, info.gs_copy_data.num_comps); + dwords_per_vertex = info.gs_copy_data.num_comps; + } + + ForEachInstruction([&](IR::IREmitter& ir, IR::Inst& inst) { + const auto opcode = inst.GetOpcode(); + switch (opcode) { + case IR::Opcode::LoadBufferU32: { + const auto info = inst.Flags(); + if (!info.system_coherent || !info.globally_coherent) { + break; + } + + const auto vertex_id = (info.index_enable ? IR::GetBufferIndexArg(&inst) + : IR::GetBufferVOffsetArg(&inst)) + .U32() >> + 2; + const auto soffset = IR::GetBufferSOffsetArg(&inst); + const auto bucket = soffset.U32() / 256u; + const auto attrib = bucket < 4 ? IR::Attribute::Position0 + : IR::Attribute::Param0 + (bucket / 4 - 1); + const auto comp = bucket % 4; + + auto attr_value = ir.GetAttribute(attrib, comp, vertex_id); + inst.ReplaceOpcode(IR::Opcode::BitCastU32F32); + inst.ClearArgs(); + inst.SetArg(0, attr_value); + break; + } + case IR::Opcode::StoreBufferU32: { + const auto buffer_info = inst.Flags(); + if (!buffer_info.system_coherent || !buffer_info.globally_coherent) { + break; + } + + const auto offset = inst.Flags().inst_offset.Value(); + const auto data = ir.BitCast(IR::U32{inst.Arg(2)}); + const auto comp_ofs = info.gs_copy_data.output_vertices * sizeof(u32); + const auto output_size = gs_info.output_vertices * dwords_per_vertex * sizeof(u32); + + const auto vc_read_ofs = (((offset / comp_ofs) * comp_ofs) % output_size) * 16u; + const auto& it = info.gs_copy_data.attr_map.find(vc_read_ofs); + ASSERT(it != info.gs_copy_data.attr_map.cend()); + const auto& [attr, comp] = it->second; + + inst.Invalidate(); + if (IsPosition(attr)) { + ExportPosition(ir, gs_info, false, attr, comp, data); + } else { + ir.SetAttribute(attr, data, comp); + } + break; + } + default: + break; + } + }); + break; + } + default: + break; + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/shader_info_collection_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/shader_info_collection_pass.cpp new file mode 100644 index 0000000..d1caefd --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/shader_info_collection_pass.cpp @@ -0,0 +1,199 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/emulator_settings.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" +#include "video_core/buffer_cache/buffer_cache.h" + +namespace Shader::Optimization { + +void Visit(Info& info, const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::GetAttribute: + case IR::Opcode::GetAttributeU1: + case IR::Opcode::GetAttributeU32: + info.loads.Set(inst.Arg(0).Attribute(), inst.Arg(1).U32()); + break; + case IR::Opcode::SetAttribute: + info.stores.Set(inst.Arg(0).Attribute(), inst.Arg(2).U32()); + break; + case IR::Opcode::GetUserData: + info.ud_mask.Set(inst.Arg(0).ScalarReg()); + break; + case IR::Opcode::SetPatch: { + const auto patch = inst.Arg(0).Patch(); + if (patch <= IR::Patch::TessellationLodBottom) { + info.stores_tess_level_outer = true; + } else if (patch <= IR::Patch::TessellationLodInteriorV) { + info.stores_tess_level_inner = true; + } else { + info.uses_patches |= 1U << IR::GenericPatchIndex(patch); + } + break; + } + case IR::Opcode::GetPatch: { + const auto patch = inst.Arg(0).Patch(); + info.uses_patches |= 1U << IR::GenericPatchIndex(patch); + break; + } + case IR::Opcode::LoadSharedU16: + case IR::Opcode::WriteSharedU16: + info.shared_types |= IR::Type::U16; + break; + case IR::Opcode::LoadSharedU32: + case IR::Opcode::WriteSharedU32: + case IR::Opcode::SharedAtomicIAdd32: + case IR::Opcode::SharedAtomicISub32: + case IR::Opcode::SharedAtomicSMin32: + case IR::Opcode::SharedAtomicUMin32: + case IR::Opcode::SharedAtomicSMax32: + case IR::Opcode::SharedAtomicUMax32: + case IR::Opcode::SharedAtomicInc32: + case IR::Opcode::SharedAtomicDec32: + case IR::Opcode::SharedAtomicAnd32: + case IR::Opcode::SharedAtomicOr32: + case IR::Opcode::SharedAtomicXor32: + case IR::Opcode::SharedAtomicCmpSwap32: + info.shared_types |= IR::Type::U32; + break; + case IR::Opcode::SharedAtomicIAdd64: + case IR::Opcode::SharedAtomicISub64: + case IR::Opcode::SharedAtomicSMin64: + case IR::Opcode::SharedAtomicUMin64: + case IR::Opcode::SharedAtomicSMax64: + case IR::Opcode::SharedAtomicUMax64: + case IR::Opcode::SharedAtomicInc64: + case IR::Opcode::SharedAtomicDec64: + case IR::Opcode::SharedAtomicAnd64: + case IR::Opcode::SharedAtomicOr64: + case IR::Opcode::SharedAtomicXor64: + case IR::Opcode::SharedAtomicCmpSwap64: + info.uses_shared_int64_atomics = true; + [[fallthrough]]; + case IR::Opcode::LoadSharedU64: + case IR::Opcode::WriteSharedU64: + info.shared_types |= IR::Type::U64; + break; + case IR::Opcode::ConvertF16F32: + case IR::Opcode::ConvertF32F16: + case IR::Opcode::BitCastU16F16: + case IR::Opcode::BitCastF16U16: + info.uses_fp16 = true; + break; + case IR::Opcode::PackDouble2x32: + case IR::Opcode::UnpackDouble2x32: + info.uses_fp64 = true; + break; + case IR::Opcode::ImageWrite: + info.has_storage_images = true; + break; + case IR::Opcode::QuadBroadcast: + info.uses_group_quad = true; + break; + case IR::Opcode::Shuffle: + case IR::Opcode::ShuffleXor: + info.uses_group_shuffle = true; + break; + case IR::Opcode::ReadLane: + case IR::Opcode::ReadFirstLane: + case IR::Opcode::WriteLane: + info.uses_group_ballot = true; + break; + case IR::Opcode::Discard: + case IR::Opcode::DiscardCond: + info.has_discard = true; + break; + case IR::Opcode::BitwiseXor32: + info.has_bitwise_xor = true; + break; + case IR::Opcode::ImageGather: + case IR::Opcode::ImageGatherDref: + info.has_image_gather = true; + break; + case IR::Opcode::ImageQueryDimensions: + case IR::Opcode::ImageQueryLod: + info.has_image_query = true; + break; + case IR::Opcode::ImageAtomicFMax32: + case IR::Opcode::ImageAtomicFMin32: + info.uses_image_atomic_float_min_max = true; + break; + case IR::Opcode::BufferAtomicFMax32: + case IR::Opcode::BufferAtomicFMin32: + info.uses_buffer_atomic_float_min_max = true; + break; + case IR::Opcode::BufferAtomicIAdd64: + case IR::Opcode::BufferAtomicSMax64: + case IR::Opcode::BufferAtomicSMin64: + case IR::Opcode::BufferAtomicUMax64: + case IR::Opcode::BufferAtomicUMin64: + info.uses_buffer_int64_atomics = true; + break; + case IR::Opcode::DataAppend: + case IR::Opcode::DataConsume: + case IR::Opcode::Ballot: + case IR::Opcode::InverseBallot: + case IR::Opcode::BallotFindLsb: + info.uses_group_ballot = true; + [[fallthrough]]; + case IR::Opcode::LaneId: + info.uses_lane_id = true; + break; + case IR::Opcode::Memtime: + info.uses_shader_clock = true; + break; + case IR::Opcode::ReadConst: + if (!info.has_readconst) { + info.buffers.push_back({ + .used_types = IR::Type::U32, + .buffer_type = BufferType::Flatbuf, + }); + info.has_readconst = true; + } + if (inst.Flags() == 0) { + info.readconst_types |= Info::ReadConstType::Immediate; + info.readconst_types |= Info::ReadConstType::Dynamic; + info.uses_dma = true; + } + break; + case IR::Opcode::PackUfloat10_11_11: + info.uses_pack_10_11_11 = true; + break; + case IR::Opcode::UnpackUfloat10_11_11: + info.uses_unpack_10_11_11 = true; + break; + default: + break; + } +} + +void CollectShaderInfoPass(IR::Program& program, const Profile& profile) { + Info& info = program.info; + for (IR::Block* const block : program.post_order_blocks) { + for (IR::Inst& inst : block->Instructions()) { + Visit(info, inst); + } + } + + if (!EmulatorSettings.IsDirectMemoryAccessEnabled()) { + info.uses_dma = false; + info.readconst_types = Info::ReadConstType::None; + } + + if (info.uses_dma) { + info.buffers.push_back({ + .used_types = IR::Type::U64, + .buffer_type = BufferType::BdaPagetable, + .is_written = true, + }); + info.buffers.push_back({ + .used_types = IR::Type::U32, + .buffer_type = BufferType::FaultBuffer, + .is_written = true, + }); + LOG_ERROR(Render, "Enabling DMA for shader {:#x}", info.pgm_hash); + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_barrier_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_barrier_pass.cpp new file mode 100644 index 0000000..ba3ffff --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_barrier_pass.cpp @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "shader_recompiler/ir/breadth_first_search.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Optimization { + +static bool IsLoadShared(const IR::Inst& inst) { + return inst.GetOpcode() == IR::Opcode::LoadSharedU16 || + inst.GetOpcode() == IR::Opcode::LoadSharedU32 || + inst.GetOpcode() == IR::Opcode::LoadSharedU64; +} + +static bool IsWriteShared(const IR::Inst& inst) { + const IR::Opcode opcode = inst.GetOpcode(); + if (opcode >= IR::Opcode::SharedAtomicIAdd32 && opcode <= IR::Opcode::SharedAtomicCmpSwap64) { + return !inst.Flags(); + } + return opcode == IR::Opcode::WriteSharedU16 || opcode == IR::Opcode::WriteSharedU32 || + opcode == IR::Opcode::WriteSharedU64; +} + +// Inserts barriers when a shared memory write and read occur in the same basic block. +static void EmitBarrierInBlock(IR::Block* block) { + enum class BarrierAction : u32 { + None, + BarrierOnWrite, + BarrierOnRead, + }; + BarrierAction action{}; + for (IR::Inst& inst : block->Instructions()) { + if (IsLoadShared(inst)) { + if (action == BarrierAction::BarrierOnRead) { + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + ir.Barrier(); + } + action = BarrierAction::BarrierOnWrite; + continue; + } + if (IsWriteShared(inst)) { + if (action == BarrierAction::BarrierOnWrite) { + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + ir.Barrier(); + } + action = BarrierAction::BarrierOnRead; + } + } + if (action != BarrierAction::None) { + IR::IREmitter ir{*block, --block->end()}; + ir.Barrier(); + } +} + +using NodeSet = std::unordered_set; + +static void EmitBarrierAtBlockStart(IR::Block* block) { + auto insert_point = std::ranges::find_if_not(block->Instructions(), IR::IsPhi); + IR::IREmitter ir{*block, insert_point}; + ir.Barrier(); +} + +static bool IsDivergent(const IR::U1& cond) { + return IR::BreadthFirstSearch(cond, [](IR::Inst* inst) -> std::optional { + if (inst->GetOpcode() == IR::Opcode::GetAttributeU32 && + inst->Arg(0).Attribute() == IR::Attribute::LocalInvocationId) { + return true; + } + return std::nullopt; + }) == true; +} + +// Inserts a barrier after divergent conditional blocks to avoid undefined +// behavior when some threads write and others read from shared memory. +static void EmitBarrierInMergeBlock(const IR::AbstractSyntaxNode::Data& data, + NodeSet& divergence_end, u32& divergence_depth) { + const IR::U1 cond = data.if_node.cond; + if (IsDivergent(cond)) { + if (divergence_depth == 0) { + EmitBarrierAtBlockStart(data.if_node.merge); + } + ++divergence_depth; + divergence_end.emplace(data.if_node.merge); + } +} + +// A barrier inside a loop is invalid when different invocations leave on different iterations. +// Mark such loops so their shared-memory synchronization can be deferred to the merge block. +static NodeSet FindDivergentLoops(const IR::AbstractSyntaxList& syntax_list) { + NodeSet divergent_loops; + for (const IR::AbstractSyntaxNode& node : syntax_list) { + switch (node.type) { + case IR::AbstractSyntaxNode::Type::Repeat: + if (IsDivergent(node.data.repeat.cond)) { + divergent_loops.emplace(node.data.repeat.merge); + } + break; + case IR::AbstractSyntaxNode::Type::Break: + if (IsDivergent(node.data.break_node.cond)) { + divergent_loops.emplace(node.data.break_node.merge); + } + break; + default: + break; + } + } + return divergent_loops; +} + +static constexpr u32 GcnSubgroupSize = 64; + +void SharedMemoryBarrierPass(IR::Program& program, const RuntimeInfo& runtime_info, + const Profile& profile) { + if (program.info.hw_stage != HwStage::Compute) { + return; + } + const auto& cs_info = runtime_info.hw.cs; + const u32 shared_memory_size = cs_info.shared_memory_size; + const u32 threadgroup_size = + cs_info.workgroup_size[0] * cs_info.workgroup_size[1] * cs_info.workgroup_size[2]; + // The compiler can only omit barriers when the local workgroup size is the same as the HW + // subgroup. + if (shared_memory_size == 0 || threadgroup_size != GcnSubgroupSize || + !profile.needs_lds_barriers) { + return; + } + using Type = IR::AbstractSyntaxNode::Type; + u32 divergence_depth{}; + NodeSet divergence_end; + const NodeSet divergent_loops = FindDivergentLoops(program.syntax_list); + for (const IR::AbstractSyntaxNode& node : program.syntax_list) { + if (node.type == Type::EndIf) { + if (divergence_end.contains(node.data.end_if.merge)) { + --divergence_depth; + } + continue; + } + // Check if branch depth is zero, we don't want to insert barrier in potentially divergent + // code. + if (node.type == Type::If) { + EmitBarrierInMergeBlock(node.data, divergence_end, divergence_depth); + continue; + } + if (node.type == Type::Loop && divergent_loops.contains(node.data.loop.merge)) { + ++divergence_depth; + continue; + } + if (node.type == Type::Repeat && divergent_loops.contains(node.data.repeat.merge)) { + ASSERT(divergence_depth > 0); + --divergence_depth; + if (divergence_depth == 0) { + EmitBarrierAtBlockStart(node.data.repeat.merge); + } + continue; + } + if (node.type == Type::Block && divergence_depth == 0) { + EmitBarrierInBlock(node.data.block); + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_simplify_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_simplify_pass.cpp new file mode 100644 index 0000000..33cee2d --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_simplify_pass.cpp @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Optimization { + +static bool Requires16BitSharedAtomic(const IR::Inst& inst) { + // Nothing yet + return false; +} + +static bool Requires64BitSharedAtomic(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::SharedAtomicIAdd64: + case IR::Opcode::SharedAtomicISub64: + case IR::Opcode::SharedAtomicSMin64: + case IR::Opcode::SharedAtomicUMin64: + case IR::Opcode::SharedAtomicSMax64: + case IR::Opcode::SharedAtomicUMax64: + case IR::Opcode::SharedAtomicInc64: + case IR::Opcode::SharedAtomicDec64: + case IR::Opcode::SharedAtomicAnd64: + case IR::Opcode::SharedAtomicOr64: + case IR::Opcode::SharedAtomicXor64: + case IR::Opcode::SharedAtomicCmpSwap64: + return true; + default: + return false; + } +} + +static bool IsNon32BitSharedLoadStore(const IR::Inst& inst) { + switch (inst.GetOpcode()) { + case IR::Opcode::LoadSharedU16: + case IR::Opcode::LoadSharedU64: + case IR::Opcode::WriteSharedU16: + case IR::Opcode::WriteSharedU64: + return true; + default: + return false; + } +} + +IR::Type CalculateSpecialSharedAtomicTypes(IR::Program& program) { + IR::Type extra_atomic_types{IR::Type::Void}; + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (Requires16BitSharedAtomic(inst)) { + extra_atomic_types |= IR::Type::U16; + } + if (Requires64BitSharedAtomic(inst)) { + extra_atomic_types |= IR::Type::U64; + } + } + } + return extra_atomic_types; +} + +// Simplifies down U16 and U64 shared memory operations to U32 when aliasing is not supported and +// atomics of the same type are not used. +void SharedMemorySimplifyPass(IR::Program& program, const Profile& profile) { + if (program.info.hw_stage != HwStage::Compute || + profile.supports_workgroup_explicit_memory_layout) { + return; + } + + const auto atomic_types = CalculateSpecialSharedAtomicTypes(program); + if (True(atomic_types & IR::Type::U16) && True(atomic_types & IR::Type::U64)) { + // If both other atomic types are used, there is nothing to do. + return; + } + + // Iterate through shared load/store U16/U64 instructions, replacing with + // equivalent U32 ops when the types are not needed for atomics. + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (!IsNon32BitSharedLoadStore(inst)) { + continue; + } + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + const IR::U32 offset{inst.Arg(0)}; + if (False(atomic_types & IR::Type::U16)) { + switch (inst.GetOpcode()) { + case IR::Opcode::LoadSharedU16: { + const IR::U32 dword_offset{ir.BitwiseAnd(offset, ir.Imm32(~3U))}; + const IR::U32 dword_value{ir.LoadShared(32, false, dword_offset)}; + const IR::U32 bit_offset{ + ir.IMul(ir.BitwiseAnd(offset, ir.Imm32(2U)), ir.Imm32(8U))}; + const IR::U32 value{ir.BitFieldExtract(dword_value, bit_offset, ir.Imm32(16U))}; + inst.ReplaceUsesWithAndRemove(ir.UConvert(16, value)); + continue; + } + case IR::Opcode::WriteSharedU16: { + const IR::U32 value{ir.UConvert(32, IR::U16{inst.Arg(1)})}; + const IR::U32 bit_offset{ + ir.IMul(ir.BitwiseAnd(offset, ir.Imm32(2U)), ir.Imm32(8U))}; + const IR::U32 dword_offset{ir.BitwiseAnd(offset, ir.Imm32(~3U))}; + const IR::U32 dword_value{ + ir.LoadShared(32, false, ir.BitwiseAnd(offset, dword_offset))}; + const IR::U32 new_dword_value{ + ir.BitFieldInsert(dword_value, value, bit_offset, ir.Imm32(16U))}; + ir.WriteShared(32, new_dword_value, dword_offset); + inst.Invalidate(); + continue; + } + default: + break; + } + } + if (False(atomic_types & IR::Type::U64)) { + switch (inst.GetOpcode()) { + case IR::Opcode::LoadSharedU64: { + const IR::U32 value0{ir.LoadShared(32, false, offset)}; + const IR::U32 value1{ir.LoadShared(32, false, ir.IAdd(offset, ir.Imm32(4U)))}; + const IR::Value value{ir.PackUint2x32(ir.CompositeConstruct(value0, value1))}; + inst.ReplaceUsesWithAndRemove(value); + continue; + } + case IR::Opcode::WriteSharedU64: { + const IR::Value value{ir.UnpackUint2x32(IR::U64{inst.Arg(1)})}; + const IR::U32 value0{ir.CompositeExtract(value, 0)}; + const IR::U32 value1{ir.CompositeExtract(value, 1)}; + ir.WriteShared(32, value0, offset); + ir.WriteShared(32, value1, ir.IAdd(offset, ir.Imm32(4U))); + inst.Invalidate(); + continue; + } + default: + break; + } + } + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_to_storage_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_to_storage_pass.cpp new file mode 100644 index 0000000..ddb28a2 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/shared_memory_to_storage_pass.cpp @@ -0,0 +1,220 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" + +namespace Shader::Optimization { + +static bool IsSharedAccess(const IR::Inst& inst) { + const auto opcode = inst.GetOpcode(); + switch (opcode) { + case IR::Opcode::LoadSharedU16: + case IR::Opcode::LoadSharedU32: + case IR::Opcode::LoadSharedU64: + case IR::Opcode::WriteSharedU16: + case IR::Opcode::WriteSharedU32: + case IR::Opcode::WriteSharedU64: + case IR::Opcode::SharedAtomicIAdd32: + case IR::Opcode::SharedAtomicISub32: + case IR::Opcode::SharedAtomicSMin32: + case IR::Opcode::SharedAtomicUMin32: + case IR::Opcode::SharedAtomicSMax32: + case IR::Opcode::SharedAtomicUMax32: + case IR::Opcode::SharedAtomicInc32: + case IR::Opcode::SharedAtomicDec32: + case IR::Opcode::SharedAtomicAnd32: + case IR::Opcode::SharedAtomicOr32: + case IR::Opcode::SharedAtomicXor32: + case IR::Opcode::SharedAtomicIAdd64: + case IR::Opcode::SharedAtomicISub64: + case IR::Opcode::SharedAtomicSMin64: + case IR::Opcode::SharedAtomicUMin64: + case IR::Opcode::SharedAtomicSMax64: + case IR::Opcode::SharedAtomicUMax64: + case IR::Opcode::SharedAtomicInc64: + case IR::Opcode::SharedAtomicDec64: + case IR::Opcode::SharedAtomicAnd64: + case IR::Opcode::SharedAtomicOr64: + case IR::Opcode::SharedAtomicXor64: + case IR::Opcode::SharedAtomicCmpSwap32: + case IR::Opcode::SharedAtomicCmpSwap64: + return true; + default: + return false; + } +} + +IR::Type CalculateSharedMemoryTypes(IR::Program& program) { + IR::Type used_types{IR::Type::Void}; + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (!IsSharedAccess(inst)) { + continue; + } + switch (inst.GetOpcode()) { + case IR::Opcode::LoadSharedU16: + case IR::Opcode::WriteSharedU16: + used_types |= IR::Type::U16; + break; + case IR::Opcode::LoadSharedU32: + case IR::Opcode::WriteSharedU32: + case IR::Opcode::SharedAtomicIAdd32: + case IR::Opcode::SharedAtomicISub32: + case IR::Opcode::SharedAtomicSMin32: + case IR::Opcode::SharedAtomicUMin32: + case IR::Opcode::SharedAtomicSMax32: + case IR::Opcode::SharedAtomicUMax32: + case IR::Opcode::SharedAtomicInc32: + case IR::Opcode::SharedAtomicDec32: + case IR::Opcode::SharedAtomicAnd32: + case IR::Opcode::SharedAtomicOr32: + case IR::Opcode::SharedAtomicXor32: + case IR::Opcode::SharedAtomicCmpSwap32: + used_types |= IR::Type::U32; + break; + case IR::Opcode::LoadSharedU64: + case IR::Opcode::WriteSharedU64: + case IR::Opcode::SharedAtomicIAdd64: + case IR::Opcode::SharedAtomicISub64: + case IR::Opcode::SharedAtomicSMin64: + case IR::Opcode::SharedAtomicUMin64: + case IR::Opcode::SharedAtomicSMax64: + case IR::Opcode::SharedAtomicUMax64: + case IR::Opcode::SharedAtomicInc64: + case IR::Opcode::SharedAtomicDec64: + case IR::Opcode::SharedAtomicAnd64: + case IR::Opcode::SharedAtomicOr64: + case IR::Opcode::SharedAtomicXor64: + case IR::Opcode::SharedAtomicCmpSwap64: + used_types |= IR::Type::U64; + break; + default: + break; + } + } + } + return used_types; +} + +void SharedMemoryToStoragePass(IR::Program& program, const RuntimeInfo& runtime_info, + const Profile& profile) { + if (program.info.hw_stage != HwStage::Compute) { + return; + } + + // Run this pass if: + // * There are shared memory instructions. + // * One of the following is true: + // * Requested shared memory size is too large for the host shared memory. + // * Workgroup explicit memory is not supported and multiple shared memory types are used. + const u32 shared_memory_size = runtime_info.hw.cs.shared_memory_size; + const auto used_types = CalculateSharedMemoryTypes(program); + if (used_types == IR::Type::Void || (shared_memory_size <= profile.max_shared_memory_size && + (profile.supports_workgroup_explicit_memory_layout || + std::popcount(static_cast(used_types)) == 1))) { + return; + } + + // Add a buffer binding for shared memory storage buffer. + const u32 binding = static_cast(program.info.buffers.size()); + program.info.buffers.push_back(BufferResource{ + .used_types = used_types, + .buffer_type = BufferType::SharedMemory, + .is_written = true, + }); + + for (IR::Block* const block : program.blocks) { + for (IR::Inst& inst : block->Instructions()) { + if (!IsSharedAccess(inst)) { + continue; + } + IR::IREmitter ir{*block, IR::Block::InstructionList::s_iterator_to(inst)}; + const IR::U32 handle = ir.Imm32(binding); + const IR::U32 offset = ir.IMul(ir.GetAttributeU32(IR::Attribute::WorkgroupIndex), + ir.Imm32(shared_memory_size)); + const IR::U32 address = ir.IAdd(IR::U32{inst.Arg(0)}, offset); + switch (inst.GetOpcode()) { + case IR::Opcode::SharedAtomicIAdd32: + case IR::Opcode::SharedAtomicIAdd64: + inst.ReplaceUsesWithAndRemove( + ir.BufferAtomicIAdd(handle, address, inst.Arg(1), {})); + continue; + case IR::Opcode::SharedAtomicISub32: + case IR::Opcode::SharedAtomicISub64: + inst.ReplaceUsesWithAndRemove( + ir.BufferAtomicISub(handle, address, inst.Arg(1), {})); + continue; + case IR::Opcode::SharedAtomicSMin32: + case IR::Opcode::SharedAtomicUMin32: + case IR::Opcode::SharedAtomicSMin64: + case IR::Opcode::SharedAtomicUMin64: { + const bool is_signed = inst.GetOpcode() == IR::Opcode::SharedAtomicSMin32 || + inst.GetOpcode() == IR::Opcode::SharedAtomicSMin64; + inst.ReplaceUsesWithAndRemove( + ir.BufferAtomicIMin(handle, address, inst.Arg(1), is_signed, {})); + continue; + } + case IR::Opcode::SharedAtomicSMax32: + case IR::Opcode::SharedAtomicUMax32: + case IR::Opcode::SharedAtomicSMax64: + case IR::Opcode::SharedAtomicUMax64: { + const bool is_signed = inst.GetOpcode() == IR::Opcode::SharedAtomicSMax32 || + inst.GetOpcode() == IR::Opcode::SharedAtomicSMax64; + inst.ReplaceUsesWithAndRemove( + ir.BufferAtomicIMax(handle, address, inst.Arg(1), is_signed, {})); + continue; + } + case IR::Opcode::SharedAtomicInc32: + inst.ReplaceUsesWithAndRemove(ir.BufferAtomicInc(handle, address, {})); + continue; + case IR::Opcode::SharedAtomicDec32: + inst.ReplaceUsesWithAndRemove(ir.BufferAtomicDec(handle, address, {})); + continue; + case IR::Opcode::SharedAtomicAnd32: + case IR::Opcode::SharedAtomicAnd64: + inst.ReplaceUsesWithAndRemove(ir.BufferAtomicAnd(handle, address, inst.Arg(1), {})); + continue; + case IR::Opcode::SharedAtomicOr32: + case IR::Opcode::SharedAtomicOr64: + inst.ReplaceUsesWithAndRemove(ir.BufferAtomicOr(handle, address, inst.Arg(1), {})); + continue; + case IR::Opcode::SharedAtomicXor32: + case IR::Opcode::SharedAtomicXor64: + inst.ReplaceUsesWithAndRemove(ir.BufferAtomicXor(handle, address, inst.Arg(1), {})); + continue; + case IR::Opcode::SharedAtomicCmpSwap32: + case IR::Opcode::SharedAtomicCmpSwap64: + inst.ReplaceUsesWithAndRemove( + ir.BufferAtomicCmpSwap(handle, address, inst.Arg(1), inst.Arg(2), {})); + continue; + case IR::Opcode::LoadSharedU16: + inst.ReplaceUsesWithAndRemove(ir.LoadBufferU16(handle, address, {})); + break; + case IR::Opcode::LoadSharedU32: + inst.ReplaceUsesWithAndRemove(ir.LoadBufferU32(1, handle, address, {})); + break; + case IR::Opcode::LoadSharedU64: + inst.ReplaceUsesWithAndRemove(ir.LoadBufferU64(handle, address, {})); + break; + case IR::Opcode::WriteSharedU16: + ir.StoreBufferU16(handle, address, IR::U16{inst.Arg(1)}, {}); + inst.Invalidate(); + break; + case IR::Opcode::WriteSharedU32: + ir.StoreBufferU32(1, handle, address, inst.Arg(1), {}); + inst.Invalidate(); + break; + case IR::Opcode::WriteSharedU64: + ir.StoreBufferU64(handle, address, IR::U64{inst.Arg(1)}, {}); + inst.Invalidate(); + break; + default: + UNREACHABLE(); + } + } + } +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/passes/srt.h b/gpu/shadps4/shader_recompiler/ir/passes/srt.h new file mode 100644 index 0000000..918b832 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/srt.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" + +namespace Serialization { +struct Archive; +} + +namespace Shader { + +using PFN_SrtWalker = void PS4_SYSV_ABI (*)(const u32* /*user_data*/, u32* /*flat_dst*/); +PFN_SrtWalker RegisterWalkerCode(const u8* ptr, size_t size); + +struct PersistentSrtInfo { + // Special case when fetch shader uses step rates. + struct SrtSharpReservation { + u32 sgpr_base; + u32 dword_offset; + u32 num_dwords; + }; + + PFN_SrtWalker walker_func{}; + size_t walker_func_size{}; + u32 flattened_bufsize_dw = 16; // NumUserDataRegs + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& ar); +}; + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/ir/passes/ssa_repair_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/ssa_repair_pass.cpp new file mode 100644 index 0000000..48f36c0 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/ssa_repair_pass.cpp @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/dominance.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader::Optimization { + +void SsaRepairPass(IR::Program& program) { + // Compute dominance on the current CFG + auto& post_order = program.post_order_blocks; + IR::ComputeDominators(post_order); + IR::ComputeDominanceFrontiers(post_order); + + boost::container::small_vector invalid_uses; + for (IR::Block* block : post_order) { + for (IR::Inst& inst : block->Instructions()) { + if (!inst.HasUses()) { + continue; + } + + for (const auto& use : inst.Uses()) { + IR::Block* use_block = use.user->GetParent(); + if (!Dominates(block, use_block)) { + invalid_uses.push_back(use); + } + } + if (invalid_uses.empty()) { + continue; + } + + // Add a store to the virtual register + const IR::VirtualReg reg{program.next_reg_index++, inst.Type()}; + IR::IREmitter ir{*block, ++IR::Block::InstructionList::s_iterator_to(inst)}; + ir.SetVirtualReg(reg, IR::Value{&inst}); + + // Replace all invalid uses with load to virtual register + for (auto& [user, operand] : invalid_uses) { + IR::IREmitter ir{*user->GetParent(), + IR::Block::InstructionList::s_iterator_to(*user)}; + user->SetArg(operand, ir.GetVirtualReg(reg)); + } + + invalid_uses.clear(); + } + } +} + +} // namespace Shader::Optimization \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/passes/ssa_rewrite_pass.cpp b/gpu/shadps4/shader_recompiler/ir/passes/ssa_rewrite_pass.cpp new file mode 100644 index 0000000..fbed36d --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/passes/ssa_rewrite_pass.cpp @@ -0,0 +1,311 @@ +// SPDX-FileCopyrightText: Copyright 2025 Philip Rebohle +// SPDX-License-Identifier: MIT + +// This file implements the SSA rewriting algorithm proposed in +// +// Simple and Efficient Construction of Static Single Assignment Form. +// Braun M., Buchwald S., Hack S., Leiba 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 +// + +#include +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::Optimization { +namespace { + +using RegType = IR::RegType; +using ValueMap = std::unordered_map; + +struct DefTable { + const IR::Value& Def(IR::Block* block, IR::RegTag tag) { + if (tag.IsIntrusive()) { + return block->ssa_state.values[tag.Index()]; + } + switch (tag.type) { + case RegType::GotoVariable: + return goto_vars[tag.index][block]; + case RegType::VirtualReg: + return reg_vars[tag.reg.Key()][block]; + default: + UNREACHABLE(); + } + } + void SetDef(IR::Block* block, IR::RegTag tag, const IR::Value& value) { + if (tag.IsIntrusive()) { + block->ssa_state.values[tag.Index()] = value; + return; + } + switch (tag.type) { + case RegType::GotoVariable: + goto_vars[tag.index].insert_or_assign(block, value); + return; + case RegType::VirtualReg: + reg_vars[tag.reg.Key()].insert_or_assign(block, value); + return; + default: + UNREACHABLE(); + } + } + + std::unordered_map goto_vars; + std::unordered_map reg_vars; +}; + +constexpr IR::Type TypeOf(IR::RegTag tag) noexcept { + switch (tag.type) { + case RegType::ScalarReg: + case RegType::VectorReg: + case RegType::VccLo: + case RegType::VccHi: + case RegType::M0: + return IR::Type::U32; + case RegType::Scc: + case RegType::Exec: + case RegType::GotoVariable: + return IR::Type::U1; + case RegType::VirtualReg: + return tag.reg.type; + default: + UNREACHABLE(); + } +} + +constexpr IR::Opcode UndefOpcode(IR::RegTag tag) noexcept { + switch (tag.type) { + case RegType::ScalarReg: + case RegType::VectorReg: + case RegType::VccLo: + case RegType::VccHi: + case RegType::M0: + return IR::Opcode::UndefU32; + case RegType::Scc: + case RegType::Exec: + case RegType::GotoVariable: + return IR::Opcode::UndefU1; + case RegType::VirtualReg: + switch (tag.reg.type) { + case IR::Type::U64: + return IR::Opcode::UndefU64; + case IR::Type::U32: + return IR::Opcode::UndefU32; + case IR::Type::U32x2: + return IR::Opcode::UndefU32x2; + case IR::Type::U32x3: + return IR::Opcode::UndefU32x3; + case IR::Type::U32x4: + return IR::Opcode::UndefU32x4; + case IR::Type::F32: + return IR::Opcode::UndefF32; + case IR::Type::U1: + return IR::Opcode::UndefU1; + default: + UNREACHABLE_MSG("Unknown virtual reg type {}", tag.reg.type); + } + default: + UNREACHABLE_MSG("Unknown reg type {}", magic_enum::enum_name(tag.type)); + } +} + +class Pass { +public: + void WriteVariable(IR::RegTag tag, IR::Block* block, const IR::Value& value) { + current_def.SetDef(block, tag, value); + } + + IR::Value ReadVariable(IR::RegTag tag, IR::Block* block) { + boost::container::small_vector chain; + IR::Value result{}; + + while (block) { + if (const IR::Value& def = current_def.Def(block, tag); !def.IsEmpty()) { + result = def; + break; + } + + const auto preds = block->ImmPredecessors(); + if (preds.size() == 1) { + // Optimize the common case of one predecessor: no phi needed + chain.push_back(std::exchange(block, preds.front())); + continue; + } else if (preds.empty()) { + result = IR::Value{&*block->PrependNewInst(block->begin(), UndefOpcode(tag))}; + WriteVariable(tag, block, result); + break; + } + + // This is a join block which may require a phi. + // That will act as the variables current definition to break potential cycles. + IR::Inst* const phi{&*block->PrependNewInst(block->begin(), IR::Opcode::Phi)}; + phi->SetFlags(TypeOf(tag)); + phi->SetRegTag(tag); + + result = IR::Value{phi}; + WriteVariable(tag, block, result); + m_pending_phis.push_back(phi); + break; + } + + for (auto it = chain.rbegin(); it != chain.rend(); ++it) { + WriteVariable(tag, *it, result); + } + + return result; + } + + void EvaluatePendingPhis() { + for (size_t i = 0; i < m_pending_phis.size(); i++) { + IR::Inst* phi = m_pending_phis[i]; + for (IR::Block* pred : phi->GetParent()->ImmPredecessors()) { + phi->AddPhiOperand(pred, ReadVariable(phi->GetRegTag(), pred)); + } + } + } + + void ResolveTrivialPhis() { + auto worklist = std::move(m_pending_phis); + while (!worklist.empty()) { + IR::Inst* phi = worklist.back(); + worklist.pop_back(); + + if (phi->GetOpcode() == IR::Opcode::Void) { + continue; + } + + IR::Value same; + bool non_trivial = false; + for (size_t i = 0; i < phi->NumArgs(); ++i) { + const IR::Value op{phi->Arg(i)}; + if (op == same || op == IR::Value{phi}) { + // Unique value or self-reference + continue; + } + if (!same.IsEmpty()) { + // The phi merges at least two values: not trivial + non_trivial = true; + break; + } + same = op; + } + if (non_trivial) { + continue; + } + + IR::Block* block = phi->GetParent(); + if (same.IsEmpty()) { + // All operands are self-references or phi has no operands + auto& list = block->Instructions(); + auto reinsert_point = std::ranges::find_if_not(list, IR::IsPhi); + same = IR::Value{ + &*block->PrependNewInst(reinsert_point, UndefOpcode(phi->GetRegTag()))}; + } + + // Add phi users to worklist since they may have become trivial + for (const auto& [user, operand] : phi->Uses()) { + if (user->GetOpcode() == IR::Opcode::Phi && user != phi) { + worklist.push_back(user); + } + } + phi->ReplaceUsesWithAndRemove(same); + auto it = IR::Block::InstructionList::s_iterator_to(*phi); + block->Instructions().erase(it); + } + } + +private: + DefTable current_def; + std::vector m_pending_phis; +}; + +void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { + const IR::Opcode opcode{inst.GetOpcode()}; + switch (opcode) { + case IR::Opcode::SetScalarRegister: + pass.WriteVariable(IR::RegTag{inst.Arg(0).ScalarReg()}, block, inst.Arg(1)); + break; + case IR::Opcode::SetVectorRegister: + pass.WriteVariable(IR::RegTag{inst.Arg(0).VectorReg()}, block, inst.Arg(1)); + break; + case IR::Opcode::SetVirtualRegister: + pass.WriteVariable(IR::RegTag{inst.Arg(0).VirtualReg()}, block, inst.Arg(1)); + break; + case IR::Opcode::SetGotoVariable: + pass.WriteVariable(IR::RegTag{RegType::GotoVariable, inst.Arg(0).U32()}, block, + inst.Arg(1)); + break; + case IR::Opcode::SetExec: + pass.WriteVariable(IR::RegTag{RegType::Exec}, block, inst.Arg(0)); + break; + case IR::Opcode::SetScc: + pass.WriteVariable(IR::RegTag{RegType::Scc}, block, inst.Arg(0)); + break; + case IR::Opcode::SetVccLo: + pass.WriteVariable(IR::RegTag{RegType::VccLo}, block, inst.Arg(0)); + break; + case IR::Opcode::SetVccHi: + pass.WriteVariable(IR::RegTag{RegType::VccHi}, block, inst.Arg(0)); + break; + case IR::Opcode::SetM0: + pass.WriteVariable(IR::RegTag{RegType::M0}, block, inst.Arg(0)); + break; + case IR::Opcode::GetScalarRegister: + inst.ReplaceUsesWithAndRemove( + pass.ReadVariable(IR::RegTag{inst.Arg(0).ScalarReg()}, block)); + break; + case IR::Opcode::GetVectorRegister: + inst.ReplaceUsesWithAndRemove( + pass.ReadVariable(IR::RegTag{inst.Arg(0).VectorReg()}, block)); + break; + case IR::Opcode::GetVirtualRegister: + inst.ReplaceUsesWithAndRemove( + pass.ReadVariable(IR::RegTag{inst.Arg(0).VirtualReg()}, block)); + break; + case IR::Opcode::GetGotoVariable: + inst.ReplaceUsesWithAndRemove( + pass.ReadVariable(IR::RegTag{RegType::GotoVariable, inst.Arg(0).U32()}, block)); + break; + case IR::Opcode::GetExec: + inst.ReplaceUsesWithAndRemove(pass.ReadVariable(IR::RegTag{RegType::Exec}, block)); + break; + case IR::Opcode::GetScc: + inst.ReplaceUsesWithAndRemove(pass.ReadVariable(IR::RegTag{RegType::Scc}, block)); + break; + case IR::Opcode::GetVccLo: + inst.ReplaceUsesWithAndRemove(pass.ReadVariable(IR::RegTag{RegType::VccLo}, block)); + break; + case IR::Opcode::GetVccHi: + inst.ReplaceUsesWithAndRemove(pass.ReadVariable(IR::RegTag{RegType::VccHi}, block)); + break; + case IR::Opcode::GetM0: + inst.ReplaceUsesWithAndRemove(pass.ReadVariable(IR::RegTag{RegType::M0}, block)); + break; + default: + break; + } +} + +} // Anonymous namespace + +void SsaRewritePass(IR::Program& program) { + Pass pass; + const auto end = program.post_order_blocks.rend(); + for (auto it = program.post_order_blocks.rbegin(); it != end; ++it) { + IR::Block* block{*it}; + for (IR::Inst& inst : block->Instructions()) { + VisitInst(pass, block, inst); + } + } + pass.EvaluatePendingPhis(); + pass.ResolveTrivialPhis(); +} + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/patch.cpp b/gpu/shadps4/shader_recompiler/ir/patch.cpp new file mode 100644 index 0000000..2485bc5 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/patch.cpp @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/patch.h" + +namespace Shader::IR { + +std::string NameOf(Patch patch) { + switch (patch) { + case Patch::TessellationLodLeft: + return "TessellationLodLeft"; + case Patch::TessellationLodTop: + return "TessellationLodTop"; + case Patch::TessellationLodRight: + return "TessellationLodRight"; + case Patch::TessellationLodBottom: + return "TessellationLodBottom"; + case Patch::TessellationLodInteriorU: + return "TessellationLodInteriorU"; + case Patch::TessellationLodInteriorV: + return "TessellationLodInteriorV"; + default: + const u32 index = u32(patch) - u32(Patch::Component0); + return fmt::format("Component{}", index); + } +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/patch.h b/gpu/shadps4/shader_recompiler/ir/patch.h new file mode 100644 index 0000000..65d2192 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/patch.h @@ -0,0 +1,173 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace Shader::IR { + +enum class Patch : u64 { + TessellationLodLeft, + TessellationLodTop, + TessellationLodRight, + TessellationLodBottom, + TessellationLodInteriorU, + TessellationLodInteriorV, + Component0, + Component1, + Component2, + Component3, + Component4, + Component5, + Component6, + Component7, + Component8, + Component9, + Component10, + Component11, + Component12, + Component13, + Component14, + Component15, + Component16, + Component17, + Component18, + Component19, + Component20, + Component21, + Component22, + Component23, + Component24, + Component25, + Component26, + Component27, + Component28, + Component29, + Component30, + Component31, + Component32, + Component33, + Component34, + Component35, + Component36, + Component37, + Component38, + Component39, + Component40, + Component41, + Component42, + Component43, + Component44, + Component45, + Component46, + Component47, + Component48, + Component49, + Component50, + Component51, + Component52, + Component53, + Component54, + Component55, + Component56, + Component57, + Component58, + Component59, + Component60, + Component61, + Component62, + Component63, + Component64, + Component65, + Component66, + Component67, + Component68, + Component69, + Component70, + Component71, + Component72, + Component73, + Component74, + Component75, + Component76, + Component77, + Component78, + Component79, + Component80, + Component81, + Component82, + Component83, + Component84, + Component85, + Component86, + Component87, + Component88, + Component89, + Component90, + Component91, + Component92, + Component93, + Component94, + Component95, + Component96, + Component97, + Component98, + Component99, + Component100, + Component101, + Component102, + Component103, + Component104, + Component105, + Component106, + Component107, + Component108, + Component109, + Component110, + Component111, + Component112, + Component113, + Component114, + Component115, + Component116, + Component117, + Component118, + Component119, +}; +static_assert(static_cast(Patch::Component119) == 125); + +constexpr bool IsGeneric(Patch patch) noexcept { + return patch >= Patch::Component0 && patch <= Patch::Component119; +} + +constexpr Patch PatchFactor(u32 index) { + return static_cast(index); +} + +constexpr Patch PatchGeneric(u32 index) { + return static_cast(static_cast(Patch::Component0) + index); +} + +constexpr u32 GenericPatchIndex(Patch patch) { + return (static_cast(patch) - static_cast(Patch::Component0)) / 4; +} + +constexpr u32 GenericPatchElement(Patch patch) { + return (static_cast(patch) - static_cast(Patch::Component0)) % 4; +} + +[[nodiscard]] std::string NameOf(Patch patch); + +} // namespace Shader::IR + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(const Shader::IR::Patch patch, format_context& ctx) const { + return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(patch)); + } +}; diff --git a/gpu/shadps4/shader_recompiler/ir/pattern_matching.h b/gpu/shadps4/shader_recompiler/ir/pattern_matching.h new file mode 100644 index 0000000..df3644c --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/pattern_matching.h @@ -0,0 +1,129 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::Optimiation::PatternMatching { + +// Attempt at pattern matching for Insts and Values +// Needs improvement, mostly a convenience + +template +struct MatchObject { + inline bool Match(IR::Value v) { + return static_cast(this)->Match(v); + } +}; + +struct MatchValue : MatchObject { + MatchValue(IR::Value& return_val_) : return_val(return_val_) {} + + inline bool Match(IR::Value v) { + return_val = v; + return true; + } + +private: + IR::Value& return_val; +}; + +struct MatchIgnore : MatchObject { + MatchIgnore() {} + + inline bool Match(IR::Value v) { + return true; + } +}; + +struct MatchImm : MatchObject { + MatchImm(IR::Value& v) : return_val(v) {} + + inline bool Match(IR::Value v) { + if (!v.IsImmediate()) { + return false; + } + + return_val = v; + return true; + } + +private: + IR::Value& return_val; +}; + +struct MatchAttribute : MatchObject { + MatchAttribute(IR::Attribute attribute_) : attribute(attribute_) {} + + inline bool Match(IR::Value v) { + return v.Type() == IR::Type::Attribute && v.Attribute() == attribute; + } + +private: + IR::Attribute attribute; +}; + +struct MatchU32 : MatchObject { + MatchU32(u32 imm_) : imm(imm_) {} + + inline bool Match(IR::Value v) { + return v.IsImmediate() && v.Type() == IR::Type::U32 && v.U32() == imm; + } + +private: + u32 imm; +}; + +template +struct MatchInstObject : MatchObject> { + static_assert(sizeof...(Args) == IR::NumArgsOf(opcode)); + MatchInstObject(Args&&... args) : pattern(std::forward_as_tuple(args...)) {} + + inline bool Match(IR::Value v) { + IR::Inst* inst = v.TryInst(); + if (!inst || inst->GetOpcode() != opcode) { + return false; + } + + bool matched = true; + + [&](std::index_sequence) { + ((matched = matched && std::get(pattern).Match(inst->Arg(Is))), ...); + }(std::make_index_sequence{}); + + return matched; + } + +private: + using MatchArgs = std::tuple; + MatchArgs pattern; +}; + +template +inline auto MakeInstPattern(Args&&... args) { + return MatchInstObject(std::forward(args)...); +} + +// Conveniences. TODO probably simpler way of doing this +#define M_READCONST(...) MakeInstPattern(__VA_ARGS__) +#define M_GETUSERDATA(...) MakeInstPattern(__VA_ARGS__) +#define M_BITFIELDUEXTRACT(...) MakeInstPattern(__VA_ARGS__) +#define M_BITFIELDSEXTRACT(...) MakeInstPattern(__VA_ARGS__) +#define M_GETATTRIBUTEU32(...) MakeInstPattern(__VA_ARGS__) +#define M_UMOD32(...) MakeInstPattern(__VA_ARGS__) +#define M_SHIFTRIGHTLOGICAL32(...) MakeInstPattern(__VA_ARGS__) +#define M_IADD32(...) MakeInstPattern(__VA_ARGS__) +#define M_IMUL32(...) MakeInstPattern(__VA_ARGS__) +#define M_BITWISEAND32(...) MakeInstPattern(__VA_ARGS__) +#define M_GETTESSGENERICATTRIBUTE(...) \ + MakeInstPattern(__VA_ARGS__) +#define M_SETTCSGENERICATTRIBUTE(...) \ + MakeInstPattern(__VA_ARGS__) +#define M_COMPOSITECONSTRUCTU32X2(...) \ + MakeInstPattern(__VA_ARGS__) +#define M_COMPOSITECONSTRUCTU32X3(...) \ + MakeInstPattern(__VA_ARGS__) +#define M_COMPOSITECONSTRUCTU32X4(...) \ + MakeInstPattern(__VA_ARGS__) + +} // namespace Shader::Optimiation::PatternMatching \ No newline at end of file diff --git a/gpu/shadps4/shader_recompiler/ir/position.h b/gpu/shadps4/shader_recompiler/ir/position.h new file mode 100644 index 0000000..a20f2cc --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/position.h @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/logging/log.h" +#include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/runtime_info.h" + +namespace Shader::IR { + +/// Maps special position export to builtin attribute stores +template +inline void ExportPosition(IREmitter& ir, const StageRuntimeInfo& stage, + bool tess_emulated_primitive, Attribute attribute, u32 comp, + const IR::F32& value) { + if (attribute == Attribute::Position0) { + ir.SetAttribute(attribute, value, comp); + return; + } + + const u32 index = u32(attribute) - u32(Attribute::Position1); + const auto output = stage.outputs[index][comp]; + if constexpr (std::is_same_v) { + // Certain outputs are supposed to be set by the last pre-rasterization stage. We don't + // currently have a mechanism for passing these on when emulating rect/quad lists using + // tessellation, which comes after, so just ignore the export for now. Note that this + // only matters for vertex shaders, as geometry shaders come last in pre-rasterization. + const auto last_stage_required = output == Output::PointSize || + output == Output::RenderTargetIndex || + output == Output::ViewportIndex; + if (tess_emulated_primitive && last_stage_required) { + LOG_WARNING(Render, + "{} is exported in vertex shader but tessellation-based primitive " + "emulation is active. Not implemented yet.", + magic_enum::enum_name(output)); + return; + } + } + + switch (output) { + case Output::ClipDist0: + case Output::ClipDist1: + case Output::ClipDist2: + case Output::ClipDist3: + case Output::ClipDist4: + case Output::ClipDist5: + case Output::ClipDist6: + case Output::ClipDist7: { + const u32 index = u32(output) - u32(Output::ClipDist0); + ir.SetAttribute(IR::Attribute::ClipDistance, value, index); + break; + } + case Output::CullDist0: + case Output::CullDist1: + case Output::CullDist2: + case Output::CullDist3: + case Output::CullDist4: + case Output::CullDist5: + case Output::CullDist6: + case Output::CullDist7: { + const u32 index = u32(output) - u32(Output::CullDist0); + ir.SetAttribute(IR::Attribute::CullDistance, value, index); + break; + } + case Output::PointSize: + ir.SetAttribute(IR::Attribute::PointSize, value); + break; + case Output::RenderTargetIndex: + ir.SetAttribute(IR::Attribute::RenderTargetIndex, value); + break; + case Output::ViewportIndex: + ir.SetAttribute(IR::Attribute::ViewportIndex, value); + break; + case Output::None: + LOG_WARNING(Render_Recompiler, "The {} component of {} isn't mapped, skipping", + "xyzw"[comp], NameOf(attribute)); + break; + default: + UNREACHABLE_MSG("Unhandled output {} on attribute {}", u32(output), NameOf(attribute)); + } +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/post_order.cpp b/gpu/shadps4/shader_recompiler/ir/post_order.cpp new file mode 100644 index 0000000..11cdf27 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/post_order.cpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include "shader_recompiler/ir/post_order.h" + +namespace Shader::IR { + +BlockList PostOrder(Block* const first_block) { + boost::container::small_vector block_stack; + boost::container::flat_set visited; + BlockList post_order_blocks; + + visited.insert(first_block); + block_stack.push_back(first_block); + + while (!block_stack.empty()) { + Block* const block = block_stack.back(); + const auto visit = [&](Block* branch) { + if (!visited.insert(branch).second) { + return false; + } + // Calling push_back twice is faster than insert on MSVC + block_stack.push_back(block); + block_stack.push_back(branch); + return true; + }; + block_stack.pop_back(); + if (std::ranges::none_of(block->ImmSuccessors(), visit)) { + block->po_index = post_order_blocks.size(); + post_order_blocks.push_back(block); + } + } + return post_order_blocks; +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/post_order.h b/gpu/shadps4/shader_recompiler/ir/post_order.h new file mode 100644 index 0000000..090413e --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/post_order.h @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/ir/abstract_syntax_list.h" +#include "shader_recompiler/ir/basic_block.h" + +namespace Shader::IR { + +BlockList PostOrder(Block* const first_block); + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/program.cpp b/gpu/shadps4/shader_recompiler/ir/program.cpp new file mode 100644 index 0000000..8c537a2 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/program.cpp @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include + +#include "common/io_file.h" +#include "common/path_util.h" +#include "core/emulator_settings.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +void DumpProgram(const Program& program, const Info& info, const std::string& type) { + using namespace Common::FS; + + if (!EmulatorSettings.IsDumpShaders()) { + return; + } + + const auto dump_dir = GetUserPath(PathType::ShaderDir) / "dumps"; + if (!std::filesystem::exists(dump_dir)) { + std::filesystem::create_directories(dump_dir); + } + const auto ir_filename = + fmt::format("{}_{:#018x}.{}irprogram.txt", info.hw_stage, info.pgm_hash, type); + const auto ir_file = IOFile{dump_dir / ir_filename, FileAccessMode::Create, FileType::TextFile}; + + size_t index{0}; + std::map inst_to_index; + std::map block_to_index; + + for (const IR::Block* const block : program.blocks) { + block_to_index.emplace(block, index); + ++index; + } + + for (const auto& block : program.blocks) { + std::string s = IR::DumpBlock(*block, block_to_index, inst_to_index, index) + '\n'; + ir_file.WriteString(s); + } + + const auto asl_filename = + fmt::format("{}_{:#018x}.{}asl.txt", info.hw_stage, info.pgm_hash, type); + const auto asl_file = + IOFile{dump_dir / asl_filename, FileAccessMode::Create, FileType::TextFile}; + + for (const auto& node : program.syntax_list) { + std::string s = IR::DumpASLNode(node, block_to_index, inst_to_index) + '\n'; + asl_file.WriteString(s); + } +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/program.h b/gpu/shadps4/shader_recompiler/ir/program.h new file mode 100644 index 0000000..548c090 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/program.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "shader_recompiler/frontend/instruction.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/ir/abstract_syntax_list.h" +#include "shader_recompiler/ir/basic_block.h" + +namespace Shader::IR { + +struct Program { + explicit Program(Info& info_) : info{info_} {} + + AbstractSyntaxList syntax_list; + BlockList blocks; + BlockList post_order_blocks; + std::vector ins_list; + u32 next_reg_index{}; + Info& info; +}; + +void DumpProgram(const Program& program, const Info& info, const std::string& type = ""); + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/reg.h b/gpu/shadps4/shader_recompiler/ir/reg.h new file mode 100644 index 0000000..682c041 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/reg.h @@ -0,0 +1,520 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/bit_field.h" +#include "common/enum.h" +#include "common/types.h" +#include "shader_recompiler/ir/type.h" +#include "video_core/amdgpu/pixel_format.h" + +namespace Shader::IR { + +enum class FloatClassFunc : u32 { + SignalingNan = 1 << 0, + QuietNan = 1 << 1, + NegativeInfinity = 1 << 2, + NegativeNormal = 1 << 3, + NegativeDenorm = 1 << 4, + NegativeZero = 1 << 5, + PositiveZero = 1 << 6, + PositiveDenorm = 1 << 7, + PositiveNormal = 1 << 8, + PositiveInfinity = 1 << 9, + + NaN = SignalingNan | QuietNan, + Infinity = PositiveInfinity | NegativeInfinity, + Negative = NegativeInfinity | NegativeNormal | NegativeDenorm | NegativeZero, + Finite = NegativeNormal | NegativeDenorm | NegativeZero | PositiveNormal | PositiveDenorm | + PositiveZero, +}; +DECLARE_ENUM_FLAG_OPERATORS(FloatClassFunc) + +union TextureInstInfo { + u32 raw; + BitField<0, 1, u32> is_depth; + BitField<1, 1, u32> has_bias; + BitField<2, 1, u32> has_lod_clamp; + BitField<3, 1, u32> force_level0; + BitField<4, 1, u32> has_lod; + BitField<5, 1, u32> has_offset; + BitField<6, 2, u32> gather_comp; + BitField<8, 1, u32> has_derivatives; + BitField<9, 1, u32> is_array; + BitField<10, 1, u32> is_unnormalized; + BitField<11, 1, u32> is_gather; + BitField<12, 1, u32> is_r128; + BitField<16, 16, u32> pc; +}; + +union BufferInstInfo { + u64 raw; + BitField<0, 1, u64> index_enable; + BitField<1, 1, u64> voffset_enable; + BitField<2, 12, u64> inst_offset; + BitField<14, 1, u64> system_coherent; + BitField<15, 1, u64> globally_coherent; + BitField<16, 1, u64> typed; + BitField<17, 4, AmdGpu::DataFormat> inst_data_fmt; + BitField<21, 3, AmdGpu::NumberFormat> inst_num_fmt; + BitField<24, 1, u64> sharp_source; + BitField<32, 16, u64> pc; + BitField<48, 16, u64> flatbuf_off_dw; +}; + +enum class ScalarReg : u32 { + S0, + S1, + S2, + S3, + S4, + S5, + S6, + S7, + S8, + S9, + S10, + S11, + S12, + S13, + S14, + S15, + S16, + S17, + S18, + S19, + S20, + S21, + S22, + S23, + S24, + S25, + S26, + S27, + S28, + S29, + S30, + S31, + S32, + S33, + S34, + S35, + S36, + S37, + S38, + S39, + S40, + S41, + S42, + S43, + S44, + S45, + S46, + S47, + S48, + S49, + S50, + S51, + S52, + S53, + S54, + S55, + S56, + S57, + S58, + S59, + S60, + S61, + S62, + S63, + S64, + S65, + S66, + S67, + S68, + S69, + S70, + S71, + S72, + S73, + S74, + S75, + S76, + S77, + S78, + S79, + S80, + S81, + S82, + S83, + S84, + S85, + S86, + S87, + S88, + S89, + S90, + S91, + S92, + S93, + S94, + S95, + S96, + S97, + S98, + S99, + S100, + S101, + S102, + S103, + Max, +}; +static constexpr size_t NumScalarRegs = static_cast(ScalarReg::Max); + +enum class VectorReg : u32 { + V0, + V1, + V2, + V3, + V4, + V5, + V6, + V7, + V8, + V9, + V10, + V11, + V12, + V13, + V14, + V15, + V16, + V17, + V18, + V19, + V20, + V21, + V22, + V23, + V24, + V25, + V26, + V27, + V28, + V29, + V30, + V31, + V32, + V33, + V34, + V35, + V36, + V37, + V38, + V39, + V40, + V41, + V42, + V43, + V44, + V45, + V46, + V47, + V48, + V49, + V50, + V51, + V52, + V53, + V54, + V55, + V56, + V57, + V58, + V59, + V60, + V61, + V62, + V63, + V64, + V65, + V66, + V67, + V68, + V69, + V70, + V71, + V72, + V73, + V74, + V75, + V76, + V77, + V78, + V79, + V80, + V81, + V82, + V83, + V84, + V85, + V86, + V87, + V88, + V89, + V90, + V91, + V92, + V93, + V94, + V95, + V96, + V97, + V98, + V99, + V100, + V101, + V102, + V103, + V104, + V105, + V106, + V107, + V108, + V109, + V110, + V111, + V112, + V113, + V114, + V115, + V116, + V117, + V118, + V119, + V120, + V121, + V122, + V123, + V124, + V125, + V126, + V127, + V128, + V129, + V130, + V131, + V132, + V133, + V134, + V135, + V136, + V137, + V138, + V139, + V140, + V141, + V142, + V143, + V144, + V145, + V146, + V147, + V148, + V149, + V150, + V151, + V152, + V153, + V154, + V155, + V156, + V157, + V158, + V159, + V160, + V161, + V162, + V163, + V164, + V165, + V166, + V167, + V168, + V169, + V170, + V171, + V172, + V173, + V174, + V175, + V176, + V177, + V178, + V179, + V180, + V181, + V182, + V183, + V184, + V185, + V186, + V187, + V188, + V189, + V190, + V191, + V192, + V193, + V194, + V195, + V196, + V197, + V198, + V199, + V200, + V201, + V202, + V203, + V204, + V205, + V206, + V207, + V208, + V209, + V210, + V211, + V212, + V213, + V214, + V215, + V216, + V217, + V218, + V219, + V220, + V221, + V222, + V223, + V224, + V225, + V226, + V227, + V228, + V229, + V230, + V231, + V232, + V233, + V234, + V235, + V236, + V237, + V238, + V239, + V240, + V241, + V242, + V243, + V244, + V245, + V246, + V247, + V248, + V249, + V250, + V251, + V252, + V253, + V254, + V255, + Max, +}; +static constexpr size_t NumVectorRegs = static_cast(VectorReg::Max); + +struct VirtualReg { + explicit VirtualReg() = default; + explicit VirtualReg(u32 index_, Type type_) : index{index_}, type{type_} { + ASSERT(type != IR::Type::Opaque); + } + + auto operator<=>(const VirtualReg&) const noexcept = default; + + constexpr u64 Key() const noexcept { + return static_cast(index) | static_cast(type) << 32; + } + + u32 index{}; + Type type{}; +}; +static_assert(offsetof(VirtualReg, index) == 0, "Required for RegTag"); + +template +concept RegT = std::is_same_v || std::is_same_v; + +template +[[nodiscard]] constexpr Reg operator+(Reg reg, int num) { + const int result{static_cast(reg) + num}; + if (result >= static_cast(Reg::Max)) { + UNREACHABLE_MSG("Overflow on register arithmetic"); + } + if (result < 0) { + UNREACHABLE_MSG("Underflow on register arithmetic"); + } + return static_cast(result); +} + +template +[[nodiscard]] constexpr Reg operator-(Reg reg, int num) { + return reg + (-num); +} + +template +constexpr Reg operator++(Reg& reg) { + reg = reg + 1; + return reg; +} + +template +constexpr Reg operator++(Reg& reg, int) { + const Reg copy{reg}; + reg = reg + 1; + return copy; +} + +template +[[nodiscard]] constexpr size_t RegIndex(Reg reg) noexcept { + return static_cast(reg); +} + +} // namespace Shader::IR + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(Shader::IR::ScalarReg reg, format_context& ctx) const { + return fmt::format_to(ctx.out(), "SGPR{}", static_cast(reg)); + } +}; +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(Shader::IR::VectorReg reg, format_context& ctx) const { + return fmt::format_to(ctx.out(), "VGPR{}", static_cast(reg)); + } +}; +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(Shader::IR::VirtualReg reg, format_context& ctx) const { + return fmt::format_to(ctx.out(), "REG{}_{}", reg.index, reg.type); + } +}; diff --git a/gpu/shadps4/shader_recompiler/ir/reinterpret.h b/gpu/shadps4/shader_recompiler/ir/reinterpret.h new file mode 100644 index 0000000..349ce44 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/reinterpret.h @@ -0,0 +1,145 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/ir/ir_emitter.h" +#include "video_core/amdgpu/pixel_format.h" + +namespace Shader::IR { + +/// Applies a component swizzle to a vec4. +inline Value ApplySwizzle(IREmitter& ir, const Value& vector, const AmdGpu::CompMapping& swizzle) { + // Constants are indexed as 0 and 1, and components are 4-7. Thus we can apply a swizzle + // using two vectors and a shuffle, using one vector of constants and one of the components. + const auto zero = ir.Imm32(0.f); + const auto one = ir.Imm32(1.f); + const auto constants_vec = ir.CompositeConstruct(zero, one, zero, zero); + const auto swizzled = + ir.CompositeShuffle(constants_vec, vector, size_t(swizzle.r), size_t(swizzle.g), + size_t(swizzle.b), size_t(swizzle.a)); + return swizzled; +} + +/// Converts gamma corrected value to linear space +inline F32 ApplyGammaToLinear(IREmitter& ir, const F32& c) { + const F32 a = + ir.FPPow(ir.FPMul(ir.FPAdd(c, ir.Imm32(0.055f)), ir.Imm32(1.0f / 1.055f)), ir.Imm32(2.4f)); + const F32 b = ir.FPMul(c, ir.Imm32(1.0f / 12.92f)); + return IR::F32{ir.Select(ir.FPGreaterThan(c, ir.Imm32(0.04045f)), a, b)}; +} + +inline Value ApplyForceDegamma(IREmitter& ir, const Value& value) { + auto x = F32{ir.CompositeExtract(value, 0)}; + auto y = F32{ir.CompositeExtract(value, 1)}; + auto z = F32{ir.CompositeExtract(value, 2)}; + auto w = F32{ir.CompositeExtract(value, 3)}; + // Gamma correction is only applied to RGB components + x = ApplyGammaToLinear(ir, x); + y = ApplyGammaToLinear(ir, y); + z = ApplyGammaToLinear(ir, z); + return ir.CompositeConstruct(x, y, z, w); +} + +/// Applies a number conversion in the read direction. +inline F32 ApplyReadNumberConversion(IREmitter& ir, const F32& value, + const AmdGpu::NumberConversion& conversion) { + switch (conversion) { + case AmdGpu::NumberConversion::None: + return value; + case AmdGpu::NumberConversion::UintToUscaled: + return ir.ConvertUToF(32, 32, ir.BitCast(value)); + case AmdGpu::NumberConversion::SintToSscaled: + return ir.ConvertSToF(32, 32, ir.BitCast(value)); + case AmdGpu::NumberConversion::UnormToUbnorm: + // Convert 0...1 to -1...1 + return ir.FPSub(ir.FPMul(value, ir.Imm32(2.f)), ir.Imm32(1.f)); + case AmdGpu::NumberConversion::Sint8ToSnormNz: { + const IR::U32 additon = ir.IAdd(ir.IMul(ir.BitCast(value), ir.Imm32(2)), ir.Imm32(1)); + const IR::F32 left = ir.ConvertSToF(32, 32, additon); + const IR::F32 max = ir.Imm32(float(std::numeric_limits::max())); + return ir.FPDiv(left, max); + } + case AmdGpu::NumberConversion::Sint16ToSnormNz: { + const IR::U32 additon = ir.IAdd(ir.IMul(ir.BitCast(value), ir.Imm32(2)), ir.Imm32(1)); + const IR::F32 left = ir.ConvertSToF(32, 32, additon); + const IR::F32 max = ir.Imm32(float(std::numeric_limits::max())); + return ir.FPDiv(left, max); + } + case AmdGpu::NumberConversion::Uint32ToUnorm: { + const auto float_val = ir.ConvertUToF(32, 32, ir.BitCast(value)); + return ir.FPDiv(float_val, ir.Imm32(static_cast(std::numeric_limits::max()))); + } + case AmdGpu::NumberConversion::SrgbToNorm: { + return ApplyGammaToLinear(ir, value); + } + default: + UNREACHABLE(); + } +} + +inline Value ApplyReadNumberConversionVec4(IREmitter& ir, const Value& value, + const AmdGpu::NumberConversion& conversion) { + if (conversion == AmdGpu::NumberConversion::None) { + return value; + } + const auto x = ApplyReadNumberConversion(ir, F32{ir.CompositeExtract(value, 0)}, conversion); + const auto y = ApplyReadNumberConversion(ir, F32{ir.CompositeExtract(value, 1)}, conversion); + const auto z = ApplyReadNumberConversion(ir, F32{ir.CompositeExtract(value, 2)}, conversion); + const auto w = ApplyReadNumberConversion(ir, F32{ir.CompositeExtract(value, 3)}, conversion); + return ir.CompositeConstruct(x, y, z, w); +} + +/// Applies a number conversion in the write direction. +inline F32 ApplyWriteNumberConversion(IREmitter& ir, const F32& value, + const AmdGpu::NumberConversion& conversion) { + switch (conversion) { + case AmdGpu::NumberConversion::None: + return value; + case AmdGpu::NumberConversion::UintToUscaled: + // Need to return float type to maintain IR semantics. + return ir.BitCast(U32{ir.ConvertFToU(32, value)}); + case AmdGpu::NumberConversion::SintToSscaled: + // Need to return float type to maintain IR semantics. + return ir.BitCast(U32{ir.ConvertFToS(32, value)}); + case AmdGpu::NumberConversion::UnormToUbnorm: + // Convert -1...1 to 0...1 + return ir.FPDiv(ir.FPAdd(value, ir.Imm32(1.f)), ir.Imm32(2.f)); + case AmdGpu::NumberConversion::Sint8ToSnormNz: { + const IR::F32 max = ir.Imm32(float(std::numeric_limits::max())); + const IR::F32 mul = ir.FPMul(ir.FPClamp(value, ir.Imm32(-1.f), ir.Imm32(1.f)), max); + const IR::F32 left = ir.FPSub(mul, ir.Imm32(1.f)); + const IR::U32 raw = ir.ConvertFToS(32, ir.FPDiv(left, ir.Imm32(2.f))); + return ir.BitCast(raw); + } + case AmdGpu::NumberConversion::Sint16ToSnormNz: { + const IR::F32 max = ir.Imm32(float(std::numeric_limits::max())); + const IR::F32 mul = ir.FPMul(ir.FPClamp(value, ir.Imm32(-1.f), ir.Imm32(1.f)), max); + const IR::F32 left = ir.FPSub(mul, ir.Imm32(1.f)); + const IR::U32 raw = ir.ConvertFToS(32, ir.FPDiv(left, ir.Imm32(2.f))); + return ir.BitCast(raw); + } + case AmdGpu::NumberConversion::Uint32ToUnorm: { + const auto clamped = ir.FPClamp(value, ir.Imm32(0.f), ir.Imm32(1.f)); + const auto unnormalized = + ir.FPMul(clamped, ir.Imm32(static_cast(std::numeric_limits::max()))); + return ir.BitCast(U32{ir.ConvertFToU(32, unnormalized)}); + } + default: + UNREACHABLE(); + } +} + +inline Value ApplyWriteNumberConversionVec4(IREmitter& ir, const Value& value, + const AmdGpu::NumberConversion& conversion) { + if (conversion == AmdGpu::NumberConversion::None) { + return value; + } + const auto x = ApplyWriteNumberConversion(ir, F32{ir.CompositeExtract(value, 0)}, conversion); + const auto y = ApplyWriteNumberConversion(ir, F32{ir.CompositeExtract(value, 1)}, conversion); + const auto z = ApplyWriteNumberConversion(ir, F32{ir.CompositeExtract(value, 2)}, conversion); + const auto w = ApplyWriteNumberConversion(ir, F32{ir.CompositeExtract(value, 3)}, conversion); + return ir.CompositeConstruct(x, y, z, w); +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/srt_gvn_table.h b/gpu/shadps4/shader_recompiler/ir/srt_gvn_table.h new file mode 100644 index 0000000..4d11b6b --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/srt_gvn_table.h @@ -0,0 +1,119 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "common/assert.h" +#include "common/hash.h" +#include "shader_recompiler/ir/microinstruction.h" +#include "shader_recompiler/ir/opcodes.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::Optimization { + +// Does global value numbering on a subset of instructions that are used +// for loads from shader resource tables. +// Inspiration from spirv-opt + +class SrtGvnTable { +public: + using ValueNumberTable = std::unordered_map; + using ValueNum = u32; + + SrtGvnTable() : value_numbers(), next_num(0) {} + + u32 GetValueNumber(IR::Inst* inst) { + return GetValueNumber(IR::Value{inst}); + } + + u32 GetValueNumber(IR::Value v) { + if (auto it = value_numbers.find(v); it != value_numbers.end()) { + return it->second; + } + if (auto* inst = v.TryInst()) { + return ComputeInstValueNumber(inst); + } + return NextValueNumber(v); + } + +private: + bool IsArgHashInst(IR::Inst* inst) { + switch (inst->GetOpcode()) { + case IR::Opcode::GetUserData: + case IR::Opcode::CompositeConstructU32x2: + case IR::Opcode::ReadConst: + case IR::Opcode::ReadConstBuffer: + case IR::Opcode::IAdd32: + case IR::Opcode::ISub32: + case IR::Opcode::IMul32: + case IR::Opcode::ShiftLeftLogical32: + case IR::Opcode::ShiftRightLogical32: + case IR::Opcode::BitwiseAnd32: + case IR::Opcode::BitwiseOr32: + case IR::Opcode::BitwiseXor32: + case IR::Opcode::BitwiseNot32: + case IR::Opcode::UMin32: + case IR::Opcode::UMax32: + case IR::Opcode::BitFieldUExtract: + ASSERT(!inst->MayHaveSideEffects()); + return true; + default: + return false; + } + } + + u32 ComputeInstValueNumber(IR::Inst* inst) { + // Should always be checking before calling this functio + ASSERT(!value_numbers.contains(IR::Value(inst))); + u32 vn; + if (IsArgHashInst(inst)) { + InstVector iv = MakeInstVector(inst); + if (auto it = iv_to_vn.find(iv); it != iv_to_vn.end()) { + vn = it->second; + value_numbers[IR::Value(inst)] = vn; + } else { + vn = NextValueNumber(IR::Value(inst)); + iv_to_vn.emplace(std::move(iv), vn); + } + } else { + vn = NextValueNumber(IR::Value(inst)); + } + return vn; + } + + u32 NextValueNumber(IR::Value v) { + u32 rv = next_num++; + value_numbers[v] = rv; + return rv; + } + + ValueNumberTable value_numbers; + u32 next_num; + + using InstVector = boost::container::small_vector; + + InstVector MakeInstVector(IR::Inst* inst) { + InstVector iv; + iv.reserve(2 + inst->NumArgs()); + iv.push_back(static_cast(inst->GetOpcode())); + iv.push_back(inst->Flags()); + for (auto i = 0; i < inst->NumArgs(); i++) { + iv.push_back(GetValueNumber(inst->Arg(i))); + } + return iv; + } + + struct HashInstVector { + size_t operator()(const InstVector& iv) const { + u32 h = 0; + for (auto vn : iv) { + h = HashCombine(vn, h); + } + return h; + } + }; + + std::unordered_map iv_to_vn; +}; + +} // namespace Shader::Optimization diff --git a/gpu/shadps4/shader_recompiler/ir/ssa.h b/gpu/shadps4/shader_recompiler/ir/ssa.h new file mode 100644 index 0000000..96c9234 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/ssa.h @@ -0,0 +1,70 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +enum class RegType { + ScalarReg, + VectorReg = ScalarReg + NumScalarRegs, + Scc = VectorReg + NumVectorRegs, + Exec, + VccLo, + VccHi, + M0, + IntrusiveEnd, + GotoVariable, + VirtualReg, + None, +}; + +struct SsaState { + static constexpr size_t NumValues = static_cast(RegType::IntrusiveEnd); + + std::array values; + + void Reset() { + std::memset(this, 0, sizeof(SsaState)); + } +}; + +struct RegTag { + RegType type{RegType::None}; + union { + u32 index{}; + IR::ScalarReg sreg; + IR::VectorReg vreg; + IR::VirtualReg reg; + }; + + RegTag() = default; + RegTag(IR::ScalarReg reg) : type{RegType::ScalarReg}, sreg{reg} {} + RegTag(IR::VectorReg reg) : type{RegType::VectorReg}, vreg{reg} {} + RegTag(IR::VirtualReg reg_) : type{RegType::VirtualReg}, reg{reg_} {} + RegTag(RegType type_, u32 index_ = 0) : type{type_}, index{index_} {} + + bool IsIntrusive() const { + return type < RegType::IntrusiveEnd; + } + + u32 Index() const { + DEBUG_ASSERT(IsIntrusive()); + return static_cast(type) + index; + } + + bool operator==(const RegTag& other) const { + return type == other.type && index == other.index; + } + + explicit operator bool() const { + return type != RegType::None; + } +}; +static constexpr RegTag EMPTY_REG_TAG{}; + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/type.cpp b/gpu/shadps4/shader_recompiler/ir/type.cpp new file mode 100644 index 0000000..16b2e89 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/type.cpp @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "shader_recompiler/ir/type.h" + +namespace Shader::IR { + +std::string NameOf(Type type) { + static constexpr std::array names{ + "Opaque", "ScalarReg", "VectorReg", "VirtualReg", "Attribute", "Patch", "U1", + "U8", "U16", "U32", "U64", "F16", "F32", "F64", + "U32x2", "U32x3", "U32x4", "F16x2", "F16x3", "F16x4", "F32x2", + "F32x3", "F32x4", "F64x2", "F64x3", "F64x4", "StringLiteral"}; + const size_t bits{static_cast(type)}; + if (bits == 0) { + return "Void"; + } + std::string result; + for (size_t i = 0; i < names.size(); i++) { + if ((bits & (size_t{1} << i)) != 0) { + if (!result.empty()) { + result += '|'; + } + result += names[i]; + } + } + return result; +} + +bool AreTypesCompatible(Type lhs, Type rhs) noexcept { + return lhs == rhs || lhs == Type::Opaque || rhs == Type::Opaque; +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/type.h b/gpu/shadps4/shader_recompiler/ir/type.h new file mode 100644 index 0000000..f329e91 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/type.h @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/enum.h" + +namespace Shader::IR { + +enum class Type { + Void = 0, + Opaque = 1 << 0, + ScalarReg = 1 << 1, + VectorReg = 1 << 2, + VirtualReg = 1 << 3, + Attribute = 1 << 4, + Patch = 1 << 5, + U1 = 1 << 6, + U8 = 1 << 7, + U16 = 1 << 8, + U32 = 1 << 9, + U64 = 1 << 10, + F16 = 1 << 11, + F32 = 1 << 12, + F64 = 1 << 13, + U32x2 = 1 << 14, + U32x3 = 1 << 15, + U32x4 = 1 << 16, + F16x2 = 1 << 17, + F16x3 = 1 << 18, + F16x4 = 1 << 19, + F32x2 = 1 << 20, + F32x3 = 1 << 21, + F32x4 = 1 << 22, + F64x2 = 1 << 23, + F64x3 = 1 << 24, + F64x4 = 1 << 25, + StringLiteral = 1 << 26, +}; +DECLARE_ENUM_FLAG_OPERATORS(Type) + +[[nodiscard]] std::string NameOf(Type type); + +[[nodiscard]] bool AreTypesCompatible(Type lhs, Type rhs) noexcept; + +} // namespace Shader::IR + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(Shader::IR::Type type, format_context& ctx) const { + return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(type)); + } +}; diff --git a/gpu/shadps4/shader_recompiler/ir/value.cpp b/gpu/shadps4/shader_recompiler/ir/value.cpp new file mode 100644 index 0000000..730a23f --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/value.cpp @@ -0,0 +1,118 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/hash.h" +#include "shader_recompiler/ir/microinstruction.h" +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +bool Value::IsPhi() const noexcept { + return type == Type::Opaque && inst->GetOpcode() == Opcode::Phi; +} + +IR::Type Value::Type() const noexcept { + if (type == Type::Opaque) { + return inst->Type(); + } + return type; +} + +u64 Value::Hash() const noexcept { + const u64 h = HashCombine(static_cast(type), 0ULL); + switch (type) { + case Type::Void: + return h; + case Type::Opaque: + return reinterpret_cast(inst); + case Type::ScalarReg: + return HashCombine(static_cast(sreg), h); + case Type::VectorReg: + return HashCombine(static_cast(vreg), h); + case Type::Attribute: + return HashCombine(static_cast(attribute), h); + case Type::U1: + return HashCombine(static_cast(imm_u1), h); + case Type::U8: + return HashCombine(static_cast(imm_u8), h); + case Type::U16: + case Type::F16: + return HashCombine(static_cast(imm_u16), h); + case Type::U32: + case Type::F32: + return HashCombine(static_cast(imm_u32), h); + case Type::U64: + case Type::F64: + return HashCombine(static_cast(imm_u64), h); + case Type::U32x2: + case Type::U32x3: + case Type::U32x4: + case Type::F16x2: + case Type::F16x3: + case Type::F16x4: + case Type::F32x2: + case Type::F32x3: + case Type::F32x4: + case Type::F64x2: + case Type::F64x3: + case Type::F64x4: + default: + break; + } + UNREACHABLE_MSG("Invalid type {}", type); +} + +bool Value::operator==(const Value& other) const { + if (type != other.type) { + return false; + } + switch (type) { + case Type::Void: + return true; + case Type::Opaque: + return inst == other.inst; + case Type::ScalarReg: + return sreg == other.sreg; + case Type::VectorReg: + return vreg == other.vreg; + case Type::Attribute: + return attribute == other.attribute; + case Type::U1: + return imm_u1 == other.imm_u1; + case Type::U8: + return imm_u8 == other.imm_u8; + case Type::U16: + case Type::F16: + return imm_u16 == other.imm_u16; + case Type::U32: + case Type::F32: + return imm_u32 == other.imm_u32; + case Type::U64: + case Type::F64: + return imm_u64 == other.imm_u64; + case Type::StringLiteral: + return std::string_view(string_literal) == other.string_literal; + case Type::U32x2: + case Type::U32x3: + case Type::U32x4: + case Type::F16x2: + case Type::F16x3: + case Type::F16x4: + case Type::F32x2: + case Type::F32x3: + case Type::F32x4: + case Type::F64x2: + case Type::F64x3: + case Type::F64x4: + default: + break; + } + UNREACHABLE_MSG("Invalid type {}", type); +} + +bool Value::operator!=(const Value& other) const { + return !operator==(other); +} + +} // namespace Shader::IR diff --git a/gpu/shadps4/shader_recompiler/ir/value.h b/gpu/shadps4/shader_recompiler/ir/value.h new file mode 100644 index 0000000..32de025 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/ir/value.h @@ -0,0 +1,196 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/assert.h" +#include "shader_recompiler/ir/attribute.h" +#include "shader_recompiler/ir/patch.h" +#include "shader_recompiler/ir/reg.h" +#include "shader_recompiler/ir/type.h" + +namespace Shader::IR { + +class Block; +class Inst; + +struct AssociatedInsts; + +class Value { +public: + Value() noexcept = default; + explicit Value(IR::Inst* value) noexcept : type{Type::Opaque}, inst{value} {} + explicit Value(IR::ScalarReg reg) noexcept : type{Type::ScalarReg}, sreg{reg} {} + explicit Value(IR::VectorReg reg) noexcept : type{Type::VectorReg}, vreg{reg} {} + explicit Value(IR::VirtualReg reg_) noexcept : type{Type::VirtualReg}, reg{reg_} {} + explicit Value(IR::Attribute value) noexcept : type{Type::Attribute}, attribute{value} {} + explicit Value(IR::Patch patch) noexcept : type{Type::Patch}, patch{patch} {} + explicit Value(bool value) noexcept : type{Type::U1}, imm_u1{value} {} + explicit Value(u8 value) noexcept : type{Type::U8}, imm_u8{value} {} + explicit Value(u16 value) noexcept : type{Type::U16}, imm_u16{value} {} + explicit Value(u32 value) noexcept : type{Type::U32}, imm_u32{value} {} + explicit Value(f32 value) noexcept : type{Type::F32}, imm_f32{value} {} + explicit Value(u64 value) noexcept : type{Type::U64}, imm_u64{value} {} + explicit Value(f64 value) noexcept : type{Type::F64}, imm_f64{value} {} + explicit Value(const char* value) noexcept : type{Type::StringLiteral}, string_literal{value} {} + + bool IsPhi() const noexcept; + IR::Type Type() const noexcept; + u64 Hash() const noexcept; + + inline bool IsEmpty() const noexcept { + return type == Type::Void; + } + + inline bool IsImmediate() const noexcept { + return type != Type::Opaque; + } + + inline IR::Inst* Inst() const { + DEBUG_ASSERT(type == Type::Opaque); + return inst; + } + + inline IR::Inst* TryInst() const { + return type == Type::Opaque ? inst : nullptr; + } + + inline IR::ScalarReg ScalarReg() const { + DEBUG_ASSERT(type == Type::ScalarReg); + return sreg; + } + + inline IR::VectorReg VectorReg() const { + DEBUG_ASSERT(type == Type::VectorReg); + return vreg; + } + + inline IR::VirtualReg VirtualReg() const { + DEBUG_ASSERT(type == Type::VirtualReg); + return reg; + } + + inline IR::Attribute Attribute() const { + DEBUG_ASSERT(type == Type::Attribute); + return attribute; + } + + inline IR::Patch Patch() const { + DEBUG_ASSERT(type == Type::Patch); + return patch; + } + + inline bool U1() const { + DEBUG_ASSERT(type == Type::U1); + return imm_u1; + } + + inline u8 U8() const { + DEBUG_ASSERT(type == Type::U8); + return imm_u8; + } + + inline u16 U16() const { + DEBUG_ASSERT(type == Type::U16); + return imm_u16; + } + + inline u32 U32() const { + DEBUG_ASSERT(type == Type::U32); + return imm_u32; + } + + inline f32 F32() const { + DEBUG_ASSERT(type == Type::F32); + return imm_f32; + } + + inline u64 U64() const { + DEBUG_ASSERT(type == Type::U64); + return imm_u64; + } + + inline f64 F64() const { + DEBUG_ASSERT(type == Type::F64); + return imm_f64; + } + + inline const char* StringLiteral() const { + DEBUG_ASSERT(type == Type::StringLiteral); + return string_literal; + } + + [[nodiscard]] bool operator==(const Value& other) const; + [[nodiscard]] bool operator!=(const Value& other) const; + +private: + IR::Type type{}; + union { + IR::Inst* inst{}; + IR::ScalarReg sreg; + IR::VectorReg vreg; + IR::VirtualReg reg; + IR::Attribute attribute; + IR::Patch patch; + bool imm_u1; + u8 imm_u8; + u16 imm_u16; + u32 imm_u32; + f32 imm_f32; + u64 imm_u64; + f64 imm_f64; + const char* string_literal; + }; + + friend class std::hash; +}; +static_assert(static_cast(IR::Type::Void) == 0, "memset relies on IR::Type being zero"); +static_assert(std::is_trivially_copyable_v); + +template +class TypedValue : public Value { +public: + TypedValue() = default; + + template + requires((other_type & type_) != IR::Type::Void) + TypedValue(const TypedValue& value) : Value(value) {} + + explicit TypedValue(const Value& value) : Value(value) { + ASSERT_MSG((value.Type() & type_) != IR::Type::Void, "Incompatible types {} and {}", type_, + value.Type()); + } + + explicit TypedValue(IR::Inst* inst_) : TypedValue(Value(inst_)) {} +}; + +using U1 = TypedValue; +using U8 = TypedValue; +using U16 = TypedValue; +using U32 = TypedValue; +using U64 = TypedValue; +using F16 = TypedValue; +using F32 = TypedValue; +using F64 = TypedValue; +using U32F32 = TypedValue; +using U64F64 = TypedValue; +using U32U64 = TypedValue; +using U16U32U64 = TypedValue; +using U8U16U32U64 = TypedValue; +using F32F64 = TypedValue; +using F16F32F64 = TypedValue; +using UAny = TypedValue; + +} // namespace Shader::IR + +namespace std { +template <> +struct hash { + std::size_t operator()(const Shader::IR::Value& v) const { + return v.Hash(); + } +}; +} // namespace std diff --git a/gpu/shadps4/shader_recompiler/params.h b/gpu/shadps4/shader_recompiler/params.h new file mode 100644 index 0000000..0dce9a0 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/params.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace Shader { + +/** + * Compilation parameters used to identify and locate a guest shader program. + */ +struct ShaderParams { + static constexpr u32 NumShaderUserData = 16; + + std::span user_data; + std::span code; + u64 hash; + + VAddr Base() const noexcept { + return reinterpret_cast(code.data()); + } +}; + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/profile.h b/gpu/shadps4/shader_recompiler/profile.h new file mode 100644 index 0000000..b8af3b7 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/profile.h @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Shader { + +struct Profile { + u32 max_viewport_width{}; + u32 max_viewport_height{}; + u32 max_shared_memory_size{}; + u32 supported_spirv{0x00010000}; + u32 subgroup_size{}; + u32 sparse_page_shift{}; + bool support_int8{}; + bool support_int16{}; + bool support_int64{}; + bool support_float16{}; + bool support_float64{}; + bool supports_denorm_behavior_independence{}; + bool supports_rounding_mode_independence{}; + bool support_fp16_denorm_preserve{}; + bool support_fp16_denorm_flush{}; + bool support_fp16_round_to_zero{}; + bool support_fp32_denorm_preserve{}; + bool support_fp32_denorm_flush{}; + bool support_fp32_round_to_zero{}; + bool support_fp64_denorm_preserve{}; + bool support_fp64_denorm_flush{}; + bool support_fp64_round_to_zero{}; + bool support_fp16_signed_zero_inf_nan_preserve{}; + bool support_fp32_signed_zero_inf_nan_preserve{}; + bool support_fp64_signed_zero_inf_nan_preserve{}; + bool supports_image_load_store_lod{}; + bool supports_native_cube_calc{}; + bool supports_trinary_minmax{}; + bool supports_buffer_fp32_atomic_min_max{}; + bool supports_image_fp32_atomic_min_max{}; + bool supports_buffer_int64_atomics{}; + bool supports_shared_int64_atomics{}; + bool supports_workgroup_explicit_memory_layout{}; + bool supports_amd_shader_explicit_vertex_parameter{}; + bool supports_fragment_shader_barycentric{}; + bool supports_shader_subgroup_clock{}; + bool has_broken_spirv_clamp{}; + bool lower_left_origin_mode{}; + bool needs_manual_interpolation{}; + bool needs_lds_barriers{}; + bool needs_buffer_offsets{}; + bool needs_unorm_fixup{}; + bool needs_clip_distance_emulation{}; + bool supports_shader_stencil_export{}; + + bool operator==(const Profile&) const = default; +}; + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/recompiler.cpp b/gpu/shadps4/shader_recompiler/recompiler.cpp new file mode 100644 index 0000000..42d0479 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/recompiler.cpp @@ -0,0 +1,149 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/classes.h" +#include "shader_recompiler/frontend/control_flow_graph.h" +#include "shader_recompiler/frontend/decode.h" +#include "shader_recompiler/frontend/structured_control_flow.h" +#include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/ir/passes/ir_passes.h" +#include "shader_recompiler/ir/post_order.h" +#include "shader_recompiler/ir/program.h" +#include "shader_recompiler/profile.h" +#include "shader_recompiler/recompiler.h" + +namespace Shader { + +IR::BlockList GenerateBlocks(const IR::AbstractSyntaxList& syntax_list) { + size_t num_syntax_blocks{}; + for (const auto& [_, type] : syntax_list) { + if (type == IR::AbstractSyntaxNode::Type::Block) { + ++num_syntax_blocks; + } + } + IR::BlockList blocks{}; + blocks.reserve(num_syntax_blocks); + for (const auto& [data, type] : syntax_list) { + if (type == IR::AbstractSyntaxNode::Type::Block) { + blocks.push_back(data.block); + } + } + return blocks; +} + +void EmitControlFlowGraph(IR::Program& program, Pools& pools, Gcn::CFG& cfg, + RuntimeInfo& runtime_info, const Profile& profile) { + Gcn::Translator translator{program.info, runtime_info, profile}; + for (auto& block : cfg) { + const u32 start = block.begin_index; + const u32 size = block.end_index - start + 1; + auto* ir_block = pools.block_pool.Create(pools.inst_pool); + ir_block->cfg_block = █ + block.ir_block = ir_block; + translator.Translate(ir_block, block.begin, block.cond, + std::span{program.ins_list}.subspan(start, size)); + program.blocks.push_back(ir_block); + } + translator.EmitPrologue(program.blocks.front()); + ASSERT_MSG(!program.info.translation_failed, "Shader translation has failed"); + for (auto& block : cfg) { + auto* ir_block = block.ir_block; + if (block.branch_true) { + auto* true_block = block.branch_true->ir_block; + ir_block->AddBranch(true_block); + } + if (block.branch_false) { + auto* false_block = block.branch_false->ir_block; + ir_block->AddBranch(false_block); + } + } + program.post_order_blocks = Shader::IR::PostOrder(program.blocks.front()); +} + +IR::Program TranslateProgram(const std::span& code, Pools& pools, Info& info, + RuntimeInfo& runtime_info, const Profile& profile) { + // Ensure first instruction is expected. + constexpr u32 token_mov_vcchi = 0xBEEB03FF; + if (code[0] != token_mov_vcchi) { + LOG_WARNING(Render_Recompiler, "First instruction is not s_mov_b32 vcc_hi, #imm"); + } + + Gcn::GcnCodeSlice slice(code.data(), code.data() + code.size()); + Gcn::GcnDecodeContext decoder; + + // Decode and save instructions + IR::Program program{info}; + program.ins_list.reserve(code.size()); + while (!slice.atEnd()) { + program.ins_list.emplace_back(decoder.decodeInstruction(slice)); + } + + // Clear any previous pooled data. + pools.ReleaseContents(); + + // Create control flow graph + Common::ObjectPool gcn_block_pool{64}; + Gcn::CFG cfg{gcn_block_pool, program.ins_list}; + EmitControlFlowGraph(program, pools, cfg, runtime_info, profile); + + // On NVIDIA GPUs HW interpolation of clip distance values seems broken, and we need to emulate + // it with expensive discard in PS. + Shader::InjectClipDistanceAttributes(program, runtime_info); + + // Run optimization passes on unstructured graph + if (!profile.support_float64) { + Shader::Optimization::LowerFp64ToFp32(program); + } + Shader::Optimization::SsaRewritePass(program); + Shader::Optimization::ConstantPropagationPass(program.post_order_blocks); + if (info.sw_stage == SwStage::TessellationControl) { + Shader::Optimization::TessellationPreprocess(program, runtime_info); + Shader::Optimization::HullShaderTransform(program, runtime_info); + } else if (info.sw_stage == SwStage::TessellationEval) { + Shader::Optimization::TessellationPreprocess(program, runtime_info); + Shader::Optimization::DomainShaderTransform(program, runtime_info); + } + Shader::Optimization::RingAccessElimination(program, runtime_info); + Shader::Optimization::ReadLaneEliminationPass(program); + Shader::IR::DumpProgram(program, info, "pre-res-discover."); + auto resources = Shader::Optimization::ResourceDiscoverPass(program, profile); + Shader::Optimization::FlattenExtendedUserdataPass(program); + Shader::IR::DumpProgram(program, info, "pre-res-patch."); + Shader::Optimization::ResourcePatchingPass(program.info, resources, profile); + Shader::Optimization::LowerBufferFormatToRaw(program); + Shader::Optimization::SharedMemorySimplifyPass(program, profile); + Shader::Optimization::SharedMemoryToStoragePass(program, runtime_info, profile); + Shader::Optimization::LowerUserClipPlanes(program, runtime_info); + Shader::Optimization::PhiSimplificationPass(program); + Shader::Optimization::InverseBallotEliminationPass(program); + Shader::Optimization::LowerHardwareIntrinsics(program); + Shader::IR::DumpProgram(program, info, "pre-lower-phi."); + + // Prepare for structurization by clearing flow graph and lowering phis + for (auto* ir_block : program.blocks) { + ir_block->imm_predecessors.clear(); + ir_block->imm_successors.clear(); + ir_block->ssa_state.Reset(); + } + Shader::Optimization::LowerPhisToRegsPass(program); + + // Structurize control flow graph and create program. + program.syntax_list = Shader::Gcn::BuildASL(pools, cfg, info); + program.blocks = GenerateBlocks(program.syntax_list); + program.post_order_blocks = Shader::IR::PostOrder(program.syntax_list.front().data.block); + + // Run optimization passes on structured graph + Shader::Optimization::SsaRepairPass(program); + Shader::Optimization::SsaRewritePass(program); + Shader::Optimization::SharedMemoryBarrierPass(program, runtime_info, profile); + Shader::Optimization::DeadCodeEliminationPass(program); + Shader::Optimization::LowerWave64BallotPass(program, runtime_info, profile); + Shader::Optimization::ConstantPropagationPass(program.post_order_blocks); + Shader::Optimization::DeadCodeEliminationPass(program); + Shader::Optimization::CollectShaderInfoPass(program, profile); + Shader::IR::DumpProgram(program, info); + + return program; +} + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/recompiler.h b/gpu/shadps4/shader_recompiler/recompiler.h new file mode 100644 index 0000000..118d259 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/recompiler.h @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/object_pool.h" +#include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/program.h" + +namespace Shader { + +struct Profile; +struct RuntimeInfo; + +struct Pools { + static constexpr u32 InstPoolSize = 8192; + static constexpr u32 BlockPoolSize = 32; + + Common::ObjectPool inst_pool; + Common::ObjectPool block_pool; + + explicit Pools() : inst_pool{InstPoolSize}, block_pool{BlockPoolSize} {} + + void ReleaseContents() { + block_pool.ReleaseContents(); + inst_pool.ReleaseContents(); + } +}; + +[[nodiscard]] IR::Program TranslateProgram(const std::span& code, Pools& pools, + Info& info, RuntimeInfo& runtime_info, + const Profile& profile); + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/resource.h b/gpu/shadps4/shader_recompiler/resource.h new file mode 100644 index 0000000..ff5bff8 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/resource.h @@ -0,0 +1,232 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "shader_recompiler/ir/type.h" +#include "video_core/amdgpu/resource.h" + +#include + +namespace Shader { + +static constexpr u32 NUM_USER_DATA_REGS = 16; +static constexpr u32 NUM_IMAGES = 64; +static constexpr u32 NUM_BUFFERS = 40; +static constexpr u32 NUM_SAMPLERS = 16; +static constexpr u32 NUM_FMASKS = 8; + +using SharpLocation = u16; + +constexpr SharpLocation UNKNOWN_LOCATION = std::numeric_limits::max(); + +template +struct SharpFetch { + static constexpr std::size_t N = sizeof(T) / sizeof(u32); + static_assert(N <= 8); + + std::array immediates; + std::array offsets; + u8 load_mask; + + bool operator==(const SharpFetch&) const = default; + + template + requires(num_dwords <= N) + constexpr bool Fetch(const u32* flatbuf, T* out) const { + u8 mask = load_mask; + for (u32 i = 0; i < num_dwords; i++) { + if (offsets[i] == UNKNOWN_LOCATION) { + return false; + } + } + std::array out_dw; + for (u32 i = 0; i < num_dwords; i++) { + out_dw[i] = (mask & 1) ? flatbuf[offsets[i]] : immediates[i]; + mask >>= 1; + } + std::memcpy(out, out_dw.data(), sizeof(out_dw)); + return true; + } +}; + +enum class SharpFetchPostOp : u8 { + None, + // For buffers + BitwiseOrDw1WithImm, + OffsetByProgramBase, + // For images, + ConvertCubeTo2DArray, + // For samplers + DisableAnisoIfSingleLod, + ForceRepeatXyzClamp, + ForceLastTexelXyClamp, + ClearAnisoRatioAndThreshold, +}; + +enum class BufferType : u8 { + Guest, + Flatbuf, + BdaPagetable, + FaultBuffer, + GdsBuffer, + SharedMemory, + ClipPlanes, +}; + +struct BufferResource { + SharpFetch sharp_fetch{}; + IR::Type used_types{}; + BufferType buffer_type{}; + bool is_written{}; + bool is_formatted{}; + SharpFetchPostOp post_op{}; + u32 post_op_dw1_mask{}; + + bool IsSpecial() const noexcept { + return buffer_type != BufferType::Guest; + } + + constexpr AmdGpu::Buffer GetSharp(const auto& info) const noexcept { + AmdGpu::Buffer buffer; + if (!sharp_fetch.Fetch(info.flattened_ud_buf.data(), &buffer)) { + return AmdGpu::Buffer::Null(); + } + if (post_op == SharpFetchPostOp::BitwiseOrDw1WithImm) { + reinterpret_cast(&buffer)[1] |= post_op_dw1_mask; + } else if (post_op == SharpFetchPostOp::OffsetByProgramBase) { + buffer.base_address += info.pgm_base; + } + if (!buffer.Valid()) { + return AmdGpu::Buffer::Null(); + } + return buffer; + } +}; +using BufferResourceList = boost::container::static_vector; + +enum class MipStorageFallbackMode : u16 { + None, + DynamicIndex, + ConstantIndex, +}; + +struct ImageResource { + SharpFetch sharp_fetch{}; + bool is_depth{}; + bool is_atomic{}; + bool is_array{}; + bool is_written{}; + bool is_r128{}; + u8 constant_mip_index{}; + MipStorageFallbackMode mip_fallback_mode{}; + SharpFetchPostOp post_op{}; + + constexpr AmdGpu::Image GetSharp(const auto& info) const noexcept { + AmdGpu::Image image{}; + if (!Fetch(info.flattened_ud_buf.data(), &image)) { + return AmdGpu::Image::Null(is_depth); + } + if (post_op == SharpFetchPostOp::ConvertCubeTo2DArray) { + image.type = u64(AmdGpu::ImageType::Color2DArray); + image.depth = (image.depth + 1) * 6 - 1; + } + if (!image.Valid()) { + image = AmdGpu::Image::Null(is_depth); + } else if (is_depth) { + const auto data_fmt = image.GetDataFmt(); + if (data_fmt != AmdGpu::DataFormat::Format16 && + data_fmt != AmdGpu::DataFormat::Format32) { + image = AmdGpu::Image::Null(true); + } + } + return image; + } + + constexpr bool Fetch(const u32* flatbuf, AmdGpu::Image* out) const { + if (!is_r128) { + // Fetch full 8 byte T# + return sharp_fetch.Fetch(flatbuf, out); + } + // Fetch r128 T# and fix pitch + if (!sharp_fetch.Fetch<4>(flatbuf, out)) { + return false; + } + out->pitch = out->width; + return true; + } + + u32 NumBindings(const auto& info) const { + const AmdGpu::Image tsharp = GetSharp(info); + return (mip_fallback_mode == MipStorageFallbackMode::DynamicIndex) + ? (tsharp.last_level - tsharp.base_level + 1) + : 1; + } +}; +using ImageResourceList = boost::container::static_vector; + +struct SamplerResource { + SharpFetch sharp_fetch{}; + SharpFetchPostOp post_op{}; + SharpLocation post_op_tsharp_dw3_off{}; + bool is_depth{}; + + constexpr AmdGpu::Sampler GetSharp(const auto& info) const noexcept { + AmdGpu::Sampler sampler{}; + sharp_fetch.Fetch(info.flattened_ud_buf.data(), &sampler); + if (post_op == SharpFetchPostOp::DisableAnisoIfSingleLod) { + const u32 tsharp_dw3 = info.flattened_ud_buf[post_op_tsharp_dw3_off]; + if (((tsharp_dw3 >> 12) & 0xff) == 0) { + sampler.max_aniso.Assign(AmdGpu::AnisoRatio::One); + } + } else if (post_op == SharpFetchPostOp::ForceRepeatXyzClamp) { + sampler.clamp_x.Assign(AmdGpu::ClampMode::Wrap); + sampler.clamp_y.Assign(AmdGpu::ClampMode::Wrap); + sampler.clamp_z.Assign(AmdGpu::ClampMode::Wrap); + } else if (post_op == SharpFetchPostOp::ForceLastTexelXyClamp) { + sampler.clamp_x.Assign(AmdGpu::ClampMode::ClampLastTexel); + sampler.clamp_y.Assign(AmdGpu::ClampMode::ClampLastTexel); + sampler.clamp_z.Assign(AmdGpu::ClampMode::Wrap); + } else if (post_op == SharpFetchPostOp::ClearAnisoRatioAndThreshold) { + sampler.max_aniso.Assign(AmdGpu::AnisoRatio::One); + sampler.aniso_threshold.Assign(0); + } + return sampler; + } +}; +using SamplerResourceList = boost::container::static_vector; + +struct FMaskResource { + SharpLocation sharp_idx; + + constexpr AmdGpu::Image GetSharp(const auto& info) const noexcept { + return info.template ReadUdSharp(sharp_idx); + } +}; +using FMaskResourceList = boost::container::static_vector; + +struct PushData { + static constexpr u32 XOffsetIndex = 0; + static constexpr u32 YOffsetIndex = 1; + static constexpr u32 XScaleIndex = 2; + static constexpr u32 YScaleIndex = 3; + static constexpr u32 UdRegsIndex = 4; + static constexpr u32 BufOffsetIndex = UdRegsIndex + NUM_USER_DATA_REGS / 4; + + float xoffset; + float yoffset; + float xscale; + float yscale; + std::array ud_regs; + std::array buf_offsets; + + void AddOffset(u32 binding, u32 offset) { + ASSERT(offset < 256 && binding < buf_offsets.size()); + buf_offsets[binding] = offset; + } +}; +static_assert(sizeof(PushData) <= 128, + "PushData size is greater than minimum size guaranteed by Vulkan spec"); + +} // namespace Shader diff --git a/gpu/shadps4/shader_recompiler/runtime_info.h b/gpu/shadps4/shader_recompiler/runtime_info.h new file mode 100644 index 0000000..7c6fd89 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/runtime_info.h @@ -0,0 +1,333 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" +#include "shader_recompiler/frontend/tessellation.h" +#include "video_core/amdgpu/pixel_format.h" +#include "video_core/amdgpu/regs_shader.h" +#include "video_core/amdgpu/regs_vertex.h" + +namespace Shader { + +enum class HwStage : u32 { + Fragment, + Vertex, + Geometry, + Export, + Hull, + Local, + Compute, +}; + +// Vertex intentionally comes after TCS/TES due to order of compilation +enum class SwStage : u32 { + Fragment, + TessellationControl, + TessellationEval, + Vertex, + Geometry, + Compute, + NumLogicalStages +}; + +constexpr u32 MaxStageTypes = static_cast(SwStage::NumLogicalStages); +constexpr auto MaxEmulatedClipDistances = 4u; + +constexpr HwStage StageFromIndex(size_t index) noexcept { + return static_cast(index); +} + +enum class Output : u8 { + None, + PointSize, + EdgeFlag, + KillFlag, + GsCutFlag, + RenderTargetIndex, + ViewportIndex, + CullDist0, + CullDist1, + CullDist2, + CullDist3, + CullDist4, + CullDist5, + CullDist6, + CullDist7, + ClipDist0, + ClipDist1, + ClipDist2, + ClipDist3, + ClipDist4, + ClipDist5, + ClipDist6, + ClipDist7, +}; +using OutputMap = std::array; + +struct SwVertexRuntimeInfo { + u32 step_rate_0; + u32 step_rate_1; + u16 vertex_sgpr_offset{}; + u16 instance_sgpr_offset{}; + bool tess_emulated_primitive{}; + + bool operator==(const SwVertexRuntimeInfo& other) const noexcept = default; +}; + +struct HwLocalRuntimeInfo { + u32 ls_stride; + + bool operator==(const HwLocalRuntimeInfo& other) const noexcept = default; +}; + +struct HwExportRuntimeInfo { + u32 vertex_data_size; + + bool operator==(const HwExportRuntimeInfo& other) const noexcept = default; +}; + +struct HwVertexRuntimeInfo { + u32 num_outputs; + std::array outputs; + bool emulate_depth_negative_one_to_one{}; + bool clip_disable{}; + u32 user_clip_plane_mask{}; + + bool operator==(const HwVertexRuntimeInfo& other) const noexcept = default; +}; + +struct SwTessControlRuntimeInfo { + u32 hs_output_cp_stride; + u32 num_input_control_points; + u32 num_threads; + AmdGpu::TessellationType tess_type; + bool offchip_lds_enable; + u32 ls_stride; + u32 hs_output_base; + + bool operator==(const SwTessControlRuntimeInfo&) const = default; + + // It might be possible for a non-passthrough TCS to have these conditions, in some dumb + // situation. In that case, it should be fine to assume passthrough and declare some extra + // output control points and attributes that shouldnt be read by the TES anyways + bool IsPassthrough() const { + return hs_output_base == 0 && ls_stride == hs_output_cp_stride && num_threads == 1; + }; + + // regs.ls_hs_config.hs_output_control_points contains the number of threads, which + // isn't exactly the number of output control points. + // For passthrough shaders, the register field is set to 1, so use the number of + // input control points + u32 NumOutputControlPoints() const { + return IsPassthrough() ? num_input_control_points : num_threads; + } +}; + +struct SwTessEvalRuntimeInfo { + u32 hs_output_cp_stride; + AmdGpu::TessellationType tess_type; + AmdGpu::TessellationTopology tess_topology; + AmdGpu::TessellationPartitioning tess_partitioning; + + bool operator==(const SwTessEvalRuntimeInfo&) const noexcept = default; +}; + +static constexpr auto GsMaxOutputStreams = 4u; +using GsOutputPrimTypes = std::array; +struct HwGeometryRuntimeInfo { + u32 num_outputs; + std::array outputs; + u32 num_invocations{}; + u32 output_vertices{}; + u32 in_vertex_data_size{}; + u32 out_vertex_data_size{}; + AmdGpu::PrimitiveType in_primitive; + GsOutputPrimTypes out_primitive; + AmdGpu::GsScenario mode; + std::span vs_copy; + u64 vs_copy_hash; + + bool operator==(const HwGeometryRuntimeInfo& other) const { + return num_outputs == other.num_outputs && outputs == other.outputs && num_invocations && + other.num_invocations && output_vertices == other.output_vertices && + in_primitive == other.in_primitive && + std::ranges::equal(out_primitive, other.out_primitive) && + vs_copy_hash == other.vs_copy_hash; + } +}; + +enum class MrtSwizzle : u8 { + Identity = 0, + Alt = 1, + Reverse = 2, + ReverseAlt = 3, +}; +static constexpr u32 MaxColorBuffers = 8; + +struct PsColorBuffer { + AmdGpu::DataFormat data_format : 6; + AmdGpu::NumberFormat num_format : 4; + AmdGpu::NumberConversion num_conversion : 3; + AmdGpu::ShaderExportFormat export_format : 4; + // GCN applies blend factors to min/max ops while Vulkan ignores them. For the self-scaled + // pattern min/max(src*src, dst*dst) the shader squares its color output instead, keeping + // the attachment in the squared domain end to end. + u32 blend_self_scale : 1; + AmdGpu::CompMapping swizzle; + + bool operator==(const PsColorBuffer& other) const = default; +}; + +struct HwFragmentRuntimeInfo { + struct PsInput { + u8 param_index; + bool is_default; + bool is_flat; + u8 default_value; + + bool IsDefault() const { + return is_default && !is_flat; + } + + bool operator==(const PsInput&) const noexcept = default; + }; + AmdGpu::PsInput en_flags; + AmdGpu::PsInput addr_flags; + u32 num_inputs; + std::array inputs; + std::array color_buffers; + AmdGpu::ShaderExportFormat z_export_format; + u8 num_samples{1}; + u8 mrtz_mask{}; + bool front_face_all_bits{false}; + bool dual_source_blending{false}; + bool clip_distance_emulation{false}; + + bool operator==(const HwFragmentRuntimeInfo& other) const noexcept { + return std::ranges::equal(color_buffers, other.color_buffers) && + en_flags == other.en_flags && addr_flags == other.addr_flags && + num_inputs == other.num_inputs && z_export_format == other.z_export_format && + num_samples == other.num_samples && mrtz_mask == other.mrtz_mask && + front_face_all_bits == other.front_face_all_bits && + dual_source_blending == other.dual_source_blending && + clip_distance_emulation == other.clip_distance_emulation && + std::ranges::equal(inputs.begin(), inputs.begin() + num_inputs, other.inputs.begin(), + other.inputs.begin() + num_inputs); + } +}; + +struct HwComputeRuntimeInfo { + u32 shared_memory_size; + std::array workgroup_size; + std::array tgid_enable; + + bool operator==(const HwComputeRuntimeInfo& other) const noexcept { + return workgroup_size == other.workgroup_size && tgid_enable == other.tgid_enable; + } +}; + +/** + * Stores information relevant to shader compilation sourced from liverpool registers. + * It may potentially differ with the same shader module so must be checked. + * It's also possible to store any other custom information that needs to be part of shader key. + */ +struct RuntimeInfo { + SwStage sw_stage; + HwStage hw_stage; + struct Properties { + AmdGpu::FpDenormMode fp_denorm_mode32; + AmdGpu::FpDenormMode fp_denorm_mode16_64; + AmdGpu::FpRoundMode fp_round_mode32; + AmdGpu::FpRoundMode fp_round_mode16_64; + u32 num_user_data; + u32 num_input_vgprs; + u32 num_allocated_vgprs; + bool operator==(const Properties&) const noexcept = default; + } props; + union SwInfo { + SwVertexRuntimeInfo vs; + SwTessControlRuntimeInfo tcs; + SwTessEvalRuntimeInfo tes; + } sw; + union HwInfo { + HwLocalRuntimeInfo ls; + HwExportRuntimeInfo es; + HwGeometryRuntimeInfo gs; + HwVertexRuntimeInfo vs; + HwFragmentRuntimeInfo fs; + HwComputeRuntimeInfo cs; + } hw; + + void Initialize(HwStage stage, SwStage l_stage) { + memset(this, 0, sizeof(*this)); + this->hw_stage = stage; + this->sw_stage = l_stage; + if (stage == HwStage::Fragment) { + hw.fs.num_samples = 1; + } + } + + bool operator==(const RuntimeInfo& other) const noexcept { + return hw_stage == other.hw_stage && sw_stage == other.sw_stage && props == other.props && + HasSameSwInfo(other.sw) && HasSameHwInfo(other.hw); + } + + bool HasSameSwInfo(const SwInfo& other) const noexcept { + switch (sw_stage) { + case SwStage::Vertex: + return sw.vs == other.vs; + case SwStage::TessellationControl: + return sw.tcs == other.tcs; + case SwStage::TessellationEval: + return sw.tes == other.tes; + default: + return true; + } + } + + bool HasSameHwInfo(const HwInfo& other) const noexcept { + switch (hw_stage) { + case HwStage::Local: + return hw.ls == other.ls; + case HwStage::Export: + return hw.es == other.es; + case HwStage::Geometry: + return hw.gs == other.gs; + case HwStage::Vertex: + return hw.vs == other.vs; + case HwStage::Fragment: + return hw.fs == other.fs; + case HwStage::Compute: + return hw.cs == other.cs; + default: + return true; + } + } + + void InitFromTessConstants(Shader::TessellationDataConstantBuffer& tess_constants) { + if (sw_stage == SwStage::TessellationControl) { + sw.tcs.hs_output_cp_stride = tess_constants.hs_cp_stride; + sw.tcs.ls_stride = tess_constants.ls_stride; + sw.tcs.hs_output_base = tess_constants.hs_output_base; + } else if (sw_stage == SwStage::TessellationEval) { + sw.tes.hs_output_cp_stride = tess_constants.hs_cp_stride; + } + } +}; + +} // namespace Shader + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(const Shader::HwStage stage, format_context& ctx) const { + constexpr static std::array names = {"fs", "vs", "gs", "es", "hs", "ls", "cs"}; + return fmt::format_to(ctx.out(), "{}", names[static_cast(stage)]); + } +}; diff --git a/gpu/shadps4/shader_recompiler/specialization.h b/gpu/shadps4/shader_recompiler/specialization.h new file mode 100644 index 0000000..75b9dc9 --- /dev/null +++ b/gpu/shadps4/shader_recompiler/specialization.h @@ -0,0 +1,252 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/types.h" +#include "shader_recompiler/backend/bindings.h" +#include "shader_recompiler/frontend/fetch_shader.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/profile.h" + +namespace Shader { + +struct VsAttribSpecialization { + u32 divisor{}; + AmdGpu::NumberClass num_class{}; + AmdGpu::CompMapping dst_select{}; + + bool operator==(const VsAttribSpecialization&) const = default; +}; + +struct BufferSpecialization { + u32 stride : 14; + u32 is_formatted : 1; + u32 swizzle_enable : 1; + u32 data_format : 6; + u32 num_format : 4; + u32 index_stride : 2; + u32 element_size : 2; + AmdGpu::CompMapping dst_select{}; + AmdGpu::NumberConversion num_conversion{}; + + bool operator==(const BufferSpecialization& other) const { + return stride == other.stride && is_formatted == other.is_formatted && + swizzle_enable == other.swizzle_enable && + (!is_formatted || + (data_format == other.data_format && num_format == other.num_format && + dst_select == other.dst_select && num_conversion == other.num_conversion)) && + (!swizzle_enable || + (index_stride == other.index_stride && element_size == other.element_size)); + } +}; + +struct ImageSpecialization { + AmdGpu::ImageType type = AmdGpu::ImageType::Color2D; + bool is_integer = false; + bool is_storage = false; + bool is_cube = false; + bool is_srgb = false; + AmdGpu::CompMapping dst_select{}; + AmdGpu::NumberConversion num_conversion{}; + // FIXME any pipeline cache changes needed? + u32 num_bindings = 0; + + bool operator==(const ImageSpecialization&) const = default; +}; + +struct FMaskSpecialization { + u32 width; + u32 height; + + bool operator==(const FMaskSpecialization&) const = default; +}; + +struct SamplerSpecialization { + u8 force_unnormalized : 1; + u8 force_degamma : 1; + + bool operator==(const SamplerSpecialization&) const = default; +}; + +/** + * Alongside runtime information, this structure also checks bound resources + * for compatibility. Can be used as a key for storing shader permutations. + * Is separate from runtime information, because resource layout can only be deduced + * after the first compilation of a module. + */ +struct StageSpecialization { + static constexpr size_t MaxStageResources = 128; + + const Info* info{}; + RuntimeInfo runtime_info{}; + std::bitset bitset{}; + std::optional fetch_shader_data{}; + boost::container::small_vector vs_attribs; + boost::container::small_vector buffers; + boost::container::small_vector images; + boost::container::small_vector fmasks; + boost::container::small_vector samplers; + Backend::Bindings start{}; + + StageSpecialization() = default; + StageSpecialization(const Info& info_, RuntimeInfo runtime_info_, const Profile& profile_, + Backend::Bindings start_) + : info{&info_}, runtime_info{runtime_info_}, start{start_} { + fetch_shader_data = Gcn::ParseFetchShader(info_); + if (info_.sw_stage == SwStage::Vertex && fetch_shader_data) { + // Specialize shader on VS input number types to follow spec. + ForEachSharp(vs_attribs, fetch_shader_data->attributes, + [this](auto& spec, const auto& desc, AmdGpu::Buffer sharp) { + using InstanceIdType = Shader::Gcn::VertexAttribute::InstanceIdType; + if (const auto step_rate = desc.GetStepRate(); + step_rate != InstanceIdType::None) { + spec.divisor = step_rate == InstanceIdType::OverStepRate0 + ? runtime_info.sw.vs.step_rate_0 + : (step_rate == InstanceIdType::OverStepRate1 + ? runtime_info.sw.vs.step_rate_1 + : 1); + } + spec.num_class = AmdGpu::GetNumberClass(sharp.GetNumberFmt()); + spec.dst_select = sharp.DstSelect(); + }); + } + u32 binding{}; + ForEachSharp(binding, buffers, info->buffers, + [](auto& spec, const auto& desc, AmdGpu::Buffer sharp) { + spec.stride = sharp.GetStride(); + spec.is_formatted = desc.is_formatted; + spec.swizzle_enable = sharp.swizzle_enable; + if (spec.is_formatted) { + spec.data_format = static_cast(sharp.GetDataFmt()); + spec.num_format = static_cast(sharp.GetNumberFmt()); + spec.dst_select = sharp.DstSelect(); + spec.num_conversion = sharp.GetNumberConversion(); + } + if (spec.swizzle_enable) { + spec.index_stride = sharp.index_stride; + spec.element_size = sharp.element_size; + } + }); + ForEachSharp(binding, images, info->images, + [&](auto& spec, const auto& desc, AmdGpu::Image sharp) { + spec.type = sharp.GetViewType(desc.is_array); + spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt()); + spec.is_storage = desc.is_written; + spec.is_cube = sharp.IsCube(); + if (spec.is_storage) { + spec.dst_select = sharp.DstSelect(); + } else { + spec.is_srgb = sharp.GetNumberFmt() == AmdGpu::NumberFormat::Srgb; + } + spec.num_conversion = sharp.GetNumberConversion(); + spec.num_bindings = desc.NumBindings(*info); + }); + ForEachSharp(binding, fmasks, info->fmasks, + [](auto& spec, const auto& desc, AmdGpu::Image sharp) { + spec.width = sharp.width; + spec.height = sharp.height; + }); + ForEachSharp(samplers, info->samplers, + [](auto& spec, const auto& desc, AmdGpu::Sampler sharp) { + spec.force_unnormalized = sharp.force_unnormalized; + spec.force_degamma = sharp.force_degamma; + }); + + // Initialize runtime_info fields that rely on analysis in tessellation passes + if (info->sw_stage == SwStage::TessellationControl || + info->sw_stage == SwStage::TessellationEval) { + TessellationDataConstantBuffer tess_constants{}; + info->ReadTessConstantBuffer(tess_constants); + runtime_info.InitFromTessConstants(tess_constants); + } + } + + void ForEachSharp(auto& spec_list, auto& desc_list, auto&& func) { + for (const auto& desc : desc_list) { + auto& spec = spec_list.emplace_back(); + const auto sharp = desc.GetSharp(*info); + if (!sharp) { + continue; + } + func(spec, desc, sharp); + } + } + + void ForEachSharp(u32& binding, auto& spec_list, auto& desc_list, auto&& func) { + for (const auto& desc : desc_list) { + auto& spec = spec_list.emplace_back(); + const auto sharp = desc.GetSharp(*info); + if (!sharp) { + binding++; + continue; + } + bitset.set(binding++); + func(spec, desc, sharp); + } + } + + [[nodiscard]] bool Valid() const { + return info != nullptr; + } + + bool operator==(const StageSpecialization& other) const { + if (!Valid()) { + return false; + } + + if (vs_attribs != other.vs_attribs) { + return false; + } + + if (runtime_info != other.runtime_info) { + return false; + } + + if (fetch_shader_data != other.fetch_shader_data) { + return false; + } + + if (fmasks != other.fmasks) { + return false; + } + + // For VS which only generates geometry and doesn't have any inputs, its start + // bindings still may change as they depend on previously processed FS. The check below + // handles this case and prevents generation of redundant permutations. This is also safe + // for other types of shaders with no bindings. + if (bitset.none() && other.bitset.none()) { + return true; + } + + if (start != other.start) { + return false; + } + + u32 binding{}; + for (u32 i = 0; i < buffers.size(); i++) { + if (other.bitset[binding++] && buffers[i] != other.buffers[i]) { + return false; + } + } + for (u32 i = 0; i < images.size(); i++) { + if (other.bitset[binding++] && images[i] != other.images[i]) { + return false; + } + } + + for (u32 i = 0; i < samplers.size(); i++) { + if (samplers[i] != other.samplers[i]) { + return false; + } + } + return true; + } + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& ar); +}; + +} // namespace Shader diff --git a/gpu/shadps4/video_core/amdgpu/cb_db_extent.h b/gpu/shadps4/video_core/amdgpu/cb_db_extent.h new file mode 100644 index 0000000..623c72b --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/cb_db_extent.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace AmdGpu { + +union CbDbExtent { + struct { + u16 width; + u16 height; + }; + u32 raw; + + bool Valid() const { + return raw != 0; + } +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/liverpool.cpp b/gpu/shadps4/video_core/amdgpu/liverpool.cpp new file mode 100644 index 0000000..d7b434e --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/liverpool.cpp @@ -0,0 +1,1200 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/assert.h" +#include "common/debug.h" +#include "common/polyfill_thread.h" +#include "common/thread.h" +#include "core/debug_state.h" +#include "core/emulator_settings.h" +#include "core/libraries/kernel/process.h" +#include "core/libraries/videoout/driver.h" +#include "core/memory.h" +#include "core/platform.h" +#include "video_core/amdgpu/liverpool.h" +#include "video_core/amdgpu/pm4_cmds.h" +#include "video_core/renderdoc.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" + +namespace AmdGpu { + +static const char* dcb_task_name{"DCB_TASK"}; +static const char* ccb_task_name{"CCB_TASK"}; + +#define MAX_NAMES 56 +static_assert(Liverpool::NumComputeRings <= MAX_NAMES); + +#define NAME_NUM(z, n, name) BOOST_PP_STRINGIZE(name) BOOST_PP_STRINGIZE(n), +#define NAME_ARRAY(name, num) {BOOST_PP_REPEAT(num, NAME_NUM, name)} + +static const char* acb_task_name[] = NAME_ARRAY(ACB_TASK, MAX_NAMES); + +#define YIELD(name) \ + FIBER_EXIT; \ + co_yield {}; \ + FIBER_ENTER(name); + +#define YIELD_CE() YIELD(ccb_task_name) +#define YIELD_GFX() YIELD(dcb_task_name) +#define YIELD_ASC(id) YIELD(acb_task_name[id]) + +#define RESUME(task, name) \ + FIBER_EXIT; \ + task.handle.resume(); \ + FIBER_ENTER(name); + +#define RESUME_CE(task) RESUME(task, ccb_task_name) +#define RESUME_GFX(task) RESUME(task, dcb_task_name) +#define RESUME_ASC(task, id) RESUME(task, acb_task_name[id]) + +std::array Liverpool::ConstantEngine::constants_heap; + +static std::span NextPacket(std::span span, size_t offset) { + if (offset > span.size()) { + LOG_ERROR( + Lib_GnmDriver, + ": packet length exceeds remaining submission size. Packet dword count={}, remaining " + "submission dwords={}", + offset, span.size()); + // Return empty subspan so check for next packet bails out + return {}; + } + + return span.subspan(offset); +} + +Liverpool::Liverpool() : guest_markers_enabled{EmulatorSettings.IsVkGuestMarkersEnabled()} { + num_counter_pairs = Libraries::Kernel::sceKernelIsNeoMode() ? 16 : 8; + process_thread = std::jthread{std::bind_front(&Liverpool::Process, this)}; +} + +Liverpool::~Liverpool() { + process_thread.request_stop(); + process_thread.join(); +} + +void Liverpool::ProcessCommands() { + // Process incoming commands with high priority + while (num_commands) { + Common::UniqueFunction callback{}; + { + std::scoped_lock lk{submit_mutex}; + callback = std::move(command_queue.front()); + command_queue.pop(); + --num_commands; + } + callback(); + } +} + +void Liverpool::Process(std::stop_token stoken) { + Common::SetCurrentThreadName("shadPS4:GpuCommandProcessor"); + gpu_id = std::this_thread::get_id(); +#ifdef __linux__ + gpu_tid = gettid(); +#endif + + while (!stoken.stop_requested()) { + { + std::unique_lock lk{submit_mutex}; + Common::CondvarWait(submit_cv, lk, stoken, + [this] { return num_commands || num_submits || submit_done; }); + } + if (stoken.stop_requested()) { + break; + } + + VideoCore::StartCapture(); + + curr_qid = -1; + + while (num_submits || num_commands) { + ProcessCommands(); + + curr_qid = (curr_qid + 1) % num_mapped_queues; + + auto& queue = mapped_queues[curr_qid]; + + Task::Handle task{}; + { + std::scoped_lock lock{queue.m_access}; + if (queue.submits.empty()) { + continue; + } + task = queue.submits.front(); + } + task.resume(); + + if (task.done()) { + task.destroy(); + + std::scoped_lock lock{queue.m_access}; + queue.submits.pop(); + + --num_submits; + std::scoped_lock lock2{submit_mutex}; + submit_cv.notify_all(); + } + } + + if (submit_done) { + VideoCore::EndCapture(); + if (rasterizer) { + rasterizer->OnSubmit(); + rasterizer->Flush(); + } + submit_done = false; + } + + Platform::IrqC::Instance()->Signal(Platform::InterruptId::GpuIdle); + } +} + +Liverpool::Task Liverpool::ProcessCeUpdate(std::span ccb) { + FIBER_ENTER(ccb_task_name); + + while (!ccb.empty()) { + ProcessCommands(); + + const auto* header = reinterpret_cast(ccb.data()); + const u32 type = header->type; + if (type != 3) { + // No other types of packets were spotted so far + UNREACHABLE_MSG("Invalid PM4 type {}", type); + } + + const PM4ItOpcode opcode = header->type3.opcode; + const auto* it_body = reinterpret_cast(header) + 1; + switch (opcode) { + case PM4ItOpcode::Nop: { + // const auto* nop = reinterpret_cast(header); + break; + } + case PM4ItOpcode::WriteConstRam: { + const auto* write_const = reinterpret_cast(header); + memcpy(cblock.constants_heap.data() + write_const->Offset(), &write_const->data, + write_const->Size()); + break; + } + case PM4ItOpcode::DumpConstRam: { + const auto* dump_const = reinterpret_cast(header); + memcpy(dump_const->Address(), + cblock.constants_heap.data() + dump_const->Offset(), dump_const->Size()); + break; + } + case PM4ItOpcode::IncrementCeCounter: { + ++cblock.ce_count; + break; + } + case PM4ItOpcode::WaitOnDeCounterDiff: { + const auto diff = it_body[0]; + while ((cblock.de_count - cblock.ce_count) >= diff) { + YIELD_CE(); + } + break; + } + case PM4ItOpcode::IndirectBufferConst: { + const auto* indirect_buffer = reinterpret_cast(header); + auto task = + ProcessCeUpdate({indirect_buffer->Address(), indirect_buffer->ib_size}); + RESUME_CE(task); + + while (!task.handle.done()) { + YIELD_CE(); + RESUME_CE(task); + } + break; + } + default: + const u32 count = header->type3.NumWords(); + UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}", + static_cast(opcode), count); + } + ccb = NextPacket(ccb, header->type3.NumWords() + 1); + } + + FIBER_EXIT; +} + +Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span ccb) { + FIBER_ENTER(dcb_task_name); + + cblock.Reset(); + + // TODO: potentially, ASCs also can depend on CE and in this case the + // CE task should be moved into more global scope + Task ce_task{}; + + if (!ccb.empty()) { + // In case of CCB provided kick off CE asap to have the constant heap ready to use + ce_task = ProcessCeUpdate(ccb); + RESUME_GFX(ce_task); + } + + const auto base_addr = reinterpret_cast(dcb.data()); + while (!dcb.empty()) { + ProcessCommands(); + + const auto* header = reinterpret_cast(dcb.data()); + const u32 type = header->type; + + switch (type) { + default: + UNREACHABLE_MSG("Wrong PM4 type {}", type); + break; + case 0: + UNREACHABLE_MSG("Unimplemented PM4 type 0, base reg: {}, size: {}", + header->type0.base.Value(), header->type0.NumWords()); + break; + case 2: + // Type-2 packet are used for padding purposes + dcb = NextPacket(dcb, 1); + continue; + case 3: + const u32 count = header->type3.NumWords(); + const PM4ItOpcode opcode = header->type3.opcode; + switch (opcode) { + case PM4ItOpcode::Nop: { + const auto* nop = reinterpret_cast(header); + if (nop->header.count.Value() == 0) { + break; + } + + switch (nop->data_block[0]) { + case PM4CmdNop::PayloadType::PatchedFlip: { + // There is no evidence that GPU CP drives flip events by parsing + // special NOP packets. For convenience lets assume that it does. + Platform::IrqC::Instance()->Signal(Platform::InterruptId::GfxFlip); + break; + } + case PM4CmdNop::PayloadType::DebugMarkerPush: { + if (guest_markers_enabled) { + const auto marker_sz = nop->header.count.Value() * 2; + const std::string_view label{ + reinterpret_cast(&nop->data_block[1]), marker_sz}; + rasterizer->ScopeMarkerBegin(label, true); + } + break; + } + case PM4CmdNop::PayloadType::DebugColorMarkerPush: { + if (guest_markers_enabled) { + const auto marker_sz = nop->header.count.Value() * 2; + const std::string_view label{ + reinterpret_cast(&nop->data_block[1]), marker_sz}; + const u32 color = *reinterpret_cast( + reinterpret_cast(&nop->data_block[1]) + marker_sz); + rasterizer->ScopedMarkerInsertColor(label, color, true); + } + break; + } + case PM4CmdNop::PayloadType::DebugMarkerPop: { + if (guest_markers_enabled) { + rasterizer->ScopeMarkerEnd(true); + } + break; + } + default: + break; + } + break; + } + case PM4ItOpcode::ContextControl: { + break; + } + case PM4ItOpcode::ClearState: { + regs.SetDefaults(); + break; + } + case PM4ItOpcode::SetConfigReg: { + const auto* set_data = reinterpret_cast(header); + const auto reg_addr = Regs::ConfigRegWordOffset + set_data->reg_offset; + const auto* payload = reinterpret_cast(header + 2); + std::memcpy(®s.reg_array[reg_addr], payload, (count - 1) * sizeof(u32)); + break; + } + case PM4ItOpcode::SetContextReg: { + const auto* set_data = reinterpret_cast(header); + const auto reg_addr = Regs::ContextRegWordOffset + set_data->reg_offset; + const auto* payload = reinterpret_cast(header + 2); + + std::memcpy(®s.reg_array[reg_addr], payload, (count - 1) * sizeof(u32)); + + // In the case of HW, render target memory has alignment as color block operates on + // tiles. There is no information of actual resource extents stored in CB context + // regs, so any deduction of it from slices/pitch will lead to a larger surface + // created. The same applies to the depth targets. Fortunately, the guest always + // sends a trailing NOP packet right after the context regs setup, so we can use the + // heuristic below and extract the hint to determine actual resource dims. + + switch (reg_addr) { + case ContextRegs::CbColor0Base: + case ContextRegs::CbColor1Base: + case ContextRegs::CbColor2Base: + case ContextRegs::CbColor3Base: + case ContextRegs::CbColor4Base: + case ContextRegs::CbColor5Base: + case ContextRegs::CbColor6Base: + case ContextRegs::CbColor7Base: { + const auto col_buf_id = (reg_addr - ContextRegs::CbColor0Base) / + (ContextRegs::CbColor1Base - ContextRegs::CbColor0Base); + ASSERT(col_buf_id < NUM_COLOR_BUFFERS); + + const auto nop_offset = header->type3.count; + if (nop_offset == 0x0e || nop_offset == 0x0d || nop_offset == 0x0b) { + ASSERT_MSG(payload[nop_offset] == 0xc0001000, + "NOP hint is missing in CB setup sequence"); + last_cb_extent[col_buf_id].raw = payload[nop_offset + 1]; + } else { + last_cb_extent[col_buf_id].raw = 0; + } + break; + } + case ContextRegs::CbColor0Cmask: + case ContextRegs::CbColor1Cmask: + case ContextRegs::CbColor2Cmask: + case ContextRegs::CbColor3Cmask: + case ContextRegs::CbColor4Cmask: + case ContextRegs::CbColor5Cmask: + case ContextRegs::CbColor6Cmask: + case ContextRegs::CbColor7Cmask: { + const auto col_buf_id = + (reg_addr - ContextRegs::CbColor0Cmask) / + (ContextRegs::CbColor1Cmask - ContextRegs::CbColor0Cmask); + ASSERT(col_buf_id < NUM_COLOR_BUFFERS); + + const auto nop_offset = header->type3.count; + if (nop_offset == 0x04) { + ASSERT_MSG(payload[nop_offset] == 0xc0001000, + "NOP hint is missing in CB setup sequence"); + last_cb_extent[col_buf_id].raw = payload[nop_offset + 1]; + } + break; + } + case ContextRegs::DbZInfo: { + if (header->type3.count == 8) { + ASSERT_MSG(payload[20] == 0xc0001000, + "NOP hint is missing in DB setup sequence"); + last_db_extent.raw = payload[21]; + } else { + last_db_extent.raw = 0; + } + break; + } + default: + break; + } + break; + } + case PM4ItOpcode::SetShReg: { + const auto* set_data = reinterpret_cast(header); + const auto set_size = (count - 1) * sizeof(u32); + + if (set_data->reg_offset >= 0x200 && + set_data->reg_offset <= (0x200 + sizeof(ComputeProgram) / 4)) { + ASSERT(set_size <= sizeof(ComputeProgram)); + auto* addr = reinterpret_cast(&mapped_queues[GfxQueueId].cs_state) + + (set_data->reg_offset - 0x200); + std::memcpy(addr, header + 2, set_size); + } else { + std::memcpy(®s.reg_array[Regs::ShRegWordOffset + set_data->reg_offset], + header + 2, set_size); + } + break; + } + case PM4ItOpcode::SetUconfigReg: { + const auto* set_data = reinterpret_cast(header); + std::memcpy(®s.reg_array[Regs::UconfigRegWordOffset + set_data->reg_offset], + header + 2, (count - 1) * sizeof(u32)); + break; + } + case PM4ItOpcode::SetPredication: { + LOG_WARNING(Render, "Unimplemented IT_SET_PREDICATION"); + break; + } + case PM4ItOpcode::IndexType: { + const auto* index_type = reinterpret_cast(header); + regs.index_buffer_type.raw = index_type->raw; + break; + } + case PM4ItOpcode::DrawIndex2: { + const auto* draw_index = reinterpret_cast(header); + regs.max_index_size = draw_index->max_size; + regs.index_base_address.base_addr_lo = draw_index->index_base_lo; + regs.index_base_address.base_addr_hi = draw_index->index_base_hi; + regs.num_indices = draw_index->index_count; + regs.draw_initiator = draw_index->draw_initiator; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker("gfx:{}:DrawIndex2", fmt::make_format_args(cmd_address), + [&] { rasterizer->Draw(true); }); + break; + } + case PM4ItOpcode::DrawIndexOffset2: { + const auto* draw_index_off = + reinterpret_cast(header); + regs.max_index_size = draw_index_off->max_size; + regs.num_indices = draw_index_off->index_count; + regs.draw_initiator = draw_index_off->draw_initiator; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker( + "gfx:{}:DrawIndexOffset2", fmt::make_format_args(cmd_address), + [&] { rasterizer->Draw(true, draw_index_off->index_offset); }); + break; + } + case PM4ItOpcode::DrawIndexAuto: { + const auto* draw_index = reinterpret_cast(header); + regs.num_indices = draw_index->index_count; + regs.draw_initiator = draw_index->draw_initiator; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker("gfx:{}:DrawIndexAuto", fmt::make_format_args(cmd_address), + [&] { rasterizer->Draw(false); }); + break; + } + case PM4ItOpcode::DrawIndirect: { + const auto* draw_indirect = reinterpret_cast(header); + const auto offset = draw_indirect->data_offset; + const auto stride = sizeof(DrawIndirectArgs); + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker( + "gfx:{}:DrawIndirect", fmt::make_format_args(cmd_address), [&] { + rasterizer->DrawIndirect(false, indirect_args_addr, offset, stride, 1, 0, + draw_indirect->base_vtx_loc, + draw_indirect->start_inst_loc); + }); + break; + } + case PM4ItOpcode::DrawIndirectMulti: { + const auto* draw_indirect = + reinterpret_cast(header); + const auto offset = draw_indirect->data_offset; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker( + "gfx:{}:DrawIndirectMulti", fmt::make_format_args(cmd_address), [&] { + rasterizer->DrawIndirect(false, indirect_args_addr, offset, + draw_indirect->stride, draw_indirect->count, 0, + draw_indirect->base_vtx_loc, + draw_indirect->start_inst_loc); + }); + break; + } + case PM4ItOpcode::DrawIndexIndirect: { + const auto* draw_index_indirect = + reinterpret_cast(header); + const auto offset = draw_index_indirect->data_offset; + const auto stride = sizeof(DrawIndexedIndirectArgs); + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker( + "gfx:{}:DrawIndexIndirect", fmt::make_format_args(cmd_address), [&] { + rasterizer->DrawIndirect(true, indirect_args_addr, offset, stride, 1, 0, + draw_index_indirect->base_vtx_loc, + draw_index_indirect->start_inst_loc); + }); + break; + } + case PM4ItOpcode::DrawIndexIndirectMulti: { + const auto* draw_index_indirect = + reinterpret_cast(header); + const auto offset = draw_index_indirect->data_offset; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker( + "gfx:{}:DrawIndexIndirectMulti", fmt::make_format_args(cmd_address), [&] { + rasterizer->DrawIndirect( + true, indirect_args_addr, offset, draw_index_indirect->stride, + draw_index_indirect->count, 0, draw_index_indirect->base_vtx_loc, + draw_index_indirect->start_inst_loc); + }); + break; + } + case PM4ItOpcode::DrawIndexIndirectCountMulti: { + const auto* draw_index_indirect = + reinterpret_cast(header); + const auto offset = draw_index_indirect->data_offset; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDump(base_addr, reinterpret_cast(header), regs); + } + if (!rasterizer) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker( + "gfx:{}:DrawIndexIndirectCountMulti", fmt::make_format_args(cmd_address), [&] { + rasterizer->DrawIndirect( + true, indirect_args_addr, offset, draw_index_indirect->stride, + draw_index_indirect->count, + draw_index_indirect->count_indirect_enable.Value() + ? draw_index_indirect->count_addr + : 0, + draw_index_indirect->base_vtx_loc, draw_index_indirect->start_inst_loc); + }); + break; + } + case PM4ItOpcode::DispatchDirect: { + const auto* dispatch_direct = reinterpret_cast(header); + auto& cs_program = GetCsRegs(); + cs_program.dim_x = dispatch_direct->dim_x; + cs_program.dim_y = dispatch_direct->dim_y; + cs_program.dim_z = dispatch_direct->dim_z; + cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDumpCompute(base_addr, reinterpret_cast(header), + cs_program); + } + if (!rasterizer || (cs_program.dispatch_initiator & 1) == 0) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker("gfx:{}:DispatchDirect", fmt::make_format_args(cmd_address), + [&] { rasterizer->DispatchDirect(); }); + break; + } + case PM4ItOpcode::DispatchIndirect: { + const auto* dispatch_indirect = + reinterpret_cast(header); + auto& cs_program = GetCsRegs(); + const auto offset = dispatch_indirect->data_offset; + const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions); + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDumpCompute(base_addr, reinterpret_cast(header), + cs_program); + } + if (!rasterizer || (cs_program.dispatch_initiator & 1) == 0) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker( + "gfx:{}:DispatchIndirect", fmt::make_format_args(cmd_address), + [&] { rasterizer->DispatchIndirect(indirect_args_addr, offset, size); }); + break; + } + case PM4ItOpcode::NumInstances: { + const auto* num_instances = reinterpret_cast(header); + regs.num_instances.num_instances = num_instances->num_instances; + break; + } + case PM4ItOpcode::IndexBase: { + const auto* index_base = reinterpret_cast(header); + regs.index_base_address.base_addr_lo = index_base->addr_lo; + regs.index_base_address.base_addr_hi = index_base->addr_hi; + break; + } + case PM4ItOpcode::IndexBufferSize: { + const auto* index_size = reinterpret_cast(header); + regs.num_indices = index_size->num_indices; + break; + } + case PM4ItOpcode::SetBase: { + const auto* set_base = reinterpret_cast(header); + ASSERT(set_base->base_index == PM4CmdSetBase::BaseIndex::DrawIndexIndirPatchTable); + indirect_args_addr = set_base->Address(); + break; + } + case PM4ItOpcode::EventWrite: { + const auto* event = reinterpret_cast(header); + LOG_DEBUG(Render, "Encountered EventWrite: event_type = {}, event_index = {}", + magic_enum::enum_name(event->event_type.Value()), + magic_enum::enum_name(event->event_index.Value())); + if (event->event_type.Value() == EventType::SoVgtStreamoutFlush) { + // TODO: handle proper synchronization, for now signal that update is done + // immediately + regs.cp_strmout_cntl.offset_update_done = 1; + } else if (event->event_index.Value() == EventIndex::ZpassDone) { + if (event->event_type.Value() == EventType::PixelPipeStatDump) { + static constexpr u64 OcclusionCounterValidMask = 0x8000000000000000ULL; + static constexpr u64 OcclusionCounterStep = 0x2FFFFFFULL; + u64* results = event->Address(); + for (s32 i = 0; i < num_counter_pairs; ++i, results += 2) { + *results = pixel_counter | OcclusionCounterValidMask; + } + pixel_counter += OcclusionCounterStep; + } + } + break; + } + case PM4ItOpcode::EventWriteEos: { + const auto* event_eos = reinterpret_cast(header); + if (rasterizer) { + rasterizer->ProcessDownloadImages(); + } + event_eos->SignalFence([](void* address, u64 data, u32 num_bytes) { + auto* memory = Core::Memory::Instance(); + if (!memory->TryWriteBacking(address, &data, num_bytes)) { + memcpy(address, &data, num_bytes); + } + }); + if (event_eos->command == PM4CmdEventWriteEos::Command::GdsStore) { + ASSERT(event_eos->size == 1); + if (rasterizer) { + rasterizer->Finish(); + const u32 value = rasterizer->ReadDataFromGds(event_eos->gds_index); + *event_eos->Address() = value; + } + } + break; + } + case PM4ItOpcode::EventWriteEop: { + const auto* event_eop = reinterpret_cast(header); + if (rasterizer) { + rasterizer->ProcessDownloadImages(); + } + event_eop->SignalFence( + [](void* address, u64 data, u32 num_bytes) { + auto* memory = Core::Memory::Instance(); + if (!memory->TryWriteBacking(address, &data, num_bytes)) { + memcpy(address, &data, num_bytes); + } + }, + [] { Platform::IrqC::Instance()->Signal(Platform::InterruptId::GfxEop); }); + break; + } + case PM4ItOpcode::DmaData: { + const auto* dma_data = reinterpret_cast(header); + if (dma_data->dst_addr_lo == 0x3022C || !rasterizer) { + break; + } + ASSERT(dma_data->command.das == 0); + if (dma_data->src_sel == DmaDataSrc::Data && dma_data->dst_sel == DmaDataDst::Gds) { + rasterizer->FillBuffer(dma_data->dst_addr_lo, dma_data->NumBytes(), + dma_data->data, true); + } else if ((dma_data->src_sel == DmaDataSrc::Memory || + dma_data->src_sel == DmaDataSrc::MemoryUsingL2) && + dma_data->dst_sel == DmaDataDst::Gds) { + rasterizer->CopyBuffer(dma_data->dst_addr_lo, dma_data->SrcAddress(), + dma_data->NumBytes(), true, false); + } else if (dma_data->src_sel == DmaDataSrc::Data && + (dma_data->dst_sel == DmaDataDst::Memory || + dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) { + rasterizer->FillBuffer(dma_data->DstAddress(), dma_data->NumBytes(), + dma_data->data, false); + } else if (dma_data->src_sel == DmaDataSrc::Gds && + (dma_data->dst_sel == DmaDataDst::Memory || + dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) { + rasterizer->CopyBuffer(dma_data->DstAddress(), dma_data->src_addr_lo, + dma_data->NumBytes(), false, true); + } else if ((dma_data->src_sel == DmaDataSrc::Memory || + dma_data->src_sel == DmaDataSrc::MemoryUsingL2) && + (dma_data->dst_sel == DmaDataDst::Memory || + dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) { + rasterizer->CopyBuffer(dma_data->DstAddress(), + dma_data->SrcAddress(), dma_data->NumBytes(), + false, false); + } else { + UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}", u32(dma_data->src_sel), + u32(dma_data->dst_sel)); + } + break; + } + case PM4ItOpcode::WriteData: { + const auto* write_data = reinterpret_cast(header); + ASSERT(write_data->dst_sel.Value() == 2 || write_data->dst_sel.Value() == 5); + const u32 data_size = (header->type3.count.Value() - 2) * 4; + u64* address = write_data->Address(); + if (!write_data->wr_one_addr.Value()) { + std::memcpy(address, write_data->data, data_size); + } else { + UNREACHABLE(); + } + break; + } + case PM4ItOpcode::CopyData: { + const auto* copy_data = reinterpret_cast(header); + LOG_WARNING(Render, + "unhandled IT_COPY_DATA src_sel = {}, dst_sel = {}, " + "count_sel = {}, wr_confirm = {}, engine_sel = {}", + u32(copy_data->src_sel.Value()), u32(copy_data->dst_sel.Value()), + copy_data->count_sel.Value(), copy_data->wr_confirm.Value(), + u32(copy_data->engine_sel.Value())); + break; + } + case PM4ItOpcode::MemSemaphore: { + const auto* mem_semaphore = reinterpret_cast(header); + if (mem_semaphore->IsSignaling()) { + mem_semaphore->Signal(); + } else { + while (!mem_semaphore->Signaled()) { + YIELD_GFX(); + } + mem_semaphore->Decrement(); + } + break; + } + case PM4ItOpcode::AcquireMem: { + // const auto* acquire_mem = reinterpret_cast(header); + break; + } + case PM4ItOpcode::Rewind: { + if (!rasterizer) { + break; + } + const PM4CmdRewind* rewind = reinterpret_cast(header); + while (!rewind->Valid()) { + YIELD_GFX(); + } + break; + } + case PM4ItOpcode::WaitRegMem: { + const auto* wait_reg_mem = reinterpret_cast(header); + // ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me); + // Optimization: VO label waits are special because the emulator + // will write to the label when presentation is finished. So if + // there are no other submits to yield to we can sleep the thread + // instead and allow other tasks to run. + const u64* wait_addr = wait_reg_mem->Address(); + if (vo_port->IsVoLabel(wait_addr) && + num_submits == mapped_queues[GfxQueueId].submits.size()) { + vo_port->WaitVoLabel([&] { return wait_reg_mem->Test(regs.reg_array); }); + break; + } + while (!wait_reg_mem->Test(regs.reg_array)) { + YIELD_GFX(); + } + break; + } + case PM4ItOpcode::IndirectBuffer: { + const auto* indirect_buffer = reinterpret_cast(header); + auto task = ProcessGraphics( + {indirect_buffer->Address(), indirect_buffer->ib_size}, {}); + RESUME_GFX(task); + + while (!task.handle.done()) { + YIELD_GFX(); + RESUME_GFX(task); + } + break; + } + case PM4ItOpcode::IncrementDeCounter: { + ++cblock.de_count; + break; + } + case PM4ItOpcode::WaitOnCeCounter: { + while (cblock.ce_count <= cblock.de_count && !ce_task.handle.done()) { + RESUME_GFX(ce_task); + } + break; + } + case PM4ItOpcode::PfpSyncMe: { + break; + } + case PM4ItOpcode::StrmoutBufferUpdate: { + const auto* strmout = reinterpret_cast(header); + LOG_WARNING(Render_Vulkan, + "Unimplemented IT_STRMOUT_BUFFER_UPDATE, update_memory = {}, " + "source_select = {}, buffer_select = {}", + strmout->update_memory.Value(), + magic_enum::enum_name(strmout->source_select.Value()), + strmout->buffer_select.Value()); + break; + } + case PM4ItOpcode::GetLodStats: { + LOG_WARNING(Render_Vulkan, "Unimplemented IT_GET_LOD_STATS"); + break; + } + case PM4ItOpcode::CondExec: { + const auto* cond_exec = reinterpret_cast(header); + if (cond_exec->command.Value() != 0) { + LOG_WARNING(Render, "IT_COND_EXEC used a reserved command"); + } + const auto skip = *cond_exec->Address() == false; + if (skip) { + dcb = NextPacket(dcb, + header->type3.NumWords() + 1 + cond_exec->exec_count.Value()); + continue; + } + break; + } + default: + UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}", + static_cast(opcode), count); + } + dcb = NextPacket(dcb, header->type3.NumWords() + 1); + break; + } + } + + if (ce_task.handle) { + while (!ce_task.handle.done()) { + RESUME_GFX(ce_task); + } + ce_task.handle.destroy(); + } + + FIBER_EXIT; +} + +template +Liverpool::Task Liverpool::ProcessCompute(std::span acb, u32 vqid) { + FIBER_ENTER(acb_task_name[vqid]); + auto& queue = asc_queues[{vqid}]; + + struct IndirectPatch { + const PM4Header* header; + VAddr indirect_addr; + }; + boost::container::small_vector indirect_patches; + + auto base_addr = reinterpret_cast(acb.data()); + size_t acb_size = acb.size_bytes(); + while (!acb.empty()) { + ProcessCommands(); + + auto* header = reinterpret_cast(acb.data()); + u32 next_dw_off = header->type3.NumWords() + 1; + + // If we have a buffered packet, use it. + if (queue.tmp_dwords > 0) [[unlikely]] { + header = reinterpret_cast(queue.tmp_packet.data()); + next_dw_off = header->type3.NumWords() + 1 - queue.tmp_dwords; + std::memcpy(queue.tmp_packet.data() + queue.tmp_dwords, acb.data(), + next_dw_off * sizeof(u32)); + queue.tmp_dwords = 0; + } + + // If the packet is split across ring boundary, buffer until next submission + if (next_dw_off > acb.size()) [[unlikely]] { + std::memcpy(queue.tmp_packet.data(), acb.data(), acb.size_bytes()); + queue.tmp_dwords = acb.size(); + if constexpr (!is_indirect) { + *queue.read_addr += acb.size(); + *queue.read_addr %= queue.ring_size_dw; + } + break; + } + + if (header->type == 2) { + // Type-2 packet are used for padding purposes + next_dw_off = 1; + acb = NextPacket(acb, next_dw_off); + if constexpr (!is_indirect) { + *queue.read_addr += next_dw_off; + *queue.read_addr %= queue.ring_size_dw; + } + continue; + } + + if (header->type != 3) { + // No other types of packets were spotted so far + UNREACHABLE_MSG("Invalid PM4 type {}", header->type.Value()); + } + + const PM4ItOpcode opcode = header->type3.opcode; + + const auto* it_body = reinterpret_cast(header) + 1; + switch (opcode) { + case PM4ItOpcode::Nop: { + const auto* nop = reinterpret_cast(header); + break; + } + case PM4ItOpcode::IndirectBuffer: { + const auto* indirect_buffer = reinterpret_cast(header); + auto task = ProcessCompute( + {indirect_buffer->Address(), indirect_buffer->ib_size}, vqid); + RESUME_ASC(task, vqid); + + while (!task.handle.done()) { + YIELD_ASC(vqid); + RESUME_ASC(task, vqid); + } + break; + } + case PM4ItOpcode::DmaData: { + const auto* dma_data = reinterpret_cast(header); + if (dma_data->dst_addr_lo == 0x3022C || !rasterizer) { + break; + } + ASSERT(dma_data->command.das == 0); + if (dma_data->src_sel == DmaDataSrc::Data && dma_data->dst_sel == DmaDataDst::Gds) { + rasterizer->FillBuffer(dma_data->dst_addr_lo, dma_data->NumBytes(), dma_data->data, + true); + } else if ((dma_data->src_sel == DmaDataSrc::Memory || + dma_data->src_sel == DmaDataSrc::MemoryUsingL2) && + dma_data->dst_sel == DmaDataDst::Gds) { + rasterizer->CopyBuffer(dma_data->dst_addr_lo, dma_data->SrcAddress(), + dma_data->NumBytes(), true, false); + } else if (dma_data->src_sel == DmaDataSrc::Data && + (dma_data->dst_sel == DmaDataDst::Memory || + dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) { + rasterizer->FillBuffer(dma_data->DstAddress(), dma_data->NumBytes(), + dma_data->data, false); + } else if (dma_data->src_sel == DmaDataSrc::Gds && + (dma_data->dst_sel == DmaDataDst::Memory || + dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) { + rasterizer->CopyBuffer(dma_data->DstAddress(), dma_data->src_addr_lo, + dma_data->NumBytes(), false, true); + } else if ((dma_data->src_sel == DmaDataSrc::Memory || + dma_data->src_sel == DmaDataSrc::MemoryUsingL2) && + (dma_data->dst_sel == DmaDataDst::Memory || + dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) { + const u32 num_bytes = dma_data->NumBytes(); + const VAddr src_addr = dma_data->SrcAddress(); + const VAddr dst_addr = dma_data->DstAddress(); + const PM4Header* header = + reinterpret_cast(dst_addr - sizeof(PM4Header)); + if (dst_addr >= base_addr && dst_addr < base_addr + acb_size && + num_bytes == sizeof(PM4CmdDispatchIndirect::GroupDimensions) && + header->type == 3 && header->type3.opcode == PM4ItOpcode::DispatchDirect) { + indirect_patches.emplace_back(header, src_addr); + } else { + rasterizer->CopyBuffer(dst_addr, src_addr, num_bytes, false, false); + } + } else { + UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}", u32(dma_data->src_sel), + u32(dma_data->dst_sel)); + } + break; + } + case PM4ItOpcode::AcquireMem: { + break; + } + case PM4ItOpcode::Rewind: { + if (!rasterizer) { + break; + } + const PM4CmdRewind* rewind = reinterpret_cast(header); + while (!rewind->Valid()) { + YIELD_ASC(vqid); + } + break; + } + case PM4ItOpcode::SetShReg: { + const auto* set_data = reinterpret_cast(header); + const auto set_size = (header->type3.NumWords() - 1) * sizeof(u32); + + if (set_data->reg_offset >= 0x200 && + set_data->reg_offset <= (0x200 + sizeof(ComputeProgram) / 4)) { + ASSERT(set_size <= sizeof(ComputeProgram)); + auto* addr = reinterpret_cast(&mapped_queues[vqid + 1].cs_state) + + (set_data->reg_offset - 0x200); + std::memcpy(addr, header + 2, set_size); + } else { + std::memcpy(®s.reg_array[Regs::ShRegWordOffset + set_data->reg_offset], + header + 2, set_size); + } + break; + } + case PM4ItOpcode::SetQueueReg: { + const auto* set_data = reinterpret_cast(header); + LOG_WARNING(Render, "Encountered compute SetQueueReg: vqid = {}, reg_offset = {:#x}", + set_data->vqid.Value(), set_data->reg_offset.Value()); + break; + } + case PM4ItOpcode::DispatchDirect: { + const auto* dispatch_direct = reinterpret_cast(header); + if (auto it = std::ranges::find(indirect_patches, header, &IndirectPatch::header); + it != indirect_patches.end()) { + const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions); + rasterizer->DispatchIndirect(it->indirect_addr, 0, size); + break; + } + auto& cs_program = GetCsRegs(); + cs_program.dim_x = dispatch_direct->dim_x; + cs_program.dim_y = dispatch_direct->dim_y; + cs_program.dim_z = dispatch_direct->dim_z; + cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator; + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDumpCompute(base_addr, reinterpret_cast(header), + cs_program); + } + if (!rasterizer || (cs_program.dispatch_initiator & 1) == 0) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker("asc[{}]:{}:DispatchDirect", + fmt::make_format_args(vqid, cmd_address), + [&] { rasterizer->DispatchDirect(); }); + break; + } + case PM4ItOpcode::DispatchIndirect: { + const auto* dispatch_indirect = + reinterpret_cast(header); + auto& cs_program = GetCsRegs(); + const auto ib_address = dispatch_indirect->Address(); + const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions); + if (DebugState.DumpingCurrentReg()) { + DebugState.PushRegsDumpCompute(base_addr, reinterpret_cast(header), + cs_program); + } + if (!rasterizer || (cs_program.dispatch_initiator & 1) == 0) { + break; + } + const auto cmd_address = reinterpret_cast(header); + rasterizer->ScopeMarker("asc[{}]:{}:DispatchIndirect", + fmt::make_format_args(vqid, cmd_address), + [&] { rasterizer->DispatchIndirect(ib_address, 0, size); }); + break; + } + case PM4ItOpcode::WriteData: { + const auto* write_data = reinterpret_cast(header); + ASSERT(write_data->dst_sel.Value() == 2 || write_data->dst_sel.Value() == 5); + const u32 data_size = (header->type3.count.Value() - 2) * 4; + if (!write_data->wr_one_addr.Value()) { + std::memcpy(write_data->Address(), write_data->data, data_size); + } else { + UNREACHABLE(); + } + break; + } + case PM4ItOpcode::MemSemaphore: { + const auto* mem_semaphore = reinterpret_cast(header); + if (mem_semaphore->IsSignaling()) { + mem_semaphore->Signal(); + } else { + while (!mem_semaphore->Signaled()) { + YIELD_ASC(vqid); + } + mem_semaphore->Decrement(); + } + break; + } + case PM4ItOpcode::WaitRegMem: { + const auto* wait_reg_mem = reinterpret_cast(header); + ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me); + while (!wait_reg_mem->Test(regs.reg_array)) { + YIELD_ASC(vqid); + } + break; + } + case PM4ItOpcode::ReleaseMem: { + const auto* release_mem = reinterpret_cast(header); + if (rasterizer) { + rasterizer->ProcessDownloadImages(); + } + release_mem->SignalFence( + [pipe_id = queue.pipe_id] { + Platform::IrqC::Instance()->Signal(static_cast(pipe_id)); + }, + [this](VAddr dst, u16 gds_index, u16 num_dwords) { + rasterizer->CopyBuffer(dst, gds_index, num_dwords * sizeof(u32), false, true); + }); + break; + } + case PM4ItOpcode::EventWrite: { + // const auto* event = reinterpret_cast(header); + break; + } + default: + UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}", + static_cast(opcode), header->type3.NumWords()); + } + + acb = NextPacket(acb, next_dw_off); + + if constexpr (!is_indirect) { + *queue.read_addr += next_dw_off; + *queue.read_addr %= queue.ring_size_dw; + } + } + + FIBER_EXIT; +} + +Liverpool::CmdBuffer Liverpool::CopyCmdBuffers(std::span dcb, std::span ccb) { + auto& queue = mapped_queues[GfxQueueId]; + ASSERT_MSG(queue.dcb_buffer.capacity() >= queue.dcb_buffer_offset + dcb.size(), + "dcb copy buffer out of reserved space"); + ASSERT_MSG(queue.ccb_buffer.capacity() >= queue.ccb_buffer_offset + ccb.size(), + "ccb copy buffer out of reserved space"); + + queue.dcb_buffer.resize( + std::max(queue.dcb_buffer.size(), queue.dcb_buffer_offset + dcb.size())); + queue.ccb_buffer.resize( + std::max(queue.ccb_buffer.size(), queue.ccb_buffer_offset + ccb.size())); + + const u32 prev_dcb_buffer_offset = queue.dcb_buffer_offset; + const u32 prev_ccb_buffer_offset = queue.ccb_buffer_offset; + if (!dcb.empty()) { + std::memcpy(queue.dcb_buffer.data() + queue.dcb_buffer_offset, dcb.data(), + dcb.size_bytes()); + queue.dcb_buffer_offset += dcb.size(); + dcb = std::span{queue.dcb_buffer.begin() + prev_dcb_buffer_offset, + queue.dcb_buffer.begin() + queue.dcb_buffer_offset}; + } + + if (!ccb.empty()) { + std::memcpy(queue.ccb_buffer.data() + queue.ccb_buffer_offset, ccb.data(), + ccb.size_bytes()); + queue.ccb_buffer_offset += ccb.size(); + ccb = std::span{queue.ccb_buffer.begin() + prev_ccb_buffer_offset, + queue.ccb_buffer.begin() + queue.ccb_buffer_offset}; + } + + return std::make_pair(dcb, ccb); +} + +void Liverpool::SubmitGfx(std::span dcb, std::span ccb) { + auto& queue = mapped_queues[GfxQueueId]; + + if (EmulatorSettings.IsCopyGpuBuffers()) { + std::tie(dcb, ccb) = CopyCmdBuffers(dcb, ccb); + } + + auto task = ProcessGraphics(dcb, ccb); + { + std::scoped_lock lock{queue.m_access}; + queue.submits.emplace(task.handle); + } + + std::scoped_lock lk{submit_mutex}; + ++num_submits; + submit_cv.notify_one(); +} + +void Liverpool::SubmitAsc(u32 gnm_vqid, std::span acb) { + ASSERT_MSG(gnm_vqid > 0 && gnm_vqid < NumTotalQueues, "Invalid virtual ASC queue index"); + auto& queue = mapped_queues[gnm_vqid]; + + const auto vqid = gnm_vqid - 1; + const auto& task = ProcessCompute(acb, vqid); + { + std::scoped_lock lock{queue.m_access}; + queue.submits.emplace(task.handle); + } + + std::scoped_lock lk{submit_mutex}; + num_mapped_queues = std::max(num_mapped_queues, gnm_vqid + 1); + ++num_submits; + submit_cv.notify_one(); +} + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/liverpool.h b/gpu/shadps4/video_core/amdgpu/liverpool.h new file mode 100644 index 0000000..1a64f50 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/liverpool.h @@ -0,0 +1,247 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/slot_vector.h" +#include "common/types.h" +#include "common/unique_function.h" +#include "video_core/amdgpu/cb_db_extent.h" +#include "video_core/amdgpu/regs.h" + +namespace Vulkan { +class Rasterizer; +} + +namespace Libraries::VideoOut { +struct VideoOutPort; +} + +namespace AmdGpu { + +struct Liverpool { + static constexpr u32 GfxQueueId = 0u; + static constexpr u32 NumGfxRings = 1u; // actually 2, but HP is reserved by system software + static constexpr u32 NumComputePipes = 7u; // actually 8, but #7 is reserved by system software + static constexpr u32 NumQueuesPerPipe = 8u; + static constexpr u32 NumComputeRings = NumComputePipes * NumQueuesPerPipe; + static constexpr u32 NumTotalQueues = NumGfxRings + NumComputeRings; + static_assert(NumTotalQueues < 64u); // need to fit into u64 bitmap for ffs + + enum ContextRegs : u32 { + DbZInfo = 0xA010, + CbColor0Base = 0xA318, + CbColor1Base = 0xA327, + CbColor2Base = 0xA336, + CbColor3Base = 0xA345, + CbColor4Base = 0xA354, + CbColor5Base = 0xA363, + CbColor6Base = 0xA372, + CbColor7Base = 0xA381, + CbColor0Cmask = 0xA31F, + CbColor1Cmask = 0xA32E, + CbColor2Cmask = 0xA33D, + CbColor3Cmask = 0xA34C, + CbColor4Cmask = 0xA35B, + CbColor5Cmask = 0xA36A, + CbColor6Cmask = 0xA379, + CbColor7Cmask = 0xA388, + }; + + Regs regs{}; + std::array last_cb_extent{}; + CbDbExtent last_db_extent{}; + +public: + explicit Liverpool(); + ~Liverpool(); + + void SubmitGfx(std::span dcb, std::span ccb); + void SubmitAsc(u32 gnm_vqid, std::span acb); + + void SubmitDone() noexcept { + std::scoped_lock lk{submit_mutex}; + mapped_queues[GfxQueueId].ccb_buffer_offset = 0; + mapped_queues[GfxQueueId].dcb_buffer_offset = 0; + submit_done = true; + submit_cv.notify_one(); + } + + void WaitGpuIdle() noexcept { + std::unique_lock lk{submit_mutex}; + submit_cv.wait(lk, [this] { return num_submits == 0; }); + } + + bool IsGpuIdle() const { + return num_submits == 0; + } + + void SetVoPort(Libraries::VideoOut::VideoOutPort* port) { + vo_port = port; + } + + void BindRasterizer(Vulkan::Rasterizer* rasterizer_) { + rasterizer = rasterizer_; + } + + template + void SendCommand(auto&& func) { + if constexpr (wait_done) { + std::binary_semaphore sem{0}; + { + std::scoped_lock lk{submit_mutex}; + command_queue.emplace([&sem, &func] { + func(); + sem.release(); + }); + ++num_commands; + submit_cv.notify_one(); + } + sem.acquire(); + } else { + std::scoped_lock lk{submit_mutex}; + command_queue.emplace(std::move(func)); + ++num_commands; + submit_cv.notify_one(); + } + } + + void ReserveCopyBufferSpace() { + GpuQueue& gfx_queue = mapped_queues[GfxQueueId]; + std::scoped_lock lk(gfx_queue.m_access); + constexpr size_t GfxReservedSize = 2_MB >> 2; + gfx_queue.ccb_buffer.reserve(GfxReservedSize); + gfx_queue.dcb_buffer.reserve(GfxReservedSize); + } + + inline ComputeProgram& GetCsRegs() { + return mapped_queues[curr_qid].cs_state; + } + + struct AscQueueInfo { + static constexpr size_t Pm4BufferSize = 1024; + VAddr map_addr; + u32* read_addr; + u32 ring_size_dw; + u32 pipe_id; + std::array tmp_packet; + u32 tmp_dwords; + }; + Common::SlotVector asc_queues{}; + + std::thread::id GetGpuCommandProcessorThread() { + return gpu_id; + } + +#ifdef __linux__ + u32 GetGpuCommandProcessorThreadId() { + return gpu_tid; + } +#endif + +private: + struct Task { + struct promise_type { + auto get_return_object() { + Task task{}; + task.handle = std::coroutine_handle::from_promise(*this); + return task; + } + static constexpr std::suspend_always initial_suspend() noexcept { + // We want the task to be suspended at start + return {}; + } + static constexpr std::suspend_always final_suspend() noexcept { + return {}; + } + void unhandled_exception() { + try { + std::rethrow_exception(std::current_exception()); + } catch (const std::exception& e) { + UNREACHABLE_MSG("Unhandled exception: {}", e.what()); + } + } + void return_void() {} + struct empty {}; + std::suspend_always yield_value(empty&&) { + return {}; + } + }; + + using Handle = std::coroutine_handle; + Handle handle; + }; + + using CmdBuffer = std::pair, std::span>; + CmdBuffer CopyCmdBuffers(std::span dcb, std::span ccb); + Task ProcessGraphics(std::span dcb, std::span ccb); + Task ProcessCeUpdate(std::span ccb); + template + Task ProcessCompute(std::span acb, u32 vqid); + + void ProcessCommands(); + void Process(std::stop_token stoken); + + struct GpuQueue { + std::mutex m_access{}; + std::atomic dcb_buffer_offset; + std::atomic ccb_buffer_offset; + std::vector dcb_buffer; + std::vector ccb_buffer; + std::queue submits{}; + ComputeProgram cs_state{}; + }; + std::array mapped_queues{}; + u32 num_mapped_queues{1u}; // GFX is always available + + VAddr indirect_args_addr{}; + u32 num_counter_pairs{}; + u64 pixel_counter{}; + + struct ConstantEngine { + void Reset() { + ce_count = 0; + de_count = 0; + ce_compare_count = 0; + } + + [[nodiscard]] u32 Diff() const { + ASSERT_MSG(ce_count >= de_count, "DE counter is ahead of CE"); + return ce_count - de_count; + } + + u32 ce_compare_count{}; + u32 ce_count{}; + u32 de_count{}; + static std::array constants_heap; + } cblock{}; + + Vulkan::Rasterizer* rasterizer{}; + Libraries::VideoOut::VideoOutPort* vo_port{}; + const bool guest_markers_enabled; + std::jthread process_thread{}; + std::atomic num_submits{}; + std::atomic num_commands{}; + std::atomic submit_done{}; + std::mutex submit_mutex; + std::condition_variable_any submit_cv; + std::queue> command_queue{}; + std::thread::id gpu_id; +#ifdef __linux__ + u32 gpu_tid; +#endif + s32 curr_qid{-1}; +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/pixel_format.cpp b/gpu/shadps4/video_core/amdgpu/pixel_format.cpp new file mode 100644 index 0000000..d88b05f --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/pixel_format.cpp @@ -0,0 +1,267 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "video_core/amdgpu/pixel_format.h" + +namespace AmdGpu { + +std::string_view NameOf(DataFormat fmt) { + switch (fmt) { + case DataFormat::FormatInvalid: + return "FormatInvalid"; + case DataFormat::Format8: + return "Format8"; + case DataFormat::Format16: + return "Format16"; + case DataFormat::Format8_8: + return "Format8_8"; + case DataFormat::Format32: + return "Format32"; + case DataFormat::Format16_16: + return "Format16_16"; + case DataFormat::Format10_11_11: + return "Format10_11_11"; + case DataFormat::Format11_11_10: + return "Format11_11_10"; + case DataFormat::Format10_10_10_2: + return "Format10_10_10_2"; + case DataFormat::Format2_10_10_10: + return "Format2_10_10_10"; + case DataFormat::Format8_8_8_8: + return "Format8_8_8_8"; + case DataFormat::Format32_32: + return "Format32_32"; + case DataFormat::Format16_16_16_16: + return "Format16_16_16_16"; + case DataFormat::Format32_32_32: + return "Format32_32_32"; + case DataFormat::Format32_32_32_32: + return "Format32_32_32_32"; + case DataFormat::Format5_6_5: + return "Format5_6_5"; + case DataFormat::Format1_5_5_5: + return "Format1_5_5_5"; + case DataFormat::Format5_5_5_1: + return "Format5_5_5_1"; + case DataFormat::Format4_4_4_4: + return "Format4_4_4_4"; + case DataFormat::Format8_24: + return "Format8_24"; + case DataFormat::Format24_8: + return "Format24_8"; + case DataFormat::FormatX24_8_32: + return "FormatX24_8_32"; + case DataFormat::FormatGB_GR: + return "FormatGB_GR"; + case DataFormat::FormatBG_RG: + return "FormatBG_RG"; + case DataFormat::Format5_9_9_9: + return "Format5_9_9_9"; + case DataFormat::FormatBc1: + return "FormatBc1"; + case DataFormat::FormatBc2: + return "FormatBc2"; + case DataFormat::FormatBc3: + return "FormatBc3"; + case DataFormat::FormatBc4: + return "FormatBc4"; + case DataFormat::FormatBc5: + return "FormatBc5"; + case DataFormat::FormatBc6: + return "FormatBc6"; + case DataFormat::FormatBc7: + return "FormatBc7"; + default: + UNREACHABLE(); + } +} + +std::string_view NameOf(NumberFormat fmt) { + switch (fmt) { + case NumberFormat::Unorm: + return "Unorm"; + case NumberFormat::Snorm: + return "Snorm"; + case NumberFormat::Uscaled: + return "Uscaled"; + case NumberFormat::Sscaled: + return "Sscaled"; + case NumberFormat::Uint: + return "Uint"; + case NumberFormat::Sint: + return "Sint"; + case NumberFormat::SnormNz: + return "SnormNz"; + case NumberFormat::Float: + return "Float"; + case NumberFormat::Srgb: + return "Srgb"; + case NumberFormat::Ubnorm: + return "Ubnorm"; + case NumberFormat::UbnormNz: + return "UbnormNz"; + case NumberFormat::Ubint: + return "Ubint"; + case NumberFormat::Ubscaled: + return "Unscaled"; + default: + UNREACHABLE(); + } +} + +static constexpr std::array NUM_COMPONENTS = { + 0, // 0 FormatInvalid + 1, // 1 Format8 + 1, // 2 Format16 + 2, // 3 Format8_8 + 1, // 4 Format32 + 2, // 5 Format16_16 + 3, // 6 Format10_11_11 + 3, // 7 Format11_11_10 + 4, // 8 Format10_10_10_2 + 4, // 9 Format2_10_10_10 + 4, // 10 Format8_8_8_8 + 2, // 11 Format32_32 + 4, // 12 Format16_16_16_16 + 3, // 13 Format32_32_32 + 4, // 14 Format32_32_32_32 + 0, // 15 + 3, // 16 Format5_6_5 + 4, // 17 Format1_5_5_5 + 4, // 18 Format5_5_5_1 + 4, // 19 Format4_4_4_4 + 2, // 20 Format8_24 + 2, // 21 Format24_8 + 2, // 22 FormatX24_8_32 + 0, // 23 + 0, // 24 + 0, // 25 + 0, // 26 + 0, // 27 + 0, // 28 + 0, // 29 + 0, // 30 + 0, // 31 + 3, // 32 FormatGB_GR + 3, // 33 FormatBG_RG + 4, // 34 Format5_9_9_9 + 4, // 35 FormatBc1 + 4, // 36 FormatBc2 + 4, // 37 FormatBc3 + 1, // 38 FormatBc4 + 2, // 39 FormatBc5 + 3, // 40 FormatBc6 + 4, // 41 FormatBc7 +}; + +u32 NumComponents(DataFormat format) { + const u32 index = static_cast(format); + ASSERT_MSG(index < NUM_COMPONENTS.size(), "Invalid data format = {}", format); + return NUM_COMPONENTS[index]; +} + +static constexpr std::array BITS_PER_BLOCK = { + 0, // 0 FormatInvalid + 8, // 1 Format8 + 16, // 2 Format16 + 16, // 3 Format8_8 + 32, // 4 Format32 + 32, // 5 Format16_16 + 32, // 6 Format10_11_11 + 32, // 7 Format11_11_10 + 32, // 8 Format10_10_10_2 + 32, // 9 Format2_10_10_10 + 32, // 10 Format8_8_8_8 + 64, // 11 Format32_32 + 64, // 12 Format16_16_16_16 + 96, // 13 Format32_32_32 + 128, // 14 Format32_32_32_32 + -1, // 15 + 16, // 16 Format5_6_5 + 16, // 17 Format1_5_5_5 + 16, // 18 Format5_5_5_1 + 16, // 19 Format4_4_4_4 + 32, // 20 Format8_24 + 32, // 21 Format24_8 + 64, // 22 FormatX24_8_32 + -1, // 23 + -1, // 24 + -1, // 25 + -1, // 26 + -1, // 27 + -1, // 28 + -1, // 29 + -1, // 30 + -1, // 31 + 16, // 32 FormatGB_GR + 16, // 33 FormatBG_RG + 32, // 34 Format5_9_9_9 + 64, // 35 FormatBc1 + 128, // 36 FormatBc2 + 128, // 37 FormatBc3 + 64, // 38 FormatBc4 + 128, // 39 FormatBc5 + 128, // 40 FormatBc6 + 128, // 41 FormatBc7 +}; + +u32 NumBitsPerBlock(DataFormat format) { + const u32 index = static_cast(format); + ASSERT_MSG(index < BITS_PER_BLOCK.size(), "Invalid data format = {}", format); + return BITS_PER_BLOCK[index]; +} + +static constexpr std::array BITS_PER_ELEMENT = { + 0, // 0 FormatInvalid + 8, // 1 Format8 + 16, // 2 Format16 + 16, // 3 Format8_8 + 32, // 4 Format32 + 32, // 5 Format16_16 + 32, // 6 Format10_11_11 + 32, // 7 Format11_11_10 + 32, // 8 Format10_10_10_2 + 32, // 9 Format2_10_10_10 + 32, // 10 Format8_8_8_8 + 64, // 11 Format32_32 + 64, // 12 Format16_16_16_16 + 96, // 13 Format32_32_32 + 128, // 14 Format32_32_32_32 + -1, // 15 + 16, // 16 Format5_6_5 + 16, // 17 Format1_5_5_5 + 16, // 18 Format5_5_5_1 + 16, // 19 Format4_4_4_4 + 32, // 20 Format8_24 + 32, // 21 Format24_8 + 64, // 22 FormatX24_8_32 + -1, // 23 + -1, // 24 + -1, // 25 + -1, // 26 + -1, // 27 + -1, // 28 + -1, // 29 + -1, // 30 + -1, // 31 + 16, // 32 FormatGB_GR + 16, // 33 FormatBG_RG + 32, // 34 Format5_9_9_9 + 4, // 35 FormatBc1 + 8, // 36 FormatBc2 + 8, // 37 FormatBc3 + 4, // 38 FormatBc4 + 8, // 39 FormatBc5 + 8, // 40 FormatBc6 + 8, // 41 FormatBc7 +}; + +u32 NumBitsPerElement(DataFormat format) { + const u32 index = static_cast(format); + ASSERT_MSG(index < BITS_PER_ELEMENT.size(), "Invalid data format = {}", format); + return BITS_PER_ELEMENT[index]; +} + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/pixel_format.h b/gpu/shadps4/video_core/amdgpu/pixel_format.h new file mode 100644 index 0000000..8b83639 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/pixel_format.h @@ -0,0 +1,422 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/assert.h" +#include "common/types.h" + +namespace AmdGpu { + +// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture] +enum class DataFormat : u32 { + FormatInvalid = 0, + Format8 = 1, + Format16 = 2, + Format8_8 = 3, + Format32 = 4, + Format16_16 = 5, + Format10_11_11 = 6, + Format11_11_10 = 7, + Format10_10_10_2 = 8, + Format2_10_10_10 = 9, + Format8_8_8_8 = 10, + Format32_32 = 11, + Format16_16_16_16 = 12, + Format32_32_32 = 13, + Format32_32_32_32 = 14, + Format5_6_5 = 16, + Format1_5_5_5 = 17, + Format5_5_5_1 = 18, + Format4_4_4_4 = 19, + Format8_24 = 20, + Format24_8 = 21, + FormatX24_8_32 = 22, + FormatGB_GR = 32, + FormatBG_RG = 33, + Format5_9_9_9 = 34, + FormatBc1 = 35, + FormatBc2 = 36, + FormatBc3 = 37, + FormatBc4 = 38, + FormatBc5 = 39, + FormatBc6 = 40, + FormatBc7 = 41, + FormatFmask8_S2_F1 = 44, + FormatFmask8_S4_F1 = 45, + FormatFmask8_S8_F1 = 46, + FormatFmask8_S2_F2 = 47, + FormatFmask8_S4_F2 = 48, + FormatFmask8_S4_F4 = 49, + FormatFmask16_S16_F1 = 50, + FormatFmask16_S8_F2 = 51, + FormatFmask32_S16_F2 = 52, + FormatFmask32_S8_F4 = 53, + FormatFmask32_S8_F8 = 54, + FormatFmask64_S16_F4 = 55, + FormatFmask64_S16_F8 = 56, + Format4_4 = 57, + Format6_5_5 = 58, + Format1 = 59, + Format1_Reversed = 60, + Format32_As_8 = 61, + Format32_As_8_8 = 62, + Format32_As_32_32_32_32 = 63, +}; + +enum class NumberFormat : u32 { + Unorm = 0, + Snorm = 1, + Uscaled = 2, + Sscaled = 3, + Uint = 4, + Sint = 5, + SnormNz = 6, + Float = 7, + Srgb = 9, + Ubnorm = 10, + UbnormNz = 11, + Ubint = 12, + Ubscaled = 13, +}; + +enum class NumberClass : u8 { + Float = 0, + Sint = 1, + Uint = 2, +}; + +enum class CompSwizzle : u8 { + Zero = 0, + One = 1, + Red = 4, + Green = 5, + Blue = 6, + Alpha = 7, +}; + +enum class NumberConversion : u32 { + None = 0, + UintToUscaled = 1, + SintToSscaled = 2, + UnormToUbnorm = 3, + Sint8ToSnormNz = 4, + Sint16ToSnormNz = 5, + Uint32ToUnorm = 6, + SrgbToNorm = 7, +}; + +union CompMapping { + struct { + CompSwizzle r; + CompSwizzle g; + CompSwizzle b; + CompSwizzle a; + }; + std::array array; + + bool operator==(const CompMapping& other) const { + return array == other.array; + } + + template + [[nodiscard]] std::array Apply(const std::array& data) const { + return { + ApplySingle(data, r), + ApplySingle(data, g), + ApplySingle(data, b), + ApplySingle(data, a), + }; + } + + [[nodiscard]] u32 ApplyMask(u32 mask) const { + u32 swizzled_mask{}; + for (u32 i = 0; i < 4; ++i) { + swizzled_mask |= ((mask >> i) & 1) << Map(i); + } + return swizzled_mask; + } + + [[nodiscard]] CompMapping Inverse() const { + CompMapping result{}; + InverseSingle(result.r, CompSwizzle::Red); + InverseSingle(result.g, CompSwizzle::Green); + InverseSingle(result.b, CompSwizzle::Blue); + InverseSingle(result.a, CompSwizzle::Alpha); + return result; + } + + [[nodiscard]] u32 Map(u32 comp) const { + const u32 swizzled_comp = u32(array[comp]); + constexpr u32 min_comp = u32(AmdGpu::CompSwizzle::Red); + return swizzled_comp >= min_comp ? swizzled_comp - min_comp : comp; + } + +private: + template + T ApplySingle(const std::array& data, const CompSwizzle swizzle) const { + switch (swizzle) { + case CompSwizzle::Zero: + return T(0); + case CompSwizzle::One: + return T(1); + case CompSwizzle::Red: + return data[0]; + case CompSwizzle::Green: + return data[1]; + case CompSwizzle::Blue: + return data[2]; + case CompSwizzle::Alpha: + return data[3]; + default: + UNREACHABLE(); + } + } + + void InverseSingle(CompSwizzle& dst, const CompSwizzle target) const { + if (r == target) { + dst = CompSwizzle::Red; + } else if (g == target) { + dst = CompSwizzle::Green; + } else if (b == target) { + dst = CompSwizzle::Blue; + } else if (a == target) { + dst = CompSwizzle::Alpha; + } else { + dst = CompSwizzle::Zero; + } + } +}; + +static constexpr CompMapping IdentityMapping = { + .r = CompSwizzle::Red, + .g = CompSwizzle::Green, + .b = CompSwizzle::Blue, + .a = CompSwizzle::Alpha, +}; + +constexpr DataFormat RemapDataFormat(const DataFormat format) { + switch (format) { + case DataFormat::Format11_11_10: + return DataFormat::Format10_11_11; + case DataFormat::Format10_10_10_2: + return DataFormat::Format2_10_10_10; + case DataFormat::Format5_5_5_1: + return DataFormat::Format1_5_5_5; + default: + return format; + } +} + +constexpr NumberFormat RemapNumberFormat(const NumberFormat format, const DataFormat data_format) { + switch (format) { + case NumberFormat::Unorm: { + switch (data_format) { + case DataFormat::Format32: + case DataFormat::Format32_32: + case DataFormat::Format32_32_32: + case DataFormat::Format32_32_32_32: + return NumberFormat::Uint; + default: + return format; + } + } + case NumberFormat::Srgb: + switch (data_format) { + case DataFormat::FormatBc4: + case DataFormat::FormatBc5: + case DataFormat::FormatBc6: + // BC4/BC5 store non-color data (single/two-channel, used for normal maps), + // and BC6 is HDR float — none have sRGB Vulkan equivalents. + return NumberFormat::Unorm; + default: + return format; + } + case NumberFormat::Uscaled: + return NumberFormat::Uint; + case NumberFormat::Sscaled: + case NumberFormat::SnormNz: + return NumberFormat::Sint; + case NumberFormat::Ubnorm: + return NumberFormat::Unorm; + case NumberFormat::Float: + if (data_format == DataFormat::Format8) { + // Games may ask for 8-bit float when they want to access the stencil component + // of a depth-stencil image. Change to unsigned int to match the stencil format. + // This is also the closest approximation to pass the bits through unconverted. + return NumberFormat::Uint; + } + [[fallthrough]]; + default: + return format; + } +} + +constexpr CompMapping RemapSwizzle(const DataFormat format, const CompMapping swizzle) { + switch (format) { + case DataFormat::Format1_5_5_5: + case DataFormat::Format11_11_10: { + CompMapping result; + result.r = swizzle.b; + result.g = swizzle.g; + result.b = swizzle.r; + result.a = swizzle.a; + return result; + } + case DataFormat::Format10_10_10_2: { + CompMapping result; + result.r = swizzle.a; + result.g = swizzle.b; + result.b = swizzle.g; + result.a = swizzle.r; + return result; + } + case DataFormat::Format4_4_4_4: { + // Remap to a more supported component order. + CompMapping result; + result.r = swizzle.g; + result.g = swizzle.b; + result.b = swizzle.a; + result.a = swizzle.r; + return result; + } + case DataFormat::Format5_6_5: { + // Remap to a more supported component order. + CompMapping result; + result.r = swizzle.b; + result.g = swizzle.g; + result.b = swizzle.r; + result.a = swizzle.a; + return result; + } + case DataFormat::Format8: + case DataFormat::Format16: + case DataFormat::Format32: { + // PS4 single-channel formats expose the texel as either R or A depending on dst_sel, + // but Vulkan single-channel formats expose it only via R. Redirect any selector + // that points at Alpha to Red so the texel is read correctly. + CompMapping result = swizzle; + const auto remap_alpha_to_red = [](CompSwizzle& c) { + if (c == CompSwizzle::Alpha) { + c = CompSwizzle::Red; + } + }; + remap_alpha_to_red(result.r); + remap_alpha_to_red(result.g); + remap_alpha_to_red(result.b); + remap_alpha_to_red(result.a); + return result; + } + default: + return swizzle; + } +} + +constexpr NumberConversion MapNumberConversion(const NumberFormat num_fmt, + const DataFormat data_fmt) { + switch (num_fmt) { + case NumberFormat::Unorm: { + switch (data_fmt) { + case DataFormat::Format32: + case DataFormat::Format32_32: + case DataFormat::Format32_32_32: + case DataFormat::Format32_32_32_32: + return NumberConversion::Uint32ToUnorm; + default: + return NumberConversion::None; + } + } + case NumberFormat::Srgb: + switch (data_fmt) { + case DataFormat::FormatBc4: + case DataFormat::FormatBc5: + // BC4/BC5 have no sRGB variant; no conversion needed (treated as Unorm). + return NumberConversion::None; + case DataFormat::FormatBc6: + return NumberConversion::SrgbToNorm; + default: + return NumberConversion::None; + } + case NumberFormat::Uscaled: + return NumberConversion::UintToUscaled; + case NumberFormat::Sscaled: + return NumberConversion::SintToSscaled; + case NumberFormat::Ubnorm: + return NumberConversion::UnormToUbnorm; + case NumberFormat::SnormNz: { + switch (data_fmt) { + case DataFormat::Format8: + case DataFormat::Format8_8: + case DataFormat::Format8_8_8_8: + return NumberConversion::Sint8ToSnormNz; + case DataFormat::Format16: + case DataFormat::Format16_16: + case DataFormat::Format16_16_16_16: + return NumberConversion::Sint16ToSnormNz; + default: + UNREACHABLE_MSG("data_fmt = {}", u32(data_fmt)); + } + } + default: + return NumberConversion::None; + } +} + +constexpr NumberClass GetNumberClass(const NumberFormat nfmt) { + switch (nfmt) { + case NumberFormat::Sint: + return NumberClass::Sint; + case NumberFormat::Uint: + return NumberClass::Uint; + default: + return NumberClass::Float; + } +} + +constexpr bool IsRgb(CompSwizzle swizzle) { + return swizzle == CompSwizzle::Red || swizzle == CompSwizzle::Green || + swizzle == CompSwizzle::Blue; +} + +constexpr bool IsInteger(const NumberFormat nfmt) { + return nfmt == NumberFormat::Sint || nfmt == NumberFormat::Uint; +} + +constexpr bool IsBlockCoded(DataFormat format) { + return format >= DataFormat::FormatBc1 && format <= DataFormat::FormatBc7; +} + +constexpr bool IsFmask(DataFormat format) { + return format >= DataFormat::FormatFmask8_S2_F1 && format <= DataFormat::FormatFmask64_S16_F8; +} + +std::string_view NameOf(DataFormat fmt); +std::string_view NameOf(NumberFormat fmt); + +u32 NumComponents(DataFormat format); +u32 NumBitsPerBlock(DataFormat format); +u32 NumBitsPerElement(DataFormat format); + +} // namespace AmdGpu + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(AmdGpu::DataFormat fmt, format_context& ctx) const { + return fmt::format_to(ctx.out(), "{}", AmdGpu::NameOf(fmt)); + } +}; + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(AmdGpu::NumberFormat fmt, format_context& ctx) const { + return fmt::format_to(ctx.out(), "{}", AmdGpu::NameOf(fmt)); + } +}; diff --git a/gpu/shadps4/video_core/amdgpu/pm4_cmds.h b/gpu/shadps4/video_core/amdgpu/pm4_cmds.h new file mode 100644 index 0000000..a1072c7 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/pm4_cmds.h @@ -0,0 +1,1239 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/assert.h" +#include "common/bit_field.h" +#include "common/types.h" +#include "common/uint128.h" +#include "core/libraries/gnmdriver/gnmdriver.h" +#include "core/libraries/kernel/time.h" +#include "video_core/amdgpu/pm4_opcodes.h" + +namespace AmdGpu { + +enum class PM4ShaderType : u32 { + ShaderGraphics = 0, + ShaderCompute = 1, +}; + +enum class PM4Predicate : u32 { + PredDisable = 0, + PredEnable = 1, +}; + +union PM4Type0Header { + u32 raw; + BitField<0, 16, u32> base; ///< DWORD Memory-mapped address + BitField<16, 14, u32> count; ///< Count of DWORDs in the *information* body (N - 1 for N dwords) + BitField<30, 2, u32> type; ///< Packet identifier. It should be 0 for type 0 packets. + + u32 NumWords() const { + return count + 1; + } +}; + +union PM4Type3Header { + static constexpr u32 TYPE = 3; + + constexpr PM4Type3Header(PM4ItOpcode code, u32 num_words_min_one, + PM4ShaderType stype = PM4ShaderType::ShaderGraphics, + PM4Predicate pred = PM4Predicate::PredDisable) { + raw = 0; + predicate.Assign(pred); + shader_type.Assign(stype); + opcode.Assign(code); + count.Assign(num_words_min_one); + type.Assign(3); + } + + u32 NumWords() const { + return (count + 1) & 0x3fff; + } + + u32 raw; + BitField<0, 1, PM4Predicate> predicate; ///< Predicated version of packet when set + BitField<1, 1, PM4ShaderType> shader_type; ///< 0: Graphics, 1: Compute Shader + BitField<8, 8, PM4ItOpcode> opcode; ///< IT opcode + BitField<16, 14, u32> count; ///< Number of DWORDs - 1 in the information body. + BitField<30, 2, u32> type; ///< Packet identifier. It should be 3 for type 3 packets +}; + +union PM4Header { + u32 raw; + PM4Type0Header type0; + PM4Type3Header type3; + BitField<30, 2, u32> type; +}; + +// Write the PM4 header +template +constexpr u32* WriteHeader(u32* cmdbuf, u32 size, + PM4ShaderType type = PM4ShaderType::ShaderGraphics, + PM4Predicate predicate = PM4Predicate::PredDisable) { + PM4Type3Header header{opcode, size - 1, type, predicate}; + std::memcpy(cmdbuf, &header, sizeof(header)); + return ++cmdbuf; +} + +// Write arguments +template +constexpr u32* WriteBody(u32* cmdbuf, Args... data) { + const std::array args{data...}; + std::memcpy(cmdbuf, args.data(), sizeof(args)); + cmdbuf += args.size(); + return cmdbuf; +} + +template +constexpr u32* WritePacket(u32* cmdbuf, PM4ShaderType type, Args... data) { + cmdbuf = WriteHeader(cmdbuf, sizeof...(Args), type); + cmdbuf = WriteBody(cmdbuf, data...); + return cmdbuf; +} + +union ContextControlEnable { + u32 raw; + BitField<0, 1, u32> enable_single_cntx_config_reg; ///< single context config reg + BitField<1, 1, u32> enable_multi_cntx_render_reg; ///< multi context render state reg + BitField<15, 1, u32> enable_user_config_reg__CI; ///< User Config Reg on CI(reserved for SI) + BitField<16, 1, u32> enable_gfx_sh_reg; ///< Gfx SH Registers + BitField<24, 1, u32> enable_cs_sh_reg; ///< CS SH Registers + BitField<31, 1, u32> enable_dw; ///< DW enable +}; + +struct PM4CmdContextControl { + PM4Type3Header header; + ContextControlEnable load_control; ///< Enable bits for loading + ContextControlEnable shadow_enable; ///< Enable bits for shadowing +}; + +union LoadAddressHigh { + u32 raw; + BitField<0, 16, u32> + addr_hi; ///< bits for the block in Memory from where the CP will fetch the state + BitField<31, 1, u32> + wait_idle; ///< if set the CP will wait for the graphics pipe to be idle by writing + ///< to the GRBM Wait Until register with "Wait for 3D idle" +}; + +/** + * PM4CMDLOADDATA can be used with the following opcodes + * - IT_LOAD_CONFIG_REG + * - IT_LOAD_CONTEXT_REG + * - IT_LOAD_SH_REG + */ +struct PM4CmdLoadData { + PM4Type3Header header; + u32 addr_lo; ///< low 32 address bits for the block in memory from where the CP will fetch the + ///< state + LoadAddressHigh addr_hi; + u32 reg_offset; ///< offset in DWords from the register base address + u32 num_dwords; ///< number of DWords that the CP will fetch and write into the chip. A value of + ///< zero will fetch nothing +}; + +enum class LoadDataIndex : u32 { + DirectAddress = 0, /// ADDR_LO is direct address + Offset = 1, /// ARRD_LO is ignored and memory offset is in addrOffset +}; + +enum class LoadDataFormat : u32 { + OffsetAndSize = 0, /// Data is consecutive DWORDs + OffsetAndData = 1, /// Register offset and data is interleaved +}; + +union LoadAddressLow { + u32 raw; + BitField<0, 1, LoadDataIndex> index; + BitField<2, 30, u32> addr_lo; ///< bits for the block in Memory from where the CP will fetch the + ///< state. DWORD aligned +}; + +/** + * PM4CMDLOADDATAINDEX can be used with the following opcodes (VI+) + * - IT_LOAD_CONTEXT_REG_INDEX + * - IT_LOAD_SH_REG_INDEX + */ +struct PM4CmdLoadDataIndex { + PM4Type3Header header; + LoadAddressLow addr_lo; ///< low 32 address bits for the block in memory from where the CP will + ///< fetch the state + u32 addr_offset; ///< addrLo.index = 1 Indexed mode + union { + BitField<0, 16, u32> reg_offset; ///< offset in DWords from the register base address + BitField<31, 1, LoadDataFormat> data_format; + u32 raw; + }; + u32 num_dwords; ///< Number of DWords that the CP will fetch and write + ///< into the chip. A value of zero will fetch nothing +}; + +/** + * PM4CMDSETDATA can be used with the following opcodes: + * + * - IT_SET_CONFIG_REG + * - IT_SET_CONTEXT_REG + * - IT_SET_CONTEXT_REG_INDIRECT + * - IT_SET_SH_REG + * - IT_SET_SH_REG_INDEX + * - IT_SET_UCONFIG_REG + */ +struct PM4CmdSetData { + PM4Type3Header header; + union { + u32 raw; + BitField<0, 16, u32> reg_offset; ///< Offset in DWords from the register base address + BitField<28, 4, u32> index; ///< Index for UCONFIG/CONTEXT on CI+ + ///< Program to zero for other opcodes and on SI + }; + u32 data[0]; + + [[nodiscard]] u32 Size() const { + return header.count << 2u; + } + + template + static constexpr u32* SetContextReg(u32* cmdbuf, Args... data) { + return WritePacket(cmdbuf, type, data...); + } + + template + static constexpr u32* SetShReg(u32* cmdbuf, Args... data) { + return WritePacket(cmdbuf, type, data...); + } + + template + static constexpr u32* SetUconfigReg(u32* cmdbuf, Args... data) { + return WritePacket(cmdbuf, type, data...); + } +}; + +struct PM4CmdSetQueueReg { + PM4Type3Header header; + union { + u32 raw; + BitField<0, 8, u32> reg_offset; ///< Offset in DWords from the register base address + BitField<15, 1, u32> defer_exec; ///< Defer execution + BitField<16, 10, u32> vqid; ///< Queue ID + }; + u32 data[0]; + + [[nodiscard]] u32 Size() const { + return header.count << 2u; + } +}; + +struct PM4CmdNop { + PM4Type3Header header; + u32 data_block[0]; + + enum PayloadType : u32 { + DebugMarkerPush = 0x68750001u, ///< Begin of GPU event scope + DebugMarkerPop = 0x68750002u, ///< End of GPU event scope + DebugSetMarker = 0x68750003u, ///< Set GPU event marker + SetVsharpInUdata = 0x68750004u, ///< Indicates that V# will be set in the next packet + SetTsharpInUdata = 0x68750005u, ///< Indicates that T# will be set in the next packet + SetSsharpInUdata = 0x68750006u, ///< Indicates that S# will be set in the next packet + DebugColorMarkerPush = 0x6875000eu, ///< Begin of GPU event scope with color + PatchedFlip = 0x68750776u, ///< Patched flip marker + PrepareFlip = 0x68750777u, ///< Flip marker + PrepareFlipLabel = 0x68750778u, ///< Flip marker with label address + PrepareFlipInterrupt = 0x68750780u, ///< Flip marker with interrupt + PrepareFlipInterruptLabel = 0x68750781u, ///< Flip marker with interrupt and label + }; +}; + +enum class SourceSelect : u32 { + BufferOffset = 0, + VgtStrmoutBufferFilledSize = 1, + SrcAddress = 2, + None = 3, +}; + +struct PM4CmdStrmoutBufferUpdate { + PM4Type3Header header; + union { + BitField<0, 1, u32> update_memory; + BitField<1, 2, SourceSelect> source_select; + BitField<8, 2, u32> buffer_select; + u32 control; + }; + union { + BitField<2, 30, u32> dst_address_lo; + BitField<0, 2, u32> swap_dst; + }; + u32 dst_address_hi; + union { + u32 buffer_offset; + BitField<2, 30, u32> src_address_lo; + BitField<0, 2, u32> swap_src; + }; + u32 src_address_hi; + + template + T DstAddress() const { + ASSERT(update_memory.Value() == 1); + return reinterpret_cast(dst_address_lo.Value() | u64(dst_address_hi & 0xFFFF) << 32); + } + + template + T SrcAddress() const { + ASSERT(source_select.Value() == SourceSelect::SrcAddress); + return reinterpret_cast(src_address_lo.Value() | u64(src_address_hi & 0xFFFF) << 32); + } +}; + +struct PM4CmdDrawIndexOffset2 { + PM4Type3Header header; + u32 max_size; ///< Maximum number of indices + u32 index_offset; ///< Zero based starting index number in the index buffer + u32 index_count; ///< number of indices in the Index Buffer + u32 draw_initiator; ///< draw Initiator Register +}; + +struct PM4CmdDrawIndex2 { + PM4Type3Header header; + u32 max_size; ///< maximum number of indices + u32 index_base_lo; ///< base Address Lo [31:1] of Index Buffer + ///< (Word-Aligned). Written to the VGT_DMA_BASE register. + u32 index_base_hi; ///< base Address Hi [39:32] of Index Buffer. + ///< Written to the VGT_DMA_BASE_HI register + u32 index_count; ///< number of indices in the Index Buffer. + ///< Written to the VGT_NUM_INDICES register. + u32 draw_initiator; ///< written to the VGT_DRAW_INITIATOR register +}; + +struct PM4CmdDrawIndexType { + PM4Type3Header header; + union { + u32 raw; + BitField<0, 2, u32> index_type; ///< Select 16 Vs 32bit index + BitField<2, 2, u32> swap_mode; ///< DMA swap mode + }; +}; + +struct PM4CmdDrawIndexAuto { + PM4Type3Header header; + u32 index_count; + u32 draw_initiator; +}; + +enum class DataSelect : u32 { + None = 0, + Data32Low = 1, + Data64 = 2, + GpuClock64 = 3, + PerfCounter = 4, + GdsMemStore = 5, +}; + +enum class InterruptSelect : u32 { + None = 0, + IrqOnly = 1, + IrqWhenWriteConfirm = 2, + IrqUndocumented = 3, +}; + +static u64 GetGpuClock64() { + auto now = std::chrono::high_resolution_clock::now(); + auto duration = now.time_since_epoch(); + auto ticks = std::chrono::duration_cast(duration).count(); + return static_cast(ticks); +} + +static u64 GetGpuPerfCounter() { + const auto cpu_freq = Libraries::Kernel::sceKernelGetTscFrequency(); + const auto gpu_freq = Libraries::GnmDriver::sceGnmGetGpuCoreClockFrequency(); + + const auto cpu_cycles = Libraries::Kernel::sceKernelReadTsc(); + const auto gpu_cycles = Common::MultiplyAndDivide64(cpu_cycles, gpu_freq, cpu_freq); + + return gpu_cycles; +} + +// VGT_EVENT_INITIATOR.EVENT_TYPE +enum class EventType : u32 { + SampleStreamoutStats1 = 1, + SampleStreamoutStats2 = 2, + SampleStreamoutStats3 = 3, + CacheFlushTs = 4, + ContextDone = 5, + CacheFlush = 6, + CsPartialFlush = 7, + VgtStreamoutSync = 8, + VgtStreamoutReset = 10, + EndOfPipeIncrDe = 11, + EndOfPipeIbEnd = 12, + RstPixCnt = 13, + VsPartialFlush = 15, + PsPartialFlush = 16, + FlushHsOutput = 17, + FlushLsOutput = 18, + CacheFlushAndInvTsEvent = 20, + ZpassDone = 21, + CacheFlushAndInvEvent = 22, + PerfcounterStart = 23, + PerfcounterStop = 24, + PipelineStatStart = 25, + PipelineStatStop = 26, + PerfcounterSample = 27, + FlushEsOutput = 28, + FlushGsOutput = 29, + SamplePipelineStat = 30, + SoVgtStreamoutFlush = 31, + SampleStreamoutStats = 32, + ResetVtxCnt = 33, + VgtFlush = 36, + ScSendDbVpz = 39, + BottomOfPipeTs = 40, + DbCacheFlushAndInv = 42, + FlushAndInvDbDataTs = 43, + FlushAndInvDbMeta = 44, + FlushAndInvCbDataTs = 45, + FlushAndInvCbMeta = 46, + CsDone = 47, + PsDone = 48, + FlushAndInvCbPixelData = 49, + ThreadTraceStart = 51, + ThreadTraceStop = 52, + ThreadTraceFlush = 54, + ThreadTraceFinish = 55, + PixelPipeStatControl = 56, + PixelPipeStatDump = 57, + PixelPipeStatReset = 58, +}; + +enum class EventIndex : u32 { + Other = 0, + ZpassDone = 1, + SamplePipelineStat = 2, + SampleStreamoutStatSx = 3, + CsVsPsPartialFlush = 4, + EopReserved = 5, + EosReserved = 6, + CacheFlush = 7, +}; + +struct PM4CmdEventWrite { + PM4Type3Header header; + union { + u32 event_control; + BitField<0, 6, EventType> event_type; ///< Event type written to VGT_EVENT_INITIATOR + BitField<8, 4, EventIndex> event_index; ///< Event index + BitField<20, 1, u32> inv_l2; ///< Send WBINVL2 op to the TC L2 cache when EVENT_INDEX = 0111 + }; + u32 address[]; + + template + T Address() const { + ASSERT(event_index.Value() >= EventIndex::ZpassDone && + event_index.Value() <= EventIndex::SampleStreamoutStatSx); + return std::bit_cast((u64(address[1]) << 32u) | u64(address[0])); + } +}; + +struct PM4CmdEventWriteEop { + PM4Type3Header header; + union { + u32 event_control; + BitField<0, 6, u32> event_type; ///< Event type written to VGT_EVENT_INITIATOR + BitField<8, 4, u32> event_index; ///< Event index + }; + u32 address_lo; + union { + u32 data_control; + BitField<0, 16, u32> address_hi; ///< High bits of address + BitField<24, 2, InterruptSelect> int_sel; ///< Selects interrupt action for end-of-pipe + BitField<29, 3, DataSelect> data_sel; ///< Selects source of data + }; + u32 data_lo; ///< Value that will be written to memory when event occurs + u32 data_hi; ///< Value that will be written to memory when event occurs + + template + T* Address() const { + return reinterpret_cast(address_lo | u64(address_hi) << 32); + } + + u32 DataDWord() const { + return data_lo; + } + + u64 DataQWord() const { + return data_lo | u64(data_hi) << 32; + } + + void SignalFence(auto&& write_mem, auto&& signal_irq) const { + u32* address = Address(); + switch (data_sel.Value()) { + case DataSelect::None: { + break; + } + case DataSelect::Data32Low: { + write_mem(address, DataDWord(), sizeof(u32)); + break; + } + case DataSelect::Data64: { + write_mem(address, DataQWord(), sizeof(u64)); + break; + } + case DataSelect::GpuClock64: { + write_mem(address, GetGpuClock64(), sizeof(u64)); + break; + } + case DataSelect::PerfCounter: { + write_mem(address, GetGpuPerfCounter(), sizeof(u64)); + break; + } + default: { + UNREACHABLE(); + } + } + + switch (int_sel.Value()) { + case InterruptSelect::None: { + // No interrupt + break; + } + case InterruptSelect::IrqOnly: + ASSERT(data_sel == DataSelect::None); + [[fallthrough]]; + case InterruptSelect::IrqWhenWriteConfirm: { + signal_irq(); + break; + } + default: { + UNREACHABLE(); + } + } + } +}; + +struct PM4CmdAcquireMem { + PM4Type3Header header; + u32 cp_coher_cntl; + u32 cp_coher_size_lo; + u32 cp_coher_size_hi; + u32 cp_coher_base_lo; + u32 cp_coher_base_hi; + u32 poll_interval; +}; + +enum class DmaDataDst : u32 { + Memory = 0, + Gds = 1, + MemoryUsingL2 = 3, +}; + +enum class DmaDataSrc : u32 { + Memory = 0, + Gds = 1, + Data = 2, + MemoryUsingL2 = 3, +}; + +struct PM4DmaData { + PM4Type3Header header; + struct { + u32 engine : 1; + u32 reserved1 : 11; + u32 src_atc : 1; + u32 src_cache_policy : 2; + u32 src_volatile : 1; + u32 reserved2 : 4; + DmaDataDst dst_sel : 2; + u32 reserved3 : 2; + u32 dst_atc : 1; + u32 dst_cache_policy : 2; + u32 dst_volatile : 1; + u32 reserved4 : 1; + DmaDataSrc src_sel : 2; + u32 cp_sync : 1; + }; + union { + u32 src_addr_lo; + u32 data; + }; + u32 src_addr_hi; + u32 dst_addr_lo; + u32 dst_addr_hi; + struct { + u32 num_bytes : 21; + u32 dis_wc : 1; + u32 src_swap : 2; + u32 dst_swap : 2; + u32 sas : 1; + u32 das : 1; + u32 saic : 1; + u32 daic : 1; + u32 raw_wait : 1; + u32 reserved5 : 1; + } command; + + template + T SrcAddress() const { + return std::bit_cast(src_addr_lo | u64(src_addr_hi) << 32); + } + + template + T DstAddress() const { + return std::bit_cast(dst_addr_lo | u64(dst_addr_hi) << 32); + } + + u32 NumBytes() const noexcept { + return command.num_bytes; + } +}; + +enum class CopyDataSrc : u32 { + MappedRegister = 0, + Memory = 1, + TCL2 = 2, + Gds = 3, + // Reserved = 4, + Immediate = 5, + Atomic = 6, + GdsAtomic0 = 7, + GdsAtomic1 = 8, + GpuClock = 9, +}; + +enum class CopyDataDst : u32 { + MappedRegister = 0, + MemorySync = 1, + TCL2 = 2, + Gds = 3, + // Reserved = 4, + MemoryAsync = 5, +}; + +enum class CopyDataEngine : u32 { + Me = 0, + Pfp = 1, + Ce = 2, + // Reserved = 3 +}; + +struct PM4CmdCopyData { + PM4Type3Header header; + union { + BitField<0, 4, CopyDataSrc> src_sel; + BitField<8, 4, CopyDataDst> dst_sel; + BitField<16, 1, u32> count_sel; + BitField<20, 1, u32> wr_confirm; + BitField<30, 2, CopyDataEngine> engine_sel; + u32 control; + }; + u32 src_addr_lo; + u32 src_addr_hi; + u32 dst_addr_lo; + u32 dst_addr_hi; + + template + T SrcAddress() const { + return std::bit_cast(src_addr_lo | u64(src_addr_hi) << 32); + } + + template + T DstAddress() const { + return std::bit_cast(dst_addr_lo | u64(dst_addr_hi) << 32); + } +}; + +struct PM4CmdRewind { + PM4Type3Header header; + union { + u32 raw; + BitField<24, 1, u32> offload_enable; ///< Enable offload polling valid bit to IQ + BitField<31, 1, u32> valid; ///< Set when subsequent packets are valid + }; + + bool Valid() const { + return valid; + } +}; + +struct PM4CmdWaitRegMem { + enum class Engine : u32 { Me = 0u, Pfp = 1u }; + enum class MemSpace : u32 { Register = 0u, Memory = 1u }; + enum class Function : u32 { + Always = 0u, + LessThan = 1u, + LessThanEqual = 2u, + Equal = 3u, + NotEqual = 4u, + GreaterThanEqual = 5u, + GreaterThan = 6u, + Reserved = 7u + }; + + PM4Type3Header header; + union { + BitField<0, 3, Function> function; + BitField<4, 1, MemSpace> mem_space; + BitField<8, 1, Engine> engine; + u32 raw; + }; + union { + BitField<0, 16, u32> reg; + BitField<2, 30, u32> poll_addr_lo; + BitField<0, 2, u32> swap; + u32 poll_addr_lo_raw; + }; + u32 poll_addr_hi; + u32 ref; + u32 mask; + u32 poll_interval; + + template + T Address() const { + return std::bit_cast((uintptr_t(poll_addr_hi) << 32) | (poll_addr_lo << 2)); + } + + u32 Reg() const { + return reg.Value(); + } + + bool Test(std::span regs) const { + u32 value = mem_space.Value() == MemSpace::Memory ? *Address() : regs[Reg()]; + switch (function.Value()) { + case Function::Always: { + return true; + } + case Function::LessThan: { + return (value & mask) < ref; + } + case Function::LessThanEqual: { + return (value & mask) <= ref; + } + case Function::Equal: { + return (value & mask) == ref; + } + case Function::NotEqual: { + return (value & mask) != ref; + } + case Function::GreaterThanEqual: { + return (value & mask) >= ref; + } + case Function::GreaterThan: { + return (value & mask) > ref; + } + case Function::Reserved: + [[fallthrough]]; + default: { + UNREACHABLE(); + } + } + } +}; + +struct PM4CmdWriteData { + PM4Type3Header header; + union { + BitField<8, 4, u32> dst_sel; + BitField<16, 1, u32> wr_one_addr; + BitField<20, 1, u32> wr_confirm; + BitField<30, 1, u32> engine_sel; + u32 raw; + }; + union { + struct { + u32 dst_addr_lo; + u32 dst_addr_hi; + }; + u64 addr64; + }; + u32 data[0]; + + u32 Size() const { + return (header.count.Value() - 2) * 4; + } + + template + void Address(T addr) { + addr64 = static_cast(addr); + } + + template + T Address() const { + return reinterpret_cast(addr64); + } +}; + +struct PM4CmdEventWriteEos { + enum class Command : u32 { + GdsStore = 1u, + SignalFence = 2u, + }; + + PM4Type3Header header; + union { + u32 event_control; + BitField<0, 6, u32> event_type; ///< Event type written to VGT_EVENT_INITIATOR + BitField<8, 4, u32> event_index; ///< Event index + }; + u32 address_lo; + union { + u32 cmd_info; + BitField<0, 16, u32> address_hi; ///< High bits of address + BitField<29, 3, Command> command; ///< Command + }; + union { + u32 data; ///< Fence value that will be written to memory when event occurs + BitField<0, 16, u32> + gds_index; ///< Indexed offset from the start of the segment within the partition + BitField<16, 16, u32> size; ///< Number of DWs to read from the GDS + }; + + template + T Address() const { + return reinterpret_cast(address_lo | u64(address_hi) << 32); + } + + u32 DataDWord() const { + return this->data; + } + + void SignalFence(auto&& write_mem) const { + const auto cmd = command.Value(); + switch (cmd) { + case Command::SignalFence: { + write_mem(Address(), DataDWord(), sizeof(u32)); + break; + } + case Command::GdsStore: { + break; + } + default: { + UNREACHABLE_MSG("Unknown command {}", u32(cmd)); + } + } + } +}; + +struct PM4WriteConstRam { + PM4Type3Header header; + union { + BitField<0, 16, u32> offset; ///< Starting DW granularity offset into the constant RAM. + ///< Thus, bits[1:0] are zero. + u32 dw1; + }; + u32 data[0]; + + [[nodiscard]] u32 Offset() const { + return offset.Value(); + } + + [[nodiscard]] u32 Size() const { + return header.count << 2u; + } +}; + +struct PM4DumpConstRam { + PM4Type3Header header; + union { + BitField<0, 16, u32> offset; ///< Starting byte offset into the Constant RAM. The minimum + ///< granularity is 4 bytes + u32 dw1; + }; + union { + BitField<0, 15, u32> + num_dw; ///< Number of DWs to read from the constant RAM. The minimum granularity is DWs + u32 dw2; + }; + u32 addr_lo; + u32 addr_hi; + + template + T Address() const { + return reinterpret_cast((u64(addr_hi) << 32u) | addr_lo); + } + + [[nodiscard]] u32 Offset() const { + return offset.Value(); + } + + [[nodiscard]] u32 Size() const { + return num_dw.Value() << 2u; + } +}; + +struct PM4CmdDispatchDirect { + PM4Type3Header header; + u32 dim_x; ///< X dimensions of the array of thread groups to be dispatched + u32 dim_y; ///< Y dimensions of the array of thread groups to be dispatched + u32 dim_z; ///< Z dimensions of the array of thread groups to be dispatched + u32 dispatch_initiator; ///< Dispatch Initiator Register +}; + +struct PM4CmdDrawNumInstances { + PM4Type3Header header; + u32 num_instances; +}; + +struct PM4CmdDrawIndexBase { + PM4Type3Header header; + u32 addr_lo; + u32 addr_hi; +}; + +struct PM4CmdDrawIndexBufferSize { + PM4Type3Header header; + u32 num_indices; +}; + +struct PM4CmdIndirectBuffer { + PM4Type3Header header; + u32 ibase_lo; ///< Indirect buffer base address, must be 4 byte aligned + union { + BitField<0, 16, u32> ibase_hi; ///< Indirect buffer base address + u32 dw1; + }; + union { + BitField<0, 20, u32> ib_size; ///< Indirect buffer size + BitField<20, 1, u32> chain; ///< set to chain to IB allocations + BitField<24, 8, u32> vmid; ///< Virtual memory domain ID for command buffer + u32 dw2; + }; + + template + T* Address() const { + return reinterpret_cast((u64(ibase_hi) << 32u) | ibase_lo); + } +}; + +struct PM4CmdReleaseMem { + PM4Type3Header header; + union { + BitField<0, 6, u32> event_type; ///< Event type written to VGT_EVENT_INITIATOR + BitField<8, 4, u32> event_index; ///< Event index + BitField<12, 1, u32> tcl1_vol_action_ena; + BitField<13, 1, u32> tc_vol_action_ena; + BitField<15, 1, u32> tc_wb_action_ena; + BitField<16, 1, u32> tcl1__action_ena; + BitField<17, 1, u32> tc_action_ena; + BitField<25, 2, u32> cache_policy; ///< Cache Policy setting used for writing fences and + ///< timestamps to the TCL2 + u32 dw1; + }; + union { + BitField<16, 2, u32> dst_sel; ///< destination select + BitField<24, 3, InterruptSelect> int_sel; ///< selects interrupt action for end-of-pipe + BitField<29, 3, DataSelect> data_sel; ///< selects source of data + u32 dw2; + }; + u32 address_lo; ///< low bits of address + u32 address_hi; ///< high bits of address + union { + struct { + u16 gds_index; ///< Byte offset into GDS to copy from + u16 num_dw; ///< Number of DWORDS of GDS to copy + }; + u32 data_lo; ///< value that will be written to memory when event occurs + }; + u32 data_hi; + + template + T Address() const { + u64 full_address = address_lo | (u64(address_hi) << 32); + return std::bit_cast(full_address); + } + + u32 DataDWord() const { + return data_lo; + } + + u64 DataQWord() const { + return data_lo | u64(data_hi) << 32; + } + + void SignalFence(auto&& signal_irq, auto&& gds_to_mem) const { + switch (data_sel.Value()) { + case DataSelect::Data32Low: { + *Address() = DataDWord(); + break; + } + case DataSelect::Data64: { + *Address() = DataQWord(); + break; + } + case DataSelect::GpuClock64: { + *Address() = GetGpuClock64(); + break; + } + case DataSelect::PerfCounter: { + *Address() = GetGpuPerfCounter(); + break; + } + case DataSelect::GdsMemStore: { + gds_to_mem(Address(), gds_index, num_dw); + break; + } + default: { + UNREACHABLE(); + } + } + + switch (int_sel.Value()) { + case InterruptSelect::None: { + // No interrupt + break; + } + case InterruptSelect::IrqUndocumented: + [[fallthrough]]; + case InterruptSelect::IrqWhenWriteConfirm: { + signal_irq(); + break; + } + default: { + UNREACHABLE(); + } + } + } +}; + +struct PM4CmdSetBase { + enum class BaseIndex : u32 { + DisplayListPatchTable = 0b0000, + DrawIndexIndirPatchTable = 0b0001, + GdsPartition = 0b0010, + CePartition = 0b0011, + }; + + PM4Type3Header header; + union { + BitField<0, 4, BaseIndex> base_index; + u32 dw1; + }; + u32 address0; + u32 address1; + + template + T Address() const { + ASSERT(base_index == BaseIndex::DisplayListPatchTable || + base_index == BaseIndex::DrawIndexIndirPatchTable); + return reinterpret_cast(address0 | (u64(address1 & 0xffff) << 32u)); + } +}; + +struct PM4CmdDispatchIndirect { + struct GroupDimensions { + u32 dim_x; + u32 dim_y; + u32 dim_z; + }; + + PM4Type3Header header; + u32 data_offset; ///< Byte aligned offset where the required data structure starts + u32 dispatch_initiator; ///< Dispatch Initiator Register +}; + +struct PM4CmdDispatchIndirectMec { + PM4Type3Header header; + u32 address0; + u32 address1; + u32 dispatch_initiator; ///< Dispatch Initiator Register + + template + T Address() const { + return std::bit_cast(address0 | (u64(address1 & 0xffff) << 32u)); + } +}; + +struct DrawIndirectArgs { + u32 vertex_count_per_instance; + u32 instance_count; + u32 start_vertex_location; + u32 start_instance_location; +}; +static_assert(sizeof(DrawIndirectArgs) == 0x10u); + +struct PM4CmdDrawIndirect { + PM4Type3Header header; ///< header + u32 data_offset; ///< Byte aligned offset where the required data structure starts + union { + u32 dw2; + BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the + ///< BaseVertexLocation it fetched from memory + }; + union { + u32 dw3; + BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the + ///< StartInstanceLocation it fetched from memory + }; + u32 draw_initiator; ///< Draw Initiator Register +}; + +struct PM4CmdDrawIndirectMulti { + PM4Type3Header header; ///< header + u32 data_offset; ///< Byte aligned offset where the required data structure starts + union { + u32 dw2; + BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the + ///< BaseVertexLocation it fetched from memory + }; + union { + u32 dw3; + BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the + ///< StartInstanceLocation it fetched from memory + }; + u32 count; ///< Count of data structures to loop through before going to next packet + u32 stride; ///< Stride in memory from one data structure to the next + u32 draw_initiator; ///< Draw Initiator Register +}; + +struct DrawIndexedIndirectArgs { + u32 index_count_per_instance; + u32 instance_count; + u32 start_index_location; + u32 base_vertex_location; + u32 start_instance_location; +}; +static_assert(sizeof(DrawIndexedIndirectArgs) == 0x14u); + +struct PM4CmdDrawIndexIndirect { + PM4Type3Header header; ///< header + u32 data_offset; ///< Byte aligned offset where the required data structure starts + union { + u32 dw2; + BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the + ///< BaseVertexLocation it fetched from memory + }; + union { + u32 dw3; + BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the + ///< StartInstanceLocation it fetched from memory + }; + u32 draw_initiator; ///< Draw Initiator Register +}; + +struct PM4CmdDrawIndexIndirectMulti { + PM4Type3Header header; ///< header + u32 data_offset; ///< Byte aligned offset where the required data structure starts + union { + u32 dw2; + BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the + ///< BaseVertexLocation it fetched from memory + }; + union { + u32 dw3; + BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the + ///< StartInstanceLocation it fetched from memory + }; + u32 count; ///< Count of data structures to loop through before going to next packet + u32 stride; ///< Stride in memory from one data structure to the next + u32 draw_initiator; ///< Draw Initiator Register +}; + +struct PM4CmdDrawIndexIndirectCountMulti { + PM4Type3Header header; ///< header + u32 data_offset; ///< Byte aligned offset where the required data structure starts + union { + u32 dw2; + BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the + ///< BaseVertexLocation it fetched from memory + }; + union { + u32 dw3; + BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the + ///< StartInstanceLocation it fetched from memory + }; + union { + u32 dw4; + BitField<0, 16, u32> draw_index_loc; ///< register offset to write the Draw Index count + BitField<30, 1, u32> + count_indirect_enable; ///< Indicates the data structure count is in memory + BitField<31, 1, u32> + draw_index_enable; ///< Enables writing of Draw Index count to DRAW_INDEX_LOC + }; + u32 count; ///< Count of data structures to loop through before going to next packet + u64 count_addr; ///< DWord aligned Address[31:2]; Valid if countIndirectEnable is set + u32 stride; ///< Stride in memory from one data structure to the next + u32 draw_initiator; ///< Draw Initiator Register +}; + +struct PM4CmdMemSemaphore { + enum class ClientCode : u32 { + CommandProcessor = 0u, + CommandBuffer = 1u, + DataBuffer = 2u, + }; + enum class Select : u32 { + SignalSemaphore = 6u, + WaitSemaphore = 7u, + }; + enum class SignalType : u32 { + Increment = 0u, + Write = 1u, + }; + + PM4Type3Header header; ///< header + union { + u32 dw1; + BitField<3, 29, u32> addr_lo; ///< Semaphore address bits [31:3] + }; + union { + u32 dw2; + BitField<0, 8, u32> addr_hi; ///< Semaphore address bits [39:32] + BitField<16, 1, u32> use_mailbox; ///< Enables waiting until mailbox is written to + BitField<20, 1, SignalType> signal_type; ///< Indicates the type of signal sent + BitField<24, 2, ClientCode> client_code; + BitField<29, 3, Select> sem_sel; ///< Indicates whether to do a signal or wait operation + }; + + template + [[nodiscard]] T Address() const { + return std::bit_cast(u64(addr_lo) << 3 | (u64(addr_hi) << 32)); + } + + [[nodiscard]] bool IsSignaling() const { + return sem_sel == Select::SignalSemaphore; + } + + [[nodiscard]] bool Signaled() const { + return *Address() > 0; + } + + void Decrement() const { + *Address() -= 1; + } + + void Signal() const { + auto* ptr = Address(); + switch (signal_type) { + case SignalType::Increment: + *ptr += 1; + break; + case SignalType::Write: + *ptr = 1; + break; + default: + UNREACHABLE_MSG("Unknown signal type {}", static_cast(signal_type.Value())); + } + } +}; + +struct PM4CmdCondExec { + PM4Type3Header header; + union { + BitField<2, 30, u32> bool_addr_lo; ///< low 32 address bits for the block in memory from + ///< where the CP will fetch the condition + }; + union { + BitField<0, 16, u32> bool_addr_hi; ///< high address bits for the condition + BitField<28, 4, u32> command; + }; + union { + BitField<0, 14, u32> exec_count; ///< Number of DWords that the CP will skip + ///< if bool pointed to is zero + }; + + bool* Address() const { + return std::bit_cast(u64(bool_addr_hi.Value()) << 32 | u64(bool_addr_lo.Value()) + << 2); + } +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/pm4_opcodes.h b/gpu/shadps4/video_core/amdgpu/pm4_opcodes.h new file mode 100644 index 0000000..4a5f2be --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/pm4_opcodes.h @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace AmdGpu { + +enum class PM4ItOpcode : u32 { + Nop = 0x10, + SetBase = 0x11, + ClearState = 0x12, + IndexBufferSize = 0x13, + DispatchDirect = 0x15, + DispatchIndirect = 0x16, + AtomicGds = 0x1D, + Atomic = 0x1E, + OcclusionQuery = 0x1F, + SetPredication = 0x20, + RegRmw = 0x21, + CondExec = 0x22, + PredExec = 0x23, + DrawIndirect = 0x24, + DrawIndexIndirect = 0x25, + IndexBase = 0x26, + DrawIndex2 = 0x27, + ContextControl = 0x28, + IndexType = 0x2A, + DrawIndirectMulti = 0x2C, + DrawIndexAuto = 0x2D, + NumInstances = 0x2F, + DrawIndexMultiAuto = 0x30, + IndirectBufferConst = 0x33, + StrmoutBufferUpdate = 0x34, + DrawIndexOffset2 = 0x35, + WriteData = 0x37, + DrawIndexIndirectMulti = 0x38, + MemSemaphore = 0x39, + WaitRegMem = 0x3c, + IndirectBuffer = 0x3F, + CondIndirectBuffer = 0x3F, + CopyData = 0x40, + CommandProcessorDma = 0x41, + PfpSyncMe = 0x42, + SurfaceSync = 0x43, + CondWrite = 0x45, + EventWrite = 0x46, + EventWriteEop = 0x47, + EventWriteEos = 0x48, + ReleaseMem = 0x49, + PreambleCntl = 0x4A, + DmaData = 0x50, + ContextRegRmw = 0x51, + AcquireMem = 0x58, + Rewind = 0x59, + LoadShReg = 0x5F, + LoadConfigReg = 0x60, + LoadContextReg = 0x61, + SetConfigReg = 0x68, + SetContextReg = 0x69, + SetContextRegIndirect = 0x73, + SetShReg = 0x76, + SetShRegOffset = 0x77, + SetQueueReg = 0x78, + SetUconfigReg = 0x79, + LoadConstRam = 0x80, + WriteConstRam = 0x81, + DumpConstRam = 0x83, + IncrementCeCounter = 0x84, + IncrementDeCounter = 0x85, + WaitOnCeCounter = 0x86, + WaitOnDeCounterDiff = 0x88, + GetLodStats = 0x8E, + DrawIndexIndirectCountMulti = 0x9d, +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs.cpp b/gpu/shadps4/video_core/amdgpu/regs.cpp new file mode 100644 index 0000000..7454eaf --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs.cpp @@ -0,0 +1,134 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "video_core/amdgpu/regs.h" + +namespace AmdGpu { + +// The following values are taken from fpPS4: +// https://github.com/red-prig/fpPS4/blob/436b43064be4c78229500f3d3c054fc76639247d/chip/pm4_pfp.pas#L410 +static constexpr std::array REG_ARRAY_DEFAULT = { + 0x00000000u, 0x80000000u, 0x40004000u, 0xdeadbeefu, 0x00000000u, 0x40004000u, 0x00000000u, + 0x40004000u, 0x00000000u, 0x40004000u, 0x00000000u, 0x40004000u, 0xaa99aaaau, 0x00000000u, + 0xdeadbeefu, 0xdeadbeefu, 0x80000000u, 0x40004000u, 0x00000000u, 0x00000000u, 0x80000000u, + 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, + 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, + 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, + 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, + 0x40004000u, 0x80000000u, 0x40004000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, + 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, + 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, + 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, + 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, + 0x2a00161au, +}; + +void Regs::SetDefaults() { + std::memset(reg_array.data(), 0, reg_array.size() * sizeof(u32)); + + std::memcpy(®_array[ContextRegWordOffset + 0x80], REG_ARRAY_DEFAULT.data(), + REG_ARRAY_DEFAULT.size() * sizeof(u32)); + + // Individual context regs values + reg_array[ContextRegWordOffset + 0x000d] = 0x40004000u; + reg_array[ContextRegWordOffset + 0x01b6] = 0x00000002u; + reg_array[ContextRegWordOffset + 0x0204] = 0x00090000u; + reg_array[ContextRegWordOffset + 0x0205] = 0x00000004u; + reg_array[ContextRegWordOffset + 0x0295] = 0x00000100u; + reg_array[ContextRegWordOffset + 0x0296] = 0x00000080u; + reg_array[ContextRegWordOffset + 0x0297] = 0x00000002u; + reg_array[ContextRegWordOffset + 0x02aa] = 0x00001000u; + reg_array[ContextRegWordOffset + 0x02f7] = 0x00001000u; + reg_array[ContextRegWordOffset + 0x02f9] = 0x00000005u; + reg_array[ContextRegWordOffset + 0x02fa] = 0x3f800000u; + reg_array[ContextRegWordOffset + 0x02fb] = 0x3f800000u; + reg_array[ContextRegWordOffset + 0x02fc] = 0x3f800000u; + reg_array[ContextRegWordOffset + 0x02fd] = 0x3f800000u; + reg_array[ContextRegWordOffset + 0x0316] = 0x0000000eu; + reg_array[ContextRegWordOffset + 0x0317] = 0x00000010u; +} + +#define GFX6_3D_REG_INDEX(field_name) (offsetof(AmdGpu::Regs, field_name) / sizeof(u32)) + +static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08); +static_assert(GFX6_3D_REG_INDEX(vs_program) == 0x2C48); +static_assert(GFX6_3D_REG_INDEX(vs_program.user_data) == 0x2C4C); +static_assert(GFX6_3D_REG_INDEX(gs_program) == 0x2C88); +static_assert(GFX6_3D_REG_INDEX(es_program) == 0x2CC8); +static_assert(GFX6_3D_REG_INDEX(hs_program) == 0x2D08); +static_assert(GFX6_3D_REG_INDEX(ls_program) == 0x2D48); +static_assert(GFX6_3D_REG_INDEX(cs_program) == 0x2E00); +static_assert(GFX6_3D_REG_INDEX(cs_program.dim_z) == 0x2E03); +static_assert(GFX6_3D_REG_INDEX(cs_program.user_data) == 0x2E40); +static_assert(GFX6_3D_REG_INDEX(depth_render_control) == 0xA000); +static_assert(GFX6_3D_REG_INDEX(depth_view) == 0xA002); +static_assert(GFX6_3D_REG_INDEX(depth_htile_data_base) == 0xA005); +static_assert(GFX6_3D_REG_INDEX(screen_scissor) == 0xA00C); +static_assert(GFX6_3D_REG_INDEX(depth_buffer.z_info) == 0xA010); +static_assert(GFX6_3D_REG_INDEX(depth_buffer.depth_slice) == 0xA017); +static_assert(GFX6_3D_REG_INDEX(ta_bc_base) == 0xA020); +static_assert(GFX6_3D_REG_INDEX(window_offset) == 0xA080); +static_assert(GFX6_3D_REG_INDEX(window_scissor) == 0xA081); +static_assert(GFX6_3D_REG_INDEX(color_target_mask) == 0xA08E); +static_assert(GFX6_3D_REG_INDEX(color_shader_mask) == 0xA08F); +static_assert(GFX6_3D_REG_INDEX(generic_scissor) == 0xA090); +static_assert(GFX6_3D_REG_INDEX(viewport_scissors) == 0xA094); +static_assert(GFX6_3D_REG_INDEX(index_offset) == 0xA102); +static_assert(GFX6_3D_REG_INDEX(primitive_restart_index) == 0xA103); +static_assert(GFX6_3D_REG_INDEX(stencil_control) == 0xA10B); +static_assert(GFX6_3D_REG_INDEX(viewports) == 0xA10F); +static_assert(GFX6_3D_REG_INDEX(clip_user_data) == 0xA16F); +static_assert(GFX6_3D_REG_INDEX(ps_inputs) == 0xA191); +static_assert(GFX6_3D_REG_INDEX(vs_output_config) == 0xA1B1); +static_assert(GFX6_3D_REG_INDEX(ps_input_ena) == 0xA1B3); +static_assert(GFX6_3D_REG_INDEX(ps_input_addr) == 0xA1B4); +static_assert(GFX6_3D_REG_INDEX(shader_pos_format) == 0xA1C3); +static_assert(GFX6_3D_REG_INDEX(z_export_format) == 0xA1C4); +static_assert(GFX6_3D_REG_INDEX(color_export_format) == 0xA1C5); +static_assert(GFX6_3D_REG_INDEX(blend_control) == 0xA1E0); +static_assert(GFX6_3D_REG_INDEX(index_base_address) == 0xA1F9); +static_assert(GFX6_3D_REG_INDEX(draw_initiator) == 0xA1FC); +static_assert(GFX6_3D_REG_INDEX(depth_control) == 0xA200); +static_assert(GFX6_3D_REG_INDEX(color_control) == 0xA202); +static_assert(GFX6_3D_REG_INDEX(clipper_control) == 0xA204); +static_assert(GFX6_3D_REG_INDEX(viewport_control) == 0xA206); +static_assert(GFX6_3D_REG_INDEX(vs_output_control) == 0xA207); +static_assert(GFX6_3D_REG_INDEX(line_control) == 0xA282); +static_assert(GFX6_3D_REG_INDEX(hs_clamp) == 0xA287); +static_assert(GFX6_3D_REG_INDEX(vgt_gs_mode) == 0xA290); +static_assert(GFX6_3D_REG_INDEX(vgt_gs_onchip_control) == 0xA291); +static_assert(GFX6_3D_REG_INDEX(mode_control) == 0xA292); +static_assert(GFX6_3D_REG_INDEX(vgt_gsvs_ring_offset_1) == 0xA298); +static_assert(GFX6_3D_REG_INDEX(vgt_gsvs_ring_offset_2) == 0xA299); +static_assert(GFX6_3D_REG_INDEX(vgt_gsvs_ring_offset_3) == 0xA29A); +static_assert(GFX6_3D_REG_INDEX(vgt_gs_out_prim_type) == 0xA29B); +static_assert(GFX6_3D_REG_INDEX(index_size) == 0xA29D); +static_assert(GFX6_3D_REG_INDEX(index_buffer_type) == 0xA29F); +static_assert(GFX6_3D_REG_INDEX(enable_primitive_id) == 0xA2A1); +static_assert(GFX6_3D_REG_INDEX(enable_primitive_restart) == 0xA2A5); +static_assert(GFX6_3D_REG_INDEX(vgt_instance_step_rate_0) == 0xA2A8); +static_assert(GFX6_3D_REG_INDEX(vgt_instance_step_rate_1) == 0xA2A9); +static_assert(GFX6_3D_REG_INDEX(vgt_esgs_ring_itemsize) == 0xA2AB); +static_assert(GFX6_3D_REG_INDEX(vgt_gsvs_ring_itemsize) == 0xA2AC); +static_assert(GFX6_3D_REG_INDEX(stage_enable) == 0xA2D5); +static_assert(GFX6_3D_REG_INDEX(vgt_gs_vert_itemsize[0]) == 0xA2D7); +static_assert(GFX6_3D_REG_INDEX(tess_config) == 0xA2DB); +static_assert(GFX6_3D_REG_INDEX(poly_offset) == 0xA2DF); +static_assert(GFX6_3D_REG_INDEX(vgt_gs_instance_cnt) == 0xA2E4); +static_assert(GFX6_3D_REG_INDEX(vgt_strmout_config) == 0xA2E5); +static_assert(GFX6_3D_REG_INDEX(vgt_strmout_buffer_config) == 0xA2E6); +static_assert(GFX6_3D_REG_INDEX(aa_config) == 0xA2F8); +static_assert(GFX6_3D_REG_INDEX(color_buffers[0].base_address) == 0xA318); +static_assert(GFX6_3D_REG_INDEX(color_buffers[0].pitch) == 0xA319); +static_assert(GFX6_3D_REG_INDEX(color_buffers[0].slice) == 0xA31A); +static_assert(GFX6_3D_REG_INDEX(color_buffers[7].base_address) == 0xA381); +static_assert(GFX6_3D_REG_INDEX(cp_strmout_cntl) == 0xC03F); +static_assert(GFX6_3D_REG_INDEX(vgt_esgs_ring_size) == 0xC240); +static_assert(GFX6_3D_REG_INDEX(vgt_gsvs_ring_size) == 0xC241); +static_assert(GFX6_3D_REG_INDEX(primitive_type) == 0xC242); +static_assert(GFX6_3D_REG_INDEX(num_instances) == 0xC24D); +static_assert(GFX6_3D_REG_INDEX(vgt_tf_memory_base) == 0xc250); + +#undef GFX6_3D_REG_INDEX + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs.h b/gpu/shadps4/video_core/amdgpu/regs.h new file mode 100644 index 0000000..8e71e5b --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs.h @@ -0,0 +1,196 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "video_core/amdgpu/regs_color.h" +#include "video_core/amdgpu/regs_depth.h" +#include "video_core/amdgpu/regs_primitive.h" +#include "video_core/amdgpu/regs_shader.h" +#include "video_core/amdgpu/regs_texture.h" +#include "video_core/amdgpu/regs_vertex.h" + +namespace AmdGpu { + +#define DO_CONCAT2(x, y) x##y +#define CONCAT2(x, y) DO_CONCAT2(x, y) +#define INSERT_PADDING_WORDS(num_words) \ + [[maybe_unused]] std::array CONCAT2(pad, __LINE__) + +union Regs { + static constexpr u32 NumRegs = 0xD000; + static constexpr u32 UconfigRegWordOffset = 0xC000; + static constexpr u32 ContextRegWordOffset = 0xA000; + static constexpr u32 ConfigRegWordOffset = 0x2000; + static constexpr u32 ShRegWordOffset = 0x2C00; + + struct { + INSERT_PADDING_WORDS(11272); + ShaderProgram ps_program; + INSERT_PADDING_WORDS(44); + ShaderProgram vs_program; + INSERT_PADDING_WORDS(44); + ShaderProgram gs_program; + INSERT_PADDING_WORDS(44); + ShaderProgram es_program; + INSERT_PADDING_WORDS(44); + ShaderProgram hs_program; + INSERT_PADDING_WORDS(44); + ShaderProgram ls_program; + INSERT_PADDING_WORDS(164); + ComputeProgram cs_program; + INSERT_PADDING_WORDS(29104); + DepthRenderControl depth_render_control; + INSERT_PADDING_WORDS(1); + DepthView depth_view; + DepthRenderOverride depth_render_override; + INSERT_PADDING_WORDS(1); + Address depth_htile_data_base; + INSERT_PADDING_WORDS(2); + float depth_bounds_min; + float depth_bounds_max; + u32 stencil_clear; + float depth_clear; + Scissor screen_scissor; + INSERT_PADDING_WORDS(2); + DepthBuffer depth_buffer; + INSERT_PADDING_WORDS(8); + BorderColorBuffer ta_bc_base; + INSERT_PADDING_WORDS(94); + WindowOffset window_offset; + ViewportScissor window_scissor; + INSERT_PADDING_WORDS(11); + ColorBufferMask color_target_mask; + ColorBufferMask color_shader_mask; + ViewportScissor generic_scissor; + INSERT_PADDING_WORDS(2); + std::array viewport_scissors; + std::array viewport_depths; + INSERT_PADDING_WORDS(46); + u32 index_offset; + u32 primitive_restart_index; + INSERT_PADDING_WORDS(1); + BlendConstants blend_constants; + INSERT_PADDING_WORDS(2); + StencilControl stencil_control; + StencilRefMask stencil_ref_front; + StencilRefMask stencil_ref_back; + INSERT_PADDING_WORDS(1); + std::array viewports; + std::array clip_user_data; + INSERT_PADDING_WORDS(10); + std::array ps_inputs; + VsOutputConfig vs_output_config; + INSERT_PADDING_WORDS(1); + PsInput ps_input_ena; + PsInput ps_input_addr; + INSERT_PADDING_WORDS(1); + u32 num_interp : 6; + INSERT_PADDING_WORDS(1); + BarycentricControl barycentric_control; + INSERT_PADDING_WORDS(10); + ShaderPosFormat shader_pos_format; + ShaderExportFormat z_export_format; + ColorExportFormat color_export_format; + INSERT_PADDING_WORDS(26); + std::array blend_control; + INSERT_PADDING_WORDS(17); + IndexBufferBase index_base_address; + INSERT_PADDING_WORDS(1); + u32 draw_initiator; + INSERT_PADDING_WORDS(3); + DepthControl depth_control; + INSERT_PADDING_WORDS(1); + ColorControl color_control; + DepthShaderControl depth_shader_control; + ClipperControl clipper_control; + PolygonControl polygon_control; + ViewportControl viewport_control; + VsOutputControl vs_output_control; + INSERT_PADDING_WORDS(122); + LineControl line_control; + INSERT_PADDING_WORDS(4); + TessFactorClamp hs_clamp; + INSERT_PADDING_WORDS(7); + GsMode vgt_gs_mode; + GsOnchip vgt_gs_onchip_control; + ModeControl mode_control; + INSERT_PADDING_WORDS(5); + RingOffset vgt_gsvs_ring_offset_1; + RingOffset vgt_gsvs_ring_offset_2; + RingOffset vgt_gsvs_ring_offset_3; + GsOutPrimitiveType vgt_gs_out_prim_type; + INSERT_PADDING_WORDS(1); + u32 index_size; + u32 max_index_size; + IndexBufferType index_buffer_type; + INSERT_PADDING_WORDS(1); + u32 enable_primitive_id; + INSERT_PADDING_WORDS(3); + u32 enable_primitive_restart; + INSERT_PADDING_WORDS(2); + u32 vgt_instance_step_rate_0; + u32 vgt_instance_step_rate_1; + INSERT_PADDING_WORDS(1); + u32 vgt_esgs_ring_itemsize; + u32 vgt_gsvs_ring_itemsize; + INSERT_PADDING_WORDS(33); + u32 vgt_gs_max_vert_out : 11; + INSERT_PADDING_WORDS(6); + ShaderStageEnable stage_enable; + LsHsConfig ls_hs_config; + u32 vgt_gs_vert_itemsize[4]; + TessellationConfig tess_config; + INSERT_PADDING_WORDS(3); + PolygonOffset poly_offset; + GsInstances vgt_gs_instance_cnt; + StreamOutConfig vgt_strmout_config; + StreamOutBufferConfig vgt_strmout_buffer_config; + INSERT_PADDING_WORDS(17); + AaConfig aa_config; + INSERT_PADDING_WORDS(31); + ColorBuffer color_buffers[NUM_COLOR_BUFFERS]; + INSERT_PADDING_WORDS(7343); + StreamOutControl cp_strmout_cntl; + INSERT_PADDING_WORDS(512); + u32 vgt_esgs_ring_size; + u32 vgt_gsvs_ring_size; + PrimitiveType primitive_type; + INSERT_PADDING_WORDS(9); + u32 num_indices; + VgtNumInstances num_instances; + INSERT_PADDING_WORDS(2); + TessFactorMemoryBase vgt_tf_memory_base; + }; + std::array reg_array; + + const ShaderProgram* ProgramForStage(u32 index) const { + switch (index) { + case 0: + return &ps_program; + case 1: + return &vs_program; + case 2: + return &gs_program; + case 3: + return &es_program; + case 4: + return &hs_program; + case 5: + return &ls_program; + } + return nullptr; + } + + bool IsClipDisabled() const { + return clipper_control.clip_disable || primitive_type == PrimitiveType::RectList; + } + + void SetDefaults(); +}; + +#undef DO_CONCAT2 +#undef CONCAT2 +#undef INSERT_PADDING_WORDS + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs_color.h b/gpu/shadps4/video_core/amdgpu/regs_color.h new file mode 100644 index 0000000..4de825d --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs_color.h @@ -0,0 +1,308 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "video_core/amdgpu/pixel_format.h" +#include "video_core/amdgpu/tiling.h" + +namespace AmdGpu { + +static constexpr u32 NUM_COLOR_BUFFERS = 8; + +using BlendConstants = std::array; + +struct BlendControl { + enum class BlendFactor : u32 { + Zero = 0, + One = 1, + SrcColor = 2, + OneMinusSrcColor = 3, + SrcAlpha = 4, + OneMinusSrcAlpha = 5, + DstAlpha = 6, + OneMinusDstAlpha = 7, + DstColor = 8, + OneMinusDstColor = 9, + SrcAlphaSaturate = 10, + ConstantColor = 13, + OneMinusConstantColor = 14, + Src1Color = 15, + InvSrc1Color = 16, + Src1Alpha = 17, + InvSrc1Alpha = 18, + ConstantAlpha = 19, + OneMinusConstantAlpha = 20, + }; + + enum class BlendFunc : u32 { + Add = 0, + Subtract = 1, + Min = 2, + Max = 3, + ReverseSubtract = 4, + }; + + BlendFactor color_src_factor : 5; + BlendFunc color_func : 3; + BlendFactor color_dst_factor : 5; + u32 : 3; + BlendFactor alpha_src_factor : 5; + BlendFunc alpha_func : 3; + BlendFactor alpha_dst_factor : 5; + u32 separate_alpha_blend : 1; + u32 enable : 1; + u32 disable_rop3 : 1; + + bool operator==(const BlendControl& other) const = default; +}; + +struct ColorControl { + enum class OperationMode : u32 { + Disable = 0u, + Normal = 1u, + EliminateFastClear = 2u, + Resolve = 3u, + Err = 4u, + FmaskDecompress = 5u, + }; + enum class LogicOp : u32 { + Clear = 0x00, + Nor = 0x11, + AndInverted = 0x22, + CopyInverted = 0x33, + AndReverse = 0x44, + Invert = 0x55, + BrushXor = 0x5a, + Xor = 0x66, + Nand = 0x77, + And = 0x88, + Equiv = 0x99, + Noop = 0xAA, + OrInverted = 0xBB, + Copy = 0xCC, + OrReverse = 0xDD, + Or = 0xEE, + Set = 0xFF, + }; + + u32 disable_dual_quad : 1; + u32 : 2; + u32 degamma_enable : 1; + OperationMode mode : 3; + u32 : 9; + LogicOp rop3 : 8; +}; + +struct ColorBufferMask { + enum ColorComponent : u32 { + ComponentR = (1u << 0), + ComponentG = (1u << 1), + ComponentB = (1u << 2), + ComponentA = (1u << 3), + }; + + u32 raw; + + u32 GetMask(u32 buf_id) const { + return (raw >> (buf_id * 4)) & 0xfu; + } + + void SetMask(u32 buf_id, u32 mask) { + raw &= ~(0xf << (buf_id * 4)); + raw |= (mask << (buf_id * 4)); + } +}; + +struct ColorBuffer { + enum class EndianSwap : u32 { + None = 0, + Swap8In16 = 1, + Swap8In32 = 2, + Swap8In64 = 3, + }; + + enum class SwapMode : u32 { + Standard = 0, + Alternate = 1, + StandardReverse = 2, + AlternateReverse = 3, + }; + + enum class RoundMode : u32 { + ByHalf = 0, + Truncate = 1, + }; + + u32 base_address; + struct { + u32 tile_max : 11; + u32 : 9; + u32 fmask_tile_max : 11; + } pitch; + struct { + u32 tile_max : 22; + } slice; + struct { + u32 slice_start : 11; + u32 : 2; + u32 slice_max : 11; + } view; + union Color0Info { + u32 raw; + struct { + EndianSwap endian : 2; + u32 format : 5; + u32 linear_general : 1; + u32 number_type : 3; + SwapMode comp_swap : 2; + u32 fast_clear : 1; + u32 compression : 1; + u32 blend_clamp : 1; + u32 blend_bypass : 1; + u32 simple_float : 1; + RoundMode round_mode : 1; + u32 cmask_is_linear : 1; + u32 blend_opt_dont_rd_dst : 3; + u32 blend_opt_discard_pixel : 3; + u32 fmask_compression_disable_ci : 1; + u32 fmask_compress_1frag_only : 1; + u32 dcc_enable : 1; + u32 cmask_addr_type : 2; + u32 alt_tile_mode : 1; + }; + } info; + union Color0Attrib { + u32 raw; + struct { + TileMode tile_mode_index : 5; + u32 fmask_tile_mode_index : 5; + u32 fmask_bank_height : 2; + u32 num_samples_log2 : 3; + u32 num_fragments_log2 : 2; + u32 force_dst_alpha_1 : 1; + }; + } attrib; + u32 pad0; + u32 cmask_base_address; + struct { + u32 tile_max : 14; + } cmask_slice; + u32 fmask_base_address; + struct { + u32 tile_max : 14; + } fmask_slice; + u32 clear_word0; + u32 clear_word1; + std::array pad1; + + operator bool() const { + return base_address && info.format; + } + + u32 Pitch() const { + return (pitch.tile_max + 1) << 3; + } + + u32 Height() const { + return (slice.tile_max + 1) * 64 / Pitch(); + } + + u64 Address() const { + return u64(base_address) << 8 | (info.linear_general ? (view.slice_start & 0xff) : 0); + } + + VAddr CmaskAddress() const { + return VAddr(cmask_base_address) << 8; + } + + VAddr FmaskAddress() const { + return VAddr(fmask_base_address) << 8; + } + + u32 NumSamples() const { + return 1 << attrib.num_fragments_log2; + } + + u32 BaseSlice() const { + return info.linear_general ? 0 : view.slice_start; + } + + u32 NumSlices() const { + return view.slice_max + 1; + } + + u32 GetColorSliceSize() const { + const auto num_bytes_per_element = NumBitsPerBlock(DataFormat(info.format)) / 8u; + const auto slice_size = num_bytes_per_element * (slice.tile_max + 1) * 64u * NumSamples(); + return slice_size; + } + + TileMode GetTileMode() const { + return info.linear_general ? TileMode::DisplayLinearGeneral : attrib.tile_mode_index; + } + + bool IsTiled() const { + return GetTileMode() != TileMode::DisplayLinearAligned && + GetTileMode() != TileMode::DisplayLinearGeneral; + } + + DataFormat GetDataFmt() const { + return RemapDataFormat(DataFormat(info.format)); + } + + NumberFormat GetNumberFmt() const { + return RemapNumberFormat(GetFixedNumberFormat(), DataFormat(info.format)); + } + + NumberConversion GetNumberConversion() const { + return MapNumberConversion(GetFixedNumberFormat(), DataFormat(info.format)); + } + + CompMapping Swizzle() const { + // clang-format off + static constexpr std::array, 4> mrt_swizzles{{ + // Standard + std::array{{ + {.r = CompSwizzle::Red, .g = CompSwizzle::Zero, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Red, .g = CompSwizzle::Green, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Red, .g = CompSwizzle::Green, .b = CompSwizzle::Blue, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Red, .g = CompSwizzle::Green, .b = CompSwizzle::Blue, .a = CompSwizzle::Alpha}, + }}, + // Alternate + std::array{{ + {.r = CompSwizzle::Green, .g = CompSwizzle::Zero, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Red, .g = CompSwizzle::Alpha, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Red, .g = CompSwizzle::Green, .b = CompSwizzle::Alpha, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Blue, .g = CompSwizzle::Green, .b = CompSwizzle::Red, .a = CompSwizzle::Alpha}, + }}, + // StandardReverse + std::array{{ + {.r = CompSwizzle::Blue, .g = CompSwizzle::Zero, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Green, .g = CompSwizzle::Red, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Blue, .g = CompSwizzle::Green, .b = CompSwizzle::Red, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Alpha, .g = CompSwizzle::Blue, .b = CompSwizzle::Green, .a = CompSwizzle::Red}, + }}, + // AlternateReverse + std::array{{ + {.r = CompSwizzle::Alpha, .g = CompSwizzle::Zero, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Alpha, .g = CompSwizzle::Red, .b = CompSwizzle::Zero, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Alpha, .g = CompSwizzle::Green, .b = CompSwizzle::Red, .a = CompSwizzle::Zero}, + {.r = CompSwizzle::Alpha, .g = CompSwizzle::Red, .b = CompSwizzle::Green, .a = CompSwizzle::Blue}, + }}, + }}; + // clang-format on + const auto swap_idx = static_cast(info.comp_swap); + const auto components_idx = NumComponents(DataFormat(info.format)) - 1; + const auto mrt_swizzle = mrt_swizzles[swap_idx][components_idx]; + return RemapSwizzle(DataFormat(info.format), mrt_swizzle); + } + + NumberFormat GetFixedNumberFormat() const { + // There is a small difference between T# and CB number types, account for it. + const auto number_fmt = NumberFormat(info.number_type); + return number_fmt == NumberFormat::SnormNz ? NumberFormat::Srgb : number_fmt; + } +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs_depth.h b/gpu/shadps4/video_core/amdgpu/regs_depth.h new file mode 100644 index 0000000..5cab35c --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs_depth.h @@ -0,0 +1,291 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/types.h" +#include "video_core/amdgpu/tiling.h" + +namespace AmdGpu { + +enum class ZOrder : u32 { + LateZ = 0, + EarlyZLateZ = 1, + ReZ = 2, + EarlyZReZ = 3, +}; + +enum class ConservativeDepth : u32 { + Any = 0, + LessThanZ = 1, + GreaterThanZ = 2, +}; + +struct DepthShaderControl { + u32 z_export_enable : 1; + u32 stencil_test_val_export_enable : 1; + u32 stencil_op_val_export_enable : 1; + u32 : 1; + ZOrder z_order : 2; + u32 kill_enable : 1; + u32 coverage_to_mask_enable : 1; + u32 mask_export_enable : 1; + u32 exec_on_hier_fail : 1; + u32 exec_on_noop : 1; + u32 alpha_to_mask_disable : 1; + u32 depth_before_shader : 1; + ConservativeDepth conservative_z_export : 2; +}; + +enum class CompareFunc : u32 { + Never = 0, + Less = 1, + Equal = 2, + LessEqual = 3, + Greater = 4, + NotEqual = 5, + GreaterEqual = 6, + Always = 7, +}; + +struct DepthControl { + u32 stencil_enable : 1; + u32 depth_enable : 1; + u32 depth_write_enable : 1; + u32 depth_bounds_enable : 1; + CompareFunc depth_func : 3; + u32 backface_enable : 1; + CompareFunc stencil_ref_func : 3; + u32 : 9; + CompareFunc stencil_bf_func : 3; + u32 : 7; + u32 enable_color_writes_on_depth_fail : 1; + u32 disable_color_writes_on_depth_pass : 1; +}; + +enum class StencilFunc : u32 { + Keep = 0, + Zero = 1, + Ones = 2, + ReplaceTest = 3, + ReplaceOp = 4, + AddClamp = 5, + SubClamp = 6, + Invert = 7, + AddWrap = 8, + SubWrap = 9, + And = 10, + Or = 11, + Xor = 12, + Nand = 13, + Nor = 14, + Xnor = 15, +}; + +struct StencilControl { + StencilFunc stencil_fail_front : 4; + StencilFunc stencil_zpass_front : 4; + StencilFunc stencil_zfail_front : 4; + StencilFunc stencil_fail_back : 4; + StencilFunc stencil_zpass_back : 4; + StencilFunc stencil_zfail_back : 4; +}; + +struct StencilRefMask { + u8 stencil_test_val; + u8 stencil_mask; + u8 stencil_write_mask; + u8 stencil_op_val; +}; + +struct DepthRenderControl { + u32 depth_clear_enable : 1; + u32 stencil_clear_enable : 1; + u32 depth_copy : 1; + u32 stencil_copy : 1; + u32 resummarize_enable : 1; + u32 stencil_compress_disable : 1; + u32 depth_compress_disable : 1; + u32 copy_centroid : 1; + u32 copy_sample : 1; + u32 decompress_enable : 1; +}; + +struct DepthView { + u32 slice_start : 11; + u32 : 2; + u32 slice_max : 11; + u32 z_read_only : 1; + u32 stencil_read_only : 1; + + u32 NumSlices() const { + return slice_max + 1u; + } +}; + +enum class ForceEnable : u32 { + Off = 0, + Enable = 1, + Disable = 2, +}; + +enum class ForceSumm : u32 { + Off = 0, + MinZ = 1, + MaxZ = 2, + Both = 3, +}; + +struct DepthRenderOverride { + ForceEnable force_hiz_enable : 2; + ForceEnable force_his_enable0 : 2; + ForceEnable force_his_enable1 : 2; + u32 force_shader_z_order : 1; + u32 fast_z_disable : 1; + u32 fast_stencil_disable : 1; + u32 noop_cull_disable : 1; + u32 force_color_kill : 1; + u32 force_z_read : 1; + u32 force_stencil_read : 1; + ForceEnable force_full_z_range : 2; + u32 force_qc_smask_conflict : 1; + u32 disable_viewport_clamp : 1; + u32 ignore_sc_zrange : 1; + u32 disable_fully_covered : 1; + ForceSumm force_z_limit_summ : 2; + u32 max_tiles_in_dtt : 5; + u32 disable_tile_rate_tiles : 1; + u32 force_z_dirty : 1; + u32 force_stencil_dirty : 1; + u32 force_z_valid : 1; + u32 force_stencil_valid : 1; + u32 preserve_compression : 1; +}; + +struct Eqaa { + u32 max_anchor_samples : 1; + u32 : 3; + u32 ps_iter_samples : 3; + u32 : 1; + u32 mask_export_num_samples : 3; + u32 : 1; + u32 alpha_to_mask_num_samples : 3; + u32 : 1; + u32 high_quality_intersections : 1; + u32 incoherent_eqaa_reads : 1; + u32 interpolate_comp_z : 1; + u32 interpolate_src_z : 1; + u32 static_anchor_associations : 1; + u32 alpha_to_mask_eqaa_disable : 1; + u32 : 2; + u32 overrasterization_amount : 3; + u32 enable_postz_overrasterization : 1; +}; + +struct DepthBuffer { + enum class ZFormat : u32 { + Invalid = 0, + Z16 = 1, + Z32Float = 3, + }; + + enum class StencilFormat : u32 { + Invalid = 0, + Stencil8 = 1, + }; + + struct ZInfo { + ZFormat format : 2; + u32 num_samples : 2; + u32 : 9; + u32 tile_split : 3; + u32 : 4; + u32 tile_mode_index : 3; + u32 decompress_on_n_zplanes : 4; + u32 allow_expclear : 1; + u32 read_size : 1; + u32 tile_surface_enable : 1; + u32 clear_disallowed : 1; + u32 zrange_precision : 1; + } z_info; + struct { + StencilFormat format : 1; + } stencil_info; + u32 z_read_base; + u32 stencil_read_base; + u32 z_write_base; + u32 stencil_write_base; + struct { + u32 pitch_tile_max : 11; + u32 height_tile_max : 11; + } depth_size; + struct { + u32 tile_max : 22; + } depth_slice; + + bool DepthValid() const { + return DepthAddress() != 0 && z_info.format != ZFormat::Invalid; + } + + bool StencilValid() const { + return StencilAddress() != 0 && stencil_info.format != StencilFormat::Invalid; + } + + bool DepthWriteValid() const { + return DepthWriteAddress() != 0 && z_info.format != ZFormat::Invalid; + } + + bool StencilWriteValid() const { + return StencilWriteAddress() != 0 && stencil_info.format != StencilFormat::Invalid; + } + + u32 Pitch() const { + return (depth_size.pitch_tile_max + 1) << 3; + } + + u32 Height() const { + return (depth_size.height_tile_max + 1) << 3; + } + + u64 DepthAddress() const { + return u64(z_read_base) << 8; + } + + u64 StencilAddress() const { + return u64(stencil_read_base) << 8; + } + + u64 DepthWriteAddress() const { + return u64(z_write_base) << 8; + } + + u64 StencilWriteAddress() const { + return u64(stencil_write_base) << 8; + } + + u32 NumSamples() const { + return 1u << z_info.num_samples; // spec doesn't say it is a log2 + } + + u32 NumBits() const { + return z_info.format == ZFormat::Z32Float ? 32 : 16; + } + + u32 GetDepthSliceSize() const { + ASSERT(z_info.format != ZFormat::Invalid); + const auto bpe = NumBits() >> 3; // in bytes + return (depth_slice.tile_max + 1) * 64 * bpe * NumSamples(); + } + + TileMode GetTileMode() const { + return static_cast(z_info.tile_mode_index); + } + + bool IsTiled() const { + return GetTileMode() != TileMode::DisplayLinearAligned && + GetTileMode() != TileMode::DisplayLinearGeneral; + } +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs_primitive.h b/gpu/shadps4/video_core/amdgpu/regs_primitive.h new file mode 100644 index 0000000..562ae65 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs_primitive.h @@ -0,0 +1,237 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace AmdGpu { + +static constexpr u32 NUM_VIEWPORTS = 16; +static constexpr u32 NUM_CLIP_PLANES = 6; + +enum class ClipSpace : u32 { + MinusWToW = 0, + ZeroToW = 1, +}; + +enum class PrimKillCond : u32 { + AllVtx = 0, + AnyVtx = 1, +}; + +struct ClipperControl { + u32 user_clip_plane_enable : 6; + u32 : 10; + u32 clip_disable : 1; + u32 : 2; + ClipSpace clip_space : 1; + u32 : 1; + PrimKillCond vtx_kill_or : 1; + u32 dx_rasterization_kill : 1; + u32 : 1; + u32 dx_linear_attr_clip_enable : 1; + u32 : 1; + u32 zclip_near_disable : 1; + u32 zclip_far_disable : 1; + + bool ZclipEnable() const { + if (zclip_near_disable != zclip_far_disable) { + return false; + } + return !zclip_near_disable; + } +}; + +enum class PolygonMode : u32 { + Point = 0, + Line = 1, + Fill = 2, +}; + +enum class ProvokingVtxLast : u32 { + First = 0, + Last = 1, +}; + +enum class CullMode : u32 { + None = 0, + Front = 1, + Back = 2, + FrontAndBack = 3, +}; + +enum class FrontFace : u32 { + CounterClockwise = 0, + Clockwise = 1, +}; + +struct PolygonControl { + u32 cull_front : 1; + u32 cull_back : 1; + FrontFace front_face : 1; + u32 enable_polygon_mode : 2; + PolygonMode polygon_mode_front : 3; + PolygonMode polygon_mode_back : 3; + u32 enable_polygon_offset_front : 1; + u32 enable_polygon_offset_back : 1; + u32 enable_polygon_offset_para : 1; + u32 : 2; + u32 enable_window_offset : 1; + u32 : 2; + ProvokingVtxLast provoking_vtx_last : 1; + u32 persp_corr_dis : 1; + u32 multi_prim_ib_ena : 1; + + PolygonMode PolyMode() const { + return enable_polygon_mode ? polygon_mode_front : PolygonMode::Fill; + } + + CullMode CullingMode() const { + return static_cast(cull_front | cull_back << 1); + } + + bool NeedsBias() const { + return enable_polygon_offset_back || enable_polygon_offset_front || + enable_polygon_offset_para; + } +}; + +struct VsOutputControl { + u32 clip_distance_enable : 8; + u32 cull_distance_enable : 8; + u32 use_vtx_point_size : 1; + u32 use_vtx_edge_flag : 1; + u32 use_vtx_render_target_idx : 1; + u32 use_vtx_viewport_idx : 1; + u32 use_vtx_kill_flag : 1; + u32 vs_out_misc_enable : 1; + u32 vs_out_ccdist0_enable : 1; + u32 vs_out_ccdist1_enable : 1; + u32 vs_out_misc_side_bus_ena : 1; + u32 use_vtx_gs_cut_flag : 1; + + bool IsClipDistEnabled(u32 index) const { + return (clip_distance_enable >> index) & 1; + } + + bool IsCullDistEnabled(u32 index) const { + return (cull_distance_enable >> index) & 1; + } +}; + +struct LineControl { + u32 width_fixed_point; + + float Width() const { + return static_cast(width_fixed_point) / 8.0; + } +}; + +struct ModeControl { + u32 msaa_enable : 1; + u32 vport_scissor_enable : 1; + u32 line_stripple_enable : 1; + u32 send_unlit_stiles_to_pkr : 1; +}; + +struct Scissor { + struct { + s16 top_left_x; + s16 top_left_y; + }; + struct { + s16 bottom_right_x; + s16 bottom_right_y; + }; + + static u16 Clamp(s16 value) { + return std::max(s16(0), value); + } + + u32 GetWidth() const { + return static_cast(Clamp(bottom_right_x) - Clamp(top_left_x)); + } + + u32 GetHeight() const { + return static_cast(Clamp(bottom_right_y) - Clamp(top_left_y)); + } +}; + +struct WindowOffset { + s32 window_x_offset : 16; + s32 window_y_offset : 16; +}; + +struct ViewportScissor { + struct { + u16 top_left_x : 15; + u16 top_left_y : 15; + u16 window_offset_disable : 1; + }; + struct { + u16 bottom_right_x : 15; + u16 bottom_right_y : 15; + }; + + u32 GetWidth() const { + return bottom_right_x - top_left_x; + } + + u32 GetHeight() const { + return bottom_right_y - top_left_y; + } +}; + +struct ViewportDepth { + float zmin; + float zmax; +}; + +struct ViewportBounds { + float xscale; + float xoffset; + float yscale; + float yoffset; + float zscale; + float zoffset; +}; + +struct ViewportControl { + u32 xscale_enable : 1; + u32 xoffset_enable : 1; + u32 yscale_enable : 1; + u32 yoffset_enable : 1; + u32 zscale_enable : 1; + u32 zoffset_enable : 1; + u32 : 2; + u32 xy_transformed : 1; + u32 z_transformed : 1; + u32 w_transformed : 1; + u32 perfcounter_ref : 1; +}; + +struct ClipUserData { + u32 data_x; + u32 data_y; + u32 data_z; + u32 data_w; +}; + +struct AaConfig { + u32 msaa_num_samples : 3; + u32 : 1; + u32 aa_mask_centroid_dtmn : 1; + u32 : 8; + u32 max_sample_dst : 4; + u32 : 3; + u32 msaa_exposed_samples : 3; + u32 : 1; + u32 detail_to_exposed_mode : 2; + + u32 NumSamples() const { + return 1 << msaa_num_samples; + } +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs_shader.h b/gpu/shadps4/video_core/amdgpu/regs_shader.h new file mode 100644 index 0000000..b531738 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs_shader.h @@ -0,0 +1,247 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/types.h" +#include "shader_recompiler/params.h" + +namespace AmdGpu { + +static constexpr u32 NUM_USER_DATA = 16; + +using UserData = std::array; + +struct BinaryInfo { + static constexpr std::array signature_ref = {0x4f, 0x72, 0x62, 0x53, + 0x68, 0x64, 0x72}; // OrbShdr + + std::array signature; + u8 version; + u32 pssl_or_cg : 1; + u32 cached : 1; + u32 type : 4; + u32 source_type : 2; + u32 length : 24; + u8 chunk_usage_base_offset_in_dw; + u8 num_input_usage_slots; + u8 is_srt : 1; + u8 is_srt_used_info_valid : 1; + u8 is_extended_usage_info : 1; + u8 reserved2 : 5; + u8 reserved3; + u64 shader_hash; + u32 crc32; + + bool Valid() const { + return signature == signature_ref; + } +}; + +enum class FpRoundMode : u32 { + NearestEven = 0, + PlusInf = 1, + MinInf = 2, + ToZero = 3, +}; + +enum class FpDenormMode : u32 { + InOutFlush = 0, + InAllowOutFlush = 1, + InFlushOutAllow = 2, + InOutAllow = 3, +}; + +struct ShaderProgram { + u64 address : 40; + struct { + u32 num_vgprs : 6; + u32 num_sgprs : 4; + u32 priority : 2; + FpRoundMode fp_round_mode32 : 2; + FpRoundMode fp_round_mode64 : 2; + FpDenormMode fp_denorm_mode32 : 2; + FpDenormMode fp_denorm_mode64 : 2; + u32 : 4; + u32 vgpr_comp_cnt : 2; + u32 : 6; + u32 scratch_en : 1; + u32 num_user_regs : 5; + u32 : 1; + u32 oc_lds_en : 1; + } settings; + UserData user_data; + + template + const T Address() const { + return std::bit_cast(address << 8); + } + + [[nodiscard]] u32 NumVgprs() const { + // Each increment allocates 4 registers, where 0 = 4 registers. + return (settings.num_vgprs + 1) * 4; + } +}; + +struct VsOutputConfig { + u32 : 1; + u32 export_count_min_one : 5; + u32 half_pack : 1; + + u32 NumExports() const { + return export_count_min_one + 1; + } +}; + +struct PsInputControl { + u32 input_offset : 5; + u32 use_default : 1; + u32 : 2; + u32 default_value : 2; + u32 flat_shade : 1; +}; + +struct PsInput { + u32 persp_sample_ena : 1; + u32 persp_center_ena : 1; + u32 persp_centroid_ena : 1; + u32 persp_pull_model_ena : 1; + u32 linear_sample_ena : 1; + u32 linear_center_ena : 1; + u32 linear_centroid_ena : 1; + u32 line_stipple_tex_ena : 1; + u32 pos_x_float_ena : 1; + u32 pos_y_float_ena : 1; + u32 pos_z_float_ena : 1; + u32 pos_w_float_ena : 1; + u32 front_face_ena : 1; + u32 ancillary_ena : 1; + u32 sample_coverage_ena : 1; + u32 pos_fixed_pt_ena : 1; + + bool operator==(const PsInput&) const = default; +}; + +struct BarycentricControl { + u32 : 24; + u32 front_face_all_bits : 1; +}; +static_assert(sizeof(BarycentricControl) == sizeof(u32)); + +enum class ShaderExportComp : u32 { + None = 0, + OneComp = 1, + TwoComp = 2, + FourCompCompressed = 3, + FourComp = 4, +}; + +struct ShaderPosFormat { + ShaderExportComp pos0 : 4; + ShaderExportComp pos1 : 4; + ShaderExportComp pos2 : 4; + ShaderExportComp pos3 : 4; +}; + +enum class ShaderExportFormat : u32 { + Zero = 0, + R_32 = 1, + GR_32 = 2, + AR_32 = 3, + ABGR_FP16 = 4, + ABGR_UNORM16 = 5, + ABGR_SNORM16 = 6, + ABGR_UINT16 = 7, + ABGR_SINT16 = 8, + ABGR_32 = 9, +}; + +struct ColorExportFormat { + u32 raw; + + [[nodiscard]] ShaderExportFormat GetFormat(const u32 buf_idx) const { + return static_cast((raw >> (buf_idx * 4)) & 0xfu); + } +}; + +struct ComputeProgram { + u32 dispatch_initiator; + u32 dim_x; + u32 dim_y; + u32 dim_z; + u32 start_x; + u32 start_y; + u32 start_z; + struct { + u16 full; + u16 partial; + } num_thread_x, num_thread_y, num_thread_z; + u32 pad0; + u32 max_wave_id : 12; + u64 address : 40; + std::array pad1; + struct { + u64 num_vgprs : 6; + u64 num_sgprs : 4; + u64 : 23; + u64 num_user_regs : 5; + u64 : 1; + u64 tgid_enable : 3; + u64 : 5; + u64 lds_dwords : 9; + } settings; + u32 pad2; + u32 resource_limits; + std::array pad3; + UserData user_data; + + template + const T Address() const { + return std::bit_cast(address << 8); + } + + u32 SharedMemSize() const noexcept { + // lds_dwords is in units of 128 dwords. We return bytes. + return settings.lds_dwords * 128 * 4; + } + + u32 NumWorkgroups() const noexcept { + return dim_x * dim_y * dim_z; + } + + bool IsTgidEnabled(u32 i) const noexcept { + return (settings.tgid_enable >> i) & 1; + } +}; + +static constexpr const BinaryInfo& SearchBinaryInfo(const u32* code) { + constexpr u32 token_mov_vcchi = 0xBEEB03FF; + if (code[0] == token_mov_vcchi) { + const auto* info = std::bit_cast(code + (code[1] + 1) * 2); + if (info->Valid()) { + return *info; + } + } + constexpr u32 signature_size = sizeof(BinaryInfo::signature_ref) / sizeof(u8); + constexpr u32 search_limit = 0x4000; + const u32* end = code + search_limit; + for (const u32* it = code; it < end; ++it) { + if (const BinaryInfo* info = std::bit_cast(it); info->Valid()) { + return *info; + } + } + UNREACHABLE_MSG("Shader binary info not found."); +} + +static constexpr Shader::ShaderParams GetParams(const auto& sh) { + const auto* code = sh.template Address(); + const auto& bininfo = SearchBinaryInfo(code); + return { + .user_data = sh.user_data, + .code = std::span{code, bininfo.length / sizeof(u32)}, + .hash = bininfo.shader_hash, + }; +} + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs_texture.h b/gpu/shadps4/video_core/amdgpu/regs_texture.h new file mode 100644 index 0000000..503cecf --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs_texture.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace AmdGpu { + +struct BorderColorBuffer { + u64 base_addr : 40; + + template + const T Address() const { + return std::bit_cast(base_addr << 8); + } +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/regs_vertex.h b/gpu/shadps4/video_core/amdgpu/regs_vertex.h new file mode 100644 index 0000000..77fdb42 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/regs_vertex.h @@ -0,0 +1,285 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/types.h" + +namespace AmdGpu { + +enum class PrimitiveType : u32 { + None = 0, + PointList = 1, + LineList = 2, + LineStrip = 3, + TriangleList = 4, + TriangleFan = 5, + TriangleStrip = 6, + PatchPrimitive = 9, + AdjLineList = 10, + AdjLineStrip = 11, + AdjTriangleList = 12, + AdjTriangleStrip = 13, + RectList = 17, + LineLoop = 18, + QuadList = 19, + QuadStrip = 20, + Polygon = 21, +}; + +struct IndexBufferBase { + u32 base_addr_hi : 8; + u32 base_addr_lo; + + template + T Address() const { + return std::bit_cast((base_addr_lo & ~1U) | u64(base_addr_hi) << 32); + } +}; + +enum class IndexType : u32 { + Index16 = 0, + Index32 = 1, +}; + +enum class IndexSwapMode : u32 { + None = 0, + Swap16 = 1, + Swap32 = 2, + SwapWord = 3, +}; + +union IndexBufferType { + u32 raw; + struct { + IndexType index_type : 2; + IndexSwapMode swap_mode : 2; + }; +}; + +struct VgtNumInstances { + u32 num_instances; + + u32 NumInstances() const { + return num_instances == 0 ? 1 : num_instances; + } +}; + +struct PolygonOffset { + float depth_bias; + float front_scale; + float front_offset; + float back_scale; + float back_offset; +}; + +struct Address { + u32 address; + + VAddr GetAddress() const { + return u64(address) << 8; + } +}; + +union ShaderStageEnable { + enum VgtStages : u32 { + Vs = 0u, // always enabled + EsGs = 0xB0u, + LsHs = 0x45u, + LsHsEsGs = 0xAD, + }; + + VgtStages raw; + struct { + u32 ls_en : 2; + u32 hs_en : 1; + u32 es_en : 2; + u32 gs_en : 1; + u32 vs_en : 2; + u32 dynamic_hs : 1; + }; + + bool IsStageEnabled(u32 stage) const { + switch (stage) { + case 0: + case 1: + return true; + case 2: + return gs_en; + case 3: + return es_en; + case 4: + return hs_en; + case 5: + return ls_en; + default: + UNREACHABLE(); + } + } +}; + +union GsInstances { + u32 raw; + struct { + u32 enable : 2; + u32 count : 6; + }; + + bool IsEnabled() const { + return enable && count > 0; + } +}; + +enum class GsOutputPrimitiveType : u32 { + PointList = 0, + LineStrip = 1, + TriangleStrip = 2, +}; + +union RingOffset { + u32 raw; + struct { + u32 offset : 15; + }; + + u32 GetOffset() const { + return offset; + } +}; + +union GsOutPrimitiveType { + u32 raw; + struct { + GsOutputPrimitiveType outprim_type : 6; + GsOutputPrimitiveType outprim_type1 : 6; + GsOutputPrimitiveType outprim_type2 : 6; + GsOutputPrimitiveType outprim_type3 : 6; + u32 reserved : 3; + u32 unique_type_per_stream : 1; + }; + + GsOutputPrimitiveType GetPrimitiveType(u32 stream) const { + if (unique_type_per_stream == 0) { + return outprim_type; + } + + switch (stream) { + case 0: + return outprim_type; + case 1: + return outprim_type1; + case 2: + return outprim_type2; + case 3: + return outprim_type3; + default: + UNREACHABLE(); + } + } +}; + +enum class GsScenario : u32 { + Off = 0, + ScenarioA = 1, + ScenarioB = 2, + ScenarioG = 3, + ScenarioC = 4, +}; + +struct GsMode { + GsScenario mode : 3; + u32 : 1; + u32 cut_mode : 2; + u32 : 5; + u32 gs_c_pack_en : 1; + u32 : 1; + u32 es_passthru : 1; + u32 compute_mode : 1; + u32 fast_compute_mode : 1; + u32 element_info_en : 1; + u32 partial_thd_at_eoi : 1; + u32 suppress_cuts : 1; + u32 es_write_optimize : 1; + u32 gs_write_optimize : 1; + u32 onchip : 2; +}; + +struct GsOnchip { + u32 es_verts_per_subgroup : 11; + u32 gs_prims_per_subgroup : 11; +}; + +struct StreamOutControl { + u32 offset_update_done : 1; + u32 : 31; +}; + +union StreamOutConfig { + u32 raw; + struct { + u32 streamout_0_en : 1; + u32 streamout_1_en : 1; + u32 streamout_2_en : 1; + u32 streamout_3_en : 1; + u32 rast_stream : 3; + u32 : 1; + u32 rast_stream_mask : 4; + u32 : 19; + u32 use_rast_stream_mask : 1; + }; +}; + +struct StreamOutBufferConfig { + u32 stream_0_buf_en : 4; + u32 stream_1_buf_en : 4; + u32 stream_2_buf_en : 4; + u32 stream_3_buf_en : 4; +}; + +struct LsHsConfig { + u32 num_patches : 8; + u32 hs_input_control_points : 6; + u32 hs_output_control_points : 6; +}; + +enum class TessellationType : u32 { + Isoline = 0, + Triangle = 1, + Quad = 2, +}; + +enum class TessellationPartitioning : u32 { + Integer = 0, + Pow2 = 1, + FracOdd = 2, + FracEven = 3, +}; + +enum class TessellationTopology : u32 { + Point = 0, + Line = 1, + TriangleCw = 2, + TriangleCcw = 3, +}; + +struct TessellationConfig { + TessellationType type : 2; + TessellationPartitioning partitioning : 3; + TessellationTopology topology : 3; +}; + +struct TessFactorMemoryBase { + u32 base; + + u64 MemoryBase() const { + return static_cast(base) << 8; + } +}; + +struct TessFactorClamp { + float hs_max_tess; + float hs_min_tess; +}; + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/resource.h b/gpu/shadps4/video_core/amdgpu/resource.h new file mode 100644 index 0000000..8255184 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/resource.h @@ -0,0 +1,509 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/alignment.h" +#include "common/assert.h" +#include "common/bit_field.h" +#include "video_core/amdgpu/pixel_format.h" +#include "video_core/amdgpu/tiling.h" + +namespace AmdGpu { + +// Table 8.5 Buffer Resource Descriptor [Sea Islands Series Instruction Set Architecture] +struct Buffer { + u64 base_address : 40; + u64 _padding0 : 8; + u64 stride : 14; + u64 cache_swizzle : 1; + u64 swizzle_enable : 1; + u32 num_records; + u32 dst_sel_x : 3; + u32 dst_sel_y : 3; + u32 dst_sel_z : 3; + u32 dst_sel_w : 3; + u32 num_format : 3; + u32 data_format : 4; + u32 element_size : 2; + u32 index_stride : 2; + u32 add_tid_enable : 1; + u32 _padding1 : 3; + u32 mtype : 3; + u32 type : 2; // overlaps with T# type, so should be 0 for buffer + + static constexpr Buffer Null() { + Buffer buffer{}; + buffer.base_address = 1; + return buffer; + } + + static constexpr Buffer Placeholder(u32 size) { + Buffer buffer{}; + buffer.base_address = 1; + buffer.num_records = size; + return buffer; + } + + bool Valid() const { + return type == 0u; + } + + operator bool() const noexcept { + return num_records != 0; + } + + bool operator==(const Buffer& other) const noexcept { + return std::memcmp(this, &other, sizeof(Buffer)) == 0; + } + + CompMapping DstSelect() const { + const CompMapping dst_sel{ + .r = CompSwizzle(dst_sel_x), + .g = CompSwizzle(dst_sel_y), + .b = CompSwizzle(dst_sel_z), + .a = CompSwizzle(dst_sel_w), + }; + return RemapSwizzle(DataFormat(data_format), dst_sel); + } + + NumberFormat GetNumberFmt() const noexcept { + return RemapNumberFormat(NumberFormat(num_format), DataFormat(data_format)); + } + + DataFormat GetDataFmt() const noexcept { + return RemapDataFormat(DataFormat(data_format)); + } + + NumberConversion GetNumberConversion() const noexcept { + return MapNumberConversion(NumberFormat(num_format), DataFormat(data_format)); + } + + u32 GetStride() const noexcept { + return stride; + } + + u32 NumDwords() const noexcept { + return Common::AlignUp(GetSize(), sizeof(u32)) >> 2; + } + + u32 GetSize() const noexcept { + return stride == 0 ? num_records : (stride * num_records); + } + + u32 GetIndexStride() const noexcept { + // Index stride is 2 bits, meaning 8, 16, 32, or 64. + return 8 << index_stride; + } + + u32 GetElementSize() const noexcept { + // Element size is 2 bits, meaning 2, 4, 8, or 16. + return 2 << element_size; + } +}; +static_assert(sizeof(Buffer) == 16); // 128bits + +enum class ImageType : u64 { + Invalid = 0, + Color1D = 8, + Color2D = 9, + Color3D = 10, + Cube = 11, + Color1DArray = 12, + Color2DArray = 13, + Color2DMsaa = 14, + Color2DMsaaArray = 15, +}; + +constexpr std::string_view NameOf(ImageType type) { + switch (type) { + case ImageType::Invalid: + return "Invalid"; + case ImageType::Color1D: + return "Color1D"; + case ImageType::Color2D: + return "Color2D"; + case ImageType::Color3D: + return "Color3D"; + case ImageType::Cube: + return "Cube"; + case ImageType::Color1DArray: + return "Color1DArray"; + case ImageType::Color2DArray: + return "Color2DArray"; + case ImageType::Color2DMsaa: + return "Color2DMsaa"; + case ImageType::Color2DMsaaArray: + return "Color2DMsaaArray"; + default: + return "Unknown"; + } +} + +struct Image { + u64 base_address : 38; + u64 mtype_l2 : 2; + u64 min_lod : 12; + u64 data_format : 6; + u64 num_format : 4; + u64 mtype : 2; + + u64 width : 14; + u64 height : 14; + u64 perf_modulation : 3; + u64 interlaced : 1; + u64 dst_sel_x : 3; + u64 dst_sel_y : 3; + u64 dst_sel_z : 3; + u64 dst_sel_w : 3; + u64 base_level : 4; + u64 last_level : 4; + u64 tiling_index : 5; + u64 pow2pad : 1; + u64 mtype2 : 1; + u64 atc : 1; + u64 type : 4; // overlaps with V# type, so shouldn't be 0 for buffer + + u64 depth : 13; + u64 pitch : 14; + u64 : 5; + u64 base_array : 13; + u64 last_array : 13; + u64 : 6; + u64 min_lod_warn : 12; + u64 counter_bank_id : 8; + u64 lod_hw_cnt_en : 1; + /// Neo-mode only + u64 compression_en : 1; + /// Neo-mode only + u64 alpha_is_on_msb : 1; + /// Neo-mode only + u64 color_transform : 1; + /// Neo-mode only + u64 alt_tile_mode : 1; + u64 : 39; + + static constexpr Image Null(bool is_depth) { + Image image{}; + image.data_format = u64(is_depth ? DataFormat::Format32 : DataFormat::Format8_8_8_8); + image.num_format = u64(is_depth ? NumberFormat::Float : NumberFormat::Unorm); + image.dst_sel_x = u64(CompSwizzle::Red); + image.dst_sel_y = u64(CompSwizzle::Green); + image.dst_sel_z = u64(CompSwizzle::Blue); + image.dst_sel_w = u64(CompSwizzle::Alpha); + image.tiling_index = u64(TileMode::Thin1DThin); + image.type = u64(ImageType::Color2D); + return image; + } + + bool Valid() const { + return (type & 0x8u) != 0; + } + + VAddr Address() const { + return base_address << 8; + } + + operator bool() const noexcept { + return base_address != 0; + } + + CompMapping DstSelect() const { + const CompMapping dst_sel{ + .r = CompSwizzle(dst_sel_x), + .g = CompSwizzle(dst_sel_y), + .b = CompSwizzle(dst_sel_z), + .a = CompSwizzle(dst_sel_w), + }; + return RemapSwizzle(DataFormat(data_format), dst_sel); + } + + u32 Pitch() const { + return pitch + 1; + } + + [[nodiscard]] u32 NumLayers() const noexcept { + // Depth is the number of layers for Array images. + u32 slices = depth + 1; + if (GetType() == ImageType::Color3D) { + // Depth is the actual texture depth for 3D images. + slices = 1; + } else if (IsCube()) { + // Depth is the number of full cubes for Cube images. + slices *= 6; + } + if (pow2pad) { + slices = std::bit_ceil(slices); + } + return slices; + } + + u32 NumLevels() const { + if (GetType() == ImageType::Color2DMsaa || GetType() == ImageType::Color2DMsaaArray) { + return 1; + } + return last_level + 1; + } + + u32 NumSamples() const { + if (GetType() == ImageType::Color2DMsaa || GetType() == ImageType::Color2DMsaaArray) { + return 1u << last_level; + } + return 1; + } + + bool IsCube() const noexcept { + return static_cast(type) == ImageType::Cube; + } + + ImageType GetType() const noexcept { + return IsCube() ? ImageType::Color2DArray : static_cast(type); + } + + DataFormat GetDataFmt() const noexcept { + return RemapDataFormat(DataFormat(data_format)); + } + + NumberFormat GetNumberFmt() const noexcept { + return RemapNumberFormat(NumberFormat(num_format), DataFormat(data_format)); + } + + NumberConversion GetNumberConversion() const noexcept { + return MapNumberConversion(NumberFormat(num_format), DataFormat(data_format)); + } + + TileMode GetTileMode() const { + return static_cast(tiling_index); + } + + bool IsTiled() const { + return GetTileMode() != TileMode::DisplayLinearAligned && + GetTileMode() != TileMode::DisplayLinearGeneral; + } + + u8 GetBankSwizzle() const { + const auto tile_mode = GetTileMode(); + const auto array_mode = GetArrayMode(tile_mode); + const auto dfmt = GetDataFmt(); + if (!alt_tile_mode || dfmt == DataFormat::FormatInvalid || !IsMacroTiled(array_mode)) { + return 0; + } + const u32 bpp = NumBitsPerElement(dfmt); + const auto macro_tile_mode = CalculateMacrotileMode(tile_mode, bpp, NumSamples()); + const u32 banks = GetAltNumBanks(macro_tile_mode); + return (((banks - 1) << 4) & base_address) >> 4; + } + + ImageType GetBaseType() const noexcept { + const auto base_type = GetType(); + if (base_type == ImageType::Color1DArray) { + return ImageType::Color1D; + } + if (base_type == ImageType::Color2DArray) { + return ImageType::Color2D; + } + if (base_type == ImageType::Color2DMsaa || base_type == ImageType::Color2DMsaaArray) { + return ImageType::Color2D; + } + return base_type; + } + + ImageType GetViewType(const bool is_array) const noexcept { + const auto base_type = GetType(); + if (IsCube()) { + // Cube needs to remain array type regardless of instruction array specifier. + return base_type; + } + if (base_type == ImageType::Color1DArray && !is_array) { + return ImageType::Color1D; + } + if (base_type == ImageType::Color2DArray && !is_array) { + return ImageType::Color2D; + } + if (base_type == ImageType::Color2DMsaaArray && !is_array) { + return ImageType::Color2DMsaa; + } + return base_type; + } + + [[nodiscard]] u32 NumViewLevels(const bool is_array) const noexcept { + switch (GetViewType(is_array)) { + case ImageType::Color2DMsaa: + case ImageType::Color2DMsaaArray: + return 1; + default: + // Constrain to actual number of available levels. + const auto max_level = std::min(last_level + 1, NumLevels()); + return max_level > base_level ? max_level - base_level : 1; + } + } + + [[nodiscard]] u32 NumViewLayers(const bool is_array) const noexcept { + switch (GetViewType(is_array)) { + case ImageType::Color1D: + case ImageType::Color2D: + case ImageType::Color2DMsaa: + case ImageType::Color3D: + return 1; + default: + // Constrain to actual number of available layers. + const auto max_array = std::min(last_array + 1, NumLayers()); + return max_array > base_array ? max_array - base_array : 1; + } + } +}; +static_assert(sizeof(Image) == 32); // 256bits + +// 8.2.7. Image Sampler [RDNA 2 Instruction Set Architecture] +enum class ClampMode : u64 { + Wrap = 0, + Mirror = 1, + ClampLastTexel = 2, + MirrorOnceLastTexel = 3, + ClampHalfBorder = 4, + MirrorOnceHalfBorder = 5, + ClampBorder = 6, + MirrorOnceBorder = 7, +}; + +enum class AnisoRatio : u64 { + One, + Two, + Four, + Eight, + Sixteen, +}; + +enum class DepthCompare : u64 { + Never = 0, + Less = 1, + Equal = 2, + LessEqual = 3, + Greater = 4, + NotEqual = 5, + GreaterEqual = 6, + Always = 7, +}; + +enum class FilterMode : u64 { + Blend = 0, + Min = 1, + Max = 2, +}; + +enum class Filter : u64 { + Point = 0, + Bilinear = 1, + AnisoPoint = 2, + AnisoLinear = 3, +}; + +constexpr bool IsAnisoFilter(const Filter filter) { + return filter == Filter::AnisoPoint || filter == Filter::AnisoLinear; +} + +enum class MipFilter : u64 { + None = 0, + Point = 1, + Linear = 2, +}; + +enum class BorderColor : u64 { + TransparentBlack = 0, + OpaqueBlack = 1, + White = 2, + Custom = 3, +}; + +// Table 8.12 Sampler Resource Definition +struct Sampler { + union { + u64 raw0; + BitField<0, 3, ClampMode> clamp_x; + BitField<3, 3, ClampMode> clamp_y; + BitField<6, 3, ClampMode> clamp_z; + BitField<9, 3, AnisoRatio> max_aniso; + BitField<12, 3, DepthCompare> depth_compare_func; + BitField<15, 1, u64> force_unnormalized; + BitField<16, 3, u64> aniso_threshold; + BitField<19, 1, u64> mc_coord_trunc; + BitField<20, 1, u64> force_degamma; + BitField<21, 6, u64> aniso_bias; + BitField<27, 1, u64> trunc_coord; + BitField<28, 1, u64> disable_cube_wrap; + BitField<29, 2, FilterMode> filter_mode; + BitField<32, 12, u64> min_lod; + BitField<44, 12, u64> max_lod; + BitField<56, 4, u64> perf_mip; + BitField<60, 4, u64> perf_z; + }; + union { + u64 raw1; + BitField<0, 14, u64> lod_bias; + BitField<14, 6, u64> lod_bias_sec; + BitField<20, 2, Filter> xy_mag_filter; + BitField<22, 2, Filter> xy_min_filter; + BitField<24, 2, u64> z_filter; + BitField<26, 2, MipFilter> mip_filter; + BitField<28, 1, u64> mip_point_preclamp; + BitField<29, 1, u64> disable_lsb_ceil; + BitField<30, 2, u64> unused0; + BitField<32, 12, u64> border_color_ptr; + BitField<42, 18, u64> unused1; + BitField<62, 2, BorderColor> border_color_type; + }; + + operator bool() const noexcept { + return raw0 != 0 || raw1 != 0; + } + + bool Valid() const { + return true; + } + + bool operator==(const Sampler& other) const noexcept { + return std::memcmp(this, &other, sizeof(Sampler)) == 0; + } + + float LodBias() const noexcept { + return static_cast(static_cast((lod_bias.Value() ^ 0x2000u) - 0x2000u)) / + 256.0f; + } + + float MinLod() const noexcept { + return static_cast(min_lod.Value()) / 256.0f; + } + + float MaxLod() const noexcept { + return static_cast(max_lod.Value()) / 256.0f; + } + + float MaxAniso() const { + switch (max_aniso.Value()) { + case AnisoRatio::One: + return 1.0f; + case AnisoRatio::Two: + return 2.0f; + case AnisoRatio::Four: + return 4.0f; + case AnisoRatio::Eight: + return 8.0f; + case AnisoRatio::Sixteen: + return 16.0f; + default: + UNREACHABLE(); + } + } +}; + +} // namespace AmdGpu + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { + return ctx.begin(); + } + auto format(AmdGpu::ImageType type, format_context& ctx) const { + return fmt::format_to(ctx.out(), "{}", AmdGpu::NameOf(type)); + } +}; diff --git a/gpu/shadps4/video_core/amdgpu/tiling.cpp b/gpu/shadps4/video_core/amdgpu/tiling.cpp new file mode 100644 index 0000000..fa3476b --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/tiling.cpp @@ -0,0 +1,560 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "video_core/amdgpu/tiling.h" + +#include + +namespace AmdGpu { + +static constexpr u32 MICROTILE_SIZE = 8; +static constexpr u32 DRAM_ROW_SIZE = 1024; + +std::string_view NameOf(TileMode tile_mode) { + return magic_enum::enum_name(tile_mode); +} + +ArrayMode GetArrayMode(TileMode tile_mode) { + switch (tile_mode) { + case TileMode::Depth1DThin: + case TileMode::Display1DThin: + case TileMode::Thin1DThin: + return ArrayMode::Array1DTiledThin1; + case TileMode::Depth2DThin64: + case TileMode::Depth2DThin128: + case TileMode::Depth2DThin256: + case TileMode::Depth2DThin512: + case TileMode::Depth2DThin1K: + case TileMode::Display2DThin: + case TileMode::Thin2DThin: + return ArrayMode::Array2DTiledThin1; + case TileMode::DisplayThinPrt: + case TileMode::ThinThinPrt: + return ArrayMode::ArrayPrtTiledThin1; + case TileMode::Depth2DThinPrt256: + case TileMode::Depth2DThinPrt1K: + case TileMode::Display2DThinPrt: + case TileMode::Thin2DThinPrt: + return ArrayMode::ArrayPrt2DTiledThin1; + case TileMode::Thin3DThin: + case TileMode::Thin3DThinPrt: + return ArrayMode::Array3DTiledThin1; + case TileMode::Thick1DThick: + return ArrayMode::Array1DTiledThick; + case TileMode::Thick2DThick: + return ArrayMode::Array2DTiledThick; + case TileMode::Thick3DThick: + return ArrayMode::Array3DTiledThick; + case TileMode::ThickThickPrt: + return ArrayMode::ArrayPrtTiledThick; + case TileMode::Thick2DThickPrt: + return ArrayMode::ArrayPrt2DTiledThick; + case TileMode::Thick3DThickPrt: + return ArrayMode::ArrayPrt3DTiledThick; + case TileMode::Thick2DXThick: + return ArrayMode::Array2DTiledXThick; + case TileMode::Thick3DXThick: + return ArrayMode::Array3DTiledXThick; + case TileMode::DisplayLinearAligned: + return ArrayMode::ArrayLinearAligned; + case TileMode::DisplayLinearGeneral: + return ArrayMode::ArrayLinearGeneral; + default: + UNREACHABLE_MSG("Unknown tile mode = {}", u32(tile_mode)); + } +} + +MicroTileMode GetMicroTileMode(TileMode tile_mode) { + switch (tile_mode) { + case TileMode::Depth2DThin64: + case TileMode::Depth2DThin128: + case TileMode::Depth2DThin256: + case TileMode::Depth2DThin512: + case TileMode::Depth2DThin1K: + case TileMode::Depth1DThin: + case TileMode::Depth2DThinPrt256: + case TileMode::Depth2DThinPrt1K: + return MicroTileMode::Depth; + case TileMode::DisplayLinearAligned: + case TileMode::Display1DThin: + case TileMode::Display2DThin: + case TileMode::DisplayThinPrt: + case TileMode::Display2DThinPrt: + case TileMode::DisplayLinearGeneral: + return MicroTileMode::Display; + case TileMode::Thin1DThin: + case TileMode::Thin2DThin: + case TileMode::Thin3DThin: + case TileMode::ThinThinPrt: + case TileMode::Thin2DThinPrt: + case TileMode::Thin3DThinPrt: + return MicroTileMode::Thin; + case TileMode::Thick1DThick: + case TileMode::Thick2DThick: + case TileMode::Thick3DThick: + case TileMode::ThickThickPrt: + case TileMode::Thick2DThickPrt: + case TileMode::Thick3DThickPrt: + case TileMode::Thick2DXThick: + case TileMode::Thick3DXThick: + return MicroTileMode::Thick; + default: + UNREACHABLE_MSG("Unknown tile mode = {}", u32(tile_mode)); + } +} + +PipeConfig GetPipeConfig(TileMode tile_mode) { + switch (tile_mode) { + case TileMode::Depth2DThin64: + case TileMode::Depth2DThin128: + case TileMode::Depth2DThin256: + case TileMode::Depth2DThin512: + case TileMode::Depth2DThin1K: + case TileMode::Depth1DThin: + case TileMode::Depth2DThinPrt256: + case TileMode::Depth2DThinPrt1K: + case TileMode::DisplayLinearAligned: + case TileMode::Display1DThin: + case TileMode::Display2DThin: + case TileMode::Display2DThinPrt: + case TileMode::Thin1DThin: + case TileMode::Thin2DThin: + case TileMode::Thin2DThinPrt: + case TileMode::Thin3DThinPrt: + case TileMode::Thick1DThick: + case TileMode::Thick2DThick: + case TileMode::Thick2DThickPrt: + case TileMode::Thick2DXThick: + return PipeConfig::P8_32x32_16x16; + case TileMode::DisplayThinPrt: + case TileMode::Thin3DThin: + case TileMode::ThinThinPrt: + case TileMode::Thick3DThick: + case TileMode::ThickThickPrt: + case TileMode::Thick3DThickPrt: + case TileMode::Thick3DXThick: + return PipeConfig::P8_32x32_8x16; + case TileMode::DisplayLinearGeneral: + return PipeConfig::P2; + default: + UNREACHABLE_MSG("Unknown tile mode = {}", u32(tile_mode)); + } +} + +PipeConfig GetAltPipeConfig(TileMode tile_mode) { + switch (tile_mode) { + case TileMode::Depth2DThin64: + case TileMode::Depth2DThin128: + case TileMode::Depth2DThin256: + case TileMode::Depth2DThin512: + case TileMode::Depth2DThin1K: + case TileMode::Depth1DThin: + case TileMode::Depth2DThinPrt256: + case TileMode::Depth2DThinPrt1K: + case TileMode::DisplayLinearAligned: + case TileMode::Display1DThin: + case TileMode::Display2DThin: + case TileMode::DisplayThinPrt: + case TileMode::Display2DThinPrt: + case TileMode::Thin1DThin: + case TileMode::Thin2DThin: + case TileMode::Thin3DThin: + case TileMode::ThinThinPrt: + case TileMode::Thin2DThinPrt: + case TileMode::Thin3DThinPrt: + case TileMode::Thick1DThick: + case TileMode::Thick2DThick: + case TileMode::Thick3DThick: + case TileMode::ThickThickPrt: + case TileMode::Thick2DThickPrt: + case TileMode::Thick3DThickPrt: + case TileMode::Thick2DXThick: + case TileMode::Thick3DXThick: + return PipeConfig::P16_32x32_8x16; + case TileMode::DisplayLinearGeneral: + return PipeConfig::P2; + default: + UNREACHABLE_MSG("Unknown tile mode = {}", u32(tile_mode)); + } +} + +u32 GetSampleSplit(TileMode tile_mode) { + switch (tile_mode) { + case TileMode::Depth2DThin64: + case TileMode::Depth2DThin128: + case TileMode::Depth2DThin256: + case TileMode::Depth2DThin512: + case TileMode::Depth2DThin1K: + case TileMode::Depth1DThin: + case TileMode::Depth2DThinPrt256: + case TileMode::Depth2DThinPrt1K: + case TileMode::DisplayLinearAligned: + case TileMode::Display1DThin: + case TileMode::Thin1DThin: + case TileMode::Thick1DThick: + case TileMode::Thick2DThick: + case TileMode::Thick3DThick: + case TileMode::ThickThickPrt: + case TileMode::Thick2DThickPrt: + case TileMode::Thick3DThickPrt: + case TileMode::Thick2DXThick: + case TileMode::Thick3DXThick: + case TileMode::DisplayLinearGeneral: + return 1; + case TileMode::Display2DThin: + case TileMode::DisplayThinPrt: + case TileMode::Display2DThinPrt: + case TileMode::Thin2DThin: + case TileMode::Thin3DThin: + case TileMode::ThinThinPrt: + case TileMode::Thin2DThinPrt: + case TileMode::Thin3DThinPrt: + return 2; + default: + UNREACHABLE_MSG("Unknown tile mode = {}", u32(tile_mode)); + } +} + +u32 GetTileSplitHw(TileMode tile_mode) { + switch (tile_mode) { + case TileMode::Depth2DThin64: + case TileMode::Depth1DThin: + case TileMode::DisplayLinearAligned: + case TileMode::Display1DThin: + case TileMode::Display2DThin: + case TileMode::DisplayThinPrt: + case TileMode::Display2DThinPrt: + case TileMode::Thin1DThin: + case TileMode::Thin2DThin: + case TileMode::Thin3DThin: + case TileMode::ThinThinPrt: + case TileMode::Thin2DThinPrt: + case TileMode::Thin3DThinPrt: + case TileMode::Thick1DThick: + case TileMode::Thick2DThick: + case TileMode::Thick3DThick: + case TileMode::ThickThickPrt: + case TileMode::Thick2DThickPrt: + case TileMode::Thick3DThickPrt: + case TileMode::Thick2DXThick: + case TileMode::Thick3DXThick: + case TileMode::DisplayLinearGeneral: + return 64; + case TileMode::Depth2DThin128: + return 128; + case TileMode::Depth2DThin256: + case TileMode::Depth2DThinPrt256: + return 256; + case TileMode::Depth2DThin512: + return 512; + case TileMode::Depth2DThin1K: + case TileMode::Depth2DThinPrt1K: + return 1024; + default: + UNREACHABLE_MSG("Unknown tile mode = {}", u32(tile_mode)); + } +} + +u32 GetBankWidth(MacroTileMode mode) { + switch (mode) { + case MacroTileMode::Mode_1x4_16: + case MacroTileMode::Mode_1x2_16: + case MacroTileMode::Mode_1x1_16: + case MacroTileMode::Mode_1x1_16_Dup: + case MacroTileMode::Mode_1x1_8: + case MacroTileMode::Mode_1x1_4: + case MacroTileMode::Mode_1x1_2: + case MacroTileMode::Mode_1x1_2_Dup: + case MacroTileMode::Mode_1x8_16: + case MacroTileMode::Mode_1x4_16_Dup: + case MacroTileMode::Mode_1x2_16_Dup: + case MacroTileMode::Mode_1x1_16_Dup2: + case MacroTileMode::Mode_1x1_8_Dup: + case MacroTileMode::Mode_1x1_4_Dup: + case MacroTileMode::Mode_1x1_2_Dup2: + case MacroTileMode::Mode_1x1_2_Dup3: + return 1; + default: + UNREACHABLE_MSG("Unknown macro tile mode = {}", u32(mode)); + } +} + +u32 GetBankHeight(MacroTileMode mode) { + switch (mode) { + case MacroTileMode::Mode_1x1_16: + case MacroTileMode::Mode_1x1_16_Dup: + case MacroTileMode::Mode_1x1_8: + case MacroTileMode::Mode_1x1_4: + case MacroTileMode::Mode_1x1_2: + case MacroTileMode::Mode_1x1_2_Dup: + case MacroTileMode::Mode_1x1_16_Dup2: + case MacroTileMode::Mode_1x1_8_Dup: + case MacroTileMode::Mode_1x1_4_Dup: + case MacroTileMode::Mode_1x1_2_Dup2: + case MacroTileMode::Mode_1x1_2_Dup3: + return 1; + case MacroTileMode::Mode_1x2_16: + case MacroTileMode::Mode_1x2_16_Dup: + return 2; + case MacroTileMode::Mode_1x4_16: + case MacroTileMode::Mode_1x4_16_Dup: + return 4; + case MacroTileMode::Mode_1x8_16: + return 8; + default: + UNREACHABLE_MSG("Unknown macro tile mode = {}", u32(mode)); + } +} + +u32 GetNumBanks(MacroTileMode mode) { + switch (mode) { + case MacroTileMode::Mode_1x1_2: + case MacroTileMode::Mode_1x1_2_Dup: + case MacroTileMode::Mode_1x1_2_Dup2: + case MacroTileMode::Mode_1x1_2_Dup3: + return 2; + case MacroTileMode::Mode_1x1_4: + case MacroTileMode::Mode_1x1_4_Dup: + return 4; + case MacroTileMode::Mode_1x1_8: + case MacroTileMode::Mode_1x1_8_Dup: + return 8; + case MacroTileMode::Mode_1x4_16: + case MacroTileMode::Mode_1x2_16: + case MacroTileMode::Mode_1x1_16: + case MacroTileMode::Mode_1x1_16_Dup: + case MacroTileMode::Mode_1x8_16: + case MacroTileMode::Mode_1x4_16_Dup: + case MacroTileMode::Mode_1x2_16_Dup: + case MacroTileMode::Mode_1x1_16_Dup2: + return 16; + default: + UNREACHABLE_MSG("Unknown macro tile mode = {}", u32(mode)); + } +} + +u32 GetMacrotileAspect(MacroTileMode mode) { + switch (mode) { + case MacroTileMode::Mode_1x1_8: + case MacroTileMode::Mode_1x1_4: + case MacroTileMode::Mode_1x1_2: + case MacroTileMode::Mode_1x1_2_Dup: + case MacroTileMode::Mode_1x1_8_Dup: + case MacroTileMode::Mode_1x1_4_Dup: + case MacroTileMode::Mode_1x1_2_Dup2: + case MacroTileMode::Mode_1x1_2_Dup3: + return 1; + case MacroTileMode::Mode_1x2_16: + case MacroTileMode::Mode_1x1_16: + case MacroTileMode::Mode_1x1_16_Dup: + case MacroTileMode::Mode_1x2_16_Dup: + case MacroTileMode::Mode_1x1_16_Dup2: + return 2; + case MacroTileMode::Mode_1x4_16: + case MacroTileMode::Mode_1x8_16: + case MacroTileMode::Mode_1x4_16_Dup: + return 4; + default: + UNREACHABLE_MSG("Unknown macro tile mode = {}", u32(mode)); + } +} + +u32 GetAltBankHeight(MacroTileMode mode) { + switch (mode) { + case MacroTileMode::Mode_1x1_8: + case MacroTileMode::Mode_1x1_4: + case MacroTileMode::Mode_1x1_2: + case MacroTileMode::Mode_1x1_2_Dup: + case MacroTileMode::Mode_1x1_16_Dup2: + case MacroTileMode::Mode_1x1_8_Dup: + case MacroTileMode::Mode_1x1_4_Dup: + case MacroTileMode::Mode_1x1_2_Dup2: + case MacroTileMode::Mode_1x1_2_Dup3: + return 1; + case MacroTileMode::Mode_1x1_16: + case MacroTileMode::Mode_1x1_16_Dup: + case MacroTileMode::Mode_1x2_16_Dup: + return 2; + case MacroTileMode::Mode_1x4_16: + case MacroTileMode::Mode_1x2_16: + case MacroTileMode::Mode_1x8_16: + case MacroTileMode::Mode_1x4_16_Dup: + return 4; + default: + UNREACHABLE_MSG("Unknown macro tile mode = {}", u32(mode)); + } +} + +u32 GetAltNumBanks(MacroTileMode mode) { + switch (mode) { + case MacroTileMode::Mode_1x1_2_Dup: + case MacroTileMode::Mode_1x1_2_Dup2: + case MacroTileMode::Mode_1x1_2_Dup3: + return 2; + case MacroTileMode::Mode_1x1_2: + case MacroTileMode::Mode_1x1_8_Dup: + case MacroTileMode::Mode_1x1_4_Dup: + return 4; + case MacroTileMode::Mode_1x4_16: + case MacroTileMode::Mode_1x2_16: + case MacroTileMode::Mode_1x1_16: + case MacroTileMode::Mode_1x1_16_Dup: + case MacroTileMode::Mode_1x1_8: + case MacroTileMode::Mode_1x1_4: + case MacroTileMode::Mode_1x4_16_Dup: + case MacroTileMode::Mode_1x2_16_Dup: + case MacroTileMode::Mode_1x1_16_Dup2: + return 8; + case MacroTileMode::Mode_1x8_16: + return 16; + default: + UNREACHABLE_MSG("Unknown macro tile mode = {}", u32(mode)); + } +} + +u32 GetAltMacrotileAspect(MacroTileMode mode) { + switch (mode) { + case MacroTileMode::Mode_1x1_16: + case MacroTileMode::Mode_1x1_16_Dup: + case MacroTileMode::Mode_1x1_8: + case MacroTileMode::Mode_1x1_4: + case MacroTileMode::Mode_1x1_2: + case MacroTileMode::Mode_1x1_2_Dup: + case MacroTileMode::Mode_1x2_16_Dup: + case MacroTileMode::Mode_1x1_16_Dup2: + case MacroTileMode::Mode_1x1_8_Dup: + case MacroTileMode::Mode_1x1_4_Dup: + case MacroTileMode::Mode_1x1_2_Dup2: + case MacroTileMode::Mode_1x1_2_Dup3: + return 1; + case MacroTileMode::Mode_1x4_16: + case MacroTileMode::Mode_1x2_16: + case MacroTileMode::Mode_1x8_16: + case MacroTileMode::Mode_1x4_16_Dup: + return 2; + default: + UNREACHABLE_MSG("Unknown macro tile mode = {}", u32(mode)); + } +} + +bool IsMacroTiled(ArrayMode array_mode) { + switch (array_mode) { + case ArrayMode::ArrayLinearGeneral: + case ArrayMode::ArrayLinearAligned: + case ArrayMode::Array1DTiledThin1: + case ArrayMode::Array1DTiledThick: + return false; + case ArrayMode::Array2DTiledThin1: + case ArrayMode::ArrayPrtTiledThin1: + case ArrayMode::ArrayPrt2DTiledThin1: + case ArrayMode::Array2DTiledThick: + case ArrayMode::Array2DTiledXThick: + case ArrayMode::ArrayPrtTiledThick: + case ArrayMode::ArrayPrt2DTiledThick: + case ArrayMode::ArrayPrt3DTiledThin1: + case ArrayMode::Array3DTiledThin1: + case ArrayMode::Array3DTiledThick: + case ArrayMode::Array3DTiledXThick: + case ArrayMode::ArrayPrt3DTiledThick: + return true; + default: + UNREACHABLE_MSG("Unknown array mode = {}", u32(array_mode)); + } +} + +bool IsPrt(ArrayMode array_mode) { + switch (array_mode) { + case ArrayMode::ArrayPrtTiledThin1: + case ArrayMode::ArrayPrtTiledThick: + case ArrayMode::ArrayPrt2DTiledThin1: + case ArrayMode::ArrayPrt2DTiledThick: + case ArrayMode::ArrayPrt3DTiledThin1: + case ArrayMode::ArrayPrt3DTiledThick: + return true; + case ArrayMode::ArrayLinearGeneral: + case ArrayMode::ArrayLinearAligned: + case ArrayMode::Array1DTiledThin1: + case ArrayMode::Array1DTiledThick: + case ArrayMode::Array2DTiledThin1: + case ArrayMode::Array2DTiledThick: + case ArrayMode::Array2DTiledXThick: + case ArrayMode::Array3DTiledThin1: + case ArrayMode::Array3DTiledThick: + case ArrayMode::Array3DTiledXThick: + return false; + default: + UNREACHABLE_MSG("Unknown array mode = {}", u32(array_mode)); + } +} + +u32 GetMicroTileThickness(ArrayMode array_mode) { + switch (array_mode) { + case ArrayMode::ArrayLinearGeneral: + case ArrayMode::ArrayLinearAligned: + case ArrayMode::Array1DTiledThin1: + case ArrayMode::Array2DTiledThin1: + case ArrayMode::ArrayPrtTiledThin1: + case ArrayMode::ArrayPrt2DTiledThin1: + case ArrayMode::ArrayPrt3DTiledThin1: + case ArrayMode::Array3DTiledThin1: + return 1; + case ArrayMode::Array1DTiledThick: + case ArrayMode::Array2DTiledThick: + case ArrayMode::Array3DTiledThick: + case ArrayMode::ArrayPrtTiledThick: + case ArrayMode::ArrayPrt2DTiledThick: + case ArrayMode::ArrayPrt3DTiledThick: + return 4; + case ArrayMode::Array2DTiledXThick: + case ArrayMode::Array3DTiledXThick: + return 8; + default: + UNREACHABLE_MSG("Unknown array mode = {}", u32(array_mode)); + } +} + +u32 GetPipeCount(PipeConfig pipe_cfg) { + switch (pipe_cfg) { + case PipeConfig::P2: + return 2; + case PipeConfig::P8_32x32_8x16: + case PipeConfig::P8_32x32_16x16: + return 8; + case PipeConfig::P16_32x32_8x16: + return 16; + default: + UNREACHABLE_MSG("Unknown pipe config = {}", u32(pipe_cfg)); + } +} + +u32 CalculateTileSplit(TileMode tile_mode, ArrayMode array_mode, MicroTileMode micro_tile_mode, + u32 bpp) { + const u32 sample_split = GetSampleSplit(tile_mode); + const u32 tile_split_hw = GetTileSplitHw(tile_mode); + const u32 tile_thickness = GetMicroTileThickness(array_mode); + const u32 tile_bytes_1x = (bpp * MICROTILE_SIZE * MICROTILE_SIZE * tile_thickness + 7) / 8; + const u32 color_tile_split = std::max(256U, sample_split * tile_bytes_1x); + const u32 tile_split = + micro_tile_mode == MicroTileMode::Depth ? tile_split_hw : color_tile_split; + return std::min(DRAM_ROW_SIZE, tile_split); +} + +MacroTileMode CalculateMacrotileMode(TileMode tile_mode, u32 bpp, u32 num_samples) { + ASSERT_MSG(std::has_single_bit(num_samples) && num_samples <= 16, "Invalid sample count {}", + num_samples); + ASSERT_MSG(bpp >= 1 && bpp <= 128, "Invalid bpp {}", bpp); + + const ArrayMode array_mode = GetArrayMode(tile_mode); + ASSERT_MSG(IsMacroTiled(array_mode), "Tile mode not macro tiled"); + + const MicroTileMode micro_tile_mode = GetMicroTileMode(tile_mode); + const u32 tile_thickness = GetMicroTileThickness(array_mode); + const u32 tile_bytes_1x = bpp * MICROTILE_SIZE * MICROTILE_SIZE * tile_thickness / 8; + const u32 tilesplic = CalculateTileSplit(tile_mode, array_mode, micro_tile_mode, bpp); + const u32 tile_bytes = std::min(tilesplic, num_samples * tile_bytes_1x); + const u32 mtm_idx = std::bit_width(tile_bytes / 64) - 1; + return IsPrt(array_mode) ? MacroTileMode(mtm_idx + 8) : MacroTileMode(mtm_idx); +} + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/amdgpu/tiling.h b/gpu/shadps4/video_core/amdgpu/tiling.h new file mode 100644 index 0000000..35d01d1 --- /dev/null +++ b/gpu/shadps4/video_core/amdgpu/tiling.h @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/types.h" + +namespace AmdGpu { + +struct Image; + +static constexpr size_t NUM_TILE_MODES = 32; + +enum class PipeConfig : u32 { + P2 = 0, + P4_8x16 = 4, + P4_16x16 = 5, + P4_16x32 = 6, + P4_32x32 = 7, + P8_16x16_8x16 = 8, + P8_16x32_8x16 = 9, + P8_32x32_8x16 = 10, + P8_16x32_16x16 = 11, + P8_32x32_16x16 = 12, + P8_32x32_16x32 = 13, + P8_32x64_32x32 = 14, + P16_32x32_8x16 = 16, + P16_32x32_16x16 = 17, + P16 = 18, +}; + +enum class MicroTileMode : u32 { + Display = 0, + Thin = 1, + Depth = 2, + Rotated = 3, + Thick = 4, +}; + +enum class MacroTileMode : u32 { + Mode_1x4_16 = 0, + Mode_1x2_16 = 1, + Mode_1x1_16 = 2, + Mode_1x1_16_Dup = 3, + Mode_1x1_8 = 4, + Mode_1x1_4 = 5, + Mode_1x1_2 = 6, + Mode_1x1_2_Dup = 7, + Mode_1x8_16 = 8, + Mode_1x4_16_Dup = 9, + Mode_1x2_16_Dup = 10, + Mode_1x1_16_Dup2 = 11, + Mode_1x1_8_Dup = 12, + Mode_1x1_4_Dup = 13, + Mode_1x1_2_Dup2 = 14, + Mode_1x1_2_Dup3 = 15, +}; + +enum class ArrayMode : u32 { + ArrayLinearGeneral = 0, + ArrayLinearAligned = 1, + Array1DTiledThin1 = 2, + Array1DTiledThick = 3, + Array2DTiledThin1 = 4, + ArrayPrtTiledThin1 = 5, + ArrayPrt2DTiledThin1 = 6, + Array2DTiledThick = 7, + Array2DTiledXThick = 8, + ArrayPrtTiledThick = 9, + ArrayPrt2DTiledThick = 10, + ArrayPrt3DTiledThin1 = 11, + Array3DTiledThin1 = 12, + Array3DTiledThick = 13, + Array3DTiledXThick = 14, + ArrayPrt3DTiledThick = 15, +}; + +enum class TileMode : u32 { + Depth2DThin64 = 0, + Depth2DThin128 = 1, + Depth2DThin256 = 2, + Depth2DThin512 = 3, + Depth2DThin1K = 4, + Depth1DThin = 5, + Depth2DThinPrt256 = 6, + Depth2DThinPrt1K = 7, + DisplayLinearAligned = 8, + Display1DThin = 9, + Display2DThin = 10, + DisplayThinPrt = 11, + Display2DThinPrt = 12, + Thin1DThin = 13, + Thin2DThin = 14, + Thin3DThin = 15, + ThinThinPrt = 16, + Thin2DThinPrt = 17, + Thin3DThinPrt = 18, + Thick1DThick = 19, + Thick2DThick = 20, + Thick3DThick = 21, + ThickThickPrt = 22, + Thick2DThickPrt = 23, + Thick3DThickPrt = 24, + Thick2DXThick = 25, + Thick3DXThick = 26, + DisplayLinearGeneral = 31, +}; + +std::string_view NameOf(TileMode tile_mode); + +ArrayMode GetArrayMode(TileMode tile_mode); + +MicroTileMode GetMicroTileMode(TileMode tile_mode); + +PipeConfig GetPipeConfig(TileMode tile_mode); + +PipeConfig GetAltPipeConfig(TileMode tile_mode); + +u32 GetSampleSplit(TileMode tile_mode); + +u32 GetTileSplitHw(TileMode tile_mode); + +u32 GetBankWidth(MacroTileMode mode); + +u32 GetBankHeight(MacroTileMode mode); + +u32 GetNumBanks(MacroTileMode mode); + +u32 GetMacrotileAspect(MacroTileMode mode); + +u32 GetAltBankHeight(MacroTileMode mode); + +u32 GetAltNumBanks(MacroTileMode mode); + +u32 GetAltMacrotileAspect(MacroTileMode mode); + +bool IsMacroTiled(ArrayMode array_mode); + +bool IsPrt(ArrayMode array_mode); + +u32 GetMicroTileThickness(ArrayMode array_mode); + +u32 GetPipeCount(PipeConfig pipe_cfg); + +u32 CalculateTileSplit(TileMode tile_mode, ArrayMode array_mode, MicroTileMode micro_tile_mode, + u32 bpp); + +MacroTileMode CalculateMacrotileMode(TileMode tile_mode, u32 bpp, u32 num_samples); + +} // namespace AmdGpu diff --git a/gpu/shadps4/video_core/buffer_cache/buffer.cpp b/gpu/shadps4/video_core/buffer_cache/buffer.cpp new file mode 100644 index 0000000..9924556 --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/buffer.cpp @@ -0,0 +1,283 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/alignment.h" +#include "common/assert.h" +#include "video_core/buffer_cache/buffer.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_platform.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" + +#include + +namespace VideoCore { + +std::string_view BufferTypeName(MemoryType type) { + switch (type) { + case MemoryType::HostUncached: + return "HostUncached"; + case MemoryType::HostCached: + return "HostCached"; + case MemoryType::Stream: + return "Stream"; + case MemoryType::DeviceLocal: + return "DeviceLocal"; + case MemoryType::Sparse: + return "Sparse"; + default: + return "Invalid"; + } +} + +[[nodiscard]] VkMemoryPropertyFlags MemoryUsagePreferredVmaFlags(MemoryType type) { + return type != MemoryType::DeviceLocal ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + : VkMemoryPropertyFlagBits{}; +} + +[[nodiscard]] VmaAllocationCreateFlags MemoryUsageVmaFlags(MemoryType type) { + switch (type) { + case MemoryType::HostUncached: + case MemoryType::Stream: + return VMA_ALLOCATION_CREATE_MAPPED_BIT | + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; + case MemoryType::HostCached: + return VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; + case MemoryType::DeviceLocal: + default: + return {}; + } +} + +[[nodiscard]] VmaMemoryUsage MemoryUsageVma(MemoryType type) { + switch (type) { + case MemoryType::DeviceLocal: + case MemoryType::Stream: + return VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + case MemoryType::HostUncached: + case MemoryType::HostCached: + return VMA_MEMORY_USAGE_AUTO_PREFER_HOST; + default: + return VMA_MEMORY_USAGE_UNKNOWN; + } +} + +UniqueBuffer::UniqueBuffer(vk::Device device_, VmaAllocator allocator_) + : device{device_}, allocator{allocator_} {} + +UniqueBuffer::~UniqueBuffer() { + Destroy(); +} + +void UniqueBuffer::Destroy() { + if (allocation) { + vmaDestroyBuffer(allocator, buffer, allocation); + } else if (buffer) { + device.destroyBuffer(buffer); + } + buffer = VK_NULL_HANDLE; + allocation = VK_NULL_HANDLE; + bda_addr = 0; +} + +void UniqueBuffer::Create(vk::BufferCreateInfo& buffer_ci, MemoryType mem_type, + VmaAllocationInfo* out_alloc_info) { + const bool with_bda = bool(buffer_ci.usage & vk::BufferUsageFlagBits::eShaderDeviceAddress); + if (mem_type != MemoryType::Sparse) { + const VmaAllocationCreateFlags bda_flag = + with_bda ? VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT : 0; + const VmaAllocationCreateInfo alloc_ci = { + .flags = + VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT | bda_flag | MemoryUsageVmaFlags(mem_type), + .usage = MemoryUsageVma(mem_type), + .requiredFlags = 0, + .preferredFlags = MemoryUsagePreferredVmaFlags(mem_type), + .pool = VK_NULL_HANDLE, + .pUserData = nullptr, + }; + + const VkBufferCreateInfo buffer_ci_unsafe = static_cast(buffer_ci); + VkBuffer unsafe_buffer{}; + VkResult result = vmaCreateBuffer(allocator, &buffer_ci_unsafe, &alloc_ci, &unsafe_buffer, + &allocation, out_alloc_info); + ASSERT_MSG(result == VK_SUCCESS, "Failed allocating buffer with error {}", + vk::to_string(vk::Result{result})); + buffer = vk::Buffer{unsafe_buffer}; + } else { + buffer_ci.flags |= + vk::BufferCreateFlagBits::eSparseBinding | vk::BufferCreateFlagBits::eSparseResidency; + buffer = Vulkan::Check(device.createBuffer(buffer_ci)); + } + + if (with_bda) { + const vk::BufferDeviceAddressInfo bda_info = { + .buffer = buffer, + }; + auto bda_result = device.getBufferAddress(bda_info); + ASSERT_MSG(bda_result != 0, "Failed to get buffer device address"); + bda_addr = bda_result; + } +} + +Buffer::Buffer(const Vulkan::Instance& instance, VAddr cpu_addr_, u64 size_bytes_, + MemoryType mem_type_, std::string_view debug_name) + : cpu_addr{cpu_addr_}, size_bytes{size_bytes_}, mem_type{mem_type_}, + buffer{instance.GetDevice(), instance.GetAllocator()} { + + vk::BufferCreateInfo buffer_ci = { + .size = size_bytes, + .usage = AllFlags, + .sharingMode = vk::SharingMode::eExclusive, + }; + VmaAllocationInfo alloc_info{}; + buffer.Create(buffer_ci, mem_type, &alloc_info); + + const auto device = instance.GetDevice(); + if (!debug_name.empty()) { + Vulkan::SetObjectName(device, Handle(), debug_name); + } else { + Vulkan::SetObjectName(device, Handle(), "Buffer {:#x}:{:#x}", cpu_addr, size_bytes); + } + + if (mem_type != MemoryType::Sparse) { + VkMemoryPropertyFlags property_flags{}; + vmaGetAllocationMemoryProperties(instance.GetAllocator(), buffer.allocation, + &property_flags); + if (alloc_info.pMappedData) { + mapped_data = std::span{std::bit_cast(alloc_info.pMappedData), size_bytes}; + } + is_coherent = property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + } +} + +void Buffer::Flush(u64 offset, u64 size) { + if (mapped_data.empty() || is_coherent) { + return; + } + vmaFlushAllocation(buffer.allocator, buffer.allocation, offset, size); +} + +void Buffer::Invalidate(u64 offset, u64 size) { + if (mapped_data.empty() || is_coherent) { + return; + } + vmaInvalidateAllocation(buffer.allocator, buffer.allocation, offset, size); +} + +constexpr u64 WATCHES_INITIAL_RESERVE = 0x100; +constexpr u64 WATCHES_RESERVE_CHUNK = 0x100; + +StreamBuffer::StreamBuffer(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler_, + MemoryType mem_type, u64 size_bytes) + : Buffer{instance, 0, size_bytes, mem_type}, scheduler{scheduler_}, + non_coherent_atom_size{instance.NonCoherentAtomSize()} { + ReserveWatches(current_watches, WATCHES_INITIAL_RESERVE); + ReserveWatches(previous_watches, WATCHES_INITIAL_RESERVE); + Vulkan::SetObjectName(instance.GetDevice(), Handle(), "StreamBuffer({}):{:#x}", + BufferTypeName(mem_type), size_bytes); +} + +bool StreamBuffer::PrepareMap(u64 size, u64 alignment, bool allow_wait) { + if (!mapped_data.empty() && !is_coherent) { + size = Common::AlignUp(size, non_coherent_atom_size); + alignment = + alignment > 0 ? std::lcm(alignment, non_coherent_atom_size) : non_coherent_atom_size; + } + + if (size > this->size_bytes) { + return false; + } + + if (alignment > 0) { + offset = Common::AlignUp(offset, alignment); + } + + if (offset + size > this->size_bytes) { + // The buffer would overflow, save the amount of used watches and reset the state. + invalidation_mark = current_watch_cursor; + current_watch_cursor = 0; + offset = 0; + + // Swap watches and reset waiting cursors. + std::swap(previous_watches, current_watches); + wait_cursor = 0; + wait_bound = 0; + } + + if (!WaitPendingOperations(offset + size, allow_wait)) { + return false; + } + + mapped_size = size; + return true; +} + +std::pair StreamBuffer::Map(u64 size, u64 alignment, bool allow_wait) { + if (!PrepareMap(size, alignment, allow_wait)) { + return {nullptr, 0}; + } + u8* const data = mapped_data.empty() ? nullptr : mapped_data.data() + offset; + return {data, offset}; +} + +void StreamBuffer::Commit() { + if (mem_type == MemoryType::HostCached) { + Invalidate(offset, mapped_size); + } else { + Flush(offset, mapped_size); + } + AdvanceAndWatch(); +} + +std::optional StreamBuffer::Reserve(u64 size, u64 alignment, bool allow_wait) { + if (!PrepareMap(size, alignment, allow_wait)) { + return std::nullopt; + } + const u64 reserved_offset = offset; + AdvanceAndWatch(); + return reserved_offset; +} + +void StreamBuffer::AdvanceAndWatch() { + offset += mapped_size; + const u64 tick = scheduler.CurrentTick(); + last_tick = tick; + + // Extend the last watch if it belongs to the same tick. + if (current_watch_cursor != 0 && current_watches[current_watch_cursor - 1].tick == tick) { + current_watches[current_watch_cursor - 1].upper_bound = offset; + return; + } + + if (current_watch_cursor + 1 >= current_watches.size()) { + // Ensure that there are enough watches. + ReserveWatches(current_watches, WATCHES_RESERVE_CHUNK); + } + + auto& watch = current_watches[current_watch_cursor++]; + watch.upper_bound = offset; + watch.tick = tick; +} + +void StreamBuffer::ReserveWatches(std::vector& watches, std::size_t grow_size) { + watches.resize(watches.size() + grow_size); +} + +bool StreamBuffer::WaitPendingOperations(u64 requested_upper_bound, bool allow_wait) { + if (!invalidation_mark) { + return true; + } + while (requested_upper_bound > wait_bound && wait_cursor < *invalidation_mark) { + auto& watch = previous_watches[wait_cursor]; + if (!scheduler.IsFree(watch.tick) && !allow_wait) { + return false; + } + scheduler.Wait(watch.tick); + wait_bound = watch.upper_bound; + ++wait_cursor; + } + return true; +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/buffer.h b/gpu/shadps4/video_core/buffer_cache/buffer.h new file mode 100644 index 0000000..2b0a821 --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/buffer.h @@ -0,0 +1,192 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan { +class Instance; +class Scheduler; +} // namespace Vulkan + +VK_DEFINE_HANDLE(VmaAllocation) +VK_DEFINE_HANDLE(VmaAllocator) + +struct VmaAllocationInfo; + +namespace VideoCore { + +/// Hints and requirements for the backing memory type of a commit +enum class MemoryType : u8 { + DeviceLocal, ///< Requests device local buffer. + HostUncached, ///< Requires a host visible memory type optimized for CPU to GPU uploads + HostCached, ///< Requires a host visible memory type optimized for GPU to CPU readbacks + Stream, ///< Requests device local host visible buffer, falling back host memory. + Sparse, ///< Requires an unbacked sparse resident buffer. +}; + +constexpr vk::BufferUsageFlags ReadFlags = + vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eUniformBuffer | + vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eVertexBuffer | + vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eShaderDeviceAddress; + +constexpr vk::BufferUsageFlags AllFlags = + ReadFlags | vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eStorageBuffer; + +struct UniqueBuffer { + explicit UniqueBuffer(vk::Device device, VmaAllocator allocator); + ~UniqueBuffer(); + + UniqueBuffer(const UniqueBuffer&) = delete; + UniqueBuffer& operator=(const UniqueBuffer&) = delete; + + UniqueBuffer(UniqueBuffer&& other) noexcept + : device{other.device}, buffer{std::exchange(other.buffer, VK_NULL_HANDLE)}, + bda_addr{std::exchange(other.bda_addr, 0)}, + allocator{std::exchange(other.allocator, VK_NULL_HANDLE)}, + allocation{std::exchange(other.allocation, VK_NULL_HANDLE)} {} + + UniqueBuffer& operator=(UniqueBuffer&& other) noexcept { + if (this != &other) { + Destroy(); + device = other.device; + buffer = std::exchange(other.buffer, VK_NULL_HANDLE); + bda_addr = std::exchange(other.bda_addr, 0); + allocator = std::exchange(other.allocator, VK_NULL_HANDLE); + allocation = std::exchange(other.allocation, VK_NULL_HANDLE); + } + return *this; + } + + void Create(vk::BufferCreateInfo& buffer_ci, MemoryType mem_type, + VmaAllocationInfo* out_alloc_info); + + void Destroy(); + + vk::Device device; + vk::Buffer buffer{}; + vk::DeviceAddress bda_addr{}; + VmaAllocator allocator; + VmaAllocation allocation{}; +}; + +struct Buffer { + explicit Buffer(const Vulkan::Instance& instance, VAddr cpu_addr_, u64 size_bytes_, + MemoryType mem_type, std::string_view debug_name = ""); + + Buffer& operator=(const Buffer&) = delete; + Buffer(const Buffer&) = delete; + + Buffer& operator=(Buffer&&) = default; + Buffer(Buffer&&) = default; + + [[nodiscard]] bool IsInBounds(VAddr addr, u64 size) const noexcept { + return addr >= cpu_addr && addr + size <= cpu_addr + SizeBytes(); + } + + [[nodiscard]] VAddr CpuAddr() const noexcept { + return cpu_addr; + } + + [[nodiscard]] u64 Offset(VAddr other_cpu_addr) const noexcept { + return other_cpu_addr - cpu_addr; + } + + size_t SizeBytes() const { + return size_bytes; + } + + vk::Buffer Handle() const noexcept { + return buffer.buffer; + } + + vk::DeviceAddress BufferDeviceAddress() const noexcept { + ASSERT_MSG(buffer.bda_addr != 0, "Can't get BDA from a non BDA buffer"); + return buffer.bda_addr; + } + + /// Makes host writes in provided range visible to the device. + void Flush(u64 offset, u64 size); + + /// Makes device writes in provided range visible to the host. + void Invalidate(u64 offset, u64 size); + + VAddr cpu_addr = 0; + size_t size_bytes = 0; + std::span mapped_data{}; + bool is_coherent{}; + MemoryType mem_type{MemoryType::DeviceLocal}; + UniqueBuffer buffer; +}; + +struct StreamBuffer : public Buffer { + explicit StreamBuffer(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler, + MemoryType mem_type, u64 size_bytes); + + /// Reserves a region of memory from the stream buffer. Must be followed by Commit(). + std::pair Map(u64 size, u64 alignment = 0, bool allow_wait = true); + + /// Ensures that reserved bytes of memory are available to the GPU. + void Commit(); + + /// Reserves and commits a region in one step. + std::optional Reserve(u64 size, u64 alignment = 0, bool allow_wait = true); + + /// Tick of the most recent commit into this buffer, 0 if never used. + [[nodiscard]] u64 LastTick() const noexcept { + return last_tick; + } + + /// Maps and commits a memory region with user provided data + u64 Copy(auto src, size_t size, size_t alignment = 0) { + const auto [data, offset] = Map(size, alignment); + ASSERT_MSG(data, "Failed to copy {:#x} bytes", size); + std::memcpy(data, reinterpret_cast(src), size); + Commit(); + return offset; + } + +private: + struct Watch { + u64 tick{}; + u64 upper_bound{}; + }; + + /// Aligns, wraps if needed and waits for the GPU. On success mapped_size is set and the + /// region starts at offset. + bool PrepareMap(u64 size, u64 alignment, bool allow_wait); + + /// Advances offset past the mapped region and records the current tick for it. + void AdvanceAndWatch(); + + /// Increases the amount of watches available. + void ReserveWatches(std::vector& watches, std::size_t grow_size); + + /// Waits pending watches until requested upper bound. + bool WaitPendingOperations(u64 requested_upper_bound, bool allow_wait); + +private: + Vulkan::Scheduler& scheduler; + vk::DeviceSize non_coherent_atom_size{}; + u64 offset{}; + u64 mapped_size{}; + u64 last_tick{}; + std::vector current_watches; + std::size_t current_watch_cursor{}; + std::optional invalidation_mark; + std::vector previous_watches; + std::size_t wait_cursor{}; + u64 wait_bound{}; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/buffer_cache.cpp b/gpu/shadps4/video_core/buffer_cache/buffer_cache.cpp new file mode 100644 index 0000000..c8156b9 --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/buffer_cache.cpp @@ -0,0 +1,449 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "common/alignment.h" +#include "core/memory.h" +#include "video_core/amdgpu/liverpool.h" +#include "video_core/buffer_cache/buffer.h" +#include "video_core/buffer_cache/buffer_cache.h" +#include "video_core/buffer_cache/memory_tracker.h" +#include "video_core/renderer_vulkan/vk_graphics_pipeline.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/texture_cache/texture_cache.h" + +#include + +namespace VideoCore { + +static constexpr size_t GDS_BUFFER_SIZE = 64_KB; +static constexpr size_t STREAM_BUFFER_SIZE = 128_MB; + +static constexpr auto ARENA_USAGE = + vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst | + vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eStorageBuffer | + vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eVertexBuffer | + vk::BufferUsageFlagBits::eIndirectBuffer | vk::BufferUsageFlagBits::eShaderDeviceAddress; + +std::optional FindMemoryType(const vk::PhysicalDeviceMemoryProperties& properties, + vk::MemoryPropertyFlags wanted, u32 memory_type_bits) { + for (u32 i = 0; i < properties.memoryTypeCount; ++i) { + if (((memory_type_bits >> i) & 1) == 0) { + continue; + } + const auto flags = properties.memoryTypes[i].propertyFlags; + if ((flags & wanted) == wanted) { + return i; + } + } + return std::nullopt; +} + +BufferCache::BufferCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, + Vulkan::Runtime& runtime_, AmdGpu::Liverpool* liverpool_, + TextureCache& texture_cache_, PageManager& tracker) + : instance{instance_}, scheduler{scheduler_}, runtime{runtime_}, + staging_pool{runtime_.GetStagingPool()}, liverpool{liverpool_}, + memory{Core::Memory::Instance()}, texture_cache{texture_cache_}, + memory_tracker{std::make_unique(tracker)}, + stream_buffer{instance, scheduler, MemoryType::Stream, STREAM_BUFFER_SIZE}, + gds_buffer{instance, 0, GDS_BUFFER_SIZE, MemoryType::Stream, "GDS Buffer"}, + memory_semaphore{instance} { + const vk::BufferCreateInfo probe_ci = { + .flags = + vk::BufferCreateFlagBits::eSparseBinding | vk::BufferCreateFlagBits::eSparseResidency, + .size = ARENA_PAGE_SIZE, + .usage = ARENA_USAGE, + .sharingMode = vk::SharingMode::eExclusive, + }; + const vk::DeviceBufferMemoryRequirements req_info = { + .pCreateInfo = &probe_ci, + }; + const auto device = instance.GetDevice(); + const auto reqs = device.getBufferMemoryRequirements(req_info).memoryRequirements; + block_size = Common::AlignUp(std::max(reqs.alignment, MIN_BLOCK_SIZE), reqs.alignment); + ASSERT_MSG(std::popcount(block_size) == 1, "Sparse block size {} is not a power of 2", + block_size); + block_shift = std::bit_width(block_size) - 1; + blocks_per_arena_page = ARENA_PAGE_SIZE / block_size; + blocks_per_arena_page_shift = ARENA_PAGE_BITS - block_shift; + arena_memory_type_index = + FindMemoryType(instance.GetMemoryProperties(), vk::MemoryPropertyFlagBits::eDeviceLocal, + reqs.memoryTypeBits) + .value(); + + const u64 bda_pagetable_size = + (blocks_per_arena_page * NUM_ARENA_PAGES) * sizeof(vk::DeviceAddress); + fault_manager = std::make_unique(instance, scheduler, *this, block_shift, + blocks_per_arena_page * NUM_ARENA_PAGES); + bda_pagetable_buffer = std::make_unique( + instance, 0, bda_pagetable_size, MemoryType::DeviceLocal, "BDA Page Table Buffer"); + runtime.FillBuffer(bda_pagetable_buffer.get(), 0u, bda_pagetable_size, 0u); +} + +BufferCache::~BufferCache() = default; + +void BufferCache::InvalidateMemory(VAddr device_addr, u64 size, bool assume_locks) { + memory_tracker->InvalidateRegion(device_addr, size, [this, device_addr, size, assume_locks] { + ReadMemory(device_addr, size, true, assume_locks); + }); +} + +void BufferCache::ReadMemory(VAddr device_addr, u64 size, bool is_write, bool assume_locks) { + const auto flush_request = [this, device_addr, size, is_write] { + const u32 first_block = device_addr >> block_shift; + const u32 last_block = (device_addr + size - 1) >> block_shift; + const auto* arena = GetArena(first_block, last_block); + + // GPU-modified ranges come as many small scattered islands, + // so the download is widened to a window around the request + constexpr u64 WindowSize = 512_KB; + const VAddr arena_end = arena->cpu_addr + arena->size_bytes; + const VAddr window_start = + std::max(Common::AlignDown(device_addr, WindowSize), arena->cpu_addr); + const VAddr window_end = std::min( + std::max(window_start + WindowSize, device_addr + size), arena_end); + DownloadMemory(arena, window_start, window_end - window_start); + if (is_write) { + memory_tracker->MarkRegionAsCpuModified(device_addr, size); + } + }; + if (assume_locks) { + flush_request(); + } else { + liverpool->SendCommand(std::move(flush_request)); + } +} + +void BufferCache::DownloadMemory(const Buffer* arena, VAddr device_addr, u64 size) { + boost::container::small_vector copies; + u64 total_size_bytes = 0; + const VAddr arena_base = arena->cpu_addr; + memory_tracker->ForEachDownloadRange(device_addr, size, [&](u64 address, u64 size) { + const auto add_download = [&](VAddr start, VAddr end) { + const u64 new_offset = start - arena_base; + const u64 new_size = end - start; + copies.push_back(vk::BufferCopy{ + .srcOffset = new_offset, + .dstOffset = total_size_bytes, + .size = new_size, + }); + // Align up to avoid cache conflicts + constexpr u64 align = 64ULL; + constexpr u64 mask = ~(align - 1ULL); + total_size_bytes += (new_size + align - 1) & mask; + }; + gpu_modified_ranges.ForEachInRange(address, size, add_download); + gpu_modified_ranges.Subtract(address, size); + }); + if (total_size_bytes == 0) { + return; + } + const auto download = staging_pool.Request(total_size_bytes, VideoCore::MemoryType::HostCached); + for (auto& copy : copies) { + copy.dstOffset += download.offset; + } + runtime.CopyBuffer(arena, download.buffer, copies); + scheduler.Finish(); + + download.buffer->Invalidate(download.offset, download.size); + for (const auto& copy : copies) { + auto* dst_addr = std::bit_cast(arena_base + copy.srcOffset); + memory->TryWriteBacking(dst_addr, download.mapped + (copy.dstOffset - download.offset), + copy.size); + } + memory_tracker->UnmarkRegionAsGpuModified(device_addr, size); +} + +std::pair BufferCache::ObtainBuffer(VAddr device_addr, u32 size, + bool is_written, bool is_texel_buffer) { + // For read-only buffers use device local stream buffer to reduce renderpass breaks. + if (!is_written && size <= STREAM_THRESHOLD && !IsRegionGpuModified(device_addr, size)) { + const auto [data, offset] = stream_buffer.Map(size, instance.UniformMinAlignment()); + memory->CopySparseMemory(device_addr, data, size); + stream_buffer.Commit(); + return {&stream_buffer, offset}; + } + const u64 first_block = device_addr >> block_shift; + const u64 last_block = (device_addr + size - 1) >> block_shift; + const auto* arena = GetArena(first_block, last_block); + EnsureResident(arena, first_block, last_block); + SynchronizeMemory(arena, device_addr, size, is_written, is_texel_buffer); + if (is_written) { + gpu_modified_ranges.Add(device_addr, size); + } + return {arena, arena->Offset(device_addr)}; +} + +std::pair BufferCache::ObtainBufferForImage(VAddr device_addr, u32 size) { + if (IsRegionGpuModified(device_addr, size)) { + return ObtainBuffer(device_addr, size, false); + } + const auto staging = staging_pool.Request(size, VideoCore::MemoryType::HostUncached, + instance.StorageMinAlignment()); + memory->CopySparseMemory(device_addr, staging.mapped, staging.size); + staging.Flush(); + return {staging.buffer, staging.offset}; +} + +bool BufferCache::IsRegionCpuModified(VAddr addr, size_t size) { + return memory_tracker->IsRegionCpuModified(addr, size); +} + +bool BufferCache::IsRegionGpuModified(VAddr addr, size_t size) { + return memory_tracker->IsRegionGpuModified(addr, size); +} + +void BufferCache::ProcessFaultBuffer() { + fault_manager->ProcessFaultBuffer(); +} + +void BufferCache::SynchronizeDmaBuffers() { + for (const auto& range : resident_ranges) { + const u64 page = range.start >> (ARENA_PAGE_BITS - block_shift); + const VAddr device_addr = range.start << block_shift; + const u64 size = (range.end - range.start) << block_shift; + SynchronizeMemory(address_space[page], device_addr, size, false, false); + } +} + +const Buffer* BufferCache::GetArena(u64 first_block, u64 last_block) { + const u64 first_page = first_block >> blocks_per_arena_page_shift; + const u64 last_page = last_block >> blocks_per_arena_page_shift; + ASSERT_MSG(last_page - first_page <= 1, + "Buffer request cannot span more than two VA arena pages"); + + const auto* first_arena = address_space[first_page]; + const auto* last_arena = address_space[last_page]; + if (first_arena == last_arena) { + if (!first_arena) { + const u64 base_block = Common::AlignDownPow2(first_block, blocks_per_arena_page); + const u64 num_pages = last_page - first_page + 1; + const auto* new_arena = + &arenas.emplace_back(instance, base_block << block_shift, + num_pages << ARENA_PAGE_BITS, MemoryType::Sparse); + address_space[first_page] = new_arena; + address_space[last_page] = new_arena; + } + return address_space[first_page]; + } + + LOG_WARNING(Render, "Migrating arena"); + + const u64 first_addr = first_arena ? first_arena->cpu_addr : (first_page << ARENA_PAGE_BITS); + const u64 first_size = first_arena ? first_arena->size_bytes : ARENA_PAGE_SIZE; + const u64 last_size = last_arena ? last_arena->size_bytes : ARENA_PAGE_SIZE; + + const u64 base_block = first_addr >> block_shift; + const u64 total_size = first_size + last_size; + const u64 end_block = (first_addr + total_size) >> block_shift; + auto* new_arena = &arenas.emplace_back(instance, first_addr, total_size, MemoryType::Sparse); + auto* bind = BindsForArena(new_arena); + resident_ranges.ForEachInRange(base_block, end_block, [&](const Backing& backing) { + const u64 start = std::max(base_block, backing.start); + const u64 end = std::min(end_block, backing.end); + bind->binds.push_back(vk::SparseMemoryBind{ + .resourceOffset = (start - base_block) << block_shift, + .size = (end - start) << block_shift, + .memory = backing.memory, + .memoryOffset = backing.offset + ((start - backing.start) << block_shift), + }); + }); + + u64 base_page = first_addr >> ARENA_PAGE_BITS; + for (u32 page = 0; page < (first_size >> ARENA_PAGE_BITS); ++page) { + address_space[base_page + page] = new_arena; + } + base_page = last_page; + for (u32 page = 0; page < (last_size >> ARENA_PAGE_BITS); ++page) { + address_space[base_page + page] = new_arena; + } + return new_arena; +} + +void BufferCache::EnsureResident(const Buffer* arena, u64 first_block, u64 last_block) { + u32 resident_blocks{}; + IntervalList bind_ranges; + resident_ranges.ForEachGap(first_block, last_block + 1, [&](u64 start, u64 end) { + resident_blocks += end - start; + bind_ranges.Add({start, end}); + }); + + if (bind_ranges.Empty()) { + return; + } + + const vk::MemoryAllocateInfo alloc_info = { + .allocationSize = resident_blocks << block_shift, + .memoryTypeIndex = arena_memory_type_index, + }; + const auto device_memory = Vulkan::Check(instance.GetDevice().allocateMemory(alloc_info)); + + boost::container::small_vector copies; + const auto staging = + staging_pool.Request(resident_blocks * sizeof(vk::DeviceAddress), MemoryType::HostUncached); + + u64 memory_offset{}; + ArenaBinds* binds = BindsForArena(arena); + auto* bda_addrs = reinterpret_cast(staging.mapped); + u64 offset = staging.offset; + for (const auto& range : bind_ranges) { + Backing backing; + backing.start = range.start; + backing.end = range.end; + backing.memory = device_memory; + backing.offset = memory_offset; + resident_ranges.Add(backing); + + LOG_INFO(Render, "Making range start={}, end={} resident", backing.start, backing.end); + + const auto& bind = binds->binds.emplace_back(vk::SparseMemoryBind{ + .resourceOffset = (range.start << block_shift) - arena->cpu_addr, + .size = (range.end - range.start) << block_shift, + .memory = device_memory, + .memoryOffset = memory_offset, + }); + memory_offset += bind.size; + + for (u32 block = 0; block < bind.size; block += block_size) { + *(bda_addrs++) = arena->BufferDeviceAddress() + bind.resourceOffset + block; + } + const u64 copy_size = (backing.end - backing.start) * sizeof(vk::DeviceAddress); + copies.emplace_back(offset, backing.start * sizeof(vk::DeviceAddress), copy_size); + offset += copy_size; + } + + staging.Flush(); + runtime.CopyBuffer(staging.buffer, bda_pagetable_buffer.get(), copies); +} + +bool BufferCache::SynchronizeMemory(const Buffer* arena, VAddr device_addr, u32 size, + bool is_written, bool is_texel_buffer) { + boost::container::small_vector copies; + size_t total_size_bytes{}; + const Buffer* src_buffer{}; + memory_tracker->ForEachUploadRange( + device_addr, size, is_written, + [&](u64 addr, u64 size) { + copies.emplace_back(total_size_bytes, addr, size); + total_size_bytes += size; + }, + [&] { src_buffer = UploadCopies(arena, copies, total_size_bytes); }); + + if (src_buffer) { + runtime.CopyBuffer(src_buffer, arena, copies); + } + if (is_texel_buffer && !is_written) { + return SynchronizeMemoryFromImage(arena, device_addr, size); + } + return false; +} + +const Buffer* BufferCache::UploadCopies(const Buffer* arena, std::span copies, + size_t total_size_bytes) { + if (copies.empty()) { + return nullptr; + } + const auto staging = staging_pool.Request(total_size_bytes, MemoryType::HostUncached); + for (auto& copy : copies) { + memory->CopySparseMemory(copy.dstOffset, staging.mapped + copy.srcOffset, copy.size); + copy.srcOffset += staging.offset; + copy.dstOffset -= arena->cpu_addr; + } + staging.Flush(); + return staging.buffer; +} + +bool BufferCache::SynchronizeMemoryFromImage(const Buffer* arena, VAddr device_addr, u32 size) { + if (auto type = texture_cache.IsMeta(device_addr)) { + if (*type == TextureCache::MetaType::HTile) { + static constexpr u32 ZmaskUncompressed = 0xf; + runtime.FillBuffer(arena, arena->Offset(device_addr), size, ZmaskUncompressed); + return true; + } else { + LOG_WARNING(Render_Vulkan, "Unhandled metadata type {}", magic_enum::enum_name(*type)); + } + } + const ImageId image_id = texture_cache.FindImageFromRange(device_addr, size); + if (!image_id) { + return false; + } + Image& image = texture_cache.GetImage(image_id); + ASSERT_MSG(device_addr == image.info.guest_address, + "Texel buffer aliases image subresources {:x} : {:x}", device_addr, + image.info.guest_address); + const u64 arena_offset = arena->Offset(device_addr); + boost::container::small_vector buffer_copies; + for (u32 mip = 0; mip < image.info.resources.levels; mip++) { + const auto& mip_info = image.info.mips_layout[mip]; + const u32 width = std::max(image.info.size.width >> mip, 1u); + const u32 height = std::max(image.info.size.height >> mip, 1u); + const u32 depth = std::max(image.info.size.depth >> mip, 1u); + if (arena_offset + mip_info.offset + mip_info.size > arena->size_bytes) { + break; + } + buffer_copies.push_back(vk::BufferImageCopy{ + .bufferOffset = mip_info.offset, + .bufferRowLength = mip_info.pitch, + .bufferImageHeight = mip_info.height, + .imageSubresource{ + .aspectMask = image.aspect_mask & ~vk::ImageAspectFlagBits::eStencil, + .mipLevel = mip, + .baseArrayLayer = 0, + .layerCount = image.info.resources.layers, + }, + .imageOffset = {0, 0, 0}, + .imageExtent = {width, height, depth}, + }); + } + if (buffer_copies.empty()) { + return false; + } + auto& tile_manager = texture_cache.GetTileManager(); + tile_manager.TileImage(image, buffer_copies, arena, arena_offset); + return true; +} + +void BufferCache::SubmitPendingArenaBinds(Vulkan::SubmitInfo& info) { + if (pending_binds.empty()) { + return; + } + + std::vector buffer_binds; + buffer_binds.reserve(pending_binds.size()); + + for (const auto& binds : pending_binds) { + buffer_binds.emplace_back(vk::SparseBufferMemoryBindInfo{ + .buffer = binds.arena->Handle(), + .bindCount = static_cast(binds.binds.size()), + .pBinds = binds.binds.data(), + }); + } + + const u64 signal_tick = memory_semaphore.NextTick(); + const auto signal_sema = memory_semaphore.Handle(); + + const vk::TimelineSemaphoreSubmitInfo timeline_si = { + .signalSemaphoreValueCount = 1u, + .pSignalSemaphoreValues = &signal_tick, + }; + + const vk::BindSparseInfo sparse_info = { + .pNext = &timeline_si, + .bufferBindCount = static_cast(buffer_binds.size()), + .pBufferBinds = buffer_binds.data(), + .signalSemaphoreCount = 1u, + .pSignalSemaphores = &signal_sema, + }; + + info.AddWait(signal_sema, signal_tick); + auto submit_result = instance.GetGraphicsQueue().bindSparse(sparse_info); + ASSERT_MSG(submit_result != vk::Result::eErrorDeviceLost, "Device lost during submit"); + + pending_binds.clear(); +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/buffer_cache.h b/gpu/shadps4/video_core/buffer_cache/buffer_cache.h new file mode 100644 index 0000000..79ddbfb --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/buffer_cache.h @@ -0,0 +1,173 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/interval_set.h" +#include "common/types.h" +#include "video_core/buffer_cache/buffer.h" +#include "video_core/buffer_cache/fault_manager.h" +#include "video_core/buffer_cache/range_set.h" +#include "video_core/renderer_vulkan/vk_semaphore.h" + +namespace AmdGpu { +struct Liverpool; +} + +namespace Core { +class MemoryManager; +} + +namespace Vulkan { +class GraphicsPipeline; +struct SubmitInfo; +class Runtime; +class StagingBufferPool; +} // namespace Vulkan + +namespace VideoCore { + +class TextureCache; +class MemoryTracker; +class PageManager; + +class BufferCache { + static constexpr u64 ADDRESS_SPACE_BITS = 40; + static constexpr u64 ARENA_PAGE_BITS = 32; + static constexpr u64 ARENA_PAGE_SIZE = u64{1} << ARENA_PAGE_BITS; + static constexpr u64 NUM_ARENA_PAGES = u64{1} << (ADDRESS_SPACE_BITS - ARENA_PAGE_BITS); + static constexpr u64 MIN_BLOCK_SIZE = 16_KB; + static constexpr u64 STREAM_THRESHOLD = 16_KB; + +public: + explicit BufferCache(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler, + Vulkan::Runtime& runtime, AmdGpu::Liverpool* liverpool, + TextureCache& texture_cache, PageManager& tracker); + ~BufferCache(); + + /// Returns a pointer to GDS device local buffer. + [[nodiscard]] const Buffer* GetGdsBuffer() const noexcept { + return &gds_buffer; + } + + /// Retrieves the device local DBA page table buffer. + [[nodiscard]] Buffer* GetBdaPageTableBuffer() noexcept { + return bda_pagetable_buffer.get(); + } + + /// Retrieves the fault buffer. + [[nodiscard]] Buffer* GetFaultBuffer() noexcept { + return fault_manager->GetFaultBuffer(); + } + + /// Retrieves the stream buffer. + StreamBuffer& GetStreamBuffer() noexcept { + return stream_buffer; + } + + /// Returns minimum granularity of a sparse memory bind. + u32 GetSparsePageShift() const noexcept { + return block_shift; + } + + /// Invalidates any buffer in the logical page range. + void InvalidateMemory(VAddr device_addr, u64 size, bool assume_locks = false); + + /// Flushes any GPU modified buffer in the logical page range back to CPU memory. + void ReadMemory(VAddr device_addr, u64 size, bool is_write = false, bool assume_locks = false); + + /// Finds a buffer for the specified region. + [[nodiscard]] std::pair ObtainBuffer(VAddr device_addr, u32 size, + bool is_written, + bool is_texel_buffer = false); + + /// Attempts to obtain a buffer without modifying the cache contents. + [[nodiscard]] std::pair ObtainBufferForImage(VAddr device_addr, u32 size); + + /// Return true when a region is modified from the CPU + [[nodiscard]] bool IsRegionCpuModified(VAddr addr, size_t size); + + /// Return true when a region is modified from the GPU + [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); + + /// Processes the fault buffer. + void ProcessFaultBuffer(); + + /// Synchronizes all buffers needed for DMA. + void SynchronizeDmaBuffers(); + + /// Commits pending sparse buffer memory binds. Must be called before every scheduler submit. + void SubmitPendingArenaBinds(Vulkan::SubmitInfo& info); + +private: + struct ArenaBinds { + const Buffer* arena; + boost::container::small_vector binds; + }; + + ArenaBinds* BindsForArena(const Buffer* arena) { + auto it = std::ranges::find(pending_binds, arena, &ArenaBinds::arena); + if (it != pending_binds.end()) { + return std::addressof(*it); + } + return &pending_binds.emplace_back(arena); + } + + const Buffer* GetArena(u64 first_block, u64 last_block); + + void EnsureResident(const Buffer* arena, u64 first_block, u64 last_block); + + void DownloadMemory(const Buffer* arena, VAddr device_addr, u64 size); + + bool SynchronizeMemory(const Buffer* arena, VAddr device_addr, u32 size, bool is_written, + bool is_texel_buffer); + + const Buffer* UploadCopies(const Buffer* arena, std::span copies, + size_t total_size_bytes); + + bool SynchronizeMemoryFromImage(const Buffer* arena, VAddr device_addr, u32 size); + + const Vulkan::Instance& instance; + Vulkan::Scheduler& scheduler; + Vulkan::Runtime& runtime; + Vulkan::StagingBufferPool& staging_pool; + AmdGpu::Liverpool* liverpool; + Core::MemoryManager* memory; + TextureCache& texture_cache; + std::unique_ptr memory_tracker; + + StreamBuffer stream_buffer; + Buffer gds_buffer; + RangeSet gpu_modified_ranges; + + std::unique_ptr fault_manager; + std::unique_ptr bda_pagetable_buffer; + + std::array address_space{}; + std::deque arenas; + std::vector pending_binds; + Vulkan::Semaphore memory_semaphore; + + struct Backing : public Interval { + vk::DeviceMemory memory; + u64 offset; + constexpr bool CanMergeWith(const Backing& other) const noexcept { + return memory == other.memory && offset + (end - start) == other.offset; + } + constexpr Backing SubRange(u64 a, u64 b) const noexcept { + return {{a, b}, memory, offset + (a - start)}; + } + }; + IntervalList resident_ranges; + + u32 arena_memory_type_index{}; + u32 block_size{}; + u32 block_shift{}; + u32 blocks_per_arena_page{}; + u32 blocks_per_arena_page_shift{}; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/fault_manager.cpp b/gpu/shadps4/video_core/buffer_cache/fault_manager.cpp new file mode 100644 index 0000000..f82967c --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/fault_manager.cpp @@ -0,0 +1,184 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/div_ceil.h" +#include "video_core/buffer_cache/buffer_cache.h" +#include "video_core/buffer_cache/fault_manager.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_platform.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +#include "video_core/host_shaders/fault_buffer_process_comp.h" + +namespace VideoCore { + +static constexpr size_t MaxPageFaults = 1024; +static constexpr size_t PageFaultAreaSize = MaxPageFaults * sizeof(u64); + +FaultManager::FaultManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler_, + BufferCache& buffer_cache_, u32 sparse_pagebits, u64 sparse_num_pages_) + : scheduler{scheduler_}, buffer_cache{buffer_cache_}, sparse_pagesize{1ULL << sparse_pagebits}, + sparse_num_pages{sparse_num_pages_}, fault_buffer_size{sparse_num_pages_ / 8}, + fault_buffer{instance, 0, fault_buffer_size, MemoryType::DeviceLocal}, + download_buffer{instance, 0, MaxPendingFaults * PageFaultAreaSize, MemoryType::HostCached} { + const auto device = instance.GetDevice(); + Vulkan::SetObjectName(device, fault_buffer.Handle(), "Fault Buffer"); + + const std::array bindings = {{ + { + .binding = 0, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }, + { + .binding = 1, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }, + }}; + const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = { + .flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR, + .bindingCount = 2, + .pBindings = bindings.data(), + }; + fault_process_desc_layout = + Vulkan::Check(device.createDescriptorSetLayoutUnique(desc_layout_ci)); + + const std::array spec_data{sparse_pagebits, MaxPageFaults}; + const std::array spec_entries{{ + {0, 0, sizeof(u32)}, + {1, sizeof(u32), sizeof(u32)}, + }}; + const vk::SpecializationInfo specialization{ + .mapEntryCount = static_cast(spec_entries.size()), + .pMapEntries = spec_entries.data(), + .dataSize = sizeof(spec_data), + .pData = spec_data.data(), + }; + const auto module = Vulkan::CompileSPV(FAULT_BUFFER_PROCESS_COMP, device); + Vulkan::SetObjectName(device, module, "Fault Buffer Parser"); + + const vk::PipelineShaderStageCreateInfo shader_ci = { + .stage = vk::ShaderStageFlagBits::eCompute, + .module = module, + .pName = "main", + .pSpecializationInfo = &specialization, + }; + + const vk::PipelineLayoutCreateInfo layout_info = { + .setLayoutCount = 1U, + .pSetLayouts = &(*fault_process_desc_layout), + }; + fault_process_pipeline_layout = Vulkan::Check(device.createPipelineLayoutUnique(layout_info)); + + const vk::ComputePipelineCreateInfo pipeline_info = { + .stage = shader_ci, + .layout = *fault_process_pipeline_layout, + }; + fault_process_pipeline = Vulkan::Check(device.createComputePipelineUnique({}, pipeline_info)); + Vulkan::SetObjectName(device, *fault_process_pipeline, "Fault Buffer Parser Pipeline"); + + device.destroyShaderModule(module); +} + +void FaultManager::ProcessFaultBuffer() { + if (u64 wait_tick = fault_areas[current_area]) { + scheduler.Wait(wait_tick); + scheduler.PopPendingOperations(); + } + + const u32 offset = current_area * PageFaultAreaSize; + u8* mapped = download_buffer.mapped_data.data() + offset; + std::memset(mapped, 0, PageFaultAreaSize); + + const vk::BufferMemoryBarrier2 pre_barrier = { + .srcStageMask = vk::PipelineStageFlagBits2::eAllCommands, + .srcAccessMask = vk::AccessFlagBits2::eShaderWrite, + .dstStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .dstAccessMask = vk::AccessFlagBits2::eShaderRead, + .buffer = fault_buffer.Handle(), + .offset = 0, + .size = fault_buffer_size, + }; + const vk::BufferMemoryBarrier2 post_barrier = { + .srcStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .srcAccessMask = vk::AccessFlagBits2::eShaderWrite, + .dstStageMask = vk::PipelineStageFlagBits2::eAllCommands, + .dstAccessMask = vk::AccessFlagBits2::eShaderWrite, + .buffer = fault_buffer.Handle(), + .offset = 0, + .size = fault_buffer_size, + }; + const vk::DescriptorBufferInfo fault_buffer_info = { + .buffer = fault_buffer.Handle(), + .offset = 0, + .range = fault_buffer_size, + }; + const vk::DescriptorBufferInfo download_info = { + .buffer = download_buffer.Handle(), + .offset = offset, + .range = PageFaultAreaSize, + }; + const std::array writes = {{ + { + .dstSet = VK_NULL_HANDLE, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .pBufferInfo = &fault_buffer_info, + }, + { + .dstSet = VK_NULL_HANDLE, + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .pBufferInfo = &download_info, + }, + }}; + scheduler.EndRendering(); + const auto cmdbuf = scheduler.CommandBuffer(); + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .dependencyFlags = vk::DependencyFlagBits::eByRegion, + .bufferMemoryBarrierCount = 1, + .pBufferMemoryBarriers = &pre_barrier, + }); + cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, *fault_process_pipeline); + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, *fault_process_pipeline_layout, 0, + writes); + // 1 bit per page, 32 pages per workgroup + const u32 num_threads = sparse_num_pages / 32; + const u32 num_workgroups = Common::DivCeil(num_threads, 64u); + cmdbuf.dispatch(num_workgroups, 1, 1); + + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .dependencyFlags = vk::DependencyFlagBits::eByRegion, + .bufferMemoryBarrierCount = 1, + .pBufferMemoryBarriers = &post_barrier, + }); + + scheduler.DeferOperation([this, mapped, area = current_area] { + fault_ranges.Clear(); + const u64* fault_buf = std::bit_cast(mapped); + const u32 fault_count = fault_buf[0]; + for (u32 i = 1; i <= fault_count; ++i) { + fault_ranges.Add(fault_buf[i], sparse_pagesize); + LOG_INFO(Render_Vulkan, "Accessed non-GPU cached memory at {:#x}", fault_buf[i]); + } + fault_ranges.ForEach([&](VAddr start, VAddr end) { + ASSERT_MSG((end - start) <= std::numeric_limits::max(), + "Buffer size is too large"); + (void)buffer_cache.ObtainBuffer(start, end - start, false); + }); + fault_areas[area] = 0; + }); + + fault_areas[current_area++] = scheduler.CurrentTick(); + current_area %= MaxPendingFaults; +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/fault_manager.h b/gpu/shadps4/video_core/buffer_cache/fault_manager.h new file mode 100644 index 0000000..5376cc5 --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/fault_manager.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "video_core/buffer_cache/buffer.h" +#include "video_core/buffer_cache/range_set.h" + +namespace VideoCore { + +class BufferCache; + +class FaultManager { + static constexpr size_t MaxPendingFaults = 8; + +public: + explicit FaultManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler, + BufferCache& buffer_cache, u32 sparse_pagebits, u64 sparse_num_pages); + + [[nodiscard]] Buffer* GetFaultBuffer() noexcept { + return &fault_buffer; + } + + void ProcessFaultBuffer(); + +private: + Vulkan::Scheduler& scheduler; + BufferCache& buffer_cache; + RangeSet fault_ranges; + u64 sparse_pagesize; + u64 sparse_num_pages; + u64 fault_buffer_size; + Buffer fault_buffer; + Buffer download_buffer; + std::array fault_areas{}; + u32 current_area{}; + vk::UniqueDescriptorSetLayout fault_process_desc_layout; + vk::UniquePipeline fault_process_pipeline; + vk::UniquePipelineLayout fault_process_pipeline_layout; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/memory_tracker.h b/gpu/shadps4/video_core/buffer_cache/memory_tracker.h new file mode 100644 index 0000000..0f2a137 --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/memory_tracker.h @@ -0,0 +1,193 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include + +#include "common/debug.h" +#include "common/types.h" +#include "core/emulator_settings.h" +#include "video_core/buffer_cache/region_manager.h" + +namespace VideoCore { + +class MemoryTracker { +public: + static constexpr size_t MAX_CPU_PAGE_BITS = 40; + static constexpr size_t NUM_HIGH_PAGES = 1ULL << (MAX_CPU_PAGE_BITS - TRACKER_HIGHER_PAGE_BITS); + static constexpr size_t MANAGER_POOL_SIZE = 32; + +public: + explicit MemoryTracker(PageManager& tracker_) : tracker{&tracker_} {} + ~MemoryTracker() = default; + + /// Returns true if a region has been modified from the CPU + bool IsRegionCpuModified(VAddr query_cpu_addr, u64 query_size) noexcept { + return IteratePages( + query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) { + return manager->template IsRegionModified(offset, size); + }); + } + + /// Returns true if a region has been modified from the GPU + bool IsRegionGpuModified(VAddr query_cpu_addr, u64 query_size) noexcept { + return IteratePages( + query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) { + return manager->template IsRegionModified(offset, size); + }); + } + + /// Mark region as CPU modified, notifying the device_tracker about this change + void MarkRegionAsCpuModified(VAddr dirty_cpu_addr, u64 query_size) { + IteratePages(dirty_cpu_addr, query_size, + [](RegionManager* manager, u64 offset, size_t size) { + std::scoped_lock lk{manager->lock}; + manager->template ChangeRegionState( + manager->GetCpuAddr() + offset, size); + }); + } + + /// Unmark region as modified from the host GPU + void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept { + IteratePages(dirty_cpu_addr, query_size, + [](RegionManager* manager, u64 offset, size_t size) { + std::scoped_lock lk{manager->lock}; + manager->template ChangeRegionState( + manager->GetCpuAddr() + offset, size); + }); + } + + /// Removes all protection from a page and ensures GPU data has been flushed if requested + void InvalidateRegion(VAddr cpu_addr, u64 size, auto&& on_flush) noexcept { + IteratePages( + cpu_addr, size, [&on_flush](RegionManager* manager, u64 offset, size_t size) { + const bool should_flush = [&] { + // Perform both the GPU modification check and CPU state change with the lock + // in case we are racing with GPU thread trying to mark the page as GPU + // modified. If we need to flush the flush function is going to perform CPU + // state change. + std::scoped_lock lk{manager->lock}; + if (EmulatorSettings.GetReadbacksMode() != GpuReadbacksMode::Disabled && + manager->template IsRegionModified(offset, size)) { + return true; + } + manager->template ChangeRegionState( + manager->GetCpuAddr() + offset, size); + return false; + }(); + if (should_flush) { + on_flush(); + } + }); + } + + /// Call 'func' for each CPU modified range and unmark those pages as CPU modified + void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, bool is_written, auto&& func, + auto&& on_upload) { + IteratePages(query_cpu_range, query_size, + [&func, is_written](RegionManager* manager, u64 offset, size_t size) { + manager->lock.lock(); + manager->template ForEachModifiedRange( + manager->GetCpuAddr() + offset, size, func); + if (!is_written) { + manager->lock.unlock(); + } + }); + on_upload(); + if (!is_written) { + return; + } + IteratePages(query_cpu_range, query_size, + [&func, is_written](RegionManager* manager, u64 offset, size_t size) { + manager->template ChangeRegionState( + manager->GetCpuAddr() + offset, size); + manager->lock.unlock(); + }); + } + + /// Call 'func' for each GPU modified range and unmark those pages as GPU modified + template + void ForEachDownloadRange(VAddr query_cpu_range, u64 query_size, auto&& func) { + IteratePages(query_cpu_range, query_size, + [&func](RegionManager* manager, u64 offset, size_t size) { + std::scoped_lock lk{manager->lock}; + manager->template ForEachModifiedRange( + manager->GetCpuAddr() + offset, size, func); + }); + } + +private: + /** + * @brief IteratePages Iterates L2 word manager page table. + * @param cpu_address Start byte cpu address + * @param size Size in bytes of the region of iterate. + * @param func Callback for each word manager. + * @return + */ + template + bool IteratePages(VAddr cpu_address, size_t size, Func&& func) { + RENDERER_TRACE; + using FuncReturn = typename std::invoke_result::type; + static constexpr bool BOOL_BREAK = std::is_same_v; + std::size_t remaining_size{size}; + std::size_t page_index{cpu_address >> TRACKER_HIGHER_PAGE_BITS}; + u64 page_offset{cpu_address & TRACKER_HIGHER_PAGE_MASK}; + while (remaining_size > 0) { + const std::size_t copy_amount{ + std::min(TRACKER_HIGHER_PAGE_SIZE - page_offset, remaining_size)}; + auto* manager{top_tier[page_index]}; + if (manager) { + if constexpr (BOOL_BREAK) { + if (func(manager, page_offset, copy_amount)) { + return true; + } + } else { + func(manager, page_offset, copy_amount); + } + } else if constexpr (create_region_on_fail) { + CreateRegion(page_index); + manager = top_tier[page_index]; + if constexpr (BOOL_BREAK) { + if (func(manager, page_offset, copy_amount)) { + return true; + } + } else { + func(manager, page_offset, copy_amount); + } + } + page_index++; + page_offset = 0; + remaining_size -= copy_amount; + } + return false; + } + + void CreateRegion(std::size_t page_index) { + const VAddr base_cpu_addr = page_index << TRACKER_HIGHER_PAGE_BITS; + if (free_managers.empty()) { + manager_pool.emplace_back(); + auto& last_pool = manager_pool.back(); + for (size_t i = 0; i < MANAGER_POOL_SIZE; i++) { + std::construct_at(&last_pool[i], tracker, 0); + free_managers.push_back(&last_pool[i]); + } + } + // Each manager tracks a 4_MB virtual address space. + auto* new_manager = free_managers.back(); + new_manager->SetCpuAddress(base_cpu_addr); + free_managers.pop_back(); + top_tier[page_index] = new_manager; + } + + PageManager* tracker; + std::deque> manager_pool; + std::vector free_managers; + std::array top_tier{}; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/range_set.h b/gpu/shadps4/video_core/buffer_cache/range_set.h new file mode 100644 index 0000000..5c8e78c --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/range_set.h @@ -0,0 +1,325 @@ +// SPDX-FileCopyrightText: 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include "common/types.h" + +namespace VideoCore { + +template +using RangeSetsAllocator = + boost::fast_pool_allocator; + +struct RangeSet { + using IntervalSet = + boost::icl::interval_set; + using IntervalType = typename IntervalSet::interval_type; + + explicit RangeSet() = default; + ~RangeSet() = default; + + void Add(VAddr base_address, size_t size) { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + m_ranges_set.add(interval); + } + + void Subtract(VAddr base_address, size_t size) { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + m_ranges_set.subtract(interval); + } + + void Clear() { + m_ranges_set.clear(); + } + + bool Contains(VAddr base_address, size_t size) const { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + return boost::icl::contains(m_ranges_set, interval); + } + + bool Intersects(VAddr base_address, size_t size) const { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + return boost::icl::intersects(m_ranges_set, interval); + } + + template + void ForEach(Func&& func) const { + if (m_ranges_set.empty()) { + return; + } + + for (const auto& set : m_ranges_set) { + const VAddr inter_addr_end = set.upper(); + const VAddr inter_addr = set.lower(); + func(inter_addr, inter_addr_end); + } + } + + template + void ForEachInRange(VAddr base_addr, size_t size, Func&& func) const { + if (m_ranges_set.empty()) { + return; + } + const VAddr start_address = base_addr; + const VAddr end_address = start_address + size; + const IntervalType search_interval{start_address, end_address}; + auto it = m_ranges_set.lower_bound(search_interval); + if (it == m_ranges_set.end()) { + return; + } + auto end_it = m_ranges_set.upper_bound(search_interval); + for (; it != end_it; it++) { + VAddr inter_addr_end = it->upper(); + VAddr inter_addr = it->lower(); + if (inter_addr_end > end_address) { + inter_addr_end = end_address; + } + if (inter_addr < start_address) { + inter_addr = start_address; + } + func(inter_addr, inter_addr_end); + } + } + + template + void ForEachNotInRange(VAddr base_addr, size_t size, Func&& func) const { + const VAddr end_addr = base_addr + size; + ForEachInRange(base_addr, size, [&](VAddr range_addr, VAddr range_end) { + if (size_t gap_size = range_addr - base_addr; gap_size != 0) { + func(base_addr, gap_size); + } + base_addr = range_end; + }); + if (base_addr != end_addr) { + func(base_addr, end_addr - base_addr); + } + } + + IntervalSet m_ranges_set; +}; + +template +class RangeMap { +public: + using IntervalMap = + boost::icl::interval_map; + using IntervalType = typename IntervalMap::interval_type; + +public: + RangeMap() = default; + ~RangeMap() = default; + + RangeMap(RangeMap const&) = delete; + RangeMap& operator=(RangeMap const&) = delete; + + RangeMap(RangeMap&& other); + RangeMap& operator=(RangeMap&& other); + + void Add(VAddr base_address, size_t size, const T& value) { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + m_ranges_map.add({interval, value}); + } + + void Subtract(VAddr base_address, size_t size) { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + m_ranges_map -= interval; + } + + void Clear() { + m_ranges_map.clear(); + } + + bool Contains(VAddr base_address, size_t size) const { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + return boost::icl::contains(m_ranges_map, interval); + } + + bool Intersects(VAddr base_address, size_t size) const { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + return boost::icl::intersects(m_ranges_map, interval); + } + + template + void ForEach(Func&& func) const { + if (m_ranges_map.empty()) { + return; + } + + for (const auto& [interval, value] : m_ranges_map) { + const VAddr inter_addr_end = interval.upper(); + const VAddr inter_addr = interval.lower(); + func(inter_addr, inter_addr_end, value); + } + } + + template + void ForEachInRange(VAddr base_addr, size_t size, Func&& func) const { + if (m_ranges_map.empty()) { + return; + } + const VAddr start_address = base_addr; + const VAddr end_address = start_address + size; + const IntervalType search_interval{start_address, end_address}; + auto it = m_ranges_map.lower_bound(search_interval); + if (it == m_ranges_map.end()) { + return; + } + auto end_it = m_ranges_map.upper_bound(search_interval); + for (; it != end_it; it++) { + VAddr inter_addr_end = it->first.upper(); + VAddr inter_addr = it->first.lower(); + if (inter_addr_end > end_address) { + inter_addr_end = end_address; + } + if (inter_addr < start_address) { + inter_addr = start_address; + } + func(inter_addr, inter_addr_end, it->second); + } + } + + template + void ForEachNotInRange(VAddr base_addr, size_t size, Func&& func) const { + const VAddr end_addr = base_addr + size; + ForEachInRange(base_addr, size, [&](VAddr range_addr, VAddr range_end, const T&) { + if (size_t gap_size = range_addr - base_addr; gap_size != 0) { + func(base_addr, gap_size); + } + base_addr = range_end; + }); + if (base_addr != end_addr) { + func(base_addr, end_addr - base_addr); + } + } + +private: + IntervalMap m_ranges_map; +}; + +template +class SplitRangeMap { +public: + using IntervalMap = boost::icl::split_interval_map< + VAddr, T, boost::icl::total_absorber, std::less, boost::icl::inplace_identity, + boost::icl::inter_section, ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, VAddr, std::less), + RangeSetsAllocator>; + using IntervalType = typename IntervalMap::interval_type; + +public: + SplitRangeMap() = default; + ~SplitRangeMap() = default; + + SplitRangeMap(SplitRangeMap const&) = delete; + SplitRangeMap& operator=(SplitRangeMap const&) = delete; + + SplitRangeMap(SplitRangeMap&& other); + SplitRangeMap& operator=(SplitRangeMap&& other); + + void Add(VAddr base_address, size_t size, const T& value) { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + m_ranges_map.add({interval, value}); + } + + void Subtract(VAddr base_address, size_t size) { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + m_ranges_map -= interval; + } + + void Clear() { + m_ranges_map.clear(); + } + + bool Contains(VAddr base_address, size_t size) const { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + return boost::icl::contains(m_ranges_map, interval); + } + + bool Intersects(VAddr base_address, size_t size) const { + const VAddr end_address = base_address + size; + IntervalType interval{base_address, end_address}; + return boost::icl::intersects(m_ranges_map, interval); + } + + template + void ForEach(Func&& func) const { + if (m_ranges_map.empty()) { + return; + } + + for (const auto& [interval, value] : m_ranges_map) { + const VAddr inter_addr_end = interval.upper(); + const VAddr inter_addr = interval.lower(); + func(inter_addr, inter_addr_end, value); + } + } + + template + void ForEachInRange(VAddr base_addr, size_t size, Func&& func) const { + if (m_ranges_map.empty()) { + return; + } + const VAddr start_address = base_addr; + const VAddr end_address = start_address + size; + const IntervalType search_interval{start_address, end_address}; + auto it = m_ranges_map.lower_bound(search_interval); + if (it == m_ranges_map.end()) { + return; + } + auto end_it = m_ranges_map.upper_bound(search_interval); + for (; it != end_it; it++) { + VAddr inter_addr_end = it->first.upper(); + VAddr inter_addr = it->first.lower(); + if (inter_addr_end > end_address) { + inter_addr_end = end_address; + } + if (inter_addr < start_address) { + inter_addr = start_address; + } + func(inter_addr, inter_addr_end, it->second); + } + } + + template + void ForEachNotInRange(VAddr base_addr, size_t size, Func&& func) const { + const VAddr end_addr = base_addr + size; + ForEachInRange(base_addr, size, [&](VAddr range_addr, VAddr range_end, const T&) { + if (size_t gap_size = range_addr - base_addr; gap_size != 0) { + func(base_addr, gap_size); + } + base_addr = range_end; + }); + if (base_addr != end_addr) { + func(base_addr, end_addr - base_addr); + } + } + +private: + IntervalMap m_ranges_map; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/region_definitions.h b/gpu/shadps4/video_core/buffer_cache/region_definitions.h new file mode 100644 index 0000000..260047d --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/region_definitions.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/bit_array.h" +#include "common/types.h" + +namespace VideoCore { + +constexpr u64 TRACKER_PAGE_BITS = 12; // 4K pages +constexpr u64 TRACKER_BYTES_PER_PAGE = 1ULL << TRACKER_PAGE_BITS; + +constexpr u64 TRACKER_HIGHER_PAGE_BITS = 22; // each region is 4MB +constexpr u64 TRACKER_HIGHER_PAGE_SIZE = 1ULL << TRACKER_HIGHER_PAGE_BITS; +constexpr u64 TRACKER_HIGHER_PAGE_MASK = TRACKER_HIGHER_PAGE_SIZE - 1ULL; +constexpr u64 NUM_PAGES_PER_REGION = TRACKER_HIGHER_PAGE_SIZE / TRACKER_BYTES_PER_PAGE; + +enum class Type { + CPU, + GPU, +}; + +using RegionBits = Common::BitArray; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/buffer_cache/region_manager.h b/gpu/shadps4/video_core/buffer_cache/region_manager.h new file mode 100644 index 0000000..ae6fbd0 --- /dev/null +++ b/gpu/shadps4/video_core/buffer_cache/region_manager.h @@ -0,0 +1,202 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "bbport_toggles.h" +#include "common/div_ceil.h" +#include "common/logging/log.h" +#include "core/emulator_settings.h" + +#ifdef __unix__ +#include "common/adaptive_mutex.h" +#else +#include "common/spin_lock.h" +#endif +#include "common/debug.h" +#include "common/types.h" +#include "video_core/buffer_cache/region_definitions.h" +#include "video_core/page_manager.h" + +namespace VideoCore { + +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +using LockType = Common::AdaptiveMutex; +#else +using LockType = Common::SpinLock; +#endif + +/** + * Allows tracking CPU and GPU modification of pages in a contigious 16MB virtual address region. + * Information is stored in bitsets for spacial locality and fast update of single pages. + */ +class RegionManager { +public: + explicit RegionManager(PageManager* tracker_, VAddr cpu_addr_) + : tracker{tracker_}, cpu_addr{cpu_addr_} { + cpu.Fill(); + gpu.Clear(); + writeable.Fill(); + readable.Fill(); + } + explicit RegionManager() = default; + + void SetCpuAddress(VAddr new_cpu_addr) { + cpu_addr = new_cpu_addr; + } + + VAddr GetCpuAddr() const { + return cpu_addr; + } + + static constexpr size_t SanitizeAddress(size_t address) { + return static_cast(std::max(static_cast(address), 0LL)); + } + + template + RegionBits& GetRegionBits() noexcept { + if constexpr (type == Type::CPU) { + return cpu; + } else if constexpr (type == Type::GPU) { + return gpu; + } + } + + template + const RegionBits& GetRegionBits() const noexcept { + if constexpr (type == Type::CPU) { + return cpu; + } else if constexpr (type == Type::GPU) { + return gpu; + } + } + + /** + * Change the state of a range of pages + * + * @param dirty_addr Base address to mark or unmark as modified + * @param size Size in bytes to mark or unmark as modified + */ + template + void ChangeRegionState(u64 dirty_addr, u64 size) noexcept(type == Type::GPU) { + RENDERER_TRACE; + const size_t offset = dirty_addr - cpu_addr; + const size_t start_page = SanitizeAddress(offset) / TRACKER_BYTES_PER_PAGE; + const size_t end_page = + Common::DivCeil(SanitizeAddress(offset + size), TRACKER_BYTES_PER_PAGE); + if (start_page >= NUM_PAGES_PER_REGION || end_page <= start_page) { + return; + } + + RegionBits& bits = GetRegionBits(); + if constexpr (enable) { + bits.SetRange(start_page, end_page); + } else { + bits.UnsetRange(start_page, end_page); + } + if constexpr (type == Type::CPU) { + UpdateProtection(); + } else if (EmulatorSettings.GetReadbacksMode() == GpuReadbacksMode::Precise) { + UpdateProtection(); + } + } + + /** + * Loop over each page in the given range, turn off those bits and notify the tracker if + * needed. Call the given function on each turned off range. + * + * @param query_cpu_range Base CPU address to loop over + * @param size Size in bytes of the CPU range to loop over + * @param func Function to call for each turned off region + */ + template + void ForEachModifiedRange(VAddr query_cpu_range, s64 size, auto&& func) { + RENDERER_TRACE; + const size_t offset = query_cpu_range - cpu_addr; + const size_t start_page = SanitizeAddress(offset) / TRACKER_BYTES_PER_PAGE; + const size_t end_page = + Common::DivCeil(SanitizeAddress(offset + size), TRACKER_BYTES_PER_PAGE); + if (start_page >= NUM_PAGES_PER_REGION || end_page <= start_page) { + return; + } + + RegionBits& bits = GetRegionBits(); + // bbport: nothing modified in the range means nothing to clear or re-protect (CPU bits + // always match `writeable` after a change); this runs for every buffer binding, so + // it is checked before building the range mask. + if (type == Type::CPU && !bits.AnyInRange(start_page, end_page) && + !BbToggle::Disabled(BbToggle::PageTrackingEarlyExit)) { + return; + } + RegionBits mask(bits, start_page, end_page); + + if constexpr (clear) { + bits.UnsetRange(start_page, end_page); + if constexpr (type == Type::CPU) { + UpdateProtection(); + } else if (EmulatorSettings.GetReadbacksMode() != GpuReadbacksMode::Disabled) { + UpdateProtection(); + } + } + + for (const auto& [start, end] : mask) { + func(cpu_addr + start * TRACKER_BYTES_PER_PAGE, (end - start) * TRACKER_BYTES_PER_PAGE); + } + } + + /** + * Returns true when a region has been modified + * + * @param offset Offset in bytes from the start of the buffer + * @param size Size in bytes of the region to query for modifications + */ + template + [[nodiscard]] bool IsRegionModified(u64 offset, u64 size) noexcept { + RENDERER_TRACE; + const size_t start_page = SanitizeAddress(offset) / TRACKER_BYTES_PER_PAGE; + const size_t end_page = + Common::DivCeil(SanitizeAddress(offset + size), TRACKER_BYTES_PER_PAGE); + if (start_page >= NUM_PAGES_PER_REGION || end_page <= start_page) { + return false; + } + + const RegionBits& bits = GetRegionBits(); + return bits.AnyInRange(start_page, end_page); + } + + LockType lock; + +private: + /** + * Notify tracker about changes in the CPU tracking state of a word in the buffer + * + * @param word_index Index to the word to notify to the tracker + * @param current_bits Current state of the word + * @param new_bits New state of the word + * + * @tparam track True when the tracker should start tracking the new pages + */ + template + void UpdateProtection() { + RENDERER_TRACE; + RegionBits mask = is_read ? (~gpu ^ readable) : (cpu ^ writeable); + if (mask.None()) { + return; + } + if constexpr (is_read) { + readable = ~gpu; + } else { + writeable = cpu; + } + tracker->UpdatePageWatchersForRegion(cpu_addr, mask); + } + + PageManager* tracker; + VAddr cpu_addr = 0; + RegionBits cpu; + RegionBits gpu; + RegionBits writeable; + RegionBits readable; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/cache_storage.cpp b/gpu/shadps4/video_core/cache_storage.cpp new file mode 100644 index 0000000..a403e85 --- /dev/null +++ b/gpu/shadps4/video_core/cache_storage.cpp @@ -0,0 +1,269 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/elf_info.h" +#include "common/io_file.h" +#include "common/polyfill_thread.h" +#include "common/thread.h" +#include "core/emulator_settings.h" + +#include "video_core/cache_storage.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_pipeline_cache.h" + +#include + +#include +#include +#include +#include +#include + +namespace { + +std::mutex submit_mutex{}; +u32 num_requests{}; +std::condition_variable_any request_cv{}; +std::queue> req_queue{}; +std::mutex m_request{}; + +mz_zip_archive zip_ar{}; +bool ar_is_read_only{true}; + +} // namespace + +namespace Storage { + +void ProcessIO(const std::stop_token& stoken) { + Common::SetCurrentThreadName("shadPS4:PipelineCacheIO"); + + while (!stoken.stop_requested()) { + { + std::unique_lock lk{submit_mutex}; + Common::CondvarWait(request_cv, lk, stoken, [&] { return num_requests; }); + } + + if (stoken.stop_requested()) { + break; + } + + while (num_requests) { + std::packaged_task request{}; + { + std::scoped_lock lock{m_request}; + if (req_queue.empty()) { + continue; + } + request = std::move(req_queue.front()); + req_queue.pop(); + } + + if (request.valid()) { + request(); + request.get_future().wait(); + } + + --num_requests; + } + } +} + +constexpr std::string GetBlobFileExtension(BlobType type) { + switch (type) { + case BlobType::ShaderMeta: { + return "meta"; + } + case BlobType::ShaderBinary: { + return "spv"; + } + case BlobType::PipelineKey: { + return "key"; + } + case BlobType::ShaderProfile: { + return "bin"; + } + default: + UNREACHABLE(); + } +} + +void DataBase::Open() { + if (opened) { + return; + } + + const auto& game_info = Common::ElfInfo::Instance(); + + using namespace Common::FS; + if (EmulatorSettings.IsPipelineCacheArchived()) { + mz_zip_zero_struct(&zip_ar); + + cache_path = GetUserPath(PathType::CacheDir) / + std::filesystem::path{game_info.GameSerial()}.replace_extension(".zip"); + + if (!mz_zip_reader_init_file(&zip_ar, cache_path.string().c_str(), + MZ_ZIP_FLAG_READ_ALLOW_WRITING) || + !mz_zip_validate_archive(&zip_ar, 0)) { + LOG_INFO(Render, "Cache archive {} is not found or archive is corrupted", + cache_path.string().c_str()); + mz_zip_reader_end(&zip_ar); + mz_zip_writer_init_file(&zip_ar, cache_path.string().c_str(), 0); + } + } else { + cache_path = GetUserPath(PathType::CacheDir) / game_info.GameSerial(); + if (!std::filesystem::exists(cache_path)) { + std::filesystem::create_directories(cache_path); + } + } + + io_worker = std::jthread{ProcessIO}; + opened = true; +} + +void DataBase::Close() { + if (!IsOpened()) { + return; + } + + io_worker.request_stop(); + io_worker.join(); + + if (EmulatorSettings.IsPipelineCacheArchived()) { + mz_zip_writer_finalize_archive(&zip_ar); + mz_zip_writer_end(&zip_ar); + } + + opened = false; + LOG_INFO(Render, "Cache dumped"); +} + +template +bool WriteVector(const BlobType type, std::filesystem::path&& path_, std::vector&& v) { + { + auto request = std::packaged_task{[=]() { + auto path{path_}; + path.replace_extension(GetBlobFileExtension(type)); + if (EmulatorSettings.IsPipelineCacheArchived()) { + ASSERT_MSG(!ar_is_read_only, + "The archive is read-only. Did you forget to call `FinishPreload`?"); + if (!mz_zip_writer_add_mem(&zip_ar, path.string().c_str(), v.data(), + v.size() * sizeof(T), MZ_BEST_COMPRESSION)) { + LOG_ERROR(Render, "Failed to add {} to the archive", path.string().c_str()); + } + } else { + using namespace Common::FS; + const auto file = IOFile{path, FileAccessMode::Create}; + file.Write(v); + } + }}; + std::scoped_lock lock{m_request}; + req_queue.emplace(std::move(request)); + } + + std::scoped_lock lk{submit_mutex}; + ++num_requests; + request_cv.notify_one(); + return true; +} + +template +void LoadVector(BlobType type, std::filesystem::path& path, std::vector& v) { + using namespace Common::FS; + path.replace_extension(GetBlobFileExtension(type)); + if (EmulatorSettings.IsPipelineCacheArchived()) { + int index{-1}; + index = mz_zip_reader_locate_file(&zip_ar, path.string().c_str(), nullptr, 0); + if (index < 0) { + LOG_WARNING(Render, "File {} is not found in the archive", path.string().c_str()); + return; + } + mz_zip_archive_file_stat stat{}; + mz_zip_reader_file_stat(&zip_ar, index, &stat); + v.resize(stat.m_uncomp_size / sizeof(T)); + mz_zip_reader_extract_to_mem(&zip_ar, index, v.data(), stat.m_uncomp_size, 0); + } else { + const auto file = IOFile{path, FileAccessMode::Read}; + v.resize(file.GetSize() / sizeof(T)); + file.Read(v); + } +} + +bool DataBase::Save(BlobType type, const std::string& name, std::vector&& data) { + if (!opened) { + return false; + } + + auto path = EmulatorSettings.IsPipelineCacheArchived() ? std::filesystem::path{name} + : cache_path / name; + return WriteVector(type, std::move(path), std::move(data)); +} + +bool DataBase::Save(BlobType type, const std::string& name, std::vector&& data) { + if (!opened) { + return false; + } + + auto path = EmulatorSettings.IsPipelineCacheArchived() ? std::filesystem::path{name} + : cache_path / name; + return WriteVector(type, std::move(path), std::move(data)); +} + +void DataBase::Load(BlobType type, const std::string& name, std::vector& data) { + if (!opened) { + return; + } + + auto path = EmulatorSettings.IsPipelineCacheArchived() ? std::filesystem::path{name} + : cache_path / name; + return LoadVector(type, path, data); +} + +void DataBase::Load(BlobType type, const std::string& name, std::vector& data) { + if (!opened) { + return; + } + + auto path = EmulatorSettings.IsPipelineCacheArchived() ? std::filesystem::path{name} + : cache_path / name; + return LoadVector(type, path, data); +} + +void DataBase::ForEachBlob(BlobType type, const std::function&& data)>& func) { + const auto& ext = GetBlobFileExtension(type); + if (EmulatorSettings.IsPipelineCacheArchived()) { + const auto num_files = mz_zip_reader_get_num_files(&zip_ar); + for (int index = 0; index < num_files; ++index) { + std::array file_name{}; + file_name.fill(0); + mz_zip_reader_get_filename(&zip_ar, index, file_name.data(), file_name.size()); + if (std::string{file_name.data()}.ends_with(ext)) { + mz_zip_archive_file_stat stat{}; + mz_zip_reader_file_stat(&zip_ar, index, &stat); + std::vector data(stat.m_uncomp_size); + mz_zip_reader_extract_to_mem(&zip_ar, index, data.data(), data.size(), 0); + func(std::move(data)); + } + } + } else { + for (const auto& file_name : std::filesystem::directory_iterator{cache_path}) { + if (file_name.path().extension().string().ends_with(ext)) { + using namespace Common::FS; + const auto& file = IOFile{file_name, FileAccessMode::Read}; + if (file.IsOpen()) { + std::vector data(file.GetSize()); + file.Read(data); + func(std::move(data)); + } + } + } + } +} + +void DataBase::FinishPreload() { + if (EmulatorSettings.IsPipelineCacheArchived()) { + mz_zip_writer_init_from_reader(&zip_ar, cache_path.string().c_str()); + ar_is_read_only = false; + } +} + +} // namespace Storage diff --git a/gpu/shadps4/video_core/cache_storage.h b/gpu/shadps4/video_core/cache_storage.h new file mode 100644 index 0000000..91f2136 --- /dev/null +++ b/gpu/shadps4/video_core/cache_storage.h @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/path_util.h" +#include "common/singleton.h" +#include "common/types.h" + +#include +#include +#include + +namespace Storage { + +enum class BlobType : u32 { + ShaderMeta, + ShaderBinary, + PipelineKey, + ShaderProfile, +}; + +class DataBase { +public: + static DataBase& Instance() { + return *Common::Singleton::Instance(); + } + + void Open(); + void Close(); + [[nodiscard]] bool IsOpened() const { + return opened; + } + void FinishPreload(); + + bool Save(BlobType type, const std::string& name, std::vector&& data); + bool Save(BlobType type, const std::string& name, std::vector&& data); + + void Load(BlobType type, const std::string& name, std::vector& data); + void Load(BlobType type, const std::string& name, std::vector& data); + + void ForEachBlob(BlobType type, const std::function&& data)>& func); + +private: + std::jthread io_worker{}; + std::filesystem::path cache_path{}; + bool opened{}; +}; + +} // namespace Storage diff --git a/gpu/shadps4/video_core/host_shaders/AddShaderHeaderInclude.cmake b/gpu/shadps4/video_core/host_shaders/AddShaderHeaderInclude.cmake new file mode 100644 index 0000000..22b6bd7 --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/AddShaderHeaderInclude.cmake @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +# SPDX-License-Identifier: GPL-2.0-or-later + +file(READ "${HEADER_FILE}" HEADER_CONTENT) +string(REPLACE "#pragma once" "#pragma once\n#include " HEADER_CONTENT "${HEADER_CONTENT}") +file(WRITE "${HEADER_FILE}" "${HEADER_CONTENT}") diff --git a/gpu/shadps4/video_core/host_shaders/CMakeLists.txt b/gpu/shadps4/video_core/host_shaders/CMakeLists.txt new file mode 100644 index 0000000..1f4d3bc --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/CMakeLists.txt @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: Copyright 2023 Citra Emulator Project +# SPDX-License-Identifier: GPL-2.0-or-later + +if (TARGET glslang-standalone) + set(GLSLANG_COMPILER glslang-standalone) +elseif (TARGET glslang::glslang-standalone) + set(GLSLANG_COMPILER glslang::glslang-standalone) +endif() + +set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) +set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) +set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) + +set(SHADER_FILES "") + +function(add_host_shader FILENAME SHADER_NAME) + set(SOURCE_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h) + set(DEPFILE ${SOURCE_HEADER_FILE}.d) + string(TOUPPER ${SHADER_NAME} SYMBOL) + set(SHADER_DEFINES ${ARGN}) + list(TRANSFORM SHADER_DEFINES PREPEND "-D") + add_custom_command( + OUTPUT ${SOURCE_HEADER_FILE} + COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADER_DIR} + COMMAND ${GLSLANG_COMPILER} --target-env vulkan1.3 + -o ${SOURCE_HEADER_FILE} --vn ${SYMBOL} --depfile ${DEPFILE} + ${SHADER_DEFINES} ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME} + COMMAND ${CMAKE_COMMAND} "-DHEADER_FILE=${SOURCE_HEADER_FILE}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/AddShaderHeaderInclude.cmake + DEPENDS ${GLSLANG_COMPILER} ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME} + ${CMAKE_CURRENT_SOURCE_DIR}/AddShaderHeaderInclude.cmake + DEPFILE ${DEPFILE} + BYPRODUCTS ${DEPFILE} + COMMENT "Building host shader ${FILENAME} -> ${SOURCE_HEADER_FILE}" + VERBATIM + ) + set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE} PARENT_SCOPE) + set(SHADER_FILES ${SHADER_FILES} ${FILENAME} PARENT_SCOPE) +endfunction() + +add_host_shader(color_to_ms_depth.frag color_to_ms_depth_frag) +add_host_shader(ms_image_blit.frag ms_image_blit_frag) +add_host_shader(ms_image_blit.frag ms_image_blit_msaa_frag SRC_MSAA=1) +add_host_shader(fault_buffer_process.comp fault_buffer_process_comp) +add_host_shader(fs_tri.vert fs_tri_vert) +add_host_shader(fsr.comp fsr_easu_comp SAMPLE_EASU=1) +add_host_shader(fsr.comp fsr_rcas_comp SAMPLE_RCAS=1) +add_host_shader(post_process.frag post_process_frag) + +foreach(BPP IN ITEMS 8 16 32 64 96 128) + add_host_shader(tiling.comp tiling_micro_${BPP}_comp BITS_PER_PIXEL=${BPP} IS_MACRO_TILED=0) + add_host_shader(tiling.comp tiling_macro_${BPP}_comp BITS_PER_PIXEL=${BPP} IS_MACRO_TILED=1) +endforeach() + +list(REMOVE_DUPLICATES SHADER_FILES) +add_custom_target(host_shaders DEPENDS ${SHADER_HEADERS} SOURCES ${SHADER_FILES}) diff --git a/gpu/shadps4/video_core/host_shaders/color_to_ms_depth.frag b/gpu/shadps4/video_core/host_shaders/color_to_ms_depth.frag new file mode 100644 index 0000000..e477fc9 --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/color_to_ms_depth.frag @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 core +#extension GL_EXT_samplerless_texture_functions : require + +layout (binding = 0, set = 0) uniform texture2D color; + +layout (location = 0) in vec2 uv; + +void main() +{ + ivec2 coord = ivec2(uv * vec2(textureSize(color, 0).xy)); + gl_FragDepth = texelFetch(color, coord, 0)[gl_SampleID]; +} diff --git a/gpu/shadps4/video_core/host_shaders/fault_buffer_process.comp b/gpu/shadps4/video_core/host_shaders/fault_buffer_process.comp new file mode 100644 index 0000000..1a5f982 --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/fault_buffer_process.comp @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 +#extension GL_ARB_gpu_shader_int64 : enable + +layout(constant_id = 0) const uint CACHING_PAGEBITS = 12; +layout(constant_id = 1) const uint MAX_PAGE_FAULTS = 1024; + +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; + +layout(std430, binding = 0) buffer input_buf { + uint fault_buffer[]; +}; + +layout(std430, binding = 1) buffer output_buf { + uint64_t download_buffer[]; +}; +layout(std430, binding = 1) buffer output_buf32 { + uint download_buffer32[]; +}; + +void main() { + const uint id = gl_GlobalInvocationID.x; + uint word = fault_buffer[id]; + fault_buffer[id] = 0u; + const uint base_bit = id * 32u; + while (word != 0u) { + const uint store_index = atomicAdd(download_buffer32[0], 1u) + 1u; + if (store_index >= MAX_PAGE_FAULTS) { + return; + } + const uint bit = findLSB(word); + word &= word - 1; + const uint page = base_bit + bit; + download_buffer[store_index] = uint64_t(page) << CACHING_PAGEBITS; + } +} diff --git a/gpu/shadps4/video_core/host_shaders/fs_tri.vert b/gpu/shadps4/video_core/host_shaders/fs_tri.vert new file mode 100644 index 0000000..d6ea55a --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/fs_tri.vert @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +#if defined(INSTANCE_AS_LAYER) +#extension GL_ARB_shader_viewport_layer_array : require +#endif + +layout(location = 0) out vec2 uv; + +void main() { + vec2 pos = vec2( + float((gl_VertexIndex & 1u) << 2u), + float((gl_VertexIndex & 2u) << 1u) + ); + gl_Position = vec4(pos - vec2(1.0, 1.0), 0.0, 1.0); +#if defined(INSTANCE_AS_LAYER) + gl_Layer = gl_InstanceIndex; +#endif + uv = pos * 0.5; +} diff --git a/gpu/shadps4/video_core/host_shaders/fsr.comp b/gpu/shadps4/video_core/host_shaders/fsr.comp new file mode 100644 index 0000000..e8349d5 --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/fsr.comp @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. +// SPDX-License-Identifier: MIT + +#version 450 +#extension GL_GOOGLE_include_directive : require +#extension GL_ARB_separate_shader_objects: enable +#extension GL_ARB_shading_language_420pack: enable + +// FidelityFX Super Resolution Sample +// +// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// 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 Software. +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +layout (push_constant) uniform const_buffer +{ + uvec4 Const0; + uvec4 Const1; + uvec4 Const2; + uvec4 Const3; + uvec4 Sample; +}; + +#define A_GPU 1 +#define A_GLSL 1 + +#define A_HALF +#include "fsr/ffx_a.h" + +layout (set = 0, binding = 0) uniform texture2D InputTexture; +layout (set = 0, binding = 1, rgba16f) uniform image2D OutputTexture; +layout (set = 0, binding = 2) uniform sampler InputSampler; + +#if SAMPLE_EASU +#define FSR_EASU_H 1 +AH4 FsrEasuRH(AF2 p) { AH4 res = AH4(textureGather(sampler2D(InputTexture, InputSampler), p, 0)); return res; } +AH4 FsrEasuGH(AF2 p) { AH4 res = AH4(textureGather(sampler2D(InputTexture, InputSampler), p, 1)); return res; } +AH4 FsrEasuBH(AF2 p) { AH4 res = AH4(textureGather(sampler2D(InputTexture, InputSampler), p, 2)); return res; } +#endif// SAMPLE_EASU + +#if SAMPLE_RCAS +#define FSR_RCAS_H +AH4 FsrRcasLoadH(ASW2 p) { return AH4(texelFetch(sampler2D(InputTexture, InputSampler), ASU2(p), 0)); } +void FsrRcasInputH(inout AH1 r, inout AH1 g, inout AH1 b) { } +#endif// SAMPLE_RCAS + +#include "fsr/ffx_fsr1.h" + +void CurrFilter(AU2 pos) +{ + #if SAMPLE_EASU + AH3 c; + FsrEasuH(c, pos, Const0, Const1, Const2, Const3); + if (Sample.x == 1) + c *= c; + imageStore(OutputTexture, ASU2(pos), AH4(c, 1)); + #endif// SAMPLE_EASU +#if SAMPLE_RCAS + AH3 c; + FsrRcasH(c.r, c.g, c.b, pos, Const0); + if (Sample.x == 1) + c *= c; + imageStore(OutputTexture, ASU2(pos), AH4(c, 1)); + #endif// SAMPLE_RCAS +} + +layout (local_size_x = 64) in; +void main() +{ + // Do remapping of local xy in workgroup for a more PS-like swizzle pattern. + AU2 gxy = ARmp8x8(gl_LocalInvocationID.x) + AU2(gl_WorkGroupID.x << 4u, gl_WorkGroupID.y << 4u); + CurrFilter(gxy); + gxy.x += 8u; + CurrFilter(gxy); + gxy.y += 8u; + CurrFilter(gxy); + gxy.x -= 8u; + CurrFilter(gxy); +} \ No newline at end of file diff --git a/gpu/shadps4/video_core/host_shaders/fsr/ffx_a.h b/gpu/shadps4/video_core/host_shaders/fsr/ffx_a.h new file mode 100644 index 0000000..882b038 --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/fsr/ffx_a.h @@ -0,0 +1,2657 @@ +// clang-format off +//============================================================================================================================== +// +// [A] SHADER PORTABILITY 1.20210629 +// +//============================================================================================================================== +// FidelityFX Super Resolution Sample +// +// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// 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 Software. +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +//------------------------------------------------------------------------------------------------------------------------------ +// MIT LICENSE +// =========== +// Copyright (c) 2014 Michal Drobot (for concepts used in "FLOAT APPROXIMATIONS"). +// ----------- +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is 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 +// Software. +// ----------- +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +//------------------------------------------------------------------------------------------------------------------------------ +// ABOUT +// ===== +// Common central point for high-level shading language and C portability for various shader headers. +//------------------------------------------------------------------------------------------------------------------------------ +// DEFINES +// ======= +// A_CPU ..... Include the CPU related code. +// A_GPU ..... Include the GPU related code. +// A_GLSL .... Using GLSL. +// A_HLSL .... Using HLSL. +// A_HLSL_6_2 Using HLSL 6.2 with new 'uint16_t' and related types (requires '-enable-16bit-types'). +// A_NO_16_BIT_CAST Don't use instructions that are not availabe in SPIR-V (needed for running A_HLSL_6_2 on Vulkan) +// A_GCC ..... Using a GCC compatible compiler (else assume MSVC compatible compiler by default). +// ======= +// A_BYTE .... Support 8-bit integer. +// A_HALF .... Support 16-bit integer and floating point. +// A_LONG .... Support 64-bit integer. +// A_DUBL .... Support 64-bit floating point. +// ======= +// A_WAVE .... Support wave-wide operations. +//------------------------------------------------------------------------------------------------------------------------------ +// To get #include "ffx_a.h" working in GLSL use '#extension GL_GOOGLE_include_directive:require'. +//------------------------------------------------------------------------------------------------------------------------------ +// SIMPLIFIED TYPE SYSTEM +// ====================== +// - All ints will be unsigned with exception of when signed is required. +// - Type naming simplified and shortened "A<#components>", +// - H = 16-bit float (half) +// - F = 32-bit float (float) +// - D = 64-bit float (double) +// - P = 1-bit integer (predicate, not using bool because 'B' is used for byte) +// - B = 8-bit integer (byte) +// - W = 16-bit integer (word) +// - U = 32-bit integer (unsigned) +// - L = 64-bit integer (long) +// - Using "AS<#components>" for signed when required. +//------------------------------------------------------------------------------------------------------------------------------ +// TODO +// ==== +// - Make sure 'ALerp*(a,b,m)' does 'b*m+(-a*m+a)' (2 ops). +//------------------------------------------------------------------------------------------------------------------------------ +// CHANGE LOG +// ========== +// 20200914 - Expanded wave ops and prx code. +// 20200713 - Added [ZOL] section, fixed serious bugs in sRGB and Rec.709 color conversion code, etc. +//============================================================================================================================== +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// COMMON +//============================================================================================================================== +#define A_2PI 6.28318530718 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// +// CPU +// +// +//============================================================================================================================== +#ifdef A_CPU + // Supporting user defined overrides. + #ifndef A_RESTRICT + #define A_RESTRICT __restrict + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #ifndef A_STATIC + #define A_STATIC static + #endif +//------------------------------------------------------------------------------------------------------------------------------ + // Same types across CPU and GPU. + // Predicate uses 32-bit integer (C friendly bool). + typedef uint32_t AP1; + typedef float AF1; + typedef double AD1; + typedef uint8_t AB1; + typedef uint16_t AW1; + typedef uint32_t AU1; + typedef uint64_t AL1; + typedef int8_t ASB1; + typedef int16_t ASW1; + typedef int32_t ASU1; + typedef int64_t ASL1; +//------------------------------------------------------------------------------------------------------------------------------ + #define AD1_(a) ((AD1)(a)) + #define AF1_(a) ((AF1)(a)) + #define AL1_(a) ((AL1)(a)) + #define AU1_(a) ((AU1)(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define ASL1_(a) ((ASL1)(a)) + #define ASU1_(a) ((ASU1)(a)) +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AU1 AU1_AF1(AF1 a){union{AF1 f;AU1 u;}bits;bits.f=a;return bits.u;} +//------------------------------------------------------------------------------------------------------------------------------ + #define A_TRUE 1 + #define A_FALSE 0 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// CPU/GPU PORTING +// +//------------------------------------------------------------------------------------------------------------------------------ +// Get CPU and GPU to share all setup code, without duplicate code paths. +// This uses a lower-case prefix for special vector constructs. +// - In C restrict pointers are used. +// - In the shading language, in/inout/out arguments are used. +// This depends on the ability to access a vector value in both languages via array syntax (aka color[2]). +//============================================================================================================================== +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// VECTOR ARGUMENT/RETURN/INITIALIZATION PORTABILITY +//============================================================================================================================== + #define retAD2 AD1 *A_RESTRICT + #define retAD3 AD1 *A_RESTRICT + #define retAD4 AD1 *A_RESTRICT + #define retAF2 AF1 *A_RESTRICT + #define retAF3 AF1 *A_RESTRICT + #define retAF4 AF1 *A_RESTRICT + #define retAL2 AL1 *A_RESTRICT + #define retAL3 AL1 *A_RESTRICT + #define retAL4 AL1 *A_RESTRICT + #define retAU2 AU1 *A_RESTRICT + #define retAU3 AU1 *A_RESTRICT + #define retAU4 AU1 *A_RESTRICT +//------------------------------------------------------------------------------------------------------------------------------ + #define inAD2 AD1 *A_RESTRICT + #define inAD3 AD1 *A_RESTRICT + #define inAD4 AD1 *A_RESTRICT + #define inAF2 AF1 *A_RESTRICT + #define inAF3 AF1 *A_RESTRICT + #define inAF4 AF1 *A_RESTRICT + #define inAL2 AL1 *A_RESTRICT + #define inAL3 AL1 *A_RESTRICT + #define inAL4 AL1 *A_RESTRICT + #define inAU2 AU1 *A_RESTRICT + #define inAU3 AU1 *A_RESTRICT + #define inAU4 AU1 *A_RESTRICT +//------------------------------------------------------------------------------------------------------------------------------ + #define inoutAD2 AD1 *A_RESTRICT + #define inoutAD3 AD1 *A_RESTRICT + #define inoutAD4 AD1 *A_RESTRICT + #define inoutAF2 AF1 *A_RESTRICT + #define inoutAF3 AF1 *A_RESTRICT + #define inoutAF4 AF1 *A_RESTRICT + #define inoutAL2 AL1 *A_RESTRICT + #define inoutAL3 AL1 *A_RESTRICT + #define inoutAL4 AL1 *A_RESTRICT + #define inoutAU2 AU1 *A_RESTRICT + #define inoutAU3 AU1 *A_RESTRICT + #define inoutAU4 AU1 *A_RESTRICT +//------------------------------------------------------------------------------------------------------------------------------ + #define outAD2 AD1 *A_RESTRICT + #define outAD3 AD1 *A_RESTRICT + #define outAD4 AD1 *A_RESTRICT + #define outAF2 AF1 *A_RESTRICT + #define outAF3 AF1 *A_RESTRICT + #define outAF4 AF1 *A_RESTRICT + #define outAL2 AL1 *A_RESTRICT + #define outAL3 AL1 *A_RESTRICT + #define outAL4 AL1 *A_RESTRICT + #define outAU2 AU1 *A_RESTRICT + #define outAU3 AU1 *A_RESTRICT + #define outAU4 AU1 *A_RESTRICT +//------------------------------------------------------------------------------------------------------------------------------ + #define varAD2(x) AD1 x[2] + #define varAD3(x) AD1 x[3] + #define varAD4(x) AD1 x[4] + #define varAF2(x) AF1 x[2] + #define varAF3(x) AF1 x[3] + #define varAF4(x) AF1 x[4] + #define varAL2(x) AL1 x[2] + #define varAL3(x) AL1 x[3] + #define varAL4(x) AL1 x[4] + #define varAU2(x) AU1 x[2] + #define varAU3(x) AU1 x[3] + #define varAU4(x) AU1 x[4] +//------------------------------------------------------------------------------------------------------------------------------ + #define initAD2(x,y) {x,y} + #define initAD3(x,y,z) {x,y,z} + #define initAD4(x,y,z,w) {x,y,z,w} + #define initAF2(x,y) {x,y} + #define initAF3(x,y,z) {x,y,z} + #define initAF4(x,y,z,w) {x,y,z,w} + #define initAL2(x,y) {x,y} + #define initAL3(x,y,z) {x,y,z} + #define initAL4(x,y,z,w) {x,y,z,w} + #define initAU2(x,y) {x,y} + #define initAU3(x,y,z) {x,y,z} + #define initAU4(x,y,z,w) {x,y,z,w} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// SCALAR RETURN OPS +//------------------------------------------------------------------------------------------------------------------------------ +// TODO +// ==== +// - Replace transcendentals with manual versions. +//============================================================================================================================== + #ifdef A_GCC + A_STATIC AD1 AAbsD1(AD1 a){return __builtin_fabs(a);} + A_STATIC AF1 AAbsF1(AF1 a){return __builtin_fabsf(a);} + A_STATIC AU1 AAbsSU1(AU1 a){return AU1_(__builtin_abs(ASU1_(a)));} + A_STATIC AL1 AAbsSL1(AL1 a){return AL1_(__builtin_llabs(ASL1_(a)));} + #else + A_STATIC AD1 AAbsD1(AD1 a){return fabs(a);} + A_STATIC AF1 AAbsF1(AF1 a){return fabsf(a);} + A_STATIC AU1 AAbsSU1(AU1 a){return AU1_(abs(ASU1_(a)));} + A_STATIC AL1 AAbsSL1(AL1 a){return AL1_(labs((long)ASL1_(a)));} + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_GCC + A_STATIC AD1 ACosD1(AD1 a){return __builtin_cos(a);} + A_STATIC AF1 ACosF1(AF1 a){return __builtin_cosf(a);} + #else + A_STATIC AD1 ACosD1(AD1 a){return cos(a);} + A_STATIC AF1 ACosF1(AF1 a){return cosf(a);} + #endif +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 ADotD2(inAD2 a,inAD2 b){return a[0]*b[0]+a[1]*b[1];} + A_STATIC AD1 ADotD3(inAD3 a,inAD3 b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];} + A_STATIC AD1 ADotD4(inAD4 a,inAD4 b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];} + A_STATIC AF1 ADotF2(inAF2 a,inAF2 b){return a[0]*b[0]+a[1]*b[1];} + A_STATIC AF1 ADotF3(inAF3 a,inAF3 b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];} + A_STATIC AF1 ADotF4(inAF4 a,inAF4 b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];} +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_GCC + A_STATIC AD1 AExp2D1(AD1 a){return __builtin_exp2(a);} + A_STATIC AF1 AExp2F1(AF1 a){return __builtin_exp2f(a);} + #else + A_STATIC AD1 AExp2D1(AD1 a){return exp2(a);} + A_STATIC AF1 AExp2F1(AF1 a){return exp2f(a);} + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_GCC + A_STATIC AD1 AFloorD1(AD1 a){return __builtin_floor(a);} + A_STATIC AF1 AFloorF1(AF1 a){return __builtin_floorf(a);} + #else + A_STATIC AD1 AFloorD1(AD1 a){return floor(a);} + A_STATIC AF1 AFloorF1(AF1 a){return floorf(a);} + #endif +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 ALerpD1(AD1 a,AD1 b,AD1 c){return b*c+(-a*c+a);} + A_STATIC AF1 ALerpF1(AF1 a,AF1 b,AF1 c){return b*c+(-a*c+a);} +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_GCC + A_STATIC AD1 ALog2D1(AD1 a){return __builtin_log2(a);} + A_STATIC AF1 ALog2F1(AF1 a){return __builtin_log2f(a);} + #else + A_STATIC AD1 ALog2D1(AD1 a){return log2(a);} + A_STATIC AF1 ALog2F1(AF1 a){return log2f(a);} + #endif +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 AMaxD1(AD1 a,AD1 b){return a>b?a:b;} + A_STATIC AF1 AMaxF1(AF1 a,AF1 b){return a>b?a:b;} + A_STATIC AL1 AMaxL1(AL1 a,AL1 b){return a>b?a:b;} + A_STATIC AU1 AMaxU1(AU1 a,AU1 b){return a>b?a:b;} +//------------------------------------------------------------------------------------------------------------------------------ + // These follow the convention that A integer types don't have signage, until they are operated on. + A_STATIC AL1 AMaxSL1(AL1 a,AL1 b){return (ASL1_(a)>ASL1_(b))?a:b;} + A_STATIC AU1 AMaxSU1(AU1 a,AU1 b){return (ASU1_(a)>ASU1_(b))?a:b;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 AMinD1(AD1 a,AD1 b){return a>ASL1_(b));} + A_STATIC AU1 AShrSU1(AU1 a,AU1 b){return AU1_(ASU1_(a)>>ASU1_(b));} +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_GCC + A_STATIC AD1 ASinD1(AD1 a){return __builtin_sin(a);} + A_STATIC AF1 ASinF1(AF1 a){return __builtin_sinf(a);} + #else + A_STATIC AD1 ASinD1(AD1 a){return sin(a);} + A_STATIC AF1 ASinF1(AF1 a){return sinf(a);} + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_GCC + A_STATIC AD1 ASqrtD1(AD1 a){return __builtin_sqrt(a);} + A_STATIC AF1 ASqrtF1(AF1 a){return __builtin_sqrtf(a);} + #else + A_STATIC AD1 ASqrtD1(AD1 a){return sqrt(a);} + A_STATIC AF1 ASqrtF1(AF1 a){return sqrtf(a);} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// SCALAR RETURN OPS - DEPENDENT +//============================================================================================================================== + A_STATIC AD1 AClampD1(AD1 x,AD1 n,AD1 m){return AMaxD1(n,AMinD1(x,m));} + A_STATIC AF1 AClampF1(AF1 x,AF1 n,AF1 m){return AMaxF1(n,AMinF1(x,m));} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 AFractD1(AD1 a){return a-AFloorD1(a);} + A_STATIC AF1 AFractF1(AF1 a){return a-AFloorF1(a);} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 APowD1(AD1 a,AD1 b){return AExp2D1(b*ALog2D1(a));} + A_STATIC AF1 APowF1(AF1 a,AF1 b){return AExp2F1(b*ALog2F1(a));} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 ARsqD1(AD1 a){return ARcpD1(ASqrtD1(a));} + A_STATIC AF1 ARsqF1(AF1 a){return ARcpF1(ASqrtF1(a));} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC AD1 ASatD1(AD1 a){return AMinD1(1.0,AMaxD1(0.0,a));} + A_STATIC AF1 ASatF1(AF1 a){return AMinF1(1.0f,AMaxF1(0.0f,a));} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// VECTOR OPS +//------------------------------------------------------------------------------------------------------------------------------ +// These are added as needed for production or prototyping, so not necessarily a complete set. +// They follow a convention of taking in a destination and also returning the destination value to increase utility. +//============================================================================================================================== + A_STATIC retAD2 opAAbsD2(outAD2 d,inAD2 a){d[0]=AAbsD1(a[0]);d[1]=AAbsD1(a[1]);return d;} + A_STATIC retAD3 opAAbsD3(outAD3 d,inAD3 a){d[0]=AAbsD1(a[0]);d[1]=AAbsD1(a[1]);d[2]=AAbsD1(a[2]);return d;} + A_STATIC retAD4 opAAbsD4(outAD4 d,inAD4 a){d[0]=AAbsD1(a[0]);d[1]=AAbsD1(a[1]);d[2]=AAbsD1(a[2]);d[3]=AAbsD1(a[3]);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opAAbsF2(outAF2 d,inAF2 a){d[0]=AAbsF1(a[0]);d[1]=AAbsF1(a[1]);return d;} + A_STATIC retAF3 opAAbsF3(outAF3 d,inAF3 a){d[0]=AAbsF1(a[0]);d[1]=AAbsF1(a[1]);d[2]=AAbsF1(a[2]);return d;} + A_STATIC retAF4 opAAbsF4(outAF4 d,inAF4 a){d[0]=AAbsF1(a[0]);d[1]=AAbsF1(a[1]);d[2]=AAbsF1(a[2]);d[3]=AAbsF1(a[3]);return d;} +//============================================================================================================================== + A_STATIC retAD2 opAAddD2(outAD2 d,inAD2 a,inAD2 b){d[0]=a[0]+b[0];d[1]=a[1]+b[1];return d;} + A_STATIC retAD3 opAAddD3(outAD3 d,inAD3 a,inAD3 b){d[0]=a[0]+b[0];d[1]=a[1]+b[1];d[2]=a[2]+b[2];return d;} + A_STATIC retAD4 opAAddD4(outAD4 d,inAD4 a,inAD4 b){d[0]=a[0]+b[0];d[1]=a[1]+b[1];d[2]=a[2]+b[2];d[3]=a[3]+b[3];return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opAAddF2(outAF2 d,inAF2 a,inAF2 b){d[0]=a[0]+b[0];d[1]=a[1]+b[1];return d;} + A_STATIC retAF3 opAAddF3(outAF3 d,inAF3 a,inAF3 b){d[0]=a[0]+b[0];d[1]=a[1]+b[1];d[2]=a[2]+b[2];return d;} + A_STATIC retAF4 opAAddF4(outAF4 d,inAF4 a,inAF4 b){d[0]=a[0]+b[0];d[1]=a[1]+b[1];d[2]=a[2]+b[2];d[3]=a[3]+b[3];return d;} +//============================================================================================================================== + A_STATIC retAD2 opAAddOneD2(outAD2 d,inAD2 a,AD1 b){d[0]=a[0]+b;d[1]=a[1]+b;return d;} + A_STATIC retAD3 opAAddOneD3(outAD3 d,inAD3 a,AD1 b){d[0]=a[0]+b;d[1]=a[1]+b;d[2]=a[2]+b;return d;} + A_STATIC retAD4 opAAddOneD4(outAD4 d,inAD4 a,AD1 b){d[0]=a[0]+b;d[1]=a[1]+b;d[2]=a[2]+b;d[3]=a[3]+b;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opAAddOneF2(outAF2 d,inAF2 a,AF1 b){d[0]=a[0]+b;d[1]=a[1]+b;return d;} + A_STATIC retAF3 opAAddOneF3(outAF3 d,inAF3 a,AF1 b){d[0]=a[0]+b;d[1]=a[1]+b;d[2]=a[2]+b;return d;} + A_STATIC retAF4 opAAddOneF4(outAF4 d,inAF4 a,AF1 b){d[0]=a[0]+b;d[1]=a[1]+b;d[2]=a[2]+b;d[3]=a[3]+b;return d;} +//============================================================================================================================== + A_STATIC retAD2 opACpyD2(outAD2 d,inAD2 a){d[0]=a[0];d[1]=a[1];return d;} + A_STATIC retAD3 opACpyD3(outAD3 d,inAD3 a){d[0]=a[0];d[1]=a[1];d[2]=a[2];return d;} + A_STATIC retAD4 opACpyD4(outAD4 d,inAD4 a){d[0]=a[0];d[1]=a[1];d[2]=a[2];d[3]=a[3];return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opACpyF2(outAF2 d,inAF2 a){d[0]=a[0];d[1]=a[1];return d;} + A_STATIC retAF3 opACpyF3(outAF3 d,inAF3 a){d[0]=a[0];d[1]=a[1];d[2]=a[2];return d;} + A_STATIC retAF4 opACpyF4(outAF4 d,inAF4 a){d[0]=a[0];d[1]=a[1];d[2]=a[2];d[3]=a[3];return d;} +//============================================================================================================================== + A_STATIC retAD2 opALerpD2(outAD2 d,inAD2 a,inAD2 b,inAD2 c){d[0]=ALerpD1(a[0],b[0],c[0]);d[1]=ALerpD1(a[1],b[1],c[1]);return d;} + A_STATIC retAD3 opALerpD3(outAD3 d,inAD3 a,inAD3 b,inAD3 c){d[0]=ALerpD1(a[0],b[0],c[0]);d[1]=ALerpD1(a[1],b[1],c[1]);d[2]=ALerpD1(a[2],b[2],c[2]);return d;} + A_STATIC retAD4 opALerpD4(outAD4 d,inAD4 a,inAD4 b,inAD4 c){d[0]=ALerpD1(a[0],b[0],c[0]);d[1]=ALerpD1(a[1],b[1],c[1]);d[2]=ALerpD1(a[2],b[2],c[2]);d[3]=ALerpD1(a[3],b[3],c[3]);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opALerpF2(outAF2 d,inAF2 a,inAF2 b,inAF2 c){d[0]=ALerpF1(a[0],b[0],c[0]);d[1]=ALerpF1(a[1],b[1],c[1]);return d;} + A_STATIC retAF3 opALerpF3(outAF3 d,inAF3 a,inAF3 b,inAF3 c){d[0]=ALerpF1(a[0],b[0],c[0]);d[1]=ALerpF1(a[1],b[1],c[1]);d[2]=ALerpF1(a[2],b[2],c[2]);return d;} + A_STATIC retAF4 opALerpF4(outAF4 d,inAF4 a,inAF4 b,inAF4 c){d[0]=ALerpF1(a[0],b[0],c[0]);d[1]=ALerpF1(a[1],b[1],c[1]);d[2]=ALerpF1(a[2],b[2],c[2]);d[3]=ALerpF1(a[3],b[3],c[3]);return d;} +//============================================================================================================================== + A_STATIC retAD2 opALerpOneD2(outAD2 d,inAD2 a,inAD2 b,AD1 c){d[0]=ALerpD1(a[0],b[0],c);d[1]=ALerpD1(a[1],b[1],c);return d;} + A_STATIC retAD3 opALerpOneD3(outAD3 d,inAD3 a,inAD3 b,AD1 c){d[0]=ALerpD1(a[0],b[0],c);d[1]=ALerpD1(a[1],b[1],c);d[2]=ALerpD1(a[2],b[2],c);return d;} + A_STATIC retAD4 opALerpOneD4(outAD4 d,inAD4 a,inAD4 b,AD1 c){d[0]=ALerpD1(a[0],b[0],c);d[1]=ALerpD1(a[1],b[1],c);d[2]=ALerpD1(a[2],b[2],c);d[3]=ALerpD1(a[3],b[3],c);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opALerpOneF2(outAF2 d,inAF2 a,inAF2 b,AF1 c){d[0]=ALerpF1(a[0],b[0],c);d[1]=ALerpF1(a[1],b[1],c);return d;} + A_STATIC retAF3 opALerpOneF3(outAF3 d,inAF3 a,inAF3 b,AF1 c){d[0]=ALerpF1(a[0],b[0],c);d[1]=ALerpF1(a[1],b[1],c);d[2]=ALerpF1(a[2],b[2],c);return d;} + A_STATIC retAF4 opALerpOneF4(outAF4 d,inAF4 a,inAF4 b,AF1 c){d[0]=ALerpF1(a[0],b[0],c);d[1]=ALerpF1(a[1],b[1],c);d[2]=ALerpF1(a[2],b[2],c);d[3]=ALerpF1(a[3],b[3],c);return d;} +//============================================================================================================================== + A_STATIC retAD2 opAMaxD2(outAD2 d,inAD2 a,inAD2 b){d[0]=AMaxD1(a[0],b[0]);d[1]=AMaxD1(a[1],b[1]);return d;} + A_STATIC retAD3 opAMaxD3(outAD3 d,inAD3 a,inAD3 b){d[0]=AMaxD1(a[0],b[0]);d[1]=AMaxD1(a[1],b[1]);d[2]=AMaxD1(a[2],b[2]);return d;} + A_STATIC retAD4 opAMaxD4(outAD4 d,inAD4 a,inAD4 b){d[0]=AMaxD1(a[0],b[0]);d[1]=AMaxD1(a[1],b[1]);d[2]=AMaxD1(a[2],b[2]);d[3]=AMaxD1(a[3],b[3]);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opAMaxF2(outAF2 d,inAF2 a,inAF2 b){d[0]=AMaxF1(a[0],b[0]);d[1]=AMaxF1(a[1],b[1]);return d;} + A_STATIC retAF3 opAMaxF3(outAF3 d,inAF3 a,inAF3 b){d[0]=AMaxF1(a[0],b[0]);d[1]=AMaxF1(a[1],b[1]);d[2]=AMaxF1(a[2],b[2]);return d;} + A_STATIC retAF4 opAMaxF4(outAF4 d,inAF4 a,inAF4 b){d[0]=AMaxF1(a[0],b[0]);d[1]=AMaxF1(a[1],b[1]);d[2]=AMaxF1(a[2],b[2]);d[3]=AMaxF1(a[3],b[3]);return d;} +//============================================================================================================================== + A_STATIC retAD2 opAMinD2(outAD2 d,inAD2 a,inAD2 b){d[0]=AMinD1(a[0],b[0]);d[1]=AMinD1(a[1],b[1]);return d;} + A_STATIC retAD3 opAMinD3(outAD3 d,inAD3 a,inAD3 b){d[0]=AMinD1(a[0],b[0]);d[1]=AMinD1(a[1],b[1]);d[2]=AMinD1(a[2],b[2]);return d;} + A_STATIC retAD4 opAMinD4(outAD4 d,inAD4 a,inAD4 b){d[0]=AMinD1(a[0],b[0]);d[1]=AMinD1(a[1],b[1]);d[2]=AMinD1(a[2],b[2]);d[3]=AMinD1(a[3],b[3]);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opAMinF2(outAF2 d,inAF2 a,inAF2 b){d[0]=AMinF1(a[0],b[0]);d[1]=AMinF1(a[1],b[1]);return d;} + A_STATIC retAF3 opAMinF3(outAF3 d,inAF3 a,inAF3 b){d[0]=AMinF1(a[0],b[0]);d[1]=AMinF1(a[1],b[1]);d[2]=AMinF1(a[2],b[2]);return d;} + A_STATIC retAF4 opAMinF4(outAF4 d,inAF4 a,inAF4 b){d[0]=AMinF1(a[0],b[0]);d[1]=AMinF1(a[1],b[1]);d[2]=AMinF1(a[2],b[2]);d[3]=AMinF1(a[3],b[3]);return d;} +//============================================================================================================================== + A_STATIC retAD2 opAMulD2(outAD2 d,inAD2 a,inAD2 b){d[0]=a[0]*b[0];d[1]=a[1]*b[1];return d;} + A_STATIC retAD3 opAMulD3(outAD3 d,inAD3 a,inAD3 b){d[0]=a[0]*b[0];d[1]=a[1]*b[1];d[2]=a[2]*b[2];return d;} + A_STATIC retAD4 opAMulD4(outAD4 d,inAD4 a,inAD4 b){d[0]=a[0]*b[0];d[1]=a[1]*b[1];d[2]=a[2]*b[2];d[3]=a[3]*b[3];return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opAMulF2(outAF2 d,inAF2 a,inAF2 b){d[0]=a[0]*b[0];d[1]=a[1]*b[1];return d;} + A_STATIC retAF3 opAMulF3(outAF3 d,inAF3 a,inAF3 b){d[0]=a[0]*b[0];d[1]=a[1]*b[1];d[2]=a[2]*b[2];return d;} + A_STATIC retAF4 opAMulF4(outAF4 d,inAF4 a,inAF4 b){d[0]=a[0]*b[0];d[1]=a[1]*b[1];d[2]=a[2]*b[2];d[3]=a[3]*b[3];return d;} +//============================================================================================================================== + A_STATIC retAD2 opAMulOneD2(outAD2 d,inAD2 a,AD1 b){d[0]=a[0]*b;d[1]=a[1]*b;return d;} + A_STATIC retAD3 opAMulOneD3(outAD3 d,inAD3 a,AD1 b){d[0]=a[0]*b;d[1]=a[1]*b;d[2]=a[2]*b;return d;} + A_STATIC retAD4 opAMulOneD4(outAD4 d,inAD4 a,AD1 b){d[0]=a[0]*b;d[1]=a[1]*b;d[2]=a[2]*b;d[3]=a[3]*b;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opAMulOneF2(outAF2 d,inAF2 a,AF1 b){d[0]=a[0]*b;d[1]=a[1]*b;return d;} + A_STATIC retAF3 opAMulOneF3(outAF3 d,inAF3 a,AF1 b){d[0]=a[0]*b;d[1]=a[1]*b;d[2]=a[2]*b;return d;} + A_STATIC retAF4 opAMulOneF4(outAF4 d,inAF4 a,AF1 b){d[0]=a[0]*b;d[1]=a[1]*b;d[2]=a[2]*b;d[3]=a[3]*b;return d;} +//============================================================================================================================== + A_STATIC retAD2 opANegD2(outAD2 d,inAD2 a){d[0]=-a[0];d[1]=-a[1];return d;} + A_STATIC retAD3 opANegD3(outAD3 d,inAD3 a){d[0]=-a[0];d[1]=-a[1];d[2]=-a[2];return d;} + A_STATIC retAD4 opANegD4(outAD4 d,inAD4 a){d[0]=-a[0];d[1]=-a[1];d[2]=-a[2];d[3]=-a[3];return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opANegF2(outAF2 d,inAF2 a){d[0]=-a[0];d[1]=-a[1];return d;} + A_STATIC retAF3 opANegF3(outAF3 d,inAF3 a){d[0]=-a[0];d[1]=-a[1];d[2]=-a[2];return d;} + A_STATIC retAF4 opANegF4(outAF4 d,inAF4 a){d[0]=-a[0];d[1]=-a[1];d[2]=-a[2];d[3]=-a[3];return d;} +//============================================================================================================================== + A_STATIC retAD2 opARcpD2(outAD2 d,inAD2 a){d[0]=ARcpD1(a[0]);d[1]=ARcpD1(a[1]);return d;} + A_STATIC retAD3 opARcpD3(outAD3 d,inAD3 a){d[0]=ARcpD1(a[0]);d[1]=ARcpD1(a[1]);d[2]=ARcpD1(a[2]);return d;} + A_STATIC retAD4 opARcpD4(outAD4 d,inAD4 a){d[0]=ARcpD1(a[0]);d[1]=ARcpD1(a[1]);d[2]=ARcpD1(a[2]);d[3]=ARcpD1(a[3]);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + A_STATIC retAF2 opARcpF2(outAF2 d,inAF2 a){d[0]=ARcpF1(a[0]);d[1]=ARcpF1(a[1]);return d;} + A_STATIC retAF3 opARcpF3(outAF3 d,inAF3 a){d[0]=ARcpF1(a[0]);d[1]=ARcpF1(a[1]);d[2]=ARcpF1(a[2]);return d;} + A_STATIC retAF4 opARcpF4(outAF4 d,inAF4 a){d[0]=ARcpF1(a[0]);d[1]=ARcpF1(a[1]);d[2]=ARcpF1(a[2]);d[3]=ARcpF1(a[3]);return d;} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// HALF FLOAT PACKING +//============================================================================================================================== + // Convert float to half (in lower 16-bits of output). + // Same fast technique as documented here: ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf + // Supports denormals. + // Conversion rules are to make computations possibly "safer" on the GPU, + // -INF & -NaN -> -65504 + // +INF & +NaN -> +65504 + A_STATIC AU1 AU1_AH1_AF1(AF1 f){ + static AW1 base[512]={ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,0x0100, + 0x0200,0x0400,0x0800,0x0c00,0x1000,0x1400,0x1800,0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00, + 0x4000,0x4400,0x4800,0x4c00,0x5000,0x5400,0x5800,0x5c00,0x6000,0x6400,0x6800,0x6c00,0x7000,0x7400,0x7800,0x7bff, + 0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff, + 0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff, + 0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff, + 0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff, + 0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff, + 0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff, + 0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff,0x7bff, + 0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, + 0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, + 0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, + 0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, + 0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, + 0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, + 0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8001,0x8002,0x8004,0x8008,0x8010,0x8020,0x8040,0x8080,0x8100, + 0x8200,0x8400,0x8800,0x8c00,0x9000,0x9400,0x9800,0x9c00,0xa000,0xa400,0xa800,0xac00,0xb000,0xb400,0xb800,0xbc00, + 0xc000,0xc400,0xc800,0xcc00,0xd000,0xd400,0xd800,0xdc00,0xe000,0xe400,0xe800,0xec00,0xf000,0xf400,0xf800,0xfbff, + 0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff, + 0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff, + 0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff, + 0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff, + 0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff, + 0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff, + 0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff,0xfbff}; + static AB1 shift[512]={ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x0f, + 0x0e,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d, + 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,0x0f, + 0x0e,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d, + 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18}; + union{AF1 f;AU1 u;}bits;bits.f=f;AU1 u=bits.u;AU1 i=u>>23;return (AU1)(base[i])+((u&0x7fffff)>>shift[i]);} +//------------------------------------------------------------------------------------------------------------------------------ + // Used to output packed constant. + A_STATIC AU1 AU1_AH2_AF2(inAF2 a){return AU1_AH1_AF1(a[0])+(AU1_AH1_AF1(a[1])<<16);} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// +// GLSL +// +// +//============================================================================================================================== +#if defined(A_GLSL) && defined(A_GPU) + #ifndef A_SKIP_EXT + #ifdef A_HALF + #extension GL_EXT_shader_16bit_storage:require + #extension GL_EXT_shader_explicit_arithmetic_types:require + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_LONG + #extension GL_ARB_gpu_shader_int64:require + #extension GL_NV_shader_atomic_int64:require + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_WAVE + #extension GL_KHR_shader_subgroup_arithmetic:require + #extension GL_KHR_shader_subgroup_ballot:require + #extension GL_KHR_shader_subgroup_quad:require + #extension GL_KHR_shader_subgroup_shuffle:require + #endif + #endif +//============================================================================================================================== + #define AP1 bool + #define AP2 bvec2 + #define AP3 bvec3 + #define AP4 bvec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AF1 float + #define AF2 vec2 + #define AF3 vec3 + #define AF4 vec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AU1 uint + #define AU2 uvec2 + #define AU3 uvec3 + #define AU4 uvec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASU1 int + #define ASU2 ivec2 + #define ASU3 ivec3 + #define ASU4 ivec4 +//============================================================================================================================== + #define AF1_AU1(x) uintBitsToFloat(AU1(x)) + #define AF2_AU2(x) uintBitsToFloat(AU2(x)) + #define AF3_AU3(x) uintBitsToFloat(AU3(x)) + #define AF4_AU4(x) uintBitsToFloat(AU4(x)) +//------------------------------------------------------------------------------------------------------------------------------ + #define AU1_AF1(x) floatBitsToUint(AF1(x)) + #define AU2_AF2(x) floatBitsToUint(AF2(x)) + #define AU3_AF3(x) floatBitsToUint(AF3(x)) + #define AU4_AF4(x) floatBitsToUint(AF4(x)) +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AU1_AH1_AF1_x(AF1 a){return packHalf2x16(AF2(a,0.0));} + #define AU1_AH1_AF1(a) AU1_AH1_AF1_x(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define AU1_AH2_AF2 packHalf2x16 + #define AU1_AW2Unorm_AF2 packUnorm2x16 + #define AU1_AB4Unorm_AF4 packUnorm4x8 +//------------------------------------------------------------------------------------------------------------------------------ + #define AF2_AH2_AU1 unpackHalf2x16 + #define AF2_AW2Unorm_AU1 unpackUnorm2x16 + #define AF4_AB4Unorm_AU1 unpackUnorm4x8 +//============================================================================================================================== + AF1 AF1_x(AF1 a){return AF1(a);} + AF2 AF2_x(AF1 a){return AF2(a,a);} + AF3 AF3_x(AF1 a){return AF3(a,a,a);} + AF4 AF4_x(AF1 a){return AF4(a,a,a,a);} + #define AF1_(a) AF1_x(AF1(a)) + #define AF2_(a) AF2_x(AF1(a)) + #define AF3_(a) AF3_x(AF1(a)) + #define AF4_(a) AF4_x(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AU1_x(AU1 a){return AU1(a);} + AU2 AU2_x(AU1 a){return AU2(a,a);} + AU3 AU3_x(AU1 a){return AU3(a,a,a);} + AU4 AU4_x(AU1 a){return AU4(a,a,a,a);} + #define AU1_(a) AU1_x(AU1(a)) + #define AU2_(a) AU2_x(AU1(a)) + #define AU3_(a) AU3_x(AU1(a)) + #define AU4_(a) AU4_x(AU1(a)) +//============================================================================================================================== + AU1 AAbsSU1(AU1 a){return AU1(abs(ASU1(a)));} + AU2 AAbsSU2(AU2 a){return AU2(abs(ASU2(a)));} + AU3 AAbsSU3(AU3 a){return AU3(abs(ASU3(a)));} + AU4 AAbsSU4(AU4 a){return AU4(abs(ASU4(a)));} +//------------------------------------------------------------------------------------------------------------------------------ + AU1 ABfe(AU1 src,AU1 off,AU1 bits){return bitfieldExtract(src,ASU1(off),ASU1(bits));} + AU1 ABfi(AU1 src,AU1 ins,AU1 mask){return (ins&mask)|(src&(~mask));} + // Proxy for V_BFI_B32 where the 'mask' is set as 'bits', 'mask=(1<>ASU1(b));} + AU2 AShrSU2(AU2 a,AU2 b){return AU2(ASU2(a)>>ASU2(b));} + AU3 AShrSU3(AU3 a,AU3 b){return AU3(ASU3(a)>>ASU3(b));} + AU4 AShrSU4(AU4 a,AU4 b){return AU4(ASU4(a)>>ASU4(b));} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// GLSL BYTE +//============================================================================================================================== + #ifdef A_BYTE + #define AB1 uint8_t + #define AB2 u8vec2 + #define AB3 u8vec3 + #define AB4 u8vec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASB1 int8_t + #define ASB2 i8vec2 + #define ASB3 i8vec3 + #define ASB4 i8vec4 +//------------------------------------------------------------------------------------------------------------------------------ + AB1 AB1_x(AB1 a){return AB1(a);} + AB2 AB2_x(AB1 a){return AB2(a,a);} + AB3 AB3_x(AB1 a){return AB3(a,a,a);} + AB4 AB4_x(AB1 a){return AB4(a,a,a,a);} + #define AB1_(a) AB1_x(AB1(a)) + #define AB2_(a) AB2_x(AB1(a)) + #define AB3_(a) AB3_x(AB1(a)) + #define AB4_(a) AB4_x(AB1(a)) + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// GLSL HALF +//============================================================================================================================== + #ifdef A_HALF + #define AH1 float16_t + #define AH2 f16vec2 + #define AH3 f16vec3 + #define AH4 f16vec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AW1 uint16_t + #define AW2 u16vec2 + #define AW3 u16vec3 + #define AW4 u16vec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASW1 int16_t + #define ASW2 i16vec2 + #define ASW3 i16vec3 + #define ASW4 i16vec4 +//============================================================================================================================== + #define AH2_AU1(x) unpackFloat2x16(AU1(x)) + AH4 AH4_AU2_x(AU2 x){return AH4(unpackFloat2x16(x.x),unpackFloat2x16(x.y));} + #define AH4_AU2(x) AH4_AU2_x(AU2(x)) + #define AW2_AU1(x) unpackUint2x16(AU1(x)) + #define AW4_AU2(x) unpackUint4x16(pack64(AU2(x))) +//------------------------------------------------------------------------------------------------------------------------------ + #define AU1_AH2(x) packFloat2x16(AH2(x)) + AU2 AU2_AH4_x(AH4 x){return AU2(packFloat2x16(x.xy),packFloat2x16(x.zw));} + #define AU2_AH4(x) AU2_AH4_x(AH4(x)) + #define AU1_AW2(x) packUint2x16(AW2(x)) + #define AU2_AW4(x) unpack32(packUint4x16(AW4(x))) +//============================================================================================================================== + #define AW1_AH1(x) halfBitsToUint16(AH1(x)) + #define AW2_AH2(x) halfBitsToUint16(AH2(x)) + #define AW3_AH3(x) halfBitsToUint16(AH3(x)) + #define AW4_AH4(x) halfBitsToUint16(AH4(x)) +//------------------------------------------------------------------------------------------------------------------------------ + #define AH1_AW1(x) uint16BitsToHalf(AW1(x)) + #define AH2_AW2(x) uint16BitsToHalf(AW2(x)) + #define AH3_AW3(x) uint16BitsToHalf(AW3(x)) + #define AH4_AW4(x) uint16BitsToHalf(AW4(x)) +//============================================================================================================================== + AH1 AH1_x(AH1 a){return AH1(a);} + AH2 AH2_x(AH1 a){return AH2(a,a);} + AH3 AH3_x(AH1 a){return AH3(a,a,a);} + AH4 AH4_x(AH1 a){return AH4(a,a,a,a);} + #define AH1_(a) AH1_x(AH1(a)) + #define AH2_(a) AH2_x(AH1(a)) + #define AH3_(a) AH3_x(AH1(a)) + #define AH4_(a) AH4_x(AH1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AW1_x(AW1 a){return AW1(a);} + AW2 AW2_x(AW1 a){return AW2(a,a);} + AW3 AW3_x(AW1 a){return AW3(a,a,a);} + AW4 AW4_x(AW1 a){return AW4(a,a,a,a);} + #define AW1_(a) AW1_x(AW1(a)) + #define AW2_(a) AW2_x(AW1(a)) + #define AW3_(a) AW3_x(AW1(a)) + #define AW4_(a) AW4_x(AW1(a)) +//============================================================================================================================== + AW1 AAbsSW1(AW1 a){return AW1(abs(ASW1(a)));} + AW2 AAbsSW2(AW2 a){return AW2(abs(ASW2(a)));} + AW3 AAbsSW3(AW3 a){return AW3(abs(ASW3(a)));} + AW4 AAbsSW4(AW4 a){return AW4(abs(ASW4(a)));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AClampH1(AH1 x,AH1 n,AH1 m){return clamp(x,n,m);} + AH2 AClampH2(AH2 x,AH2 n,AH2 m){return clamp(x,n,m);} + AH3 AClampH3(AH3 x,AH3 n,AH3 m){return clamp(x,n,m);} + AH4 AClampH4(AH4 x,AH4 n,AH4 m){return clamp(x,n,m);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AFractH1(AH1 x){return fract(x);} + AH2 AFractH2(AH2 x){return fract(x);} + AH3 AFractH3(AH3 x){return fract(x);} + AH4 AFractH4(AH4 x){return fract(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ALerpH1(AH1 x,AH1 y,AH1 a){return mix(x,y,a);} + AH2 ALerpH2(AH2 x,AH2 y,AH2 a){return mix(x,y,a);} + AH3 ALerpH3(AH3 x,AH3 y,AH3 a){return mix(x,y,a);} + AH4 ALerpH4(AH4 x,AH4 y,AH4 a){return mix(x,y,a);} +//------------------------------------------------------------------------------------------------------------------------------ + // No packed version of max3. + AH1 AMax3H1(AH1 x,AH1 y,AH1 z){return max(x,max(y,z));} + AH2 AMax3H2(AH2 x,AH2 y,AH2 z){return max(x,max(y,z));} + AH3 AMax3H3(AH3 x,AH3 y,AH3 z){return max(x,max(y,z));} + AH4 AMax3H4(AH4 x,AH4 y,AH4 z){return max(x,max(y,z));} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AMaxSW1(AW1 a,AW1 b){return AW1(max(ASU1(a),ASU1(b)));} + AW2 AMaxSW2(AW2 a,AW2 b){return AW2(max(ASU2(a),ASU2(b)));} + AW3 AMaxSW3(AW3 a,AW3 b){return AW3(max(ASU3(a),ASU3(b)));} + AW4 AMaxSW4(AW4 a,AW4 b){return AW4(max(ASU4(a),ASU4(b)));} +//------------------------------------------------------------------------------------------------------------------------------ + // No packed version of min3. + AH1 AMin3H1(AH1 x,AH1 y,AH1 z){return min(x,min(y,z));} + AH2 AMin3H2(AH2 x,AH2 y,AH2 z){return min(x,min(y,z));} + AH3 AMin3H3(AH3 x,AH3 y,AH3 z){return min(x,min(y,z));} + AH4 AMin3H4(AH4 x,AH4 y,AH4 z){return min(x,min(y,z));} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AMinSW1(AW1 a,AW1 b){return AW1(min(ASU1(a),ASU1(b)));} + AW2 AMinSW2(AW2 a,AW2 b){return AW2(min(ASU2(a),ASU2(b)));} + AW3 AMinSW3(AW3 a,AW3 b){return AW3(min(ASU3(a),ASU3(b)));} + AW4 AMinSW4(AW4 a,AW4 b){return AW4(min(ASU4(a),ASU4(b)));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ARcpH1(AH1 x){return AH1_(1.0)/x;} + AH2 ARcpH2(AH2 x){return AH2_(1.0)/x;} + AH3 ARcpH3(AH3 x){return AH3_(1.0)/x;} + AH4 ARcpH4(AH4 x){return AH4_(1.0)/x;} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ARsqH1(AH1 x){return AH1_(1.0)/sqrt(x);} + AH2 ARsqH2(AH2 x){return AH2_(1.0)/sqrt(x);} + AH3 ARsqH3(AH3 x){return AH3_(1.0)/sqrt(x);} + AH4 ARsqH4(AH4 x){return AH4_(1.0)/sqrt(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ASatH1(AH1 x){return clamp(x,AH1_(0.0),AH1_(1.0));} + AH2 ASatH2(AH2 x){return clamp(x,AH2_(0.0),AH2_(1.0));} + AH3 ASatH3(AH3 x){return clamp(x,AH3_(0.0),AH3_(1.0));} + AH4 ASatH4(AH4 x){return clamp(x,AH4_(0.0),AH4_(1.0));} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AShrSW1(AW1 a,AW1 b){return AW1(ASW1(a)>>ASW1(b));} + AW2 AShrSW2(AW2 a,AW2 b){return AW2(ASW2(a)>>ASW2(b));} + AW3 AShrSW3(AW3 a,AW3 b){return AW3(ASW3(a)>>ASW3(b));} + AW4 AShrSW4(AW4 a,AW4 b){return AW4(ASW4(a)>>ASW4(b));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// GLSL DOUBLE +//============================================================================================================================== + #ifdef A_DUBL + #define AD1 double + #define AD2 dvec2 + #define AD3 dvec3 + #define AD4 dvec4 +//------------------------------------------------------------------------------------------------------------------------------ + AD1 AD1_x(AD1 a){return AD1(a);} + AD2 AD2_x(AD1 a){return AD2(a,a);} + AD3 AD3_x(AD1 a){return AD3(a,a,a);} + AD4 AD4_x(AD1 a){return AD4(a,a,a,a);} + #define AD1_(a) AD1_x(AD1(a)) + #define AD2_(a) AD2_x(AD1(a)) + #define AD3_(a) AD3_x(AD1(a)) + #define AD4_(a) AD4_x(AD1(a)) +//============================================================================================================================== + AD1 AFractD1(AD1 x){return fract(x);} + AD2 AFractD2(AD2 x){return fract(x);} + AD3 AFractD3(AD3 x){return fract(x);} + AD4 AFractD4(AD4 x){return fract(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ALerpD1(AD1 x,AD1 y,AD1 a){return mix(x,y,a);} + AD2 ALerpD2(AD2 x,AD2 y,AD2 a){return mix(x,y,a);} + AD3 ALerpD3(AD3 x,AD3 y,AD3 a){return mix(x,y,a);} + AD4 ALerpD4(AD4 x,AD4 y,AD4 a){return mix(x,y,a);} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ARcpD1(AD1 x){return AD1_(1.0)/x;} + AD2 ARcpD2(AD2 x){return AD2_(1.0)/x;} + AD3 ARcpD3(AD3 x){return AD3_(1.0)/x;} + AD4 ARcpD4(AD4 x){return AD4_(1.0)/x;} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ARsqD1(AD1 x){return AD1_(1.0)/sqrt(x);} + AD2 ARsqD2(AD2 x){return AD2_(1.0)/sqrt(x);} + AD3 ARsqD3(AD3 x){return AD3_(1.0)/sqrt(x);} + AD4 ARsqD4(AD4 x){return AD4_(1.0)/sqrt(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ASatD1(AD1 x){return clamp(x,AD1_(0.0),AD1_(1.0));} + AD2 ASatD2(AD2 x){return clamp(x,AD2_(0.0),AD2_(1.0));} + AD3 ASatD3(AD3 x){return clamp(x,AD3_(0.0),AD3_(1.0));} + AD4 ASatD4(AD4 x){return clamp(x,AD4_(0.0),AD4_(1.0));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// GLSL LONG +//============================================================================================================================== + #ifdef A_LONG + #define AL1 uint64_t + #define AL2 u64vec2 + #define AL3 u64vec3 + #define AL4 u64vec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASL1 int64_t + #define ASL2 i64vec2 + #define ASL3 i64vec3 + #define ASL4 i64vec4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AL1_AU2(x) packUint2x32(AU2(x)) + #define AU2_AL1(x) unpackUint2x32(AL1(x)) +//------------------------------------------------------------------------------------------------------------------------------ + AL1 AL1_x(AL1 a){return AL1(a);} + AL2 AL2_x(AL1 a){return AL2(a,a);} + AL3 AL3_x(AL1 a){return AL3(a,a,a);} + AL4 AL4_x(AL1 a){return AL4(a,a,a,a);} + #define AL1_(a) AL1_x(AL1(a)) + #define AL2_(a) AL2_x(AL1(a)) + #define AL3_(a) AL3_x(AL1(a)) + #define AL4_(a) AL4_x(AL1(a)) +//============================================================================================================================== + AL1 AAbsSL1(AL1 a){return AL1(abs(ASL1(a)));} + AL2 AAbsSL2(AL2 a){return AL2(abs(ASL2(a)));} + AL3 AAbsSL3(AL3 a){return AL3(abs(ASL3(a)));} + AL4 AAbsSL4(AL4 a){return AL4(abs(ASL4(a)));} +//------------------------------------------------------------------------------------------------------------------------------ + AL1 AMaxSL1(AL1 a,AL1 b){return AL1(max(ASU1(a),ASU1(b)));} + AL2 AMaxSL2(AL2 a,AL2 b){return AL2(max(ASU2(a),ASU2(b)));} + AL3 AMaxSL3(AL3 a,AL3 b){return AL3(max(ASU3(a),ASU3(b)));} + AL4 AMaxSL4(AL4 a,AL4 b){return AL4(max(ASU4(a),ASU4(b)));} +//------------------------------------------------------------------------------------------------------------------------------ + AL1 AMinSL1(AL1 a,AL1 b){return AL1(min(ASU1(a),ASU1(b)));} + AL2 AMinSL2(AL2 a,AL2 b){return AL2(min(ASU2(a),ASU2(b)));} + AL3 AMinSL3(AL3 a,AL3 b){return AL3(min(ASU3(a),ASU3(b)));} + AL4 AMinSL4(AL4 a,AL4 b){return AL4(min(ASU4(a),ASU4(b)));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// WAVE OPERATIONS +//============================================================================================================================== + #ifdef A_WAVE + // Where 'x' must be a compile time literal. + AF1 AWaveXorF1(AF1 v,AU1 x){return subgroupShuffleXor(v,x);} + AF2 AWaveXorF2(AF2 v,AU1 x){return subgroupShuffleXor(v,x);} + AF3 AWaveXorF3(AF3 v,AU1 x){return subgroupShuffleXor(v,x);} + AF4 AWaveXorF4(AF4 v,AU1 x){return subgroupShuffleXor(v,x);} + AU1 AWaveXorU1(AU1 v,AU1 x){return subgroupShuffleXor(v,x);} + AU2 AWaveXorU2(AU2 v,AU1 x){return subgroupShuffleXor(v,x);} + AU3 AWaveXorU3(AU3 v,AU1 x){return subgroupShuffleXor(v,x);} + AU4 AWaveXorU4(AU4 v,AU1 x){return subgroupShuffleXor(v,x);} +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_HALF + AH2 AWaveXorH2(AH2 v,AU1 x){return AH2_AU1(subgroupShuffleXor(AU1_AH2(v),x));} + AH4 AWaveXorH4(AH4 v,AU1 x){return AH4_AU2(subgroupShuffleXor(AU2_AH4(v),x));} + AW2 AWaveXorW2(AW2 v,AU1 x){return AW2_AU1(subgroupShuffleXor(AU1_AW2(v),x));} + AW4 AWaveXorW4(AW4 v,AU1 x){return AW4_AU2(subgroupShuffleXor(AU2_AW4(v),x));} + #endif + #endif +//============================================================================================================================== +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// +// HLSL +// +// +//============================================================================================================================== +#if defined(A_HLSL) && defined(A_GPU) + #ifdef A_HLSL_6_2 + #define AP1 bool + #define AP2 bool2 + #define AP3 bool3 + #define AP4 bool4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AF1 float32_t + #define AF2 float32_t2 + #define AF3 float32_t3 + #define AF4 float32_t4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AU1 uint32_t + #define AU2 uint32_t2 + #define AU3 uint32_t3 + #define AU4 uint32_t4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASU1 int32_t + #define ASU2 int32_t2 + #define ASU3 int32_t3 + #define ASU4 int32_t4 + #else + #define AP1 bool + #define AP2 bool2 + #define AP3 bool3 + #define AP4 bool4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AF1 float + #define AF2 float2 + #define AF3 float3 + #define AF4 float4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AU1 uint + #define AU2 uint2 + #define AU3 uint3 + #define AU4 uint4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASU1 int + #define ASU2 int2 + #define ASU3 int3 + #define ASU4 int4 + #endif +//============================================================================================================================== + #define AF1_AU1(x) asfloat(AU1(x)) + #define AF2_AU2(x) asfloat(AU2(x)) + #define AF3_AU3(x) asfloat(AU3(x)) + #define AF4_AU4(x) asfloat(AU4(x)) +//------------------------------------------------------------------------------------------------------------------------------ + #define AU1_AF1(x) asuint(AF1(x)) + #define AU2_AF2(x) asuint(AF2(x)) + #define AU3_AF3(x) asuint(AF3(x)) + #define AU4_AF4(x) asuint(AF4(x)) +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AU1_AH1_AF1_x(AF1 a){return f32tof16(a);} + #define AU1_AH1_AF1(a) AU1_AH1_AF1_x(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AU1_AH2_AF2_x(AF2 a){return f32tof16(a.x)|(f32tof16(a.y)<<16);} + #define AU1_AH2_AF2(a) AU1_AH2_AF2_x(AF2(a)) + #define AU1_AB4Unorm_AF4(x) D3DCOLORtoUBYTE4(AF4(x)) +//------------------------------------------------------------------------------------------------------------------------------ + AF2 AF2_AH2_AU1_x(AU1 x){return AF2(f16tof32(x&0xFFFF),f16tof32(x>>16));} + #define AF2_AH2_AU1(x) AF2_AH2_AU1_x(AU1(x)) +//============================================================================================================================== + AF1 AF1_x(AF1 a){return AF1(a);} + AF2 AF2_x(AF1 a){return AF2(a,a);} + AF3 AF3_x(AF1 a){return AF3(a,a,a);} + AF4 AF4_x(AF1 a){return AF4(a,a,a,a);} + #define AF1_(a) AF1_x(AF1(a)) + #define AF2_(a) AF2_x(AF1(a)) + #define AF3_(a) AF3_x(AF1(a)) + #define AF4_(a) AF4_x(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AU1_x(AU1 a){return AU1(a);} + AU2 AU2_x(AU1 a){return AU2(a,a);} + AU3 AU3_x(AU1 a){return AU3(a,a,a);} + AU4 AU4_x(AU1 a){return AU4(a,a,a,a);} + #define AU1_(a) AU1_x(AU1(a)) + #define AU2_(a) AU2_x(AU1(a)) + #define AU3_(a) AU3_x(AU1(a)) + #define AU4_(a) AU4_x(AU1(a)) +//============================================================================================================================== + AU1 AAbsSU1(AU1 a){return AU1(abs(ASU1(a)));} + AU2 AAbsSU2(AU2 a){return AU2(abs(ASU2(a)));} + AU3 AAbsSU3(AU3 a){return AU3(abs(ASU3(a)));} + AU4 AAbsSU4(AU4 a){return AU4(abs(ASU4(a)));} +//------------------------------------------------------------------------------------------------------------------------------ + AU1 ABfe(AU1 src,AU1 off,AU1 bits){AU1 mask=(1u<>off)&mask;} + AU1 ABfi(AU1 src,AU1 ins,AU1 mask){return (ins&mask)|(src&(~mask));} + AU1 ABfiM(AU1 src,AU1 ins,AU1 bits){AU1 mask=(1u<>ASU1(b));} + AU2 AShrSU2(AU2 a,AU2 b){return AU2(ASU2(a)>>ASU2(b));} + AU3 AShrSU3(AU3 a,AU3 b){return AU3(ASU3(a)>>ASU3(b));} + AU4 AShrSU4(AU4 a,AU4 b){return AU4(ASU4(a)>>ASU4(b));} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// HLSL BYTE +//============================================================================================================================== + #ifdef A_BYTE + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// HLSL HALF +//============================================================================================================================== + #ifdef A_HALF + #ifdef A_HLSL_6_2 + #define AH1 float16_t + #define AH2 float16_t2 + #define AH3 float16_t3 + #define AH4 float16_t4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AW1 uint16_t + #define AW2 uint16_t2 + #define AW3 uint16_t3 + #define AW4 uint16_t4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASW1 int16_t + #define ASW2 int16_t2 + #define ASW3 int16_t3 + #define ASW4 int16_t4 + #else + #define AH1 min16float + #define AH2 min16float2 + #define AH3 min16float3 + #define AH4 min16float4 +//------------------------------------------------------------------------------------------------------------------------------ + #define AW1 min16uint + #define AW2 min16uint2 + #define AW3 min16uint3 + #define AW4 min16uint4 +//------------------------------------------------------------------------------------------------------------------------------ + #define ASW1 min16int + #define ASW2 min16int2 + #define ASW3 min16int3 + #define ASW4 min16int4 + #endif +//============================================================================================================================== + // Need to use manual unpack to get optimal execution (don't use packed types in buffers directly). + // Unpack requires this pattern: https://gpuopen.com/first-steps-implementing-fp16/ + AH2 AH2_AU1_x(AU1 x){AF2 t=f16tof32(AU2(x&0xFFFF,x>>16));return AH2(t);} + AH4 AH4_AU2_x(AU2 x){return AH4(AH2_AU1_x(x.x),AH2_AU1_x(x.y));} + AW2 AW2_AU1_x(AU1 x){AU2 t=AU2(x&0xFFFF,x>>16);return AW2(t);} + AW4 AW4_AU2_x(AU2 x){return AW4(AW2_AU1_x(x.x),AW2_AU1_x(x.y));} + #define AH2_AU1(x) AH2_AU1_x(AU1(x)) + #define AH4_AU2(x) AH4_AU2_x(AU2(x)) + #define AW2_AU1(x) AW2_AU1_x(AU1(x)) + #define AW4_AU2(x) AW4_AU2_x(AU2(x)) +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AU1_AH2_x(AH2 x){return f32tof16(x.x)+(f32tof16(x.y)<<16);} + AU2 AU2_AH4_x(AH4 x){return AU2(AU1_AH2_x(x.xy),AU1_AH2_x(x.zw));} + AU1 AU1_AW2_x(AW2 x){return AU1(x.x)+(AU1(x.y)<<16);} + AU2 AU2_AW4_x(AW4 x){return AU2(AU1_AW2_x(x.xy),AU1_AW2_x(x.zw));} + #define AU1_AH2(x) AU1_AH2_x(AH2(x)) + #define AU2_AH4(x) AU2_AH4_x(AH4(x)) + #define AU1_AW2(x) AU1_AW2_x(AW2(x)) + #define AU2_AW4(x) AU2_AW4_x(AW4(x)) +//============================================================================================================================== + #if defined(A_HLSL_6_2) && !defined(A_NO_16_BIT_CAST) + #define AW1_AH1(x) asuint16(x) + #define AW2_AH2(x) asuint16(x) + #define AW3_AH3(x) asuint16(x) + #define AW4_AH4(x) asuint16(x) + #else + #define AW1_AH1(a) AW1(f32tof16(AF1(a))) + #define AW2_AH2(a) AW2(AW1_AH1((a).x),AW1_AH1((a).y)) + #define AW3_AH3(a) AW3(AW1_AH1((a).x),AW1_AH1((a).y),AW1_AH1((a).z)) + #define AW4_AH4(a) AW4(AW1_AH1((a).x),AW1_AH1((a).y),AW1_AH1((a).z),AW1_AH1((a).w)) + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #if defined(A_HLSL_6_2) && !defined(A_NO_16_BIT_CAST) + #define AH1_AW1(x) asfloat16(x) + #define AH2_AW2(x) asfloat16(x) + #define AH3_AW3(x) asfloat16(x) + #define AH4_AW4(x) asfloat16(x) + #else + #define AH1_AW1(a) AH1(f16tof32(AU1(a))) + #define AH2_AW2(a) AH2(AH1_AW1((a).x),AH1_AW1((a).y)) + #define AH3_AW3(a) AH3(AH1_AW1((a).x),AH1_AW1((a).y),AH1_AW1((a).z)) + #define AH4_AW4(a) AH4(AH1_AW1((a).x),AH1_AW1((a).y),AH1_AW1((a).z),AH1_AW1((a).w)) + #endif +//============================================================================================================================== + AH1 AH1_x(AH1 a){return AH1(a);} + AH2 AH2_x(AH1 a){return AH2(a,a);} + AH3 AH3_x(AH1 a){return AH3(a,a,a);} + AH4 AH4_x(AH1 a){return AH4(a,a,a,a);} + #define AH1_(a) AH1_x(AH1(a)) + #define AH2_(a) AH2_x(AH1(a)) + #define AH3_(a) AH3_x(AH1(a)) + #define AH4_(a) AH4_x(AH1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AW1_x(AW1 a){return AW1(a);} + AW2 AW2_x(AW1 a){return AW2(a,a);} + AW3 AW3_x(AW1 a){return AW3(a,a,a);} + AW4 AW4_x(AW1 a){return AW4(a,a,a,a);} + #define AW1_(a) AW1_x(AW1(a)) + #define AW2_(a) AW2_x(AW1(a)) + #define AW3_(a) AW3_x(AW1(a)) + #define AW4_(a) AW4_x(AW1(a)) +//============================================================================================================================== + AW1 AAbsSW1(AW1 a){return AW1(abs(ASW1(a)));} + AW2 AAbsSW2(AW2 a){return AW2(abs(ASW2(a)));} + AW3 AAbsSW3(AW3 a){return AW3(abs(ASW3(a)));} + AW4 AAbsSW4(AW4 a){return AW4(abs(ASW4(a)));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AClampH1(AH1 x,AH1 n,AH1 m){return max(n,min(x,m));} + AH2 AClampH2(AH2 x,AH2 n,AH2 m){return max(n,min(x,m));} + AH3 AClampH3(AH3 x,AH3 n,AH3 m){return max(n,min(x,m));} + AH4 AClampH4(AH4 x,AH4 n,AH4 m){return max(n,min(x,m));} +//------------------------------------------------------------------------------------------------------------------------------ + // V_FRACT_F16 (note DX frac() is different). + AH1 AFractH1(AH1 x){return x-floor(x);} + AH2 AFractH2(AH2 x){return x-floor(x);} + AH3 AFractH3(AH3 x){return x-floor(x);} + AH4 AFractH4(AH4 x){return x-floor(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ALerpH1(AH1 x,AH1 y,AH1 a){return lerp(x,y,a);} + AH2 ALerpH2(AH2 x,AH2 y,AH2 a){return lerp(x,y,a);} + AH3 ALerpH3(AH3 x,AH3 y,AH3 a){return lerp(x,y,a);} + AH4 ALerpH4(AH4 x,AH4 y,AH4 a){return lerp(x,y,a);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AMax3H1(AH1 x,AH1 y,AH1 z){return max(x,max(y,z));} + AH2 AMax3H2(AH2 x,AH2 y,AH2 z){return max(x,max(y,z));} + AH3 AMax3H3(AH3 x,AH3 y,AH3 z){return max(x,max(y,z));} + AH4 AMax3H4(AH4 x,AH4 y,AH4 z){return max(x,max(y,z));} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AMaxSW1(AW1 a,AW1 b){return AW1(max(ASU1(a),ASU1(b)));} + AW2 AMaxSW2(AW2 a,AW2 b){return AW2(max(ASU2(a),ASU2(b)));} + AW3 AMaxSW3(AW3 a,AW3 b){return AW3(max(ASU3(a),ASU3(b)));} + AW4 AMaxSW4(AW4 a,AW4 b){return AW4(max(ASU4(a),ASU4(b)));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AMin3H1(AH1 x,AH1 y,AH1 z){return min(x,min(y,z));} + AH2 AMin3H2(AH2 x,AH2 y,AH2 z){return min(x,min(y,z));} + AH3 AMin3H3(AH3 x,AH3 y,AH3 z){return min(x,min(y,z));} + AH4 AMin3H4(AH4 x,AH4 y,AH4 z){return min(x,min(y,z));} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AMinSW1(AW1 a,AW1 b){return AW1(min(ASU1(a),ASU1(b)));} + AW2 AMinSW2(AW2 a,AW2 b){return AW2(min(ASU2(a),ASU2(b)));} + AW3 AMinSW3(AW3 a,AW3 b){return AW3(min(ASU3(a),ASU3(b)));} + AW4 AMinSW4(AW4 a,AW4 b){return AW4(min(ASU4(a),ASU4(b)));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ARcpH1(AH1 x){return rcp(x);} + AH2 ARcpH2(AH2 x){return rcp(x);} + AH3 ARcpH3(AH3 x){return rcp(x);} + AH4 ARcpH4(AH4 x){return rcp(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ARsqH1(AH1 x){return rsqrt(x);} + AH2 ARsqH2(AH2 x){return rsqrt(x);} + AH3 ARsqH3(AH3 x){return rsqrt(x);} + AH4 ARsqH4(AH4 x){return rsqrt(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ASatH1(AH1 x){return saturate(x);} + AH2 ASatH2(AH2 x){return saturate(x);} + AH3 ASatH3(AH3 x){return saturate(x);} + AH4 ASatH4(AH4 x){return saturate(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AShrSW1(AW1 a,AW1 b){return AW1(ASW1(a)>>ASW1(b));} + AW2 AShrSW2(AW2 a,AW2 b){return AW2(ASW2(a)>>ASW2(b));} + AW3 AShrSW3(AW3 a,AW3 b){return AW3(ASW3(a)>>ASW3(b));} + AW4 AShrSW4(AW4 a,AW4 b){return AW4(ASW4(a)>>ASW4(b));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// HLSL DOUBLE +//============================================================================================================================== + #ifdef A_DUBL + #ifdef A_HLSL_6_2 + #define AD1 float64_t + #define AD2 float64_t2 + #define AD3 float64_t3 + #define AD4 float64_t4 + #else + #define AD1 double + #define AD2 double2 + #define AD3 double3 + #define AD4 double4 + #endif +//------------------------------------------------------------------------------------------------------------------------------ + AD1 AD1_x(AD1 a){return AD1(a);} + AD2 AD2_x(AD1 a){return AD2(a,a);} + AD3 AD3_x(AD1 a){return AD3(a,a,a);} + AD4 AD4_x(AD1 a){return AD4(a,a,a,a);} + #define AD1_(a) AD1_x(AD1(a)) + #define AD2_(a) AD2_x(AD1(a)) + #define AD3_(a) AD3_x(AD1(a)) + #define AD4_(a) AD4_x(AD1(a)) +//============================================================================================================================== + AD1 AFractD1(AD1 a){return a-floor(a);} + AD2 AFractD2(AD2 a){return a-floor(a);} + AD3 AFractD3(AD3 a){return a-floor(a);} + AD4 AFractD4(AD4 a){return a-floor(a);} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ALerpD1(AD1 x,AD1 y,AD1 a){return lerp(x,y,a);} + AD2 ALerpD2(AD2 x,AD2 y,AD2 a){return lerp(x,y,a);} + AD3 ALerpD3(AD3 x,AD3 y,AD3 a){return lerp(x,y,a);} + AD4 ALerpD4(AD4 x,AD4 y,AD4 a){return lerp(x,y,a);} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ARcpD1(AD1 x){return rcp(x);} + AD2 ARcpD2(AD2 x){return rcp(x);} + AD3 ARcpD3(AD3 x){return rcp(x);} + AD4 ARcpD4(AD4 x){return rcp(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ARsqD1(AD1 x){return rsqrt(x);} + AD2 ARsqD2(AD2 x){return rsqrt(x);} + AD3 ARsqD3(AD3 x){return rsqrt(x);} + AD4 ARsqD4(AD4 x){return rsqrt(x);} +//------------------------------------------------------------------------------------------------------------------------------ + AD1 ASatD1(AD1 x){return saturate(x);} + AD2 ASatD2(AD2 x){return saturate(x);} + AD3 ASatD3(AD3 x){return saturate(x);} + AD4 ASatD4(AD4 x){return saturate(x);} + #endif +//============================================================================================================================== +// HLSL WAVE +//============================================================================================================================== + #ifdef A_WAVE + // Where 'x' must be a compile time literal. + AF1 AWaveXorF1(AF1 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} + AF2 AWaveXorF2(AF2 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} + AF3 AWaveXorF3(AF3 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} + AF4 AWaveXorF4(AF4 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} + AU1 AWaveXorU1(AU1 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} + AU2 AWaveXorU1(AU2 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} + AU3 AWaveXorU1(AU3 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} + AU4 AWaveXorU1(AU4 v,AU1 x){return WaveReadLaneAt(v,WaveGetLaneIndex()^x);} +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_HALF + AH2 AWaveXorH2(AH2 v,AU1 x){return AH2_AU1(WaveReadLaneAt(AU1_AH2(v),WaveGetLaneIndex()^x));} + AH4 AWaveXorH4(AH4 v,AU1 x){return AH4_AU2(WaveReadLaneAt(AU2_AH4(v),WaveGetLaneIndex()^x));} + AW2 AWaveXorW2(AW2 v,AU1 x){return AW2_AU1(WaveReadLaneAt(AU1_AW2(v),WaveGetLaneIndex()^x));} + AW4 AWaveXorW4(AW4 v,AU1 x){return AW4_AU1(WaveReadLaneAt(AU1_AW4(v),WaveGetLaneIndex()^x));} + #endif + #endif +//============================================================================================================================== +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// +// GPU COMMON +// +// +//============================================================================================================================== +#ifdef A_GPU + // Negative and positive infinity. + #define A_INFP_F AF1_AU1(0x7f800000u) + #define A_INFN_F AF1_AU1(0xff800000u) +//------------------------------------------------------------------------------------------------------------------------------ + // Copy sign from 's' to positive 'd'. + AF1 ACpySgnF1(AF1 d,AF1 s){return AF1_AU1(AU1_AF1(d)|(AU1_AF1(s)&AU1_(0x80000000u)));} + AF2 ACpySgnF2(AF2 d,AF2 s){return AF2_AU2(AU2_AF2(d)|(AU2_AF2(s)&AU2_(0x80000000u)));} + AF3 ACpySgnF3(AF3 d,AF3 s){return AF3_AU3(AU3_AF3(d)|(AU3_AF3(s)&AU3_(0x80000000u)));} + AF4 ACpySgnF4(AF4 d,AF4 s){return AF4_AU4(AU4_AF4(d)|(AU4_AF4(s)&AU4_(0x80000000u)));} +//------------------------------------------------------------------------------------------------------------------------------ + // Single operation to return (useful to create a mask to use in lerp for branch free logic), + // m=NaN := 0 + // m>=0 := 0 + // m<0 := 1 + // Uses the following useful floating point logic, + // saturate(+a*(-INF)==-INF) := 0 + // saturate( 0*(-INF)== NaN) := 0 + // saturate(-a*(-INF)==+INF) := 1 + AF1 ASignedF1(AF1 m){return ASatF1(m*AF1_(A_INFN_F));} + AF2 ASignedF2(AF2 m){return ASatF2(m*AF2_(A_INFN_F));} + AF3 ASignedF3(AF3 m){return ASatF3(m*AF3_(A_INFN_F));} + AF4 ASignedF4(AF4 m){return ASatF4(m*AF4_(A_INFN_F));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AGtZeroF1(AF1 m){return ASatF1(m*AF1_(A_INFP_F));} + AF2 AGtZeroF2(AF2 m){return ASatF2(m*AF2_(A_INFP_F));} + AF3 AGtZeroF3(AF3 m){return ASatF3(m*AF3_(A_INFP_F));} + AF4 AGtZeroF4(AF4 m){return ASatF4(m*AF4_(A_INFP_F));} +//============================================================================================================================== + #ifdef A_HALF + #ifdef A_HLSL_6_2 + #define A_INFP_H AH1_AW1((uint16_t)0x7c00u) + #define A_INFN_H AH1_AW1((uint16_t)0xfc00u) + #else + #define A_INFP_H AH1_AW1(0x7c00u) + #define A_INFN_H AH1_AW1(0xfc00u) + #endif + +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ACpySgnH1(AH1 d,AH1 s){return AH1_AW1(AW1_AH1(d)|(AW1_AH1(s)&AW1_(0x8000u)));} + AH2 ACpySgnH2(AH2 d,AH2 s){return AH2_AW2(AW2_AH2(d)|(AW2_AH2(s)&AW2_(0x8000u)));} + AH3 ACpySgnH3(AH3 d,AH3 s){return AH3_AW3(AW3_AH3(d)|(AW3_AH3(s)&AW3_(0x8000u)));} + AH4 ACpySgnH4(AH4 d,AH4 s){return AH4_AW4(AW4_AH4(d)|(AW4_AH4(s)&AW4_(0x8000u)));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ASignedH1(AH1 m){return ASatH1(m*AH1_(A_INFN_H));} + AH2 ASignedH2(AH2 m){return ASatH2(m*AH2_(A_INFN_H));} + AH3 ASignedH3(AH3 m){return ASatH3(m*AH3_(A_INFN_H));} + AH4 ASignedH4(AH4 m){return ASatH4(m*AH4_(A_INFN_H));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AGtZeroH1(AH1 m){return ASatH1(m*AH1_(A_INFP_H));} + AH2 AGtZeroH2(AH2 m){return ASatH2(m*AH2_(A_INFP_H));} + AH3 AGtZeroH3(AH3 m){return ASatH3(m*AH3_(A_INFP_H));} + AH4 AGtZeroH4(AH4 m){return ASatH4(m*AH4_(A_INFP_H));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// [FIS] FLOAT INTEGER SORTABLE +//------------------------------------------------------------------------------------------------------------------------------ +// Float to integer sortable. +// - If sign bit=0, flip the sign bit (positives). +// - If sign bit=1, flip all bits (negatives). +// Integer sortable to float. +// - If sign bit=1, flip the sign bit (positives). +// - If sign bit=0, flip all bits (negatives). +// Has nice side effects. +// - Larger integers are more positive values. +// - Float zero is mapped to center of integers (so clear to integer zero is a nice default for atomic max usage). +// Burns 3 ops for conversion {shift,or,xor}. +//============================================================================================================================== + AU1 AFisToU1(AU1 x){return x^(( AShrSU1(x,AU1_(31)))|AU1_(0x80000000));} + AU1 AFisFromU1(AU1 x){return x^((~AShrSU1(x,AU1_(31)))|AU1_(0x80000000));} +//------------------------------------------------------------------------------------------------------------------------------ + // Just adjust high 16-bit value (useful when upper part of 32-bit word is a 16-bit float value). + AU1 AFisToHiU1(AU1 x){return x^(( AShrSU1(x,AU1_(15)))|AU1_(0x80000000));} + AU1 AFisFromHiU1(AU1 x){return x^((~AShrSU1(x,AU1_(15)))|AU1_(0x80000000));} +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_HALF + AW1 AFisToW1(AW1 x){return x^(( AShrSW1(x,AW1_(15)))|AW1_(0x8000));} + AW1 AFisFromW1(AW1 x){return x^((~AShrSW1(x,AW1_(15)))|AW1_(0x8000));} +//------------------------------------------------------------------------------------------------------------------------------ + AW2 AFisToW2(AW2 x){return x^(( AShrSW2(x,AW2_(15)))|AW2_(0x8000));} + AW2 AFisFromW2(AW2 x){return x^((~AShrSW2(x,AW2_(15)))|AW2_(0x8000));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// [PERM] V_PERM_B32 +//------------------------------------------------------------------------------------------------------------------------------ +// Support for V_PERM_B32 started in the 3rd generation of GCN. +//------------------------------------------------------------------------------------------------------------------------------ +// yyyyxxxx - The 'i' input. +// 76543210 +// ======== +// HGFEDCBA - Naming on permutation. +//------------------------------------------------------------------------------------------------------------------------------ +// TODO +// ==== +// - Make sure compiler optimizes this. +//============================================================================================================================== + #ifdef A_HALF + AU1 APerm0E0A(AU2 i){return((i.x )&0xffu)|((i.y<<16)&0xff0000u);} + AU1 APerm0F0B(AU2 i){return((i.x>> 8)&0xffu)|((i.y<< 8)&0xff0000u);} + AU1 APerm0G0C(AU2 i){return((i.x>>16)&0xffu)|((i.y )&0xff0000u);} + AU1 APerm0H0D(AU2 i){return((i.x>>24)&0xffu)|((i.y>> 8)&0xff0000u);} +//------------------------------------------------------------------------------------------------------------------------------ + AU1 APermHGFA(AU2 i){return((i.x )&0x000000ffu)|(i.y&0xffffff00u);} + AU1 APermHGFC(AU2 i){return((i.x>>16)&0x000000ffu)|(i.y&0xffffff00u);} + AU1 APermHGAE(AU2 i){return((i.x<< 8)&0x0000ff00u)|(i.y&0xffff00ffu);} + AU1 APermHGCE(AU2 i){return((i.x>> 8)&0x0000ff00u)|(i.y&0xffff00ffu);} + AU1 APermHAFE(AU2 i){return((i.x<<16)&0x00ff0000u)|(i.y&0xff00ffffu);} + AU1 APermHCFE(AU2 i){return((i.x )&0x00ff0000u)|(i.y&0xff00ffffu);} + AU1 APermAGFE(AU2 i){return((i.x<<24)&0xff000000u)|(i.y&0x00ffffffu);} + AU1 APermCGFE(AU2 i){return((i.x<< 8)&0xff000000u)|(i.y&0x00ffffffu);} +//------------------------------------------------------------------------------------------------------------------------------ + AU1 APermGCEA(AU2 i){return((i.x)&0x00ff00ffu)|((i.y<<8)&0xff00ff00u);} + AU1 APermGECA(AU2 i){return(((i.x)&0xffu)|((i.x>>8)&0xff00u)|((i.y<<16)&0xff0000u)|((i.y<<8)&0xff000000u));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// [BUC] BYTE UNSIGNED CONVERSION +//------------------------------------------------------------------------------------------------------------------------------ +// Designed to use the optimal conversion, enables the scaling to possibly be factored into other computation. +// Works on a range of {0 to A_BUC_<32,16>}, for <32-bit, and 16-bit> respectively. +//------------------------------------------------------------------------------------------------------------------------------ +// OPCODE NOTES +// ============ +// GCN does not do UNORM or SNORM for bytes in opcodes. +// - V_CVT_F32_UBYTE{0,1,2,3} - Unsigned byte to float. +// - V_CVT_PKACC_U8_F32 - Float to unsigned byte (does bit-field insert into 32-bit integer). +// V_PERM_B32 does byte packing with ability to zero fill bytes as well. +// - Can pull out byte values from two sources, and zero fill upper 8-bits of packed hi and lo. +//------------------------------------------------------------------------------------------------------------------------------ +// BYTE : FLOAT - ABuc{0,1,2,3}{To,From}U1() - Designed for V_CVT_F32_UBYTE* and V_CVT_PKACCUM_U8_F32 ops. +// ==== ===== +// 0 : 0 +// 1 : 1 +// ... +// 255 : 255 +// : 256 (just outside the encoding range) +//------------------------------------------------------------------------------------------------------------------------------ +// BYTE : FLOAT - ABuc{0,1,2,3}{To,From}U2() - Designed for 16-bit denormal tricks and V_PERM_B32. +// ==== ===== +// 0 : 0 +// 1 : 1/512 +// 2 : 1/256 +// ... +// 64 : 1/8 +// 128 : 1/4 +// 255 : 255/512 +// : 1/2 (just outside the encoding range) +//------------------------------------------------------------------------------------------------------------------------------ +// OPTIMAL IMPLEMENTATIONS ON AMD ARCHITECTURES +// ============================================ +// r=ABuc0FromU1(i) +// V_CVT_F32_UBYTE0 r,i +// -------------------------------------------- +// r=ABuc0ToU1(d,i) +// V_CVT_PKACCUM_U8_F32 r,i,0,d +// -------------------------------------------- +// d=ABuc0FromU2(i) +// Where 'k0' is an SGPR with 0x0E0A +// Where 'k1' is an SGPR with {32768.0} packed into the lower 16-bits +// V_PERM_B32 d,i.x,i.y,k0 +// V_PK_FMA_F16 d,d,k1.x,0 +// -------------------------------------------- +// r=ABuc0ToU2(d,i) +// Where 'k0' is an SGPR with {1.0/32768.0} packed into the lower 16-bits +// Where 'k1' is an SGPR with 0x???? +// Where 'k2' is an SGPR with 0x???? +// V_PK_FMA_F16 i,i,k0.x,0 +// V_PERM_B32 r.x,i,i,k1 +// V_PERM_B32 r.y,i,i,k2 +//============================================================================================================================== + // Peak range for 32-bit and 16-bit operations. + #define A_BUC_32 (255.0) + #define A_BUC_16 (255.0/512.0) +//============================================================================================================================== + #if 1 + // Designed to be one V_CVT_PKACCUM_U8_F32. + // The extra min is required to pattern match to V_CVT_PKACCUM_U8_F32. + AU1 ABuc0ToU1(AU1 d,AF1 i){return (d&0xffffff00u)|((min(AU1(i),255u) )&(0x000000ffu));} + AU1 ABuc1ToU1(AU1 d,AF1 i){return (d&0xffff00ffu)|((min(AU1(i),255u)<< 8)&(0x0000ff00u));} + AU1 ABuc2ToU1(AU1 d,AF1 i){return (d&0xff00ffffu)|((min(AU1(i),255u)<<16)&(0x00ff0000u));} + AU1 ABuc3ToU1(AU1 d,AF1 i){return (d&0x00ffffffu)|((min(AU1(i),255u)<<24)&(0xff000000u));} +//------------------------------------------------------------------------------------------------------------------------------ + // Designed to be one V_CVT_F32_UBYTE*. + AF1 ABuc0FromU1(AU1 i){return AF1((i )&255u);} + AF1 ABuc1FromU1(AU1 i){return AF1((i>> 8)&255u);} + AF1 ABuc2FromU1(AU1 i){return AF1((i>>16)&255u);} + AF1 ABuc3FromU1(AU1 i){return AF1((i>>24)&255u);} + #endif +//============================================================================================================================== + #ifdef A_HALF + // Takes {x0,x1} and {y0,y1} and builds {{x0,y0},{x1,y1}}. + AW2 ABuc01ToW2(AH2 x,AH2 y){x*=AH2_(1.0/32768.0);y*=AH2_(1.0/32768.0); + return AW2_AU1(APermGCEA(AU2(AU1_AW2(AW2_AH2(x)),AU1_AW2(AW2_AH2(y)))));} +//------------------------------------------------------------------------------------------------------------------------------ + // Designed for 3 ops to do SOA to AOS and conversion. + AU2 ABuc0ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0))); + return AU2(APermHGFA(AU2(d.x,b)),APermHGFC(AU2(d.y,b)));} + AU2 ABuc1ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0))); + return AU2(APermHGAE(AU2(d.x,b)),APermHGCE(AU2(d.y,b)));} + AU2 ABuc2ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0))); + return AU2(APermHAFE(AU2(d.x,b)),APermHCFE(AU2(d.y,b)));} + AU2 ABuc3ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0))); + return AU2(APermAGFE(AU2(d.x,b)),APermCGFE(AU2(d.y,b)));} +//------------------------------------------------------------------------------------------------------------------------------ + // Designed for 2 ops to do both AOS to SOA, and conversion. + AH2 ABuc0FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0E0A(i)))*AH2_(32768.0);} + AH2 ABuc1FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0F0B(i)))*AH2_(32768.0);} + AH2 ABuc2FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0G0C(i)))*AH2_(32768.0);} + AH2 ABuc3FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0H0D(i)))*AH2_(32768.0);} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// [BSC] BYTE SIGNED CONVERSION +//------------------------------------------------------------------------------------------------------------------------------ +// Similar to [BUC]. +// Works on a range of {-/+ A_BSC_<32,16>}, for <32-bit, and 16-bit> respectively. +//------------------------------------------------------------------------------------------------------------------------------ +// ENCODING (without zero-based encoding) +// ======== +// 0 = unused (can be used to mean something else) +// 1 = lowest value +// 128 = exact zero center (zero based encoding +// 255 = highest value +//------------------------------------------------------------------------------------------------------------------------------ +// Zero-based [Zb] flips the MSB bit of the byte (making 128 "exact zero" actually zero). +// This is useful if there is a desire for cleared values to decode as zero. +//------------------------------------------------------------------------------------------------------------------------------ +// BYTE : FLOAT - ABsc{0,1,2,3}{To,From}U2() - Designed for 16-bit denormal tricks and V_PERM_B32. +// ==== ===== +// 0 : -127/512 (unused) +// 1 : -126/512 +// 2 : -125/512 +// ... +// 128 : 0 +// ... +// 255 : 127/512 +// : 1/4 (just outside the encoding range) +//============================================================================================================================== + // Peak range for 32-bit and 16-bit operations. + #define A_BSC_32 (127.0) + #define A_BSC_16 (127.0/512.0) +//============================================================================================================================== + #if 1 + AU1 ABsc0ToU1(AU1 d,AF1 i){return (d&0xffffff00u)|((min(AU1(i+128.0),255u) )&(0x000000ffu));} + AU1 ABsc1ToU1(AU1 d,AF1 i){return (d&0xffff00ffu)|((min(AU1(i+128.0),255u)<< 8)&(0x0000ff00u));} + AU1 ABsc2ToU1(AU1 d,AF1 i){return (d&0xff00ffffu)|((min(AU1(i+128.0),255u)<<16)&(0x00ff0000u));} + AU1 ABsc3ToU1(AU1 d,AF1 i){return (d&0x00ffffffu)|((min(AU1(i+128.0),255u)<<24)&(0xff000000u));} +//------------------------------------------------------------------------------------------------------------------------------ + AU1 ABsc0ToZbU1(AU1 d,AF1 i){return ((d&0xffffff00u)|((min(AU1(trunc(i)+128.0),255u) )&(0x000000ffu)))^0x00000080u;} + AU1 ABsc1ToZbU1(AU1 d,AF1 i){return ((d&0xffff00ffu)|((min(AU1(trunc(i)+128.0),255u)<< 8)&(0x0000ff00u)))^0x00008000u;} + AU1 ABsc2ToZbU1(AU1 d,AF1 i){return ((d&0xff00ffffu)|((min(AU1(trunc(i)+128.0),255u)<<16)&(0x00ff0000u)))^0x00800000u;} + AU1 ABsc3ToZbU1(AU1 d,AF1 i){return ((d&0x00ffffffu)|((min(AU1(trunc(i)+128.0),255u)<<24)&(0xff000000u)))^0x80000000u;} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 ABsc0FromU1(AU1 i){return AF1((i )&255u)-128.0;} + AF1 ABsc1FromU1(AU1 i){return AF1((i>> 8)&255u)-128.0;} + AF1 ABsc2FromU1(AU1 i){return AF1((i>>16)&255u)-128.0;} + AF1 ABsc3FromU1(AU1 i){return AF1((i>>24)&255u)-128.0;} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 ABsc0FromZbU1(AU1 i){return AF1(((i )&255u)^0x80u)-128.0;} + AF1 ABsc1FromZbU1(AU1 i){return AF1(((i>> 8)&255u)^0x80u)-128.0;} + AF1 ABsc2FromZbU1(AU1 i){return AF1(((i>>16)&255u)^0x80u)-128.0;} + AF1 ABsc3FromZbU1(AU1 i){return AF1(((i>>24)&255u)^0x80u)-128.0;} + #endif +//============================================================================================================================== + #ifdef A_HALF + // Takes {x0,x1} and {y0,y1} and builds {{x0,y0},{x1,y1}}. + AW2 ABsc01ToW2(AH2 x,AH2 y){x=x*AH2_(1.0/32768.0)+AH2_(0.25/32768.0);y=y*AH2_(1.0/32768.0)+AH2_(0.25/32768.0); + return AW2_AU1(APermGCEA(AU2(AU1_AW2(AW2_AH2(x)),AU1_AW2(AW2_AH2(y)))));} +//------------------------------------------------------------------------------------------------------------------------------ + AU2 ABsc0ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0))); + return AU2(APermHGFA(AU2(d.x,b)),APermHGFC(AU2(d.y,b)));} + AU2 ABsc1ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0))); + return AU2(APermHGAE(AU2(d.x,b)),APermHGCE(AU2(d.y,b)));} + AU2 ABsc2ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0))); + return AU2(APermHAFE(AU2(d.x,b)),APermHCFE(AU2(d.y,b)));} + AU2 ABsc3ToU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0))); + return AU2(APermAGFE(AU2(d.x,b)),APermCGFE(AU2(d.y,b)));} +//------------------------------------------------------------------------------------------------------------------------------ + AU2 ABsc0ToZbU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0)))^0x00800080u; + return AU2(APermHGFA(AU2(d.x,b)),APermHGFC(AU2(d.y,b)));} + AU2 ABsc1ToZbU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0)))^0x00800080u; + return AU2(APermHGAE(AU2(d.x,b)),APermHGCE(AU2(d.y,b)));} + AU2 ABsc2ToZbU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0)))^0x00800080u; + return AU2(APermHAFE(AU2(d.x,b)),APermHCFE(AU2(d.y,b)));} + AU2 ABsc3ToZbU2(AU2 d,AH2 i){AU1 b=AU1_AW2(AW2_AH2(i*AH2_(1.0/32768.0)+AH2_(0.25/32768.0)))^0x00800080u; + return AU2(APermAGFE(AU2(d.x,b)),APermCGFE(AU2(d.y,b)));} +//------------------------------------------------------------------------------------------------------------------------------ + AH2 ABsc0FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0E0A(i)))*AH2_(32768.0)-AH2_(0.25);} + AH2 ABsc1FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0F0B(i)))*AH2_(32768.0)-AH2_(0.25);} + AH2 ABsc2FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0G0C(i)))*AH2_(32768.0)-AH2_(0.25);} + AH2 ABsc3FromU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0H0D(i)))*AH2_(32768.0)-AH2_(0.25);} +//------------------------------------------------------------------------------------------------------------------------------ + AH2 ABsc0FromZbU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0E0A(i)^0x00800080u))*AH2_(32768.0)-AH2_(0.25);} + AH2 ABsc1FromZbU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0F0B(i)^0x00800080u))*AH2_(32768.0)-AH2_(0.25);} + AH2 ABsc2FromZbU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0G0C(i)^0x00800080u))*AH2_(32768.0)-AH2_(0.25);} + AH2 ABsc3FromZbU2(AU2 i){return AH2_AW2(AW2_AU1(APerm0H0D(i)^0x00800080u))*AH2_(32768.0)-AH2_(0.25);} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// HALF APPROXIMATIONS +//------------------------------------------------------------------------------------------------------------------------------ +// These support only positive inputs. +// Did not see value yet in specialization for range. +// Using quick testing, ended up mostly getting the same "best" approximation for various ranges. +// With hardware that can co-execute transcendentals, the value in approximations could be less than expected. +// However from a latency perspective, if execution of a transcendental is 4 clk, with no packed support, -> 8 clk total. +// And co-execution would require a compiler interleaving a lot of independent work for packed usage. +//------------------------------------------------------------------------------------------------------------------------------ +// The one Newton Raphson iteration form of rsq() was skipped (requires 6 ops total). +// Same with sqrt(), as this could be x*rsq() (7 ops). +//============================================================================================================================== + #ifdef A_HALF + // Minimize squared error across full positive range, 2 ops. + // The 0x1de2 based approximation maps {0 to 1} input maps to < 1 output. + AH1 APrxLoSqrtH1(AH1 a){return AH1_AW1((AW1_AH1(a)>>AW1_(1))+AW1_(0x1de2));} + AH2 APrxLoSqrtH2(AH2 a){return AH2_AW2((AW2_AH2(a)>>AW2_(1))+AW2_(0x1de2));} + AH3 APrxLoSqrtH3(AH3 a){return AH3_AW3((AW3_AH3(a)>>AW3_(1))+AW3_(0x1de2));} + AH4 APrxLoSqrtH4(AH4 a){return AH4_AW4((AW4_AH4(a)>>AW4_(1))+AW4_(0x1de2));} +//------------------------------------------------------------------------------------------------------------------------------ + // Lower precision estimation, 1 op. + // Minimize squared error across {smallest normal to 16384.0}. + AH1 APrxLoRcpH1(AH1 a){return AH1_AW1(AW1_(0x7784)-AW1_AH1(a));} + AH2 APrxLoRcpH2(AH2 a){return AH2_AW2(AW2_(0x7784)-AW2_AH2(a));} + AH3 APrxLoRcpH3(AH3 a){return AH3_AW3(AW3_(0x7784)-AW3_AH3(a));} + AH4 APrxLoRcpH4(AH4 a){return AH4_AW4(AW4_(0x7784)-AW4_AH4(a));} +//------------------------------------------------------------------------------------------------------------------------------ + // Medium precision estimation, one Newton Raphson iteration, 3 ops. + AH1 APrxMedRcpH1(AH1 a){AH1 b=AH1_AW1(AW1_(0x778d)-AW1_AH1(a));return b*(-b*a+AH1_(2.0));} + AH2 APrxMedRcpH2(AH2 a){AH2 b=AH2_AW2(AW2_(0x778d)-AW2_AH2(a));return b*(-b*a+AH2_(2.0));} + AH3 APrxMedRcpH3(AH3 a){AH3 b=AH3_AW3(AW3_(0x778d)-AW3_AH3(a));return b*(-b*a+AH3_(2.0));} + AH4 APrxMedRcpH4(AH4 a){AH4 b=AH4_AW4(AW4_(0x778d)-AW4_AH4(a));return b*(-b*a+AH4_(2.0));} +//------------------------------------------------------------------------------------------------------------------------------ + // Minimize squared error across {smallest normal to 16384.0}, 2 ops. + AH1 APrxLoRsqH1(AH1 a){return AH1_AW1(AW1_(0x59a3)-(AW1_AH1(a)>>AW1_(1)));} + AH2 APrxLoRsqH2(AH2 a){return AH2_AW2(AW2_(0x59a3)-(AW2_AH2(a)>>AW2_(1)));} + AH3 APrxLoRsqH3(AH3 a){return AH3_AW3(AW3_(0x59a3)-(AW3_AH3(a)>>AW3_(1)));} + AH4 APrxLoRsqH4(AH4 a){return AH4_AW4(AW4_(0x59a3)-(AW4_AH4(a)>>AW4_(1)));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// FLOAT APPROXIMATIONS +//------------------------------------------------------------------------------------------------------------------------------ +// Michal Drobot has an excellent presentation on these: "Low Level Optimizations For GCN", +// - Idea dates back to SGI, then to Quake 3, etc. +// - https://michaldrobot.files.wordpress.com/2014/05/gcn_alu_opt_digitaldragons2014.pdf +// - sqrt(x)=rsqrt(x)*x +// - rcp(x)=rsqrt(x)*rsqrt(x) for positive x +// - https://github.com/michaldrobot/ShaderFastLibs/blob/master/ShaderFastMathLib.h +//------------------------------------------------------------------------------------------------------------------------------ +// These below are from perhaps less complete searching for optimal. +// Used FP16 normal range for testing with +4096 32-bit step size for sampling error. +// So these match up well with the half approximations. +//============================================================================================================================== + AF1 APrxLoSqrtF1(AF1 a){return AF1_AU1((AU1_AF1(a)>>AU1_(1))+AU1_(0x1fbc4639));} + AF1 APrxLoRcpF1(AF1 a){return AF1_AU1(AU1_(0x7ef07ebb)-AU1_AF1(a));} + AF1 APrxMedRcpF1(AF1 a){AF1 b=AF1_AU1(AU1_(0x7ef19fff)-AU1_AF1(a));return b*(-b*a+AF1_(2.0));} + AF1 APrxLoRsqF1(AF1 a){return AF1_AU1(AU1_(0x5f347d74)-(AU1_AF1(a)>>AU1_(1)));} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 APrxLoSqrtF2(AF2 a){return AF2_AU2((AU2_AF2(a)>>AU2_(1))+AU2_(0x1fbc4639));} + AF2 APrxLoRcpF2(AF2 a){return AF2_AU2(AU2_(0x7ef07ebb)-AU2_AF2(a));} + AF2 APrxMedRcpF2(AF2 a){AF2 b=AF2_AU2(AU2_(0x7ef19fff)-AU2_AF2(a));return b*(-b*a+AF2_(2.0));} + AF2 APrxLoRsqF2(AF2 a){return AF2_AU2(AU2_(0x5f347d74)-(AU2_AF2(a)>>AU2_(1)));} +//------------------------------------------------------------------------------------------------------------------------------ + AF3 APrxLoSqrtF3(AF3 a){return AF3_AU3((AU3_AF3(a)>>AU3_(1))+AU3_(0x1fbc4639));} + AF3 APrxLoRcpF3(AF3 a){return AF3_AU3(AU3_(0x7ef07ebb)-AU3_AF3(a));} + AF3 APrxMedRcpF3(AF3 a){AF3 b=AF3_AU3(AU3_(0x7ef19fff)-AU3_AF3(a));return b*(-b*a+AF3_(2.0));} + AF3 APrxLoRsqF3(AF3 a){return AF3_AU3(AU3_(0x5f347d74)-(AU3_AF3(a)>>AU3_(1)));} +//------------------------------------------------------------------------------------------------------------------------------ + AF4 APrxLoSqrtF4(AF4 a){return AF4_AU4((AU4_AF4(a)>>AU4_(1))+AU4_(0x1fbc4639));} + AF4 APrxLoRcpF4(AF4 a){return AF4_AU4(AU4_(0x7ef07ebb)-AU4_AF4(a));} + AF4 APrxMedRcpF4(AF4 a){AF4 b=AF4_AU4(AU4_(0x7ef19fff)-AU4_AF4(a));return b*(-b*a+AF4_(2.0));} + AF4 APrxLoRsqF4(AF4 a){return AF4_AU4(AU4_(0x5f347d74)-(AU4_AF4(a)>>AU4_(1)));} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// PQ APPROXIMATIONS +//------------------------------------------------------------------------------------------------------------------------------ +// PQ is very close to x^(1/8). The functions below Use the fast float approximation method to do +// PQ<~>Gamma2 (4th power and fast 4th root) and PQ<~>Linear (8th power and fast 8th root). Maximum error is ~0.2%. +//============================================================================================================================== +// Helpers + AF1 Quart(AF1 a) { a = a * a; return a * a;} + AF1 Oct(AF1 a) { a = a * a; a = a * a; return a * a; } + AF2 Quart(AF2 a) { a = a * a; return a * a; } + AF2 Oct(AF2 a) { a = a * a; a = a * a; return a * a; } + AF3 Quart(AF3 a) { a = a * a; return a * a; } + AF3 Oct(AF3 a) { a = a * a; a = a * a; return a * a; } + AF4 Quart(AF4 a) { a = a * a; return a * a; } + AF4 Oct(AF4 a) { a = a * a; a = a * a; return a * a; } + //------------------------------------------------------------------------------------------------------------------------------ + AF1 APrxPQToGamma2(AF1 a) { return Quart(a); } + AF1 APrxPQToLinear(AF1 a) { return Oct(a); } + AF1 APrxLoGamma2ToPQ(AF1 a) { return AF1_AU1((AU1_AF1(a) >> AU1_(2)) + AU1_(0x2F9A4E46)); } + AF1 APrxMedGamma2ToPQ(AF1 a) { AF1 b = AF1_AU1((AU1_AF1(a) >> AU1_(2)) + AU1_(0x2F9A4E46)); AF1 b4 = Quart(b); return b - b * (b4 - a) / (AF1_(4.0) * b4); } + AF1 APrxHighGamma2ToPQ(AF1 a) { return sqrt(sqrt(a)); } + AF1 APrxLoLinearToPQ(AF1 a) { return AF1_AU1((AU1_AF1(a) >> AU1_(3)) + AU1_(0x378D8723)); } + AF1 APrxMedLinearToPQ(AF1 a) { AF1 b = AF1_AU1((AU1_AF1(a) >> AU1_(3)) + AU1_(0x378D8723)); AF1 b8 = Oct(b); return b - b * (b8 - a) / (AF1_(8.0) * b8); } + AF1 APrxHighLinearToPQ(AF1 a) { return sqrt(sqrt(sqrt(a))); } + //------------------------------------------------------------------------------------------------------------------------------ + AF2 APrxPQToGamma2(AF2 a) { return Quart(a); } + AF2 APrxPQToLinear(AF2 a) { return Oct(a); } + AF2 APrxLoGamma2ToPQ(AF2 a) { return AF2_AU2((AU2_AF2(a) >> AU2_(2)) + AU2_(0x2F9A4E46)); } + AF2 APrxMedGamma2ToPQ(AF2 a) { AF2 b = AF2_AU2((AU2_AF2(a) >> AU2_(2)) + AU2_(0x2F9A4E46)); AF2 b4 = Quart(b); return b - b * (b4 - a) / (AF1_(4.0) * b4); } + AF2 APrxHighGamma2ToPQ(AF2 a) { return sqrt(sqrt(a)); } + AF2 APrxLoLinearToPQ(AF2 a) { return AF2_AU2((AU2_AF2(a) >> AU2_(3)) + AU2_(0x378D8723)); } + AF2 APrxMedLinearToPQ(AF2 a) { AF2 b = AF2_AU2((AU2_AF2(a) >> AU2_(3)) + AU2_(0x378D8723)); AF2 b8 = Oct(b); return b - b * (b8 - a) / (AF1_(8.0) * b8); } + AF2 APrxHighLinearToPQ(AF2 a) { return sqrt(sqrt(sqrt(a))); } + //------------------------------------------------------------------------------------------------------------------------------ + AF3 APrxPQToGamma2(AF3 a) { return Quart(a); } + AF3 APrxPQToLinear(AF3 a) { return Oct(a); } + AF3 APrxLoGamma2ToPQ(AF3 a) { return AF3_AU3((AU3_AF3(a) >> AU3_(2)) + AU3_(0x2F9A4E46)); } + AF3 APrxMedGamma2ToPQ(AF3 a) { AF3 b = AF3_AU3((AU3_AF3(a) >> AU3_(2)) + AU3_(0x2F9A4E46)); AF3 b4 = Quart(b); return b - b * (b4 - a) / (AF1_(4.0) * b4); } + AF3 APrxHighGamma2ToPQ(AF3 a) { return sqrt(sqrt(a)); } + AF3 APrxLoLinearToPQ(AF3 a) { return AF3_AU3((AU3_AF3(a) >> AU3_(3)) + AU3_(0x378D8723)); } + AF3 APrxMedLinearToPQ(AF3 a) { AF3 b = AF3_AU3((AU3_AF3(a) >> AU3_(3)) + AU3_(0x378D8723)); AF3 b8 = Oct(b); return b - b * (b8 - a) / (AF1_(8.0) * b8); } + AF3 APrxHighLinearToPQ(AF3 a) { return sqrt(sqrt(sqrt(a))); } + //------------------------------------------------------------------------------------------------------------------------------ + AF4 APrxPQToGamma2(AF4 a) { return Quart(a); } + AF4 APrxPQToLinear(AF4 a) { return Oct(a); } + AF4 APrxLoGamma2ToPQ(AF4 a) { return AF4_AU4((AU4_AF4(a) >> AU4_(2)) + AU4_(0x2F9A4E46)); } + AF4 APrxMedGamma2ToPQ(AF4 a) { AF4 b = AF4_AU4((AU4_AF4(a) >> AU4_(2)) + AU4_(0x2F9A4E46)); AF4 b4 = Quart(b); return b - b * (b4 - a) / (AF1_(4.0) * b4); } + AF4 APrxHighGamma2ToPQ(AF4 a) { return sqrt(sqrt(a)); } + AF4 APrxLoLinearToPQ(AF4 a) { return AF4_AU4((AU4_AF4(a) >> AU4_(3)) + AU4_(0x378D8723)); } + AF4 APrxMedLinearToPQ(AF4 a) { AF4 b = AF4_AU4((AU4_AF4(a) >> AU4_(3)) + AU4_(0x378D8723)); AF4 b8 = Oct(b); return b - b * (b8 - a) / (AF1_(8.0) * b8); } + AF4 APrxHighLinearToPQ(AF4 a) { return sqrt(sqrt(sqrt(a))); } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// PARABOLIC SIN & COS +//------------------------------------------------------------------------------------------------------------------------------ +// Approximate answers to transcendental questions. +//------------------------------------------------------------------------------------------------------------------------------ +//============================================================================================================================== + #if 1 + // Valid input range is {-1 to 1} representing {0 to 2 pi}. + // Output range is {-1/4 to 1/4} representing {-1 to 1}. + AF1 APSinF1(AF1 x){return x*abs(x)-x;} // MAD. + AF2 APSinF2(AF2 x){return x*abs(x)-x;} + AF1 APCosF1(AF1 x){x=AFractF1(x*AF1_(0.5)+AF1_(0.75));x=x*AF1_(2.0)-AF1_(1.0);return APSinF1(x);} // 3x MAD, FRACT + AF2 APCosF2(AF2 x){x=AFractF2(x*AF2_(0.5)+AF2_(0.75));x=x*AF2_(2.0)-AF2_(1.0);return APSinF2(x);} + AF2 APSinCosF1(AF1 x){AF1 y=AFractF1(x*AF1_(0.5)+AF1_(0.75));y=y*AF1_(2.0)-AF1_(1.0);return APSinF2(AF2(x,y));} + #endif +//------------------------------------------------------------------------------------------------------------------------------ + #ifdef A_HALF + // For a packed {sin,cos} pair, + // - Native takes 16 clocks and 4 issue slots (no packed transcendentals). + // - Parabolic takes 8 clocks and 8 issue slots (only fract is non-packed). + AH1 APSinH1(AH1 x){return x*abs(x)-x;} + AH2 APSinH2(AH2 x){return x*abs(x)-x;} // AND,FMA + AH1 APCosH1(AH1 x){x=AFractH1(x*AH1_(0.5)+AH1_(0.75));x=x*AH1_(2.0)-AH1_(1.0);return APSinH1(x);} + AH2 APCosH2(AH2 x){x=AFractH2(x*AH2_(0.5)+AH2_(0.75));x=x*AH2_(2.0)-AH2_(1.0);return APSinH2(x);} // 3x FMA, 2xFRACT, AND + AH2 APSinCosH1(AH1 x){AH1 y=AFractH1(x*AH1_(0.5)+AH1_(0.75));y=y*AH1_(2.0)-AH1_(1.0);return APSinH2(AH2(x,y));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// [ZOL] ZERO ONE LOGIC +//------------------------------------------------------------------------------------------------------------------------------ +// Conditional free logic designed for easy 16-bit packing, and backwards porting to 32-bit. +//------------------------------------------------------------------------------------------------------------------------------ +// 0 := false +// 1 := true +//------------------------------------------------------------------------------------------------------------------------------ +// AndNot(x,y) -> !(x&y) .... One op. +// AndOr(x,y,z) -> (x&y)|z ... One op. +// GtZero(x) -> x>0.0 ..... One op. +// Sel(x,y,z) -> x?y:z ..... Two ops, has no precision loss. +// Signed(x) -> x<0.0 ..... One op. +// ZeroPass(x,y) -> x?0:y ..... Two ops, 'y' is a pass through safe for aliasing as integer. +//------------------------------------------------------------------------------------------------------------------------------ +// OPTIMIZATION NOTES +// ================== +// - On Vega to use 2 constants in a packed op, pass in as one AW2 or one AH2 'k.xy' and use as 'k.xx' and 'k.yy'. +// For example 'a.xy*k.xx+k.yy'. +//============================================================================================================================== + #if 1 + AU1 AZolAndU1(AU1 x,AU1 y){return min(x,y);} + AU2 AZolAndU2(AU2 x,AU2 y){return min(x,y);} + AU3 AZolAndU3(AU3 x,AU3 y){return min(x,y);} + AU4 AZolAndU4(AU4 x,AU4 y){return min(x,y);} +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AZolNotU1(AU1 x){return x^AU1_(1);} + AU2 AZolNotU2(AU2 x){return x^AU2_(1);} + AU3 AZolNotU3(AU3 x){return x^AU3_(1);} + AU4 AZolNotU4(AU4 x){return x^AU4_(1);} +//------------------------------------------------------------------------------------------------------------------------------ + AU1 AZolOrU1(AU1 x,AU1 y){return max(x,y);} + AU2 AZolOrU2(AU2 x,AU2 y){return max(x,y);} + AU3 AZolOrU3(AU3 x,AU3 y){return max(x,y);} + AU4 AZolOrU4(AU4 x,AU4 y){return max(x,y);} +//============================================================================================================================== + AU1 AZolF1ToU1(AF1 x){return AU1(x);} + AU2 AZolF2ToU2(AF2 x){return AU2(x);} + AU3 AZolF3ToU3(AF3 x){return AU3(x);} + AU4 AZolF4ToU4(AF4 x){return AU4(x);} +//------------------------------------------------------------------------------------------------------------------------------ + // 2 ops, denormals don't work in 32-bit on PC (and if they are enabled, OMOD is disabled). + AU1 AZolNotF1ToU1(AF1 x){return AU1(AF1_(1.0)-x);} + AU2 AZolNotF2ToU2(AF2 x){return AU2(AF2_(1.0)-x);} + AU3 AZolNotF3ToU3(AF3 x){return AU3(AF3_(1.0)-x);} + AU4 AZolNotF4ToU4(AF4 x){return AU4(AF4_(1.0)-x);} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolU1ToF1(AU1 x){return AF1(x);} + AF2 AZolU2ToF2(AU2 x){return AF2(x);} + AF3 AZolU3ToF3(AU3 x){return AF3(x);} + AF4 AZolU4ToF4(AU4 x){return AF4(x);} +//============================================================================================================================== + AF1 AZolAndF1(AF1 x,AF1 y){return min(x,y);} + AF2 AZolAndF2(AF2 x,AF2 y){return min(x,y);} + AF3 AZolAndF3(AF3 x,AF3 y){return min(x,y);} + AF4 AZolAndF4(AF4 x,AF4 y){return min(x,y);} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 ASolAndNotF1(AF1 x,AF1 y){return (-x)*y+AF1_(1.0);} + AF2 ASolAndNotF2(AF2 x,AF2 y){return (-x)*y+AF2_(1.0);} + AF3 ASolAndNotF3(AF3 x,AF3 y){return (-x)*y+AF3_(1.0);} + AF4 ASolAndNotF4(AF4 x,AF4 y){return (-x)*y+AF4_(1.0);} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolAndOrF1(AF1 x,AF1 y,AF1 z){return ASatF1(x*y+z);} + AF2 AZolAndOrF2(AF2 x,AF2 y,AF2 z){return ASatF2(x*y+z);} + AF3 AZolAndOrF3(AF3 x,AF3 y,AF3 z){return ASatF3(x*y+z);} + AF4 AZolAndOrF4(AF4 x,AF4 y,AF4 z){return ASatF4(x*y+z);} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolGtZeroF1(AF1 x){return ASatF1(x*AF1_(A_INFP_F));} + AF2 AZolGtZeroF2(AF2 x){return ASatF2(x*AF2_(A_INFP_F));} + AF3 AZolGtZeroF3(AF3 x){return ASatF3(x*AF3_(A_INFP_F));} + AF4 AZolGtZeroF4(AF4 x){return ASatF4(x*AF4_(A_INFP_F));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolNotF1(AF1 x){return AF1_(1.0)-x;} + AF2 AZolNotF2(AF2 x){return AF2_(1.0)-x;} + AF3 AZolNotF3(AF3 x){return AF3_(1.0)-x;} + AF4 AZolNotF4(AF4 x){return AF4_(1.0)-x;} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolOrF1(AF1 x,AF1 y){return max(x,y);} + AF2 AZolOrF2(AF2 x,AF2 y){return max(x,y);} + AF3 AZolOrF3(AF3 x,AF3 y){return max(x,y);} + AF4 AZolOrF4(AF4 x,AF4 y){return max(x,y);} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolSelF1(AF1 x,AF1 y,AF1 z){AF1 r=(-x)*z+z;return x*y+r;} + AF2 AZolSelF2(AF2 x,AF2 y,AF2 z){AF2 r=(-x)*z+z;return x*y+r;} + AF3 AZolSelF3(AF3 x,AF3 y,AF3 z){AF3 r=(-x)*z+z;return x*y+r;} + AF4 AZolSelF4(AF4 x,AF4 y,AF4 z){AF4 r=(-x)*z+z;return x*y+r;} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolSignedF1(AF1 x){return ASatF1(x*AF1_(A_INFN_F));} + AF2 AZolSignedF2(AF2 x){return ASatF2(x*AF2_(A_INFN_F));} + AF3 AZolSignedF3(AF3 x){return ASatF3(x*AF3_(A_INFN_F));} + AF4 AZolSignedF4(AF4 x){return ASatF4(x*AF4_(A_INFN_F));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AZolZeroPassF1(AF1 x,AF1 y){return AF1_AU1((AU1_AF1(x)!=AU1_(0))?AU1_(0):AU1_AF1(y));} + AF2 AZolZeroPassF2(AF2 x,AF2 y){return AF2_AU2((AU2_AF2(x)!=AU2_(0))?AU2_(0):AU2_AF2(y));} + AF3 AZolZeroPassF3(AF3 x,AF3 y){return AF3_AU3((AU3_AF3(x)!=AU3_(0))?AU3_(0):AU3_AF3(y));} + AF4 AZolZeroPassF4(AF4 x,AF4 y){return AF4_AU4((AU4_AF4(x)!=AU4_(0))?AU4_(0):AU4_AF4(y));} + #endif +//============================================================================================================================== + #ifdef A_HALF + AW1 AZolAndW1(AW1 x,AW1 y){return min(x,y);} + AW2 AZolAndW2(AW2 x,AW2 y){return min(x,y);} + AW3 AZolAndW3(AW3 x,AW3 y){return min(x,y);} + AW4 AZolAndW4(AW4 x,AW4 y){return min(x,y);} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AZolNotW1(AW1 x){return x^AW1_(1);} + AW2 AZolNotW2(AW2 x){return x^AW2_(1);} + AW3 AZolNotW3(AW3 x){return x^AW3_(1);} + AW4 AZolNotW4(AW4 x){return x^AW4_(1);} +//------------------------------------------------------------------------------------------------------------------------------ + AW1 AZolOrW1(AW1 x,AW1 y){return max(x,y);} + AW2 AZolOrW2(AW2 x,AW2 y){return max(x,y);} + AW3 AZolOrW3(AW3 x,AW3 y){return max(x,y);} + AW4 AZolOrW4(AW4 x,AW4 y){return max(x,y);} +//============================================================================================================================== + // Uses denormal trick. + AW1 AZolH1ToW1(AH1 x){return AW1_AH1(x*AH1_AW1(AW1_(1)));} + AW2 AZolH2ToW2(AH2 x){return AW2_AH2(x*AH2_AW2(AW2_(1)));} + AW3 AZolH3ToW3(AH3 x){return AW3_AH3(x*AH3_AW3(AW3_(1)));} + AW4 AZolH4ToW4(AH4 x){return AW4_AH4(x*AH4_AW4(AW4_(1)));} +//------------------------------------------------------------------------------------------------------------------------------ + // AMD arch lacks a packed conversion opcode. + AH1 AZolW1ToH1(AW1 x){return AH1_AW1(x*AW1_AH1(AH1_(1.0)));} + AH2 AZolW2ToH2(AW2 x){return AH2_AW2(x*AW2_AH2(AH2_(1.0)));} + AH3 AZolW1ToH3(AW3 x){return AH3_AW3(x*AW3_AH3(AH3_(1.0)));} + AH4 AZolW2ToH4(AW4 x){return AH4_AW4(x*AW4_AH4(AH4_(1.0)));} +//============================================================================================================================== + AH1 AZolAndH1(AH1 x,AH1 y){return min(x,y);} + AH2 AZolAndH2(AH2 x,AH2 y){return min(x,y);} + AH3 AZolAndH3(AH3 x,AH3 y){return min(x,y);} + AH4 AZolAndH4(AH4 x,AH4 y){return min(x,y);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 ASolAndNotH1(AH1 x,AH1 y){return (-x)*y+AH1_(1.0);} + AH2 ASolAndNotH2(AH2 x,AH2 y){return (-x)*y+AH2_(1.0);} + AH3 ASolAndNotH3(AH3 x,AH3 y){return (-x)*y+AH3_(1.0);} + AH4 ASolAndNotH4(AH4 x,AH4 y){return (-x)*y+AH4_(1.0);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AZolAndOrH1(AH1 x,AH1 y,AH1 z){return ASatH1(x*y+z);} + AH2 AZolAndOrH2(AH2 x,AH2 y,AH2 z){return ASatH2(x*y+z);} + AH3 AZolAndOrH3(AH3 x,AH3 y,AH3 z){return ASatH3(x*y+z);} + AH4 AZolAndOrH4(AH4 x,AH4 y,AH4 z){return ASatH4(x*y+z);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AZolGtZeroH1(AH1 x){return ASatH1(x*AH1_(A_INFP_H));} + AH2 AZolGtZeroH2(AH2 x){return ASatH2(x*AH2_(A_INFP_H));} + AH3 AZolGtZeroH3(AH3 x){return ASatH3(x*AH3_(A_INFP_H));} + AH4 AZolGtZeroH4(AH4 x){return ASatH4(x*AH4_(A_INFP_H));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AZolNotH1(AH1 x){return AH1_(1.0)-x;} + AH2 AZolNotH2(AH2 x){return AH2_(1.0)-x;} + AH3 AZolNotH3(AH3 x){return AH3_(1.0)-x;} + AH4 AZolNotH4(AH4 x){return AH4_(1.0)-x;} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AZolOrH1(AH1 x,AH1 y){return max(x,y);} + AH2 AZolOrH2(AH2 x,AH2 y){return max(x,y);} + AH3 AZolOrH3(AH3 x,AH3 y){return max(x,y);} + AH4 AZolOrH4(AH4 x,AH4 y){return max(x,y);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AZolSelH1(AH1 x,AH1 y,AH1 z){AH1 r=(-x)*z+z;return x*y+r;} + AH2 AZolSelH2(AH2 x,AH2 y,AH2 z){AH2 r=(-x)*z+z;return x*y+r;} + AH3 AZolSelH3(AH3 x,AH3 y,AH3 z){AH3 r=(-x)*z+z;return x*y+r;} + AH4 AZolSelH4(AH4 x,AH4 y,AH4 z){AH4 r=(-x)*z+z;return x*y+r;} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AZolSignedH1(AH1 x){return ASatH1(x*AH1_(A_INFN_H));} + AH2 AZolSignedH2(AH2 x){return ASatH2(x*AH2_(A_INFN_H));} + AH3 AZolSignedH3(AH3 x){return ASatH3(x*AH3_(A_INFN_H));} + AH4 AZolSignedH4(AH4 x){return ASatH4(x*AH4_(A_INFN_H));} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// COLOR CONVERSIONS +//------------------------------------------------------------------------------------------------------------------------------ +// These are all linear to/from some other space (where 'linear' has been shortened out of the function name). +// So 'ToGamma' is 'LinearToGamma', and 'FromGamma' is 'LinearFromGamma'. +// These are branch free implementations. +// The AToSrgbF1() function is useful for stores for compute shaders for GPUs without hardware linear->sRGB store conversion. +//------------------------------------------------------------------------------------------------------------------------------ +// TRANSFER FUNCTIONS +// ================== +// 709 ..... Rec709 used for some HDTVs +// Gamma ... Typically 2.2 for some PC displays, or 2.4-2.5 for CRTs, or 2.2 FreeSync2 native +// Pq ...... PQ native for HDR10 +// Srgb .... The sRGB output, typical of PC displays, useful for 10-bit output, or storing to 8-bit UNORM without SRGB type +// Two ..... Gamma 2.0, fastest conversion (useful for intermediate pass approximations) +// Three ... Gamma 3.0, less fast, but good for HDR. +//------------------------------------------------------------------------------------------------------------------------------ +// KEEPING TO SPEC +// =============== +// Both Rec.709 and sRGB have a linear segment which as spec'ed would intersect the curved segment 2 times. +// (a.) For 8-bit sRGB, steps {0 to 10.3} are in the linear region (4% of the encoding range). +// (b.) For 8-bit 709, steps {0 to 20.7} are in the linear region (8% of the encoding range). +// Also there is a slight step in the transition regions. +// Precision of the coefficients in the spec being the likely cause. +// Main usage case of the sRGB code is to do the linear->sRGB converstion in a compute shader before store. +// This is to work around lack of hardware (typically only ROP does the conversion for free). +// To "correct" the linear segment, would be to introduce error, because hardware decode of sRGB->linear is fixed (and free). +// So this header keeps with the spec. +// For linear->sRGB transforms, the linear segment in some respects reduces error, because rounding in that region is linear. +// Rounding in the curved region in hardware (and fast software code) introduces error due to rounding in non-linear. +//------------------------------------------------------------------------------------------------------------------------------ +// FOR PQ +// ====== +// Both input and output is {0.0-1.0}, and where output 1.0 represents 10000.0 cd/m^2. +// All constants are only specified to FP32 precision. +// External PQ source reference, +// - https://github.com/ampas/aces-dev/blob/master/transforms/ctl/utilities/ACESlib.Utilities_Color.a1.0.1.ctl +//------------------------------------------------------------------------------------------------------------------------------ +// PACKED VERSIONS +// =============== +// These are the A*H2() functions. +// There is no PQ functions as FP16 seemed to not have enough precision for the conversion. +// The remaining functions are "good enough" for 8-bit, and maybe 10-bit if not concerned about a few 1-bit errors. +// Precision is lowest in the 709 conversion, higher in sRGB, higher still in Two and Gamma (when using 2.2 at least). +//------------------------------------------------------------------------------------------------------------------------------ +// NOTES +// ===== +// Could be faster for PQ conversions to be in ALU or a texture lookup depending on usage case. +//============================================================================================================================== + #if 1 + AF1 ATo709F1(AF1 c){AF3 j=AF3(0.018*4.5,4.5,0.45);AF2 k=AF2(1.099,-0.099); + return clamp(j.x ,c*j.y ,pow(c,j.z )*k.x +k.y );} + AF2 ATo709F2(AF2 c){AF3 j=AF3(0.018*4.5,4.5,0.45);AF2 k=AF2(1.099,-0.099); + return clamp(j.xx ,c*j.yy ,pow(c,j.zz )*k.xx +k.yy );} + AF3 ATo709F3(AF3 c){AF3 j=AF3(0.018*4.5,4.5,0.45);AF2 k=AF2(1.099,-0.099); + return clamp(j.xxx,c*j.yyy,pow(c,j.zzz)*k.xxx+k.yyy);} +//------------------------------------------------------------------------------------------------------------------------------ + // Note 'rcpX' is '1/x', where the 'x' is what would be used in AFromGamma(). + AF1 AToGammaF1(AF1 c,AF1 rcpX){return pow(c,AF1_(rcpX));} + AF2 AToGammaF2(AF2 c,AF1 rcpX){return pow(c,AF2_(rcpX));} + AF3 AToGammaF3(AF3 c,AF1 rcpX){return pow(c,AF3_(rcpX));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AToPqF1(AF1 x){AF1 p=pow(x,AF1_(0.159302)); + return pow((AF1_(0.835938)+AF1_(18.8516)*p)/(AF1_(1.0)+AF1_(18.6875)*p),AF1_(78.8438));} + AF2 AToPqF1(AF2 x){AF2 p=pow(x,AF2_(0.159302)); + return pow((AF2_(0.835938)+AF2_(18.8516)*p)/(AF2_(1.0)+AF2_(18.6875)*p),AF2_(78.8438));} + AF3 AToPqF1(AF3 x){AF3 p=pow(x,AF3_(0.159302)); + return pow((AF3_(0.835938)+AF3_(18.8516)*p)/(AF3_(1.0)+AF3_(18.6875)*p),AF3_(78.8438));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AToSrgbF1(AF1 c){AF3 j=AF3(0.0031308*12.92,12.92,1.0/2.4);AF2 k=AF2(1.055,-0.055); + return clamp(j.x ,c*j.y ,pow(c,j.z )*k.x +k.y );} + AF2 AToSrgbF2(AF2 c){AF3 j=AF3(0.0031308*12.92,12.92,1.0/2.4);AF2 k=AF2(1.055,-0.055); + return clamp(j.xx ,c*j.yy ,pow(c,j.zz )*k.xx +k.yy );} + AF3 AToSrgbF3(AF3 c){AF3 j=AF3(0.0031308*12.92,12.92,1.0/2.4);AF2 k=AF2(1.055,-0.055); + return clamp(j.xxx,c*j.yyy,pow(c,j.zzz)*k.xxx+k.yyy);} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AToTwoF1(AF1 c){return sqrt(c);} + AF2 AToTwoF2(AF2 c){return sqrt(c);} + AF3 AToTwoF3(AF3 c){return sqrt(c);} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AToThreeF1(AF1 c){return pow(c,AF1_(1.0/3.0));} + AF2 AToThreeF2(AF2 c){return pow(c,AF2_(1.0/3.0));} + AF3 AToThreeF3(AF3 c){return pow(c,AF3_(1.0/3.0));} + #endif +//============================================================================================================================== + #if 1 + // Unfortunately median won't work here. + AF1 AFrom709F1(AF1 c){AF3 j=AF3(0.081/4.5,1.0/4.5,1.0/0.45);AF2 k=AF2(1.0/1.099,0.099/1.099); + return AZolSelF1(AZolSignedF1(c-j.x ),c*j.y ,pow(c*k.x +k.y ,j.z ));} + AF2 AFrom709F2(AF2 c){AF3 j=AF3(0.081/4.5,1.0/4.5,1.0/0.45);AF2 k=AF2(1.0/1.099,0.099/1.099); + return AZolSelF2(AZolSignedF2(c-j.xx ),c*j.yy ,pow(c*k.xx +k.yy ,j.zz ));} + AF3 AFrom709F3(AF3 c){AF3 j=AF3(0.081/4.5,1.0/4.5,1.0/0.45);AF2 k=AF2(1.0/1.099,0.099/1.099); + return AZolSelF3(AZolSignedF3(c-j.xxx),c*j.yyy,pow(c*k.xxx+k.yyy,j.zzz));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AFromGammaF1(AF1 c,AF1 x){return pow(c,AF1_(x));} + AF2 AFromGammaF2(AF2 c,AF1 x){return pow(c,AF2_(x));} + AF3 AFromGammaF3(AF3 c,AF1 x){return pow(c,AF3_(x));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AFromPqF1(AF1 x){AF1 p=pow(x,AF1_(0.0126833)); + return pow(ASatF1(p-AF1_(0.835938))/(AF1_(18.8516)-AF1_(18.6875)*p),AF1_(6.27739));} + AF2 AFromPqF1(AF2 x){AF2 p=pow(x,AF2_(0.0126833)); + return pow(ASatF2(p-AF2_(0.835938))/(AF2_(18.8516)-AF2_(18.6875)*p),AF2_(6.27739));} + AF3 AFromPqF1(AF3 x){AF3 p=pow(x,AF3_(0.0126833)); + return pow(ASatF3(p-AF3_(0.835938))/(AF3_(18.8516)-AF3_(18.6875)*p),AF3_(6.27739));} +//------------------------------------------------------------------------------------------------------------------------------ + // Unfortunately median won't work here. + AF1 AFromSrgbF1(AF1 c){AF3 j=AF3(0.04045/12.92,1.0/12.92,2.4);AF2 k=AF2(1.0/1.055,0.055/1.055); + return AZolSelF1(AZolSignedF1(c-j.x ),c*j.y ,pow(c*k.x +k.y ,j.z ));} + AF2 AFromSrgbF2(AF2 c){AF3 j=AF3(0.04045/12.92,1.0/12.92,2.4);AF2 k=AF2(1.0/1.055,0.055/1.055); + return AZolSelF2(AZolSignedF2(c-j.xx ),c*j.yy ,pow(c*k.xx +k.yy ,j.zz ));} + AF3 AFromSrgbF3(AF3 c){AF3 j=AF3(0.04045/12.92,1.0/12.92,2.4);AF2 k=AF2(1.0/1.055,0.055/1.055); + return AZolSelF3(AZolSignedF3(c-j.xxx),c*j.yyy,pow(c*k.xxx+k.yyy,j.zzz));} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AFromTwoF1(AF1 c){return c*c;} + AF2 AFromTwoF2(AF2 c){return c*c;} + AF3 AFromTwoF3(AF3 c){return c*c;} +//------------------------------------------------------------------------------------------------------------------------------ + AF1 AFromThreeF1(AF1 c){return c*c*c;} + AF2 AFromThreeF2(AF2 c){return c*c*c;} + AF3 AFromThreeF3(AF3 c){return c*c*c;} + #endif +//============================================================================================================================== + #ifdef A_HALF + AH1 ATo709H1(AH1 c){AH3 j=AH3(0.018*4.5,4.5,0.45);AH2 k=AH2(1.099,-0.099); + return clamp(j.x ,c*j.y ,pow(c,j.z )*k.x +k.y );} + AH2 ATo709H2(AH2 c){AH3 j=AH3(0.018*4.5,4.5,0.45);AH2 k=AH2(1.099,-0.099); + return clamp(j.xx ,c*j.yy ,pow(c,j.zz )*k.xx +k.yy );} + AH3 ATo709H3(AH3 c){AH3 j=AH3(0.018*4.5,4.5,0.45);AH2 k=AH2(1.099,-0.099); + return clamp(j.xxx,c*j.yyy,pow(c,j.zzz)*k.xxx+k.yyy);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AToGammaH1(AH1 c,AH1 rcpX){return pow(c,AH1_(rcpX));} + AH2 AToGammaH2(AH2 c,AH1 rcpX){return pow(c,AH2_(rcpX));} + AH3 AToGammaH3(AH3 c,AH1 rcpX){return pow(c,AH3_(rcpX));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AToSrgbH1(AH1 c){AH3 j=AH3(0.0031308*12.92,12.92,1.0/2.4);AH2 k=AH2(1.055,-0.055); + return clamp(j.x ,c*j.y ,pow(c,j.z )*k.x +k.y );} + AH2 AToSrgbH2(AH2 c){AH3 j=AH3(0.0031308*12.92,12.92,1.0/2.4);AH2 k=AH2(1.055,-0.055); + return clamp(j.xx ,c*j.yy ,pow(c,j.zz )*k.xx +k.yy );} + AH3 AToSrgbH3(AH3 c){AH3 j=AH3(0.0031308*12.92,12.92,1.0/2.4);AH2 k=AH2(1.055,-0.055); + return clamp(j.xxx,c*j.yyy,pow(c,j.zzz)*k.xxx+k.yyy);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AToTwoH1(AH1 c){return sqrt(c);} + AH2 AToTwoH2(AH2 c){return sqrt(c);} + AH3 AToTwoH3(AH3 c){return sqrt(c);} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AToThreeF1(AH1 c){return pow(c,AH1_(1.0/3.0));} + AH2 AToThreeF2(AH2 c){return pow(c,AH2_(1.0/3.0));} + AH3 AToThreeF3(AH3 c){return pow(c,AH3_(1.0/3.0));} + #endif +//============================================================================================================================== + #ifdef A_HALF + AH1 AFrom709H1(AH1 c){AH3 j=AH3(0.081/4.5,1.0/4.5,1.0/0.45);AH2 k=AH2(1.0/1.099,0.099/1.099); + return AZolSelH1(AZolSignedH1(c-j.x ),c*j.y ,pow(c*k.x +k.y ,j.z ));} + AH2 AFrom709H2(AH2 c){AH3 j=AH3(0.081/4.5,1.0/4.5,1.0/0.45);AH2 k=AH2(1.0/1.099,0.099/1.099); + return AZolSelH2(AZolSignedH2(c-j.xx ),c*j.yy ,pow(c*k.xx +k.yy ,j.zz ));} + AH3 AFrom709H3(AH3 c){AH3 j=AH3(0.081/4.5,1.0/4.5,1.0/0.45);AH2 k=AH2(1.0/1.099,0.099/1.099); + return AZolSelH3(AZolSignedH3(c-j.xxx),c*j.yyy,pow(c*k.xxx+k.yyy,j.zzz));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AFromGammaH1(AH1 c,AH1 x){return pow(c,AH1_(x));} + AH2 AFromGammaH2(AH2 c,AH1 x){return pow(c,AH2_(x));} + AH3 AFromGammaH3(AH3 c,AH1 x){return pow(c,AH3_(x));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AHromSrgbF1(AH1 c){AH3 j=AH3(0.04045/12.92,1.0/12.92,2.4);AH2 k=AH2(1.0/1.055,0.055/1.055); + return AZolSelH1(AZolSignedH1(c-j.x ),c*j.y ,pow(c*k.x +k.y ,j.z ));} + AH2 AHromSrgbF2(AH2 c){AH3 j=AH3(0.04045/12.92,1.0/12.92,2.4);AH2 k=AH2(1.0/1.055,0.055/1.055); + return AZolSelH2(AZolSignedH2(c-j.xx ),c*j.yy ,pow(c*k.xx +k.yy ,j.zz ));} + AH3 AHromSrgbF3(AH3 c){AH3 j=AH3(0.04045/12.92,1.0/12.92,2.4);AH2 k=AH2(1.0/1.055,0.055/1.055); + return AZolSelH3(AZolSignedH3(c-j.xxx),c*j.yyy,pow(c*k.xxx+k.yyy,j.zzz));} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AFromTwoH1(AH1 c){return c*c;} + AH2 AFromTwoH2(AH2 c){return c*c;} + AH3 AFromTwoH3(AH3 c){return c*c;} +//------------------------------------------------------------------------------------------------------------------------------ + AH1 AFromThreeH1(AH1 c){return c*c*c;} + AH2 AFromThreeH2(AH2 c){return c*c*c;} + AH3 AFromThreeH3(AH3 c){return c*c*c;} + #endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// CS REMAP +//============================================================================================================================== + // Simple remap 64x1 to 8x8 with rotated 2x2 pixel quads in quad linear. + // 543210 + // ====== + // ..xxx. + // yy...y + AU2 ARmp8x8(AU1 a){return AU2(ABfe(a,1u,3u),ABfiM(ABfe(a,3u,3u),a,1u));} +//============================================================================================================================== + // More complex remap 64x1 to 8x8 which is necessary for 2D wave reductions. + // 543210 + // ====== + // .xx..x + // y..yy. + // Details, + // LANE TO 8x8 MAPPING + // =================== + // 00 01 08 09 10 11 18 19 + // 02 03 0a 0b 12 13 1a 1b + // 04 05 0c 0d 14 15 1c 1d + // 06 07 0e 0f 16 17 1e 1f + // 20 21 28 29 30 31 38 39 + // 22 23 2a 2b 32 33 3a 3b + // 24 25 2c 2d 34 35 3c 3d + // 26 27 2e 2f 36 37 3e 3f + AU2 ARmpRed8x8(AU1 a){return AU2(ABfiM(ABfe(a,2u,3u),a,1u),ABfiM(ABfe(a,3u,3u),ABfe(a,1u,2u),2u));} +//============================================================================================================================== + #ifdef A_HALF + AW2 ARmp8x8H(AU1 a){return AW2(ABfe(a,1u,3u),ABfiM(ABfe(a,3u,3u),a,1u));} + AW2 ARmpRed8x8H(AU1 a){return AW2(ABfiM(ABfe(a,2u,3u),a,1u),ABfiM(ABfe(a,3u,3u),ABfe(a,1u,2u),2u));} + #endif +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// REFERENCE +// +//------------------------------------------------------------------------------------------------------------------------------ +// IEEE FLOAT RULES +// ================ +// - saturate(NaN)=0, saturate(-INF)=0, saturate(+INF)=1 +// - {+/-}0 * {+/-}INF = NaN +// - -INF + (+INF) = NaN +// - {+/-}0 / {+/-}0 = NaN +// - {+/-}INF / {+/-}INF = NaN +// - a<(-0) := sqrt(a) = NaN (a=-0.0 won't NaN) +// - 0 == -0 +// - 4/0 = +INF +// - 4/-0 = -INF +// - 4+INF = +INF +// - 4-INF = -INF +// - 4*(+INF) = +INF +// - 4*(-INF) = -INF +// - -4*(+INF) = -INF +// - sqrt(+INF) = +INF +//------------------------------------------------------------------------------------------------------------------------------ +// FP16 ENCODING +// ============= +// fedcba9876543210 +// ---------------- +// ......mmmmmmmmmm 10-bit mantissa (encodes 11-bit 0.5 to 1.0 except for denormals) +// .eeeee.......... 5-bit exponent +// .00000.......... denormals +// .00001.......... -14 exponent +// .11110.......... 15 exponent +// .111110000000000 infinity +// .11111nnnnnnnnnn NaN with n!=0 +// s............... sign +//------------------------------------------------------------------------------------------------------------------------------ +// FP16/INT16 ALIASING DENORMAL +// ============================ +// 11-bit unsigned integers alias with half float denormal/normal values, +// 1 = 2^(-24) = 1/16777216 ....................... first denormal value +// 2 = 2^(-23) +// ... +// 1023 = 2^(-14)*(1-2^(-10)) = 2^(-14)*(1-1/1024) ... last denormal value +// 1024 = 2^(-14) = 1/16384 .......................... first normal value that still maps to integers +// 2047 .............................................. last normal value that still maps to integers +// Scaling limits, +// 2^15 = 32768 ...................................... largest power of 2 scaling +// Largest pow2 conversion mapping is at *32768, +// 1 : 2^(-9) = 1/512 +// 2 : 1/256 +// 4 : 1/128 +// 8 : 1/64 +// 16 : 1/32 +// 32 : 1/16 +// 64 : 1/8 +// 128 : 1/4 +// 256 : 1/2 +// 512 : 1 +// 1024 : 2 +// 2047 : a little less than 4 +//============================================================================================================================== +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// +// GPU/CPU PORTABILITY +// +// +//------------------------------------------------------------------------------------------------------------------------------ +// This is the GPU implementation. +// See the CPU implementation for docs. +//============================================================================================================================== +#ifdef A_GPU + #define A_TRUE true + #define A_FALSE false + #define A_STATIC +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// VECTOR ARGUMENT/RETURN/INITIALIZATION PORTABILITY +//============================================================================================================================== + #define retAD2 AD2 + #define retAD3 AD3 + #define retAD4 AD4 + #define retAF2 AF2 + #define retAF3 AF3 + #define retAF4 AF4 + #define retAL2 AL2 + #define retAL3 AL3 + #define retAL4 AL4 + #define retAU2 AU2 + #define retAU3 AU3 + #define retAU4 AU4 +//------------------------------------------------------------------------------------------------------------------------------ + #define inAD2 in AD2 + #define inAD3 in AD3 + #define inAD4 in AD4 + #define inAF2 in AF2 + #define inAF3 in AF3 + #define inAF4 in AF4 + #define inAL2 in AL2 + #define inAL3 in AL3 + #define inAL4 in AL4 + #define inAU2 in AU2 + #define inAU3 in AU3 + #define inAU4 in AU4 +//------------------------------------------------------------------------------------------------------------------------------ + #define inoutAD2 inout AD2 + #define inoutAD3 inout AD3 + #define inoutAD4 inout AD4 + #define inoutAF2 inout AF2 + #define inoutAF3 inout AF3 + #define inoutAF4 inout AF4 + #define inoutAL2 inout AL2 + #define inoutAL3 inout AL3 + #define inoutAL4 inout AL4 + #define inoutAU2 inout AU2 + #define inoutAU3 inout AU3 + #define inoutAU4 inout AU4 +//------------------------------------------------------------------------------------------------------------------------------ + #define outAD2 out AD2 + #define outAD3 out AD3 + #define outAD4 out AD4 + #define outAF2 out AF2 + #define outAF3 out AF3 + #define outAF4 out AF4 + #define outAL2 out AL2 + #define outAL3 out AL3 + #define outAL4 out AL4 + #define outAU2 out AU2 + #define outAU3 out AU3 + #define outAU4 out AU4 +//------------------------------------------------------------------------------------------------------------------------------ + #define varAD2(x) AD2 x + #define varAD3(x) AD3 x + #define varAD4(x) AD4 x + #define varAF2(x) AF2 x + #define varAF3(x) AF3 x + #define varAF4(x) AF4 x + #define varAL2(x) AL2 x + #define varAL3(x) AL3 x + #define varAL4(x) AL4 x + #define varAU2(x) AU2 x + #define varAU3(x) AU3 x + #define varAU4(x) AU4 x +//------------------------------------------------------------------------------------------------------------------------------ + #define initAD2(x,y) AD2(x,y) + #define initAD3(x,y,z) AD3(x,y,z) + #define initAD4(x,y,z,w) AD4(x,y,z,w) + #define initAF2(x,y) AF2(x,y) + #define initAF3(x,y,z) AF3(x,y,z) + #define initAF4(x,y,z,w) AF4(x,y,z,w) + #define initAL2(x,y) AL2(x,y) + #define initAL3(x,y,z) AL3(x,y,z) + #define initAL4(x,y,z,w) AL4(x,y,z,w) + #define initAU2(x,y) AU2(x,y) + #define initAU3(x,y,z) AU3(x,y,z) + #define initAU4(x,y,z,w) AU4(x,y,z,w) +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// SCALAR RETURN OPS +//============================================================================================================================== + #define AAbsD1(a) abs(AD1(a)) + #define AAbsF1(a) abs(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define ACosD1(a) cos(AD1(a)) + #define ACosF1(a) cos(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define ADotD2(a,b) dot(AD2(a),AD2(b)) + #define ADotD3(a,b) dot(AD3(a),AD3(b)) + #define ADotD4(a,b) dot(AD4(a),AD4(b)) + #define ADotF2(a,b) dot(AF2(a),AF2(b)) + #define ADotF3(a,b) dot(AF3(a),AF3(b)) + #define ADotF4(a,b) dot(AF4(a),AF4(b)) +//------------------------------------------------------------------------------------------------------------------------------ + #define AExp2D1(a) exp2(AD1(a)) + #define AExp2F1(a) exp2(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define AFloorD1(a) floor(AD1(a)) + #define AFloorF1(a) floor(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define ALog2D1(a) log2(AD1(a)) + #define ALog2F1(a) log2(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define AMaxD1(a,b) max(a,b) + #define AMaxF1(a,b) max(a,b) + #define AMaxL1(a,b) max(a,b) + #define AMaxU1(a,b) max(a,b) +//------------------------------------------------------------------------------------------------------------------------------ + #define AMinD1(a,b) min(a,b) + #define AMinF1(a,b) min(a,b) + #define AMinL1(a,b) min(a,b) + #define AMinU1(a,b) min(a,b) +//------------------------------------------------------------------------------------------------------------------------------ + #define ASinD1(a) sin(AD1(a)) + #define ASinF1(a) sin(AF1(a)) +//------------------------------------------------------------------------------------------------------------------------------ + #define ASqrtD1(a) sqrt(AD1(a)) + #define ASqrtF1(a) sqrt(AF1(a)) +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// SCALAR RETURN OPS - DEPENDENT +//============================================================================================================================== + #define APowD1(a,b) pow(AD1(a),AF1(b)) + #define APowF1(a,b) pow(AF1(a),AF1(b)) +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// VECTOR OPS +//------------------------------------------------------------------------------------------------------------------------------ +// These are added as needed for production or prototyping, so not necessarily a complete set. +// They follow a convention of taking in a destination and also returning the destination value to increase utility. +//============================================================================================================================== + #ifdef A_DUBL + AD2 opAAbsD2(outAD2 d,inAD2 a){d=abs(a);return d;} + AD3 opAAbsD3(outAD3 d,inAD3 a){d=abs(a);return d;} + AD4 opAAbsD4(outAD4 d,inAD4 a){d=abs(a);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opAAddD2(outAD2 d,inAD2 a,inAD2 b){d=a+b;return d;} + AD3 opAAddD3(outAD3 d,inAD3 a,inAD3 b){d=a+b;return d;} + AD4 opAAddD4(outAD4 d,inAD4 a,inAD4 b){d=a+b;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opAAddOneD2(outAD2 d,inAD2 a,AD1 b){d=a+AD2_(b);return d;} + AD3 opAAddOneD3(outAD3 d,inAD3 a,AD1 b){d=a+AD3_(b);return d;} + AD4 opAAddOneD4(outAD4 d,inAD4 a,AD1 b){d=a+AD4_(b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opACpyD2(outAD2 d,inAD2 a){d=a;return d;} + AD3 opACpyD3(outAD3 d,inAD3 a){d=a;return d;} + AD4 opACpyD4(outAD4 d,inAD4 a){d=a;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opALerpD2(outAD2 d,inAD2 a,inAD2 b,inAD2 c){d=ALerpD2(a,b,c);return d;} + AD3 opALerpD3(outAD3 d,inAD3 a,inAD3 b,inAD3 c){d=ALerpD3(a,b,c);return d;} + AD4 opALerpD4(outAD4 d,inAD4 a,inAD4 b,inAD4 c){d=ALerpD4(a,b,c);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opALerpOneD2(outAD2 d,inAD2 a,inAD2 b,AD1 c){d=ALerpD2(a,b,AD2_(c));return d;} + AD3 opALerpOneD3(outAD3 d,inAD3 a,inAD3 b,AD1 c){d=ALerpD3(a,b,AD3_(c));return d;} + AD4 opALerpOneD4(outAD4 d,inAD4 a,inAD4 b,AD1 c){d=ALerpD4(a,b,AD4_(c));return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opAMaxD2(outAD2 d,inAD2 a,inAD2 b){d=max(a,b);return d;} + AD3 opAMaxD3(outAD3 d,inAD3 a,inAD3 b){d=max(a,b);return d;} + AD4 opAMaxD4(outAD4 d,inAD4 a,inAD4 b){d=max(a,b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opAMinD2(outAD2 d,inAD2 a,inAD2 b){d=min(a,b);return d;} + AD3 opAMinD3(outAD3 d,inAD3 a,inAD3 b){d=min(a,b);return d;} + AD4 opAMinD4(outAD4 d,inAD4 a,inAD4 b){d=min(a,b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opAMulD2(outAD2 d,inAD2 a,inAD2 b){d=a*b;return d;} + AD3 opAMulD3(outAD3 d,inAD3 a,inAD3 b){d=a*b;return d;} + AD4 opAMulD4(outAD4 d,inAD4 a,inAD4 b){d=a*b;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opAMulOneD2(outAD2 d,inAD2 a,AD1 b){d=a*AD2_(b);return d;} + AD3 opAMulOneD3(outAD3 d,inAD3 a,AD1 b){d=a*AD3_(b);return d;} + AD4 opAMulOneD4(outAD4 d,inAD4 a,AD1 b){d=a*AD4_(b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opANegD2(outAD2 d,inAD2 a){d=-a;return d;} + AD3 opANegD3(outAD3 d,inAD3 a){d=-a;return d;} + AD4 opANegD4(outAD4 d,inAD4 a){d=-a;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AD2 opARcpD2(outAD2 d,inAD2 a){d=ARcpD2(a);return d;} + AD3 opARcpD3(outAD3 d,inAD3 a){d=ARcpD3(a);return d;} + AD4 opARcpD4(outAD4 d,inAD4 a){d=ARcpD4(a);return d;} + #endif +//============================================================================================================================== + AF2 opAAbsF2(outAF2 d,inAF2 a){d=abs(a);return d;} + AF3 opAAbsF3(outAF3 d,inAF3 a){d=abs(a);return d;} + AF4 opAAbsF4(outAF4 d,inAF4 a){d=abs(a);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opAAddF2(outAF2 d,inAF2 a,inAF2 b){d=a+b;return d;} + AF3 opAAddF3(outAF3 d,inAF3 a,inAF3 b){d=a+b;return d;} + AF4 opAAddF4(outAF4 d,inAF4 a,inAF4 b){d=a+b;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opAAddOneF2(outAF2 d,inAF2 a,AF1 b){d=a+AF2_(b);return d;} + AF3 opAAddOneF3(outAF3 d,inAF3 a,AF1 b){d=a+AF3_(b);return d;} + AF4 opAAddOneF4(outAF4 d,inAF4 a,AF1 b){d=a+AF4_(b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opACpyF2(outAF2 d,inAF2 a){d=a;return d;} + AF3 opACpyF3(outAF3 d,inAF3 a){d=a;return d;} + AF4 opACpyF4(outAF4 d,inAF4 a){d=a;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opALerpF2(outAF2 d,inAF2 a,inAF2 b,inAF2 c){d=ALerpF2(a,b,c);return d;} + AF3 opALerpF3(outAF3 d,inAF3 a,inAF3 b,inAF3 c){d=ALerpF3(a,b,c);return d;} + AF4 opALerpF4(outAF4 d,inAF4 a,inAF4 b,inAF4 c){d=ALerpF4(a,b,c);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opALerpOneF2(outAF2 d,inAF2 a,inAF2 b,AF1 c){d=ALerpF2(a,b,AF2_(c));return d;} + AF3 opALerpOneF3(outAF3 d,inAF3 a,inAF3 b,AF1 c){d=ALerpF3(a,b,AF3_(c));return d;} + AF4 opALerpOneF4(outAF4 d,inAF4 a,inAF4 b,AF1 c){d=ALerpF4(a,b,AF4_(c));return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opAMaxF2(outAF2 d,inAF2 a,inAF2 b){d=max(a,b);return d;} + AF3 opAMaxF3(outAF3 d,inAF3 a,inAF3 b){d=max(a,b);return d;} + AF4 opAMaxF4(outAF4 d,inAF4 a,inAF4 b){d=max(a,b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opAMinF2(outAF2 d,inAF2 a,inAF2 b){d=min(a,b);return d;} + AF3 opAMinF3(outAF3 d,inAF3 a,inAF3 b){d=min(a,b);return d;} + AF4 opAMinF4(outAF4 d,inAF4 a,inAF4 b){d=min(a,b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opAMulF2(outAF2 d,inAF2 a,inAF2 b){d=a*b;return d;} + AF3 opAMulF3(outAF3 d,inAF3 a,inAF3 b){d=a*b;return d;} + AF4 opAMulF4(outAF4 d,inAF4 a,inAF4 b){d=a*b;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opAMulOneF2(outAF2 d,inAF2 a,AF1 b){d=a*AF2_(b);return d;} + AF3 opAMulOneF3(outAF3 d,inAF3 a,AF1 b){d=a*AF3_(b);return d;} + AF4 opAMulOneF4(outAF4 d,inAF4 a,AF1 b){d=a*AF4_(b);return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opANegF2(outAF2 d,inAF2 a){d=-a;return d;} + AF3 opANegF3(outAF3 d,inAF3 a){d=-a;return d;} + AF4 opANegF4(outAF4 d,inAF4 a){d=-a;return d;} +//------------------------------------------------------------------------------------------------------------------------------ + AF2 opARcpF2(outAF2 d,inAF2 a){d=ARcpF2(a);return d;} + AF3 opARcpF3(outAF3 d,inAF3 a){d=ARcpF3(a);return d;} + AF4 opARcpF4(outAF4 d,inAF4 a){d=ARcpF4(a);return d;} +#endif diff --git a/gpu/shadps4/video_core/host_shaders/fsr/ffx_fsr1.h b/gpu/shadps4/video_core/host_shaders/fsr/ffx_fsr1.h new file mode 100644 index 0000000..b0fe75e --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/fsr/ffx_fsr1.h @@ -0,0 +1,1200 @@ +// clang-format off +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// +// AMD FidelityFX SUPER RESOLUTION [FSR 1] ::: SPATIAL SCALING & EXTRAS - v1.20210629 +// +// +//------------------------------------------------------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------------------------ +// FidelityFX Super Resolution Sample +// +// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// 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 Software. +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +//------------------------------------------------------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------------------------ +// ABOUT +// ===== +// FSR is a collection of algorithms relating to generating a higher resolution image. +// This specific header focuses on single-image non-temporal image scaling, and related tools. +// +// The core functions are EASU and RCAS: +// [EASU] Edge Adaptive Spatial Upsampling ....... 1x to 4x area range spatial scaling, clamped adaptive elliptical filter. +// [RCAS] Robust Contrast Adaptive Sharpening .... A non-scaling variation on CAS. +// RCAS needs to be applied after EASU as a separate pass. +// +// Optional utility functions are: +// [LFGA] Linear Film Grain Applicator ........... Tool to apply film grain after scaling. +// [SRTM] Simple Reversible Tone-Mapper .......... Linear HDR {0 to FP16_MAX} to {0 to 1} and back. +// [TEPD] Temporal Energy Preserving Dither ...... Temporally energy preserving dithered {0 to 1} linear to gamma 2.0 conversion. +// See each individual sub-section for inline documentation. +//------------------------------------------------------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------------------------ +// FUNCTION PERMUTATIONS +// ===================== +// *F() ..... Single item computation with 32-bit. +// *H() ..... Single item computation with 16-bit, with packing (aka two 16-bit ops in parallel) when possible. +// *Hx2() ... Processing two items in parallel with 16-bit, easier packing. +// Not all interfaces in this file have a *Hx2() form. +//============================================================================================================================== +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// FSR - [EASU] EDGE ADAPTIVE SPATIAL UPSAMPLING +// +//------------------------------------------------------------------------------------------------------------------------------ +// EASU provides a high quality spatial-only scaling at relatively low cost. +// Meaning EASU is appropiate for laptops and other low-end GPUs. +// Quality from 1x to 4x area scaling is good. +//------------------------------------------------------------------------------------------------------------------------------ +// The scalar uses a modified fast approximation to the standard lanczos(size=2) kernel. +// EASU runs in a single pass, so it applies a directionally and anisotropically adaptive radial lanczos. +// This is also kept as simple as possible to have minimum runtime. +//------------------------------------------------------------------------------------------------------------------------------ +// The lanzcos filter has negative lobes, so by itself it will introduce ringing. +// To remove all ringing, the algorithm uses the nearest 2x2 input texels as a neighborhood, +// and limits output to the minimum and maximum of that neighborhood. +//------------------------------------------------------------------------------------------------------------------------------ +// Input image requirements: +// +// Color needs to be encoded as 3 channel[red, green, blue](e.g.XYZ not supported) +// Each channel needs to be in the range[0, 1] +// Any color primaries are supported +// Display / tonemapping curve needs to be as if presenting to sRGB display or similar(e.g.Gamma 2.0) +// There should be no banding in the input +// There should be no high amplitude noise in the input +// There should be no noise in the input that is not at input pixel granularity +// For performance purposes, use 32bpp formats +//------------------------------------------------------------------------------------------------------------------------------ +// Best to apply EASU at the end of the frame after tonemapping +// but before film grain or composite of the UI. +//------------------------------------------------------------------------------------------------------------------------------ +// Example of including this header for D3D HLSL : +// +// #define A_GPU 1 +// #define A_HLSL 1 +// #define A_HALF 1 +// #include "ffx_a.h" +// #define FSR_EASU_H 1 +// #define FSR_RCAS_H 1 +// //declare input callbacks +// #include "ffx_fsr1.h" +// +// Example of including this header for Vulkan GLSL : +// +// #define A_GPU 1 +// #define A_GLSL 1 +// #define A_HALF 1 +// #include "ffx_a.h" +// #define FSR_EASU_H 1 +// #define FSR_RCAS_H 1 +// //declare input callbacks +// #include "ffx_fsr1.h" +// +// Example of including this header for Vulkan HLSL : +// +// #define A_GPU 1 +// #define A_HLSL 1 +// #define A_HLSL_6_2 1 +// #define A_NO_16_BIT_CAST 1 +// #define A_HALF 1 +// #include "ffx_a.h" +// #define FSR_EASU_H 1 +// #define FSR_RCAS_H 1 +// //declare input callbacks +// #include "ffx_fsr1.h" +// +// Example of declaring the required input callbacks for GLSL : +// The callbacks need to gather4 for each color channel using the specified texture coordinate 'p'. +// EASU uses gather4 to reduce position computation logic and for free Arrays of Structures to Structures of Arrays conversion. +// +// AH4 FsrEasuRH(AF2 p){return AH4(textureGather(sampler2D(tex,sam),p,0));} +// AH4 FsrEasuGH(AF2 p){return AH4(textureGather(sampler2D(tex,sam),p,1));} +// AH4 FsrEasuBH(AF2 p){return AH4(textureGather(sampler2D(tex,sam),p,2));} +// ... +// The FsrEasuCon function needs to be called from the CPU or GPU to set up constants. +// The difference in viewport and input image size is there to support Dynamic Resolution Scaling. +// To use FsrEasuCon() on the CPU, define A_CPU before including ffx_a and ffx_fsr1. +// Including a GPU example here, the 'con0' through 'con3' values would be stored out to a constant buffer. +// AU4 con0,con1,con2,con3; +// FsrEasuCon(con0,con1,con2,con3, +// 1920.0,1080.0, // Viewport size (top left aligned) in the input image which is to be scaled. +// 3840.0,2160.0, // The size of the input image. +// 2560.0,1440.0); // The output resolution. +//============================================================================================================================== +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// CONSTANT SETUP +//============================================================================================================================== +// Call to setup required constant values (works on CPU or GPU). +A_STATIC void FsrEasuCon( +outAU4 con0, +outAU4 con1, +outAU4 con2, +outAU4 con3, +// This the rendered image resolution being upscaled +AF1 inputViewportInPixelsX, +AF1 inputViewportInPixelsY, +// This is the resolution of the resource containing the input image (useful for dynamic resolution) +AF1 inputSizeInPixelsX, +AF1 inputSizeInPixelsY, +// This is the display resolution which the input image gets upscaled to +AF1 outputSizeInPixelsX, +AF1 outputSizeInPixelsY){ + // Output integer position to a pixel position in viewport. + con0[0]=AU1_AF1(inputViewportInPixelsX*ARcpF1(outputSizeInPixelsX)); + con0[1]=AU1_AF1(inputViewportInPixelsY*ARcpF1(outputSizeInPixelsY)); + con0[2]=AU1_AF1(AF1_(0.5)*inputViewportInPixelsX*ARcpF1(outputSizeInPixelsX)-AF1_(0.5)); + con0[3]=AU1_AF1(AF1_(0.5)*inputViewportInPixelsY*ARcpF1(outputSizeInPixelsY)-AF1_(0.5)); + // Viewport pixel position to normalized image space. + // This is used to get upper-left of 'F' tap. + con1[0]=AU1_AF1(ARcpF1(inputSizeInPixelsX)); + con1[1]=AU1_AF1(ARcpF1(inputSizeInPixelsY)); + // Centers of gather4, first offset from upper-left of 'F'. + // +---+---+ + // | | | + // +--(0)--+ + // | b | c | + // +---F---+---+---+ + // | e | f | g | h | + // +--(1)--+--(2)--+ + // | i | j | k | l | + // +---+---+---+---+ + // | n | o | + // +--(3)--+ + // | | | + // +---+---+ + con1[2]=AU1_AF1(AF1_( 1.0)*ARcpF1(inputSizeInPixelsX)); + con1[3]=AU1_AF1(AF1_(-1.0)*ARcpF1(inputSizeInPixelsY)); + // These are from (0) instead of 'F'. + con2[0]=AU1_AF1(AF1_(-1.0)*ARcpF1(inputSizeInPixelsX)); + con2[1]=AU1_AF1(AF1_( 2.0)*ARcpF1(inputSizeInPixelsY)); + con2[2]=AU1_AF1(AF1_( 1.0)*ARcpF1(inputSizeInPixelsX)); + con2[3]=AU1_AF1(AF1_( 2.0)*ARcpF1(inputSizeInPixelsY)); + con3[0]=AU1_AF1(AF1_( 0.0)*ARcpF1(inputSizeInPixelsX)); + con3[1]=AU1_AF1(AF1_( 4.0)*ARcpF1(inputSizeInPixelsY)); + con3[2]=con3[3]=0;} + +//If the an offset into the input image resource +A_STATIC void FsrEasuConOffset( + outAU4 con0, + outAU4 con1, + outAU4 con2, + outAU4 con3, + // This the rendered image resolution being upscaled + AF1 inputViewportInPixelsX, + AF1 inputViewportInPixelsY, + // This is the resolution of the resource containing the input image (useful for dynamic resolution) + AF1 inputSizeInPixelsX, + AF1 inputSizeInPixelsY, + // This is the display resolution which the input image gets upscaled to + AF1 outputSizeInPixelsX, + AF1 outputSizeInPixelsY, + // This is the input image offset into the resource containing it (useful for dynamic resolution) + AF1 inputOffsetInPixelsX, + AF1 inputOffsetInPixelsY) { + FsrEasuCon(con0, con1, con2, con3, inputViewportInPixelsX, inputViewportInPixelsY, inputSizeInPixelsX, inputSizeInPixelsY, outputSizeInPixelsX, outputSizeInPixelsY); + con0[2] = AU1_AF1(AF1_(0.5) * inputViewportInPixelsX * ARcpF1(outputSizeInPixelsX) - AF1_(0.5) + inputOffsetInPixelsX); + con0[3] = AU1_AF1(AF1_(0.5) * inputViewportInPixelsY * ARcpF1(outputSizeInPixelsY) - AF1_(0.5) + inputOffsetInPixelsY); +} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// NON-PACKED 32-BIT VERSION +//============================================================================================================================== +#if defined(A_GPU)&&defined(FSR_EASU_F) + // Input callback prototypes, need to be implemented by calling shader + AF4 FsrEasuRF(AF2 p); + AF4 FsrEasuGF(AF2 p); + AF4 FsrEasuBF(AF2 p); +//------------------------------------------------------------------------------------------------------------------------------ + // Filtering for a given tap for the scalar. + void FsrEasuTapF( + inout AF3 aC, // Accumulated color, with negative lobe. + inout AF1 aW, // Accumulated weight. + AF2 off, // Pixel offset from resolve position to tap. + AF2 dir, // Gradient direction. + AF2 len, // Length. + AF1 lob, // Negative lobe strength. + AF1 clp, // Clipping point. + AF3 c){ // Tap color. + // Rotate offset by direction. + AF2 v; + v.x=(off.x*( dir.x))+(off.y*dir.y); + v.y=(off.x*(-dir.y))+(off.y*dir.x); + // Anisotropy. + v*=len; + // Compute distance^2. + AF1 d2=v.x*v.x+v.y*v.y; + // Limit to the window as at corner, 2 taps can easily be outside. + d2=min(d2,clp); + // Approximation of lancos2 without sin() or rcp(), or sqrt() to get x. + // (25/16 * (2/5 * x^2 - 1)^2 - (25/16 - 1)) * (1/4 * x^2 - 1)^2 + // |_______________________________________| |_______________| + // base window + // The general form of the 'base' is, + // (a*(b*x^2-1)^2-(a-1)) + // Where 'a=1/(2*b-b^2)' and 'b' moves around the negative lobe. + AF1 wB=AF1_(2.0/5.0)*d2+AF1_(-1.0); + AF1 wA=lob*d2+AF1_(-1.0); + wB*=wB; + wA*=wA; + wB=AF1_(25.0/16.0)*wB+AF1_(-(25.0/16.0-1.0)); + AF1 w=wB*wA; + // Do weighted average. + aC+=c*w;aW+=w;} +//------------------------------------------------------------------------------------------------------------------------------ + // Accumulate direction and length. + void FsrEasuSetF( + inout AF2 dir, + inout AF1 len, + AF2 pp, + AP1 biS,AP1 biT,AP1 biU,AP1 biV, + AF1 lA,AF1 lB,AF1 lC,AF1 lD,AF1 lE){ + // Compute bilinear weight, branches factor out as predicates are compiler time immediates. + // s t + // u v + AF1 w = AF1_(0.0); + if(biS)w=(AF1_(1.0)-pp.x)*(AF1_(1.0)-pp.y); + if(biT)w= pp.x *(AF1_(1.0)-pp.y); + if(biU)w=(AF1_(1.0)-pp.x)* pp.y ; + if(biV)w= pp.x * pp.y ; + // Direction is the '+' diff. + // a + // b c d + // e + // Then takes magnitude from abs average of both sides of 'c'. + // Length converts gradient reversal to 0, smoothly to non-reversal at 1, shaped, then adding horz and vert terms. + AF1 dc=lD-lC; + AF1 cb=lC-lB; + AF1 lenX=max(abs(dc),abs(cb)); + lenX=APrxLoRcpF1(lenX); + AF1 dirX=lD-lB; + dir.x+=dirX*w; + lenX=ASatF1(abs(dirX)*lenX); + lenX*=lenX; + len+=lenX*w; + // Repeat for the y axis. + AF1 ec=lE-lC; + AF1 ca=lC-lA; + AF1 lenY=max(abs(ec),abs(ca)); + lenY=APrxLoRcpF1(lenY); + AF1 dirY=lE-lA; + dir.y+=dirY*w; + lenY=ASatF1(abs(dirY)*lenY); + lenY*=lenY; + len+=lenY*w;} +//------------------------------------------------------------------------------------------------------------------------------ + void FsrEasuF( + out AF3 pix, + AU2 ip, // Integer pixel position in output. + AU4 con0, // Constants generated by FsrEasuCon(). + AU4 con1, + AU4 con2, + AU4 con3){ +//------------------------------------------------------------------------------------------------------------------------------ + // Get position of 'f'. + AF2 pp=AF2(ip)*AF2_AU2(con0.xy)+AF2_AU2(con0.zw); + AF2 fp=floor(pp); + pp-=fp; +//------------------------------------------------------------------------------------------------------------------------------ + // 12-tap kernel. + // b c + // e f g h + // i j k l + // n o + // Gather 4 ordering. + // a b + // r g + // For packed FP16, need either {rg} or {ab} so using the following setup for gather in all versions, + // a b <- unused (z) + // r g + // a b a b + // r g r g + // a b + // r g <- unused (z) + // Allowing dead-code removal to remove the 'z's. + AF2 p0=fp*AF2_AU2(con1.xy)+AF2_AU2(con1.zw); + // These are from p0 to avoid pulling two constants on pre-Navi hardware. + AF2 p1=p0+AF2_AU2(con2.xy); + AF2 p2=p0+AF2_AU2(con2.zw); + AF2 p3=p0+AF2_AU2(con3.xy); + AF4 bczzR=FsrEasuRF(p0); + AF4 bczzG=FsrEasuGF(p0); + AF4 bczzB=FsrEasuBF(p0); + AF4 ijfeR=FsrEasuRF(p1); + AF4 ijfeG=FsrEasuGF(p1); + AF4 ijfeB=FsrEasuBF(p1); + AF4 klhgR=FsrEasuRF(p2); + AF4 klhgG=FsrEasuGF(p2); + AF4 klhgB=FsrEasuBF(p2); + AF4 zzonR=FsrEasuRF(p3); + AF4 zzonG=FsrEasuGF(p3); + AF4 zzonB=FsrEasuBF(p3); +//------------------------------------------------------------------------------------------------------------------------------ + // Simplest multi-channel approximate luma possible (luma times 2, in 2 FMA/MAD). + AF4 bczzL=bczzB*AF4_(0.5)+(bczzR*AF4_(0.5)+bczzG); + AF4 ijfeL=ijfeB*AF4_(0.5)+(ijfeR*AF4_(0.5)+ijfeG); + AF4 klhgL=klhgB*AF4_(0.5)+(klhgR*AF4_(0.5)+klhgG); + AF4 zzonL=zzonB*AF4_(0.5)+(zzonR*AF4_(0.5)+zzonG); + // Rename. + AF1 bL=bczzL.x; + AF1 cL=bczzL.y; + AF1 iL=ijfeL.x; + AF1 jL=ijfeL.y; + AF1 fL=ijfeL.z; + AF1 eL=ijfeL.w; + AF1 kL=klhgL.x; + AF1 lL=klhgL.y; + AF1 hL=klhgL.z; + AF1 gL=klhgL.w; + AF1 oL=zzonL.z; + AF1 nL=zzonL.w; + // Accumulate for bilinear interpolation. + AF2 dir=AF2_(0.0); + AF1 len=AF1_(0.0); + FsrEasuSetF(dir,len,pp,true, false,false,false,bL,eL,fL,gL,jL); + FsrEasuSetF(dir,len,pp,false,true ,false,false,cL,fL,gL,hL,kL); + FsrEasuSetF(dir,len,pp,false,false,true ,false,fL,iL,jL,kL,nL); + FsrEasuSetF(dir,len,pp,false,false,false,true ,gL,jL,kL,lL,oL); +//------------------------------------------------------------------------------------------------------------------------------ + // Normalize with approximation, and cleanup close to zero. + AF2 dir2=dir*dir; + AF1 dirR=dir2.x+dir2.y; + AP1 zro=dirR w = -m/(n+e+w+s) +// 1 == (w*(n+e+w+s)+m)/(4*w+1) -> w = (1-m)/(n+e+w+s-4*1) +// Then chooses the 'w' which results in no clipping, limits 'w', and multiplies by the 'sharp' amount. +// This solution above has issues with MSAA input as the steps along the gradient cause edge detection issues. +// So RCAS uses 4x the maximum and 4x the minimum (depending on equation)in place of the individual taps. +// As well as switching from 'm' to either the minimum or maximum (depending on side), to help in energy conservation. +// This stabilizes RCAS. +// RCAS does a simple highpass which is normalized against the local contrast then shaped, +// 0.25 +// 0.25 -1 0.25 +// 0.25 +// This is used as a noise detection filter, to reduce the effect of RCAS on grain, and focus on real edges. +// +// GLSL example for the required callbacks : +// +// AH4 FsrRcasLoadH(ASW2 p){return AH4(imageLoad(imgSrc,ASU2(p)));} +// void FsrRcasInputH(inout AH1 r,inout AH1 g,inout AH1 b) +// { +// //do any simple input color conversions here or leave empty if none needed +// } +// +// FsrRcasCon need to be called from the CPU or GPU to set up constants. +// Including a GPU example here, the 'con' value would be stored out to a constant buffer. +// +// AU4 con; +// FsrRcasCon(con, +// 0.0); // The scale is {0.0 := maximum sharpness, to N>0, where N is the number of stops (halving) of the reduction of sharpness}. +// --------------- +// RCAS sharpening supports a CAS-like pass-through alpha via, +// #define FSR_RCAS_PASSTHROUGH_ALPHA 1 +// RCAS also supports a define to enable a more expensive path to avoid some sharpening of noise. +// Would suggest it is better to apply film grain after RCAS sharpening (and after scaling) instead of using this define, +// #define FSR_RCAS_DENOISE 1 +//============================================================================================================================== +// This is set at the limit of providing unnatural results for sharpening. +#define FSR_RCAS_LIMIT (0.25-(1.0/16.0)) +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// CONSTANT SETUP +//============================================================================================================================== +// Call to setup required constant values (works on CPU or GPU). +A_STATIC void FsrRcasCon( +outAU4 con, +// The scale is {0.0 := maximum, to N>0, where N is the number of stops (halving) of the reduction of sharpness}. +AF1 sharpness){ + // Transform from stops to linear value. + sharpness=AExp2F1(-sharpness); + varAF2(hSharp)=initAF2(sharpness,sharpness); + con[0]=AU1_AF1(sharpness); + con[1]=AU1_AH2_AF2(hSharp); + con[2]=0; + con[3]=0;} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// NON-PACKED 32-BIT VERSION +//============================================================================================================================== +#if defined(A_GPU)&&defined(FSR_RCAS_F) + // Input callback prototypes that need to be implemented by calling shader + AF4 FsrRcasLoadF(ASU2 p); + void FsrRcasInputF(inout AF1 r,inout AF1 g,inout AF1 b); +//------------------------------------------------------------------------------------------------------------------------------ + void FsrRcasF( + out AF1 pixR, // Output values, non-vector so port between RcasFilter() and RcasFilterH() is easy. + out AF1 pixG, + out AF1 pixB, + #ifdef FSR_RCAS_PASSTHROUGH_ALPHA + out AF1 pixA, + #endif + AU2 ip, // Integer pixel position in output. + AU4 con){ // Constant generated by RcasSetup(). + // Algorithm uses minimal 3x3 pixel neighborhood. + // b + // d e f + // h + ASU2 sp=ASU2(ip); + AF3 b=FsrRcasLoadF(sp+ASU2( 0,-1)).rgb; + AF3 d=FsrRcasLoadF(sp+ASU2(-1, 0)).rgb; + #ifdef FSR_RCAS_PASSTHROUGH_ALPHA + AF4 ee=FsrRcasLoadF(sp); + AF3 e=ee.rgb;pixA=ee.a; + #else + AF3 e=FsrRcasLoadF(sp).rgb; + #endif + AF3 f=FsrRcasLoadF(sp+ASU2( 1, 0)).rgb; + AF3 h=FsrRcasLoadF(sp+ASU2( 0, 1)).rgb; + // Rename (32-bit) or regroup (16-bit). + AF1 bR=b.r; + AF1 bG=b.g; + AF1 bB=b.b; + AF1 dR=d.r; + AF1 dG=d.g; + AF1 dB=d.b; + AF1 eR=e.r; + AF1 eG=e.g; + AF1 eB=e.b; + AF1 fR=f.r; + AF1 fG=f.g; + AF1 fB=f.b; + AF1 hR=h.r; + AF1 hG=h.g; + AF1 hB=h.b; + // Run optional input transform. + FsrRcasInputF(bR,bG,bB); + FsrRcasInputF(dR,dG,dB); + FsrRcasInputF(eR,eG,eB); + FsrRcasInputF(fR,fG,fB); + FsrRcasInputF(hR,hG,hB); + // Luma times 2. + AF1 bL=bB*AF1_(0.5)+(bR*AF1_(0.5)+bG); + AF1 dL=dB*AF1_(0.5)+(dR*AF1_(0.5)+dG); + AF1 eL=eB*AF1_(0.5)+(eR*AF1_(0.5)+eG); + AF1 fL=fB*AF1_(0.5)+(fR*AF1_(0.5)+fG); + AF1 hL=hB*AF1_(0.5)+(hR*AF1_(0.5)+hG); + // Noise detection. + AF1 nz=AF1_(0.25)*bL+AF1_(0.25)*dL+AF1_(0.25)*fL+AF1_(0.25)*hL-eL; + nz=ASatF1(abs(nz)*APrxMedRcpF1(AMax3F1(AMax3F1(bL,dL,eL),fL,hL)-AMin3F1(AMin3F1(bL,dL,eL),fL,hL))); + nz=AF1_(-0.5)*nz+AF1_(1.0); + // Min and max of ring. + AF1 mn4R=min(AMin3F1(bR,dR,fR),hR); + AF1 mn4G=min(AMin3F1(bG,dG,fG),hG); + AF1 mn4B=min(AMin3F1(bB,dB,fB),hB); + AF1 mx4R=max(AMax3F1(bR,dR,fR),hR); + AF1 mx4G=max(AMax3F1(bG,dG,fG),hG); + AF1 mx4B=max(AMax3F1(bB,dB,fB),hB); + // Immediate constants for peak range. + AF2 peakC=AF2(1.0,-1.0*4.0); + // Limiters, these need to be high precision RCPs. + AF1 hitMinR=min(mn4R,eR)*ARcpF1(AF1_(4.0)*mx4R); + AF1 hitMinG=min(mn4G,eG)*ARcpF1(AF1_(4.0)*mx4G); + AF1 hitMinB=min(mn4B,eB)*ARcpF1(AF1_(4.0)*mx4B); + AF1 hitMaxR=(peakC.x-max(mx4R,eR))*ARcpF1(AF1_(4.0)*mn4R+peakC.y); + AF1 hitMaxG=(peakC.x-max(mx4G,eG))*ARcpF1(AF1_(4.0)*mn4G+peakC.y); + AF1 hitMaxB=(peakC.x-max(mx4B,eB))*ARcpF1(AF1_(4.0)*mn4B+peakC.y); + AF1 lobeR=max(-hitMinR,hitMaxR); + AF1 lobeG=max(-hitMinG,hitMaxG); + AF1 lobeB=max(-hitMinB,hitMaxB); + AF1 lobe=max(AF1_(-FSR_RCAS_LIMIT),min(AMax3F1(lobeR,lobeG,lobeB),AF1_(0.0)))*AF1_AU1(con.x); + // Apply noise removal. + #ifdef FSR_RCAS_DENOISE + lobe*=nz; + #endif + // Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes. + AF1 rcpL=APrxMedRcpF1(AF1_(4.0)*lobe+AF1_(1.0)); + pixR=(lobe*bR+lobe*dR+lobe*hR+lobe*fR+eR)*rcpL; + pixG=(lobe*bG+lobe*dG+lobe*hG+lobe*fG+eG)*rcpL; + pixB=(lobe*bB+lobe*dB+lobe*hB+lobe*fB+eB)*rcpL; + return;} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// NON-PACKED 16-BIT VERSION +//============================================================================================================================== +#if defined(A_GPU)&&defined(A_HALF)&&defined(FSR_RCAS_H) + // Input callback prototypes that need to be implemented by calling shader + AH4 FsrRcasLoadH(ASW2 p); + void FsrRcasInputH(inout AH1 r,inout AH1 g,inout AH1 b); +//------------------------------------------------------------------------------------------------------------------------------ + void FsrRcasH( + out AH1 pixR, // Output values, non-vector so port between RcasFilter() and RcasFilterH() is easy. + out AH1 pixG, + out AH1 pixB, + #ifdef FSR_RCAS_PASSTHROUGH_ALPHA + out AH1 pixA, + #endif + AU2 ip, // Integer pixel position in output. + AU4 con){ // Constant generated by RcasSetup(). + // Sharpening algorithm uses minimal 3x3 pixel neighborhood. + // b + // d e f + // h + ASW2 sp=ASW2(ip); + AH3 b=FsrRcasLoadH(sp+ASW2( 0,-1)).rgb; + AH3 d=FsrRcasLoadH(sp+ASW2(-1, 0)).rgb; + #ifdef FSR_RCAS_PASSTHROUGH_ALPHA + AH4 ee=FsrRcasLoadH(sp); + AH3 e=ee.rgb;pixA=ee.a; + #else + AH3 e=FsrRcasLoadH(sp).rgb; + #endif + AH3 f=FsrRcasLoadH(sp+ASW2( 1, 0)).rgb; + AH3 h=FsrRcasLoadH(sp+ASW2( 0, 1)).rgb; + // Rename (32-bit) or regroup (16-bit). + AH1 bR=b.r; + AH1 bG=b.g; + AH1 bB=b.b; + AH1 dR=d.r; + AH1 dG=d.g; + AH1 dB=d.b; + AH1 eR=e.r; + AH1 eG=e.g; + AH1 eB=e.b; + AH1 fR=f.r; + AH1 fG=f.g; + AH1 fB=f.b; + AH1 hR=h.r; + AH1 hG=h.g; + AH1 hB=h.b; + // Run optional input transform. + FsrRcasInputH(bR,bG,bB); + FsrRcasInputH(dR,dG,dB); + FsrRcasInputH(eR,eG,eB); + FsrRcasInputH(fR,fG,fB); + FsrRcasInputH(hR,hG,hB); + // Luma times 2. + AH1 bL=bB*AH1_(0.5)+(bR*AH1_(0.5)+bG); + AH1 dL=dB*AH1_(0.5)+(dR*AH1_(0.5)+dG); + AH1 eL=eB*AH1_(0.5)+(eR*AH1_(0.5)+eG); + AH1 fL=fB*AH1_(0.5)+(fR*AH1_(0.5)+fG); + AH1 hL=hB*AH1_(0.5)+(hR*AH1_(0.5)+hG); + // Noise detection. + AH1 nz=AH1_(0.25)*bL+AH1_(0.25)*dL+AH1_(0.25)*fL+AH1_(0.25)*hL-eL; + nz=ASatH1(abs(nz)*APrxMedRcpH1(AMax3H1(AMax3H1(bL,dL,eL),fL,hL)-AMin3H1(AMin3H1(bL,dL,eL),fL,hL))); + nz=AH1_(-0.5)*nz+AH1_(1.0); + // Min and max of ring. + AH1 mn4R=min(AMin3H1(bR,dR,fR),hR); + AH1 mn4G=min(AMin3H1(bG,dG,fG),hG); + AH1 mn4B=min(AMin3H1(bB,dB,fB),hB); + AH1 mx4R=max(AMax3H1(bR,dR,fR),hR); + AH1 mx4G=max(AMax3H1(bG,dG,fG),hG); + AH1 mx4B=max(AMax3H1(bB,dB,fB),hB); + // Immediate constants for peak range. + AH2 peakC=AH2(1.0,-1.0*4.0); + // Limiters, these need to be high precision RCPs. + AH1 hitMinR=min(mn4R,eR)*ARcpH1(AH1_(4.0)*mx4R); + AH1 hitMinG=min(mn4G,eG)*ARcpH1(AH1_(4.0)*mx4G); + AH1 hitMinB=min(mn4B,eB)*ARcpH1(AH1_(4.0)*mx4B); + AH1 hitMaxR=(peakC.x-max(mx4R,eR))*ARcpH1(AH1_(4.0)*mn4R+peakC.y); + AH1 hitMaxG=(peakC.x-max(mx4G,eG))*ARcpH1(AH1_(4.0)*mn4G+peakC.y); + AH1 hitMaxB=(peakC.x-max(mx4B,eB))*ARcpH1(AH1_(4.0)*mn4B+peakC.y); + AH1 lobeR=max(-hitMinR,hitMaxR); + AH1 lobeG=max(-hitMinG,hitMaxG); + AH1 lobeB=max(-hitMinB,hitMaxB); + AH1 lobe=max(AH1_(-FSR_RCAS_LIMIT),min(AMax3H1(lobeR,lobeG,lobeB),AH1_(0.0)))*AH2_AU1(con.y).x; + // Apply noise removal. + #ifdef FSR_RCAS_DENOISE + lobe*=nz; + #endif + // Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes. + AH1 rcpL=APrxMedRcpH1(AH1_(4.0)*lobe+AH1_(1.0)); + pixR=(lobe*bR+lobe*dR+lobe*hR+lobe*fR+eR)*rcpL; + pixG=(lobe*bG+lobe*dG+lobe*hG+lobe*fG+eG)*rcpL; + pixB=(lobe*bB+lobe*dB+lobe*hB+lobe*fB+eB)*rcpL;} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// PACKED 16-BIT VERSION +//============================================================================================================================== +#if defined(A_GPU)&&defined(A_HALF)&&defined(FSR_RCAS_HX2) + // Input callback prototypes that need to be implemented by the calling shader + AH4 FsrRcasLoadHx2(ASW2 p); + void FsrRcasInputHx2(inout AH2 r,inout AH2 g,inout AH2 b); +//------------------------------------------------------------------------------------------------------------------------------ + // Can be used to convert from packed Structures of Arrays to Arrays of Structures for store. + void FsrRcasDepackHx2(out AH4 pix0,out AH4 pix1,AH2 pixR,AH2 pixG,AH2 pixB){ + #ifdef A_HLSL + // Invoke a slower path for DX only, since it won't allow uninitialized values. + pix0.a=pix1.a=0.0; + #endif + pix0.rgb=AH3(pixR.x,pixG.x,pixB.x); + pix1.rgb=AH3(pixR.y,pixG.y,pixB.y);} +//------------------------------------------------------------------------------------------------------------------------------ + void FsrRcasHx2( + // Output values are for 2 8x8 tiles in a 16x8 region. + // pix.x = left 8x8 tile + // pix.y = right 8x8 tile + // This enables later processing to easily be packed as well. + out AH2 pixR, + out AH2 pixG, + out AH2 pixB, + #ifdef FSR_RCAS_PASSTHROUGH_ALPHA + out AH2 pixA, + #endif + AU2 ip, // Integer pixel position in output. + AU4 con){ // Constant generated by RcasSetup(). + // No scaling algorithm uses minimal 3x3 pixel neighborhood. + ASW2 sp0=ASW2(ip); + AH3 b0=FsrRcasLoadHx2(sp0+ASW2( 0,-1)).rgb; + AH3 d0=FsrRcasLoadHx2(sp0+ASW2(-1, 0)).rgb; + #ifdef FSR_RCAS_PASSTHROUGH_ALPHA + AH4 ee0=FsrRcasLoadHx2(sp0); + AH3 e0=ee0.rgb;pixA.r=ee0.a; + #else + AH3 e0=FsrRcasLoadHx2(sp0).rgb; + #endif + AH3 f0=FsrRcasLoadHx2(sp0+ASW2( 1, 0)).rgb; + AH3 h0=FsrRcasLoadHx2(sp0+ASW2( 0, 1)).rgb; + ASW2 sp1=sp0+ASW2(8,0); + AH3 b1=FsrRcasLoadHx2(sp1+ASW2( 0,-1)).rgb; + AH3 d1=FsrRcasLoadHx2(sp1+ASW2(-1, 0)).rgb; + #ifdef FSR_RCAS_PASSTHROUGH_ALPHA + AH4 ee1=FsrRcasLoadHx2(sp1); + AH3 e1=ee1.rgb;pixA.g=ee1.a; + #else + AH3 e1=FsrRcasLoadHx2(sp1).rgb; + #endif + AH3 f1=FsrRcasLoadHx2(sp1+ASW2( 1, 0)).rgb; + AH3 h1=FsrRcasLoadHx2(sp1+ASW2( 0, 1)).rgb; + // Arrays of Structures to Structures of Arrays conversion. + AH2 bR=AH2(b0.r,b1.r); + AH2 bG=AH2(b0.g,b1.g); + AH2 bB=AH2(b0.b,b1.b); + AH2 dR=AH2(d0.r,d1.r); + AH2 dG=AH2(d0.g,d1.g); + AH2 dB=AH2(d0.b,d1.b); + AH2 eR=AH2(e0.r,e1.r); + AH2 eG=AH2(e0.g,e1.g); + AH2 eB=AH2(e0.b,e1.b); + AH2 fR=AH2(f0.r,f1.r); + AH2 fG=AH2(f0.g,f1.g); + AH2 fB=AH2(f0.b,f1.b); + AH2 hR=AH2(h0.r,h1.r); + AH2 hG=AH2(h0.g,h1.g); + AH2 hB=AH2(h0.b,h1.b); + // Run optional input transform. + FsrRcasInputHx2(bR,bG,bB); + FsrRcasInputHx2(dR,dG,dB); + FsrRcasInputHx2(eR,eG,eB); + FsrRcasInputHx2(fR,fG,fB); + FsrRcasInputHx2(hR,hG,hB); + // Luma times 2. + AH2 bL=bB*AH2_(0.5)+(bR*AH2_(0.5)+bG); + AH2 dL=dB*AH2_(0.5)+(dR*AH2_(0.5)+dG); + AH2 eL=eB*AH2_(0.5)+(eR*AH2_(0.5)+eG); + AH2 fL=fB*AH2_(0.5)+(fR*AH2_(0.5)+fG); + AH2 hL=hB*AH2_(0.5)+(hR*AH2_(0.5)+hG); + // Noise detection. + AH2 nz=AH2_(0.25)*bL+AH2_(0.25)*dL+AH2_(0.25)*fL+AH2_(0.25)*hL-eL; + nz=ASatH2(abs(nz)*APrxMedRcpH2(AMax3H2(AMax3H2(bL,dL,eL),fL,hL)-AMin3H2(AMin3H2(bL,dL,eL),fL,hL))); + nz=AH2_(-0.5)*nz+AH2_(1.0); + // Min and max of ring. + AH2 mn4R=min(AMin3H2(bR,dR,fR),hR); + AH2 mn4G=min(AMin3H2(bG,dG,fG),hG); + AH2 mn4B=min(AMin3H2(bB,dB,fB),hB); + AH2 mx4R=max(AMax3H2(bR,dR,fR),hR); + AH2 mx4G=max(AMax3H2(bG,dG,fG),hG); + AH2 mx4B=max(AMax3H2(bB,dB,fB),hB); + // Immediate constants for peak range. + AH2 peakC=AH2(1.0,-1.0*4.0); + // Limiters, these need to be high precision RCPs. + AH2 hitMinR=min(mn4R,eR)*ARcpH2(AH2_(4.0)*mx4R); + AH2 hitMinG=min(mn4G,eG)*ARcpH2(AH2_(4.0)*mx4G); + AH2 hitMinB=min(mn4B,eB)*ARcpH2(AH2_(4.0)*mx4B); + AH2 hitMaxR=(peakC.x-max(mx4R,eR))*ARcpH2(AH2_(4.0)*mn4R+peakC.y); + AH2 hitMaxG=(peakC.x-max(mx4G,eG))*ARcpH2(AH2_(4.0)*mn4G+peakC.y); + AH2 hitMaxB=(peakC.x-max(mx4B,eB))*ARcpH2(AH2_(4.0)*mn4B+peakC.y); + AH2 lobeR=max(-hitMinR,hitMaxR); + AH2 lobeG=max(-hitMinG,hitMaxG); + AH2 lobeB=max(-hitMinB,hitMaxB); + AH2 lobe=max(AH2_(-FSR_RCAS_LIMIT),min(AMax3H2(lobeR,lobeG,lobeB),AH2_(0.0)))*AH2_(AH2_AU1(con.y).x); + // Apply noise removal. + #ifdef FSR_RCAS_DENOISE + lobe*=nz; + #endif + // Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes. + AH2 rcpL=APrxMedRcpH2(AH2_(4.0)*lobe+AH2_(1.0)); + pixR=(lobe*bR+lobe*dR+lobe*hR+lobe*fR+eR)*rcpL; + pixG=(lobe*bG+lobe*dG+lobe*hG+lobe*fG+eG)*rcpL; + pixB=(lobe*bB+lobe*dB+lobe*hB+lobe*fB+eB)*rcpL;} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// FSR - [LFGA] LINEAR FILM GRAIN APPLICATOR +// +//------------------------------------------------------------------------------------------------------------------------------ +// Adding output-resolution film grain after scaling is a good way to mask both rendering and scaling artifacts. +// Suggest using tiled blue noise as film grain input, with peak noise frequency set for a specific look and feel. +// The 'Lfga*()' functions provide a convenient way to introduce grain. +// These functions limit grain based on distance to signal limits. +// This is done so that the grain is temporally energy preserving, and thus won't modify image tonality. +// Grain application should be done in a linear colorspace. +// The grain should be temporally changing, but have a temporal sum per pixel that adds to zero (non-biased). +//------------------------------------------------------------------------------------------------------------------------------ +// Usage, +// FsrLfga*( +// color, // In/out linear colorspace color {0 to 1} ranged. +// grain, // Per pixel grain texture value {-0.5 to 0.5} ranged, input is 3-channel to support colored grain. +// amount); // Amount of grain (0 to 1} ranged. +//------------------------------------------------------------------------------------------------------------------------------ +// Example if grain texture is monochrome: 'FsrLfgaF(color,AF3_(grain),amount)' +//============================================================================================================================== +#if defined(A_GPU) + // Maximum grain is the minimum distance to the signal limit. + void FsrLfgaF(inout AF3 c,AF3 t,AF1 a){c+=(t*AF3_(a))*min(AF3_(1.0)-c,c);} +#endif +//============================================================================================================================== +#if defined(A_GPU)&&defined(A_HALF) + // Half precision version (slower). + void FsrLfgaH(inout AH3 c,AH3 t,AH1 a){c+=(t*AH3_(a))*min(AH3_(1.0)-c,c);} +//------------------------------------------------------------------------------------------------------------------------------ + // Packed half precision version (faster). + void FsrLfgaHx2(inout AH2 cR,inout AH2 cG,inout AH2 cB,AH2 tR,AH2 tG,AH2 tB,AH1 a){ + cR+=(tR*AH2_(a))*min(AH2_(1.0)-cR,cR);cG+=(tG*AH2_(a))*min(AH2_(1.0)-cG,cG);cB+=(tB*AH2_(a))*min(AH2_(1.0)-cB,cB);} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// FSR - [SRTM] SIMPLE REVERSIBLE TONE-MAPPER +// +//------------------------------------------------------------------------------------------------------------------------------ +// This provides a way to take linear HDR color {0 to FP16_MAX} and convert it into a temporary {0 to 1} ranged post-tonemapped linear. +// The tonemapper preserves RGB ratio, which helps maintain HDR color bleed during filtering. +//------------------------------------------------------------------------------------------------------------------------------ +// Reversible tonemapper usage, +// FsrSrtm*(color); // {0 to FP16_MAX} converted to {0 to 1}. +// FsrSrtmInv*(color); // {0 to 1} converted into {0 to 32768, output peak safe for FP16}. +//============================================================================================================================== +#if defined(A_GPU) + void FsrSrtmF(inout AF3 c){c*=AF3_(ARcpF1(AMax3F1(c.r,c.g,c.b)+AF1_(1.0)));} + // The extra max solves the c=1.0 case (which is a /0). + void FsrSrtmInvF(inout AF3 c){c*=AF3_(ARcpF1(max(AF1_(1.0/32768.0),AF1_(1.0)-AMax3F1(c.r,c.g,c.b))));} +#endif +//============================================================================================================================== +#if defined(A_GPU)&&defined(A_HALF) + void FsrSrtmH(inout AH3 c){c*=AH3_(ARcpH1(AMax3H1(c.r,c.g,c.b)+AH1_(1.0)));} + void FsrSrtmInvH(inout AH3 c){c*=AH3_(ARcpH1(max(AH1_(1.0/32768.0),AH1_(1.0)-AMax3H1(c.r,c.g,c.b))));} +//------------------------------------------------------------------------------------------------------------------------------ + void FsrSrtmHx2(inout AH2 cR,inout AH2 cG,inout AH2 cB){ + AH2 rcp=ARcpH2(AMax3H2(cR,cG,cB)+AH2_(1.0));cR*=rcp;cG*=rcp;cB*=rcp;} + void FsrSrtmInvHx2(inout AH2 cR,inout AH2 cG,inout AH2 cB){ + AH2 rcp=ARcpH2(max(AH2_(1.0/32768.0),AH2_(1.0)-AMax3H2(cR,cG,cB)));cR*=rcp;cG*=rcp;cB*=rcp;} +#endif +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//_____________________________________________________________/\_______________________________________________________________ +//============================================================================================================================== +// +// FSR - [TEPD] TEMPORAL ENERGY PRESERVING DITHER +// +//------------------------------------------------------------------------------------------------------------------------------ +// Temporally energy preserving dithered {0 to 1} linear to gamma 2.0 conversion. +// Gamma 2.0 is used so that the conversion back to linear is just to square the color. +// The conversion comes in 8-bit and 10-bit modes, designed for output to 8-bit UNORM or 10:10:10:2 respectively. +// Given good non-biased temporal blue noise as dither input, +// the output dither will temporally conserve energy. +// This is done by choosing the linear nearest step point instead of perceptual nearest. +// See code below for details. +//------------------------------------------------------------------------------------------------------------------------------ +// DX SPEC RULES FOR FLOAT->UNORM 8-BIT CONVERSION +// =============================================== +// - Output is 'uint(floor(saturate(n)*255.0+0.5))'. +// - Thus rounding is to nearest. +// - NaN gets converted to zero. +// - INF is clamped to {0.0 to 1.0}. +//============================================================================================================================== +#if defined(A_GPU) + // Hand tuned integer position to dither value, with more values than simple checkerboard. + // Only 32-bit has enough precision for this compddation. + // Output is {0 to <1}. + AF1 FsrTepdDitF(AU2 p,AU1 f){ + AF1 x=AF1_(p.x+f); + AF1 y=AF1_(p.y); + // The 1.61803 golden ratio. + AF1 a=AF1_((1.0+sqrt(5.0))/2.0); + // Number designed to provide a good visual pattern. + AF1 b=AF1_(1.0/3.69); + x=x*a+(y*b); + return AFractF1(x);} +//------------------------------------------------------------------------------------------------------------------------------ + // This version is 8-bit gamma 2.0. + // The 'c' input is {0 to 1}. + // Output is {0 to 1} ready for image store. + void FsrTepdC8F(inout AF3 c,AF1 dit){ + AF3 n=sqrt(c); + n=floor(n*AF3_(255.0))*AF3_(1.0/255.0); + AF3 a=n*n; + AF3 b=n+AF3_(1.0/255.0);b=b*b; + // Ratio of 'a' to 'b' required to produce 'c'. + // APrxLoRcpF1() won't work here (at least for very high dynamic ranges). + // APrxMedRcpF1() is an IADD,FMA,MUL. + AF3 r=(c-b)*APrxMedRcpF3(a-b); + // Use the ratio as a cutoff to choose 'a' or 'b'. + // AGtZeroF1() is a MUL. + c=ASatF3(n+AGtZeroF3(AF3_(dit)-r)*AF3_(1.0/255.0));} +//------------------------------------------------------------------------------------------------------------------------------ + // This version is 10-bit gamma 2.0. + // The 'c' input is {0 to 1}. + // Output is {0 to 1} ready for image store. + void FsrTepdC10F(inout AF3 c,AF1 dit){ + AF3 n=sqrt(c); + n=floor(n*AF3_(1023.0))*AF3_(1.0/1023.0); + AF3 a=n*n; + AF3 b=n+AF3_(1.0/1023.0);b=b*b; + AF3 r=(c-b)*APrxMedRcpF3(a-b); + c=ASatF3(n+AGtZeroF3(AF3_(dit)-r)*AF3_(1.0/1023.0));} +#endif +//============================================================================================================================== +#if defined(A_GPU)&&defined(A_HALF) + AH1 FsrTepdDitH(AU2 p,AU1 f){ + AF1 x=AF1_(p.x+f); + AF1 y=AF1_(p.y); + AF1 a=AF1_((1.0+sqrt(5.0))/2.0); + AF1 b=AF1_(1.0/3.69); + x=x*a+(y*b); + return AH1(AFractF1(x));} +//------------------------------------------------------------------------------------------------------------------------------ + void FsrTepdC8H(inout AH3 c,AH1 dit){ + AH3 n=sqrt(c); + n=floor(n*AH3_(255.0))*AH3_(1.0/255.0); + AH3 a=n*n; + AH3 b=n+AH3_(1.0/255.0);b=b*b; + AH3 r=(c-b)*APrxMedRcpH3(a-b); + c=ASatH3(n+AGtZeroH3(AH3_(dit)-r)*AH3_(1.0/255.0));} +//------------------------------------------------------------------------------------------------------------------------------ + void FsrTepdC10H(inout AH3 c,AH1 dit){ + AH3 n=sqrt(c); + n=floor(n*AH3_(1023.0))*AH3_(1.0/1023.0); + AH3 a=n*n; + AH3 b=n+AH3_(1.0/1023.0);b=b*b; + AH3 r=(c-b)*APrxMedRcpH3(a-b); + c=ASatH3(n+AGtZeroH3(AH3_(dit)-r)*AH3_(1.0/1023.0));} +//============================================================================================================================== + // This computes dither for positions 'p' and 'p+{8,0}'. + AH2 FsrTepdDitHx2(AU2 p,AU1 f){ + AF2 x; + x.x=AF1_(p.x+f); + x.y=x.x+AF1_(8.0); + AF1 y=AF1_(p.y); + AF1 a=AF1_((1.0+sqrt(5.0))/2.0); + AF1 b=AF1_(1.0/3.69); + x=x*AF2_(a)+AF2_(y*b); + return AH2(AFractF2(x));} +//------------------------------------------------------------------------------------------------------------------------------ + void FsrTepdC8Hx2(inout AH2 cR,inout AH2 cG,inout AH2 cB,AH2 dit){ + AH2 nR=sqrt(cR); + AH2 nG=sqrt(cG); + AH2 nB=sqrt(cB); + nR=floor(nR*AH2_(255.0))*AH2_(1.0/255.0); + nG=floor(nG*AH2_(255.0))*AH2_(1.0/255.0); + nB=floor(nB*AH2_(255.0))*AH2_(1.0/255.0); + AH2 aR=nR*nR; + AH2 aG=nG*nG; + AH2 aB=nB*nB; + AH2 bR=nR+AH2_(1.0/255.0);bR=bR*bR; + AH2 bG=nG+AH2_(1.0/255.0);bG=bG*bG; + AH2 bB=nB+AH2_(1.0/255.0);bB=bB*bB; + AH2 rR=(cR-bR)*APrxMedRcpH2(aR-bR); + AH2 rG=(cG-bG)*APrxMedRcpH2(aG-bG); + AH2 rB=(cB-bB)*APrxMedRcpH2(aB-bB); + cR=ASatH2(nR+AGtZeroH2(dit-rR)*AH2_(1.0/255.0)); + cG=ASatH2(nG+AGtZeroH2(dit-rG)*AH2_(1.0/255.0)); + cB=ASatH2(nB+AGtZeroH2(dit-rB)*AH2_(1.0/255.0));} +//------------------------------------------------------------------------------------------------------------------------------ + void FsrTepdC10Hx2(inout AH2 cR,inout AH2 cG,inout AH2 cB,AH2 dit){ + AH2 nR=sqrt(cR); + AH2 nG=sqrt(cG); + AH2 nB=sqrt(cB); + nR=floor(nR*AH2_(1023.0))*AH2_(1.0/1023.0); + nG=floor(nG*AH2_(1023.0))*AH2_(1.0/1023.0); + nB=floor(nB*AH2_(1023.0))*AH2_(1.0/1023.0); + AH2 aR=nR*nR; + AH2 aG=nG*nG; + AH2 aB=nB*nB; + AH2 bR=nR+AH2_(1.0/1023.0);bR=bR*bR; + AH2 bG=nG+AH2_(1.0/1023.0);bG=bG*bG; + AH2 bB=nB+AH2_(1.0/1023.0);bB=bB*bB; + AH2 rR=(cR-bR)*APrxMedRcpH2(aR-bR); + AH2 rG=(cG-bG)*APrxMedRcpH2(aG-bG); + AH2 rB=(cB-bB)*APrxMedRcpH2(aB-bB); + cR=ASatH2(nR+AGtZeroH2(dit-rR)*AH2_(1.0/1023.0)); + cG=ASatH2(nG+AGtZeroH2(dit-rG)*AH2_(1.0/1023.0)); + cB=ASatH2(nB+AGtZeroH2(dit-rB)*AH2_(1.0/1023.0));} +#endif diff --git a/gpu/shadps4/video_core/host_shaders/ms_image_blit.frag b/gpu/shadps4/video_core/host_shaders/ms_image_blit.frag new file mode 100644 index 0000000..44811dc --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/ms_image_blit.frag @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 core +#extension GL_EXT_samplerless_texture_functions : require + +#if defined(SRC_MSAA) +layout (binding = 0, set = 0) uniform texture2DMS in_tex; +#else +layout (binding = 0, set = 0) uniform texture2D in_tex; +#endif + +layout (location = 0) in vec2 uv; +layout (location = 0) out vec4 out_color; + +void main() +{ +#if defined(SRC_MSAA) + out_color = texelFetch(in_tex, ivec2(gl_FragCoord.xy), gl_SampleID); +#else + out_color = texelFetch(in_tex, ivec2(gl_FragCoord.xy), 0); +#endif +} diff --git a/gpu/shadps4/video_core/host_shaders/post_process.frag b/gpu/shadps4/video_core/host_shaders/post_process.frag new file mode 100644 index 0000000..fdcfa18 --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/post_process.frag @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout (location = 0) in vec2 uv; +layout (location = 0) out vec4 color; + +layout (binding = 0) uniform sampler2D texSampler; + +layout (push_constant) uniform settings { + float gamma; + bool hdr; + bool srgb_input; +} pp; + +const float cutoff = 0.0031308, a = 1.055, b = 0.055, d = 12.92; +vec3 gamma(vec3 rgb) { + return mix( + a * pow(rgb, vec3(1.0 / (2.4 + 1.0 - pp.gamma))) - b, + d * rgb / pp.gamma, + lessThan(rgb, vec3(cutoff)) + ); +} + +// Exact inverse of gamma() at unit gamma, for buffers that are sRGB encoded but must be sampled +// through a UNORM view because Vulkan has no sRGB variant of the 10-bit format. +vec3 degamma(vec3 rgb) { + return mix( + pow(max(rgb + b, 0.0) / a, vec3(2.4)), + rgb / d, + lessThan(rgb, vec3(d * cutoff)) + ); +} + +void main() { + vec4 color_linear = texture(texSampler, uv); + if (pp.hdr) { + color = color_linear; + } else { + if (pp.srgb_input) color_linear.rgb = degamma(color_linear.rgb); + color = vec4(gamma(color_linear.rgb), color_linear.a); + } +} diff --git a/gpu/shadps4/video_core/host_shaders/tiling.comp b/gpu/shadps4/video_core/host_shaders/tiling.comp new file mode 100644 index 0000000..4b005cd --- /dev/null +++ b/gpu/shadps4/video_core/host_shaders/tiling.comp @@ -0,0 +1,448 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 core + +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_scalar_block_layout : require +#extension GL_EXT_shader_explicit_arithmetic_types : require + +layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; + +layout(constant_id = 0) const uint NUM_SAMPLES = 1; +layout(constant_id = 1) const uint MICRO_TILE_MODE = 1; +layout(constant_id = 2) const uint MICRO_TILE_THICKNESS = 1; +layout(constant_id = 3) const uint IS_TILER = 0; +#if IS_MACRO_TILED +layout(constant_id = 4) const uint ARRAY_MODE = 0; +layout(constant_id = 5) const uint PIPE_CONFIG = 0; +layout(constant_id = 6) const uint BANK_WIDTH = 1; +layout(constant_id = 7) const uint BANK_HEIGHT = 1; +layout(constant_id = 8) const uint NUM_BANKS = 1; +layout(constant_id = 9) const uint NUM_BANK_BITS = 1; +layout(constant_id = 10) const uint TILE_SPLIT_BYTES = 1; +layout(constant_id = 11) const uint MACRO_TILE_ASPECT = 1; +#endif + +#define BYTES_PER_PIXEL (BITS_PER_PIXEL / 8) + +#if BITS_PER_PIXEL == 8 +#define BLOCK_TYPE uint8_t +#elif BITS_PER_PIXEL == 16 +#define BLOCK_TYPE uint16_t +#elif BITS_PER_PIXEL == 32 +#define BLOCK_TYPE uint32_t +#elif BITS_PER_PIXEL == 64 +#define BLOCK_TYPE u32vec2 +#elif BITS_PER_PIXEL == 96 +#define BLOCK_TYPE u32vec3 +#else +#define BLOCK_TYPE u32vec4 +#endif + +#if IS_MACRO_TILED +const uint NUM_PIPES = PIPE_CONFIG == 0 ? 2 : 8; +const uint NUM_PIPE_BITS = PIPE_CONFIG == 0 ? 1 : 3; +#endif + +#define MICRO_TILE_WIDTH 8 +#define MICRO_TILE_HEIGHT 8 +#define MICRO_TILE_PIXELS (MICRO_TILE_WIDTH * MICRO_TILE_HEIGHT) +#define MICRO_TILE_BITS (MICRO_TILE_PIXELS * MICRO_TILE_THICKNESS * BITS_PER_PIXEL * NUM_SAMPLES) +#define MICRO_TILE_BYTES (MICRO_TILE_BITS / 8) + +#define NUM_PIPE_INTERLEAVE_BITS 8 + +#define ADDR_SURF_DISPLAY_MICRO_TILING 0 +#define ADDR_SURF_THIN_MICRO_TILING 1 +#define ADDR_SURF_DEPTH_MICRO_TILING 2 +#define ADDR_SURF_ROTATED_MICRO_TILING 3 + +#define ARRAY_LINEAR_GENERAL 0 +#define ARRAY_LINEAR_ALIGNED 1 +#define ARRAY_1D_TILED_THIN1 2 +#define ARRAY_1D_TILED_THICK 3 +#define ARRAY_2D_TILED_THIN1 4 +#define ARRAY_PRT_TILED_THIN1 5 +#define ARRAY_PRT_2D_TILED_THIN1 6 +#define ARRAY_2D_TILED_THICK 7 +#define ARRAY_2D_TILED_XTHICK 8 +#define ARRAY_PRT_TILED_THICK 9 +#define ARRAY_PRT_2D_TILED_THICK 10 +#define ARRAY_PRT_3D_TILED_THIN1 11 +#define ARRAY_3D_TILED_THIN1 12 +#define ARRAY_3D_TILED_THICK 13 +#define ARRAY_3D_TILED_XTHICK 14 +#define ARRAY_PRT_3D_TILED_THICK 15 + +#define ADDR_SURF_P2 0 +#define ADDR_SURF_P8_32x32_8x16 10 +#define ADDR_SURF_P8_32x32_16x16 12 + +#define BITS_PER_BYTE 8 +#define BITS_TO_BYTES(x) (((x) + (BITS_PER_BYTE-1)) / BITS_PER_BYTE) + +#define _BIT(v, b) bitfieldExtract((v), (b), 1) + +struct MipInfo { + uint size; + uint pitch; + uint height; + uint offset; +}; + +layout (set = 0, binding = 0, scalar) buffer InputBuf { + BLOCK_TYPE tiled_data[]; +}; + +layout (set = 0, binding = 1, scalar) buffer OutputBuf { + BLOCK_TYPE linear_data[]; +}; + +layout (set = 0, binding = 2, scalar) uniform TilingInfo { + uint bank_swizzle; + uint num_slices; + uint num_mips; + MipInfo mips[16]; +} info; + +uint32_t ComputePixelIndexWithinMicroTile(uint32_t x, uint32_t y, uint32_t z) { + uint32_t p0 = 0; + uint32_t p1 = 0; + uint32_t p2 = 0; + uint32_t p3 = 0; + uint32_t p4 = 0; + uint32_t p5 = 0; + uint32_t p6 = 0; + uint32_t p7 = 0; + uint32_t p8 = 0; + + uint32_t x0 = _BIT(x, 0); + uint32_t x1 = _BIT(x, 1); + uint32_t x2 = _BIT(x, 2); + uint32_t y0 = _BIT(y, 0); + uint32_t y1 = _BIT(y, 1); + uint32_t y2 = _BIT(y, 2); + uint32_t z0 = _BIT(z, 0); + uint32_t z1 = _BIT(z, 1); + uint32_t z2 = _BIT(z, 2); + + if (MICRO_TILE_MODE == ADDR_SURF_DISPLAY_MICRO_TILING) { +#if BITS_PER_PIXEL == 8 + p0 = x0; + p1 = x1; + p2 = x2; + p3 = y1; + p4 = y0; + p5 = y2; +#elif BITS_PER_PIXEL == 16 + p0 = x0; + p1 = x1; + p2 = x2; + p3 = y0; + p4 = y1; + p5 = y2; +#elif BITS_PER_PIXEL == 32 + p0 = x0; + p1 = x1; + p2 = y0; + p3 = x2; + p4 = y1; + p5 = y2; +#elif BITS_PER_PIXEL == 64 + p0 = x0; + p1 = y0; + p2 = x1; + p3 = x2; + p4 = y1; + p5 = y2; +#elif BITS_PER_PIXEL == 128 + p0 = y0; + p1 = x0; + p2 = x1; + p3 = x2; + p4 = y1; + p5 = y2; +#endif + } else if (MICRO_TILE_MODE == ADDR_SURF_THIN_MICRO_TILING || + MICRO_TILE_MODE == ADDR_SURF_DEPTH_MICRO_TILING) { + p0 = x0; + p1 = y0; + p2 = x1; + p3 = y1; + p4 = x2; + p5 = y2; + } else { +#if BITS_PER_PIXEL == 8 || BITS_PER_PIXEL == 16 + p0 = x0; + p1 = y0; + p2 = x1; + p3 = y1; + p4 = z0; + p5 = z1; +#elif BITS_PER_PIXEL == 32 + p0 = x0; + p1 = y0; + p2 = x1; + p3 = z0; + p4 = y1; + p5 = z1; +#elif BITS_PER_PIXEL == 64 || BITS_PER_PIXEL == 128 + p0 = x0; + p1 = y0; + p2 = z0; + p3 = x1; + p4 = y1; + p5 = z1; +#endif + p6 = x2; + p7 = y2; + + if (MICRO_TILE_THICKNESS == 8) { + p8 = z2; + } + } + + uint32_t pixel_number = + ((p0) | (p1 << 1) | (p2 << 2) | (p3 << 3) | (p4 << 4) | + (p5 << 5) | (p6 << 6) | (p7 << 7) | (p8 << 8)); + + return pixel_number; +} + +#if !IS_MACRO_TILED +uint32_t ComputeSurfaceAddrFromCoordMicroTiled(uint32_t x, uint32_t y, uint32_t slice, uint32_t pitch, uint32_t height, uint32_t sample_index) { + uint32_t slice_bytes = BITS_TO_BYTES(pitch * height * MICRO_TILE_THICKNESS * BITS_PER_PIXEL * NUM_SAMPLES); + + uint32_t micro_tiles_per_row = pitch / MICRO_TILE_WIDTH; + uint32_t micro_tile_index_x = x / MICRO_TILE_WIDTH; + uint32_t micro_tile_index_y = y / MICRO_TILE_HEIGHT; + uint32_t micro_tile_index_z = slice / MICRO_TILE_THICKNESS; + + uint32_t slice_offset = micro_tile_index_z * slice_bytes; + uint32_t micro_tile_offset = (micro_tile_index_y * micro_tiles_per_row + micro_tile_index_x) * MICRO_TILE_BYTES; + + uint32_t pixel_index = ComputePixelIndexWithinMicroTile(x, y, slice); + + uint32_t sample_offset; + uint32_t pixel_offset; + if (MICRO_TILE_MODE == ADDR_SURF_DEPTH_MICRO_TILING) { + sample_offset = sample_index * BITS_PER_PIXEL; + pixel_offset = pixel_index * BITS_PER_PIXEL * NUM_SAMPLES; + } else { + sample_offset = sample_index * (MICRO_TILE_BYTES * 8 / NUM_SAMPLES); + pixel_offset = pixel_index * BITS_PER_PIXEL; + } + + uint32_t elem_offset = (sample_offset + pixel_offset) / 8; + return slice_offset + micro_tile_offset + elem_offset; +} + +#else +uint32_t ComputePipeFromCoord(uint32_t x, uint32_t y, uint32_t slice) { + uint32_t p0 = 0; + uint32_t p1 = 0; + uint32_t p2 = 0; + + uint32_t tx = x / MICRO_TILE_WIDTH; + uint32_t ty = y / MICRO_TILE_HEIGHT; + uint32_t x3 = _BIT(tx, 0); + uint32_t x4 = _BIT(tx, 1); + uint32_t x5 = _BIT(tx, 2); + uint32_t y3 = _BIT(ty, 0); + uint32_t y4 = _BIT(ty, 1); + uint32_t y5 = _BIT(ty, 2); + + if (PIPE_CONFIG == ADDR_SURF_P2) { + p0 = x3 ^ y3; + } else if (PIPE_CONFIG == ADDR_SURF_P8_32x32_8x16) { + p0 = x4 ^ y3 ^ x5; + p1 = x3 ^ y4; + p2 = x5 ^ y5; + } else if (PIPE_CONFIG == ADDR_SURF_P8_32x32_16x16) { + p0 = x3 ^ y3 ^ x4; + p1 = x4 ^ y4; + p2 = x5 ^ y5; + } + + uint32_t pipe = p0 | (p1 << 1) | (p2 << 2); + + uint32_t pipe_swizzle = 0; + if (ARRAY_MODE == ARRAY_3D_TILED_THIN1 || ARRAY_MODE == ARRAY_3D_TILED_THICK || + ARRAY_MODE == ARRAY_3D_TILED_XTHICK) { + pipe_swizzle += max(1u, NUM_PIPES / 2 - 1) * (slice / MICRO_TILE_THICKNESS); + } + pipe_swizzle &= (NUM_PIPES - 1); + pipe = pipe ^ pipe_swizzle; + return pipe; +} + +uint32_t ComputeBankFromCoord(uint32_t x, uint32_t y, uint32_t slice, uint32_t tile_split_slice) { + uint32_t b0 = 0; + uint32_t b1 = 0; + uint32_t b2 = 0; + uint32_t b3 = 0; + uint32_t slice_rotation = 0; + uint32_t tile_split_rotation = 0; + + uint32_t tx = x / MICRO_TILE_WIDTH / (BANK_WIDTH * NUM_PIPES); + uint32_t ty = y / MICRO_TILE_HEIGHT / BANK_HEIGHT; + + uint32_t x3 = _BIT(tx, 0); + uint32_t x4 = _BIT(tx, 1); + uint32_t x5 = _BIT(tx, 2); + uint32_t x6 = _BIT(tx, 3); + uint32_t y3 = _BIT(ty, 0); + uint32_t y4 = _BIT(ty, 1); + uint32_t y5 = _BIT(ty, 2); + uint32_t y6 = _BIT(ty, 3); + + if (NUM_BANKS == 16) { + b0 = x3 ^ y6; + b1 = x4 ^ y5 ^ y6; + b2 = x5 ^ y4; + b3 = x6 ^ y3; + } else if (NUM_BANKS == 8) { + b0 = x3 ^ y5; + b1 = x4 ^ y4 ^ y5; + b2 = x5 ^ y3; + } else if (NUM_BANKS == 4) { + b0 = x3 ^ y4; + b1 = x4 ^ y3; + } else if (NUM_BANKS == 2) { + b0 = x3 ^ y3; + } + + uint32_t bank = b0 | (b1 << 1) | (b2 << 2) | (b3 << 3); + + if (ARRAY_MODE == ARRAY_2D_TILED_THIN1 || ARRAY_MODE == ARRAY_2D_TILED_THICK || + ARRAY_MODE == ARRAY_2D_TILED_XTHICK) { + slice_rotation = ((NUM_BANKS / 2) - 1) * (slice / MICRO_TILE_THICKNESS); + } else if (ARRAY_MODE == ARRAY_3D_TILED_THIN1 || ARRAY_MODE == ARRAY_3D_TILED_THICK || + ARRAY_MODE == ARRAY_3D_TILED_XTHICK) { + slice_rotation = max(1u, (NUM_PIPES / 2) - 1) * (slice / MICRO_TILE_THICKNESS) / NUM_PIPES; + } + + if (ARRAY_MODE == ARRAY_2D_TILED_THIN1 || ARRAY_MODE == ARRAY_3D_TILED_THIN1 || + ARRAY_MODE == ARRAY_PRT_2D_TILED_THIN1 || ARRAY_MODE == ARRAY_PRT_3D_TILED_THIN1) { + tile_split_rotation = ((NUM_BANKS / 2) + 1) * tile_split_slice; + } + + bank ^= info.bank_swizzle + slice_rotation; + bank ^= tile_split_rotation; + bank &= (NUM_BANKS - 1); + + return bank; +} + +uint32_t ComputeSurfaceAddrFromCoordMacroTiled(uint32_t x, uint32_t y, uint32_t slice, uint32_t pitch, uint32_t height, uint32_t sample_index) { + uint32_t pixel_index = ComputePixelIndexWithinMicroTile(x, y, slice); + + uint32_t sample_offset; + uint32_t pixel_offset; + if (MICRO_TILE_MODE == ADDR_SURF_DEPTH_MICRO_TILING) { + sample_offset = sample_index * BITS_PER_PIXEL; + pixel_offset = pixel_index * BITS_PER_PIXEL * NUM_SAMPLES; + } else { + sample_offset = sample_index * (MICRO_TILE_BITS / NUM_SAMPLES); + pixel_offset = pixel_index * BITS_PER_PIXEL; + } + + uint32_t element_offset = (pixel_offset + sample_offset) / 8; + + uint32_t micro_tile_bytes = MICRO_TILE_BYTES; + uint32_t slices_per_tile = 1; + uint32_t tile_split_slice = 0; + if (MICRO_TILE_BYTES > TILE_SPLIT_BYTES && MICRO_TILE_THICKNESS == 1) { + slices_per_tile = MICRO_TILE_BYTES / TILE_SPLIT_BYTES; + tile_split_slice = element_offset / TILE_SPLIT_BYTES; + element_offset %= TILE_SPLIT_BYTES; + micro_tile_bytes = TILE_SPLIT_BYTES; + } + + uint32_t macro_tile_pitch = (MICRO_TILE_WIDTH * BANK_WIDTH * NUM_PIPES) * MACRO_TILE_ASPECT; + uint32_t macro_tile_height = (MICRO_TILE_HEIGHT * BANK_HEIGHT * NUM_BANKS) / MACRO_TILE_ASPECT; + + uint32_t macro_tile_bytes = micro_tile_bytes * + (macro_tile_pitch / MICRO_TILE_WIDTH) * + (macro_tile_height / MICRO_TILE_HEIGHT) / (NUM_PIPES * NUM_BANKS); + + uint32_t macro_tiles_per_row = pitch / macro_tile_pitch; + + uint32_t macro_tile_index_x = x / macro_tile_pitch; + uint32_t macro_tile_index_y = y / macro_tile_height; + uint32_t macro_tile_offset = + ((macro_tile_index_y * macro_tiles_per_row) + macro_tile_index_x) * macro_tile_bytes; + uint32_t macro_tiles_per_slice = macro_tiles_per_row * (height / macro_tile_height); + + uint32_t slice_bytes = macro_tiles_per_slice * macro_tile_bytes; + uint32_t slice_offset = + slice_bytes * (tile_split_slice + slices_per_tile * (slice / MICRO_TILE_THICKNESS)); + + uint32_t tile_row_index = (y / MICRO_TILE_HEIGHT) % BANK_HEIGHT; + uint32_t tile_column_index = ((x / MICRO_TILE_WIDTH) / NUM_PIPES) % BANK_WIDTH; + uint32_t tile_index = (tile_row_index * BANK_WIDTH) + tile_column_index; + uint32_t tile_offset = tile_index * micro_tile_bytes; + + uint32_t total_offset = slice_offset + macro_tile_offset + element_offset + tile_offset; + + if (ARRAY_MODE == ARRAY_PRT_TILED_THIN1 || ARRAY_MODE == ARRAY_PRT_TILED_THICK || + ARRAY_MODE == ARRAY_PRT_2D_TILED_THIN1 || ARRAY_MODE == ARRAY_PRT_2D_TILED_THICK || + ARRAY_MODE == ARRAY_PRT_3D_TILED_THIN1 || ARRAY_MODE == ARRAY_PRT_3D_TILED_THICK) { + x %= macro_tile_pitch; + y %= macro_tile_height; + } + + uint32_t pipe = ComputePipeFromCoord(x, y, slice); + uint32_t bank = ComputeBankFromCoord(x, y, slice, tile_split_slice); + + uint32_t pipe_interleave_mask = (1 << NUM_PIPE_INTERLEAVE_BITS) - 1; + uint32_t pipe_interleave_offset = total_offset & pipe_interleave_mask; + uint32_t offset = total_offset >> NUM_PIPE_INTERLEAVE_BITS; + + uint32_t addr = pipe_interleave_offset; + uint32_t pipe_bits = pipe << NUM_PIPE_INTERLEAVE_BITS; + uint32_t bank_bits = bank << (NUM_PIPE_INTERLEAVE_BITS + NUM_PIPE_BITS); + uint32_t offset_bits = offset << (NUM_PIPE_INTERLEAVE_BITS + NUM_PIPE_BITS + NUM_BANK_BITS); + + addr |= pipe_bits; + addr |= bank_bits; + addr |= offset_bits; + + return addr; +} +#endif + +uint GetMipLevel(inout uint texel) { + uint mip = 0; + uint mip_size = info.mips[mip].size / BYTES_PER_PIXEL; + while (texel >= mip_size && mip < info.num_mips) { + texel -= mip_size; + ++mip; + mip_size = info.mips[mip].size / BYTES_PER_PIXEL; + } + return mip; +} + +void main() { + uint texel = gl_GlobalInvocationID.x; + uint mip = GetMipLevel(texel); + uint pitch = info.mips[mip].pitch; + uint height = info.mips[mip].height; + uint tiled_offset = info.mips[mip].offset; + uint x = texel % pitch; + uint y = (texel / pitch) % height; + uint slice = texel / (pitch * height); + +#if IS_MACRO_TILED + tiled_offset += ComputeSurfaceAddrFromCoordMacroTiled(x, y, slice, pitch, height, 0); +#else + tiled_offset += ComputeSurfaceAddrFromCoordMicroTiled(x, y, slice, pitch, height, 0); +#endif + + if (IS_TILER != 0) { + tiled_data[tiled_offset / BYTES_PER_PIXEL] = linear_data[gl_GlobalInvocationID.x]; + } else { + linear_data[gl_GlobalInvocationID.x] = tiled_data[tiled_offset / BYTES_PER_PIXEL]; + } +} diff --git a/gpu/shadps4/video_core/multi_level_page_table.h b/gpu/shadps4/video_core/multi_level_page_table.h new file mode 100644 index 0000000..7f3205e --- /dev/null +++ b/gpu/shadps4/video_core/multi_level_page_table.h @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "common/object_pool.h" +#include "common/types.h" + +namespace VideoCore { + +template +class MultiLevelPageTable final { + using Entry = typename Traits::Entry; + + static constexpr size_t AddressSpaceBits = Traits::AddressSpaceBits; + static constexpr size_t FirstLevelBits = Traits::FirstLevelBits; + static constexpr size_t PageBits = Traits::PageBits; + static constexpr size_t FirstLevelShift = AddressSpaceBits - FirstLevelBits; + static constexpr size_t SecondLevelBits = FirstLevelShift - PageBits; + static constexpr size_t NumEntriesPerL1Page = 1ULL << SecondLevelBits; + + using L1Page = std::array; + +public: + explicit MultiLevelPageTable() : first_level_map{1ULL << FirstLevelBits, nullptr} {} + + ~MultiLevelPageTable() noexcept = default; + + [[nodiscard]] Entry* find(size_t page) { + const size_t l1_page = page >> SecondLevelBits; + const size_t l2_page = page & (NumEntriesPerL1Page - 1); + if (!first_level_map[l1_page]) { + return nullptr; + } + return &(*first_level_map[l1_page])[l2_page]; + } + + [[nodiscard]] const Entry* find(size_t page) const { + const size_t l1_page = page >> SecondLevelBits; + const size_t l2_page = page & (NumEntriesPerL1Page - 1); + if (!first_level_map[l1_page]) { + return nullptr; + } + return &(*first_level_map[l1_page])[l2_page]; + } + + [[nodiscard]] const Entry& operator[](size_t page) const { + const size_t l1_page = page >> SecondLevelBits; + const size_t l2_page = page & (NumEntriesPerL1Page - 1); + if (!first_level_map[l1_page]) { + first_level_map[l1_page] = page_alloc.Create(); + } + return (*first_level_map[l1_page])[l2_page]; + } + + [[nodiscard]] Entry& operator[](size_t page) { + const size_t l1_page = page >> SecondLevelBits; + const size_t l2_page = page & (NumEntriesPerL1Page - 1); + if (!first_level_map[l1_page]) { + first_level_map[l1_page] = page_alloc.Create(); + } + return (*first_level_map[l1_page])[l2_page]; + } + +private: + std::vector first_level_map{}; + Common::ObjectPool page_alloc; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/page_manager.cpp b/gpu/shadps4/video_core/page_manager.cpp new file mode 100644 index 0000000..cf9321c --- /dev/null +++ b/gpu/shadps4/video_core/page_manager.cpp @@ -0,0 +1,461 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "common/debug.h" +#include "common/div_ceil.h" +#include "common/error.h" +#include "common/range_lock.h" +#include "common/signal_context.h" +#include "core/emulator_settings.h" +#include "core/memory.h" +#include "core/signals.h" +#include "video_core/page_manager.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" + +#ifndef _WIN64 +#include +#include "common/adaptive_mutex.h" +#else +#include +#endif + +#ifdef __linux__ +#include +#include +#include +#include +#include +#include +#else +#include "common/spin_lock.h" +#endif + +namespace VideoCore { + +constexpr size_t PM_PAGE_SIZE = 4_KB; +constexpr size_t PM_PAGE_BITS = 12; + +struct PageManager::Impl { + struct PageState { + u8 num_write_watchers : 7; + // At the moment only buffer cache can request read watchers. + // And buffers cannot overlap, thus only 1 can exist per page. + u8 num_read_watchers : 1; + + Core::MemoryPermission WritePerm() const noexcept { + return num_write_watchers == 0 ? Core::MemoryPermission::Write + : Core::MemoryPermission::None; + } + + Core::MemoryPermission ReadPerm() const noexcept { + return num_read_watchers == 0 ? Core::MemoryPermission::Read + : Core::MemoryPermission::None; + } + + Core::MemoryPermission Perms() const noexcept { + return ReadPerm() | WritePerm(); + } + + template + u8 AddDelta() { + if constexpr (is_read) { + if constexpr (delta == 1) { + return ++num_read_watchers; + } else if (delta == -1) { + ASSERT_MSG(num_read_watchers > 0, "Not enough watchers"); + return --num_read_watchers; + } else { + return num_read_watchers; + } + } else { + if constexpr (delta == 1) { + return ++num_write_watchers; + } else if (delta == -1) { + ASSERT_MSG(num_write_watchers > 0, "Not enough watchers"); + return --num_write_watchers; + } else { + return num_write_watchers; + } + } + } + }; + + static constexpr size_t ADDRESS_BITS = 40; + static constexpr size_t NUM_ADDRESS_PAGES = 1ULL << (40 - PM_PAGE_BITS); + static constexpr size_t NUM_ADDRESS_LOCKS = NUM_ADDRESS_PAGES / PAGES_PER_LOCK; + inline static Vulkan::Rasterizer* rasterizer; + + Impl() = default; + virtual ~Impl() = default; + + virtual void OnMap(VAddr address, size_t size) { + // No-op + } + + virtual void OnUnmap(VAddr address, size_t size) { + // No-op + } + + virtual void Protect(VAddr address, size_t size, Core::MemoryPermission perms) = 0; + + template + void UpdatePageWatchers(VAddr addr, u64 size) { + RENDERER_TRACE; + + size_t page = addr >> PM_PAGE_BITS; + const u64 page_end = Common::DivCeil(addr + size, PM_PAGE_SIZE); + + // Acquire locks for the range of pages + const auto lock_start = locks.begin() + (page / PAGES_PER_LOCK); + const auto lock_end = locks.begin() + Common::DivCeil(page_end, PAGES_PER_LOCK); + Common::RangeLockGuard lk(lock_start, lock_end); + + auto perms = cached_pages[page].Perms(); + u64 range_begin = 0; + u64 range_bytes = 0; + u64 potential_range_bytes = 0; + + const auto release_pending = [&] { + if (range_bytes > 0) { + RENDERER_TRACE; + // Perform pending (un)protect action + Protect(range_begin << PM_PAGE_BITS, range_bytes, perms); + range_bytes = 0; + potential_range_bytes = 0; + } + }; + + // Iterate requested pages + const u64 aligned_addr = page << PM_PAGE_BITS; + const u64 aligned_end = page_end << PM_PAGE_BITS; + if (!rasterizer->IsMapped(aligned_addr, aligned_end - aligned_addr)) { + LOG_WARNING(Render, + "Tracking memory region {:#x} - {:#x} which is not fully GPU mapped.", + aligned_addr, aligned_end); + } + + for (; page != page_end; ++page) { + PageState& state = cached_pages[page]; + + // Apply the change to the page state + const u8 new_count = state.AddDelta(); + + if (auto new_perms = state.Perms(); new_perms != perms) [[unlikely]] { + // If the protection changed add pending (un)protect action + release_pending(); + perms = new_perms; + } else if (range_bytes != 0) { + // If the protection did not change, extend the potential range + potential_range_bytes += PM_PAGE_SIZE; + } + + // Only start a new range if the page must be (un)protected + if ((new_count == 0 && !track) || (new_count == 1 && track)) { + if (range_bytes == 0) { + // Start a new potential range + range_begin = page; + potential_range_bytes = PM_PAGE_SIZE; + } + // Extend current range up to potential range + range_bytes = potential_range_bytes; + } + } + + // Add pending (un)protect action + release_pending(); + } + + template + void UpdatePageWatchersForRegion(VAddr base_addr, RegionBits& mask) { + RENDERER_TRACE; + auto start_range = mask.FirstRange(); + auto end_range = mask.LastRange(); + + if (start_range.second == end_range.second) { + // if all pages are contiguous, use the regular UpdatePageWatchers + const VAddr start_addr = base_addr + (start_range.first << PM_PAGE_BITS); + const u64 size = (start_range.second - start_range.first) << PM_PAGE_BITS; + return UpdatePageWatchers(start_addr, size); + } + + size_t base_page = (base_addr >> PM_PAGE_BITS); + ASSERT(base_page % PAGES_PER_LOCK == 0); + std::scoped_lock lk(locks[base_page / PAGES_PER_LOCK]); + auto perms = cached_pages[base_page + start_range.first].Perms(); + u64 range_begin = 0; + u64 range_bytes = 0; + u64 potential_range_bytes = 0; + + const auto release_pending = [&] { + if (range_bytes > 0) { + RENDERER_TRACE; + // Perform pending (un)protect action + Protect((range_begin << PM_PAGE_BITS), range_bytes, perms); + range_bytes = 0; + potential_range_bytes = 0; + } + }; + + // Iterate pages + for (size_t page = start_range.first; page < end_range.second; ++page) { + PageState& state = cached_pages[base_page + page]; + const bool update = mask.Get(page); + + // Apply the change to the page state + const u8 new_count = + update ? state.AddDelta() : state.AddDelta<0, is_read>(); + + if (auto new_perms = state.Perms(); new_perms != perms) [[unlikely]] { + // If the protection changed add pending (un)protect action + release_pending(); + perms = new_perms; + } else if (range_bytes != 0) { + // If the protection did not change, extend the potential range + potential_range_bytes += PM_PAGE_SIZE; + } + + // If the page is not being updated, skip it + if (!update) { + continue; + } + + // If the page must be (un)protected + if ((new_count == 0 && !track) || (new_count == 1 && track)) { + if (range_bytes == 0) { + // Start a new potential range + range_begin = base_page + page; + potential_range_bytes = PM_PAGE_SIZE; + } + // Extend current rango up to potential range + range_bytes = potential_range_bytes; + } + } + + // Add pending (un)protect action + release_pending(); + } + + std::array cached_pages{}; +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP + using LockType = Common::AdaptiveMutex; +#else + using LockType = Common::SpinLock; +#endif + std::array locks{}; +}; + +#ifdef __linux__ +struct UffdImpl : public PageManager::Impl { +private: + std::jthread ufd_thread; + int uffd; + +public: + UffdImpl(Vulkan::Rasterizer* rasterizer_) : Impl() { + rasterizer = rasterizer_; + uffd = syscall(SYS_userfaultfd, O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY); + if (uffd == -1) { + LOG_ERROR(Common_Memory, + "userfaultfd syscall failed: {}, falling back to signal implementation", + Common::GetLastErrorMsg()); + throw std::runtime_error("userfaultfd"); + } + + // Request uffdio features from kernel. + uffdio_api api; + api.api = UFFD_API; + api.features = UFFD_FEATURE_THREAD_ID; + const int ret = ioctl(uffd, UFFDIO_API, &api); + if (ret != 0) { + LOG_ERROR(Common_Memory, + "uffdio_api call failed: {}, falling back to signal implementation", + Common::GetLastErrorMsg()); + throw std::runtime_error("uffdio_api"); + } + + // Create uffd handler thread + ufd_thread = std::jthread([&](std::stop_token token) { UffdHandler(token); }); + } + + ~UffdImpl() = default; + + void OnMap(VAddr address, size_t size) override { + uffdio_register reg; + reg.range.start = address; + reg.range.len = size; + reg.mode = UFFDIO_REGISTER_MODE_WP; + const int ret = ioctl(uffd, UFFDIO_REGISTER, ®); + ASSERT_MSG(ret != -1, "Uffdio register failed with error: {}", Common::GetLastErrorMsg()); + } + + void OnUnmap(VAddr address, size_t size) override { + uffdio_range range; + range.start = address; + range.len = size; + const int ret = ioctl(uffd, UFFDIO_UNREGISTER, &range); + ASSERT_MSG(ret != -1, "Uffdio unregister failed with error: {}", Common::GetLastErrorMsg()); + } + + void Protect(VAddr address, size_t size, Core::MemoryPermission perms) override { + bool allow_write = True(perms & Core::MemoryPermission::Write); + uffdio_writeprotect wp; + wp.range.start = address; + wp.range.len = size; + wp.mode = allow_write ? UFFDIO_WRITEPROTECT_MODE_DONTWAKE : UFFDIO_WRITEPROTECT_MODE_WP; + const int ret = ioctl(uffd, UFFDIO_WRITEPROTECT, &wp); + ASSERT_MSG(ret != -1, "Uffdio writeprotect failed with error: {}", + Common::GetLastErrorMsg()); + } + + void UffdHandler(std::stop_token token) { + Common::SetCurrentThreadName("shadPS4:Uffd"); + + auto regions = Core::Memory::Instance()->GetAddressSpace().GetUsableRegions(); + for (auto& region : regions) { + OnMap(region.lower(), region.upper()); + } + LOG_INFO(Common_Memory, "registered reserved memory with userfaultfd"); + + while (!token.stop_requested()) { + pollfd pollfd; + pollfd.fd = uffd; + pollfd.events = POLLIN; + + // Block until the descriptor is ready for data reads. + const int pollres = poll(&pollfd, 1, -1); + switch (pollres) { + case -1: + perror("Poll userfaultfd"); + continue; + break; + case 0: + continue; + case 1: + break; + default: + UNREACHABLE_MSG("Unexpected number of descriptors {} out of poll", pollres); + } + + // We don't want an error condition to have occured. + ASSERT_MSG(!(pollfd.revents & POLLERR), "POLLERR on userfaultfd"); + + // We waited until there is data to read, we don't care about anything else. + if (!(pollfd.revents & POLLIN)) { + continue; + } + + // Read message from kernel. + uffd_msg msg; + const int readret = read(uffd, &msg, sizeof(msg)); + if (readret == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + continue; + } + LOG_ERROR(Common_Memory, "Unexpected result of uffd read: {}", + Common::GetLastErrorMsg()); + break; + } + ASSERT_MSG(readret == sizeof(msg), "Unexpected short read, exiting"); + ASSERT(msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WP); + + // Notify rasterizer about the fault. + const VAddr addr = msg.arg.pagefault.address; + const auto ptid = msg.arg.pagefault.feat.ptid; + rasterizer->InvalidateMemory(addr, 1, + ptid == rasterizer->GetGpuCommandProcessorThreadId()); + + // Some calls to InvalidateMemory never reach the UFFDIO_WRITEPROTECT ioctl in + // ::Protect, therefore we use MODE_DONTWAKE and wake the thread with UFFDIO_WAKE here + uffdio_range wake; + wake.start = msg.arg.pagefault.address; + wake.len = PM_PAGE_SIZE; + const int ret = ioctl(uffd, UFFDIO_WAKE, &wake); + ASSERT_MSG(ret != -1, "Waking thread {} failed with: {}", ptid, + Common::GetLastErrorMsg()); + } + } +}; +#endif // __linux__ + +struct SignalImpl : public PageManager::Impl { + SignalImpl(Vulkan::Rasterizer* rasterizer_) : Impl() { + rasterizer = rasterizer_; + + // Should be called first. + constexpr auto priority = std::numeric_limits::min(); + Core::Signals::Instance()->RegisterAccessViolationHandler(GuestFaultSignalHandler, + priority); + } + + void Protect(VAddr address, size_t size, Core::MemoryPermission perms) override { + RENDERER_TRACE; + auto* memory = Core::Memory::Instance(); + auto& impl = memory->GetAddressSpace(); + ASSERT_MSG(perms != Core::MemoryPermission::Write, + "Attempted to protect region as write-only which is not a valid permission"); + impl.Protect(address, size, perms); + } + + static bool GuestFaultSignalHandler(void* context, void* fault_address) { + const auto addr = reinterpret_cast(fault_address); + const auto is_gpu_thread = + std::this_thread::get_id() == rasterizer->GetGpuCommandProcessorThread(); + if (Common::IsWriteError(context)) { + return rasterizer->InvalidateMemory(addr, 8, is_gpu_thread); + } else { + return rasterizer->ReadMemory(addr, 8, is_gpu_thread); + } + return false; + } +}; + +PageManager::PageManager(Vulkan::Rasterizer* rasterizer_) { +#ifdef __linux__ + if (EmulatorSettings.IsUserfaultfdTracking()) { + try { + impl = std::make_unique(rasterizer_); + LOG_INFO(Config, "Memory tracking method: userfaultfd"); + return; + } catch (const std::runtime_error& e) { + // if uffd is unsupported, falls back to SignalImpl + } + } + LOG_INFO(Config, "Memory tracking method: signals"); +#endif + impl = std::make_unique(rasterizer_); +} + +PageManager::~PageManager() = default; + +void PageManager::OnGpuMap(VAddr address, size_t size) { + impl->OnMap(address, size); +} + +void PageManager::OnGpuUnmap(VAddr address, size_t size) { + impl->OnUnmap(address, size); +} + +template +void PageManager::UpdatePageWatchers(VAddr addr, u64 size) const { + impl->UpdatePageWatchers(addr, size); +} + +template +void PageManager::UpdatePageWatchersForRegion(VAddr base_addr, RegionBits& mask) const { + impl->UpdatePageWatchersForRegion(base_addr, mask); +} + +template void PageManager::UpdatePageWatchers(VAddr addr, u64 size) const; +template void PageManager::UpdatePageWatchers(VAddr addr, u64 size) const; +template void PageManager::UpdatePageWatchersForRegion(VAddr base_addr, + RegionBits& mask) const; +template void PageManager::UpdatePageWatchersForRegion(VAddr base_addr, + RegionBits& mask) const; +template void PageManager::UpdatePageWatchersForRegion(VAddr base_addr, + RegionBits& mask) const; +template void PageManager::UpdatePageWatchersForRegion(VAddr base_addr, + RegionBits& mask) const; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/page_manager.h b/gpu/shadps4/video_core/page_manager.h new file mode 100644 index 0000000..eb3b01c --- /dev/null +++ b/gpu/shadps4/video_core/page_manager.h @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/alignment.h" +#include "common/types.h" +#include "video_core/buffer_cache//region_definitions.h" + +namespace Vulkan { +class Rasterizer; +} + +namespace VideoCore { + +struct UffdImpl; +struct SignalImpl; + +class PageManager { + // PAGE_SIZE and PAGE_BITS conflicts with machine/param.h definitions on freebsd! + // Use the same page size as the tracker. + static constexpr size_t PM_PAGE_BITS = TRACKER_PAGE_BITS; + static constexpr size_t PM_PAGE_SIZE = TRACKER_BYTES_PER_PAGE; + + // Keep the lock granularity the same as region granularity. (since each regions has + // itself a lock) + static constexpr size_t PAGES_PER_LOCK = NUM_PAGES_PER_REGION; + +public: + explicit PageManager(Vulkan::Rasterizer* rasterizer); + ~PageManager(); + + /// Register a range of mapped gpu memory. + void OnGpuMap(VAddr address, size_t size); + + /// Unregister a range of gpu memory that was unmapped. + void OnGpuUnmap(VAddr address, size_t size); + + /// Updates watches in the pages touching the specified region. + template + void UpdatePageWatchers(VAddr addr, u64 size) const; + + /// Updates watches in the pages touching the specified region using a mask. + template + void UpdatePageWatchersForRegion(VAddr base_addr, RegionBits& mask) const; + + /// Returns page aligned address. + static constexpr VAddr GetPageAddr(VAddr addr) { + return Common::AlignDown(addr, PM_PAGE_SIZE); + } + + /// Returns address of the next page. + static constexpr VAddr GetNextPageAddr(VAddr addr) { + return Common::AlignUp(addr + 1, PM_PAGE_SIZE); + } + +private: + friend struct UffdImpl; + friend struct SignalImpl; + struct Impl; + std::unique_ptr impl; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/renderdoc.cpp b/gpu/shadps4/video_core/renderdoc.cpp new file mode 100644 index 0000000..0fe7e9f --- /dev/null +++ b/gpu/shadps4/video_core/renderdoc.cpp @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "common/logging/formatter.h" +#include "core/emulator_settings.h" +#include "video_core/renderdoc.h" + +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include + +namespace VideoCore { + +enum class CaptureState { + Idle, + Triggered, + InProgress, +}; +static CaptureState capture_state{CaptureState::Idle}; +static std::atomic screenshot_game_only_count{0}; +static std::atomic screenshot_with_overlays_count{0}; + +RENDERDOC_API_1_6_0* rdoc_api{}; + +void LoadRenderDoc() { +#ifdef WIN32 + + // Check if we are running by RDoc GUI + HMODULE mod = GetModuleHandleA("renderdoc.dll"); + if (!mod && EmulatorSettings.IsRenderdocEnabled()) { + // If enabled in config, try to load RDoc runtime in offline mode + HKEY h_reg_key; + LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Classes\\RenderDoc.RDCCapture.1\\DefaultIcon\\", 0, + KEY_READ, &h_reg_key); + if (result != ERROR_SUCCESS) { + return; + } + std::array key_str{}; + DWORD str_sz_out{key_str.size()}; + result = RegQueryValueExW(h_reg_key, L"", 0, NULL, (LPBYTE)key_str.data(), &str_sz_out); + if (result != ERROR_SUCCESS) { + return; + } + + std::filesystem::path path{key_str.cbegin(), key_str.cend()}; + path = path.parent_path().append("renderdoc.dll"); + const auto path_to_lib = path.generic_string(); + mod = LoadLibraryA(path_to_lib.c_str()); + } + + if (mod) { + const auto RENDERDOC_GetAPI = + reinterpret_cast(GetProcAddress(mod, "RENDERDOC_GetAPI")); + const s32 ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0, (void**)&rdoc_api); + ASSERT(ret == 1); + } +#else +#ifdef ANDROID + static constexpr const char RENDERDOC_LIB[] = "libVkLayer_GLES_RenderDoc.so"; +#else + static constexpr const char RENDERDOC_LIB[] = "librenderdoc.so"; +#endif + // Check if we are running by RDoc GUI + void* mod = dlopen(RENDERDOC_LIB, RTLD_NOW | RTLD_NOLOAD); + if (!mod && EmulatorSettings.IsRenderdocEnabled()) { + // If enabled in config, try to load RDoc runtime in offline mode + if ((mod = dlopen(RENDERDOC_LIB, RTLD_NOW))) { + const auto RENDERDOC_GetAPI = + reinterpret_cast(dlsym(mod, "RENDERDOC_GetAPI")); + const s32 ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0, (void**)&rdoc_api); + ASSERT(ret == 1); + } else { + LOG_ERROR(Render, "Cannot load RenderDoc: {}", dlerror()); + } + } +#endif + if (rdoc_api) { + // Disable default capture keys as they suppose to trigger present-to-present capturing + // and it is not what we want + rdoc_api->SetCaptureKeys(nullptr, 0); + + // Also remove rdoc crash handler + rdoc_api->UnloadCrashHandler(); + } +} + +void StartCapture() { + if (!rdoc_api) { + return; + } + + if (capture_state == CaptureState::Triggered) { + rdoc_api->StartFrameCapture(nullptr, nullptr); + capture_state = CaptureState::InProgress; + } +} + +void EndCapture() { + if (!rdoc_api) { + return; + } + + if (capture_state == CaptureState::InProgress) { + rdoc_api->EndFrameCapture(nullptr, nullptr); + capture_state = CaptureState::Idle; + } +} + +void TriggerCapture() { + if (capture_state == CaptureState::Idle) { + capture_state = CaptureState::Triggered; + } +} + +void SetOutputDir(const std::filesystem::path& path, const std::string& prefix) { + if (!rdoc_api) { + return; + } + LOG_WARNING(Common, "RenderDoc capture path: {}", (path / prefix).string()); + rdoc_api->SetCaptureFilePathTemplate(fmt::UTF((path / prefix).u8string()).data.data()); +} + +bool IsRenderDocLoaded() { + return rdoc_api != nullptr; +} + +void RequestScreenshot(const ScreenshotRequest request) { + switch (request) { + case ScreenshotRequest::GameOnly: + screenshot_game_only_count.fetch_add(1, std::memory_order_relaxed); + break; + case ScreenshotRequest::WithOverlays: + screenshot_with_overlays_count.fetch_add(1, std::memory_order_relaxed); + break; + case ScreenshotRequest::None: + default: + break; + } +} + +u32 ConsumeGameOnlyScreenshotRequests() { + return screenshot_game_only_count.exchange(0, std::memory_order_acq_rel); +} + +u32 ConsumeWithOverlaysScreenshotRequests() { + return screenshot_with_overlays_count.exchange(0, std::memory_order_acq_rel); +} + +ScreenshotRequests ConsumeScreenshotRequests() { + return ScreenshotRequests{ + .game_only_count = ConsumeGameOnlyScreenshotRequests(), + .with_overlays_count = ConsumeWithOverlaysScreenshotRequests(), + }; +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/renderdoc.h b/gpu/shadps4/video_core/renderdoc.h new file mode 100644 index 0000000..5e87be5 --- /dev/null +++ b/gpu/shadps4/video_core/renderdoc.h @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" + +namespace VideoCore { + +/// Loads renderdoc dynamic library module. +void LoadRenderDoc(); + +/// Begins a capture if a renderdoc instance is attached. +void StartCapture(); + +/// Ends current renderdoc capture. +void EndCapture(); + +/// Triggers capturing process. +void TriggerCapture(); + +/// Sets output directory for captures +void SetOutputDir(const std::filesystem::path& path, const std::string& prefix); + +/// Returns true when RenderDoc API was loaded and is usable. +bool IsRenderDocLoaded(); + +enum class ScreenshotRequest : u32 { + None = 0, + GameOnly = 1, + WithOverlays = 2, +}; + +struct ScreenshotRequests { + u32 game_only_count{}; + u32 with_overlays_count{}; +}; + +/// Queues an in-emulator screenshot request to be consumed by the presenter. +void RequestScreenshot(ScreenshotRequest request); + +/// Atomically consumes and returns pending "game only" screenshot request counter. +u32 ConsumeGameOnlyScreenshotRequests(); + +/// Atomically consumes and returns pending "with overlays" screenshot request counter. +u32 ConsumeWithOverlaysScreenshotRequests(); + +/// Atomically consumes and returns pending screenshot request counters. +ScreenshotRequests ConsumeScreenshotRequests(); + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/renderer_vulkan/host_passes/fsr_pass.cpp b/gpu/shadps4/video_core/renderer_vulkan/host_passes/fsr_pass.cpp new file mode 100644 index 0000000..4dd46cf --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/host_passes/fsr_pass.cpp @@ -0,0 +1,455 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "core/emulator_settings.h" +#include "video_core/host_shaders/fsr_easu_comp.h" +#include "video_core/host_shaders/fsr_rcas_comp.h" +#include "video_core/renderer_vulkan/host_passes/fsr_pass.h" +#include "video_core/renderer_vulkan/vk_platform.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +#define A_CPU +#include "core/debug_state.h" +#include "video_core/host_shaders/fsr/ffx_a.h" +#include "video_core/host_shaders/fsr/ffx_fsr1.h" + +typedef u32 uvec4[4]; + +struct FSRConstants { + uvec4 Const0; + uvec4 Const1; + uvec4 Const2; + uvec4 Const3; + uvec4 Sample; +}; + +namespace Vulkan::HostPasses { + +void FsrPass::Create(vk::Device device, VmaAllocator allocator, u32 num_images) { + this->device = device; + this->num_images = num_images; + + sampler = Check<"create upscaling sampler">(device.createSamplerUnique(vk::SamplerCreateInfo{ + .magFilter = vk::Filter::eLinear, + .minFilter = vk::Filter::eLinear, + .mipmapMode = vk::SamplerMipmapMode::eNearest, + .addressModeU = vk::SamplerAddressMode::eClampToEdge, + .addressModeV = vk::SamplerAddressMode::eClampToEdge, + .addressModeW = vk::SamplerAddressMode::eClampToEdge, + .maxAnisotropy = 1.0f, + .minLod = -1000.0f, + .maxLod = 1000.0f, + })); + + std::array layoutBindings{{ + { + .binding = 0, + .descriptorType = vk::DescriptorType::eSampledImage, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }, + { + .binding = 1, + .descriptorType = vk::DescriptorType::eStorageImage, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }, + { + .binding = 2, + .descriptorType = vk::DescriptorType::eSampler, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + .pImmutableSamplers = &sampler.get(), + }, + }}; + + descriptor_set_layout = + Check<"create fsr descriptor set layout">(device.createDescriptorSetLayoutUnique({ + .flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptor, + .bindingCount = layoutBindings.size(), + .pBindings = layoutBindings.data(), + })); + + const vk::PushConstantRange push_constants{ + .stageFlags = vk::ShaderStageFlagBits::eCompute, + .offset = 0, + .size = sizeof(FSRConstants), + }; + + const auto& cs_easu_module = CompileSPV(FSR_EASU_COMP, device); + ASSERT(cs_easu_module); + SetObjectName(device, cs_easu_module, "fsr.comp [EASU]"); + + const auto& cs_rcas_module = CompileSPV(FSR_RCAS_COMP, device); + ASSERT(cs_rcas_module); + SetObjectName(device, cs_rcas_module, "fsr.comp [RCAS]"); + + pipeline_layout = Check<"fsp pipeline layout">(device.createPipelineLayoutUnique({ + .setLayoutCount = 1, + .pSetLayouts = &descriptor_set_layout.get(), + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_constants, + })); + SetObjectName(device, pipeline_layout.get(), "fsr pipeline layout"); + + const vk::ComputePipelineCreateInfo easu_pinfo{ + .stage{ + .stage = vk::ShaderStageFlagBits::eCompute, + .module = cs_easu_module, + .pName = "main", + }, + .layout = pipeline_layout.get(), + }; + easu_pipeline = + Check<"fsp easu compute pipelines">(device.createComputePipelineUnique({}, easu_pinfo)); + SetObjectName(device, easu_pipeline.get(), "fsr easu pipeline"); + + const vk::ComputePipelineCreateInfo rcas_pinfo{ + .stage{ + .stage = vk::ShaderStageFlagBits::eCompute, + .module = cs_rcas_module, + .pName = "main", + }, + .layout = pipeline_layout.get(), + }; + rcas_pipeline = + Check<"fsp rcas compute pipelines">(device.createComputePipelineUnique({}, rcas_pinfo)); + SetObjectName(device, rcas_pipeline.get(), "fsr rcas pipeline"); + + device.destroyShaderModule(cs_easu_module); + device.destroyShaderModule(cs_rcas_module); + + available_imgs.resize(num_images); + for (int i = 0; i < num_images; ++i) { + auto& img = available_imgs[i]; + img.id = i; + img.intermediary_image = VideoCore::UniqueImage(device, allocator); + img.output_image = VideoCore::UniqueImage(device, allocator); + } +} + +vk::ImageView FsrPass::Render(vk::CommandBuffer cmdbuf, vk::ImageView input, + vk::Extent2D input_size, vk::Extent2D output_size, Settings settings, + bool hdr) { + if (!settings.enable) { + DebugState.is_using_fsr = false; + return input; + } + if (input_size.width >= output_size.width && input_size.height >= output_size.height) { + DebugState.is_using_fsr = false; + return input; + } + + DebugState.is_using_fsr = true; + + if (output_size != cur_size) { + ResizeAndInvalidate(output_size.width, output_size.height); + } + auto [width, height] = cur_size; + + auto& img = available_imgs[cur_image]; + if (++cur_image >= available_imgs.size()) { + cur_image = 0; + } + + if (img.dirty) { + CreateImages(img); + } + + if (EmulatorSettings.IsVkHostMarkersEnabled()) { + cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ + .pLabelName = "Host/FSR", + }); + } + + static const int thread_group_work_region_dim = 16; + int dispatch_x = (width + (thread_group_work_region_dim - 1)) / thread_group_work_region_dim; + int dispatch_y = (height + (thread_group_work_region_dim - 1)) / thread_group_work_region_dim; + + constexpr vk::ImageSubresourceRange simple_subresource = { + .aspectMask = vk::ImageAspectFlagBits::eColor, + .levelCount = 1, + .layerCount = 1, + }; + const std::array enter_barrier{ + vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .srcAccessMask = vk::AccessFlagBits2::eShaderRead, + .dstStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .dstAccessMask = vk::AccessFlagBits2::eShaderWrite, + .oldLayout = vk::ImageLayout::eUndefined, + .newLayout = vk::ImageLayout::eGeneral, + .image = img.intermediary_image, + .subresourceRange = simple_subresource, + }, + }; + cmdbuf.pipelineBarrier2({ + .imageMemoryBarrierCount = enter_barrier.size(), + .pImageMemoryBarriers = enter_barrier.data(), + }); + + FSRConstants consts{}; + FsrEasuCon(reinterpret_cast(&consts.Const0), reinterpret_cast(&consts.Const1), + reinterpret_cast(&consts.Const2), reinterpret_cast(&consts.Const3), + static_cast(input_size.width), static_cast(input_size.height), + static_cast(input_size.width), static_cast(input_size.height), (AF1)width, + (AF1)height); + consts.Sample[0] = hdr && !settings.use_rcas ? 1 : 0; + + if (settings.use_rcas) { + + { // easu + std::array img_info{{ + { + .imageView = input, + .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + }, + { + .imageView = img.intermediary_image_view.get(), + .imageLayout = vk::ImageLayout::eGeneral, + }, + { + .sampler = sampler.get(), + }, + }}; + + std::array set_writes{{ + { + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampledImage, + .pImageInfo = &img_info[0], + }, + { + .dstBinding = 1, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageImage, + .pImageInfo = &img_info[1], + }, + { + .dstBinding = 2, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampler, + .pImageInfo = &img_info[2], + }, + }}; + + cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, easu_pipeline.get()); + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, pipeline_layout.get(), 0, + set_writes); + cmdbuf.pushConstants(pipeline_layout.get(), vk::ShaderStageFlagBits::eCompute, 0, + sizeof(FSRConstants), &consts); + cmdbuf.dispatch(dispatch_x, dispatch_y, 1); + } + + std::array img_barrier{ + vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .srcAccessMask = vk::AccessFlagBits2::eShaderStorageWrite, + .dstStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .dstAccessMask = vk::AccessFlagBits2::eShaderRead, + .oldLayout = vk::ImageLayout::eGeneral, + .newLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + .image = img.intermediary_image, + .subresourceRange = simple_subresource, + }, + vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eTopOfPipe, + .srcAccessMask = vk::AccessFlagBits2::eNone, + .dstStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .dstAccessMask = vk::AccessFlagBits2::eShaderStorageWrite, + .oldLayout = vk::ImageLayout::eUndefined, + .newLayout = vk::ImageLayout::eGeneral, + .image = img.output_image, + .subresourceRange = simple_subresource, + }, + }; + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .imageMemoryBarrierCount = img_barrier.size(), + .pImageMemoryBarriers = img_barrier.data(), + }); + + { // rcas + consts = {}; + FsrRcasCon(reinterpret_cast(&consts.Const0), settings.rcas_attenuation); + consts.Sample[0] = hdr ? 1 : 0; + + std::array img_info{{ + { + .imageView = img.intermediary_image_view.get(), + .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + }, + { + .imageView = img.output_image_view.get(), + .imageLayout = vk::ImageLayout::eGeneral, + }, + { + .sampler = sampler.get(), + }, + }}; + + std::array set_writes{{ + { + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampledImage, + .pImageInfo = &img_info[0], + }, + { + .dstBinding = 1, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageImage, + .pImageInfo = &img_info[1], + }, + { + .dstBinding = 2, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampler, + .pImageInfo = &img_info[2], + }, + }}; + + cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, rcas_pipeline.get()); + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, pipeline_layout.get(), 0, + set_writes); + cmdbuf.pushConstants(pipeline_layout.get(), vk::ShaderStageFlagBits::eCompute, 0, + sizeof(FSRConstants), &consts); + cmdbuf.dispatch(dispatch_x, dispatch_y, 1); + } + + } else { + // only easu + std::array img_info{{ + { + .imageView = input, + .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + }, + { + .imageView = img.output_image_view.get(), + .imageLayout = vk::ImageLayout::eGeneral, + }, + { + .sampler = sampler.get(), + }, + }}; + + std::array set_writes{{ + { + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampledImage, + .pImageInfo = &img_info[0], + }, + { + .dstBinding = 1, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageImage, + .pImageInfo = &img_info[1], + }, + { + .dstBinding = 2, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampler, + .pImageInfo = &img_info[2], + }, + }}; + + cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, easu_pipeline.get()); + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, pipeline_layout.get(), 0, + set_writes); + cmdbuf.pushConstants(pipeline_layout.get(), vk::ShaderStageFlagBits::eCompute, 0, + sizeof(FSRConstants), &consts); + cmdbuf.dispatch(dispatch_x, dispatch_y, 1); + } + + const std::array return_barrier{ + vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eComputeShader, + .srcAccessMask = vk::AccessFlagBits2::eShaderStorageWrite, + .dstStageMask = vk::PipelineStageFlagBits2::eAllCommands, + .dstAccessMask = vk::AccessFlagBits2::eShaderRead, + .oldLayout = vk::ImageLayout::eGeneral, + .newLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + .image = img.output_image, + .subresourceRange = simple_subresource, + }, + }; + cmdbuf.pipelineBarrier2({ + .imageMemoryBarrierCount = return_barrier.size(), + .pImageMemoryBarriers = return_barrier.data(), + }); + + if (EmulatorSettings.IsVkHostMarkersEnabled()) { + cmdbuf.endDebugUtilsLabelEXT(); + } + + return img.output_image_view.get(); +} + +void FsrPass::ResizeAndInvalidate(u32 width, u32 height) { + this->cur_size = vk::Extent2D{ + .width = width, + .height = height, + }; + for (int i = 0; i < num_images; ++i) { + available_imgs[i].dirty = true; + } +} + +void FsrPass::CreateImages(Img& img) const { + img.dirty = false; + + // Destroy previous resources before re-creating at new size. + // Views first, then images (views reference the images). + img.intermediary_image_view.reset(); + img.output_image_view.reset(); + img.intermediary_image.Destroy(); + img.output_image.Destroy(); + + vk::ImageCreateInfo image_create_info{ + .imageType = vk::ImageType::e2D, + .format = vk::Format::eR16G16B16A16Sfloat, + .extent{ + .width = cur_size.width, + .height = cur_size.height, + .depth = 1, + }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = vk::SampleCountFlagBits::e1, + // .tiling = vk::ImageTiling::eOptimal, + .usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eStorage, + .initialLayout = vk::ImageLayout::eUndefined, + }; + img.intermediary_image.Create(image_create_info); + SetObjectName(device, static_cast(img.intermediary_image), + "FSR Intermediary Image #{}", img.id); + image_create_info.usage = vk::ImageUsageFlagBits::eTransferSrc | + vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eStorage | + vk::ImageUsageFlagBits::eColorAttachment; + img.output_image.Create(image_create_info); + SetObjectName(device, static_cast(img.output_image), "FSR Output Image #{}", img.id); + + vk::ImageViewCreateInfo image_view_create_info{ + .image = img.intermediary_image, + .viewType = vk::ImageViewType::e2D, + .format = vk::Format::eR16G16B16A16Sfloat, + .subresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .levelCount = 1, + .layerCount = 1, + }, + }; + img.intermediary_image_view = Check<"create fsr intermediary image view">( + device.createImageViewUnique(image_view_create_info)); + SetObjectName(device, img.intermediary_image_view.get(), "FSR Intermediary ImageView #{}", + img.id); + + image_view_create_info.image = img.output_image; + img.output_image_view = + Check<"create fsr output image view">(device.createImageViewUnique(image_view_create_info)); + SetObjectName(device, img.output_image_view.get(), "FSR Output ImageView #{}", img.id); +} + +} // namespace Vulkan::HostPasses diff --git a/gpu/shadps4/video_core/renderer_vulkan/host_passes/fsr_pass.h b/gpu/shadps4/video_core/renderer_vulkan/host_passes/fsr_pass.h new file mode 100644 index 0000000..3d48d85 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/host_passes/fsr_pass.h @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" +#include "video_core/texture_cache/image.h" + +namespace Vulkan::HostPasses { + +class FsrPass { +public: + struct Settings { + bool enable{true}; + bool use_rcas{true}; + float rcas_attenuation{0.25f}; + }; + + void Create(vk::Device device, VmaAllocator allocator, u32 num_images); + + vk::ImageView Render(vk::CommandBuffer cmdbuf, vk::ImageView input, vk::Extent2D input_size, + vk::Extent2D output_size, Settings settings, bool hdr); + +private: + struct Img { + u8 id{}; + bool dirty{true}; + + VideoCore::UniqueImage intermediary_image; + vk::UniqueImageView intermediary_image_view; + + VideoCore::UniqueImage output_image; + vk::UniqueImageView output_image_view; + }; + + void ResizeAndInvalidate(u32 width, u32 height); + void CreateImages(Img& img) const; + + vk::Device device{}; + u32 num_images{}; + + vk::UniqueDescriptorSetLayout descriptor_set_layout{}; + vk::UniqueDescriptorSet easu_descriptor_set{}; + vk::UniqueDescriptorSet rcas_descriptor_set{}; + vk::UniqueSampler sampler{}; + vk::UniquePipelineLayout pipeline_layout{}; + vk::UniquePipeline easu_pipeline{}; + vk::UniquePipeline rcas_pipeline{}; + + vk::Extent2D cur_size{}; + u32 cur_image{}; + std::vector available_imgs; +}; + +} // namespace Vulkan::HostPasses diff --git a/gpu/shadps4/video_core/renderer_vulkan/host_passes/pp_pass.cpp b/gpu/shadps4/video_core/renderer_vulkan/host_passes/pp_pass.cpp new file mode 100644 index 0000000..1e05096 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/host_passes/pp_pass.cpp @@ -0,0 +1,282 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "video_core/renderer_vulkan/host_passes/pp_pass.h" + +#include "common/assert.h" +#include "core/emulator_settings.h" +#include "video_core/host_shaders/fs_tri_vert.h" +#include "video_core/host_shaders/post_process_frag.h" +#include "video_core/renderer_vulkan/vk_platform.h" +#include "video_core/renderer_vulkan/vk_presenter.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +#include + +namespace Vulkan::HostPasses { + +void PostProcessingPass::Create(vk::Device device, const vk::Format surface_format) { + boost::container::static_vector bindings{ + { + .binding = 0, + .descriptorType = vk::DescriptorType::eCombinedImageSampler, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eFragment, + }, + }; + + const vk::DescriptorSetLayoutCreateInfo desc_layout_ci{ + .flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR, + .bindingCount = static_cast(bindings.size()), + .pBindings = bindings.data(), + }; + + desc_set_layout = Check<"create pp descriptor set layout">( + device.createDescriptorSetLayoutUnique(desc_layout_ci)); + + const vk::PushConstantRange push_constants{ + .stageFlags = vk::ShaderStageFlagBits::eFragment, + .offset = 0, + .size = sizeof(Settings), + }; + + const auto& vs_module = CompileSPV(FS_TRI_VERT, device); + ASSERT(vs_module); + SetObjectName(device, vs_module, "fs_tri.vert"); + + const auto& fs_module = CompileSPV(POST_PROCESS_FRAG, device); + ASSERT(fs_module); + SetObjectName(device, fs_module, "post_process.frag"); + + const std::array shaders_ci{ + vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eVertex, + .module = vs_module, + .pName = "main", + }, + vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eFragment, + .module = fs_module, + .pName = "main", + }, + }; + + const vk::PipelineLayoutCreateInfo layout_info{ + .setLayoutCount = 1U, + .pSetLayouts = &*desc_set_layout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_constants, + }; + + pipeline_layout = + Check<"create pp pipeline layout">(device.createPipelineLayoutUnique(layout_info)); + + const std::array pp_color_formats{ + surface_format, + }; + const vk::PipelineRenderingCreateInfo pipeline_rendering_ci{ + .colorAttachmentCount = pp_color_formats.size(), + .pColorAttachmentFormats = pp_color_formats.data(), + }; + + const vk::PipelineVertexInputStateCreateInfo vertex_input_info{ + .vertexBindingDescriptionCount = 0u, + .vertexAttributeDescriptionCount = 0u, + }; + + const vk::PipelineInputAssemblyStateCreateInfo input_assembly{ + .topology = vk::PrimitiveTopology::eTriangleList, + }; + + const vk::Viewport viewport{ + .x = 0.0f, + .y = 0.0f, + .width = 1.0f, + .height = 1.0f, + .minDepth = 0.0f, + .maxDepth = 1.0f, + }; + + const vk::Rect2D scissor = { + .offset = {0, 0}, + .extent = {1, 1}, + }; + + const vk::PipelineViewportStateCreateInfo viewport_info{ + .viewportCount = 1, + .pViewports = &viewport, + .scissorCount = 1, + .pScissors = &scissor, + }; + + const vk::PipelineRasterizationStateCreateInfo raster_state{ + .depthClampEnable = false, + .rasterizerDiscardEnable = false, + .polygonMode = vk::PolygonMode::eFill, + .cullMode = vk::CullModeFlagBits::eBack, + .frontFace = vk::FrontFace::eClockwise, + .depthBiasEnable = false, + .lineWidth = 1.0f, + }; + + const vk::PipelineMultisampleStateCreateInfo multisampling{ + .rasterizationSamples = vk::SampleCountFlagBits::e1, + }; + + const std::array attachments{ + vk::PipelineColorBlendAttachmentState{ + .blendEnable = false, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA, + }, + }; + + const vk::PipelineColorBlendStateCreateInfo color_blending{ + .logicOpEnable = false, + .logicOp = vk::LogicOp::eCopy, + .attachmentCount = attachments.size(), + .pAttachments = attachments.data(), + .blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f}, + }; + + const std::array dynamic_states{ + vk::DynamicState::eViewport, + vk::DynamicState::eScissor, + }; + + const vk::PipelineDynamicStateCreateInfo dynamic_info{ + .dynamicStateCount = dynamic_states.size(), + .pDynamicStates = dynamic_states.data(), + }; + + const vk::GraphicsPipelineCreateInfo pipeline_info{ + .pNext = &pipeline_rendering_ci, + .stageCount = shaders_ci.size(), + .pStages = shaders_ci.data(), + .pVertexInputState = &vertex_input_info, + .pInputAssemblyState = &input_assembly, + .pViewportState = &viewport_info, + .pRasterizationState = &raster_state, + .pMultisampleState = &multisampling, + .pColorBlendState = &color_blending, + .pDynamicState = &dynamic_info, + .layout = *pipeline_layout, + }; + + pipeline = Check<"create post process pipeline">(device.createGraphicsPipelineUnique( + /*pipeline_cache*/ {}, pipeline_info)); + + // Once pipeline is compiled, we don't need the shader module anymore + device.destroyShaderModule(vs_module); + device.destroyShaderModule(fs_module); + + // Create sampler resource + const vk::SamplerCreateInfo sampler_ci{ + .magFilter = vk::Filter::eLinear, + .minFilter = vk::Filter::eLinear, + .mipmapMode = vk::SamplerMipmapMode::eNearest, + .addressModeU = vk::SamplerAddressMode::eClampToEdge, + .addressModeV = vk::SamplerAddressMode::eClampToEdge, + }; + sampler = Check<"create pp sampler">(device.createSamplerUnique(sampler_ci)); +} + +void PostProcessingPass::Render(vk::CommandBuffer cmdbuf, vk::ImageView input, + vk::Extent2D input_size, Frame& frame, Settings settings) { + if (EmulatorSettings.IsVkHostMarkersEnabled()) { + cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ + .pLabelName = "Host/Post processing", + }); + } + + constexpr vk::ImageSubresourceRange simple_subresource = { + .aspectMask = vk::ImageAspectFlagBits::eColor, + .levelCount = 1, + .layerCount = 1, + }; + const std::array attachments{{ + { + .imageView = frame.image_view, + .imageLayout = vk::ImageLayout::eColorAttachmentOptimal, + .loadOp = vk::AttachmentLoadOp::eClear, + .storeOp = vk::AttachmentStoreOp::eStore, + }, + }}; + const vk::RenderingInfo rendering_info{ + .renderArea{ + .extent{ + .width = frame.width, + .height = frame.height, + }, + }, + .layerCount = 1, + .colorAttachmentCount = attachments.size(), + .pColorAttachments = attachments.data(), + }; + + vk::DescriptorImageInfo image_info{ + .sampler = *sampler, + .imageView = input, + .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + }; + + const std::array set_writes{ + vk::WriteDescriptorSet{ + .dstSet = VK_NULL_HANDLE, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eCombinedImageSampler, + .pImageInfo = &image_info, + }, + }; + + cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, *pipeline); + + const std::array viewports = { + vk::Viewport{ + .width = static_cast(frame.width), + .height = static_cast(frame.height), + .minDepth = 0.0f, + .maxDepth = 1.0f, + }, + }; + + cmdbuf.setViewport(0, viewports); + cmdbuf.setScissor(0, vk::Rect2D{ + .extent{ + .width = frame.width, + .height = frame.height, + }, + }); + + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0, set_writes); + cmdbuf.pushConstants(*pipeline_layout, vk::ShaderStageFlagBits::eFragment, 0, sizeof(Settings), + &settings); + + cmdbuf.beginRendering(rendering_info); + cmdbuf.draw(3, 1, 0, 0); + cmdbuf.endRendering(); + + const auto post_barrier = vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite, + .dstStageMask = vk::PipelineStageFlagBits2::eFragmentShader, + .dstAccessMask = vk::AccessFlagBits2::eShaderRead, + .oldLayout = vk::ImageLayout::eColorAttachmentOptimal, + .newLayout = vk::ImageLayout::eGeneral, + .image = frame.image, + .subresourceRange = simple_subresource, + }; + + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .imageMemoryBarrierCount = 1, + .pImageMemoryBarriers = &post_barrier, + }); + + if (EmulatorSettings.IsVkHostMarkersEnabled()) { + cmdbuf.endDebugUtilsLabelEXT(); + } +} + +} // namespace Vulkan::HostPasses diff --git a/gpu/shadps4/video_core/renderer_vulkan/host_passes/pp_pass.h b/gpu/shadps4/video_core/renderer_vulkan/host_passes/pp_pass.h new file mode 100644 index 0000000..6aebb2d --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/host_passes/pp_pass.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan { +class Frame; +} + +namespace Vulkan::HostPasses { + +class PostProcessingPass { +public: + struct Settings { + float gamma = 1.0f; + u32 hdr = 0; + u32 srgb_input = 0; + }; + + void Create(vk::Device device, vk::Format surface_format); + + void Render(vk::CommandBuffer cmdbuf, vk::ImageView input, vk::Extent2D input_size, + Frame& output, Settings settings); + +private: + vk::UniquePipeline pipeline{}; + vk::UniquePipelineLayout pipeline_layout{}; + vk::UniqueDescriptorSetLayout desc_set_layout{}; + vk::UniqueSampler sampler{}; +}; + +} // namespace Vulkan::HostPasses diff --git a/gpu/shadps4/video_core/renderer_vulkan/liverpool_to_vk.cpp b/gpu/shadps4/video_core/renderer_vulkan/liverpool_to_vk.cpp new file mode 100644 index 0000000..a74066e --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -0,0 +1,1191 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "common/number_utils.h" +#include "video_core/amdgpu/pixel_format.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" + +#include + +#define INVALID_NUMBER_FORMAT_COMBO \ + LOG_ERROR(Render_Vulkan, "Unsupported number type {} for format {}", number_type, format); + +namespace Vulkan::LiverpoolToVK { + +using DepthBuffer = AmdGpu::DepthBuffer; + +vk::StencilOp StencilOp(AmdGpu::StencilFunc op) { + switch (op) { + case AmdGpu::StencilFunc::Keep: + return vk::StencilOp::eKeep; + case AmdGpu::StencilFunc::Zero: + return vk::StencilOp::eZero; + case AmdGpu::StencilFunc::ReplaceTest: + return vk::StencilOp::eReplace; + case AmdGpu::StencilFunc::AddClamp: + return vk::StencilOp::eIncrementAndClamp; + case AmdGpu::StencilFunc::SubClamp: + return vk::StencilOp::eDecrementAndClamp; + case AmdGpu::StencilFunc::Invert: + return vk::StencilOp::eInvert; + case AmdGpu::StencilFunc::AddWrap: + return vk::StencilOp::eIncrementAndWrap; + case AmdGpu::StencilFunc::SubWrap: + return vk::StencilOp::eDecrementAndWrap; + case AmdGpu::StencilFunc::ReplaceOp: + return vk::StencilOp::eReplace; + case AmdGpu::StencilFunc::Ones: + LOG_WARNING(Render_Vulkan, "Unsupported stencil op {}, using Replace.", + static_cast(op)); + return vk::StencilOp::eReplace; + case AmdGpu::StencilFunc::And: + case AmdGpu::StencilFunc::Or: + case AmdGpu::StencilFunc::Xor: + case AmdGpu::StencilFunc::Nand: + case AmdGpu::StencilFunc::Nor: + case AmdGpu::StencilFunc::Xnor: + // Bitwise stencil operations have no Vulkan equivalent; eKeep is the safest fallback. + LOG_WARNING(Render_Vulkan, "Unsupported bitwise stencil op {}, using Keep.", + static_cast(op)); + return vk::StencilOp::eKeep; + default: + UNREACHABLE(); + return vk::StencilOp::eKeep; + } +} + +vk::CompareOp CompareOp(AmdGpu::CompareFunc func) { + switch (func) { + case AmdGpu::CompareFunc::Always: + return vk::CompareOp::eAlways; + case AmdGpu::CompareFunc::Equal: + return vk::CompareOp::eEqual; + case AmdGpu::CompareFunc::GreaterEqual: + return vk::CompareOp::eGreaterOrEqual; + case AmdGpu::CompareFunc::Greater: + return vk::CompareOp::eGreater; + case AmdGpu::CompareFunc::LessEqual: + return vk::CompareOp::eLessOrEqual; + case AmdGpu::CompareFunc::Less: + return vk::CompareOp::eLess; + case AmdGpu::CompareFunc::NotEqual: + return vk::CompareOp::eNotEqual; + case AmdGpu::CompareFunc::Never: + return vk::CompareOp::eNever; + default: + UNREACHABLE(); + return vk::CompareOp::eAlways; + } +} + +bool IsPrimitiveCulled(AmdGpu::PrimitiveType type) { + switch (type) { + case AmdGpu::PrimitiveType::TriangleList: + case AmdGpu::PrimitiveType::TriangleFan: + case AmdGpu::PrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::PatchPrimitive: + case AmdGpu::PrimitiveType::AdjTriangleList: + case AmdGpu::PrimitiveType::AdjTriangleStrip: + case AmdGpu::PrimitiveType::QuadList: + case AmdGpu::PrimitiveType::QuadStrip: + case AmdGpu::PrimitiveType::Polygon: + return true; + case AmdGpu::PrimitiveType::None: + case AmdGpu::PrimitiveType::PointList: + case AmdGpu::PrimitiveType::LineList: + case AmdGpu::PrimitiveType::LineStrip: + case AmdGpu::PrimitiveType::AdjLineList: + case AmdGpu::PrimitiveType::AdjLineStrip: + case AmdGpu::PrimitiveType::RectList: // Screen-aligned rectangles that are not culled + case AmdGpu::PrimitiveType::LineLoop: + return false; + default: + UNREACHABLE(); + return true; + } +} + +vk::PrimitiveTopology PrimitiveType(AmdGpu::PrimitiveType type) { + switch (type) { + case AmdGpu::PrimitiveType::PointList: + return vk::PrimitiveTopology::ePointList; + case AmdGpu::PrimitiveType::LineList: + return vk::PrimitiveTopology::eLineList; + case AmdGpu::PrimitiveType::LineStrip: + return vk::PrimitiveTopology::eLineStrip; + case AmdGpu::PrimitiveType::TriangleList: + return vk::PrimitiveTopology::eTriangleList; + case AmdGpu::PrimitiveType::TriangleFan: + case AmdGpu::PrimitiveType::Polygon: + return vk::PrimitiveTopology::eTriangleFan; + case AmdGpu::PrimitiveType::TriangleStrip: + return vk::PrimitiveTopology::eTriangleStrip; + case AmdGpu::PrimitiveType::QuadStrip: + LOG_WARNING(Render_Vulkan, "Unimplemented primitive type, using TriangleStrip."); + return vk::PrimitiveTopology::eTriangleStrip; + case AmdGpu::PrimitiveType::AdjLineList: + return vk::PrimitiveTopology::eLineListWithAdjacency; + case AmdGpu::PrimitiveType::AdjLineStrip: + return vk::PrimitiveTopology::eLineStripWithAdjacency; + case AmdGpu::PrimitiveType::AdjTriangleList: + return vk::PrimitiveTopology::eTriangleListWithAdjacency; + case AmdGpu::PrimitiveType::AdjTriangleStrip: + return vk::PrimitiveTopology::eTriangleStripWithAdjacency; + case AmdGpu::PrimitiveType::PatchPrimitive: + return vk::PrimitiveTopology::ePatchList; + case AmdGpu::PrimitiveType::QuadList: + case AmdGpu::PrimitiveType::RectList: + return vk::PrimitiveTopology::ePatchList; + default: + UNREACHABLE_MSG("Unimplemented primitive type: {}", static_cast(type)); + return vk::PrimitiveTopology::eTriangleList; + } +} + +vk::PolygonMode PolygonMode(AmdGpu::PolygonMode mode) { + switch (mode) { + case AmdGpu::PolygonMode::Point: + return vk::PolygonMode::ePoint; + case AmdGpu::PolygonMode::Line: + return vk::PolygonMode::eLine; + case AmdGpu::PolygonMode::Fill: + return vk::PolygonMode::eFill; + default: + UNREACHABLE(); + return vk::PolygonMode::eFill; + } +} + +vk::CullModeFlags CullMode(AmdGpu::CullMode mode) { + switch (mode) { + case AmdGpu::CullMode::None: + return vk::CullModeFlagBits::eNone; + case AmdGpu::CullMode::Front: + return vk::CullModeFlagBits::eFront; + case AmdGpu::CullMode::Back: + return vk::CullModeFlagBits::eBack; + case AmdGpu::CullMode::FrontAndBack: + return vk::CullModeFlagBits::eFrontAndBack; + default: + UNREACHABLE(); + return vk::CullModeFlagBits::eNone; + } +} + +vk::FrontFace FrontFace(AmdGpu::FrontFace face) { + switch (face) { + case AmdGpu::FrontFace::Clockwise: + return vk::FrontFace::eClockwise; + case AmdGpu::FrontFace::CounterClockwise: + return vk::FrontFace::eCounterClockwise; + default: + UNREACHABLE(); + return vk::FrontFace::eClockwise; + } +} + +vk::BlendFactor BlendFactor(AmdGpu::BlendControl::BlendFactor factor) { + using BlendFactor = AmdGpu::BlendControl::BlendFactor; + switch (factor) { + case BlendFactor::Zero: + return vk::BlendFactor::eZero; + case BlendFactor::One: + return vk::BlendFactor::eOne; + case BlendFactor::SrcColor: + return vk::BlendFactor::eSrcColor; + case BlendFactor::OneMinusSrcColor: + return vk::BlendFactor::eOneMinusSrcColor; + case BlendFactor::SrcAlpha: + return vk::BlendFactor::eSrcAlpha; + case BlendFactor::OneMinusSrcAlpha: + return vk::BlendFactor::eOneMinusSrcAlpha; + case BlendFactor::DstAlpha: + return vk::BlendFactor::eDstAlpha; + case BlendFactor::OneMinusDstAlpha: + return vk::BlendFactor::eOneMinusDstAlpha; + case BlendFactor::DstColor: + return vk::BlendFactor::eDstColor; + case BlendFactor::OneMinusDstColor: + return vk::BlendFactor::eOneMinusDstColor; + case BlendFactor::SrcAlphaSaturate: + return vk::BlendFactor::eSrcAlphaSaturate; + case BlendFactor::ConstantColor: + return vk::BlendFactor::eConstantColor; + case BlendFactor::OneMinusConstantColor: + return vk::BlendFactor::eOneMinusConstantColor; + case BlendFactor::Src1Color: + return vk::BlendFactor::eSrc1Color; + case BlendFactor::InvSrc1Color: + return vk::BlendFactor::eOneMinusSrc1Color; + case BlendFactor::Src1Alpha: + return vk::BlendFactor::eSrc1Alpha; + case BlendFactor::InvSrc1Alpha: + return vk::BlendFactor::eOneMinusSrc1Alpha; + case BlendFactor::ConstantAlpha: + return vk::BlendFactor::eConstantAlpha; + case BlendFactor::OneMinusConstantAlpha: + return vk::BlendFactor::eOneMinusConstantAlpha; + default: + UNREACHABLE_MSG("Unknown blend factor: {}", static_cast(factor)); + } +} + +bool IsDualSourceBlendFactor(AmdGpu::BlendControl::BlendFactor factor) { + using BlendFactor = AmdGpu::BlendControl::BlendFactor; + switch (factor) { + case BlendFactor::Src1Color: + case BlendFactor::Src1Alpha: + case BlendFactor::InvSrc1Color: + case BlendFactor::InvSrc1Alpha: + return true; + default: + return false; + } +} + +vk::BlendOp BlendOp(AmdGpu::BlendControl::BlendFunc func) { + using BlendFunc = AmdGpu::BlendControl::BlendFunc; + switch (func) { + case BlendFunc::Add: + return vk::BlendOp::eAdd; + case BlendFunc::Subtract: + return vk::BlendOp::eSubtract; + case BlendFunc::Min: + return vk::BlendOp::eMin; + case BlendFunc::Max: + return vk::BlendOp::eMax; + case BlendFunc::ReverseSubtract: + return vk::BlendOp::eReverseSubtract; + default: + UNREACHABLE_MSG("Unknown blend op: {}", static_cast(func)); + } +} + +vk::LogicOp LogicOp(AmdGpu::ColorControl::LogicOp logic_op) { + using LogicOp = AmdGpu::ColorControl::LogicOp; + switch (logic_op) { + case LogicOp::Clear: + return vk::LogicOp::eClear; + case LogicOp::Nor: + return vk::LogicOp::eNor; + case LogicOp::AndInverted: + return vk::LogicOp::eAndInverted; + case LogicOp::CopyInverted: + return vk::LogicOp::eCopyInverted; + case LogicOp::AndReverse: + return vk::LogicOp::eAndReverse; + case LogicOp::Invert: + return vk::LogicOp::eInvert; + case LogicOp::BrushXor: + LOG_WARNING(Render_Vulkan, "Unimplemented logic op {:#x}, using closest equivalent", + u32(logic_op)); + [[fallthrough]]; + case LogicOp::Xor: + return vk::LogicOp::eXor; + case LogicOp::Nand: + return vk::LogicOp::eNand; + case LogicOp::And: + return vk::LogicOp::eAnd; + case LogicOp::Equiv: + return vk::LogicOp::eEquivalent; + case LogicOp::Noop: + return vk::LogicOp::eNoOp; + case LogicOp::OrInverted: + return vk::LogicOp::eOrInverted; + case LogicOp::Copy: + return vk::LogicOp::eCopy; + case LogicOp::OrReverse: + return vk::LogicOp::eOrReverse; + case LogicOp::Or: + return vk::LogicOp::eOr; + case LogicOp::Set: + return vk::LogicOp::eSet; + default: + UNREACHABLE_MSG("Unknown logic op {}", u32(logic_op)); + } +} + +// https://github.com/chaotic-cx/mesa-mirror/blob/0954afff5/src/amd/vulkan/radv_sampler.c#L21 +vk::SamplerAddressMode ClampMode(AmdGpu::ClampMode mode) { + switch (mode) { + case AmdGpu::ClampMode::Wrap: + return vk::SamplerAddressMode::eRepeat; + case AmdGpu::ClampMode::Mirror: + return vk::SamplerAddressMode::eMirroredRepeat; + case AmdGpu::ClampMode::ClampLastTexel: + return vk::SamplerAddressMode::eClampToEdge; + case AmdGpu::ClampMode::MirrorOnceHalfBorder: + case AmdGpu::ClampMode::MirrorOnceBorder: + LOG_WARNING(Render_Vulkan, "Unimplemented clamp mode {}, using closest equivalent.", + static_cast(mode)); + [[fallthrough]]; + case AmdGpu::ClampMode::MirrorOnceLastTexel: + return vk::SamplerAddressMode::eMirrorClampToEdge; + case AmdGpu::ClampMode::ClampHalfBorder: + LOG_WARNING(Render_Vulkan, "Unimplemented clamp mode {}, using closest equivalent.", + static_cast(mode)); + [[fallthrough]]; + case AmdGpu::ClampMode::ClampBorder: + return vk::SamplerAddressMode::eClampToBorder; + default: + UNREACHABLE(); + } +} + +vk::CompareOp DepthCompare(AmdGpu::DepthCompare comp) { + switch (comp) { + case AmdGpu::DepthCompare::Never: + return vk::CompareOp::eNever; + case AmdGpu::DepthCompare::Less: + return vk::CompareOp::eLess; + case AmdGpu::DepthCompare::Equal: + return vk::CompareOp::eEqual; + case AmdGpu::DepthCompare::LessEqual: + return vk::CompareOp::eLessOrEqual; + case AmdGpu::DepthCompare::Greater: + return vk::CompareOp::eGreater; + case AmdGpu::DepthCompare::NotEqual: + return vk::CompareOp::eNotEqual; + case AmdGpu::DepthCompare::GreaterEqual: + return vk::CompareOp::eGreaterOrEqual; + case AmdGpu::DepthCompare::Always: + return vk::CompareOp::eAlways; + default: + UNREACHABLE(); + } +} + +vk::Filter Filter(AmdGpu::Filter filter) { + switch (filter) { + case AmdGpu::Filter::Point: + case AmdGpu::Filter::AnisoPoint: + return vk::Filter::eNearest; + case AmdGpu::Filter::Bilinear: + case AmdGpu::Filter::AnisoLinear: + return vk::Filter::eLinear; + default: + UNREACHABLE(); + } +} + +vk::SamplerReductionMode FilterMode(AmdGpu::FilterMode mode) { + switch (mode) { + case AmdGpu::FilterMode::Blend: + return vk::SamplerReductionMode::eWeightedAverage; + case AmdGpu::FilterMode::Min: + return vk::SamplerReductionMode::eMin; + case AmdGpu::FilterMode::Max: + return vk::SamplerReductionMode::eMax; + default: + UNREACHABLE(); + } +} + +vk::SamplerMipmapMode MipFilter(AmdGpu::MipFilter filter) { + switch (filter) { + case AmdGpu::MipFilter::Point: + return vk::SamplerMipmapMode::eNearest; + case AmdGpu::MipFilter::Linear: + return vk::SamplerMipmapMode::eLinear; + case AmdGpu::MipFilter::None: + return vk::SamplerMipmapMode::eNearest; + default: + UNREACHABLE(); + } +} + +vk::BorderColor BorderColor(AmdGpu::BorderColor color) { + switch (color) { + case AmdGpu::BorderColor::TransparentBlack: + return vk::BorderColor::eFloatTransparentBlack; + case AmdGpu::BorderColor::OpaqueBlack: + return vk::BorderColor::eFloatOpaqueBlack; + case AmdGpu::BorderColor::White: + return vk::BorderColor::eFloatOpaqueWhite; + case AmdGpu::BorderColor::Custom: + return vk::BorderColor::eFloatCustomEXT; + default: + UNREACHABLE(); + } +} + +vk::ComponentSwizzle ComponentSwizzle(AmdGpu::CompSwizzle comp_swizzle) { + switch (comp_swizzle) { + case AmdGpu::CompSwizzle::Zero: + return vk::ComponentSwizzle::eZero; + case AmdGpu::CompSwizzle::One: + return vk::ComponentSwizzle::eOne; + case AmdGpu::CompSwizzle::Red: + return vk::ComponentSwizzle::eR; + case AmdGpu::CompSwizzle::Green: + return vk::ComponentSwizzle::eG; + case AmdGpu::CompSwizzle::Blue: + return vk::ComponentSwizzle::eB; + case AmdGpu::CompSwizzle::Alpha: + return vk::ComponentSwizzle::eA; + default: + UNREACHABLE(); + } +} + +vk::ComponentMapping ComponentMapping(AmdGpu::CompMapping comp_mapping) { + return vk::ComponentMapping{ + .r = ComponentSwizzle(comp_mapping.r), + .g = ComponentSwizzle(comp_mapping.g), + .b = ComponentSwizzle(comp_mapping.b), + .a = ComponentSwizzle(comp_mapping.a), + }; +} + +// Texel buffer feature flags are not needed as format is interpreted in-shader. +static constexpr vk::FormatFeatureFlags2 BufferRead = vk::FormatFeatureFlagBits2::eVertexBuffer; +static constexpr vk::FormatFeatureFlags2 BufferWrite = static_cast(0); +static constexpr vk::FormatFeatureFlags2 ImageRead = vk::FormatFeatureFlagBits2::eTransferSrc | + vk::FormatFeatureFlagBits2::eTransferDst | + vk::FormatFeatureFlagBits2::eSampledImage; +static constexpr vk::FormatFeatureFlags2 ImageWrite = + vk::FormatFeatureFlagBits2::eStorageImage | + vk::FormatFeatureFlagBits2::eStorageReadWithoutFormat | + vk::FormatFeatureFlagBits2::eStorageWriteWithoutFormat; +static constexpr vk::FormatFeatureFlags2 Mrt = vk::FormatFeatureFlagBits2::eColorAttachment; + +// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture] +static constexpr vk::FormatFeatureFlags2 GetDataFormatFeatureFlags( + const AmdGpu::DataFormat data_format) { + switch (data_format) { + case AmdGpu::DataFormat::FormatInvalid: + case AmdGpu::DataFormat::Format8: + case AmdGpu::DataFormat::Format16: + case AmdGpu::DataFormat::Format8_8: + case AmdGpu::DataFormat::Format32: + case AmdGpu::DataFormat::Format16_16: + case AmdGpu::DataFormat::Format10_11_11: + case AmdGpu::DataFormat::Format11_11_10: + case AmdGpu::DataFormat::Format10_10_10_2: + case AmdGpu::DataFormat::Format2_10_10_10: + case AmdGpu::DataFormat::Format8_8_8_8: + case AmdGpu::DataFormat::Format32_32: + case AmdGpu::DataFormat::Format16_16_16_16: + case AmdGpu::DataFormat::Format32_32_32_32: + return BufferRead | BufferWrite | ImageRead | ImageWrite | Mrt; + case AmdGpu::DataFormat::Format32_32_32: + return BufferRead | BufferWrite | ImageRead; + case AmdGpu::DataFormat::Format5_6_5: + case AmdGpu::DataFormat::Format1_5_5_5: + case AmdGpu::DataFormat::Format5_5_5_1: + case AmdGpu::DataFormat::Format4_4_4_4: + return ImageRead | ImageWrite | Mrt; + case AmdGpu::DataFormat::Format8_24: + case AmdGpu::DataFormat::Format24_8: + case AmdGpu::DataFormat::FormatX24_8_32: + return ImageRead | Mrt; + case AmdGpu::DataFormat::FormatGB_GR: + case AmdGpu::DataFormat::FormatBG_RG: + case AmdGpu::DataFormat::Format5_9_9_9: + case AmdGpu::DataFormat::FormatBc1: + case AmdGpu::DataFormat::FormatBc2: + case AmdGpu::DataFormat::FormatBc3: + case AmdGpu::DataFormat::FormatBc4: + case AmdGpu::DataFormat::FormatBc5: + case AmdGpu::DataFormat::FormatBc6: + case AmdGpu::DataFormat::FormatBc7: + case AmdGpu::DataFormat::Format4_4: + case AmdGpu::DataFormat::Format6_5_5: + case AmdGpu::DataFormat::Format1: + case AmdGpu::DataFormat::Format1_Reversed: + case AmdGpu::DataFormat::Format32_As_8: + case AmdGpu::DataFormat::Format32_As_8_8: + case AmdGpu::DataFormat::Format32_As_32_32_32_32: + return ImageRead; + case AmdGpu::DataFormat::FormatFmask8_S2_F1: + case AmdGpu::DataFormat::FormatFmask8_S4_F1: + case AmdGpu::DataFormat::FormatFmask8_S8_F1: + case AmdGpu::DataFormat::FormatFmask8_S2_F2: + case AmdGpu::DataFormat::FormatFmask8_S4_F2: + case AmdGpu::DataFormat::FormatFmask8_S4_F4: + case AmdGpu::DataFormat::FormatFmask16_S16_F1: + case AmdGpu::DataFormat::FormatFmask16_S8_F2: + case AmdGpu::DataFormat::FormatFmask32_S16_F2: + case AmdGpu::DataFormat::FormatFmask32_S8_F4: + case AmdGpu::DataFormat::FormatFmask32_S8_F8: + case AmdGpu::DataFormat::FormatFmask64_S16_F4: + case AmdGpu::DataFormat::FormatFmask64_S16_F8: + return ImageRead | ImageWrite; + } + UNREACHABLE_MSG("Missing feature flags for data format {}", static_cast(data_format)); +} + +// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture] +static constexpr vk::FormatFeatureFlags2 GetNumberFormatFeatureFlags( + const AmdGpu::NumberFormat number_format) { + switch (number_format) { + case AmdGpu::NumberFormat::Unorm: + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + case AmdGpu::NumberFormat::Float: + return BufferRead | BufferWrite | ImageRead | ImageWrite | Mrt; + case AmdGpu::NumberFormat::Uscaled: + case AmdGpu::NumberFormat::Sscaled: + case AmdGpu::NumberFormat::SnormNz: + return BufferRead | ImageRead; + case AmdGpu::NumberFormat::Srgb: + return ImageRead | Mrt; + case AmdGpu::NumberFormat::Ubnorm: + case AmdGpu::NumberFormat::UbnormNz: + case AmdGpu::NumberFormat::Ubint: + case AmdGpu::NumberFormat::Ubscaled: + return ImageRead; + } + UNREACHABLE_MSG("Missing feature flags for number format {}", static_cast(number_format)); +} + +static constexpr SurfaceFormatInfo CreateSurfaceFormatInfo(const AmdGpu::DataFormat data_format, + const AmdGpu::NumberFormat number_format, + const vk::Format vk_format) { + return { + .data_format = data_format, + .number_format = number_format, + .vk_format = vk_format, + .flags = + GetDataFormatFeatureFlags(data_format) & GetNumberFormatFeatureFlags(number_format), + }; +} + +std::span SurfaceFormats() { + // Uscaled, Sscaled, and Ubnorm formats are automatically remapped and handled in shader. + static constexpr std::array formats{ + // Invalid + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Unorm, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Snorm, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Uscaled, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Sscaled, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Uint, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Sint, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::SnormNz, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Float, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Srgb, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Ubnorm, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::UbnormNz, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Ubint, + vk::Format::eUndefined), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Ubscaled, + vk::Format::eUndefined), + // 8 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Unorm, + vk::Format::eR8Unorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Snorm, + vk::Format::eR8Snorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Uint, + vk::Format::eR8Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Sint, + vk::Format::eR8Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Srgb, + vk::Format::eR8Srgb), + // 16 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Unorm, + vk::Format::eR16Unorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Snorm, + vk::Format::eR16Snorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Uint, + vk::Format::eR16Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Sint, + vk::Format::eR16Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Float, + vk::Format::eR16Sfloat), + // 8_8 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Unorm, + vk::Format::eR8G8Unorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Snorm, + vk::Format::eR8G8Snorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Uint, + vk::Format::eR8G8Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Sint, + vk::Format::eR8G8Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Srgb, + vk::Format::eR8G8Srgb), + // 32 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32, AmdGpu::NumberFormat::Uint, + vk::Format::eR32Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32, AmdGpu::NumberFormat::Sint, + vk::Format::eR32Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32, AmdGpu::NumberFormat::Float, + vk::Format::eR32Sfloat), + // 16_16 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Unorm, + vk::Format::eR16G16Unorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Snorm, + vk::Format::eR16G16Snorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Uint, + vk::Format::eR16G16Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Sint, + vk::Format::eR16G16Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Float, + vk::Format::eR16G16Sfloat), + // 10_11_11 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format10_11_11, AmdGpu::NumberFormat::Float, + vk::Format::eB10G11R11UfloatPack32), + // 11_11_10 - Remapped to 10_11_11. + // 10_10_10_2 - Remapped to 2_10_10_10. + // 2_10_10_10 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format2_10_10_10, AmdGpu::NumberFormat::Unorm, + vk::Format::eA2B10G10R10UnormPack32), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format2_10_10_10, AmdGpu::NumberFormat::Snorm, + vk::Format::eA2B10G10R10SnormPack32), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format2_10_10_10, AmdGpu::NumberFormat::Uint, + vk::Format::eA2B10G10R10UintPack32), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format2_10_10_10, AmdGpu::NumberFormat::Sint, + vk::Format::eA2B10G10R10SintPack32), + // 8_8_8_8 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Unorm, + vk::Format::eR8G8B8A8Unorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Snorm, + vk::Format::eR8G8B8A8Snorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Uint, + vk::Format::eR8G8B8A8Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Sint, + vk::Format::eR8G8B8A8Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Srgb, + vk::Format::eR8G8B8A8Srgb), + // 32_32 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32, AmdGpu::NumberFormat::Uint, + vk::Format::eR32G32Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32, AmdGpu::NumberFormat::Sint, + vk::Format::eR32G32Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32, AmdGpu::NumberFormat::Float, + vk::Format::eR32G32Sfloat), + // 16_16_16_16 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Unorm, + vk::Format::eR16G16B16A16Unorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Snorm, + vk::Format::eR16G16B16A16Snorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Uint, + vk::Format::eR16G16B16A16Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Sint, + vk::Format::eR16G16B16A16Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, + AmdGpu::NumberFormat::SnormNz, vk::Format::eR16G16B16A16Snorm), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Float, + vk::Format::eR16G16B16A16Sfloat), + // 32_32_32 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32, AmdGpu::NumberFormat::Uint, + vk::Format::eR32G32B32Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32, AmdGpu::NumberFormat::Sint, + vk::Format::eR32G32B32Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32, AmdGpu::NumberFormat::Float, + vk::Format::eR32G32B32Sfloat), + // 32_32_32_32 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32_32, AmdGpu::NumberFormat::Uint, + vk::Format::eR32G32B32A32Uint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32_32, AmdGpu::NumberFormat::Sint, + vk::Format::eR32G32B32A32Sint), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32_32, AmdGpu::NumberFormat::Float, + vk::Format::eR32G32B32A32Sfloat), + // 5_6_5 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format5_6_5, AmdGpu::NumberFormat::Unorm, + vk::Format::eR5G6B5UnormPack16), + // 1_5_5_5 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format1_5_5_5, AmdGpu::NumberFormat::Unorm, + vk::Format::eA1R5G5B5UnormPack16), + // 5_5_5_1 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format5_5_5_1, AmdGpu::NumberFormat::Unorm, + vk::Format::eR5G5B5A1UnormPack16), + // 4_4_4_4 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format4_4_4_4, AmdGpu::NumberFormat::Unorm, + vk::Format::eB4G4R4A4UnormPack16), + // 8_24 + // 24_8 + // X24_8_32 + // GB_GR + // BG_RG + // 5_9_9_9 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format5_9_9_9, AmdGpu::NumberFormat::Float, + vk::Format::eE5B9G9R9UfloatPack32), + // BC1 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc1, AmdGpu::NumberFormat::Unorm, + vk::Format::eBc1RgbaUnormBlock), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc1, AmdGpu::NumberFormat::Srgb, + vk::Format::eBc1RgbaSrgbBlock), + // BC2 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc2, AmdGpu::NumberFormat::Unorm, + vk::Format::eBc2UnormBlock), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc2, AmdGpu::NumberFormat::Srgb, + vk::Format::eBc2SrgbBlock), + // BC3 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc3, AmdGpu::NumberFormat::Unorm, + vk::Format::eBc3UnormBlock), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc3, AmdGpu::NumberFormat::Srgb, + vk::Format::eBc3SrgbBlock), + // BC4 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc4, AmdGpu::NumberFormat::Unorm, + vk::Format::eBc4UnormBlock), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc4, AmdGpu::NumberFormat::Snorm, + vk::Format::eBc4SnormBlock), + // BC5 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc5, AmdGpu::NumberFormat::Unorm, + vk::Format::eBc5UnormBlock), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc5, AmdGpu::NumberFormat::Snorm, + vk::Format::eBc5SnormBlock), + // BC6 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc6, AmdGpu::NumberFormat::Unorm, + vk::Format::eBc6HUfloatBlock), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc6, AmdGpu::NumberFormat::Snorm, + vk::Format::eBc6HSfloatBlock), + // BC7 + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc7, AmdGpu::NumberFormat::Unorm, + vk::Format::eBc7UnormBlock), + CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc7, AmdGpu::NumberFormat::Srgb, + vk::Format::eBc7SrgbBlock), + }; + return formats; +} + +// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture] +static const size_t amd_gpu_data_format_bit_size = 6; // All values are under 64 +static const size_t amd_gpu_number_format_bit_size = 4; // All values are under 16 + +static size_t GetSurfaceFormatTableIndex(AmdGpu::DataFormat data_format, + AmdGpu::NumberFormat num_format) { + DEBUG_ASSERT(u32(data_format) < 1 << amd_gpu_data_format_bit_size); + DEBUG_ASSERT(u32(num_format) < 1 << amd_gpu_number_format_bit_size); + size_t result = static_cast(num_format) | + (static_cast(data_format) << amd_gpu_number_format_bit_size); + return result; +} + +static auto surface_format_table = []() constexpr { + std::array + result; + for (auto& entry : result) { + entry = vk::Format::eUndefined; + } + for (const auto& supported_format : SurfaceFormats()) { + result[GetSurfaceFormatTableIndex(supported_format.data_format, + supported_format.number_format)] = + supported_format.vk_format; + } + return result; +}(); + +vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) { + vk::Format result = surface_format_table[GetSurfaceFormatTableIndex(data_format, num_format)]; + bool found = + result != vk::Format::eUndefined || data_format == AmdGpu::DataFormat::FormatInvalid; + ASSERT_MSG(found, "Unknown data_format={} and num_format={}", static_cast(data_format), + static_cast(num_format)); + return result; +} + +static constexpr DepthFormatInfo CreateDepthFormatInfo( + const DepthBuffer::ZFormat z_format, const DepthBuffer::StencilFormat stencil_format, + const vk::Format vk_format) { + return { + .z_format = z_format, + .stencil_format = stencil_format, + .vk_format = vk_format, + .flags = vk::FormatFeatureFlagBits2::eDepthStencilAttachment, + }; +} + +std::span DepthFormats() { + using ZFormat = DepthBuffer::ZFormat; + using StencilFormat = DepthBuffer::StencilFormat; + static constexpr std::array formats{ + // Invalid + CreateDepthFormatInfo(ZFormat::Invalid, StencilFormat::Invalid, vk::Format::eUndefined), + CreateDepthFormatInfo(ZFormat::Invalid, StencilFormat::Stencil8, + vk::Format::eD32SfloatS8Uint), + // 16 + CreateDepthFormatInfo(ZFormat::Z16, StencilFormat::Invalid, vk::Format::eD16Unorm), + CreateDepthFormatInfo(ZFormat::Z16, StencilFormat::Stencil8, vk::Format::eD16UnormS8Uint), + // 32_Float + CreateDepthFormatInfo(ZFormat::Z32Float, StencilFormat::Invalid, vk::Format::eD32Sfloat), + CreateDepthFormatInfo(ZFormat::Z32Float, StencilFormat::Stencil8, + vk::Format::eD32SfloatS8Uint), + }; + return formats; +} + +vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat stencil_format) { + const auto& formats = DepthFormats(); + const auto format = + std::find_if(formats.begin(), formats.end(), [&](const DepthFormatInfo& format_info) { + return format_info.z_format == z_format && format_info.stencil_format == stencil_format; + }); + ASSERT_MSG(format != formats.end(), "Unknown z_format={} and stencil_format={}", + static_cast(z_format), static_cast(stencil_format)); + return format->vk_format; +} + +vk::ClearValue ColorBufferClearValue(const AmdGpu::ColorBuffer& color_buffer) { + const auto comp_swizzle = color_buffer.Swizzle(); + const auto format = AmdGpu::DataFormat(color_buffer.info.format); + const auto number_type = color_buffer.GetFixedNumberFormat(); + + const auto& c0 = color_buffer.clear_word0; + const auto& c1 = color_buffer.clear_word1; + + vk::ClearColorValue color{}; + + switch (number_type) { + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[3] = 1; + break; + default: + color.float32[3] = 1.0f; + break; + } + + switch (format) { + case AmdGpu::DataFormat::Format8: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + case AmdGpu::NumberFormat::Srgb: // Should we handle gamma correction here? + color.float32[0] = NumberUtils::U8ToUnorm(c0 & 0xff); + break; + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S8ToSnorm(c0 & 0xff); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0; + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format16: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + color.float32[0] = NumberUtils::U16ToUnorm(c0 & 0xffff); + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S16ToSnorm(c0 & 0xffff); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0; + break; + case AmdGpu::NumberFormat::Float: + color.float32[0] = NumberUtils::Uf16ToF32(c0 & 0xffff); + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format8_8: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + case AmdGpu::NumberFormat::Srgb: // Should we handle gamma correction here? + color.float32[0] = NumberUtils::U8ToUnorm(c0 & 0xff); + color.float32[1] = NumberUtils::U8ToUnorm((c0 >> 8) & 0xff); + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S8ToSnorm(c0 & 0xff); + color.float32[1] = NumberUtils::S8ToSnorm((c0 >> 8) & 0xff); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0 & 0xff; + color.uint32[1] = (c0 >> 8) & 0xff; + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format32: + switch (number_type) { + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0; + break; + case AmdGpu::NumberFormat::Float: + color.float32[0] = *(reinterpret_cast(&c0)); + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format16_16: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + color.float32[0] = NumberUtils::U16ToUnorm(c0 & 0xffff); + color.float32[1] = NumberUtils::U16ToUnorm((c0 >> 16) & 0xffff); + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S16ToSnorm(c0 & 0xffff); + color.float32[1] = NumberUtils::S16ToSnorm((c0 >> 16) & 0xffff); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0 & 0xffff; + color.uint32[1] = (c0 >> 16) & 0xffff; + break; + case AmdGpu::NumberFormat::Float: + color.float32[0] = NumberUtils::Uf16ToF32(c0 & 0xffff); + color.float32[1] = NumberUtils::Uf16ToF32((c0 >> 16) & 0xffff); + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format10_11_11: + color.float32[0] = NumberUtils::Uf11ToF32(c0 & 0x7ff); + color.float32[1] = NumberUtils::Uf11ToF32((c0 >> 11) & 0x7ff); + color.float32[2] = NumberUtils::Uf10ToF32((c0 >> 22) & 0x3ff); + break; + case AmdGpu::DataFormat::Format11_11_10: + color.float32[0] = NumberUtils::Uf10ToF32(c0 & 0x3ff); + color.float32[1] = NumberUtils::Uf11ToF32((c0 >> 10) & 0x7ff); + color.float32[2] = NumberUtils::Uf11ToF32((c0 >> 21) & 0x7ff); + break; + case AmdGpu::DataFormat::Format5_9_9_9: { + int exponent; + union { + float f; + u32 u; + } scale; + + exponent = (c0 >> 27) - 10; + scale.u = (exponent + 127) << 23; + + color.float32[0] = (c0 & 0x1ff) * scale.f; + color.float32[1] = ((c0 >> 9) & 0x1ff) * scale.f; + color.float32[2] = ((c0 >> 18) & 0x1ff) * scale.f; + break; + } + case AmdGpu::DataFormat::Format10_10_10_2: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + color.float32[0] = NumberUtils::U2ToUnorm(c0 & 0x3); + color.float32[1] = NumberUtils::U10ToUnorm((c0 >> 2) & 0x3ff); + color.float32[2] = NumberUtils::U10ToUnorm((c0 >> 12) & 0x3ff); + color.float32[3] = NumberUtils::U10ToUnorm(c0 >> 22); + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S2ToSnorm(c0 & 0x3); + color.float32[1] = NumberUtils::S10ToSnorm((c0 >> 2) & 0x3ff); + color.float32[2] = NumberUtils::S10ToSnorm((c0 >> 12) & 0x3ff); + color.float32[3] = NumberUtils::S2ToSnorm(c0 >> 22); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0 & 0x3; + color.uint32[1] = (c0 >> 2) & 0x3ff; + color.uint32[2] = (c0 >> 12) & 0x3ff; + color.uint32[3] = c0 >> 22; + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format2_10_10_10: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + color.float32[0] = NumberUtils::U10ToUnorm(c0 & 0x3ff); + color.float32[1] = NumberUtils::U10ToUnorm((c0 >> 10) & 0x3ff); + color.float32[2] = NumberUtils::U10ToUnorm((c0 >> 20) & 0x3ff); + color.float32[3] = NumberUtils::U2ToUnorm(c0 >> 30); + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S10ToSnorm(c0 & 0x3ff); + color.float32[1] = NumberUtils::S10ToSnorm((c0 >> 10) & 0x3ff); + color.float32[2] = NumberUtils::S10ToSnorm((c0 >> 20) & 0x3ff); + color.float32[3] = NumberUtils::S2ToSnorm(c0 >> 30); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0 & 0x3ff; + color.uint32[1] = (c0 >> 10) & 0x3ff; + color.uint32[2] = (c0 >> 20) & 0x3ff; + color.uint32[3] = c0 >> 30; + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format8_8_8_8: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + case AmdGpu::NumberFormat::Srgb: // Should we handle gamma correction here? + color.float32[0] = NumberUtils::U8ToUnorm(c0 & 0xff); + color.float32[1] = NumberUtils::U8ToUnorm((c0 >> 8) & 0xff); + color.float32[2] = NumberUtils::U8ToUnorm((c0 >> 16) & 0xff); + color.float32[3] = NumberUtils::U8ToUnorm(c0 >> 24); + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S8ToSnorm(c0 & 0xff); + color.float32[1] = NumberUtils::S8ToSnorm((c0 >> 8) & 0xff); + color.float32[2] = NumberUtils::S8ToSnorm((c0 >> 16) & 0xff); + color.float32[3] = NumberUtils::S8ToSnorm(c0 >> 24); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0 & 0xff; + color.uint32[1] = (c0 >> 8) & 0xff; + color.uint32[2] = (c0 >> 16) & 0xff; + color.uint32[3] = c0 >> 24; + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format32_32: + switch (number_type) { + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0; + color.uint32[1] = c1; + break; + case AmdGpu::NumberFormat::Float: + color.float32[0] = *(reinterpret_cast(&c0)); + color.float32[1] = *(reinterpret_cast(&c1)); + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format16_16_16_16: + switch (number_type) { + case AmdGpu::NumberFormat::Unorm: + color.float32[0] = NumberUtils::U16ToUnorm(c0 & 0xffff); + color.float32[1] = NumberUtils::U16ToUnorm((c0 >> 16) & 0xffff); + color.float32[2] = NumberUtils::U16ToUnorm(c1 & 0xffff); + color.float32[3] = NumberUtils::U16ToUnorm((c1 >> 16) & 0xffff); + break; + case AmdGpu::NumberFormat::Snorm: + case AmdGpu::NumberFormat::SnormNz: + color.float32[0] = NumberUtils::S16ToSnorm(c0 & 0xffff); + color.float32[1] = NumberUtils::S16ToSnorm((c0 >> 16) & 0xffff); + color.float32[2] = NumberUtils::S16ToSnorm(c1 & 0xffff); + color.float32[3] = NumberUtils::S16ToSnorm((c1 >> 16) & 0xffff); + break; + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0 & 0xffff; + color.uint32[1] = (c0 >> 16) & 0xffff; + color.uint32[2] = c1 & 0xffff; + color.uint32[3] = (c1 >> 16) & 0xffff; + break; + case AmdGpu::NumberFormat::Float: + color.float32[0] = NumberUtils::Uf16ToF32(c0 & 0xffff); + color.float32[1] = NumberUtils::Uf16ToF32((c0 >> 16) & 0xffff); + color.float32[2] = NumberUtils::Uf16ToF32(c1 & 0xffff); + color.float32[3] = NumberUtils::Uf16ToF32((c1 >> 16) & 0xffff); + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format32_32_32_32: + switch (number_type) { + case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberFormat::Sint: + color.uint32[0] = c0; + color.uint32[1] = c0; + color.uint32[2] = c0; + color.uint32[3] = c1; + break; + case AmdGpu::NumberFormat::Float: + color.float32[0] = *(reinterpret_cast(&c0)); + color.float32[1] = *(reinterpret_cast(&c0)); + color.float32[2] = *(reinterpret_cast(&c0)); + color.float32[3] = *(reinterpret_cast(&c1)); + break; + default: + INVALID_NUMBER_FORMAT_COMBO; + break; + } + break; + case AmdGpu::DataFormat::Format5_6_5: + color.float32[0] = NumberUtils::U5ToUnorm(c0 & 0x1f); + color.float32[1] = NumberUtils::U6ToUnorm((c0 >> 5) & 0x3f); + color.float32[2] = NumberUtils::U5ToUnorm(c0 >> 11); + break; + case AmdGpu::DataFormat::Format1_5_5_5: + color.float32[0] = NumberUtils::U5ToUnorm(c0 & 0x1f); + color.float32[1] = NumberUtils::U5ToUnorm((c0 >> 5) & 0x1f); + color.float32[2] = NumberUtils::U5ToUnorm((c0 >> 10) & 0x1f); + color.float32[3] = (c0 >> 15) ? 1.0f : 0.0f; + break; + case AmdGpu::DataFormat::Format5_5_5_1: + color.float32[0] = (c0 & 0x1) ? 1.0f : 0.0f; + color.float32[1] = NumberUtils::U5ToUnorm((c0 >> 1) & 0x1f); + color.float32[2] = NumberUtils::U5ToUnorm((c0 >> 6) & 0x1f); + color.float32[3] = NumberUtils::U5ToUnorm((c0 >> 11) & 0x1f); + break; + case AmdGpu::DataFormat::Format4_4_4_4: + color.float32[0] = NumberUtils::U4ToUnorm(c0 & 0xf); + color.float32[1] = NumberUtils::U4ToUnorm((c0 >> 4) & 0xf); + color.float32[2] = NumberUtils::U4ToUnorm((c0 >> 8) & 0xf); + color.float32[3] = NumberUtils::U4ToUnorm(c0 >> 12); + break; + default: + LOG_ERROR(Render_Vulkan, "Unsupported color buffer format: {}", format); + break; + } + + color.float32 = comp_swizzle.Apply(color.float32); + return {.color = color}; +} + +vk::SampleCountFlagBits RawNumSamples(u32 num_samples) { + switch (num_samples) { + case 1: + return vk::SampleCountFlagBits::e1; + case 2: + return vk::SampleCountFlagBits::e2; + case 4: + return vk::SampleCountFlagBits::e4; + case 8: + return vk::SampleCountFlagBits::e8; + case 16: + return vk::SampleCountFlagBits::e16; + default: + UNREACHABLE(); + } +} + +vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags) { + vk::SampleCountFlagBits flags = RawNumSamples(num_samples); + // Half sample counts until supported, with a minimum of 1. + while (!(supported_flags & flags) && num_samples > 1) { + num_samples /= 2; + flags = RawNumSamples(num_samples); + } + return flags; +} + +} // namespace Vulkan::LiverpoolToVK diff --git a/gpu/shadps4/video_core/renderer_vulkan/liverpool_to_vk.h b/gpu/shadps4/video_core/renderer_vulkan/liverpool_to_vk.h new file mode 100644 index 0000000..2ca737a --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/liverpool_to_vk.h @@ -0,0 +1,117 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/assert.h" +#include "video_core/amdgpu/pixel_format.h" +#include "video_core/amdgpu/regs_color.h" +#include "video_core/amdgpu/regs_depth.h" +#include "video_core/amdgpu/regs_primitive.h" +#include "video_core/amdgpu/regs_vertex.h" +#include "video_core/amdgpu/resource.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan::LiverpoolToVK { + +vk::StencilOp StencilOp(AmdGpu::StencilFunc op); + +vk::CompareOp CompareOp(AmdGpu::CompareFunc func); + +bool IsPrimitiveCulled(AmdGpu::PrimitiveType type); + +vk::PrimitiveTopology PrimitiveType(AmdGpu::PrimitiveType type); + +vk::PolygonMode PolygonMode(AmdGpu::PolygonMode mode); + +vk::CullModeFlags CullMode(AmdGpu::CullMode mode); + +vk::FrontFace FrontFace(AmdGpu::FrontFace mode); + +vk::BlendFactor BlendFactor(AmdGpu::BlendControl::BlendFactor factor); + +bool IsDualSourceBlendFactor(AmdGpu::BlendControl::BlendFactor factor); + +vk::BlendOp BlendOp(AmdGpu::BlendControl::BlendFunc func); + +vk::LogicOp LogicOp(AmdGpu::ColorControl::LogicOp logic_op); + +vk::SamplerAddressMode ClampMode(AmdGpu::ClampMode mode); + +vk::CompareOp DepthCompare(AmdGpu::DepthCompare comp); + +vk::Filter Filter(AmdGpu::Filter filter); + +vk::SamplerReductionMode FilterMode(AmdGpu::FilterMode mode); + +vk::SamplerMipmapMode MipFilter(AmdGpu::MipFilter filter); + +vk::BorderColor BorderColor(AmdGpu::BorderColor color); + +vk::ComponentSwizzle ComponentSwizzle(AmdGpu::CompSwizzle comp_swizzle); + +vk::ComponentMapping ComponentMapping(AmdGpu::CompMapping comp_mapping); + +struct SurfaceFormatInfo { + AmdGpu::DataFormat data_format; + AmdGpu::NumberFormat number_format; + vk::Format vk_format; + vk::FormatFeatureFlags2 flags; +}; +std::span SurfaceFormats(); + +vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format); + +struct DepthFormatInfo { + AmdGpu::DepthBuffer::ZFormat z_format; + AmdGpu::DepthBuffer::StencilFormat stencil_format; + vk::Format vk_format; + vk::FormatFeatureFlags2 flags; +}; +std::span DepthFormats(); + +vk::Format DepthFormat(AmdGpu::DepthBuffer::ZFormat z_format, + AmdGpu::DepthBuffer::StencilFormat stencil_format); + +vk::ClearValue ColorBufferClearValue(const AmdGpu::ColorBuffer& color_buffer); + +vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags); + +static inline bool IsFormatDepthCompatible(vk::Format fmt) { + switch (fmt) { + // 32-bit float compatible + case vk::Format::eD32Sfloat: + case vk::Format::eR32Sfloat: + case vk::Format::eR32Uint: + // 16-bit unorm compatible + case vk::Format::eD16Unorm: + case vk::Format::eR16Unorm: + return true; + default: + return false; + } +} + +static inline bool IsFormatStencilCompatible(vk::Format fmt) { + switch (fmt) { + // 8-bit uint compatible + case vk::Format::eS8Uint: + case vk::Format::eR8Uint: + case vk::Format::eR8Unorm: + return true; + default: + return false; + } +} + +static inline vk::Format PromoteFormatToDepth(vk::Format fmt) { + if (fmt == vk::Format::eR32Sfloat || fmt == vk::Format::eR32Uint) { + return vk::Format::eD32Sfloat; + } else if (fmt == vk::Format::eR16Unorm) { + return vk::Format::eD16Unorm; + } + UNREACHABLE_MSG("Unexpected depth format {}", vk::to_string(fmt)); +} + +} // namespace Vulkan::LiverpoolToVK diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_barrier_tracker.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_barrier_tracker.cpp new file mode 100644 index 0000000..c7d9131 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_barrier_tracker.cpp @@ -0,0 +1,368 @@ +// SPDX-FileCopyrightText: Copyright DXVK Project +// SPDX-License-Identifier: Zlib + +#include +#include "video_core/renderer_vulkan/vk_barrier_tracker.h" + +namespace Vulkan { + +BarrierTracker::BarrierTracker() { + // Having an accessible 0 node makes certain things easier to + // implement and allows us to use 0 as an invalid node index. + nodes.emplace_back(); + + // Pre-allocate root nodes for the implicit hash table + for (u32 i = 0; i < 2u * HashTableSize; i++) { + AllocateNode(); + } +} + +bool BarrierTracker::FindRange(const AddressRange& range, Access access_type) const { + u32 root_index = ComputeRootIndex(range, access_type); + u32 node_index = FindNode(range, root_index); + return node_index; +} + +void BarrierTracker::InsertRange(const AddressRange& range, Access access_type) { + // If we can just insert the node with no conflicts, we don't have to do anything. + u32 root_index = ComputeRootIndex(range, access_type); + u32 node_index = InsertNode(range, root_index); + + if (!node_index) [[likely]] { + return; + } + + // If there's an existing node and it contains the entire range we want to add already, also + // don't do anything. If there are conflicting access ops, reset it. + auto& node = nodes[node_index]; + if (node.address_range.Contains(range)) { + return; + } + + // Otherwise, check if there are any other overlapping ranges. + // If that is not the case, simply update the range we found. + bool has_overlap = false; + + if (range.range_start < node.address_range.range_start) { + AddressRange test_range; + test_range.resource = range.resource; + test_range.range_start = range.range_start; + test_range.range_end = node.address_range.range_start - 1; + has_overlap = FindNode(test_range, root_index); + } + + if (range.range_end > node.address_range.range_end && !has_overlap) { + AddressRange test_range; + test_range.resource = range.resource; + test_range.range_start = node.address_range.range_end + 1; + test_range.range_end = range.range_end; + has_overlap = FindNode(test_range, root_index); + } + + if (!has_overlap) { + node.address_range.range_start = + std::min(node.address_range.range_start, range.range_start); + node.address_range.range_end = std::max(node.address_range.range_end, range.range_end); + return; + } + + // If there are multiple ranges overlapping the one being inserted, remove them all and insert + // the merged range. + AddressRange merged_range = range; + while (node_index) { + auto& node = nodes[node_index]; + merged_range.range_start = + std::min(merged_range.range_start, node.address_range.range_start); + merged_range.range_end = std::max(merged_range.range_end, node.address_range.range_end); + + RemoveNode(node_index, root_index); + node_index = FindNode(range, root_index); + } + InsertNode(merged_range, root_index); +} + +void BarrierTracker::Clear() { + root_mask_valid = 0; + while (root_mask_subtree) { + // Free subtrees if any, but keep the root node intact + const u32 root_index = std::countr_zero(root_mask_subtree) + 1; + auto& root = nodes[root_index]; + if (root.header) { + FreeNode(root.Child(0)); + FreeNode(root.Child(1)); + root.header = 0; + } + root_mask_subtree &= root_mask_subtree - 1; + } +} + +u32 BarrierTracker::AllocateNode() { + if (!free.empty()) { + const u32 node_index = free.back(); + free.pop_back(); + + // Free any subtree that the node might still have + auto& node = nodes[node_index]; + FreeNode(node.Child(0)); + FreeNode(node.Child(1)); + + node.header = 0; + return node_index; + } else { + // Allocate entirely new node in the array + const u32 node_index = nodes.size(); + nodes.emplace_back(); + return node_index; + } +} + +void BarrierTracker::FreeNode(u32 node) { + if (node) { + free.push_back(node); + } +} + +u32 BarrierTracker::FindNode(const AddressRange& range, u32 root_index) const { + // Check if the given root is valid at all + const u64 root_bit = 1ULL << (root_index - 1); + if (!(root_mask_valid & root_bit)) { + return false; + } + + // Traverse search tree normally + u32 node_index = root_index; + while (node_index) { + auto& node = nodes[node_index]; + if (node.address_range.Overlaps(range)) { + return node_index; + } + node_index = node.Child(node.address_range < range); + } + return 0; +} + +u32 BarrierTracker::InsertNode(const AddressRange& range, u32 root_index) { + // Check if the given root is valid at all + const u64 root_bit = 1ULL << (root_index - 1); + + if (!(root_mask_valid & root_bit)) { + // Update root node as necessary. Also reset its red-ness if we set it during deletion. + root_mask_valid |= root_bit; + auto& node = nodes[root_index]; + node.header = 0; + node.address_range = range; + return 0; + } + + // Traverse tree and abort if we find any range overlapping the one we're trying to insert. + u32 parent_index = root_index; + u32 child_index = 0; + + while (true) { + auto& parent = nodes[parent_index]; + if (parent.address_range.Overlaps(range)) { + return parent_index; + } + child_index = parent.address_range < range; + if (!parent.Child(child_index)) { + break; + } + parent_index = parent.Child(child_index); + } + + // Create and insert new node into the tree + const u32 node_index = AllocateNode(); + + auto& parent = nodes[parent_index]; + parent.SetChild(child_index, node_index); + + auto& node = nodes[node_index]; + node.SetRed(true); + node.SetParent(parent_index); + node.address_range = range; + + // Only do the fixup to maintain red-black properties if + // we haven't marked the root node as red in a deletion. + if (parent_index != root_index && !nodes[root_index].IsRed()) { + RebalancePostInsert(node_index, root_index); + } + + root_mask_subtree |= root_bit; + return 0; +} + +void BarrierTracker::RemoveNode(u32 node_index, u32 root_index) { + auto& node = nodes[node_index]; + + u32 l = node.Child(0); + u32 r = node.Child(1); + + if (l && r) { + // Both children are valid. Take the payload from the smallest + // node in the right subtree and delete that node instead. + u32 child_index = r; + while (nodes[child_index].Child(0)) { + child_index = nodes[child_index].Child(0); + } + + node.address_range = nodes[child_index].address_range; + RemoveNode(child_index, root_index); + return; + } + + // Deletion is expected to be exceptionally rare, to the point of + // being irrelevant in practice since it can only ever happen if an + // app reads multiple disjoint blocks of a resource and then reads + // another range covering multiple of those blocks again. Instead + // of implementing a complex post-delete fixup, mark the root as + // red and allow the tree to go unbalanced until the next reset. + if (!node.IsRed() && (node_index != root_index)) { + nodes[root_index].SetRed(true); + } + + // We're deleting the a node with one or no children. To avoid + // special-casing the root node, copy the child node to it and + // update links as necessary. + u32 child_index = std::max(l, r); + u32 parent_index = node.Parent(); + + if (child_index) { + auto& child = nodes[child_index]; + + u32 cl = child.Child(0); + u32 cr = child.Child(1); + + node.SetChild(0, cl); + node.SetChild(1, cr); + + if (node_index != root_index) + node.SetRed(child.IsRed()); + + node.address_range = child.address_range; + + if (cl) { + nodes[cl].SetParent(node_index); + } + if (cr) { + nodes[cr].SetParent(node_index); + } + + child.header = 0; + FreeNode(child_index); + } else if (node_index != root_index) { + // Removing leaf node, update parent link and move on. + auto& parent = nodes[parent_index]; + + const u32 which = parent.Child(1) == node_index; + parent.SetChild(which, 0); + + node.header = 0; + FreeNode(node_index); + } else { + // Removing root with no children, mark tree as invalid + const u64 root_bit = 1ULL << (root_index - 1u); + root_mask_subtree &= ~root_bit; + root_mask_valid &= ~root_bit; + } +} + +void BarrierTracker::RebalancePostInsert(u32 node_index, u32 root_index) { + while (node_index != root_index) { + auto& node = nodes[node_index]; + auto& p = nodes[node.Parent()]; + + if (!p.IsRed()) { + break; + } + + auto& g = nodes[p.Parent()]; + + if (g.Child(1) == node.Parent()) { + auto& u = nodes[g.Child(0)]; + + if (g.Child(0) && u.IsRed()) { + g.SetRed(true); + u.SetRed(false); + p.SetRed(false); + node_index = p.Parent(); + } else { + if (p.Child(0) == node_index) { + RotateRight(node.Parent(), root_index); + } + p.SetRed(false); + g.SetRed(true); + RotateLeft(p.Parent(), root_index); + } + } else { + auto& u = nodes[g.Child(1)]; + if (g.Child(1) && u.IsRed()) { + g.SetRed(true); + u.SetRed(false); + p.SetRed(false); + node_index = p.Parent(); + } else { + if (p.Child(1) == node_index) { + RotateLeft(node.Parent(), root_index); + } + p.SetRed(false); + g.SetRed(true); + RotateRight(p.Parent(), root_index); + } + } + } + nodes[root_index].SetRed(false); +} + +void BarrierTracker::RotateLeft(u32 node_index, u32 root_index) { + // This implements rotations in such a way that the node to + // rotate around does not move. This is important to avoid + // having a special case for the root node, and avoids having + // to access the parent or special-case the root node. + auto& node = nodes[node_index]; + + u32 l = node.Child(0); + u32 r = node.Child(1); + u32 rl = nodes[r].Child(0); + u32 rr = nodes[r].Child(1); + + nodes[l].SetParent(r); + + const bool is_red = nodes[r].IsRed(); + nodes[r].SetRed(node.IsRed()); + nodes[r].SetChild(0, l); + nodes[r].SetChild(1, rl); + + nodes[rr].SetParent(node_index); + + node.SetRed(is_red && node_index != root_index); + node.SetChild(0, r); + node.SetChild(1, rr); + + std::swap(node.address_range, nodes[r].address_range); +} + +void BarrierTracker::RotateRight(u32 node_index, u32 root_index) { + auto& node = nodes[node_index]; + + u32 l = node.Child(0); + u32 r = node.Child(1); + u32 ll = nodes[l].Child(0); + u32 lr = nodes[l].Child(1); + + nodes[r].SetParent(l); + + const bool is_red = nodes[l].IsRed(); + nodes[l].SetRed(node.IsRed()); + nodes[l].SetChild(0, lr); + nodes[l].SetChild(1, r); + + nodes[ll].SetParent(node_index); + + node.SetRed(is_red && node_index != root_index); + node.SetChild(0, ll); + node.SetChild(1, l); + + std::swap(node.address_range, nodes[l].address_range); +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_barrier_tracker.h b/gpu/shadps4/video_core/renderer_vulkan/vk_barrier_tracker.h new file mode 100644 index 0000000..0a41c81 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_barrier_tracker.h @@ -0,0 +1,137 @@ +// SPDX-FileCopyrightText: Copyright DXVK Project +// SPDX-License-Identifier: Zlib + +#pragma once + +#include +#include "common/types.h" + +namespace Vulkan { + +enum class Access : u32 { + None = 0, + Read = 1, + Write = 2, +}; + +struct AddressRange { + u64 resource{}; + u64 range_start{}; + u64 range_end{}; + + bool Contains(const AddressRange& other) const { + return resource == other.resource && range_start <= other.range_start && + range_end >= other.range_end; + } + + bool Overlaps(const AddressRange& other) const { + return resource == other.resource && range_end >= other.range_start && + range_start <= other.range_end; + } + + bool operator<(const AddressRange& other) const { + return (resource < other.resource) || + (resource == other.resource && range_start < other.range_start); + } +}; + +/** + * Node of a red-black tree, consisting of a packed node header as well as a resource address range. + * GCC generates weird code with bitfields here, so pack manually. + */ +struct BarrierTreeNode { + constexpr static u64 NodeIndexMask = (1u << 21) - 1u; + + // Packed header with node indices and the node color. + // [0:0]: Set if the node is red, clear otherwise. + // [21:1]: Index of the left child node, may be 0. + // [42:22]: Index of the right child node, may be 0. + // [43:63]: Index of the parent node, may be 0 for the root. + u64 header{}; + + // Address range of the node + AddressRange address_range{}; + + void SetRed(bool red) { + header &= ~1ULL; + header |= u64(red); + } + + bool IsRed() const { + return header & 1u; + } + + void SetParent(u32 node) { + header &= ~(NodeIndexMask << 43); + header |= u64(node) << 43; + } + + void SetChild(u32 index, u32 node) { + const u32 shift = (index ? 22 : 1); + header &= ~(NodeIndexMask << shift); + header |= u64(node) << shift; + } + + u32 Parent() const { + return (header >> 43) & NodeIndexMask; + } + + u32 Child(u32 index) const { + const u32 shift = (index ? 22 : 1); + return (header >> shift) & NodeIndexMask; + } + + bool IsRoot() const { + return Parent() == 0u; + } +}; + +/** + * Provides a two-part hash table for read and written resource ranges, which is + * backed by binary trees to handle individual address ranges as well as collisions. + */ +class BarrierTracker { + constexpr static u32 HashTableSize = 32u; + +public: + explicit BarrierTracker(); + ~BarrierTracker() = default; + + /// Checks whether there is a pending access of a given type + bool FindRange(const AddressRange& range, Access access_type) const; + + /// Inserts address range for a given access type + void InsertRange(const AddressRange& range, Access access_type); + + /// Clears the entire structure + void Clear(); + + /// Checks whether any resources are dirty + bool Empty() const { + return !root_mask_valid; + } + +private: + u32 AllocateNode(); + void FreeNode(u32 node); + u32 FindNode(const AddressRange& range, u32 root_index) const; + u32 InsertNode(const AddressRange& range, u32 root_index); + void RemoveNode(u32 node_index, u32 root_index); + void RebalancePostInsert(u32 node_index, u32 root_index); + void RotateLeft(u32 node_index, u32 root_index); + void RotateRight(u32 node_index, u32 root_index); + + constexpr static u32 ComputeRootIndex(const AddressRange& range, Access access) { + u64 hash = range.resource * 93887; + hash ^= (hash >> 16); + return 1 + (hash % HashTableSize) + (access == Access::Write ? HashTableSize : 0); + } + +private: + u64 root_mask_valid{}; + u64 root_mask_subtree{}; + std::vector nodes; + std::vector free; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_common.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_common.cpp new file mode 100644 index 0000000..b195678 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_common.cpp @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "video_core/renderer_vulkan/vk_common.h" + +// Implement vma functions +#define VMA_IMPLEMENTATION +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" +#include +#pragma clang diagnostic pop + +// Store the dispatch loader here +VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_common.h b/gpu/shadps4/video_core/renderer_vulkan/vk_common.h new file mode 100644 index 0000000..5fe199e --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_common.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +// Include vulkan-hpp header +#define VK_ENABLE_BETA_EXTENSIONS +#define VK_NO_PROTOTYPES +#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 +#define VULKAN_HPP_NO_CONSTRUCTORS +#define VULKAN_HPP_NO_STRUCT_SETTERS +#define VULKAN_HPP_HAS_SPACESHIP_OPERATOR +#define VULKAN_HPP_NO_EXCEPTIONS +// Define assert-on-result to nothing to instead return the result for our handling. +#define VULKAN_HPP_ASSERT_ON_RESULT + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-value" +#include +#pragma clang diagnostic pop + +#define VMA_STATIC_VULKAN_FUNCTIONS 0 +#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_compute_pipeline.cpp new file mode 100644 index 0000000..5addcb0 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -0,0 +1,119 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "shader_recompiler/info.h" +#include "video_core/renderer_vulkan/vk_compute_pipeline.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" + +namespace Vulkan { + +ComputePipeline::ComputePipeline(const Instance& instance, Scheduler& scheduler, + DescriptorHeap& desc_heap, const Shader::Profile& profile, + vk::PipelineCache pipeline_cache, ComputePipelineKey compute_key_, + const Shader::Info& info_, vk::ShaderModule module, + SerializationSupport& sdata, bool preloading /*=false*/) + : Pipeline{instance, scheduler, desc_heap, profile, pipeline_cache, true}, + compute_key{compute_key_} { + auto& info = stages[int(Shader::SwStage::Compute)]; + info = &info_; + const auto debug_str = GetDebugString(); + + const vk::PipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_size_ci = { + .requiredSubgroupSize = 64, + }; + const vk::PipelineShaderStageCreateInfo shader_ci = { + .pNext = instance.IsSubgroupSize64Supported() ? &subgroup_size_ci : nullptr, + .stage = vk::ShaderStageFlagBits::eCompute, + .module = module, + .pName = "main", + }; + + u32 binding{}; + boost::container::small_vector bindings; + for (const auto& buffer : info->buffers) { + // During deserialization, we don't have access to the UD to fetch sharp data. To address + // this properly we need to track shaprs or portion of them in `sdata`, but since we're + // interested only in "is storage" flag (which is not even effective atm), we can take a + // shortcut there. + const auto sharp = preloading ? AmdGpu::Buffer{} : buffer.GetSharp(*info); + bindings.push_back({ + .binding = binding++, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }); + } + for (const auto& image : info->images) { + const u32 num_bindings = image.NumBindings(*info); + bindings.push_back({ + .binding = binding, + .descriptorType = image.is_written ? vk::DescriptorType::eStorageImage + : vk::DescriptorType::eSampledImage, + .descriptorCount = num_bindings, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }); + binding += num_bindings; + } + for (const auto& sampler : info->samplers) { + bindings.push_back({ + .binding = binding++, + .descriptorType = vk::DescriptorType::eSampler, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }); + } + + const vk::PushConstantRange push_constants = { + .stageFlags = vk::ShaderStageFlagBits::eCompute, + .offset = 0, + .size = sizeof(Shader::PushData), + }; + + uses_push_descriptors = binding < instance.MaxPushDescriptors(); + const auto flags = uses_push_descriptors + ? vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR + : vk::DescriptorSetLayoutCreateFlagBits{}; + const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = { + .flags = flags, + .bindingCount = static_cast(bindings.size()), + .pBindings = bindings.data(), + }; + const auto device = instance.GetDevice(); + auto [descriptor_set_result, descriptor_set] = + device.createDescriptorSetLayoutUnique(desc_layout_ci); + ASSERT_MSG(descriptor_set_result == vk::Result::eSuccess, + "Failed to create compute descriptor set layout: {}", + vk::to_string(descriptor_set_result)); + desc_layout = std::move(descriptor_set); + + const vk::DescriptorSetLayout set_layout = *desc_layout; + const vk::PipelineLayoutCreateInfo layout_info = { + .setLayoutCount = 1U, + .pSetLayouts = &set_layout, + .pushConstantRangeCount = 1U, + .pPushConstantRanges = &push_constants, + }; + auto [layout_result, layout] = instance.GetDevice().createPipelineLayoutUnique(layout_info); + ASSERT_MSG(layout_result == vk::Result::eSuccess, + "Failed to create compute pipeline layout: {}", vk::to_string(layout_result)); + pipeline_layout = std::move(layout); + SetObjectName(device, *pipeline_layout, "Compute PipelineLayout {}", debug_str); + + const vk::ComputePipelineCreateInfo compute_pipeline_ci = { + .stage = shader_ci, + .layout = *pipeline_layout, + }; + auto [pipeline_result, pipe] = + instance.GetDevice().createComputePipelineUnique(pipeline_cache, compute_pipeline_ci); + ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create compute pipeline: {}", + vk::to_string(pipeline_result)); + pipeline = std::move(pipe); + SetObjectName(device, *pipeline, "Compute Pipeline {}", debug_str); +} + +ComputePipeline::~ComputePipeline() = default; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_compute_pipeline.h b/gpu/shadps4/video_core/renderer_vulkan/vk_compute_pipeline.h new file mode 100644 index 0000000..1cac720 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_compute_pipeline.h @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "video_core/renderer_vulkan/vk_common.h" +#include "video_core/renderer_vulkan/vk_pipeline_common.h" + +namespace VideoCore { +class BufferCache; +class TextureCache; +} // namespace VideoCore + +namespace Serialization { +struct Archive; +} + +namespace Vulkan { + +class Instance; +class Scheduler; +class DescriptorHeap; + +struct ComputePipelineKey { + size_t value; + + friend bool operator==(const ComputePipelineKey& lhs, const ComputePipelineKey& rhs) { + return lhs.value == rhs.value; + } + friend bool operator!=(const ComputePipelineKey& lhs, const ComputePipelineKey& rhs) { + return !(lhs == rhs); + } + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& ar); +}; + +class ComputePipeline : public Pipeline { +public: + struct SerializationSupport { + u32 dummy{}; + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& ar); + }; + + ComputePipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap, + const Shader::Profile& profile, vk::PipelineCache pipeline_cache, + ComputePipelineKey compute_key, const Shader::Info& info, + vk::ShaderModule module, SerializationSupport& sdata, bool preloading); + ~ComputePipeline(); + +private: + ComputePipelineKey compute_key; +}; + +} // namespace Vulkan + +template <> +struct std::hash { + std::size_t operator()(const Vulkan::ComputePipelineKey& key) const noexcept { + return std::hash{}(key.value); + } +}; diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_graphics_pipeline.cpp new file mode 100644 index 0000000..afcb597 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -0,0 +1,541 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include + +#include "common/assert.h" +#include "shader_recompiler/backend/spirv/emit_spirv_discard_frag.h" +#include "shader_recompiler/backend/spirv/emit_spirv_quad_rect.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_graphics_pipeline.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +namespace Vulkan { + +using Shader::Backend::SPIRV::AuxShaderType; + +static constexpr std::array LogicalStageToStageBit = { + vk::ShaderStageFlagBits::eFragment, + vk::ShaderStageFlagBits::eTessellationControl, + vk::ShaderStageFlagBits::eTessellationEvaluation, + vk::ShaderStageFlagBits::eVertex, + vk::ShaderStageFlagBits::eGeometry, + vk::ShaderStageFlagBits::eCompute, +}; + +GraphicsPipeline::GraphicsPipeline( + const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap, + const Shader::Profile& profile, const GraphicsPipelineKey& key_, + vk::PipelineCache pipeline_cache, std::span infos, + std::span runtime_infos, + std::optional fetch_shader_, + std::span modules, SerializationSupport& sdata, bool preloading) + : Pipeline{instance, scheduler, desc_heap, profile, pipeline_cache}, key{key_}, + fetch_shader{std::move(fetch_shader_)} { + const vk::Device device = instance.GetDevice(); + std::ranges::copy(infos, stages.begin()); + BuildDescSetLayout(preloading); + const auto debug_str = GetDebugString(); + + const vk::PushConstantRange push_constants = { + .stageFlags = AllGraphicsStageBits, + .offset = 0, + .size = sizeof(Shader::PushData), + }; + + const vk::DescriptorSetLayout set_layout = *desc_layout; + const vk::PipelineLayoutCreateInfo layout_info = { + .setLayoutCount = 1U, + .pSetLayouts = &set_layout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_constants, + }; + auto [layout_result, layout] = instance.GetDevice().createPipelineLayoutUnique(layout_info); + ASSERT_MSG(layout_result == vk::Result::eSuccess, + "Failed to create graphics pipeline layout: {}", vk::to_string(layout_result)); + pipeline_layout = std::move(layout); + SetObjectName(device, *pipeline_layout, "Graphics PipelineLayout {}", debug_str); + + if (!preloading) { + VertexInputs guest_buffers; + if (!instance.IsVertexInputDynamicState()) { + const auto& vs_info = runtime_infos[u32(Shader::SwStage::Vertex)].sw.vs; + GetVertexInputs(sdata.vertex_attributes, sdata.vertex_bindings, sdata.divisors, + guest_buffers, vs_info.step_rate_0, vs_info.step_rate_1); + } + } + + const vk::PipelineVertexInputDivisorStateCreateInfo divisor_state = { + .vertexBindingDivisorCount = static_cast(sdata.divisors.size()), + .pVertexBindingDivisors = sdata.divisors.data(), + }; + + const vk::PipelineVertexInputStateCreateInfo vertex_input_info = { + .pNext = sdata.divisors.empty() ? nullptr : &divisor_state, + .vertexBindingDescriptionCount = static_cast(sdata.vertex_bindings.size()), + .pVertexBindingDescriptions = sdata.vertex_bindings.data(), + .vertexAttributeDescriptionCount = static_cast(sdata.vertex_attributes.size()), + .pVertexAttributeDescriptions = sdata.vertex_attributes.data(), + }; + + const auto topology = LiverpoolToVK::PrimitiveType(key.prim_type); + const vk::PipelineInputAssemblyStateCreateInfo input_assembly = { + .topology = topology, + }; + + const bool is_rect_list = key.prim_type == AmdGpu::PrimitiveType::RectList; + const bool is_quad_list = key.prim_type == AmdGpu::PrimitiveType::QuadList; + const vk::PipelineTessellationStateCreateInfo tessellation_state = { + .patchControlPoints = is_rect_list ? 3U : (is_quad_list ? 4U : key.patch_control_points), + }; + + vk::StructureChain raster_chain = { + vk::PipelineRasterizationStateCreateInfo{ + .depthClampEnable = key.depth_clamp_enable && + (!key.depth_clip_enable || instance.IsDepthClipEnableSupported()), + .rasterizerDiscardEnable = false, + .polygonMode = LiverpoolToVK::PolygonMode(key.polygon_mode), + .lineWidth = 1.0f, + }, + vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT{ + .provokingVertexMode = key.provoking_vtx_last == AmdGpu::ProvokingVtxLast::First + ? vk::ProvokingVertexModeEXT::eFirstVertex + : vk::ProvokingVertexModeEXT::eLastVertex, + }, + vk::PipelineRasterizationDepthClipStateCreateInfoEXT{ + .depthClipEnable = key.depth_clip_enable, + }, + }; + + if (!instance.IsProvokingVertexSupported()) { + raster_chain.unlink(); + } + if (!instance.IsDepthClipEnableSupported()) { + raster_chain.unlink(); + } + + if (!preloading) { + const auto& fs_info = runtime_infos[u32(Shader::SwStage::Fragment)].hw.fs; + sdata.multisampling = { + .rasterizationSamples = LiverpoolToVK::NumSamples( + key.num_samples, instance.GetColorSampleCounts() & instance.GetDepthSampleCounts()), + .sampleShadingEnable = + fs_info.addr_flags.persp_sample_ena || fs_info.addr_flags.linear_sample_ena, + }; + } + + const vk::PipelineViewportDepthClipControlCreateInfoEXT clip_control = { + .negativeOneToOne = key.clip_space == AmdGpu::ClipSpace::MinusWToW, + }; + + const vk::PipelineViewportStateCreateInfo viewport_info = { + .pNext = instance.IsDepthClipControlSupported() ? &clip_control : nullptr, + }; + + boost::container::static_vector dynamic_states = { + vk::DynamicState::eViewportWithCount, vk::DynamicState::eScissorWithCount, + vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnable, + vk::DynamicState::eDepthWriteEnable, vk::DynamicState::eDepthCompareOp, + vk::DynamicState::eDepthBiasEnable, vk::DynamicState::eDepthBias, + vk::DynamicState::eStencilTestEnable, vk::DynamicState::eStencilReference, + vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, + vk::DynamicState::eStencilOp, vk::DynamicState::eCullMode, + vk::DynamicState::eFrontFace, vk::DynamicState::eRasterizerDiscardEnable, + vk::DynamicState::eLineWidth, vk::DynamicState::ePrimitiveRestartEnable, + }; + + if (instance.IsDepthBoundsSupported()) { + dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnable); + dynamic_states.push_back(vk::DynamicState::eDepthBounds); + } + if (instance.IsDynamicColorWriteMaskSupported()) { + dynamic_states.push_back(vk::DynamicState::eColorWriteMaskEXT); + } + if (instance.IsVertexInputDynamicState()) { + dynamic_states.push_back(vk::DynamicState::eVertexInputEXT); + } else if (!sdata.vertex_bindings.empty()) { + dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStride); + } + + const vk::PipelineDynamicStateCreateInfo dynamic_info = { + .dynamicStateCount = static_cast(dynamic_states.size()), + .pDynamicStates = dynamic_states.data(), + }; + + boost::container::static_vector + shader_stages; + auto stage = u32(Shader::SwStage::Vertex); + if (infos[stage]) { + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eVertex, + .module = modules[stage], + .pName = "main", + }); + } + stage = u32(Shader::SwStage::Geometry); + if (infos[stage]) { + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eGeometry, + .module = modules[stage], + .pName = "main", + }); + } + stage = u32(Shader::SwStage::TessellationControl); + if (infos[stage]) { + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eTessellationControl, + .module = modules[stage], + .pName = "main", + }); + } else if (is_rect_list || is_quad_list) { + const auto type = is_quad_list ? AuxShaderType::QuadListTCS : AuxShaderType::RectListTCS; + if (!preloading) { + const auto& fs_info = runtime_infos[u32(Shader::SwStage::Fragment)].hw.fs; + sdata.tcs = Shader::Backend::SPIRV::EmitAuxilaryTessShader(type, fs_info); + } + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eTessellationControl, + .module = CompileSPV(sdata.tcs, instance.GetDevice()), + .pName = "main", + }); + } + stage = u32(Shader::SwStage::TessellationEval); + if (infos[stage]) { + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eTessellationEvaluation, + .module = modules[stage], + .pName = "main", + }); + } else if (is_rect_list || is_quad_list) { + if (!preloading) { + const auto& fs_info = runtime_infos[u32(Shader::SwStage::Fragment)].hw.fs; + sdata.tes = Shader::Backend::SPIRV::EmitAuxilaryTessShader( + AuxShaderType::PassthroughTES, fs_info); + } + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eTessellationEvaluation, + .module = CompileSPV(sdata.tes, instance.GetDevice()), + .pName = "main", + }); + } + stage = u32(Shader::SwStage::Fragment); + if (infos[stage]) { + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eFragment, + .module = modules[stage], + .pName = "main", + }); + } else if (runtime_infos[u32(Shader::SwStage::Fragment)].hw.fs.clip_distance_emulation) { + if (!preloading) { + const auto& vs = runtime_infos[static_cast(Shader::SwStage::Vertex)].hw.vs; + + sdata.fragment = Shader::Backend::SPIRV::EmitDiscardFragmentShader(vs.outputs); + } + shader_stages.emplace_back(vk::PipelineShaderStageCreateInfo{ + .stage = vk::ShaderStageFlagBits::eFragment, + .module = CompileSPV(sdata.fragment, instance.GetDevice()), + .pName = "main", + }); + } + + const vk::PipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_size_ci = { + .requiredSubgroupSize = 64, + }; + for (auto& stage : shader_stages) { + stage.pNext = instance.IsSubgroupSize64Supported() ? &subgroup_size_ci : nullptr; + } + + const auto depth_format = + instance.GetSupportedFormat(LiverpoolToVK::DepthFormat(key.z_format, key.stencil_format), + vk::FormatFeatureFlagBits2::eDepthStencilAttachment); + std::array color_formats; + for (s32 i = 0; i < key.num_color_attachments; ++i) { + const auto& col_buf = key.color_buffers[i]; + const auto format = LiverpoolToVK::SurfaceFormat(col_buf.data_format, col_buf.num_format); + const auto color_format = + instance.GetSupportedFormat(format, vk::FormatFeatureFlagBits2::eColorAttachment); + if (!instance.IsFormatSupported(color_format, + vk::FormatFeatureFlagBits2::eColorAttachment)) { + LOG_WARNING(Render_Vulkan, + "color buffer format {} does not support COLOR_ATTACHMENT_BIT", + vk::to_string(color_format)); + } + color_formats[i] = color_format; + } + + std::array color_samples; + std::ranges::transform(key.color_samples, color_samples.begin(), [&instance](u8 num_samples) { + return num_samples ? LiverpoolToVK::NumSamples(num_samples, instance.GetColorSampleCounts()) + : vk::SampleCountFlagBits::e1; + }); + const vk::AttachmentSampleCountInfoAMD mixed_samples = { + .colorAttachmentCount = key.num_color_attachments, + .pColorAttachmentSamples = color_samples.data(), + .depthStencilAttachmentSamples = + LiverpoolToVK::NumSamples(key.depth_samples, instance.GetDepthSampleCounts()), + }; + + const vk::PipelineRenderingCreateInfo pipeline_rendering_ci = { + .pNext = instance.IsMixedDepthSamplesSupported() ? &mixed_samples : nullptr, + .colorAttachmentCount = key.num_color_attachments, + .pColorAttachmentFormats = color_formats.data(), + .depthAttachmentFormat = key.z_format != AmdGpu::DepthBuffer::ZFormat::Invalid + ? depth_format + : vk::Format::eUndefined, + .stencilAttachmentFormat = key.stencil_format != AmdGpu::DepthBuffer::StencilFormat::Invalid + ? depth_format + : vk::Format::eUndefined, + }; + + std::array attachments; + for (u32 i = 0; i < key.num_color_attachments; i++) { + const auto& control = key.blend_controls[i]; + + const auto src_color = LiverpoolToVK::BlendFactor(control.color_src_factor); + const auto dst_color = LiverpoolToVK::BlendFactor(control.color_dst_factor); + const auto color_blend = LiverpoolToVK::BlendOp(control.color_func); + + const auto src_alpha = control.separate_alpha_blend + ? LiverpoolToVK::BlendFactor(control.alpha_src_factor) + : src_color; + const auto dst_alpha = control.separate_alpha_blend + ? LiverpoolToVK::BlendFactor(control.alpha_dst_factor) + : dst_color; + const auto alpha_blend = + control.separate_alpha_blend ? LiverpoolToVK::BlendOp(control.alpha_func) : color_blend; + + // Vulkan ignores blend factors for min/max, but a factor that zeroes one operand + // makes the operation collapse to a plain selection: min(s, 0) is 0 and max(s, 0) + // is s for normalized alpha. Rewrite those to the equivalent add so the result is + // exact instead of leaving the other operand to survive. + auto eff_src_alpha = src_alpha; + auto eff_dst_alpha = dst_alpha; + auto eff_alpha_blend = alpha_blend; + if (alpha_blend == vk::BlendOp::eMin || alpha_blend == vk::BlendOp::eMax) { + const bool takes_max = alpha_blend == vk::BlendOp::eMax; + if (src_alpha == vk::BlendFactor::eOne && dst_alpha == vk::BlendFactor::eZero) { + eff_alpha_blend = vk::BlendOp::eAdd; + eff_src_alpha = takes_max ? vk::BlendFactor::eOne : vk::BlendFactor::eZero; + eff_dst_alpha = vk::BlendFactor::eZero; + } else if (src_alpha == vk::BlendFactor::eZero && dst_alpha == vk::BlendFactor::eOne) { + eff_alpha_blend = vk::BlendOp::eAdd; + eff_src_alpha = vk::BlendFactor::eZero; + eff_dst_alpha = takes_max ? vk::BlendFactor::eOne : vk::BlendFactor::eZero; + } + } + + const auto color_scaled_min_max = + (color_blend == vk::BlendOp::eMin || color_blend == vk::BlendOp::eMax) && + (src_color != vk::BlendFactor::eOne || dst_color != vk::BlendFactor::eOne) && + !key.color_buffers[i].blend_self_scale; + const auto alpha_scaled_min_max = + (eff_alpha_blend == vk::BlendOp::eMin || eff_alpha_blend == vk::BlendOp::eMax) && + (eff_src_alpha != vk::BlendFactor::eOne || eff_dst_alpha != vk::BlendFactor::eOne); + if (color_scaled_min_max || alpha_scaled_min_max) { + LOG_WARNING( + Render_Vulkan, + "Unimplemented use of min/max blend op with blend factor not equal to one."); + } + + attachments[i] = vk::PipelineColorBlendAttachmentState{ + .blendEnable = control.enable, + .srcColorBlendFactor = src_color, + .dstColorBlendFactor = dst_color, + .colorBlendOp = color_blend, + .srcAlphaBlendFactor = eff_src_alpha, + .dstAlphaBlendFactor = eff_dst_alpha, + .alphaBlendOp = eff_alpha_blend, + .colorWriteMask = + instance.IsDynamicColorWriteMaskSupported() + ? vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA + : key.write_masks[i], + }; + + // The shader squares its color output for this attachment (see PsColorBuffer), so the + // factors must not scale the operands again. + if (key.color_buffers[i].blend_self_scale) { + LOG_WARNING( + Render_Vulkan, + "Emulating scaled min/max blend with squared shader output on attachment {}", i); + attachments[i].srcColorBlendFactor = vk::BlendFactor::eOne; + attachments[i].dstColorBlendFactor = vk::BlendFactor::eOne; + } + + // On GCN GPU there is an additional mask which allows to control color components exported + // from a pixel shader. A situation possible, when the game may mask out the alpha channel, + // while it is still need to be used in blending ops. For such cases, HW will default alpha + // to 1 and perform the blending, while shader normally outputs 0 in the last component. + // Unfortunatelly, Vulkan doesn't provide any control on blend inputs, so below we detecting + // such cases and override alpha value in order to emulate HW behaviour. + const auto has_alpha_masked_out = + (key.cb_shader_mask.GetMask(i) & AmdGpu::ColorBufferMask::ComponentA) == 0; + const auto has_src_alpha_in_src_blend = src_color == vk::BlendFactor::eSrcAlpha || + src_color == vk::BlendFactor::eOneMinusSrcAlpha; + const auto has_src_alpha_in_dst_blend = dst_color == vk::BlendFactor::eSrcAlpha || + dst_color == vk::BlendFactor::eOneMinusSrcAlpha; + if (has_alpha_masked_out && has_src_alpha_in_src_blend) { + attachments[i].srcColorBlendFactor = src_color == vk::BlendFactor::eSrcAlpha + ? vk::BlendFactor::eOne + : vk::BlendFactor::eZero; // 1-A + } + if (has_alpha_masked_out && has_src_alpha_in_dst_blend) { + attachments[i].dstColorBlendFactor = dst_color == vk::BlendFactor::eSrcAlpha + ? vk::BlendFactor::eOne + : vk::BlendFactor::eZero; // 1-A + } + } + + const vk::PipelineColorBlendStateCreateInfo color_blending = { + .logicOpEnable = + instance.IsLogicOpSupported() && key.logic_op != AmdGpu::ColorControl::LogicOp::Copy, + .logicOp = LiverpoolToVK::LogicOp(key.logic_op), + .attachmentCount = key.num_color_attachments, + .pAttachments = attachments.data(), + .blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f}, + }; + + // Required by spec unless VK_EXT_extended_dynamic_state3 is supported. + // In practice, we use dynamic state for all of it. + constexpr vk::PipelineDepthStencilStateCreateInfo depth_stencil_info = {}; + + const vk::GraphicsPipelineCreateInfo pipeline_info = { + .pNext = &pipeline_rendering_ci, + .stageCount = static_cast(shader_stages.size()), + .pStages = shader_stages.data(), + .pVertexInputState = !instance.IsVertexInputDynamicState() ? &vertex_input_info : nullptr, + .pInputAssemblyState = &input_assembly, + .pTessellationState = &tessellation_state, + .pViewportState = &viewport_info, + .pRasterizationState = &raster_chain.get(), + .pMultisampleState = &sdata.multisampling, + .pDepthStencilState = + !instance.IsExtendedDynamicState3Supported() ? &depth_stencil_info : nullptr, + .pColorBlendState = &color_blending, + .pDynamicState = &dynamic_info, + .layout = *pipeline_layout, + }; + + auto [pipeline_result, pipe] = + device.createGraphicsPipelineUnique(pipeline_cache, pipeline_info); + ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create graphics pipeline: {}", + vk::to_string(pipeline_result)); + pipeline = std::move(pipe); + SetObjectName(device, *pipeline, "Graphics Pipeline {}", debug_str); +} + +GraphicsPipeline::~GraphicsPipeline() = default; + +template +void GraphicsPipeline::GetVertexInputs( + VertexInputs& attributes, VertexInputs& bindings, + VertexInputs& divisors, + VertexInputs& guest_buffers, u32 step_rate_0, u32 step_rate_1) const { + using InstanceIdType = Shader::Gcn::VertexAttribute::InstanceIdType; + if (!fetch_shader || fetch_shader->attributes.empty()) { + return; + } + const auto& vs_info = GetStage(Shader::SwStage::Vertex); + for (const auto& attrib : fetch_shader->attributes) { + const auto step_rate = attrib.GetStepRate(); + const auto buffer = attrib.GetSharp(vs_info); + attributes.push_back(Attribute{ + .location = attrib.semantic, + .binding = attrib.semantic, + .format = LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt()), + .offset = 0, + }); + bindings.push_back(Binding{ + .binding = attrib.semantic, + .stride = buffer.GetStride(), + .inputRate = step_rate == InstanceIdType::None ? vk::VertexInputRate::eVertex + : vk::VertexInputRate::eInstance, + }); + const u32 divisor = step_rate == InstanceIdType::OverStepRate0 + ? step_rate_0 + : (step_rate == InstanceIdType::OverStepRate1 ? step_rate_1 : 1); + if constexpr (std::is_same_v) { + bindings.back().divisor = divisor; + } else if (step_rate != InstanceIdType::None) { + divisors.push_back(vk::VertexInputBindingDivisorDescriptionEXT{ + .binding = attrib.semantic, + .divisor = divisor, + }); + } + guest_buffers.emplace_back(buffer); + } +} + +// Declare templated GetVertexInputs for necessary types. +template void GraphicsPipeline::GetVertexInputs( + VertexInputs& attributes, + VertexInputs& bindings, + VertexInputs& divisors, + VertexInputs& guest_buffers, u32 step_rate_0, u32 step_rate_1) const; +template void GraphicsPipeline::GetVertexInputs( + VertexInputs& attributes, + VertexInputs& bindings, + VertexInputs& divisors, + VertexInputs& guest_buffers, u32 step_rate_0, u32 step_rate_1) const; + +void GraphicsPipeline::BuildDescSetLayout(bool preloading) { + boost::container::small_vector bindings; + u32 binding{}; + + for (const auto* stage : stages) { + if (!stage) { + continue; + } + const auto stage_bit = LogicalStageToStageBit[u32(stage->sw_stage)]; + for (const auto& buffer : stage->buffers) { + const auto sharp = + preloading ? AmdGpu::Buffer{} + : buffer.GetSharp(*stage); // See for the comment in compute PL creation + bindings.push_back({ + .binding = binding++, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .descriptorCount = 1, + .stageFlags = stage_bit, + }); + } + for (const auto& image : stage->images) { + const u32 num_bindings = image.NumBindings(*stage); + bindings.push_back({ + .binding = binding, + .descriptorType = image.is_written ? vk::DescriptorType::eStorageImage + : vk::DescriptorType::eSampledImage, + .descriptorCount = num_bindings, + .stageFlags = stage_bit, + }); + binding += num_bindings; + } + for (const auto& sampler : stage->samplers) { + bindings.push_back({ + .binding = binding++, + .descriptorType = vk::DescriptorType::eSampler, + .descriptorCount = 1, + .stageFlags = stage_bit, + }); + } + } + uses_push_descriptors = binding < instance.MaxPushDescriptors(); + const auto flags = uses_push_descriptors + ? vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR + : vk::DescriptorSetLayoutCreateFlagBits{}; + const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = { + .flags = flags, + .bindingCount = static_cast(bindings.size()), + .pBindings = bindings.data(), + }; + auto [layout_result, layout] = + instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci); + ASSERT_MSG(layout_result == vk::Result::eSuccess, + "Failed to create graphics descriptor set layout: {}", vk::to_string(layout_result)); + desc_layout = std::move(layout); +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_graphics_pipeline.h b/gpu/shadps4/video_core/renderer_vulkan/vk_graphics_pipeline.h new file mode 100644 index 0000000..2f33789 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -0,0 +1,141 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "shader_recompiler/frontend/fetch_shader.h" +#include "video_core/amdgpu/regs_color.h" +#include "video_core/amdgpu/regs_depth.h" +#include "video_core/amdgpu/regs_primitive.h" +#include "video_core/renderer_vulkan/vk_pipeline_common.h" + +namespace VideoCore { +class BufferCache; +class TextureCache; +} // namespace VideoCore + +namespace Vulkan { + +static constexpr u32 MaxShaderStages = static_cast(Shader::SwStage::NumLogicalStages); +static constexpr u32 MaxVertexBufferCount = 32; + +class Instance; +class Scheduler; +class DescriptorHeap; + +template +using VertexInputs = boost::container::static_vector; + +struct GraphicsPipelineKey { + std::array stage_hashes; + std::array vertex_buffer_formats; + u32 patch_control_points; + u32 num_color_attachments; + std::array color_buffers; + std::array blend_controls; + std::array write_masks; + AmdGpu::ColorBufferMask cb_shader_mask; + AmdGpu::ColorControl::LogicOp logic_op; + u8 num_samples; + u8 depth_samples; + std::array color_samples; + u32 mrt_mask; + struct { + AmdGpu::DepthBuffer::ZFormat z_format : 2; + AmdGpu::DepthBuffer::StencilFormat stencil_format : 1; + u32 depth_clamp_enable : 1; + }; + struct { + AmdGpu::PrimitiveType prim_type : 5; + AmdGpu::PolygonMode polygon_mode : 2; + AmdGpu::ClipSpace clip_space : 1; + AmdGpu::ProvokingVtxLast provoking_vtx_last : 1; + u32 depth_clip_enable : 1; + }; + + GraphicsPipelineKey() { + std::memset(this, 0, sizeof(*this)); + } + + bool operator==(const GraphicsPipelineKey& key) const noexcept { + return std::memcmp(this, &key, sizeof(key)) == 0; + } + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& ar); +}; + +class GraphicsPipeline : public Pipeline { +public: + struct SerializationSupport { + VertexInputs vertex_attributes{}; + VertexInputs vertex_bindings{}; + VertexInputs divisors{}; + vk::PipelineMultisampleStateCreateInfo multisampling{}; + std::vector tcs{}; + std::vector tes{}; + std::vector fragment{}; + + void Serialize(Serialization::Archive& ar) const; + bool Deserialize(Serialization::Archive& ar); + }; + + GraphicsPipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap, + const Shader::Profile& profile, const GraphicsPipelineKey& key, + vk::PipelineCache pipeline_cache, + std::span stages, + std::span runtime_infos, + std::optional fetch_shader, + std::span modules, SerializationSupport& sdata, + bool preloading); + ~GraphicsPipeline(); + + const std::optional& GetFetchShader() const noexcept { + return fetch_shader; + } + + const GraphicsPipelineKey& GetGraphicsKey() const { + return key; + } + + /// Gets the attributes and bindings for vertex inputs. + template + void GetVertexInputs(VertexInputs& attributes, VertexInputs& bindings, + VertexInputs& divisors, + VertexInputs& guest_buffers, u32 step_rate_0, + u32 step_rate_1) const; + +private: + void BuildDescSetLayout(bool preloading); + +private: + GraphicsPipelineKey key; + std::optional fetch_shader{}; +}; + +struct ClipDistanceShaderKey { + std::array, 8> clip_locations; + + bool operator==(const ClipDistanceShaderKey& key) const noexcept { + return std::memcmp(this, &key, sizeof(key)) == 0; + } +}; + +} // namespace Vulkan + +template <> +struct std::hash { + std::size_t operator()(const Vulkan::GraphicsPipelineKey& key) const noexcept { + return XXH3_64bits(&key, sizeof(key)); + } +}; + +template <> +struct std::hash { + std::size_t operator()(const Vulkan::ClipDistanceShaderKey& key) const noexcept { + return XXH3_64bits(&key, sizeof(key)); + } +}; diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_instance.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_instance.cpp new file mode 100644 index 0000000..3b5467c --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_instance.cpp @@ -0,0 +1,831 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include + +#include "common/assert.h" +#include "common/debug.h" +#include "common/types.h" +#include "imgui/renderer/imgui_core.h" +#include "sdl_window.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_platform.h" + +#include + +namespace Vulkan { + +namespace { + +std::vector EnumeratePhysicalDevices(vk::UniqueInstance& instance) { + auto [devices_result, devices] = instance->enumeratePhysicalDevices(); + ASSERT_MSG(devices_result == vk::Result::eSuccess, "Failed to enumerate physical devices: {}", + vk::to_string(devices_result)); + return std::move(devices); +} + +std::vector GetSupportedExtensions(vk::PhysicalDevice physical) { + const auto [extensions_result, extensions] = physical.enumerateDeviceExtensionProperties(); + if (extensions_result != vk::Result::eSuccess) { + LOG_ERROR(Render_Vulkan, "Could not query supported extensions: {}", + vk::to_string(extensions_result)); + return {}; + } + std::vector supported_extensions; + supported_extensions.reserve(extensions.size()); + for (const auto& extension : extensions) { + supported_extensions.emplace_back(extension.extensionName.data()); + } + return supported_extensions; +} + +vk::FormatProperties3 GetFormatProperties(vk::PhysicalDevice physical, vk::Format format) { + vk::FormatProperties3 properties3{}; + vk::FormatProperties2 properties2 = { + .pNext = &properties3, + }; + physical.getFormatProperties2(format, &properties2); + return properties3; +} + +std::unordered_map GetFormatProperties( + vk::PhysicalDevice physical) { + std::unordered_map format_properties; + for (const auto& format_info : LiverpoolToVK::SurfaceFormats()) { + const auto format = format_info.vk_format; + if (!format_properties.contains(format)) { + format_properties.emplace(format, GetFormatProperties(physical, format)); + } + } + for (const auto& format_info : LiverpoolToVK::DepthFormats()) { + const auto format = format_info.vk_format; + if (!format_properties.contains(format)) { + format_properties.emplace(format, GetFormatProperties(physical, format)); + } + } + // Other miscellaneous formats, e.g. for color buffers, swizzles, or compatibility + static constexpr std::array misc_formats = { + vk::Format::eA2R10G10B10UnormPack32, + vk::Format::eB8G8R8A8Unorm, + vk::Format::eB8G8R8A8Srgb, + vk::Format::eD24UnormS8Uint, + }; + for (const auto& format : misc_formats) { + if (!format_properties.contains(format)) { + format_properties.emplace(format, GetFormatProperties(physical, format)); + } + } + return format_properties; +} + +std::string GetReadableVersion(u32 version) { + return fmt::format("{}.{}.{}", VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version), + VK_VERSION_PATCH(version)); +} + +} // Anonymous namespace + +Instance::Instance(bool enable_validation, bool enable_crash_diagnostic) + : instance{CreateInstance(Frontend::WindowSystemType::Headless, enable_validation, + enable_crash_diagnostic)}, + physical_devices{EnumeratePhysicalDevices(instance)} {} + +Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index, + bool enable_validation /*= false*/, bool enable_crash_diagnostic /*= false*/) + : instance{CreateInstance(window.GetWindowInfo().type, enable_validation, + enable_crash_diagnostic)}, + physical_devices{EnumeratePhysicalDevices(instance)} { + if (enable_validation) { + debug_callback = CreateDebugCallback(*instance); + } + const std::size_t num_physical_devices = static_cast(physical_devices.size()); + ASSERT_MSG(num_physical_devices > 0, "No physical devices found"); + LOG_INFO(Render_Vulkan, "Found {} physical devices", num_physical_devices); + + if (physical_device_index < 0) { + std::vector< + std::tuple> + properties2{}; + for (auto const& physical : physical_devices) { + properties2.emplace_back(properties2.size(), physical.getProperties2(), + physical.getMemoryProperties()); + } + std::sort(properties2.begin(), properties2.end(), [](const auto& left, const auto& right) { + const vk::PhysicalDeviceProperties& left_prop = std::get<1>(left).properties; + const vk::PhysicalDeviceProperties& right_prop = std::get<1>(right).properties; + const bool left_supports_api = left_prop.apiVersion >= TargetVulkanApiVersion; + const bool right_supports_api = right_prop.apiVersion >= TargetVulkanApiVersion; + if (left_supports_api != right_supports_api) { + return left_supports_api; + } + + const bool left_is_discrete = + left_prop.deviceType == vk::PhysicalDeviceType::eDiscreteGpu; + const bool right_is_discrete = + right_prop.deviceType == vk::PhysicalDeviceType::eDiscreteGpu; + if (left_is_discrete != right_is_discrete) { + return left_is_discrete; + } + + // Software renderers advertise system memory as device local, so they + // would win the memory comparison below against real hardware. + const bool left_is_cpu = left_prop.deviceType == vk::PhysicalDeviceType::eCpu; + const bool right_is_cpu = right_prop.deviceType == vk::PhysicalDeviceType::eCpu; + if (left_is_cpu != right_is_cpu) { + return right_is_cpu; + } + + constexpr auto get_mem = [](const vk::PhysicalDeviceMemoryProperties& mem) -> size_t { + size_t max = 0; + for (u32 i = 0; i < mem.memoryHeapCount; i++) { + const vk::MemoryHeap& heap = mem.memoryHeaps[i]; + if (heap.flags & vk::MemoryHeapFlagBits::eDeviceLocal && heap.size > max) { + max = heap.size; + } + } + return max; + }; + size_t left_mem_size = get_mem(std::get<2>(left)); + size_t right_mem_size = get_mem(std::get<2>(right)); + return left_mem_size > right_mem_size; + }); + physical_device = physical_devices[std::get<0>(properties2[0])]; + } else { + ASSERT_MSG(physical_device_index < num_physical_devices, + "Invalid physical device index {} provided when only {} devices exist", + physical_device_index, num_physical_devices); + + physical_device = physical_devices[physical_device_index]; + } + + available_extensions = GetSupportedExtensions(physical_device); + format_properties = GetFormatProperties(physical_device); + properties = physical_device.getProperties(); + memory_properties = physical_device.getMemoryProperties(); + CollectDeviceParameters(); + ASSERT_MSG(properties.apiVersion >= TargetVulkanApiVersion, + "Vulkan {}.{} is required, but only {}.{} is supported by device!", + VK_VERSION_MAJOR(TargetVulkanApiVersion), VK_VERSION_MINOR(TargetVulkanApiVersion), + VK_VERSION_MAJOR(properties.apiVersion), VK_VERSION_MINOR(properties.apiVersion)); + + CreateDevice(); + CollectPhysicalMemoryInfo(); + CollectImageFormatInfo(); + CollectToolingInfo(); +} + +Instance::~Instance() { + ImGui::Core::Shutdown(GetDevice()); + vmaDestroyAllocator(allocator); +} + +std::string Instance::GetDriverVersionName() { + // Extracted from + // https://github.com/SaschaWillems/vulkan.gpuinfo.org/blob/5dddea46ea1120b0df14eef8f15ff8e318e35462/functions.php#L308-L314 + const u32 version = properties.driverVersion; + if (driver_id == vk::DriverId::eNvidiaProprietary) { + const u32 major = (version >> 22) & 0x3ff; + const u32 minor = (version >> 14) & 0x0ff; + const u32 secondary = (version >> 6) & 0x0ff; + const u32 tertiary = version & 0x003f; + return fmt::format("{}.{}.{}.{}", major, minor, secondary, tertiary); + } + if (driver_id == vk::DriverId::eIntelProprietaryWindows) { + const u32 major = version >> 14; + const u32 minor = version & 0x3fff; + return fmt::format("{}.{}", major, minor); + } + return GetReadableVersion(version); +} + +bool Instance::CreateDevice() { + const vk::StructureChain feature_chain = physical_device.getFeatures2< + vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, + vk::PhysicalDeviceVulkan12Features, vk::PhysicalDeviceVulkan13Features, + vk::PhysicalDeviceRobustness2FeaturesEXT, + vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT, + vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, + vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT, + vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, + vk::PhysicalDeviceImage2DViewOf3DFeaturesEXT, vk::PhysicalDeviceShaderClockFeaturesKHR>(); + features = feature_chain.get().features; + + const vk::StructureChain properties_chain = physical_device.getProperties2< + vk::PhysicalDeviceProperties2, vk::PhysicalDeviceVulkan11Properties, + vk::PhysicalDeviceVulkan12Properties, vk::PhysicalDeviceVulkan13Properties, + vk::PhysicalDevicePushDescriptorPropertiesKHR>(); + vk11_props = properties_chain.get(); + vk12_props = properties_chain.get(); + vk13_props = properties_chain.get(); + push_descriptor_props = properties_chain.get(); + LOG_INFO(Render_Vulkan, "Physical device subgroup size {}", vk11_props.subgroupSize); + + if (available_extensions.empty()) { + LOG_CRITICAL(Render_Vulkan, "No extensions supported by device."); + return false; + } + + boost::container::static_vector enabled_extensions; + const auto add_extension = [&](std::string_view extension) -> bool { + const auto result = + std::find_if(available_extensions.begin(), available_extensions.end(), + [&](const std::string& name) { return name == extension; }); + + if (result != available_extensions.end()) { + LOG_INFO(Render_Vulkan, "Enabling extension: {}", extension); + enabled_extensions.push_back(extension.data()); + return true; + } + + LOG_WARNING(Render_Vulkan, "Extension {} unavailable.", extension); + return false; + }; + + // Required + ASSERT_MSG(add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME), + "Required Vulkan extension unavailable: {}", VK_KHR_SWAPCHAIN_EXTENSION_NAME); + ASSERT_MSG(add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME), + "Required Vulkan extension unavailable: {}", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + ASSERT_MSG(add_extension(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME), + "Required Vulkan extension unavailable: {}", + VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME); + ASSERT_MSG(add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME), + "Required Vulkan extension unavailable: {}", VK_EXT_ROBUSTNESS_2_EXTENSION_NAME); + + const auto robustness2_features = feature_chain.get(); + ASSERT_MSG(robustness2_features.robustBufferAccess2, + "Required Vulkan feature unavailable: robustBufferAccess2"); + ASSERT_MSG(robustness2_features.robustImageAccess2, + "Required Vulkan feature unavailable: robustImageAccess2"); + ASSERT_MSG(robustness2_features.nullDescriptor, + "Required Vulkan feature unavailable: nullDescriptor"); + + // Optional + maintenance_5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); + maintenance_8 = add_extension(VK_KHR_MAINTENANCE_8_EXTENSION_NAME); + attachment_feedback_loop = add_extension(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME); + if (attachment_feedback_loop) { + attachment_feedback_loop = + add_extension(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME); + if (!attachment_feedback_loop) { + // We want both extensions so remove the first if the second isn't available + enabled_extensions.pop_back(); + } + } + depth_range_unrestricted = add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); + dynamic_state_3 = add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + if (dynamic_state_3) { + dynamic_state_3_features = + feature_chain.get(); + LOG_INFO(Render_Vulkan, "- extendedDynamicState3ColorWriteMask: {}", + dynamic_state_3_features.extendedDynamicState3ColorWriteMask); + } + custom_border_color = add_extension(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + depth_clip_control = add_extension(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); + depth_clip_enable = add_extension(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME); + vertex_input_dynamic_state = add_extension(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + list_restart = add_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME); + if (list_restart) { + list_restart_features = + feature_chain.get(); + LOG_INFO(Render_Vulkan, "- primitiveTopologyListRestart: {}", + list_restart_features.primitiveTopologyListRestart); + LOG_INFO(Render_Vulkan, "- primitiveTopologyPatchListRestart: {}", + list_restart_features.primitiveTopologyPatchListRestart); + } + amd_shader_explicit_vertex_parameter = + add_extension(VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME); + if (!amd_shader_explicit_vertex_parameter) { + fragment_shader_barycentric = + add_extension(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME); + } + provoking_vertex = add_extension(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); + shader_stencil_export = add_extension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); + image_load_store_lod = add_extension(VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME); + amd_gcn_shader = add_extension(VK_AMD_GCN_SHADER_EXTENSION_NAME); + amd_shader_trinary_minmax = add_extension(VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME); + nv_framebuffer_mixed_samples = add_extension(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME); + amd_mixed_attachment_samples = add_extension(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); + shader_atomic_float = add_extension(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME); + shader_atomic_float2 = add_extension(VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME); + if (shader_atomic_float2) { + shader_atomic_float2_features = + feature_chain.get(); + LOG_INFO(Render_Vulkan, "- shaderBufferFloat32AtomicMinMax: {}", + shader_atomic_float2_features.shaderBufferFloat32AtomicMinMax); + LOG_INFO(Render_Vulkan, "- shaderImageFloat32AtomicMinMax: {}", + shader_atomic_float2_features.shaderImageFloat32AtomicMinMax); + } + workgroup_memory_explicit_layout = + add_extension(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); + if (workgroup_memory_explicit_layout) { + workgroup_memory_explicit_layout_features = + feature_chain.get(); + LOG_INFO(Render_Vulkan, "- workgroupMemoryExplicitLayout: {}", + workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout); + LOG_INFO(Render_Vulkan, "- workgroupMemoryExplicitLayoutScalarBlockLayout: {}", + workgroup_memory_explicit_layout_features + .workgroupMemoryExplicitLayoutScalarBlockLayout); + LOG_INFO( + Render_Vulkan, "- workgroupMemoryExplicitLayout16BitAccess: {}", + workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout16BitAccess); + } + image_2d_view_of_3d = add_extension(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME); + if (image_2d_view_of_3d) { + image_2d_view_of_3d_features = + feature_chain.get(); + LOG_INFO(Render_Vulkan, "- image2DViewOf3D: {}", + image_2d_view_of_3d_features.image2DViewOf3D); + LOG_INFO(Render_Vulkan, "- sampler2DViewOf3D: {}", + image_2d_view_of_3d_features.sampler2DViewOf3D); + } + image_view_min_lod = add_extension(VK_EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME); + supports_memory_budget = add_extension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME); + shader_clock = add_extension(VK_KHR_SHADER_CLOCK_EXTENSION_NAME); + if (shader_clock) { + shader_clock_features = feature_chain.get(); + LOG_INFO(Render_Vulkan, "- shaderSubgroupClock: {}", + shader_clock_features.shaderSubgroupClock); + } + const bool calibrated_timestamps = + TRACY_GPU_ENABLED ? add_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME) : false; + + const auto family_properties = physical_device.getQueueFamilyProperties(); + if (family_properties.empty()) { + LOG_CRITICAL(Render_Vulkan, "Physical device reported no queues."); + return false; + } + + bool graphics_queue_found = false; + for (std::size_t i = 0; i < family_properties.size(); i++) { + const u32 index = static_cast(i); + if (family_properties[i].queueFlags & vk::QueueFlagBits::eGraphics) { + queue_family_index = index; + graphics_queue_found = true; + } + } + + if (!graphics_queue_found) { + LOG_CRITICAL(Render_Vulkan, "Unable to find graphics and/or present queues."); + return false; + } + + static constexpr std::array queue_priorities = {1.0f}; + const vk::DeviceQueueCreateInfo queue_info = { + .queueFamilyIndex = queue_family_index, + .queueCount = static_cast(queue_priorities.size()), + .pQueuePriorities = queue_priorities.data(), + }; + + const auto vk11_features = feature_chain.get(); + vk12_features = feature_chain.get(); + vk13_features = feature_chain.get(); + vk::StructureChain device_chain = { + vk::DeviceCreateInfo{ + .queueCreateInfoCount = 1u, + .pQueueCreateInfos = &queue_info, + .enabledExtensionCount = static_cast(enabled_extensions.size()), + .ppEnabledExtensionNames = enabled_extensions.data(), + }, + vk::PhysicalDeviceFeatures2{ + .features{ + .robustBufferAccess = features.robustBufferAccess, + .imageCubeArray = features.imageCubeArray, + .independentBlend = features.independentBlend, + .geometryShader = features.geometryShader, + .tessellationShader = features.tessellationShader, + .sampleRateShading = features.sampleRateShading, + .dualSrcBlend = features.dualSrcBlend, + .logicOp = features.logicOp, + .multiDrawIndirect = features.multiDrawIndirect, + .depthClamp = features.depthClamp, + .depthBiasClamp = features.depthBiasClamp, + .fillModeNonSolid = features.fillModeNonSolid, + .depthBounds = features.depthBounds, + .wideLines = features.wideLines, + .multiViewport = features.multiViewport, + .samplerAnisotropy = features.samplerAnisotropy, + .vertexPipelineStoresAndAtomics = features.vertexPipelineStoresAndAtomics, + .fragmentStoresAndAtomics = features.fragmentStoresAndAtomics, + .shaderImageGatherExtended = features.shaderImageGatherExtended, + .shaderStorageImageExtendedFormats = features.shaderStorageImageExtendedFormats, + .shaderStorageImageMultisample = features.shaderStorageImageMultisample, + .shaderClipDistance = features.shaderClipDistance, + .shaderFloat64 = features.shaderFloat64, + .shaderInt64 = features.shaderInt64, + .shaderInt16 = features.shaderInt16, + .sparseBinding = features.sparseBinding, + .sparseResidencyBuffer = features.sparseResidencyBuffer, + }, + }, + vk::PhysicalDeviceVulkan11Features{ + .storageBuffer16BitAccess = vk11_features.storageBuffer16BitAccess, + .shaderDrawParameters = vk11_features.shaderDrawParameters, + }, + vk::PhysicalDeviceVulkan12Features{ + .samplerMirrorClampToEdge = vk12_features.samplerMirrorClampToEdge, + .drawIndirectCount = vk12_features.drawIndirectCount, + .storageBuffer8BitAccess = vk12_features.storageBuffer8BitAccess, + .shaderBufferInt64Atomics = vk12_features.shaderBufferInt64Atomics, + .shaderSharedInt64Atomics = vk12_features.shaderSharedInt64Atomics, + .shaderFloat16 = vk12_features.shaderFloat16, + .shaderInt8 = vk12_features.shaderInt8, + .scalarBlockLayout = vk12_features.scalarBlockLayout, + .uniformBufferStandardLayout = vk12_features.uniformBufferStandardLayout, + .separateDepthStencilLayouts = vk12_features.separateDepthStencilLayouts, + .hostQueryReset = vk12_features.hostQueryReset, + .timelineSemaphore = vk12_features.timelineSemaphore, + .bufferDeviceAddress = vk12_features.bufferDeviceAddress, + .shaderOutputLayer = vk12_features.shaderOutputLayer, + }, + vk::PhysicalDeviceVulkan13Features{ + .robustImageAccess = vk13_features.robustImageAccess, + .shaderDemoteToHelperInvocation = vk13_features.shaderDemoteToHelperInvocation, + .subgroupSizeControl = vk13_features.subgroupSizeControl, + .synchronization2 = vk13_features.synchronization2, + .dynamicRendering = vk13_features.dynamicRendering, + .maintenance4 = vk13_features.maintenance4, + }, + // Extensions + vk::PhysicalDeviceCustomBorderColorFeaturesEXT{ + .customBorderColors = true, + .customBorderColorWithoutFormat = true, + }, + vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT{ + .extendedDynamicState3ColorWriteMask = + dynamic_state_3_features.extendedDynamicState3ColorWriteMask, + }, + vk::PhysicalDeviceDepthClipControlFeaturesEXT{ + .depthClipControl = true, + }, + vk::PhysicalDeviceDepthClipEnableFeaturesEXT{ + .depthClipEnable = true, + }, + vk::PhysicalDeviceRobustness2FeaturesEXT{ + .robustBufferAccess2 = true, + .robustImageAccess2 = true, + .nullDescriptor = true, + }, + vk::PhysicalDeviceVertexInputDynamicStateFeaturesEXT{ + .vertexInputDynamicState = true, + }, + vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT{ + .primitiveTopologyListRestart = list_restart_features.primitiveTopologyListRestart, + .primitiveTopologyPatchListRestart = + list_restart_features.primitiveTopologyPatchListRestart, + }, + vk::PhysicalDeviceFragmentShaderBarycentricFeaturesKHR{ + .fragmentShaderBarycentric = true, + }, + vk::PhysicalDeviceProvokingVertexFeaturesEXT{ + .provokingVertexLast = true, + }, + vk::PhysicalDeviceVertexAttributeDivisorFeatures{ + .vertexAttributeInstanceRateDivisor = true, + }, + vk::PhysicalDeviceMaintenance5FeaturesKHR{ + .maintenance5 = true, + }, + vk::PhysicalDeviceMaintenance8FeaturesKHR{ + .maintenance8 = true, + }, + vk::PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT{ + .attachmentFeedbackLoopLayout = true, + }, + vk::PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT{ + .attachmentFeedbackLoopDynamicState = true, + }, + vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT{ + .shaderBufferFloat32AtomicMinMax = + shader_atomic_float2_features.shaderBufferFloat32AtomicMinMax, + .shaderImageFloat32AtomicMinMax = + shader_atomic_float2_features.shaderImageFloat32AtomicMinMax, + }, + vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR{ + .workgroupMemoryExplicitLayout = + workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout, + .workgroupMemoryExplicitLayoutScalarBlockLayout = + workgroup_memory_explicit_layout_features + .workgroupMemoryExplicitLayoutScalarBlockLayout, + .workgroupMemoryExplicitLayout16BitAccess = + workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout16BitAccess, + }, + vk::PhysicalDeviceImage2DViewOf3DFeaturesEXT{ + .image2DViewOf3D = image_2d_view_of_3d_features.image2DViewOf3D, + .sampler2DViewOf3D = image_2d_view_of_3d_features.sampler2DViewOf3D, + }, + vk::PhysicalDeviceImageViewMinLodFeaturesEXT{ + .minLod = true, + }, + vk::PhysicalDeviceShaderClockFeaturesKHR{ + .shaderSubgroupClock = shader_clock_features.shaderSubgroupClock, + }, + }; + + if (!custom_border_color) { + device_chain.unlink(); + } + if (!dynamic_state_3) { + device_chain.unlink(); + } + if (!depth_clip_control) { + device_chain.unlink(); + } + if (!depth_clip_enable) { + device_chain.unlink(); + } + if (!vertex_input_dynamic_state) { + device_chain.unlink(); + } + if (!list_restart) { + device_chain.unlink(); + } + if (!fragment_shader_barycentric) { + device_chain.unlink(); + } + if (!provoking_vertex) { + device_chain.unlink(); + } + if (!maintenance_5) { + device_chain.unlink(); + } + if (!maintenance_8) { + device_chain.unlink(); + } + if (!attachment_feedback_loop) { + device_chain.unlink(); + device_chain.unlink(); + } + if (!shader_atomic_float2) { + device_chain.unlink(); + } + if (!workgroup_memory_explicit_layout) { + device_chain.unlink(); + } + if (!image_2d_view_of_3d) { + device_chain.unlink(); + } + if (!image_view_min_lod) { + device_chain.unlink(); + } + if (!shader_clock) { + device_chain.unlink(); + } + + auto [device_result, dev] = physical_device.createDeviceUnique(device_chain.get()); + if (device_result != vk::Result::eSuccess) { + LOG_CRITICAL(Render_Vulkan, "Failed to create device: {}", vk::to_string(device_result)); + return false; + } + device = std::move(dev); + + VULKAN_HPP_DEFAULT_DISPATCHER.init(*device); + + graphics_queue = device->getQueue(queue_family_index, 0); + present_queue = device->getQueue(queue_family_index, 0); + + if (calibrated_timestamps) { + const auto [time_domains_result, time_domains] = + physical_device.getCalibrateableTimeDomainsEXT(); + if (time_domains_result == vk::Result::eSuccess) { +#if _WIN64 + const bool has_host_time_domain = + std::find(time_domains.cbegin(), time_domains.cend(), + vk::TimeDomainEXT::eQueryPerformanceCounter) != time_domains.cend(); +#elif __linux__ + const bool has_host_time_domain = + std::find(time_domains.cbegin(), time_domains.cend(), + vk::TimeDomainEXT::eClockMonotonicRaw) != time_domains.cend(); +#else + // Tracy limitation means only Windows and Linux can use host time domain. + // https://github.com/shadps4-emu/tracy/blob/c6d779d78508514102fbe1b8eb28bda10d95bb2a/public/tracy/TracyVulkan.hpp#L384-L389 + const bool has_host_time_domain = false; +#endif + if (has_host_time_domain) { + static constexpr std::string_view context_name{"vk_rasterizer"}; + profiler_context = TracyVkContextHostCalibrated( + *instance, physical_device, *device, + VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr, + VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr); + TracyVkContextName(profiler_context, context_name.data(), context_name.size()); + } + } else { + LOG_WARNING(Render_Vulkan, "Could not query calibrated time domains for profiling: {}", + vk::to_string(time_domains_result)); + } + } + + CreateAllocator(); + return true; +} + +void Instance::CreateAllocator() { + const VmaVulkanFunctions functions = { + .vkGetInstanceProcAddr = VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr, + .vkGetDeviceProcAddr = VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr, + }; + + const VmaAllocatorCreateInfo allocator_info = { + .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, + .physicalDevice = physical_device, + .device = *device, + .pVulkanFunctions = &functions, + .instance = *instance, + .vulkanApiVersion = TargetVulkanApiVersion, + }; + + const VkResult result = vmaCreateAllocator(&allocator_info, &allocator); + if (result != VK_SUCCESS) { + UNREACHABLE_MSG("Failed to initialize VMA with error {}", + vk::to_string(vk::Result{result})); + } +} + +void Instance::CollectDeviceParameters() { + const vk::StructureChain property_chain = + physical_device + .getProperties2(); + const vk::PhysicalDeviceDriverProperties driver = + property_chain.get(); + + driver_id = driver.driverID; + vendor_name = driver.driverName.data(); + + const std::string model_name{GetModelName()}; + const std::string driver_version = GetDriverVersionName(); + const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version); + const std::string api_version = GetReadableVersion(properties.apiVersion); + const std::string extensions = fmt::format("{}", fmt::join(available_extensions, ", ")); + + LOG_INFO(Render_Vulkan, "GPU_Vendor: {}", vendor_name); + LOG_INFO(Render_Vulkan, "GPU_Model: {}", model_name); + LOG_INFO(Render_Vulkan, "GPU_Integrated: {}", IsIntegrated() ? "Yes" : "No"); + LOG_INFO(Render_Vulkan, "GPU_Vulkan_Driver: {}", driver_name); + LOG_INFO(Render_Vulkan, "GPU_Vulkan_Version: {}", api_version); + LOG_INFO(Render_Vulkan, "GPU_Vulkan_Extensions: {}", extensions); +} + +void Instance::CollectPhysicalMemoryInfo() { + vk::PhysicalDeviceMemoryBudgetPropertiesEXT budget{}; + vk::PhysicalDeviceMemoryProperties2 props = { + .pNext = supports_memory_budget ? &budget : nullptr, + }; + physical_device.getMemoryProperties2(&props); + const auto& memory_props = props.memoryProperties; + const size_t num_props = memory_props.memoryHeapCount; + total_memory_budget = 0; + u64 device_initial_usage = 0; + u64 local_memory = 0; + for (size_t i = 0; i < num_props; ++i) { + const bool is_device_local = + (memory_props.memoryHeaps[i].flags & vk::MemoryHeapFlagBits::eDeviceLocal) != + vk::MemoryHeapFlags{}; + if (!IsIntegrated() && !is_device_local) { + // Ignore non-device local memory on discrete GPUs. + continue; + } + valid_heaps.push_back(i); + if (is_device_local) { + local_memory += memory_props.memoryHeaps[i].size; + } + if (supports_memory_budget) { + device_initial_usage += budget.heapUsage[i]; + total_memory_budget += budget.heapBudget[i]; + continue; + } + // If memory budget is not supported, use the size of the heap as the budget. + total_memory_budget += memory_props.memoryHeaps[i].size; + } + if (!IsIntegrated()) { + // We reserve some memory for the system. + const u64 system_memory = std::min(total_memory_budget / 8, 1_GB); + total_memory_budget -= system_memory; + return; + } + // Leave at least 8 GB for the system on integrated GPUs. + const s64 available_memory = static_cast(total_memory_budget - device_initial_usage); + total_memory_budget = + static_cast(std::max(available_memory - 8_GB, static_cast(local_memory))); +} + +void Instance::CollectImageFormatInfo() { + // Check for block texel view support using basic image format info. + const vk::PhysicalDeviceImageFormatInfo2 block_texel_view_info{ + .format = vk::Format::eBc1RgbaUnormBlock, + .type = vk::ImageType::e2D, + .tiling = vk::ImageTiling::eOptimal, + .usage = vk::ImageUsageFlagBits::eSampled, + .flags = vk::ImageCreateFlagBits::eBlockTexelViewCompatible, + }; + const auto block_texel_view_props = + physical_device.getImageFormatProperties2(block_texel_view_info); + supports_block_texel_view = block_texel_view_props.result == vk::Result::eSuccess; + LOG_INFO(Render_Vulkan, "Block Texel View support: {}", + supports_block_texel_view ? "Yes" : "No"); + + // Check and log format support details. + for (const auto& format : LiverpoolToVK::SurfaceFormats()) { + if (!IsFormatSupported(format.vk_format, format.flags)) { + LOG_WARNING(Render_Vulkan, + "Surface format data_format={}, number_format={} is not fully supported " + "(vk_format={}, missing features={})", + static_cast(format.data_format), + static_cast(format.number_format), vk::to_string(format.vk_format), + vk::to_string(format.flags & ~GetFormatFeatureFlags(format.vk_format))); + } + } + for (const auto& format : LiverpoolToVK::DepthFormats()) { + if (!IsFormatSupported(format.vk_format, format.flags)) { + LOG_WARNING(Render_Vulkan, + "Depth format z_format={}, stencil_format={} is not fully supported " + "(vk_format={}, missing features={})", + static_cast(format.z_format), static_cast(format.stencil_format), + vk::to_string(format.vk_format), + vk::to_string(format.flags & ~GetFormatFeatureFlags(format.vk_format))); + } + } +} + +void Instance::CollectToolingInfo() const { + if (driver_id == vk::DriverId::eAmdProprietary || + driver_id == vk::DriverId::eIntelProprietaryWindows) { + // AMD: Causes issues with Reshade. + // Intel: Causes crash on start. + return; + } + const auto [tools_result, tools] = physical_device.getToolProperties(); + if (tools_result != vk::Result::eSuccess) { + LOG_ERROR(Render_Vulkan, "Could not get Vulkan tool properties: {}", + vk::to_string(tools_result)); + return; + } + for (const vk::PhysicalDeviceToolProperties& tool : tools) { + const std::string_view name = tool.name; + LOG_INFO(Render_Vulkan, "Attached debugging tool: {}", name); + } +} + +u64 Instance::GetDeviceMemoryUsage() const { + vk::PhysicalDeviceMemoryBudgetPropertiesEXT memory_budget_props{}; + vk::PhysicalDeviceMemoryProperties2 props = { + .pNext = &memory_budget_props, + }; + physical_device.getMemoryProperties2(&props); + + u64 total_usage = 0; + for (const size_t heap : valid_heaps) { + total_usage += memory_budget_props.heapUsage[heap]; + } + return total_usage; +} + +vk::FormatFeatureFlags2 Instance::GetFormatFeatureFlags(vk::Format format) const { + const auto it = format_properties.find(format); + if (it == format_properties.end()) { + UNIMPLEMENTED_MSG("Properties of format {} have not been queried.", vk::to_string(format)); + } + + return it->second.optimalTilingFeatures | it->second.bufferFeatures; +} + +bool Instance::IsFormatSupported(const vk::Format format, + const vk::FormatFeatureFlags2 flags) const { + if (format == vk::Format::eUndefined) [[unlikely]] { + return true; + } + return (GetFormatFeatureFlags(format) & flags) == flags; +} + +vk::Format Instance::GetSupportedFormat(const vk::Format format, + const vk::FormatFeatureFlags2 flags) const { + if (!IsFormatSupported(format, flags)) [[unlikely]] { + switch (format) { + case vk::Format::eD16UnormS8Uint: + if (IsFormatSupported(vk::Format::eD24UnormS8Uint, flags)) { + return vk::Format::eD24UnormS8Uint; + } + if (IsFormatSupported(vk::Format::eD32SfloatS8Uint, flags)) { + return vk::Format::eD32SfloatS8Uint; + } + break; + case vk::Format::eR8Srgb: + if (IsFormatSupported(vk::Format::eR8Unorm, flags)) { + return vk::Format::eR8Unorm; + } + break; + case vk::Format::eR8G8Srgb: + if (IsFormatSupported(vk::Format::eR8G8Unorm, flags)) { + return vk::Format::eR8G8Unorm; + } + break; + default: + break; + } + } + return format; +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_instance.h b/gpu/shadps4/video_core/renderer_vulkan/vk_instance.h new file mode 100644 index 0000000..3f35562 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_instance.h @@ -0,0 +1,537 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "video_core/renderer_vulkan/vk_platform.h" + +#define TRACY_VK_USE_SYMBOL_TABLE +#include + +namespace Frontend { +class WindowSDL; +} + +VK_DEFINE_HANDLE(VmaAllocator) + +namespace Vulkan { + +class Instance { +public: + explicit Instance(bool validation = false, bool crash_diagnostic = false); + explicit Instance(Frontend::WindowSDL& window, s32 physical_device_index, + bool enable_validation = false, bool enable_crash_diagnostic = false); + ~Instance(); + + /// Returns a formatted string for the driver version + std::string GetDriverVersionName(); + + /// Gets a compatibility format if the format is not supported. + [[nodiscard]] vk::Format GetSupportedFormat(vk::Format format, + vk::FormatFeatureFlags2 flags) const; + + /// Returns the Vulkan instance + vk::Instance GetInstance() const { + return *instance; + } + + /// Returns the current physical device + vk::PhysicalDevice GetPhysicalDevice() const { + return physical_device; + } + + /// Returns the Vulkan device + vk::Device GetDevice() const { + return *device; + } + + /// Returns the VMA allocator handle + VmaAllocator GetAllocator() const { + return allocator; + } + + /// Returns a list of the available physical devices + std::span GetPhysicalDevices() const { + return physical_devices; + } + + /// Retrieve queue information + u32 GetGraphicsQueueFamilyIndex() const { + return queue_family_index; + } + + u32 GetPresentQueueFamilyIndex() const { + return queue_family_index; + } + + vk::Queue GetGraphicsQueue() const { + return graphics_queue; + } + + vk::Queue GetPresentQueue() const { + return present_queue; + } + + TracyVkCtx GetProfilerContext() const { + return profiler_context; + } + + /// Returns true if anisotropic filtering is supported + bool IsAnisotropicFilteringSupported() const { + return features.samplerAnisotropy; + } + + /// Returns true if depth bounds testing is supported + bool IsDepthBoundsSupported() const { + return features.depthBounds; + } + + /// Returns true if 16-bit floats are supported in shaders + bool IsShaderFloat16Supported() const { + return vk12_features.shaderFloat16; + } + + /// Returns true if 64-bit floats are supported in shaders + bool IsShaderFloat64Supported() const { + return features.shaderFloat64; + } + + /// Returns true if 64-bit ints are supported in shaders + bool IsShaderInt64Supported() const { + return features.shaderInt64; + } + + /// Returns true if 16-bit ints are supported in shaders + bool IsShaderInt16Supported() const { + return features.shaderInt16; + } + + /// Returns true if 8-bit ints are supported in shaders + bool IsShaderInt8Supported() const { + return vk12_features.shaderInt8; + } + + /// Returns true if VK_KHR_maintenance8 is supported + bool IsMaintenance8Supported() const { + return maintenance_8; + } + + /// Returns true if VK_EXT_attachment_feedback_loop_layout is supported + bool IsAttachmentFeedbackLoopLayoutSupported() const { + return attachment_feedback_loop; + } + + /// Returns true when VK_EXT_custom_border_color is supported + bool IsCustomBorderColorSupported() const { + return custom_border_color; + } + + /// Returns true when VK_EXT_shader_stencil_export is supported + bool IsShaderStencilExportSupported() const { + return shader_stencil_export; + } + + /// Returns true when VK_EXT_depth_clip_control is supported + bool IsDepthClipControlSupported() const { + return depth_clip_control; + } + + /// Returns true when VK_EXT_depth_clip_enable is supported + bool IsDepthClipEnableSupported() const { + return depth_clip_enable; + } + + /// Returns true when VK_EXT_depth_range_unrestricted is supported + bool IsDepthRangeUnrestrictedSupported() const { + return depth_range_unrestricted; + } + + /// Returns true when VK_EXT_extended_dynamic_state3 is supported + bool IsExtendedDynamicState3Supported() const { + return dynamic_state_3; + } + + /// Returns true when the extendedDynamicState3ColorWriteMask feature of + /// VK_EXT_extended_dynamic_state3 is supported. + bool IsDynamicColorWriteMaskSupported() const { + return dynamic_state_3 && dynamic_state_3_features.extendedDynamicState3ColorWriteMask; + } + + /// Returns true when VK_EXT_vertex_input_dynamic_state is supported. + bool IsVertexInputDynamicState() const { + return vertex_input_dynamic_state; + } + + /// Returns true when VK_KHR_fragment_shader_barycentric is supported. + bool IsFragmentShaderBarycentricSupported() const { + return fragment_shader_barycentric; + } + + /// Returns true when VK_AMD_shader_explicit_vertex_parameter is supported. + bool IsAmdShaderExplicitVertexParameterSupported() const { + return amd_shader_explicit_vertex_parameter; + } + + /// Returns true when VK_EXT_primitive_topology_list_restart is supported for regular lists. + bool IsListRestartSupported() const { + return list_restart && list_restart_features.primitiveTopologyListRestart; + } + + /// Returns true when VK_EXT_primitive_topology_list_restart is supported for patch lists. + bool IsPatchListRestartSupported() const { + return list_restart && list_restart_features.primitiveTopologyPatchListRestart; + } + + /// Returns true when VK_EXT_provoking_vertex is supported. + bool IsProvokingVertexSupported() const { + return provoking_vertex; + } + + /// Returns true when VK_AMD_shader_image_load_store_lod is supported. + bool IsImageLoadStoreLodSupported() const { + return image_load_store_lod; + } + + /// Returns true when VK_AMD_gcn_shader is supported. + bool IsAmdGcnShaderSupported() const { + return amd_gcn_shader; + } + + /// Returns true when VK_AMD_shader_trinary_minmax is supported. + bool IsAmdShaderTrinaryMinMaxSupported() const { + return amd_shader_trinary_minmax; + } + + /// Returns true when the shaderBufferFloat32AtomicMinMax feature of + /// VK_EXT_shader_atomic_float2 is supported. + bool IsShaderAtomicFloatBuffer32MinMaxSupported() const { + return shader_atomic_float2 && + shader_atomic_float2_features.shaderBufferFloat32AtomicMinMax; + } + + /// Returns true when the shaderImageFloat32AtomicMinMax feature of + /// VK_EXT_shader_atomic_float2 is supported. + bool IsShaderAtomicFloatImage32MinMaxSupported() const { + return shader_atomic_float2 && shader_atomic_float2_features.shaderImageFloat32AtomicMinMax; + } + + /// Returns true if 64-bit integer atomic operations can be used on buffers + bool IsBufferInt64AtomicsSupported() const { + return vk12_features.shaderBufferInt64Atomics; + } + + /// Returns true if 64-bit integer atomic operations can be used on shared memory + bool IsSharedInt64AtomicsSupported() const { + return vk12_features.shaderSharedInt64Atomics; + } + + /// Returns true if the subgroup size can be set to match guest subgroup size + bool IsSubgroupSize64Supported() const { + return vk13_features.subgroupSizeControl && vk13_props.maxSubgroupSize >= 64; + } + + /// Returns true when VK_KHR_workgroup_memory_explicit_layout is supported. + bool IsWorkgroupMemoryExplicitLayoutSupported() const { + return workgroup_memory_explicit_layout && + workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout16BitAccess; + } + + /// Returns true if VK_NV_framebuffer_mixed_samples or + /// VK_AMD_mixed_attachment_samples is supported + bool IsMixedDepthSamplesSupported() const { + return nv_framebuffer_mixed_samples || amd_mixed_attachment_samples; + } + + /// Returns true if VK_AMD_mixed_attachment_samples is supported + bool IsMixedAnySamplesSupported() const { + return amd_mixed_attachment_samples; + } + + /// Returns true when geometry shaders are supported by the device + bool IsGeometryStageSupported() const { + return features.geometryShader; + } + + /// Returns true when tessellation is supported by the device + bool IsTessellationSupported() const { + return features.tessellationShader; + } + + /// Returns true when the shaderSubgroupClock feature of + /// VK_KHR_shader_clock is supported. + bool IsShaderSubgroupClockSupported() const { + return shader_clock && shader_clock_features.shaderSubgroupClock; + } + + /// Returns the vendor ID of the physical device + u32 GetVendorID() const { + return properties.vendorID; + } + + /// Returns the device ID of the physical device + u32 GetDeviceID() const { + return properties.deviceID; + } + + /// Returns the driver ID. + vk::DriverId GetDriverID() const { + return driver_id; + } + + /// Returns the current driver version provided in Vulkan-formatted version numbers. + u32 GetDriverVersion() const { + return properties.driverVersion; + } + + /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers. + u32 ApiVersion() const { + return properties.apiVersion; + } + + /// Returns the vendor name reported from Vulkan. + std::string_view GetVendorName() const { + return vendor_name; + } + + /// Returns the list of available extensions. + std::span GetAvailableExtensions() const { + return available_extensions; + } + + /// Returns the device name. + std::string_view GetModelName() const { + return properties.deviceName; + } + + /// Returns if the device is an integrated GPU. + bool IsIntegrated() const { + return properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu; + } + + /// Returns the pipeline cache unique identifier + const auto GetPipelineCacheUUID() const { + return properties.pipelineCacheUUID; + } + + /// Returns the minimum required alignment for uniforms + vk::DeviceSize UniformMinAlignment() const { + return properties.limits.minUniformBufferOffsetAlignment; + } + + /// Returns the minimum required alignment for storage buffers + vk::DeviceSize StorageMinAlignment() const { + return properties.limits.minStorageBufferOffsetAlignment; + } + + /// Returns the minimum alignment required for accessing host-mapped device memory + vk::DeviceSize NonCoherentAtomSize() const { + return properties.limits.nonCoherentAtomSize; + } + + /// Returns the subgroup size of the selected physical device. + u32 SubgroupSize() const { + return vk11_props.subgroupSize; + } + + /// Returns the maximum size of compute shared memory. + u32 MaxComputeSharedMemorySize() const { + return properties.limits.maxComputeSharedMemorySize; + } + + /// Returns the maximum sampler LOD bias. + float MaxSamplerLodBias() const { + return properties.limits.maxSamplerLodBias; + } + + /// Returns the maximum sampler anisotropy. + float MaxSamplerAnisotropy() const { + return properties.limits.maxSamplerAnisotropy; + } + + /// Returns the maximum number of push descriptors. + u32 MaxPushDescriptors() const { + return push_descriptor_props.maxPushDescriptors; + } + + /// Returns the maximum size of a single VkDeviceMemory + vk::DeviceSize MaxMemoryAllocationSize() const { + return vk11_props.maxMemoryAllocationSize; + } + + /// Returns the vulkan 1.2 physical device properties. + const vk::PhysicalDeviceVulkan12Properties& GetVk12Properties() const noexcept { + return vk12_props; + } + + /// Returns the memory properties of the physical device. + const vk::PhysicalDeviceMemoryProperties& GetMemoryProperties() const noexcept { + return memory_properties; + } + + /// Returns true if shaders can declare the ClipDistance attribute + bool IsShaderClipDistanceSupported() const { + return features.shaderClipDistance; + } + + /// Returns the maximim viewport width. + u32 GetMaxViewportWidth() const { + return properties.limits.maxViewportDimensions[0]; + } + + /// Returns the maximum viewport height. + u32 GetMaxViewportHeight() const { + return properties.limits.maxViewportDimensions[1]; + } + + /// Returns the maximum render area width. + u32 GetMaxFramebufferWidth() const { + return properties.limits.maxFramebufferWidth; + } + + /// Returns the maximum render area height. + u32 GetMaxFramebufferHeight() const { + return properties.limits.maxFramebufferHeight; + } + + /// Returns the maximum number of samplers that can be allocated at once. + u32 GetMaxSamplerAllocationCount() const { + if (driver_id == vk::DriverId::eMesaKosmickrisp) { + // FIXME: KosmicKrisp has an internal 1024 unique sampler limit before + // vkCreateSampler starts returning VK_ERROR_OUT_OF_HOST_MEMORY. Work + // around this for now by reducing the value to 1024. + return 1024; + } + return properties.limits.maxSamplerAllocationCount; + } + + /// Returns the sample count flags supported by color buffers. + vk::SampleCountFlags GetColorSampleCounts() const { + return properties.limits.framebufferColorSampleCounts; + } + + /// Returns the sample count flags supported by depth buffer. + vk::SampleCountFlags GetDepthSampleCounts() const { + return properties.limits.framebufferDepthSampleCounts & + properties.limits.framebufferStencilSampleCounts; + } + + /// Returns true if logic ops are supported by the device. + bool IsLogicOpSupported() const { + return features.logicOp; + } + + /// Returns whether VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT is supported on compressed + /// images. + bool IsBlockTexelViewSupported() const { + return supports_block_texel_view; + } + + /// Returns whether VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT is supported on 3D images + bool Is2dViewOf3dSupported() const { + return image_2d_view_of_3d && image_2d_view_of_3d_features.image2DViewOf3D && + image_2d_view_of_3d_features.sampler2DViewOf3D; + } + + /// Returns whether VK_EXT_image_view_min_lod is supported. + bool IsImageViewMinLodSupported() const { + return image_view_min_lod; + } + + /// Returns whether the device can report memory usage. + bool CanReportMemoryUsage() const { + return supports_memory_budget; + } + + /// Returns the amount of memory used. + [[nodiscard]] u64 GetDeviceMemoryUsage() const; + + /// Returns the total memory budget available to the device. + [[nodiscard]] u64 GetTotalMemoryBudget() const { + return total_memory_budget; + } + + /// Determines if a format is supported for a set of feature flags. + [[nodiscard]] bool IsFormatSupported(vk::Format format, vk::FormatFeatureFlags2 flags) const; + +private: + /// Creates the logical device opportunistically enabling extensions + bool CreateDevice(); + + /// Creates the VMA allocator handle + void CreateAllocator(); + + /// Collects various information from the device. + void CollectDeviceParameters(); + void CollectPhysicalMemoryInfo(); + void CollectImageFormatInfo(); + void CollectToolingInfo() const; + + /// Gets the supported feature flags for a format. + [[nodiscard]] vk::FormatFeatureFlags2 GetFormatFeatureFlags(vk::Format format) const; + +private: + vk::UniqueInstance instance; + vk::PhysicalDevice physical_device; + vk::UniqueDevice device; + vk::PhysicalDeviceProperties properties; + vk::PhysicalDeviceMemoryProperties memory_properties; + vk::PhysicalDeviceVulkan11Properties vk11_props; + vk::PhysicalDeviceVulkan12Properties vk12_props; + vk::PhysicalDeviceVulkan13Properties vk13_props; + vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props; + vk::PhysicalDeviceFeatures features; + vk::PhysicalDeviceVulkan12Features vk12_features; + vk::PhysicalDeviceVulkan13Features vk13_features; + vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT dynamic_state_3_features; + vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT shader_atomic_float2_features; + vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR + workgroup_memory_explicit_layout_features; + vk::PhysicalDeviceImage2DViewOf3DFeaturesEXT image_2d_view_of_3d_features; + vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT list_restart_features; + vk::PhysicalDeviceShaderClockFeaturesKHR shader_clock_features; + vk::DriverIdKHR driver_id; + vk::UniqueDebugUtilsMessengerEXT debug_callback{}; + std::string vendor_name; + VmaAllocator allocator{}; + vk::Queue present_queue; + vk::Queue graphics_queue; + std::vector physical_devices; + std::vector available_extensions; + std::unordered_map format_properties; + TracyVkCtx profiler_context{}; + u32 queue_family_index{0}; + bool custom_border_color{}; + bool fragment_shader_barycentric{}; + bool amd_shader_explicit_vertex_parameter{}; + bool depth_clip_control{}; + bool depth_clip_enable{}; + bool dynamic_state_3{}; + bool depth_range_unrestricted{}; + bool vertex_input_dynamic_state{}; + bool list_restart{}; + bool provoking_vertex{}; + bool shader_stencil_export{}; + bool image_load_store_lod{}; + bool amd_gcn_shader{}; + bool amd_shader_trinary_minmax{}; + bool nv_framebuffer_mixed_samples{}; + bool amd_mixed_attachment_samples{}; + bool shader_atomic_float{}; + bool shader_atomic_float2{}; + bool workgroup_memory_explicit_layout{}; + bool maintenance_5{}; + bool maintenance_8{}; + bool attachment_feedback_loop{}; + bool image_2d_view_of_3d{}; + bool image_view_min_lod{}; + bool shader_clock{}; + bool supports_memory_budget{}; + bool supports_block_texel_view{}; + u64 total_memory_budget{}; + std::vector valid_heaps; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_cache.cpp new file mode 100644 index 0000000..e74fc07 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -0,0 +1,794 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include + +#include "common/hash.h" +#include "common/io_file.h" +#include "common/path_util.h" +#include "core/debug_state.h" +#include "core/emulator_settings.h" +#include "shader_recompiler/backend/spirv/emit_spirv.h" +#include "shader_recompiler/info.h" +#include "shader_recompiler/recompiler.h" +#include "shader_recompiler/runtime_info.h" +#include "video_core/amdgpu/liverpool.h" +#include "video_core/cache_storage.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_pipeline_serialization.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +namespace Vulkan { + +using Shader::HwStage; +using Shader::Output; +using Shader::SwStage; + +constexpr static auto SpirvVersion1_6 = 0x00010600U; + +constexpr static std::array DescriptorHeapSizes = { + vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer, 512}, + vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer, 8192}, + vk::DescriptorPoolSize{vk::DescriptorType::eSampledImage, 8192}, + vk::DescriptorPoolSize{vk::DescriptorType::eStorageImage, 1024}, + vk::DescriptorPoolSize{vk::DescriptorType::eSampler, 1024}, +}; + +static u32 MapOutputs(std::span outputs, const AmdGpu::VsOutputControl& ctl) { + u32 num_outputs = 0; + + if (ctl.vs_out_misc_enable) { + auto& misc_vec = outputs[num_outputs++]; + misc_vec[0] = ctl.use_vtx_point_size ? Output::PointSize : Output::None; + misc_vec[1] = ctl.use_vtx_edge_flag + ? Output::EdgeFlag + : (ctl.use_vtx_gs_cut_flag ? Output::GsCutFlag : Output::None); + misc_vec[2] = + ctl.use_vtx_kill_flag + ? Output::KillFlag + : (ctl.use_vtx_render_target_idx ? Output::RenderTargetIndex : Output::None); + misc_vec[3] = ctl.use_vtx_viewport_idx ? Output::ViewportIndex : Output::None; + } + + if (ctl.vs_out_ccdist0_enable) { + auto& ccdist0 = outputs[num_outputs++]; + ccdist0[0] = ctl.IsClipDistEnabled(0) + ? Output::ClipDist0 + : (ctl.IsCullDistEnabled(0) ? Output::CullDist0 : Output::None); + ccdist0[1] = ctl.IsClipDistEnabled(1) + ? Output::ClipDist1 + : (ctl.IsCullDistEnabled(1) ? Output::CullDist1 : Output::None); + ccdist0[2] = ctl.IsClipDistEnabled(2) + ? Output::ClipDist2 + : (ctl.IsCullDistEnabled(2) ? Output::CullDist2 : Output::None); + ccdist0[3] = ctl.IsClipDistEnabled(3) + ? Output::ClipDist3 + : (ctl.IsCullDistEnabled(3) ? Output::CullDist3 : Output::None); + } + + if (ctl.vs_out_ccdist1_enable) { + auto& ccdist1 = outputs[num_outputs++]; + ccdist1[0] = ctl.IsClipDistEnabled(4) + ? Output::ClipDist4 + : (ctl.IsCullDistEnabled(4) ? Output::CullDist4 : Output::None); + ccdist1[1] = ctl.IsClipDistEnabled(5) + ? Output::ClipDist5 + : (ctl.IsCullDistEnabled(5) ? Output::CullDist5 : Output::None); + ccdist1[2] = ctl.IsClipDistEnabled(6) + ? Output::ClipDist6 + : (ctl.IsCullDistEnabled(6) ? Output::CullDist6 : Output::None); + ccdist1[3] = ctl.IsClipDistEnabled(7) + ? Output::ClipDist7 + : (ctl.IsCullDistEnabled(7) ? Output::CullDist7 : Output::None); + } + + return num_outputs; +} + +const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(HwStage stage, SwStage l_stage) { + auto& info = runtime_infos[u32(l_stage)]; + const auto& regs = liverpool->regs; + const auto BuildCommon = [&](const auto& program) { + info.props.num_user_data = program.settings.num_user_regs; + info.props.num_input_vgprs = program.settings.vgpr_comp_cnt; + info.props.num_allocated_vgprs = program.NumVgprs(); + info.props.fp_denorm_mode32 = program.settings.fp_denorm_mode32; + info.props.fp_denorm_mode16_64 = program.settings.fp_denorm_mode64; + info.props.fp_round_mode32 = program.settings.fp_round_mode32; + info.props.fp_round_mode16_64 = program.settings.fp_round_mode64; + }; + info.Initialize(stage, l_stage); + switch (stage) { + case HwStage::Local: { + BuildCommon(regs.ls_program); + Shader::TessellationDataConstantBuffer tess_constants{}; + const auto* hull_info = infos[u32(SwStage::TessellationControl)]; + hull_info->ReadTessConstantBuffer(tess_constants); + info.hw.ls.ls_stride = tess_constants.ls_stride; + break; + } + case HwStage::Hull: + BuildCommon(regs.hs_program); + break; + case HwStage::Export: + BuildCommon(regs.es_program); + info.hw.es.vertex_data_size = regs.vgt_esgs_ring_itemsize; + break; + case HwStage::Geometry: { + BuildCommon(regs.gs_program); + info.hw.gs.num_outputs = MapOutputs(info.hw.gs.outputs, regs.vs_output_control); + info.hw.gs.output_vertices = regs.vgt_gs_max_vert_out; + info.hw.gs.num_invocations = + regs.vgt_gs_instance_cnt.IsEnabled() ? regs.vgt_gs_instance_cnt.count : 1; + if (regs.stage_enable.raw == AmdGpu::ShaderStageEnable::LsHsEsGs) { + info.hw.gs.in_primitive = [&]() { + switch (regs.tess_config.topology) { + case AmdGpu::TessellationTopology::Point: + return AmdGpu::PrimitiveType::PointList; + case AmdGpu::TessellationTopology::Line: + return AmdGpu::PrimitiveType::LineList; + case AmdGpu::TessellationTopology::TriangleCw: + case AmdGpu::TessellationTopology::TriangleCcw: + return AmdGpu::PrimitiveType::TriangleList; + default: + UNREACHABLE(); + } + }(); + } else { + info.hw.gs.in_primitive = regs.primitive_type; + } + for (u32 stream_id = 0; stream_id < Shader::GsMaxOutputStreams; ++stream_id) { + info.hw.gs.out_primitive[stream_id] = + regs.vgt_gs_out_prim_type.GetPrimitiveType(stream_id); + } + info.hw.gs.in_vertex_data_size = regs.vgt_esgs_ring_itemsize; + info.hw.gs.out_vertex_data_size = regs.vgt_gs_vert_itemsize[0]; + info.hw.gs.mode = regs.vgt_gs_mode.mode; + const auto params_vc = AmdGpu::GetParams(regs.vs_program); + info.hw.gs.vs_copy = params_vc.code; + info.hw.gs.vs_copy_hash = params_vc.hash; + DumpShader(info.hw.gs.vs_copy, info.hw.gs.vs_copy_hash, Shader::HwStage::Vertex, 0, + "copy.bin"); + break; + } + case HwStage::Vertex: { + BuildCommon(regs.vs_program); + info.hw.vs.user_clip_plane_mask = regs.clipper_control.user_clip_plane_enable; + info.hw.vs.num_outputs = MapOutputs(info.hw.vs.outputs, regs.vs_output_control); + info.hw.vs.emulate_depth_negative_one_to_one = + !instance.IsDepthClipControlSupported() && + regs.clipper_control.clip_space == AmdGpu::ClipSpace::MinusWToW; + info.hw.vs.clip_disable = regs.IsClipDisabled(); + break; + } + case HwStage::Fragment: { + BuildCommon(regs.ps_program); + info.hw.fs.en_flags = regs.ps_input_ena; + info.hw.fs.addr_flags = regs.ps_input_addr; + info.hw.fs.num_inputs = regs.num_interp; + info.hw.fs.front_face_all_bits = regs.barycentric_control.front_face_all_bits; + info.hw.fs.num_samples = + regs.ps_input_addr.sample_coverage_ena && regs.ps_input_ena.sample_coverage_ena + ? regs.aa_config.NumSamples() + : 1; + info.hw.fs.z_export_format = regs.z_export_format; + u8 stencil_ref_export_enable = regs.depth_shader_control.stencil_op_val_export_enable | + regs.depth_shader_control.stencil_test_val_export_enable; + info.hw.fs.mrtz_mask = regs.depth_shader_control.z_export_enable | + (stencil_ref_export_enable << 1) | + (regs.depth_shader_control.mask_export_enable << 2) | + (regs.depth_shader_control.coverage_to_mask_enable << 3); + const auto& cb0_blend = regs.blend_control[0]; + if (cb0_blend.enable) { + info.hw.fs.dual_source_blending = + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.color_dst_factor) || + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.color_src_factor); + if (cb0_blend.separate_alpha_blend) { + info.hw.fs.dual_source_blending |= + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.alpha_dst_factor) || + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.alpha_src_factor); + } + } else { + info.hw.fs.dual_source_blending = false; + } + const auto& ps_inputs = regs.ps_inputs; + for (u32 i = 0; i < regs.num_interp; i++) { + info.hw.fs.inputs[i] = { + .param_index = u8(ps_inputs[i].input_offset), + .is_default = bool(ps_inputs[i].use_default), + .is_flat = bool(ps_inputs[i].flat_shade), + .default_value = u8(ps_inputs[i].default_value), + }; + } + for (u32 i = 0; i < Shader::MaxColorBuffers; i++) { + info.hw.fs.color_buffers[i] = graphics_key.color_buffers[i]; + } + // Lowered user clip planes ride the same emulation path as guest-exported distances, so + // the fragment side arms whenever the hardware vertex stage lowers them, keeping its input + // locations in sync with the shifted vertex outputs. + const bool lowers_user_clip_planes = + regs.clipper_control.user_clip_plane_enable && + !regs.stage_enable.IsStageEnabled(static_cast(HwStage::Geometry)); + info.hw.fs.clip_distance_emulation = + ((regs.vs_output_control.clip_distance_enable && + !regs.stage_enable.IsStageEnabled(static_cast(HwStage::Local))) || + lowers_user_clip_planes) && + profile.needs_clip_distance_emulation; + break; + } + case HwStage::Compute: { + const auto& cs_pgm = liverpool->GetCsRegs(); + info.props.num_user_data = cs_pgm.settings.num_user_regs; + info.props.num_allocated_vgprs = cs_pgm.settings.num_vgprs * 4; + info.hw.cs.workgroup_size = {cs_pgm.num_thread_x.full, cs_pgm.num_thread_y.full, + cs_pgm.num_thread_z.full}; + info.hw.cs.tgid_enable = {cs_pgm.IsTgidEnabled(0), cs_pgm.IsTgidEnabled(1), + cs_pgm.IsTgidEnabled(2)}; + info.hw.cs.shared_memory_size = cs_pgm.SharedMemSize(); + break; + } + default: + break; + } + switch (l_stage) { + case SwStage::Vertex: + info.sw.vs.step_rate_0 = regs.vgt_instance_step_rate_0; + info.sw.vs.step_rate_1 = regs.vgt_instance_step_rate_1; + info.sw.vs.vertex_sgpr_offset = draw_indirect_params.vertex_sgpr_offset; + info.sw.vs.instance_sgpr_offset = draw_indirect_params.instance_sgpr_offset; + info.sw.vs.tess_emulated_primitive = + regs.primitive_type == AmdGpu::PrimitiveType::RectList || + regs.primitive_type == AmdGpu::PrimitiveType::QuadList; + break; + case SwStage::TessellationControl: { + info.sw.tcs.num_input_control_points = regs.ls_hs_config.hs_input_control_points; + info.sw.tcs.num_threads = regs.ls_hs_config.hs_output_control_points; + info.sw.tcs.tess_type = regs.tess_config.type; + info.sw.tcs.offchip_lds_enable = regs.hs_program.settings.oc_lds_en; + break; + } + case SwStage::TessellationEval: { + info.sw.tes.tess_type = regs.tess_config.type; + info.sw.tes.tess_topology = regs.tess_config.topology; + info.sw.tes.tess_partitioning = regs.tess_config.partitioning; + break; + } + default: + break; + } + return info; +} + +PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_, + AmdGpu::Liverpool* liverpool_, u32 sparse_page_shift) + : instance{instance_}, scheduler{scheduler_}, liverpool{liverpool_}, + desc_heap{instance, scheduler.GetWorkSemaphore(), DescriptorHeapSizes} { + const auto& vk12_props = instance.GetVk12Properties(); + profile = Shader::Profile{ + .max_viewport_width = instance.GetMaxViewportWidth(), + .max_viewport_height = instance.GetMaxViewportHeight(), + .max_shared_memory_size = instance.MaxComputeSharedMemorySize(), + .supported_spirv = SpirvVersion1_6, + .subgroup_size = instance.SubgroupSize(), + .sparse_page_shift = sparse_page_shift, + .support_int8 = instance.IsShaderInt8Supported(), + .support_int16 = instance.IsShaderInt16Supported(), + .support_int64 = instance.IsShaderInt64Supported(), + .support_float16 = instance.IsShaderFloat16Supported(), + .support_float64 = instance.IsShaderFloat64Supported(), + .supports_denorm_behavior_independence = + vk12_props.denormBehaviorIndependence != vk::ShaderFloatControlsIndependence::eNone, + .supports_rounding_mode_independence = + vk12_props.roundingModeIndependence != vk::ShaderFloatControlsIndependence::eNone, + .support_fp16_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat16), + .support_fp16_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat16), + .support_fp16_round_to_zero = bool(vk12_props.shaderRoundingModeRTZFloat16), + .support_fp32_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat32), + .support_fp32_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat32), + .support_fp32_round_to_zero = bool(vk12_props.shaderRoundingModeRTZFloat32), + .support_fp64_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat64), + .support_fp64_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat64), + .support_fp64_round_to_zero = bool(vk12_props.shaderRoundingModeRTZFloat64), + .support_fp16_signed_zero_inf_nan_preserve = + bool(vk12_props.shaderSignedZeroInfNanPreserveFloat16), + .support_fp32_signed_zero_inf_nan_preserve = + bool(vk12_props.shaderSignedZeroInfNanPreserveFloat32), + .support_fp64_signed_zero_inf_nan_preserve = + bool(vk12_props.shaderSignedZeroInfNanPreserveFloat64), + .supports_image_load_store_lod = instance_.IsImageLoadStoreLodSupported(), + .supports_native_cube_calc = instance_.IsAmdGcnShaderSupported(), + .supports_trinary_minmax = instance_.IsAmdShaderTrinaryMinMaxSupported(), + .supports_buffer_fp32_atomic_min_max = + instance_.IsShaderAtomicFloatBuffer32MinMaxSupported(), + .supports_image_fp32_atomic_min_max = instance_.IsShaderAtomicFloatImage32MinMaxSupported(), + .supports_buffer_int64_atomics = instance_.IsBufferInt64AtomicsSupported(), + .supports_shared_int64_atomics = instance_.IsSharedInt64AtomicsSupported(), + .supports_workgroup_explicit_memory_layout = + instance_.IsWorkgroupMemoryExplicitLayoutSupported(), + .supports_amd_shader_explicit_vertex_parameter = + instance_.IsAmdShaderExplicitVertexParameterSupported(), + .supports_fragment_shader_barycentric = instance_.IsFragmentShaderBarycentricSupported(), + .supports_shader_subgroup_clock = instance_.IsShaderSubgroupClockSupported(), + .needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() && + instance.GetDriverID() == vk::DriverId::eNvidiaProprietary, + .needs_lds_barriers = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary || + instance.GetDriverID() == vk::DriverId::eMesaKosmickrisp, + .needs_buffer_offsets = instance.StorageMinAlignment() > 4, + .needs_unorm_fixup = instance.GetDriverID() == vk::DriverId::eMesaKosmickrisp, + .needs_clip_distance_emulation = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary, + .supports_shader_stencil_export = instance_.IsShaderStencilExportSupported(), + }; + WarmUp(); + + auto [cache_result, cache] = instance.GetDevice().createPipelineCacheUnique({}); + ASSERT_MSG(cache_result == vk::Result::eSuccess, "Failed to create pipeline cache: {}", + vk::to_string(cache_result)); + pipeline_cache = std::move(cache); +} + +PipelineCache::~PipelineCache() = default; + +// bbport: shader/pipeline compile time on the GPU thread, reported by BB_FRAME_STATS. +std::atomic g_bb_compile_ns; +std::atomic g_bb_compiles; +namespace { +struct CompileTimer { + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); + ~CompileTimer() { + g_bb_compile_ns += u64(std::chrono::duration_cast( + std::chrono::steady_clock::now() - start) + .count()); + ++g_bb_compiles; + } +}; +} // namespace + +const GraphicsPipeline* PipelineCache::GetGraphicsPipeline(const DrawIndirectParams params) { + draw_indirect_params = params; + if (!RefreshGraphicsKey()) { + return nullptr; + } + const auto [it, is_new] = graphics_pipelines.try_emplace(graphics_key); + if (is_new) { + const auto pipeline_hash = std::hash{}(graphics_key); + LOG_INFO(Render_Vulkan, "Compiling graphics pipeline {:#x}", pipeline_hash); + CompileTimer timer; + + GraphicsPipeline::SerializationSupport sdata{}; + it.value() = std::make_unique( + instance, scheduler, desc_heap, profile, graphics_key, *pipeline_cache, infos, + runtime_infos, fetch_shader, modules, sdata, false); + + RegisterPipelineData(graphics_key, pipeline_hash, sdata); + ++num_new_pipelines; + + if (EmulatorSettings.IsShaderCollect()) { + for (auto stage = 0; stage < MaxShaderStages; ++stage) { + if (infos[stage]) { + auto& m = modules[stage]; + module_related_pipelines[m].emplace_back(graphics_key); + } + } + } + fetch_shader.reset(); + } + return it->second.get(); +} + +const ComputePipeline* PipelineCache::GetComputePipeline() { + if (!RefreshComputeKey()) { + return nullptr; + } + const auto [it, is_new] = compute_pipelines.try_emplace(compute_key); + if (is_new) { + const auto pipeline_hash = std::hash{}(compute_key); + LOG_INFO(Render_Vulkan, "Compiling compute pipeline {:#x}", pipeline_hash); + CompileTimer timer; + + ComputePipeline::SerializationSupport sdata{}; + it.value() = std::make_unique(instance, scheduler, desc_heap, profile, + *pipeline_cache, compute_key, *infos[0], + modules[0], sdata, false); + RegisterPipelineData(compute_key, sdata); + ++num_new_pipelines; + + if (EmulatorSettings.IsShaderCollect()) { + auto& m = modules[0]; + module_related_pipelines[m].emplace_back(compute_key); + } + } + return it->second.get(); +} + +bool PipelineCache::RefreshGraphicsKey() { + std::memset(&graphics_key, 0, sizeof(GraphicsPipelineKey)); + const auto& regs = liverpool->regs; + auto& key = graphics_key; + + const bool db_enabled = regs.depth_buffer.DepthValid() || regs.depth_buffer.StencilValid(); + + key.z_format = regs.depth_buffer.DepthValid() ? regs.depth_buffer.z_info.format + : AmdGpu::DepthBuffer::ZFormat::Invalid; + key.stencil_format = regs.depth_buffer.StencilValid() + ? regs.depth_buffer.stencil_info.format + : AmdGpu::DepthBuffer::StencilFormat::Invalid; + key.depth_clamp_enable = !regs.depth_render_override.disable_viewport_clamp; + key.depth_clip_enable = regs.clipper_control.ZclipEnable(); + key.clip_space = regs.clipper_control.clip_space; + key.provoking_vtx_last = regs.polygon_control.provoking_vtx_last; + key.prim_type = regs.primitive_type; + key.polygon_mode = regs.polygon_control.PolyMode(); + key.patch_control_points = + regs.stage_enable.hs_en ? regs.ls_hs_config.hs_input_control_points : 0; + key.logic_op = regs.color_control.rop3; + key.depth_samples = db_enabled ? regs.depth_buffer.NumSamples() : 1; + key.num_samples = key.depth_samples; + key.cb_shader_mask = regs.color_shader_mask; + + const bool skip_cb_binding = + regs.color_control.mode == AmdGpu::ColorControl::OperationMode::Disable; + + // First pass to fill render target information needed by shader recompiler + for (s32 cb = 0; cb < AmdGpu::NUM_COLOR_BUFFERS && !skip_cb_binding; ++cb) { + const auto& col_buf = regs.color_buffers[cb]; + if (!col_buf || !regs.color_target_mask.GetMask(cb)) { + // No attachment bound or writing to it is disabled. + continue; + } + + // Fill color target information + auto& color_buffer = key.color_buffers[cb]; + color_buffer.data_format = col_buf.GetDataFmt(); + color_buffer.num_format = col_buf.GetNumberFmt(); + color_buffer.num_conversion = col_buf.GetNumberConversion(); + color_buffer.export_format = regs.color_export_format.GetFormat(cb); + color_buffer.swizzle = col_buf.Swizzle(); + + const auto& bc = regs.blend_control[cb]; + color_buffer.blend_self_scale = + bc.enable && !col_buf.info.blend_bypass && + (bc.color_func == AmdGpu::BlendControl::BlendFunc::Min || + bc.color_func == AmdGpu::BlendControl::BlendFunc::Max) && + bc.color_src_factor == AmdGpu::BlendControl::BlendFactor::SrcColor && + bc.color_dst_factor == AmdGpu::BlendControl::BlendFactor::DstColor; + } + + // Compile and bind shader stages + if (!RefreshGraphicsStages()) { + return false; + } + + // Second pass to mask out render targets not written by shader and fill remaining info + u8 color_samples = 0; + bool all_color_samples_same = true; + for (s32 cb = 0; cb < key.num_color_attachments && !skip_cb_binding; ++cb) { + const auto& col_buf = regs.color_buffers[cb]; + const u32 target_mask = regs.color_target_mask.GetMask(cb); + if (!col_buf || !target_mask) { + continue; + } + if ((key.mrt_mask & (1u << cb)) == 0) { + std::memset(&key.color_buffers[cb], 0, sizeof(Shader::PsColorBuffer)); + continue; + } + + // Fill color blending information + if (regs.blend_control[cb].enable && !col_buf.info.blend_bypass) { + key.blend_controls[cb] = regs.blend_control[cb]; + } + + // Apply swizzle to target mask + key.write_masks[cb] = + vk::ColorComponentFlags{key.color_buffers[cb].swizzle.ApplyMask(target_mask)}; + + // Fill color samples + const u8 prev_color_samples = std::exchange(color_samples, col_buf.NumSamples()); + all_color_samples_same &= color_samples == prev_color_samples || prev_color_samples == 0; + key.color_samples[cb] = color_samples; + key.num_samples = std::max(key.num_samples, color_samples); + } + + // Force all color samples to match depth samples to avoid unsupported MSAA configuration + if (color_samples != 0) { + const bool depth_mismatch = db_enabled && color_samples != key.depth_samples; + if (!all_color_samples_same && !instance.IsMixedAnySamplesSupported() || + all_color_samples_same && depth_mismatch && !instance.IsMixedDepthSamplesSupported()) { + key.color_samples.fill(key.depth_samples); + key.num_samples = key.depth_samples; + } + } + + return true; +} + +bool PipelineCache::RefreshGraphicsStages() { + const auto& regs = liverpool->regs; + auto& key = graphics_key; + fetch_shader = std::nullopt; + + Shader::Backend::Bindings binding{}; + const auto bind_stage = [&](HwStage stage_in, SwStage stage_out) -> bool { + const auto stage_in_idx = static_cast(stage_in); + const auto stage_out_idx = static_cast(stage_out); + if (!regs.stage_enable.IsStageEnabled(stage_in_idx)) { + key.stage_hashes[stage_out_idx] = 0; + infos[stage_out_idx] = nullptr; + return false; + } + + const auto* pgm = regs.ProgramForStage(stage_in_idx); + if (!pgm || !pgm->Address()) { + key.stage_hashes[stage_out_idx] = 0; + infos[stage_out_idx] = nullptr; + return false; + } + + const auto params = AmdGpu::GetParams(*pgm); + std::optional fetch_shader_; + std::tie(infos[stage_out_idx], modules[stage_out_idx], fetch_shader_, + key.stage_hashes[stage_out_idx]) = + GetProgram(stage_in, stage_out, params, binding); + if (fetch_shader_) { + fetch_shader = fetch_shader_; + } + return true; + }; + + infos.fill(nullptr); + modules.fill(nullptr); + + bind_stage(HwStage::Fragment, SwStage::Fragment); + + const auto* fs_info = infos[static_cast(SwStage::Fragment)]; + key.mrt_mask = fs_info ? fs_info->mrt_mask : 0u; + key.num_color_attachments = std::bit_width(key.mrt_mask); + + switch (regs.stage_enable.raw) { + case AmdGpu::ShaderStageEnable::VgtStages::EsGs: + if (!instance.IsGeometryStageSupported()) { + LOG_WARNING(Render_Vulkan, "Geometry shader stage unsupported, skipping"); + return false; + } + if (regs.vgt_gs_mode.onchip || regs.vgt_strmout_config.raw) { + LOG_WARNING(Render_Vulkan, "Geometry shader features unsupported, skipping"); + return false; + } + if (!bind_stage(HwStage::Export, SwStage::Vertex)) { + return false; + } + if (!bind_stage(HwStage::Geometry, SwStage::Geometry)) { + return false; + } + break; + case AmdGpu::ShaderStageEnable::VgtStages::LsHs: + if (!instance.IsTessellationSupported()) { + return false; + } + if (!bind_stage(HwStage::Hull, SwStage::TessellationControl)) { + return false; + } + if (!bind_stage(HwStage::Vertex, SwStage::TessellationEval)) { + return false; + } + if (!bind_stage(HwStage::Local, SwStage::Vertex)) { + return false; + } + break; + case AmdGpu::ShaderStageEnable::VgtStages::LsHsEsGs: + if (!instance.IsTessellationSupported()) { + return false; + } + if (!instance.IsGeometryStageSupported()) { + LOG_WARNING(Render_Vulkan, "Geometry shader stage unsupported, skipping"); + return false; + } + if (regs.vgt_gs_mode.onchip || regs.vgt_strmout_config.raw) { + LOG_WARNING(Render_Vulkan, "Geometry shader features unsupported, skipping"); + return false; + } + if (!bind_stage(HwStage::Hull, SwStage::TessellationControl)) { + return false; + } + if (!bind_stage(HwStage::Export, SwStage::TessellationEval)) { + return false; + } + if (!bind_stage(HwStage::Local, SwStage::Vertex)) { + return false; + } + if (!bind_stage(HwStage::Geometry, SwStage::Geometry)) { + return false; + } + break; + case AmdGpu::ShaderStageEnable::VgtStages::Vs: + bind_stage(HwStage::Vertex, SwStage::Vertex); + break; + default: + LOG_WARNING(Render_Vulkan, "unimplemented shader stage {}", (u32)regs.stage_enable.raw); + return false; + } + + const auto* vs_info = infos[static_cast(SwStage::Vertex)]; + if (vs_info && fetch_shader && !instance.IsVertexInputDynamicState()) { + // Without vertex input dynamic state, the pipeline needs to specialize on format. + // Stride will still be handled outside the pipeline using dynamic state. + u32 vertex_binding = 0; + for (const auto& attrib : fetch_shader->attributes) { + const auto& buffer = attrib.GetSharp(*vs_info); + ASSERT_MSG(vertex_binding < MaxVertexBufferCount, + "Vertex attribute binding count exceeded limit: {} >= {}", vertex_binding, + MaxVertexBufferCount); + key.vertex_buffer_formats[vertex_binding++] = + Vulkan::LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt()); + } + } + + return true; +} + +bool PipelineCache::RefreshComputeKey() { + Shader::Backend::Bindings binding{}; + const auto& cs_pgm = liverpool->GetCsRegs(); + const auto cs_params = AmdGpu::GetParams(cs_pgm); + std::tie(infos[0], modules[0], fetch_shader, compute_key.value) = + GetProgram(HwStage::Compute, SwStage::Compute, cs_params, binding); + return true; +} + +vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::RuntimeInfo& runtime_info, + const std::span& code, size_t perm_idx, + Shader::Backend::Bindings& binding) { + LOG_INFO(Render_Vulkan, "Compiling {} shader {:#x} {}", info.hw_stage, info.pgm_hash, + perm_idx != 0 ? "(permutation)" : ""); + DumpShader(code, info.pgm_hash, info.hw_stage, perm_idx, "bin"); + CompileTimer timer; + + const auto ir_program = Shader::TranslateProgram(code, pools, info, runtime_info, profile); + auto spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding); + DumpShader(spv, info.pgm_hash, info.hw_stage, perm_idx, "spv"); + + vk::ShaderModule module; + + auto patch = GetShaderPatch(info.pgm_hash, info.hw_stage, perm_idx, "spv"); + const bool is_patched = patch && EmulatorSettings.IsPatchShaders(); + if (is_patched) { + LOG_INFO(Loader, "Loaded patch for {} shader {:#x}", info.hw_stage, info.pgm_hash); + module = CompileSPV(*patch, instance.GetDevice()); + } else { + module = CompileSPV(spv, instance.GetDevice()); + } + + RegisterShaderBinary(std::move(spv), info.pgm_hash, perm_idx); + + const auto name = GetShaderName(info.hw_stage, info.pgm_hash, perm_idx); + Vulkan::SetObjectName(instance.GetDevice(), module, name); + if (EmulatorSettings.IsShaderCollect()) { + DebugState.CollectShader(name, info.sw_stage, module, spv, code, + patch ? *patch : std::span{}, is_patched); + } + return module; +} + +PipelineCache::Result PipelineCache::GetProgram(HwStage hw_stage, SwStage sw_stage, + const Shader::ShaderParams& params, + Shader::Backend::Bindings& binding) { + auto runtime_info = BuildRuntimeInfo(hw_stage, sw_stage); + auto [it_pgm, new_program] = program_cache.try_emplace(params.hash); + if (new_program) { + it_pgm.value() = std::make_unique(hw_stage, sw_stage, params); + auto& program = it_pgm.value(); + auto start = binding; + const auto module = CompileModule(program->info, runtime_info, params.code, 0, binding); + auto spec = Shader::StageSpecialization(program->info, runtime_info, profile, start); + const auto perm_hash = HashCombine(params.hash, 0); + + RegisterShaderMeta(program->info, spec.fetch_shader_data, spec, perm_hash, 0); + program->AddPermut(module, std::move(spec)); + return std::make_tuple(&program->info, module, program->modules[0].spec.fetch_shader_data, + perm_hash); + } + + auto& program = it_pgm.value(); + auto& info = program->info; + info.pgm_base = params.Base(); // Needs to be actualized for inline cbuffer address fixup + info.user_data = params.user_data; + info.RefreshFlatBuf(); + auto spec = Shader::StageSpecialization(info, runtime_info, profile, binding); + + size_t perm_idx = program->modules.size(); + u64 perm_hash = HashCombine(params.hash, perm_idx); + + vk::ShaderModule module{}; + + const auto it = std::ranges::find(program->modules, spec, &Program::Module::spec); + if (it == program->modules.end()) { + auto new_info = Shader::Info(hw_stage, sw_stage, params); + module = CompileModule(new_info, runtime_info, params.code, perm_idx, binding); + + RegisterShaderMeta(info, spec.fetch_shader_data, spec, perm_hash, perm_idx); + program->AddPermut(module, std::move(spec)); + } else { + info.AddBindings(binding); + module = it->module; + perm_idx = std::distance(program->modules.begin(), it); + perm_hash = HashCombine(params.hash, perm_idx); + } + return std::make_tuple(&program->info, module, + program->modules[perm_idx].spec.fetch_shader_data, perm_hash); +} + +std::optional PipelineCache::ReplaceShader(vk::ShaderModule module, + std::span spv_code) { + std::optional new_module{}; + for (const auto& [_, program] : program_cache) { + for (auto& m : program->modules) { + if (m.module == module) { + const auto& d = instance.GetDevice(); + d.destroyShaderModule(m.module); + m.module = CompileSPV(spv_code, d); + new_module = m.module; + } + } + } + if (module_related_pipelines.contains(module)) { + auto& pipeline_keys = module_related_pipelines[module]; + for (auto& key : pipeline_keys) { + if (std::holds_alternative(key)) { + auto& graphics_key = std::get(key); + graphics_pipelines.erase(graphics_key); + } else if (std::holds_alternative(key)) { + auto& compute_key = std::get(key); + compute_pipelines.erase(compute_key); + } + } + } + return new_module; +} + +std::string PipelineCache::GetShaderName(Shader::HwStage stage, u64 hash, + std::optional perm) { + if (perm) { + return fmt::format("{}_{:#018x}_{}", stage, hash, *perm); + } + return fmt::format("{}_{:#018x}", stage, hash); +} + +void PipelineCache::DumpShader(std::span code, u64 hash, Shader::HwStage stage, + size_t perm_idx, std::string_view ext) { + if (!EmulatorSettings.IsDumpShaders()) { + return; + } + + using namespace Common::FS; + const auto dump_dir = GetUserPath(PathType::ShaderDir) / "dumps"; + if (!std::filesystem::exists(dump_dir)) { + std::filesystem::create_directories(dump_dir); + } + const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext); + const auto file = IOFile{dump_dir / filename, FileAccessMode::Create}; + file.WriteSpan(code); +} + +std::optional> PipelineCache::GetShaderPatch(u64 hash, Shader::HwStage stage, + size_t perm_idx, + std::string_view ext) { + + using namespace Common::FS; + const auto patch_dir = GetUserPath(PathType::ShaderDir) / "patch"; + if (!std::filesystem::exists(patch_dir)) { + std::filesystem::create_directories(patch_dir); + } + const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext); + const auto filepath = patch_dir / filename; + if (!std::filesystem::exists(filepath)) { + return {}; + } + const auto file = IOFile{patch_dir / filename, FileAccessMode::Read}; + std::vector code(file.GetSize() / sizeof(u32)); + file.Read(code); + return code; +} +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_cache.h b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_cache.h new file mode 100644 index 0000000..da18ba4 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -0,0 +1,148 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "shader_recompiler/profile.h" +#include "shader_recompiler/recompiler.h" +#include "shader_recompiler/specialization.h" +#include "video_core/renderer_vulkan/vk_compute_pipeline.h" +#include "video_core/renderer_vulkan/vk_graphics_pipeline.h" +#include "video_core/renderer_vulkan/vk_resource_pool.h" + +template <> +struct std::hash { + std::size_t operator()(const vk::ShaderModule& module) const noexcept { + return std::hash{}(reinterpret_cast((VkShaderModule)module)); + } +}; + +namespace AmdGpu { +class Liverpool; +} + +namespace Serialization { +struct Archive; +} + +namespace Shader { +struct Info; +} + +namespace Vulkan { + +class Instance; +class Scheduler; +class ShaderCache; + +struct Program { + struct Module { + vk::ShaderModule module; + Shader::StageSpecialization spec; + }; + static constexpr size_t MaxPermutations = 8; + using ModuleList = boost::container::small_vector; + + Shader::Info info; + ModuleList modules{}; + + Program() = default; + Program(Shader::HwStage stage, Shader::SwStage l_stage, Shader::ShaderParams params) + : info{stage, l_stage, params} {} + + void AddPermut(vk::ShaderModule module, Shader::StageSpecialization&& spec) { + modules.emplace_back(module, std::move(spec)); + } + + void InsertPermut(vk::ShaderModule module, Shader::StageSpecialization&& spec, + size_t perm_idx) { + modules.resize(std::max(modules.size(), perm_idx + 1)); // <-- beware of realloc + modules[perm_idx] = {module, std::move(spec)}; + } +}; + +struct DrawIndirectParams { + u16 vertex_sgpr_offset; + u32 instance_sgpr_offset; +}; + +class PipelineCache { +public: + explicit PipelineCache(const Instance& instance, Scheduler& scheduler, + AmdGpu::Liverpool* liverpool, u32 sparse_page_shift); + ~PipelineCache(); + + void WarmUp(); + void Sync(); + + bool LoadComputePipeline(Serialization::Archive& ar); + bool LoadGraphicsPipeline(Serialization::Archive& ar); + bool LoadPipelineStage(Serialization::Archive& ar, size_t stage); + + const GraphicsPipeline* GetGraphicsPipeline(const DrawIndirectParams params = {}); + + const ComputePipeline* GetComputePipeline(); + + using Result = std::tuple, u64>; + Result GetProgram(Shader::HwStage stage, Shader::SwStage l_stage, + const Shader::ShaderParams& params, Shader::Backend::Bindings& binding); + + std::optional ReplaceShader(vk::ShaderModule module, + std::span spv_code); + + static std::string GetShaderName(Shader::HwStage stage, u64 hash, + std::optional perm = {}); + + auto& GetProfile() const { + return profile; + } + +private: + bool RefreshGraphicsKey(); + bool RefreshGraphicsStages(); + bool RefreshComputeKey(); + + void DumpShader(std::span code, u64 hash, Shader::HwStage stage, size_t perm_idx, + std::string_view ext); + std::optional> GetShaderPatch(u64 hash, Shader::HwStage stage, size_t perm_idx, + std::string_view ext); + vk::ShaderModule CompileModule(Shader::Info& info, Shader::RuntimeInfo& runtime_info, + const std::span& code, size_t perm_idx, + Shader::Backend::Bindings& binding); + const Shader::RuntimeInfo& BuildRuntimeInfo(Shader::HwStage stage, Shader::SwStage l_stage); + + [[nodiscard]] bool IsPipelineCacheDirty() const { + return num_new_pipelines > 0; + } + +private: + const Instance& instance; + Scheduler& scheduler; + AmdGpu::Liverpool* liverpool; + DescriptorHeap desc_heap; + vk::UniquePipelineCache pipeline_cache; + vk::UniquePipelineLayout pipeline_layout; + Shader::Profile profile{}; + Shader::Pools pools; + DrawIndirectParams draw_indirect_params{}; + tsl::robin_map> program_cache; + tsl::robin_map> compute_pipelines; + tsl::robin_map> graphics_pipelines; + std::array runtime_infos{}; + std::array infos{}; + std::array modules{}; + std::optional fetch_shader{}; + GraphicsPipelineKey graphics_key{}; + ComputePipelineKey compute_key{}; + u32 num_new_pipelines{}; // new pipelines added to the cache since the game start + + // Only if Config::collectShadersForDebug() + tsl::robin_map>> + module_related_pipelines; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_common.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_common.cpp new file mode 100644 index 0000000..3ae9fa0 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_common.cpp @@ -0,0 +1,122 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include +#include + +#include "shader_recompiler/resource.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_pipeline_cache.h" +#include "video_core/renderer_vulkan/vk_pipeline_common.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" + +namespace Vulkan { + +Pipeline::Pipeline(const Instance& instance_, Scheduler& scheduler_, DescriptorHeap& desc_heap_, + const Shader::Profile& profile_, vk::PipelineCache pipeline_cache, + bool is_compute_ /*= false*/) + : instance{instance_}, scheduler{scheduler_}, desc_heap{desc_heap_}, profile{profile_}, + is_compute{is_compute_} {} + +Pipeline::~Pipeline() = default; + +namespace { +// bbport: descriptor writes copied with the infos they point to, for deferred recording. +struct RecordedWrites { + boost::container::small_vector writes; + boost::container::small_vector buffers; + boost::container::small_vector images; + boost::container::small_vector views; + + explicit RecordedWrites(const Pipeline::DescriptorWrites& set_writes) { + writes.assign(set_writes.begin(), set_writes.end()); + for (const auto& write : set_writes) { + if (write.pBufferInfo) { + buffers.insert(buffers.end(), write.pBufferInfo, + write.pBufferInfo + write.descriptorCount); + } + if (write.pImageInfo) { + images.insert(images.end(), write.pImageInfo, + write.pImageInfo + write.descriptorCount); + } + if (write.pTexelBufferView) { + views.insert(views.end(), write.pTexelBufferView, + write.pTexelBufferView + write.descriptorCount); + } + } + } + + /// Points the writes at this object's copies; the object must not move afterwards. + std::span Resolve() { + size_t buffer = 0, image = 0, view = 0; + for (auto& write : writes) { + if (write.pBufferInfo) { + write.pBufferInfo = buffers.data() + buffer; + buffer += write.descriptorCount; + } + if (write.pImageInfo) { + write.pImageInfo = images.data() + image; + image += write.descriptorCount; + } + if (write.pTexelBufferView) { + write.pTexelBufferView = views.data() + view; + view += write.descriptorCount; + } + } + return writes; + } +}; +} // namespace + +void Pipeline::BindResources(DescriptorWrites& set_writes, + const Shader::PushData& push_data) const { + const auto bind_point = + IsCompute() ? vk::PipelineBindPoint::eCompute : vk::PipelineBindPoint::eGraphics; + const auto stage_flags = IsCompute() ? vk::ShaderStageFlagBits::eCompute : AllGraphicsStageBits; + const vk::PipelineLayout layout = *pipeline_layout; + scheduler.Record([layout, stage_flags, push_data](vk::CommandBuffer cmdbuf) { + cmdbuf.pushConstants(layout, stage_flags, 0u, sizeof(push_data), &push_data); + }); + + // Bind descriptor set. + if (set_writes.empty()) { + return; + } + + if (uses_push_descriptors) { + scheduler.Record([bind_point, layout, recorded = RecordedWrites{set_writes}]( + vk::CommandBuffer cmdbuf) mutable { + cmdbuf.pushDescriptorSetKHR(bind_point, layout, 0, recorded.Resolve()); + }); + return; + } + + // Descriptor set updates are device calls: they stay on this thread. + const auto desc_set = desc_heap.Commit(*desc_layout); + for (auto& set_write : set_writes) { + set_write.dstSet = desc_set; + } + instance.GetDevice().updateDescriptorSets(set_writes, {}); + scheduler.Record([bind_point, layout, desc_set](vk::CommandBuffer cmdbuf) { + cmdbuf.bindDescriptorSets(bind_point, layout, 0, desc_set, {}); + }); +} + +std::string Pipeline::GetDebugString() const { + std::string stage_desc; + for (const auto& stage : stages) { + if (stage) { + const auto shader_name = PipelineCache::GetShaderName(stage->hw_stage, stage->pgm_hash); + if (stage_desc.empty()) { + stage_desc = shader_name; + } else { + stage_desc = fmt::format("{},{}", stage_desc, shader_name); + } + } + } + return stage_desc; +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_common.h b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_common.h new file mode 100644 index 0000000..00ca80c --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_common.h @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/profile.h" +#include "shader_recompiler/runtime_info.h" +#include "video_core/renderer_vulkan/vk_common.h" + +#include + +namespace Shader { +struct Info; +struct PushData; +} // namespace Shader + +namespace Vulkan { + +static constexpr auto AllGraphicsStageBits = + vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eTessellationControl | + vk::ShaderStageFlagBits::eTessellationEvaluation | vk::ShaderStageFlagBits::eGeometry | + vk::ShaderStageFlagBits::eFragment; + +class Instance; +class Scheduler; +class DescriptorHeap; + +class Pipeline { +public: + Pipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap, + const Shader::Profile& profile, vk::PipelineCache pipeline_cache, + bool is_compute = false); + virtual ~Pipeline(); + + vk::Pipeline Handle() const noexcept { + return *pipeline; + } + + vk::PipelineLayout GetLayout() const noexcept { + return *pipeline_layout; + } + + auto GetStages() const { + static_assert(static_cast(Shader::SwStage::Compute) == Shader::MaxStageTypes - 1); + if (is_compute) { + return std::span{stages.cend() - 1, stages.cend()}; + } else { + return std::span{stages.cbegin(), stages.cend() - 1}; + } + } + + const Shader::Info& GetStage(Shader::SwStage stage) const noexcept { + return *stages[u32(stage)]; + } + + bool IsCompute() const { + return is_compute; + } + + using DescriptorWrites = std::vector; + void BindResources(DescriptorWrites& set_writes, const Shader::PushData& push_data) const; + +protected: + [[nodiscard]] std::string GetDebugString() const; + + const Instance& instance; + Scheduler& scheduler; + DescriptorHeap& desc_heap; + const Shader::Profile& profile; + vk::UniquePipeline pipeline; + vk::UniquePipelineLayout pipeline_layout; + vk::UniqueDescriptorSetLayout desc_layout; + std::array stages{}; + bool uses_push_descriptors{}; + bool is_compute; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_serialization.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_serialization.cpp new file mode 100644 index 0000000..2c6fc3c --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_serialization.cpp @@ -0,0 +1,498 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/serdes.h" +#include "core/emulator_settings.h" +#include "shader_recompiler/frontend/fetch_shader.h" +#include "shader_recompiler/info.h" +#include "video_core/cache_storage.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_pipeline_cache.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +namespace Serialization { +/* You should increment versions below once corresponding serialization scheme is changed. */ +static constexpr u32 ShaderBinaryVersion = 5u; +static constexpr u32 ShaderMetaVersion = 5u; +static constexpr u32 PipelineKeyVersion = 3u; +} // namespace Serialization + +namespace Vulkan { + +void RegisterPipelineData(const ComputePipelineKey& key, + ComputePipeline::SerializationSupport& sdata) { + if (!Storage::DataBase::Instance().IsOpened()) { + return; + } + + Serialization::Archive ar{}; + Serialization::Writer pldata{ar}; + + pldata.Write(Serialization::PipelineKeyVersion); + pldata.Write(u32{1}); // compute + + key.Serialize(ar); + sdata.Serialize(ar); + + Storage::DataBase::Instance().Save(Storage::BlobType::PipelineKey, + fmt::format("c_{:#018x}", key.value), ar.TakeOff()); +} + +void RegisterPipelineData(const GraphicsPipelineKey& key, u64 hash, + GraphicsPipeline::SerializationSupport& sdata) { + if (!Storage::DataBase::Instance().IsOpened()) { + return; + } + + Serialization::Archive ar{}; + Serialization::Writer pldata{ar}; + + pldata.Write(Serialization::PipelineKeyVersion); + pldata.Write(u32{0}); // graphics + + key.Serialize(ar); + sdata.Serialize(ar); + + Storage::DataBase::Instance().Save(Storage::BlobType::PipelineKey, + fmt::format("g_{:#018x}", hash), ar.TakeOff()); +} + +void RegisterShaderMeta(const Shader::Info& info, + const std::optional& fetch_shader_data, + const Shader::StageSpecialization& spec, size_t perm_hash, + size_t perm_idx) { + if (!Storage::DataBase::Instance().IsOpened()) { + return; + } + + Serialization::Archive ar; + Serialization::Writer meta{ar}; + + meta.Write(Serialization::ShaderMetaVersion); + meta.Write(Serialization::ShaderBinaryVersion); + + meta.Write(perm_hash); + meta.Write(perm_idx); + + spec.Serialize(ar); + info.Serialize(ar); + + Storage::DataBase::Instance().Save(Storage::BlobType::ShaderMeta, + fmt::format("{:#018x}", perm_hash), ar.TakeOff()); +} + +void RegisterShaderBinary(std::vector&& spv, u64 pgm_hash, size_t perm_idx) { + if (!Storage::DataBase::Instance().IsOpened()) { + return; + } + + Storage::DataBase::Instance().Save(Storage::BlobType::ShaderBinary, + fmt::format("{:#018x}_{}", pgm_hash, perm_idx), + std::move(spv)); +} + +bool LoadShaderMeta(Serialization::Archive& ar, Shader::Info& info, + std::optional& fetch_shader_data, + Shader::StageSpecialization& spec, size_t& perm_idx) { + Serialization::Reader meta{ar}; + + u32 meta_version{}; + meta.Read(meta_version); + if (meta_version != Serialization::ShaderMetaVersion) { + return false; + } + + u32 binary_version{}; + meta.Read(binary_version); + if (binary_version != Serialization::ShaderBinaryVersion) { + return false; + } + + u64 perm_hash_ar{}; + meta.Read(perm_hash_ar); + meta.Read(perm_idx); + + spec.Deserialize(ar); + info.Deserialize(ar); + + fetch_shader_data = spec.fetch_shader_data; + return true; +} + +void ComputePipelineKey::Serialize(Serialization::Archive& ar) const { + Serialization::Writer key{ar}; + key.Write(value); +} + +bool ComputePipelineKey::Deserialize(Serialization::Archive& ar) { + Serialization::Reader key{ar}; + key.Read(value); + return true; +} + +void ComputePipeline::SerializationSupport::Serialize(Serialization::Archive& ar) const { + // Nothing here yet + return; +} + +bool ComputePipeline::SerializationSupport::Deserialize(Serialization::Archive& ar) { + // Nothing here yet + return true; +} + +bool PipelineCache::LoadComputePipeline(Serialization::Archive& ar) { + compute_key.Deserialize(ar); + + ComputePipeline::SerializationSupport sdata{}; + sdata.Deserialize(ar); + + std::vector meta_blob; + Storage::DataBase::Instance().Load(Storage::BlobType::ShaderMeta, + fmt::format("{:#018x}", compute_key.value), meta_blob); + if (meta_blob.empty()) { + return false; + } + + Serialization::Archive meta_ar{std::move(meta_blob)}; + + if (!LoadPipelineStage(meta_ar, 0)) { + return false; + } + + const auto [it, is_new] = compute_pipelines.try_emplace(compute_key); + ASSERT(is_new); + + it.value() = + std::make_unique(instance, scheduler, desc_heap, profile, *pipeline_cache, + compute_key, *infos[0], modules[0], sdata, true); + + infos.fill(nullptr); + modules.fill(nullptr); + + return true; +} + +void GraphicsPipelineKey::Serialize(Serialization::Archive& ar) const { + Serialization::Writer key{ar}; + + key.Write(this, sizeof(*this)); +} + +bool GraphicsPipelineKey::Deserialize(Serialization::Archive& ar) { + Serialization::Reader key{ar}; + + key.Read(this, sizeof(*this)); + return true; +} + +void GraphicsPipeline::SerializationSupport::Serialize(Serialization::Archive& ar) const { + Serialization::Writer sdata{ar}; + + sdata.Write(&vertex_attributes, sizeof(vertex_attributes)); + sdata.Write(&vertex_bindings, sizeof(vertex_bindings)); + sdata.Write(&divisors, sizeof(divisors)); + sdata.Write(multisampling); + sdata.Write(tcs); + sdata.Write(tes); +} + +bool GraphicsPipeline::SerializationSupport::Deserialize(Serialization::Archive& ar) { + Serialization::Reader sdata{ar}; + + sdata.Read(&vertex_attributes, sizeof(vertex_attributes)); + sdata.Read(&vertex_bindings, sizeof(vertex_bindings)); + sdata.Read(&divisors, sizeof(divisors)); + sdata.Read(multisampling); + sdata.Read(tcs); + sdata.Read(tes); + return true; +} + +bool PipelineCache::LoadGraphicsPipeline(Serialization::Archive& ar) { + graphics_key.Deserialize(ar); + + GraphicsPipeline::SerializationSupport sdata{}; + sdata.Deserialize(ar); + + for (int stage_idx = 0; stage_idx < MaxShaderStages; ++stage_idx) { + const auto& hash = graphics_key.stage_hashes[stage_idx]; + if (!hash) { + continue; + } + + std::vector meta_blob; + Storage::DataBase::Instance().Load(Storage::BlobType::ShaderMeta, + fmt::format("{:#018x}", hash), meta_blob); + if (meta_blob.empty()) { + return false; + } + + Serialization::Archive meta_ar{std::move(meta_blob)}; + + if (!LoadPipelineStage(meta_ar, stage_idx)) { + return false; + } + } + + const auto [it, is_new] = graphics_pipelines.try_emplace(graphics_key); + ASSERT(is_new); + + it.value() = std::make_unique( + instance, scheduler, desc_heap, profile, graphics_key, *pipeline_cache, infos, + runtime_infos, fetch_shader, modules, sdata, true); + + infos.fill(nullptr); + modules.fill(nullptr); + fetch_shader.reset(); + + return true; +} + +bool PipelineCache::LoadPipelineStage(Serialization::Archive& ar, size_t stage) { + auto program = std::make_unique(); + Shader::StageSpecialization spec{}; + spec.info = &program->info; + size_t perm_idx{}; + if (!LoadShaderMeta(ar, program->info, fetch_shader, spec, perm_idx)) { + return false; + } + + std::vector spv{}; + Storage::DataBase::Instance().Load(Storage::BlobType::ShaderBinary, + fmt::format("{:#018x}_{}", program->info.pgm_hash, perm_idx), + spv); + if (spv.empty()) { + return false; + } + + // Permutation hash depends on shader variation index. To prevent collisions, we need insert it + // at the exact position rather than append + + vk::ShaderModule module{}; + + auto [it_pgm, new_program] = program_cache.try_emplace(program->info.pgm_hash); + if (new_program) { + module = CompileSPV(spv, instance.GetDevice()); + it_pgm.value() = std::move(program); + } else { + const auto& it = std::ranges::find(it_pgm.value()->modules, spec, &Program::Module::spec); + if (it != it_pgm.value()->modules.end()) { + // A matching permutation is valid only at its original index. A different index means + // the store holds entries from more than one cache generation, so this pipeline is + // left to compile at runtime. + const auto idx = std::distance(it_pgm.value()->modules.begin(), it); + if (perm_idx != idx) { + LOG_WARNING(Render_Vulkan, + "Cached permutation {} of {}_{:x} conflicts with index {}, skipping " + "preload", + perm_idx, program->info.hw_stage, program->info.pgm_hash, idx); + return false; + } + module = it->module; + } else { + module = CompileSPV(spv, instance.GetDevice()); + } + } + it_pgm.value()->InsertPermut(module, std::move(spec), perm_idx); + + infos[stage] = &it_pgm.value()->info; + modules[stage] = module; + + return true; +} + +void PipelineCache::WarmUp() { + if (!EmulatorSettings.IsPipelineCacheEnabled()) { + return; + } + + Storage::DataBase::Instance().Open(); + + // Check if cache is compatible + std::vector profile_data{}; + Storage::DataBase::Instance().Load(Storage::BlobType::ShaderProfile, "profile", profile_data); + if (profile_data.empty()) { + Storage::DataBase::Instance().FinishPreload(); + + profile_data.resize(sizeof(profile)); + std::memcpy(profile_data.data(), &profile, sizeof(profile)); + Storage::DataBase::Instance().Save(Storage::BlobType::ShaderProfile, "profile", + std::move(profile_data)); + return; + } + if (profile_data.size() != sizeof(Shader::Profile)) { + LOG_WARNING(Render, + "Pipeline cache profile has unexpected size ({} != {}). Ignoring the cache", + profile_data.size(), sizeof(Shader::Profile)); + Storage::DataBase::Instance().Close(); + return; + } + + Shader::Profile cached_profile{}; + std::memcpy(&cached_profile, profile_data.data(), sizeof(cached_profile)); + if (cached_profile != profile) { + LOG_WARNING(Render, + "Pipeline cache isn't compatible with current system. Ignoring the cache"); + Storage::DataBase::Instance().Close(); + return; + } + + u32 num_pipelines{}; + u32 num_total_pipelines{}; + + Storage::DataBase::Instance().ForEachBlob( + Storage::BlobType::PipelineKey, [&](std::vector&& data) { + ++num_total_pipelines; + + Serialization::Archive ar{std::move(data)}; + Serialization::Reader pldata{ar}; + + u32 version{}; + pldata.Read(version); + if (version != Serialization::PipelineKeyVersion) { + return; + } + + u32 is_compute{}; + pldata.Read(is_compute); + + bool result{}; + if (is_compute) { + result = LoadComputePipeline(ar); + } else { + result = LoadGraphicsPipeline(ar); + } + + if (result) { + ++num_pipelines; + } + }); + + LOG_INFO(Render, "Preloaded {} pipelines", num_pipelines); + if (num_total_pipelines > num_pipelines) { + LOG_WARNING(Render, "{} stale pipelines were found. Consider re-generating the cache", + num_total_pipelines - num_pipelines); + } + + Storage::DataBase::Instance().FinishPreload(); +} + +void PipelineCache::Sync() { + Storage::DataBase::Instance().Close(); +} + +} // namespace Vulkan + +namespace Shader { + +void Info::Serialize(Serialization::Archive& ar) const { + Serialization::Writer info{ar}; + + info.Write(this, sizeof(InfoPersistent)); + info.Write(flattened_ud_buf); + srt_info.Serialize(ar); +} + +bool Info::Deserialize(Serialization::Archive& ar) { + Serialization::Reader info{ar}; + + info.Read(this, sizeof(Shader::InfoPersistent)); + info.Read(flattened_ud_buf); + + return srt_info.Deserialize(ar); +} + +void Gcn::FetchShaderData::Serialize(Serialization::Archive& ar) const { + Serialization::Writer fetch{ar}; + ar.Grow(6 + attributes.size() * sizeof(VertexAttribute)); + + fetch.Write(size); + fetch.Write(vertex_offset_sgpr); + fetch.Write(instance_offset_sgpr); + fetch.Write(attributes); +} + +bool Gcn::FetchShaderData::Deserialize(Serialization::Archive& ar) { + Serialization::Reader fetch{ar}; + + fetch.Read(size); + fetch.Read(vertex_offset_sgpr); + fetch.Read(instance_offset_sgpr); + fetch.Read(attributes); + + return true; +} + +void PersistentSrtInfo::Serialize(Serialization::Archive& ar) const { + Serialization::Writer srt{ar}; + + srt.Write(this, sizeof(*this)); + if (walker_func_size) { + srt.Write(reinterpret_cast(walker_func), walker_func_size); + } +} + +bool PersistentSrtInfo::Deserialize(Serialization::Archive& ar) { + Serialization::Reader srt{ar}; + + srt.Read(this, sizeof(*this)); + + if (walker_func_size) { + walker_func = RegisterWalkerCode(ar.CurrPtr(), walker_func_size); + ar.Advance(walker_func_size); + } + + return true; +} + +void StageSpecialization::Serialize(Serialization::Archive& ar) const { + Serialization::Writer spec{ar}; + + spec.Write(start); + spec.Write(runtime_info); + + spec.Write(bitset.to_string()); + + if (fetch_shader_data) { + spec.Write(sizeof(*fetch_shader_data)); + fetch_shader_data->Serialize(ar); + } else { + spec.Write(size_t{0}); + } + + spec.Write(vs_attribs); + spec.Write(buffers); + spec.Write(images); + spec.Write(fmasks); + spec.Write(samplers); +} + +bool StageSpecialization::Deserialize(Serialization::Archive& ar) { + Serialization::Reader spec{ar}; + + spec.Read(start); + spec.Read(runtime_info); + + std::string bits{}; + spec.Read(bits); + bitset = std::bitset(bits); + + u64 fetch_data_size{}; + spec.Read(fetch_data_size); + + if (fetch_data_size) { + Gcn::FetchShaderData fetch_data; + fetch_data.Deserialize(ar); + fetch_shader_data = fetch_data; + } + + spec.Read(vs_attribs); + spec.Read(buffers); + spec.Read(images); + spec.Read(fmasks); + spec.Read(samplers); + + return true; +} + +} // namespace Shader diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_serialization.h b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_serialization.h new file mode 100644 index 0000000..31ea4e3 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_pipeline_serialization.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "shader_recompiler/frontend/fetch_shader.h" +#include "video_core/renderer_vulkan/vk_pipeline_cache.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +namespace Vulkan { + +void RegisterPipelineData(const ComputePipelineKey& key, + ComputePipeline::SerializationSupport& sdata); +void RegisterPipelineData(const GraphicsPipelineKey& key, u64 hash, + GraphicsPipeline::SerializationSupport& sdata); +void RegisterShaderMeta(const Shader::Info& info, + const std::optional& fetch_shader_data, + const Shader::StageSpecialization& spec, size_t perm_hash, size_t perm_idx); +void RegisterShaderBinary(std::vector&& spv, u64 pgm_hash, size_t perm_idx); + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_platform.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_platform.cpp new file mode 100644 index 0000000..6b8f6b1 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_platform.cpp @@ -0,0 +1,442 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// Include the vulkan platform specific header +#if defined(ANDROID) +#define VK_USE_PLATFORM_ANDROID_KHR +#elif defined(_WIN64) +#define VK_USE_PLATFORM_WIN32_KHR +#elif defined(__APPLE__) +#define VK_USE_PLATFORM_METAL_EXT +#else +#define VK_USE_PLATFORM_WAYLAND_KHR +#define VK_USE_PLATFORM_XLIB_KHR +#endif + +#include +#include + +#include "common/assert.h" +#include "common/logging/log.h" +#include "common/path_util.h" +#include "core/emulator_settings.h" +#include "sdl_window.h" +#include "video_core/renderer_vulkan/vk_platform.h" + +#ifdef __APPLE__ +#include +#endif + +namespace Vulkan { + +static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation"; +static const char* const CRASH_DIAGNOSTIC_LAYER_NAME = "VK_LAYER_LUNARG_crash_diagnostic"; + +static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback( + vk::DebugUtilsMessageSeverityFlagBitsEXT severity, vk::DebugUtilsMessageTypeFlagsEXT type, + const vk::DebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) { + + spdlog::level level{}; + switch (severity) { + case vk::DebugUtilsMessageSeverityFlagBitsEXT::eError: + level = spdlog::level::err; + break; + case vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning: + level = spdlog::level::info; + break; + case vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo: + case vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose: + level = spdlog::level::debug; + break; + default: + level = spdlog::level::info; + } + + LOG_GENERIC(Common::Log::Class::Render_Vulkan, level, "{}: {}", + callback_data->pMessageIdName ? callback_data->pMessageIdName : "", + callback_data->pMessage ? callback_data->pMessage : ""); + + return VK_FALSE; +} + +vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window) { + const auto& window_info = emu_window.GetWindowInfo(); + vk::SurfaceKHR surface{}; + +#if defined(VK_USE_PLATFORM_WIN32_KHR) + if (window_info.type == Frontend::WindowSystemType::Windows) { + const vk::Win32SurfaceCreateInfoKHR win32_ci = { + .hinstance = nullptr, + .hwnd = static_cast(window_info.render_surface), + }; + + if (instance.createWin32SurfaceKHR(&win32_ci, nullptr, &surface) != vk::Result::eSuccess) { + LOG_CRITICAL(Render_Vulkan, "Failed to initialize Win32 surface"); + UNREACHABLE(); + } + } +#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR) + if (window_info.type == Frontend::WindowSystemType::X11) { + const vk::XlibSurfaceCreateInfoKHR xlib_ci = { + .dpy = static_cast(window_info.display_connection), + .window = reinterpret_cast(window_info.render_surface), + }; + + if (instance.createXlibSurfaceKHR(&xlib_ci, nullptr, &surface) != vk::Result::eSuccess) { + LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface"); + UNREACHABLE(); + } + } else if (window_info.type == Frontend::WindowSystemType::Wayland) { + if (EmulatorSettings.IsRenderdocEnabled()) { + LOG_ERROR(Render_Vulkan, + "RenderDoc is not compatible with Wayland, use an X11 window instead."); + } + + const vk::WaylandSurfaceCreateInfoKHR wayland_ci = { + .display = static_cast(window_info.display_connection), + .surface = static_cast(window_info.render_surface), + }; + + if (instance.createWaylandSurfaceKHR(&wayland_ci, nullptr, &surface) != + vk::Result::eSuccess) { + LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface"); + UNREACHABLE(); + } + } +#elif defined(VK_USE_PLATFORM_METAL_EXT) + if (window_info.type == Frontend::WindowSystemType::Metal) { + const vk::MetalSurfaceCreateInfoEXT macos_ci = { + .pLayer = static_cast(window_info.render_surface), + }; + + if (instance.createMetalSurfaceEXT(&macos_ci, nullptr, &surface) != vk::Result::eSuccess) { + LOG_CRITICAL(Render_Vulkan, "Failed to initialize MacOS surface"); + UNREACHABLE(); + } + } +#endif + + if (!surface) { + LOG_CRITICAL(Render_Vulkan, "Presentation not supported on this platform"); + UNREACHABLE(); + } + + return surface; +} + +static auto GetLayerExtensions(std::vector&& extensions, + const std::vector& layers) { + auto all_missing_vk_settings = true; + + for (const auto& layer_name : layers) { + const auto [layer_properties_result, layer_extensions] = + vk::enumerateInstanceExtensionProperties(std::string(layer_name)); + if (layer_properties_result != vk::Result::eSuccess) { + LOG_ERROR(Render_Vulkan, "Failed to query extension properties of {}: {}", layer_name, + vk::to_string(layer_properties_result)); + } + auto found = false; + for (const auto& extension : layer_extensions) { + if (extension.extensionName == std::string_view(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME)) { + found = true; + all_missing_vk_settings = false; + break; + } + } + if (!found) { + LOG_ERROR(Render_Vulkan, "Settings for layer {} not available.", layer_name); + } + } + + if (!all_missing_vk_settings) { + extensions.push_back(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME); + } + + return extensions; +} + +std::vector GetInstanceExtensions(Frontend::WindowSystemType window_type, + bool enable_debug_utils) { + const auto [properties_result, properties] = vk::enumerateInstanceExtensionProperties(); + if (properties_result != vk::Result::eSuccess || properties.empty()) { + LOG_ERROR(Render_Vulkan, "Failed to query extension properties: {}", + vk::to_string(properties_result)); + return {}; + } + + // Add the windowing system specific extension + std::vector extensions; + extensions.reserve(7); + + switch (window_type) { + case Frontend::WindowSystemType::Headless: + break; +#if defined(VK_USE_PLATFORM_WIN32_KHR) + case Frontend::WindowSystemType::Windows: + extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + break; +#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR) + case Frontend::WindowSystemType::X11: + extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); + break; + case Frontend::WindowSystemType::Wayland: + extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); + break; +#elif defined(VK_USE_PLATFORM_METAL_EXT) + case Frontend::WindowSystemType::Metal: + extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); + break; +#endif + default: + LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform"); + break; + } + + if (window_type != Frontend::WindowSystemType::Headless) { + extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + } + + if (EmulatorSettings.IsHdrAllowed()) { + extensions.push_back(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME); + } + + if (enable_debug_utils) { + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + } + + // Sanitize extension list + std::erase_if(extensions, [&](const char* extension) -> bool { + const auto it = + std::find_if(properties.begin(), properties.end(), [extension](const auto& prop) { + return std::strcmp(extension, prop.extensionName) == 0; + }); + + if (it == properties.end()) { + LOG_INFO(Render_Vulkan, "Candidate instance extension {} is not available", extension); + return true; + } + return false; + }); + + return extensions; +} + +std::vector GetInstanceLayers(bool enable_validation, bool enable_crash_diagnostic) { + const auto [properties_result, properties] = vk::enumerateInstanceLayerProperties(); + if (properties_result != vk::Result::eSuccess || properties.empty()) { + LOG_ERROR(Render_Vulkan, "Failed to query layer properties: {}", + vk::to_string(properties_result)); + return {}; + } + + std::vector layers; + layers.reserve(2); + + if (enable_validation) { + layers.push_back(VALIDATION_LAYER_NAME); + } + if (enable_crash_diagnostic) { + layers.push_back(CRASH_DIAGNOSTIC_LAYER_NAME); + } + + // Sanitize layer list + std::erase_if(layers, [&](const char* layer) -> bool { + const auto it = std::ranges::find_if(properties, [layer](const auto& prop) { + return std::strcmp(layer, prop.layerName) == 0; + }); + if (it == properties.end()) { + LOG_ERROR(Render_Vulkan, "Requested layer {} is not available", layer); + return true; + } + return false; + }); + + return layers; +} + +vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool enable_validation, + bool enable_crash_diagnostic) { + LOG_INFO(Render_Vulkan, "Creating vulkan instance"); + +#if defined(__APPLE__) + // Initialize the environment with the path to the included ICD, so that the loader will + // find it. + static const auto icd_path = [] { + char path[PATH_MAX]; + u32 length = PATH_MAX; + _NSGetExecutablePath(path, &length); + return std::filesystem::path(path).parent_path(); + }(); + setenv("VK_DRIVER_FILES", icd_path.c_str(), true); +#endif + + static vk::detail::DynamicLoader dl; + VULKAN_HPP_DEFAULT_DISPATCHER.init( + dl.getProcAddress("vkGetInstanceProcAddr")); + + const auto [available_version_result, available_version] = + VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumerateInstanceVersion + ? vk::enumerateInstanceVersion() + : vk::ResultValue(vk::Result::eSuccess, VK_API_VERSION_1_0); + ASSERT_MSG(available_version_result == vk::Result::eSuccess, + "Failed to query Vulkan API version: {}", vk::to_string(available_version_result)); + ASSERT_MSG(available_version >= TargetVulkanApiVersion, + "Vulkan {}.{} is required, but only {}.{} is supported by instance!", + VK_VERSION_MAJOR(TargetVulkanApiVersion), VK_VERSION_MINOR(TargetVulkanApiVersion), + VK_VERSION_MAJOR(available_version), VK_VERSION_MINOR(available_version)); + + const auto layers = GetInstanceLayers(enable_validation, enable_crash_diagnostic); + const auto extensions = GetLayerExtensions(GetInstanceExtensions(window_type, true), layers); + + const vk::ApplicationInfo application_info = { + .pApplicationName = "shadPS4", + .applicationVersion = VK_MAKE_VERSION(1, 0, 0), + .pEngineName = "shadPS4 Vulkan", + .engineVersion = VK_MAKE_VERSION(1, 0, 0), + .apiVersion = available_version, + }; + + const std::string extensions_string = fmt::format("{}", fmt::join(extensions, ", ")); + const std::string layers_string = fmt::format("{}", fmt::join(layers, ", ")); + LOG_INFO(Render_Vulkan, "Enabled instance extensions: {}", extensions_string); + LOG_INFO(Render_Vulkan, "Enabled instance layers: {}", layers_string); + + // Validation settings + vk::Bool32 enable_core = EmulatorSettings.IsVkValidationCoreEnabled() ? vk::True : vk::False; + vk::Bool32 enable_sync = EmulatorSettings.IsVkValidationSyncEnabled() ? vk::True : vk::False; + vk::Bool32 enable_gpuav = EmulatorSettings.IsVkValidationGpuEnabled() ? vk::True : vk::False; + + // Crash diagnostics settings + static const auto crash_diagnostic_path = + Common::FS::GetUserPathString(Common::FS::PathType::LogDir); + const char* log_path = crash_diagnostic_path.c_str(); + vk::Bool32 enable_force_barriers = vk::True; + + const std::array layer_setings = { + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "validate_core", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_core, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "validate_sync", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_sync, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "syncval_submit_time_validation", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_sync, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "gpuav_enable", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_gpuav, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "gpuav_descriptor_checks", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_gpuav, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "gpuav_buffers_validation", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_gpuav, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "gpuav_indirect_draws_buffers", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_gpuav, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "gpuav_indirect_dispatches_buffers", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_gpuav, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "gpuav_indirect_trace_rays_buffers", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_gpuav, + }, + vk::LayerSettingEXT{ + .pLayerName = VALIDATION_LAYER_NAME, + .pSettingName = "gpuav_buffer_copies", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_gpuav, + }, + vk::LayerSettingEXT{ + .pLayerName = "lunarg_crash_diagnostic", + .pSettingName = "output_path", + .type = vk::LayerSettingTypeEXT::eString, + .valueCount = 1, + .pValues = &log_path, + }, + vk::LayerSettingEXT{ + .pLayerName = "lunarg_crash_diagnostic", + .pSettingName = "sync_after_commands", + .type = vk::LayerSettingTypeEXT::eBool32, + .valueCount = 1, + .pValues = &enable_force_barriers, + }, + }; + + vk::StructureChain instance_ci_chain = { + vk::InstanceCreateInfo{ + .pApplicationInfo = &application_info, + .enabledLayerCount = static_cast(layers.size()), + .ppEnabledLayerNames = layers.data(), + .enabledExtensionCount = static_cast(extensions.size()), + .ppEnabledExtensionNames = extensions.data(), + }, + vk::LayerSettingsCreateInfoEXT{ + .settingCount = layer_setings.size(), + .pSettings = layer_setings.data(), + }, + }; + + auto [instance_result, instance] = vk::createInstanceUnique(instance_ci_chain.get()); + ASSERT_MSG(instance_result == vk::Result::eSuccess, "Failed to create instance: {}", + vk::to_string(instance_result)); + + VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance); + + return std::move(instance); +} + +vk::UniqueDebugUtilsMessengerEXT CreateDebugCallback(vk::Instance instance) { + const vk::DebugUtilsMessengerCreateInfoEXT msg_ci = { + .messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo | + vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | + vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | + vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose, + .messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | + vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation | + vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, + .pfnUserCallback = DebugUtilsCallback, + }; + auto [messenger_result, messenger] = instance.createDebugUtilsMessengerEXTUnique(msg_ci); + ASSERT_MSG(messenger_result == vk::Result::eSuccess, "Failed to create debug callback: {}", + vk::to_string(messenger_result)); + return std::move(messenger); +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_platform.h b/gpu/shadps4/video_core/renderer_vulkan/vk_platform.h new file mode 100644 index 0000000..b8f5f9f --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_platform.h @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/assert.h" +#include "common/logging/log.h" +#include "common/string_literal.h" +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Frontend { +enum class WindowSystemType : u8; +class WindowSDL; +} // namespace Frontend + +namespace Vulkan { + +constexpr u32 TargetVulkanApiVersion = VK_API_VERSION_1_3; + +vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window); + +vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool enable_validation, + bool enable_crash_diagnostic); + +vk::UniqueDebugUtilsMessengerEXT CreateDebugCallback(vk::Instance instance); + +template +concept VulkanHandleType = vk::isVulkanHandleType::value; + +template +void SetObjectName(vk::Device device, const HandleType& handle, std::string_view debug_name) { + const vk::DebugUtilsObjectNameInfoEXT name_info = { + .objectType = HandleType::objectType, + .objectHandle = reinterpret_cast(static_cast(handle)), + .pObjectName = debug_name.data(), + }; + auto result = device.setDebugUtilsObjectNameEXT(name_info); + if (result != vk::Result::eSuccess) { + LOG_DEBUG(Render_Vulkan, "Could not set object debug name: {}", vk::to_string(result)); + } +} + +template +void SetObjectName(vk::Device device, const HandleType& handle, const char* format, + const Args&... args) { + const std::string debug_name = fmt::vformat(format, fmt::make_format_args(args...)); + SetObjectName(device, handle, debug_name); +} + +template +static void Check(vk::Result r) { + if constexpr (msg.len <= 1) { + ASSERT_MSG(r == vk::Result::eSuccess, "vk::Result={}", vk::to_string(r)); + } else { + ASSERT_MSG(r == vk::Result::eSuccess, "Failed to {}: vk::Result={}", msg.value, + vk::to_string(r)); + } +} + +template +static T Check(vk::ResultValue r) { + if constexpr (msg.len <= 1) { + ASSERT_MSG(r.result == vk::Result::eSuccess, "vk::Result={}", vk::to_string(r.result)); + } else { + ASSERT_MSG(r.result == vk::Result::eSuccess, "Failed to {}: vk::Result={}", msg.value, + vk::to_string(r.result)); + } + return std::move(r.value); +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_presenter.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_presenter.cpp new file mode 100644 index 0000000..8863caa --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_presenter.cpp @@ -0,0 +1,651 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/debug.h" +#include "common/elf_info.h" +#include "common/io_file.h" +#include "common/path_util.h" +#include "common/singleton.h" +#include "core/debug_state.h" +#include "core/emulator_settings.h" +#include "sdl_window.h" +#include "video_core/buffer_cache/buffer.h" +#include "video_core/renderdoc.h" +#include "video_core/renderer_vulkan/vk_platform.h" +#include "video_core/renderer_vulkan/vk_presenter.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" +#include "video_core/texture_cache/image.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Vulkan { + +bool CanBlitToSwapchain(const vk::PhysicalDevice physical_device, vk::Format format) { + const vk::FormatProperties props{physical_device.getFormatProperties(format)}; + return static_cast(props.optimalTilingFeatures & vk::FormatFeatureFlagBits::eBlitDst); +} + +[[nodiscard]] vk::ImageSubresourceLayers MakeImageSubresourceLayers() { + return vk::ImageSubresourceLayers{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1, + }; +} + +[[nodiscard]] vk::ImageBlit MakeImageBlit(s32 frame_width, s32 frame_height, s32 dst_width, + s32 dst_height, s32 offset_x, s32 offset_y) { + return vk::ImageBlit{ + .srcSubresource = MakeImageSubresourceLayers(), + .srcOffsets = + std::array{ + vk::Offset3D{ + .x = 0, + .y = 0, + .z = 0, + }, + vk::Offset3D{ + .x = frame_width, + .y = frame_height, + .z = 1, + }, + }, + .dstSubresource = MakeImageSubresourceLayers(), + .dstOffsets = + std::array{ + vk::Offset3D{ + .x = offset_x, + .y = offset_y, + .z = 0, + }, + vk::Offset3D{ + .x = offset_x + dst_width, + .y = offset_y + dst_height, + .z = 1, + }, + }, + }; +} + +[[nodiscard]] vk::ImageBlit MakeImageBlitStretch(s32 frame_width, s32 frame_height, + s32 swapchain_width, s32 swapchain_height) { + return MakeImageBlit(frame_width, frame_height, swapchain_width, swapchain_height, 0, 0); +} + +static vk::Rect2D FitImage(s32 frame_width, s32 frame_height, s32 swapchain_width, + s32 swapchain_height) { + float frame_aspect = static_cast(frame_width) / frame_height; + float swapchain_aspect = static_cast(swapchain_width) / swapchain_height; + + u32 dst_width = swapchain_width; + u32 dst_height = swapchain_height; + + if (frame_aspect > swapchain_aspect) { + dst_height = static_cast(swapchain_width / frame_aspect); + } else { + dst_width = static_cast(swapchain_height * frame_aspect); + } + + const s32 offset_x = (swapchain_width - dst_width) / 2; + const s32 offset_y = (swapchain_height - dst_height) / 2; + + return vk::Rect2D{{offset_x, offset_y}, {dst_width, dst_height}}; +} + +[[nodiscard]] vk::ImageBlit MakeImageBlitFit(s32 frame_width, s32 frame_height, s32 swapchain_width, + s32 swapchain_height) { + const auto& dst_rect = FitImage(frame_width, frame_height, swapchain_width, swapchain_height); + + return MakeImageBlit(frame_width, frame_height, dst_rect.extent.width, dst_rect.extent.height, + dst_rect.offset.x, dst_rect.offset.y); +} + +// bbport: screenshot capture and ImGui overlays removed; the port presents directly. + +Presenter::Presenter(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_) + : window{window_}, liverpool{liverpool_}, + instance{window, EmulatorSettings.GetGpuId(), EmulatorSettings.IsVkValidationEnabled(), + EmulatorSettings.IsVkCrashDiagnosticEnabled()}, + draw_scheduler{instance, true}, present_scheduler{instance}, flip_scheduler{instance}, + swapchain{instance, window}, runtime{instance, draw_scheduler}, + rasterizer{std::make_unique(instance, draw_scheduler, runtime, liverpool)}, + texture_cache{rasterizer->GetTextureCache()} { + const u32 num_images = swapchain.GetImageCount(); + const vk::Device device = instance.GetDevice(); + + // Create presentation frames. + present_frames.resize(num_images); + for (u32 i = 0; i < num_images; i++) { + Frame& frame = present_frames[i]; + frame.id = i; + auto fence = Check<"create present done fence">( + device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled})); + frame.present_done = fence; + free_queue.push(&frame); + } + + fsr_settings.enable = EmulatorSettings.IsFsrEnabled(); + fsr_settings.use_rcas = EmulatorSettings.IsRcasEnabled(); + fsr_settings.rcas_attenuation = + static_cast(EmulatorSettings.GetRcasAttenuation() / 1000.f); + + fsr_pass.Create(device, instance.GetAllocator(), num_images); + pp_pass.Create(device, swapchain.GetSurfaceFormat().format); + +} + +Presenter::~Presenter() { + + draw_scheduler.Finish(); + present_scheduler.Finish(); + flip_scheduler.Finish(); + Check(draw_scheduler.CommandBuffer().reset()); + Check(present_scheduler.CommandBuffer().reset()); + Check(flip_scheduler.CommandBuffer().reset()); + + const vk::Device device = instance.GetDevice(); + for (auto& frame : present_frames) { + vmaDestroyImage(instance.GetAllocator(), frame.image, frame.allocation); + device.destroyImageView(frame.image_view); + device.destroyFence(frame.present_done); + } +} + +bool Presenter::IsVideoOutSurface(const AmdGpu::ColorBuffer& color_buffer) const { + return std::ranges::find(vo_buffers_addr, color_buffer.Address()) != vo_buffers_addr.cend(); +} + +void Presenter::RecreateFrame(Frame* frame, u32 width, u32 height) { + const vk::Device device = instance.GetDevice(); + if (frame->image_view) { + device.destroyImageView(frame->image_view); + } + if (frame->image) { + vmaDestroyImage(instance.GetAllocator(), frame->image, frame->allocation); + } + + const vk::Format format = swapchain.GetSurfaceFormat().format; + const vk::ImageCreateInfo image_info = { + .flags = vk::ImageCreateFlagBits::eMutableFormat, + .imageType = vk::ImageType::e2D, + .format = format, + .extent = {width, height, 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = vk::SampleCountFlagBits::e1, + .usage = vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst | + vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eSampled, + }; + + const VmaAllocationCreateInfo alloc_info = { + .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT, + .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + .requiredFlags = 0, + .preferredFlags = 0, + .pool = VK_NULL_HANDLE, + .pUserData = nullptr, + }; + + VkImage unsafe_image{}; + VkImageCreateInfo unsafe_image_info = static_cast(image_info); + + VkResult result = vmaCreateImage(instance.GetAllocator(), &unsafe_image_info, &alloc_info, + &unsafe_image, &frame->allocation, nullptr); + if (result != VK_SUCCESS) [[unlikely]] { + LOG_CRITICAL(Render_Vulkan, "Failed allocating texture with error {}", + vk::to_string(vk::Result{result})); + UNREACHABLE(); + } + frame->image = vk::Image{unsafe_image}; + SetObjectName(device, frame->image, "Frame image #{}", frame->id); + + const vk::ImageViewCreateInfo view_info = { + .image = frame->image, + .viewType = vk::ImageViewType::e2D, + .format = format, + .subresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; + auto view = Check<"create frame image view">(device.createImageView(view_info)); + frame->image_view = view; + frame->width = width; + frame->height = height; + + frame->is_hdr = swapchain.GetHDR(); +} + +Frame* Presenter::PrepareLastFrame() { + if (last_submit_frame == nullptr) { + return nullptr; + } + + Frame* frame = last_submit_frame; + + while (true) { + vk::Result result = instance.GetDevice().waitForFences(frame->present_done, false, + std::numeric_limits::max()); + if (result == vk::Result::eSuccess) { + break; + } + if (result == vk::Result::eTimeout) { + continue; + } + ASSERT_MSG(result != vk::Result::eErrorDeviceLost, + "Device lost during waiting for a frame"); + } + + auto& scheduler = flip_scheduler; + scheduler.EndRendering(); + const auto cmdbuf = scheduler.CommandBuffer(); + + const auto frame_subresources = vk::ImageSubresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }; + + const auto pre_barrier = + vk::ImageMemoryBarrier2{.srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .srcAccessMask = vk::AccessFlagBits2::eColorAttachmentRead, + .dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite, + .oldLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + .newLayout = vk::ImageLayout::eGeneral, + .image = frame->image, + .subresourceRange{frame_subresources}}; + + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .imageMemoryBarrierCount = 1, + .pImageMemoryBarriers = &pre_barrier, + }); + + // Flush frame creation commands. + frame->ready_semaphore = scheduler.GetWorkSemaphore()->Handle(); + frame->ready_tick = scheduler.CurrentTick(); + SubmitInfo info{}; + scheduler.Flush(info); + return frame; +} + +static vk::Format GetFrameViewFormat(const Libraries::VideoOut::PixelFormat format) { + switch (format) { + case Libraries::VideoOut::PixelFormat::A8B8G8R8Srgb: + return vk::Format::eR8G8B8A8Srgb; + case Libraries::VideoOut::PixelFormat::A8R8G8B8Srgb: + return vk::Format::eB8G8R8A8Srgb; + case Libraries::VideoOut::PixelFormat::A2R10G10B10: + case Libraries::VideoOut::PixelFormat::A2R10G10B10Srgb: + case Libraries::VideoOut::PixelFormat::A2R10G10B10Bt2020Pq: + return vk::Format::eA2R10G10B10UnormPack32; + default: + break; + } + UNREACHABLE_MSG("Unknown format={}", static_cast(format)); + return {}; +} + +Frame* Presenter::PrepareFrame(const Libraries::VideoOut::BufferAttributeGroup& attribute, + VAddr cpu_address) { + auto desc = VideoCore::TextureCache::ImageDesc{attribute, cpu_address}; + const auto image_id = texture_cache.FindImage(desc); + texture_cache.UpdateImage(image_id); + + Frame* frame = GetRenderFrame(); + + const auto frame_subresources = vk::ImageSubresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }; + + const auto pre_barrier = vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .srcAccessMask = vk::AccessFlagBits2::eColorAttachmentRead, + .dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite, + .oldLayout = vk::ImageLayout::eUndefined, + .newLayout = vk::ImageLayout::eColorAttachmentOptimal, + .image = frame->image, + .subresourceRange{frame_subresources}, + }; + + draw_scheduler.EndRendering(); + const auto cmdbuf = draw_scheduler.CommandBuffer(); + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .imageMemoryBarrierCount = 1, + .pImageMemoryBarriers = &pre_barrier, + }); + + VideoCore::ImageViewInfo view_info{}; + view_info.format = GetFrameViewFormat(attribute.attrib.pixel_format); + // Exclude alpha from output frame to avoid blending with UI. + view_info.mapping.a = vk::ComponentSwizzle::eOne; + + auto& image = texture_cache.GetImage(image_id); + auto image_view = *image.FindView(view_info).image_view; + const vk::Extent2D image_size = {image.info.size.width, image.info.size.height}; + expected_ratio = static_cast(image_size.width) / static_cast(image_size.height); + + // bbport: upscaler integration point: the guest VideoOut image enters host passes here. + // Continue with host-side passes that draw the displayed (scaled) frame. + + runtime.Transit(&image, vk::ImageLayout::eShaderReadOnlyOptimal, + vk::PipelineStageFlagBits2::eFragmentShader, vk::AccessFlagBits2::eShaderRead); + runtime.FlushBarriers(); + + image_view = fsr_pass.Render(cmdbuf, image_view, image_size, {frame->width, frame->height}, + fsr_settings, frame->is_hdr); + + // Vulkan has no sRGB variant of the 10-bit format, so an A2R10G10B10Srgb buffer reaches + // the post process pass still sRGB encoded and has to be decoded there instead. + pp_settings.srgb_input = + attribute.attrib.pixel_format == Libraries::VideoOut::PixelFormat::A2R10G10B10Srgb; + pp_pass.Render(cmdbuf, image_view, image_size, *frame, pp_settings); + + + + // Flush frame creation commands. + frame->ready_semaphore = draw_scheduler.GetWorkSemaphore()->Handle(); + frame->ready_tick = draw_scheduler.CurrentTick(); + SubmitInfo info{}; + draw_scheduler.Flush(info); + return frame; +} + +Frame* Presenter::PrepareBlankFrame(bool present_thread) { + // Request a free presentation frame. + Frame* frame = GetRenderFrame(); + + auto& scheduler = present_thread ? present_scheduler : draw_scheduler; + scheduler.EndRendering(); + + const auto cmdbuf = scheduler.CommandBuffer(); + + constexpr vk::ImageSubresourceRange simple_subresource = { + .aspectMask = vk::ImageAspectFlagBits::eColor, + .levelCount = 1, + .layerCount = 1, + }; + const auto pre_barrier = vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .srcAccessMask = vk::AccessFlagBits2::eColorAttachmentRead, + .dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite, + .oldLayout = vk::ImageLayout::eUndefined, + .newLayout = vk::ImageLayout::eColorAttachmentOptimal, + .image = frame->image, + .subresourceRange = simple_subresource, + }; + + const auto post_barrier = vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput, + .srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite, + .dstStageMask = vk::PipelineStageFlagBits2::eFragmentShader, + .dstAccessMask = vk::AccessFlagBits2::eShaderRead, + .oldLayout = vk::ImageLayout::eColorAttachmentOptimal, + .newLayout = vk::ImageLayout::eGeneral, + .image = frame->image, + .subresourceRange = simple_subresource, + }; + + const vk::RenderingAttachmentInfo attachment = { + .imageView = frame->image_view, + .imageLayout = vk::ImageLayout::eColorAttachmentOptimal, + .loadOp = vk::AttachmentLoadOp::eClear, + .storeOp = vk::AttachmentStoreOp::eStore, + }; + const vk::RenderingInfo rendering_info = { + .renderArea = + { + .extent = {frame->width, frame->height}, + }, + .layerCount = 1, + .colorAttachmentCount = 1u, + .pColorAttachments = &attachment, + }; + + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .imageMemoryBarrierCount = 1, + .pImageMemoryBarriers = &pre_barrier, + }); + + cmdbuf.beginRendering(rendering_info); + cmdbuf.endRendering(); + + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .imageMemoryBarrierCount = 1, + .pImageMemoryBarriers = &post_barrier, + }); + + // Flush frame creation commands. + frame->ready_semaphore = scheduler.GetWorkSemaphore()->Handle(); + frame->ready_tick = scheduler.CurrentTick(); + SubmitInfo info{}; + scheduler.Flush(info); + return frame; +} + +void Presenter::Present(Frame* frame, bool is_reusing_frame, bool is_game_frame) { + // Free the frame for reuse + const auto free_frame = [&] { + if (!is_reusing_frame) { + last_submit_frame = frame; + std::scoped_lock fl{free_mutex}; + free_queue.push(frame); + free_cv.notify_one(); + } + }; + + // Recreate the swapchain if the window was resized. + if (window.GetWidth() != swapchain.GetWidth() || window.GetHeight() != swapchain.GetHeight()) { + swapchain.Recreate(window.GetWidth(), window.GetHeight()); + } + + if (!swapchain.AcquireNextImage()) { + swapchain.Recreate(window.GetWidth(), window.GetHeight()); + if (!swapchain.AcquireNextImage()) { + // User resizes the window too fast and GPU can't keep up. Skip this frame. + LOG_WARNING(Render_Vulkan, "Skipping frame!"); + free_frame(); + return; + } + } + + // Reset fence for queue submission. Do it here instead of GetRenderFrame() because we may + // skip frame because of slow swapchain recreation. If a frame skip occurs, we skip signal + // the frame's present fence and future GetRenderFrame() call will hang waiting for this frame. + const auto reset_result = instance.GetDevice().resetFences(frame->present_done); + ASSERT_MSG(reset_result == vk::Result::eSuccess, + "Unexpected error resetting present done fence: {}", vk::to_string(reset_result)); + + // bbport: the game frame is blitted (letterboxed) straight into the swapchain image. + const vk::Image swapchain_image = swapchain.Image(); + auto& scheduler = present_scheduler; + const auto cmdbuf = scheduler.CommandBuffer(); + + if (EmulatorSettings.IsVkHostMarkersEnabled()) { + cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ + .pLabelName = "Present", + }); + } + + { + const vk::Extent2D extent = swapchain.GetExtent(); + SetExpectedGameSize(s32(extent.width), s32(extent.height)); + const vk::ImageSubresourceRange color_range{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }; + const std::array pre_barriers{ + vk::ImageMemoryBarrier{ + .srcAccessMask = vk::AccessFlagBits::eNone, + .dstAccessMask = vk::AccessFlagBits::eTransferWrite, + .oldLayout = vk::ImageLayout::eUndefined, + .newLayout = vk::ImageLayout::eTransferDstOptimal, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = swapchain_image, + .subresourceRange = color_range, + }, + vk::ImageMemoryBarrier{ + .srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite, + .dstAccessMask = vk::AccessFlagBits::eTransferRead, + .oldLayout = vk::ImageLayout::eGeneral, + .newLayout = vk::ImageLayout::eTransferSrcOptimal, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = frame->image, + .subresourceRange = color_range, + }, + }; + cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, + vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlagBits::eByRegion, + {}, {}, pre_barriers); + const vk::ClearColorValue black{std::array{0.0f, 0.0f, 0.0f, 1.0f}}; + cmdbuf.clearColorImage(swapchain_image, vk::ImageLayout::eTransferDstOptimal, black, color_range); + const vk::MemoryBarrier clear_done{ + .srcAccessMask = vk::AccessFlagBits::eTransferWrite, + .dstAccessMask = vk::AccessFlagBits::eTransferWrite, + }; + cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, + vk::DependencyFlagBits::eByRegion, clear_done, {}, {}); + cmdbuf.blitImage(frame->image, vk::ImageLayout::eTransferSrcOptimal, swapchain_image, + vk::ImageLayout::eTransferDstOptimal, + MakeImageBlitFit(frame->width, frame->height, extent.width, extent.height), + vk::Filter::eLinear); + const std::array post_barriers{ + vk::ImageMemoryBarrier{ + .srcAccessMask = vk::AccessFlagBits::eTransferWrite, + .dstAccessMask = vk::AccessFlagBits::eNone, + .oldLayout = vk::ImageLayout::eTransferDstOptimal, + .newLayout = vk::ImageLayout::ePresentSrcKHR, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = swapchain_image, + .subresourceRange = color_range, + }, + vk::ImageMemoryBarrier{ + .srcAccessMask = vk::AccessFlagBits::eTransferRead, + .dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite, + .oldLayout = vk::ImageLayout::eTransferSrcOptimal, + .newLayout = vk::ImageLayout::eGeneral, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = frame->image, + .subresourceRange = color_range, + }, + }; + cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, + vk::PipelineStageFlagBits::eAllCommands, + vk::DependencyFlagBits::eByRegion, {}, {}, post_barriers); + } + if (EmulatorSettings.IsVkHostMarkersEnabled()) { + cmdbuf.endDebugUtilsLabelEXT(); + } + + // Flush vulkan commands. + + SubmitInfo info{}; + info.AddWait(swapchain.GetImageAcquiredSemaphore()); + info.AddWait(frame->ready_semaphore, frame->ready_tick); + info.AddSignal(swapchain.GetPresentReadySemaphore()); + info.AddSignal(frame->present_done); + scheduler.Flush(info); + + // Present to swapchain. + { + std::scoped_lock submit_lock{Scheduler::submit_mutex}; + if (!swapchain.Present()) { + swapchain.Recreate(window.GetWidth(), window.GetHeight()); + } + } + + free_frame(); + if (!is_reusing_frame && is_game_frame) { + DebugState.IncFlipFrameNum(); + } +} + +Frame* Presenter::GetRenderFrame() { + // Wait for free presentation frames + Frame* frame; + { + std::unique_lock lock{free_mutex}; + free_cv.wait(lock, [this] { return !free_queue.empty(); }); + LOG_DEBUG(Render_Vulkan, "Got render frame, remaining {}", free_queue.size() - 1); + + // Take the frame from the queue + frame = free_queue.front(); + free_queue.pop(); + } + + const vk::Device device = instance.GetDevice(); + vk::Result result{}; + + const auto wait = [&]() { + result = device.waitForFences(frame->present_done, false, std::numeric_limits::max()); + return result; + }; + + // Wait for the presentation to be finished so all frame resources are free + while (wait() != vk::Result::eSuccess) { + ASSERT_MSG(result != vk::Result::eErrorDeviceLost, + "Device lost during waiting for a frame"); + // Retry if the waiting times out + if (result == vk::Result::eTimeout) { + continue; + } + } + + if (frame->width != expected_frame_width || frame->height != expected_frame_height || + frame->is_hdr != swapchain.GetHDR()) { + RecreateFrame(frame, expected_frame_width, expected_frame_height); + } + + return frame; +} + +void Presenter::SetExpectedGameSize(s32 width, s32 height) { + const float ratio = (float)width / (float)height; + + expected_frame_height = height; + expected_frame_width = width; + if (ratio > expected_ratio) { + expected_frame_width = static_cast(height * expected_ratio); + } else { + expected_frame_height = static_cast(width / expected_ratio); + } +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_presenter.h b/gpu/shadps4/video_core/renderer_vulkan/vk_presenter.h new file mode 100644 index 0000000..e897ff6 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_presenter.h @@ -0,0 +1,138 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "core/libraries/videoout/buffer.h" +#include "video_core/renderer_vulkan/host_passes/fsr_pass.h" +#include "video_core/renderer_vulkan/host_passes/pp_pass.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_swapchain.h" +#include "video_core/texture_cache/texture_cache.h" + +namespace Frontend { +class WindowSDL; +} + +namespace AmdGpu { +struct Liverpool; +} + +namespace Vulkan { + +struct Frame { + u32 width; + u32 height; + VmaAllocation allocation; + vk::Image image; + vk::ImageView image_view; + vk::Fence present_done; + vk::Semaphore ready_semaphore; + u64 ready_tick; + bool is_hdr{false}; + u8 id{}; + +}; + +enum SchedulerType { + Draw, + Present, + CpuFlip, +}; + +class Rasterizer; + +class Presenter { +public: + Presenter(Frontend::WindowSDL& window, AmdGpu::Liverpool* liverpool); + ~Presenter(); + + HostPasses::PostProcessingPass::Settings& GetPPSettingsRef() { + return pp_settings; + } + + HostPasses::FsrPass::Settings& GetFsrSettingsRef() { + return fsr_settings; + } + + Frontend::WindowSDL& GetWindow() const { + return window; + } + + Rasterizer& GetRasterizer() const { + return *rasterizer.get(); + } + + bool IsHDRSupported() const { + return swapchain.HasHDR(); + } + + void SetHDR(bool enable) { + if (!IsHDRSupported()) { + return; + } + swapchain.SetHDR(enable); + pp_settings.hdr = enable ? 1 : 0; + } + + VideoCore::Image& RegisterVideoOutSurface( + const Libraries::VideoOut::BufferAttributeGroup& attribute, VAddr cpu_address) { + vo_buffers_addr.emplace_back(cpu_address); + auto desc = VideoCore::TextureCache::ImageDesc{attribute, cpu_address}; + const auto image_id = texture_cache.FindImage(desc); + auto& image = texture_cache.GetImage(image_id); + image.usage.vo_surface = 1u; + return image; + } + + bool IsVideoOutSurface(const AmdGpu::ColorBuffer& color_buffer) const; + + Frame* PrepareFrame(const Libraries::VideoOut::BufferAttributeGroup& attribute, + VAddr cpu_address); + + Frame* PrepareBlankFrame(bool present_thread); + + void Present(Frame* frame, bool is_reusing_frame = false, bool is_game_frame = true); + Frame* PrepareLastFrame(); + +private: + Frame* GetRenderFrame(); + + void RecreateFrame(Frame* frame, u32 width, u32 height); + + void SetExpectedGameSize(s32 width, s32 height); + +private: + float expected_ratio{1920.0 / 1080.0f}; + u32 expected_frame_width{1920}; + u32 expected_frame_height{1080}; + + Frontend::WindowSDL& window; + Instance instance; + HostPasses::FsrPass fsr_pass; + HostPasses::FsrPass::Settings fsr_settings{}; + HostPasses::PostProcessingPass::Settings pp_settings{}; + HostPasses::PostProcessingPass pp_pass; + AmdGpu::Liverpool* liverpool; + Scheduler draw_scheduler; + Scheduler present_scheduler; + Scheduler flip_scheduler; + Swapchain swapchain; + Runtime runtime; + std::unique_ptr rasterizer; + VideoCore::TextureCache& texture_cache; + vk::UniqueCommandPool command_pool; + std::vector present_frames; + std::queue free_queue; + Frame* last_submit_frame; + std::mutex free_mutex; + std::condition_variable free_cv; + std::condition_variable_any frame_cv; + std::vector vo_buffers_addr; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_rasterizer.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_rasterizer.cpp new file mode 100644 index 0000000..c17ec11 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -0,0 +1,1640 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bbport_toggles.h" +#include "common/debug.h" +#include "core/debug_state.h" +#include "core/emulator_settings.h" +#include "core/memory.h" +#include "shader_recompiler/runtime_info.h" +#include "video_core/amdgpu/liverpool.h" +#include "video_core/buffer_cache/buffer.h" +#include "video_core/buffer_cache/buffer_cache.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_pipeline_cache.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_shader_hle.h" +#include "video_core/texture_cache/image_view.h" +#include "video_core/texture_cache/texture_cache.h" + +namespace Vulkan { + +static Shader::PushData MakeUserData(const AmdGpu::Regs& regs) { + // TODO(roamic): Add support for multiple viewports and geometry shaders when ViewportIndex + // is encountered and implemented in the recompiler. + Shader::PushData push_data{}; + push_data.xoffset = regs.viewport_control.xoffset_enable ? regs.viewports[0].xoffset : 0.f; + push_data.xscale = regs.viewport_control.xscale_enable ? regs.viewports[0].xscale : 1.f; + push_data.yoffset = regs.viewport_control.yoffset_enable ? regs.viewports[0].yoffset : 0.f; + push_data.yscale = regs.viewport_control.yscale_enable ? regs.viewports[0].yscale : 1.f; + return push_data; +} + +Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_, Runtime& runtime_, + AmdGpu::Liverpool* liverpool_) + : instance{instance_}, scheduler{scheduler_}, runtime{runtime_}, page_manager{this}, + buffer_cache{instance, scheduler, runtime, liverpool_, texture_cache, page_manager}, + texture_cache{instance, scheduler, runtime, liverpool_, buffer_cache, page_manager}, + liverpool{liverpool_}, memory{Core::Memory::Instance()}, + pipeline_cache{instance, scheduler, liverpool, buffer_cache.GetSparsePageShift()}, + host_markers_enabled{EmulatorSettings.IsVkHostMarkersEnabled()}, + guest_markers_enabled{EmulatorSettings.IsVkGuestMarkersEnabled()} { + if (!EmulatorSettings.IsNullGPU()) { + liverpool->BindRasterizer(this); + } + memory->SetRasterizer(this); + + scheduler.SetSubmitCallback([this](Vulkan::SubmitInfo& info) { + runtime.FlushBarriers(); + buffer_cache.SubmitPendingArenaBinds(info); + }); +} + +Rasterizer::~Rasterizer() = default; + +bool Rasterizer::FilterDraw() { + const auto& regs = liverpool->regs; + if (regs.color_control.mode == AmdGpu::ColorControl::OperationMode::EliminateFastClear) { + // Clears the render target if FCE is launched before any draws + EliminateFastClear(); + return false; + } + if (regs.color_control.mode == AmdGpu::ColorControl::OperationMode::FmaskDecompress) { + // TODO: check for a valid MRT1 to promote the draw to the resolve pass. + LOG_TRACE(Render_Vulkan, "FMask decompression pass skipped"); + ScopedMarkerInsert("FmaskDecompress"); + return false; + } + if (regs.color_control.mode == AmdGpu::ColorControl::OperationMode::Resolve) { + LOG_TRACE(Render_Vulkan, "Resolve pass"); + Resolve(); + return false; + } + if (regs.primitive_type == AmdGpu::PrimitiveType::None) { + LOG_TRACE(Render_Vulkan, "Primitive type 'None' skipped"); + ScopedMarkerInsert("PrimitiveTypeNone"); + return false; + } + + const bool cb_disabled = + regs.color_control.mode == AmdGpu::ColorControl::OperationMode::Disable; + const auto depth_copy = + regs.depth_render_override.force_z_dirty && regs.depth_render_override.force_z_valid && + regs.depth_buffer.DepthValid() && regs.depth_buffer.DepthWriteValid() && + regs.depth_buffer.DepthAddress() != regs.depth_buffer.DepthWriteAddress(); + const auto stencil_copy = + regs.depth_render_override.force_stencil_dirty && + regs.depth_render_override.force_stencil_valid && regs.depth_buffer.StencilValid() && + regs.depth_buffer.StencilWriteValid() && + regs.depth_buffer.StencilAddress() != regs.depth_buffer.StencilWriteAddress(); + if (cb_disabled && (depth_copy || stencil_copy)) { + // Games may disable color buffer and enable force depth/stencil dirty and valid to + // do a copy from one depth-stencil surface to another, without a pixel shader. + // We need to detect this case and perform the copy, otherwise it will have no effect. + LOG_TRACE(Render_Vulkan, "Performing depth-stencil override copy"); + DepthStencilCopy(depth_copy, stencil_copy); + return false; + } + + return true; +} + +void Rasterizer::PrepareRenderState(const GraphicsPipeline* pipeline) { + // Prefetch render targets to handle overlaps with bound textures (e.g. mipgen) + const auto& key = pipeline->GetGraphicsKey(); + const auto& regs = liverpool->regs; + if (regs.color_control.degamma_enable) { + LOG_WARNING(Render_Vulkan, "Color buffers require gamma correction"); + } + + const bool skip_cb_binding = + regs.color_control.mode == AmdGpu::ColorControl::OperationMode::Disable; + for (s32 cb = 0; cb < std::bit_width(key.mrt_mask); ++cb) { + auto& [image_id, desc] = cb_descs[cb]; + const auto& col_buf = regs.color_buffers[cb]; + const u32 target_mask = regs.color_target_mask.GetMask(cb); + if (skip_cb_binding || !col_buf || !target_mask || (key.mrt_mask & (1 << cb)) == 0) { + image_id = {}; + continue; + } + const auto& hint = liverpool->last_cb_extent[cb]; + std::construct_at(&desc, col_buf, hint); + image_id = bound_images.emplace_back(texture_cache.FindImage(desc)); + auto& image = texture_cache.GetImage(image_id); + image.binding.is_target = 1u; + } + + if ((regs.depth_control.depth_enable && regs.depth_buffer.DepthValid()) || + (regs.depth_control.stencil_enable && regs.depth_buffer.StencilValid())) { + const auto htile_address = regs.depth_htile_data_base.GetAddress(); + const auto& hint = liverpool->last_db_extent; + auto& [image_id, desc] = db_desc; + std::construct_at(&desc, regs.depth_buffer, regs.depth_view, regs.depth_control, + htile_address, hint); + image_id = bound_images.emplace_back(texture_cache.FindImage(desc)); + auto& image = texture_cache.GetImage(image_id); + image.binding.is_target = 1u; + } else { + db_desc.first = {}; + } +} + +static std::pair GetDrawOffsets( + const AmdGpu::Regs& regs, const Shader::Info& info, + const std::optional& fetch_shader) { + u32 vertex_offset = regs.index_offset; + u32 instance_offset = 0; + if (fetch_shader) { + if (vertex_offset == 0 && fetch_shader->vertex_offset_sgpr != -1) { + vertex_offset = info.user_data[fetch_shader->vertex_offset_sgpr]; + } + if (fetch_shader->instance_offset_sgpr != -1) { + instance_offset = info.user_data[fetch_shader->instance_offset_sgpr]; + } + } + return {vertex_offset, instance_offset}; +} + +void Rasterizer::EliminateFastClear() { + auto& col_buf = liverpool->regs.color_buffers[0]; + if (!col_buf || !col_buf.info.fast_clear) { + return; + } + VideoCore::TextureCache::ImageDesc desc(col_buf, liverpool->last_cb_extent[0]); + const auto image_id = texture_cache.FindImage(desc); + const auto& image_view = texture_cache.FindRenderTarget(image_id, desc); + if (!texture_cache.IsMetaCleared(col_buf.CmaskAddress(), col_buf.view.slice_start)) { + return; + } + for (u32 slice = col_buf.view.slice_start; slice <= col_buf.view.slice_max; ++slice) { + texture_cache.TouchMeta(col_buf.CmaskAddress(), slice, false); + } + auto& image = texture_cache.GetImage(image_id); + const auto clear_value = LiverpoolToVK::ColorBufferClearValue(col_buf); + + ScopeMarkerBegin(fmt::format("EliminateFastClear:MRT={:#x}:M={:#x}", col_buf.Address(), + col_buf.CmaskAddress())); + runtime.ClearImage(&image, desc.view_info.range, clear_value); + ScopeMarkerEnd(); +} + +void Rasterizer::Draw(bool is_indexed, u32 index_offset) { + RENDERER_TRACE; + + scheduler.PopPendingOperations(); + + if (!FilterDraw()) { + return; + } + + const auto& regs = liverpool->regs; + const GraphicsPipeline* pipeline = pipeline_cache.GetGraphicsPipeline(); + if (!pipeline) { + return; + } + + PrepareRenderState(pipeline); + if (!BindResources(pipeline)) { + return; + } + const auto state = BeginRendering(pipeline); + + BindVertexBuffers(pipeline); + if (is_indexed) { + BindIndexBuffer(index_offset); + } + + if (needs_barrier) { + runtime.FlushBarriers(); + } + + pipeline->BindResources(set_writes, push_data); + UpdateDynamicState(pipeline, is_indexed); + scheduler.BeginRendering(state); + + const auto& vs_info = pipeline->GetStage(Shader::SwStage::Vertex); + const auto& fetch_shader = pipeline->GetFetchShader(); + const auto [vertex_offset, instance_offset] = GetDrawOffsets(regs, vs_info, fetch_shader); + + const vk::Pipeline handle = pipeline->Handle(); + const u32 num_indices = regs.num_indices; + const u32 num_instances = regs.num_instances.NumInstances(); + const u32 first_vertex = vertex_offset; + const u32 first_instance = instance_offset; + scheduler.Record([=](vk::CommandBuffer cmdbuf) { + cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, handle); + if (is_indexed) { + cmdbuf.drawIndexed(num_indices, num_instances, 0, s32(first_vertex), first_instance); + } else { + cmdbuf.draw(num_indices, num_instances, first_vertex, first_instance); + } + }); + DebugState.IncDrawCall(); + + ResetBindings(false); + scheduler.KickRecording(); +} + +void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u32 stride, + u32 max_count, VAddr count_address, u16 vertex_sgpr_offset, + u16 instance_sgpr_offset) { + RENDERER_TRACE; + + scheduler.PopPendingOperations(); + + if (!FilterDraw()) { + return; + } + + const DrawIndirectParams params = { + .vertex_sgpr_offset = vertex_sgpr_offset, + .instance_sgpr_offset = instance_sgpr_offset, + }; + const GraphicsPipeline* pipeline = pipeline_cache.GetGraphicsPipeline(params); + if (!pipeline) { + return; + } + + PrepareRenderState(pipeline); + if (!BindResources(pipeline)) { + return; + } + const auto state = BeginRendering(pipeline); + + BindVertexBuffers(pipeline); + if (is_indexed) { + BindIndexBuffer(); + } + + const auto [buffer, base] = + buffer_cache.ObtainBuffer(arg_address + offset, stride * max_count, false); + needs_barrier |= runtime.IsBufferAccessed(buffer, base, stride * max_count); + + const VideoCore::Buffer* count_buffer; + u64 count_offset; + if (count_address != 0) { + std::tie(count_buffer, count_offset) = buffer_cache.ObtainBuffer(count_address, 4, false); + needs_barrier |= runtime.IsBufferAccessed(count_buffer, count_offset, 4); + } + + if (needs_barrier) { + runtime.FlushBarriers(); + } + + pipeline->BindResources(set_writes, push_data); + UpdateDynamicState(pipeline, is_indexed); + scheduler.BeginRendering(state); + + ASSERT(stride == (is_indexed ? sizeof(VkDrawIndexedIndirectCommand) + : sizeof(VkDrawIndirectCommand))); + const vk::Pipeline handle = pipeline->Handle(); + const vk::Buffer args = buffer->Handle(); + const u64 args_offset = base; + const vk::Buffer counts = count_address != 0 ? count_buffer->Handle() : vk::Buffer{}; + const u64 counts_offset = count_address != 0 ? count_offset : 0; + scheduler.Record([=](vk::CommandBuffer cmdbuf) { + cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, handle); + if (is_indexed) { + if (counts) { + cmdbuf.drawIndexedIndirectCount(args, args_offset, counts, counts_offset, max_count, + stride); + } else { + cmdbuf.drawIndexedIndirect(args, args_offset, max_count, stride); + } + } else if (counts) { + cmdbuf.drawIndirectCount(args, args_offset, counts, counts_offset, max_count, stride); + } else { + cmdbuf.drawIndirect(args, args_offset, max_count, stride); + } + }); + DebugState.IncDrawCall(); + + ResetBindings(false); + scheduler.KickRecording(); +} + +void Rasterizer::DispatchDirect() { + RENDERER_TRACE; + + scheduler.PopPendingOperations(); + + const auto& cs_program = liverpool->GetCsRegs(); + const ComputePipeline* pipeline = pipeline_cache.GetComputePipeline(); + if (!pipeline) { + return; + } + + const auto& cs = pipeline->GetStage(Shader::SwStage::Compute); + if (ExecuteShaderHLE(cs, liverpool->regs, cs_program, *this)) { + return; + } + + if (!BindResources(pipeline)) { + return; + } + + if (needs_barrier) { + runtime.FlushBarriers(); + } + + scheduler.EndRendering(); + pipeline->BindResources(set_writes, push_data); + + const vk::Pipeline handle = pipeline->Handle(); + const u32 dim_x = cs_program.dim_x, dim_y = cs_program.dim_y, dim_z = cs_program.dim_z; + scheduler.Record([=](vk::CommandBuffer cmdbuf) { + cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, handle); + cmdbuf.dispatch(dim_x, dim_y, dim_z); + }); + DebugState.IncDispatch(); + + ResetBindings(true); + scheduler.KickRecording(); +} + +void Rasterizer::DispatchIndirect(VAddr address, u32 offset, u32 size) { + RENDERER_TRACE; + + scheduler.PopPendingOperations(); + + const auto& cs_program = liverpool->GetCsRegs(); + const ComputePipeline* pipeline = pipeline_cache.GetComputePipeline(); + if (!pipeline) { + return; + } + + if (!BindResources(pipeline)) { + return; + } + + const auto [buffer, base] = buffer_cache.ObtainBuffer(address + offset, size, false); + needs_barrier |= runtime.IsBufferAccessed(buffer, base, size); + + if (needs_barrier) { + runtime.FlushBarriers(); + } + + scheduler.EndRendering(); + pipeline->BindResources(set_writes, push_data); + + const vk::Pipeline handle = pipeline->Handle(); + const vk::Buffer args = buffer->Handle(); + const u64 args_offset = base; + scheduler.Record([=](vk::CommandBuffer cmdbuf) { + cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, handle); + cmdbuf.dispatchIndirect(args, args_offset); + }); + DebugState.IncDispatch(); + + ResetBindings(true); + scheduler.KickRecording(); +} + +u64 Rasterizer::Flush() { + const u64 current_tick = scheduler.CurrentTick(); + SubmitInfo info{}; + scheduler.Flush(info); + return current_tick; +} + +void Rasterizer::Finish() { + scheduler.Finish(); +} + +void Rasterizer::OnSubmit() { + if (fault_process_pending) { + fault_process_pending = false; + buffer_cache.ProcessFaultBuffer(); + } + texture_cache.ProcessDownloadImages(); + texture_cache.RunGarbageCollector(); + runtime.TickFrame(); +} + +bool Rasterizer::BindResources(const Pipeline* pipeline) { + if (IsComputeImageCopy(pipeline) || IsComputeMetaClear(pipeline) || + IsComputeImageClear(pipeline)) { + return false; + } + + set_write_index = 0; + set_writes.clear(); + buffer_infos.clear(); + image_infos.clear(); + + bool uses_dma = false; + + // Bind resource buffers and textures. + Shader::Backend::Bindings binding{}; + push_data = MakeUserData(liverpool->regs); + for (const auto* stage : pipeline->GetStages()) { + if (!stage) { + continue; + } + set_writes.resize(set_writes.size() + stage->buffers.size() + stage->images.size() + + stage->samplers.size()); + stage->PushUd(binding, push_data); + BindBuffers(*stage, binding, push_data); + BindTextures(*stage, binding); + uses_dma |= stage->uses_dma; + } + + if (uses_dma) { + buffer_cache.SynchronizeDmaBuffers(); + fault_process_pending = true; + } + + return true; +} + +void Rasterizer::BindVertexBuffers(const GraphicsPipeline* pipeline) { + const auto& regs = liverpool->regs; + VertexInputs attributes; + VertexInputs bindings; + VertexInputs divisors; + VertexInputs guest_buffers; + pipeline->GetVertexInputs(attributes, bindings, divisors, guest_buffers, + regs.vgt_instance_step_rate_0, regs.vgt_instance_step_rate_1); + + if (instance.IsVertexInputDynamicState()) { + // Update current vertex inputs. + scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) { + cmdbuf.setVertexInputEXT(bindings, attributes); + }); + } + + if (bindings.empty()) { + // If there are no bindings, there is nothing further to do. + return; + } + + struct BufferRange { + VAddr base_address; + VAddr end_address; + const VideoCore::Buffer* buffer; + u64 offset; + + [[nodiscard]] size_t GetSize() const { + return end_address - base_address; + } + }; + + // Build list of ranges covering the requested buffers + VertexInputs ranges{}; + for (const auto& buffer : guest_buffers) { + if (buffer.base_address != 0 && buffer.GetSize() > 0) { + ranges.emplace_back(buffer.base_address, buffer.base_address + buffer.GetSize()); + } + } + + // Merge connecting ranges together + VertexInputs ranges_merged{}; + if (!ranges.empty()) { + std::ranges::sort(ranges, [](const BufferRange& lhv, const BufferRange& rhv) { + return lhv.base_address < rhv.base_address; + }); + ranges_merged.emplace_back(ranges[0]); + for (auto range : ranges) { + auto& prev_range = ranges_merged.back(); + if (prev_range.end_address < range.base_address) { + ranges_merged.emplace_back(range); + } else { + prev_range.end_address = std::max(prev_range.end_address, range.end_address); + } + } + } + + // Map buffers for merged ranges + for (auto& range : ranges_merged) { + const u64 size = memory->ClampRangeSize(range.base_address, range.GetSize()); + std::tie(range.buffer, range.offset) = + buffer_cache.ObtainBuffer(range.base_address, size, false); + needs_barrier |= runtime.IsBufferAccessed(range.buffer, range.offset, size); + } + + // Bind vertex buffers + VertexInputs host_buffers; + VertexInputs host_offsets; + VertexInputs host_sizes; + VertexInputs host_strides; + for (const auto& buffer : guest_buffers) { + if (buffer.base_address != 0 && buffer.GetSize() > 0) { + const auto host_buffer_info = + std::ranges::find_if(ranges_merged, [&](const BufferRange& range) { + return buffer.base_address >= range.base_address && + buffer.base_address < range.end_address; + }); + ASSERT(host_buffer_info != ranges_merged.cend()); + host_buffers.emplace_back(host_buffer_info->buffer->Handle()); + host_offsets.push_back(host_buffer_info->offset + buffer.base_address - + host_buffer_info->base_address); + } else { + host_buffers.emplace_back(VK_NULL_HANDLE); + host_offsets.push_back(0); + } + host_sizes.push_back(buffer.GetSize()); + host_strides.push_back(buffer.GetStride()); + } + + const u32 num_buffers = static_cast(guest_buffers.size()); + const bool dynamic_input = instance.IsVertexInputDynamicState(); + scheduler.Record([=](vk::CommandBuffer cmdbuf) { + if (dynamic_input) { + cmdbuf.bindVertexBuffers(0, num_buffers, host_buffers.data(), host_offsets.data()); + } else { + cmdbuf.bindVertexBuffers2(0, num_buffers, host_buffers.data(), host_offsets.data(), + host_sizes.data(), host_strides.data()); + } + }); +} + +void Rasterizer::BindIndexBuffer(u32 index_offset) { + const auto& regs = liverpool->regs; + + // Figure out index type and size. + const bool is_index16 = regs.index_buffer_type.index_type == AmdGpu::IndexType::Index16; + const vk::IndexType index_type = is_index16 ? vk::IndexType::eUint16 : vk::IndexType::eUint32; + const u32 index_size = is_index16 ? sizeof(u16) : sizeof(u32); + const VAddr index_address = + regs.index_base_address.Address() + index_offset * index_size; + + // Bind index buffer. + const u32 index_buffer_size = regs.num_indices * index_size; + const auto [buffer, offset] = + buffer_cache.ObtainBuffer(index_address, index_buffer_size, false); + needs_barrier |= runtime.IsBufferAccessed(buffer, offset, index_buffer_size); + const vk::Buffer handle = buffer->Handle(); + const u64 handle_offset = offset; + scheduler.Record([=](vk::CommandBuffer cmdbuf) { + cmdbuf.bindIndexBuffer(handle, handle_offset, index_type); + }); +} + +void Rasterizer::ResetBindings(bool is_compute) { + for (auto& image_id : bound_images) { + texture_cache.GetImage(image_id).binding = {}; + } + for (const auto [buffer, offset, size, is_written] : bound_buffers) { + const auto dst_stage = is_compute ? vk::PipelineStageFlagBits2::eComputeShader + : vk::PipelineStageFlagBits2::eAllGraphics; + const auto write_flag = + is_written ? vk::AccessFlagBits2::eShaderWrite : vk::AccessFlagBits2::eNone; + runtime.AccessBuffer(buffer, offset, size, dst_stage, + vk::AccessFlagBits2::eShaderRead | write_flag); + } + bound_images.clear(); + bound_buffers.clear(); + needs_barrier = false; +} + +bool Rasterizer::IsComputeMetaClear(const Pipeline* pipeline) { + if (!pipeline->IsCompute()) { + return false; + } + + // Most of the time when a metadata is updated with a shader it gets cleared. It means + // we can skip the whole dispatch and update the tracked state instead. Also, it is not + // intended to be consumed and in such rare cases (e.g. HTile introspection, CRAA) we + // will need its full emulation anyways. + const auto& info = pipeline->GetStage(Shader::SwStage::Compute); + + // Assume if a shader reads metadata, it is a copy shader. + for (const auto& desc : info.buffers) { + const VAddr address = desc.GetSharp(info).base_address; + if (!desc.IsSpecial() && !desc.is_written && texture_cache.IsMeta(address)) { + return false; + } + } + + // Metadata surfaces are tiled and thus need address calculation to be written properly. + // If a shader wants to encode HTILE, for example, from a depth image it will have to compute + // proper tile address from dispatch invocation id. This address calculation contains an xor + // operation so use it as a heuristic for metadata writes that are probably not clears. + if (!info.has_bitwise_xor) { + // Assume if a shader writes metadata without address calculation, it is a clear shader. + for (const auto& desc : info.buffers) { + const VAddr address = desc.GetSharp(info).base_address; + if (!desc.IsSpecial() && desc.is_written && texture_cache.ClearMeta(address)) { + // Assume all slices were updates + LOG_TRACE(Render_Vulkan, "Metadata update skipped"); + return true; + } + } + } + return false; +} + +bool Rasterizer::IsComputeImageCopy(const Pipeline* pipeline) { + if (!pipeline->IsCompute()) { + return false; + } + + // Ensure shader only has 2 bound buffers + const auto& cs_pgm = liverpool->GetCsRegs(); + const auto& info = pipeline->GetStage(Shader::SwStage::Compute); + if (cs_pgm.num_thread_x.full != 64 || info.buffers.size() != 2 || !info.images.empty()) { + return false; + } + + // Those 2 buffers must both be formatted. One must be source and another destination. + const auto& desc0 = info.buffers[0]; + const auto& desc1 = info.buffers[1]; + if (!desc0.is_formatted || !desc1.is_formatted || desc0.is_written == desc1.is_written) { + return false; + } + + // Buffers must have the same size and each thread of the dispatch must copy 1 dword of data + const AmdGpu::Buffer buf0 = desc0.GetSharp(info); + const AmdGpu::Buffer buf1 = desc1.GetSharp(info); + if (buf0.GetSize() != buf1.GetSize() || cs_pgm.dim_x != (buf0.GetSize() / 256)) { + return false; + } + + // Find images the buffer alias + const auto image0_id = texture_cache.FindImageFromRange(buf0.base_address, buf0.GetSize()); + if (!image0_id) { + return false; + } + const auto image1_id = + texture_cache.FindImageFromRange(buf1.base_address, buf1.GetSize(), false); + if (!image1_id) { + return false; + } + + // Image copy must be valid + VideoCore::Image& image0 = texture_cache.GetImage(image0_id); + VideoCore::Image& image1 = texture_cache.GetImage(image1_id); + if (image0.info.guest_size != image1.info.guest_size || + image0.info.pitch != image1.info.pitch || image0.info.guest_size != buf0.GetSize() || + image0.info.num_bits != image1.info.num_bits) { + return false; + } + + // Perform image copy + VideoCore::Image& src_image = desc0.is_written ? image1 : image0; + VideoCore::Image& dst_image = desc0.is_written ? image0 : image1; + runtime.CopyColorAndDepth(&src_image, &dst_image); + return true; +} + +bool Rasterizer::IsComputeImageClear(const Pipeline* pipeline) { + if (!pipeline->IsCompute()) { + return false; + } + + // Ensure shader only has 2 bound buffers + const auto& cs_pgm = liverpool->GetCsRegs(); + const auto& info = pipeline->GetStage(Shader::SwStage::Compute); + if (cs_pgm.num_thread_x.full != 64 || info.buffers.size() != 2 || !info.images.empty()) { + return false; + } + + // From those 2 buffers, first must hold the clear vector and second the image being cleared + const auto& desc0 = info.buffers[0]; + const auto& desc1 = info.buffers[1]; + if (desc0.is_formatted || !desc1.is_formatted || desc0.is_written || !desc1.is_written) { + return false; + } + + // First buffer must have size of vec4 and second the size of a single layer + const AmdGpu::Buffer buf0 = desc0.GetSharp(info); + const AmdGpu::Buffer buf1 = desc1.GetSharp(info); + const u32 buf1_bpp = AmdGpu::NumBitsPerBlock(buf1.GetDataFmt()); + if (buf0.GetSize() != 16 || (cs_pgm.dim_x * 128ULL * (buf1_bpp / 8)) != buf1.GetSize()) { + return false; + } + + // Find image the buffer alias + const auto image1_id = + texture_cache.FindImageFromRange(buf1.base_address, buf1.GetSize(), false); + if (!image1_id) { + return false; + } + + // Image clear must be valid + VideoCore::Image& image1 = texture_cache.GetImage(image1_id); + if (image1.info.guest_size != buf1.GetSize() || image1.info.num_bits != buf1_bpp || + image1.info.props.is_depth) { + return false; + } + + // Perform image clear + const float* values = reinterpret_cast(buf0.base_address); + const vk::ClearValue clear = { + .color = {.float32 = std::array{values[0], values[1], values[2], values[3]}}, + }; + const VideoCore::SubresourceRange range = { + .base = + { + .level = 0, + .layer = 0, + }, + .extent = image1.info.resources, + }; + runtime.ClearImage(&image1, range, clear); + return true; +} + +void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Bindings& binding, + Shader::PushData& push_data) { + const u64 alignment = instance.StorageMinAlignment(); + for (const auto& desc : stage.buffers) { + if (desc.IsSpecial()) { + if (desc.buffer_type == Shader::BufferType::GdsBuffer) { + const auto* gds_buf = buffer_cache.GetGdsBuffer(); + buffer_infos.emplace_back(gds_buf->Handle(), 0, gds_buf->SizeBytes()); + needs_barrier |= runtime.IsBufferAccessed(gds_buf, 0, gds_buf->SizeBytes()); + } else if (desc.buffer_type == Shader::BufferType::Flatbuf) { + auto& vk_buffer = buffer_cache.GetStreamBuffer(); + const u32 ubo_size = stage.flattened_ud_buf.size() * sizeof(u32); + const u64 offset = + vk_buffer.Copy(stage.flattened_ud_buf.data(), ubo_size, alignment); + buffer_infos.emplace_back(vk_buffer.Handle(), offset, ubo_size); + } else if (desc.buffer_type == Shader::BufferType::ClipPlanes) { + // Permutations compiled without enabled planes never read the buffer, so the + // declared binding is satisfied with a null descriptor instead of a copy. + if (liverpool->regs.clipper_control.user_clip_plane_enable == 0) { + buffer_infos.emplace_back(VK_NULL_HANDLE, 0, VK_WHOLE_SIZE); + } else { + auto& vk_buffer = buffer_cache.GetStreamBuffer(); + std::array planes{}; + for (u32 i = 0; i < AmdGpu::NUM_CLIP_PLANES; ++i) { + const auto& plane = liverpool->regs.clip_user_data[i]; + planes[i * 4 + 0] = std::bit_cast(plane.data_x); + planes[i * 4 + 1] = std::bit_cast(plane.data_y); + planes[i * 4 + 2] = std::bit_cast(plane.data_z); + planes[i * 4 + 3] = std::bit_cast(plane.data_w); + } + const u32 ubo_size = static_cast(sizeof(planes)); + const u64 offset = vk_buffer.Copy(planes.data(), ubo_size, alignment); + buffer_infos.emplace_back(vk_buffer.Handle(), offset, ubo_size); + } + } else if (desc.buffer_type == Shader::BufferType::BdaPagetable) { + const auto* bda_buffer = buffer_cache.GetBdaPageTableBuffer(); + buffer_infos.emplace_back(bda_buffer->Handle(), 0, bda_buffer->SizeBytes()); + } else if (desc.buffer_type == Shader::BufferType::FaultBuffer) { + const auto* fault_buffer = buffer_cache.GetFaultBuffer(); + buffer_infos.emplace_back(fault_buffer->Handle(), 0, fault_buffer->SizeBytes()); + } else if (desc.buffer_type == Shader::BufferType::SharedMemory) { + auto& lds_buffer = buffer_cache.GetStreamBuffer(); + const auto& cs_program = liverpool->GetCsRegs(); + const auto lds_size = cs_program.SharedMemSize() * cs_program.NumWorkgroups(); + const auto [data, offset] = lds_buffer.Map(lds_size, alignment); + std::memset(data, 0, lds_size); + lds_buffer.Commit(); + buffer_infos.emplace_back(lds_buffer.Handle(), offset, lds_size); + } else { + UNREACHABLE_MSG("Unexpected buffer type {}", u32(desc.buffer_type)); + } + } else { + const auto vsharp = desc.GetSharp(stage); + if (vsharp.base_address == 0 || vsharp.GetSize() == 0) { + buffer_infos.emplace_back(VK_NULL_HANDLE, 0, VK_WHOLE_SIZE); + } else { + const u64 size = memory->ClampRangeSize(vsharp.base_address, vsharp.GetSize()); + if (size != vsharp.GetSize()) { + LOG_ERROR(Render, "Clamped size from {} to {} for stage {:#x}", + vsharp.GetSize(), size, stage.pgm_hash); + } + const auto [buffer, offset] = buffer_cache.ObtainBuffer( + vsharp.base_address, size, desc.is_written, desc.is_formatted); + const u64 offset_aligned = Common::AlignDown(offset, alignment); + const u64 adjust = offset - offset_aligned; + if (adjust % 4 != 0) { + LOG_WARNING(Render_Vulkan, "Buffer binding in shader {:#x} isn't dword aligned", + stage.pgm_hash); + } + push_data.AddOffset(binding.buffer, adjust); + buffer_infos.emplace_back(buffer->Handle(), offset_aligned, size + adjust); + bound_buffers.emplace_back(buffer, offset, size, desc.is_written); + if (desc.is_written) { + // Raw storage-buffer writes can also make an aliased cached image stale. + texture_cache.InvalidateMemoryFromGPU(vsharp.base_address, size); + } + needs_barrier |= runtime.IsBufferAccessed(buffer, offset, size, desc.is_written); + } + } + + auto& set_write = set_writes[set_write_index++]; + set_write.dstSet = VK_NULL_HANDLE; + set_write.dstBinding = binding.unified++; + set_write.dstArrayElement = 0; + set_write.descriptorCount = 1; + set_write.descriptorType = vk::DescriptorType::eStorageBuffer; + set_write.pBufferInfo = &buffer_infos.back(); + ++binding.buffer; + } +} + +const VideoCore::TextureCache::ImageDesc& Rasterizer::CachedImageDesc( + const AmdGpu::Image& sharp, const Shader::ImageResource& res) { + std::array key; + std::memcpy(key.data(), &sharp, sizeof(key)); + const u32 flags = u32(res.is_written) | u32(res.is_depth) << 1 | u32(res.is_array) << 2; + u64 hash = flags * 0x9E3779B97F4A7C15ull; + for (const u64 word : key) { + hash = (hash ^ word) * 0xFF51AFD7ED558CCDull; + hash ^= hash >> 32; + } + auto& entry = image_desc_cache[hash % image_desc_cache.size()]; + if (entry.flags != flags || entry.sharp != key || + BbToggle::Disabled(BbToggle::ImageDescCache)) { + entry.desc = VideoCore::TextureCache::ImageDesc{sharp, res}; + entry.sharp = key; + entry.flags = flags; + } + return entry.desc; +} + +void Rasterizer::BindTextures(const Shader::Info& stage, Shader::Backend::Bindings& binding) { + image_bindings.clear(); + const u32 first_image_idx = image_infos.size(); + // To emulate storing to explicit mip levels, build a descriptor array with each mip level. + boost::container::small_vector image_descriptor_array_sizes; + + for (const auto& image_desc : stage.images) { + const auto tsharp = image_desc.GetSharp(stage); + if (texture_cache.IsMeta(tsharp.Address())) { + LOG_WARNING(Render_Vulkan, "Unexpected metadata read by a shader (texture)"); + } + + const auto data_fmt = tsharp.GetDataFmt(); + const auto num_fmt = tsharp.GetNumberFmt(); + if (tsharp.Address() == 0 || data_fmt == AmdGpu::DataFormat::FormatInvalid) { + image_bindings.emplace_back(std::piecewise_construct, std::tuple{}, std::tuple{}); + image_descriptor_array_sizes.push_back(1); + continue; + } + + if (!memory->IsValidGpuMapping(tsharp.Address(), 0) || + !magic_enum::enum_contains(data_fmt) || !magic_enum::enum_contains(num_fmt)) { + LOG_WARNING(Render_Vulkan, + "Rejecting invalid T# address={:#x}, pitch={}, width={}, " + "data_format={}, num_format={}", + tsharp.Address(), tsharp.pitch, tsharp.width, static_cast(data_fmt), + static_cast(num_fmt)); + image_bindings.emplace_back(std::piecewise_construct, std::tuple{}, std::tuple{}); + image_descriptor_array_sizes.push_back(1); + continue; + } + + const Shader::MipStorageFallbackMode mip_fallback_mode = image_desc.mip_fallback_mode; + const u32 num_bindings = image_desc.NumBindings(stage); + + for (auto i = 0; i < num_bindings; i++) { + auto& [image_id, desc] = image_bindings.emplace_back( + std::piecewise_construct, std::tuple{}, + std::tuple{CachedImageDesc(tsharp, image_desc)}); + + if (mip_fallback_mode == Shader::MipStorageFallbackMode::ConstantIndex) { + ASSERT(num_bindings == 1); + desc.view_info.range.base.level += image_desc.constant_mip_index; + desc.view_info.range.extent.levels = 1; + } else if (mip_fallback_mode == Shader::MipStorageFallbackMode::DynamicIndex) { + desc.view_info.range.base.level += i; + desc.view_info.range.extent.levels = 1; + } + + image_id = texture_cache.FindImage(desc); + auto* image = &texture_cache.GetImage(image_id); + if (auto depth_image_id = texture_cache.GetAssociatedDepth(*image)) { + // If this image has an associated depth image, it's a stencil attachment. + // Redirect the access to the actual depth-stencil buffer. + image_id = depth_image_id; + image = &texture_cache.GetImage(image_id); + } + if (image->binding.is_bound) { + // The image is already bound. In case if it is about to be used as storage we + // need to force general layout on it. + image->binding.force_general |= image_desc.is_written; + } + image->binding.is_bound = 1u; + } + + image_descriptor_array_sizes.push_back(num_bindings); + } + + // Second pass to re-bind images that were updated after binding + for (auto& [image_id, desc] : image_bindings) { + bool is_storage = desc.type == VideoCore::TextureCache::BindingType::Storage; + if (!image_id) { + image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral); + } else { + if (auto& old_image = texture_cache.GetImage(image_id); + old_image.binding.needs_rebind) { + old_image.binding = {}; + image_id = texture_cache.FindImage(desc); + } + + bound_images.emplace_back(image_id); + + auto& image = texture_cache.GetImage(image_id); + auto& image_view = texture_cache.FindTexture(image_id, desc); + const auto binding = image.binding; + + // The image is either bound as storage in a separate descriptor or bound as render + // target in feedback loop. Depth images are excluded because they can't be bound as + // storage and feedback loop doesn't make sense for them + if ((binding.force_general || binding.is_target) && !image.info.props.is_depth) { + if (instance.IsAttachmentFeedbackLoopLayoutSupported() && image.binding.is_target) { + needs_barrier |= runtime.Transit( + &image, vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT, + vk::PipelineStageFlagBits2::eAllGraphics, vk::AccessFlagBits2::eShaderRead); + } else { + needs_barrier |= runtime.Transit( + &image, vk::ImageLayout::eGeneral, vk::PipelineStageFlagBits2::eAllCommands, + vk::AccessFlagBits2::eShaderRead | vk::AccessFlagBits2::eShaderWrite); + } + } else { + if (is_storage) { + needs_barrier |= runtime.Transit( + &image, vk::ImageLayout::eGeneral, vk::PipelineStageFlagBits2::eAllCommands, + vk::AccessFlagBits2::eShaderRead | vk::AccessFlagBits2::eShaderWrite, + desc.view_info.range); + } else { + const auto new_layout = image.info.props.is_depth + ? vk::ImageLayout::eDepthStencilReadOnlyOptimal + : vk::ImageLayout::eShaderReadOnlyOptimal; + needs_barrier |= runtime.Transit( + &image, new_layout, vk::PipelineStageFlagBits2::eAllCommands, + vk::AccessFlagBits2::eShaderRead, desc.view_info.range); + } + } + image.usage.storage |= is_storage; + image.usage.texture |= !is_storage; + + image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, + image.backing->state.layout); + } + } + + u32 image_info_idx = first_image_idx; + u32 image_binding_idx = 0; + for (u32 array_size : image_descriptor_array_sizes) { + const auto& [_, desc] = image_bindings[image_binding_idx]; + const bool is_storage = desc.type == VideoCore::TextureCache::BindingType::Storage; + auto& set_write = set_writes[set_write_index++]; + set_write.dstSet = VK_NULL_HANDLE; + set_write.dstBinding = binding.unified; + set_write.dstArrayElement = 0; + set_write.descriptorCount = array_size; + set_write.descriptorType = + is_storage ? vk::DescriptorType::eStorageImage : vk::DescriptorType::eSampledImage; + set_write.pImageInfo = &image_infos[image_info_idx]; + + image_info_idx += array_size; + image_binding_idx += array_size; + binding.unified += array_size; + } + + for (const auto& sampler : stage.samplers) { + auto ssharp = sampler.GetSharp(stage); + const auto vk_sampler = + texture_cache.GetSampler(ssharp, liverpool->regs.ta_bc_base, sampler.is_depth); + image_infos.emplace_back(vk_sampler, VK_NULL_HANDLE, vk::ImageLayout::eGeneral); + auto& set_write = set_writes[set_write_index++]; + set_write.dstSet = VK_NULL_HANDLE; + set_write.dstBinding = binding.unified++; + set_write.dstArrayElement = 0; + set_write.descriptorCount = 1; + set_write.descriptorType = vk::DescriptorType::eSampler; + set_write.pImageInfo = &image_infos.back(); + } +} + +RenderState Rasterizer::BeginRendering(const GraphicsPipeline* pipeline) { + attachment_feedback_loop = false; + const auto& regs = liverpool->regs; + const auto& key = pipeline->GetGraphicsKey(); + RenderState state; + state.width = instance.GetMaxFramebufferWidth(); + state.height = instance.GetMaxFramebufferHeight(); + state.num_layers = std::numeric_limits::max(); + state.num_color_attachments = std::bit_width(key.mrt_mask); + for (auto cb = 0u; cb < state.num_color_attachments; ++cb) { + auto& [image_id, desc] = cb_descs[cb]; + if (!image_id) { + state.color_attachments[cb] = {}; + continue; + } + auto* image = &texture_cache.GetImage(image_id); + if (image->binding.needs_rebind) { + image_id = bound_images.emplace_back(texture_cache.FindImage(desc)); + image = &texture_cache.GetImage(image_id); + } + texture_cache.UpdateImage(image_id); + runtime.SetBackingSamples(image, key.color_samples[cb]); + const auto& image_view = texture_cache.FindRenderTarget(image_id, desc); + const auto slice = image_view.info.range.base.layer; + const auto mip = image_view.info.range.base.level; + + const auto& col_buf = regs.color_buffers[cb]; + const bool is_clear = texture_cache.IsMetaCleared(col_buf.CmaskAddress(), slice); + texture_cache.TouchMeta(col_buf.CmaskAddress(), slice, false); + + if (image->binding.is_bound) { + ASSERT_MSG(!image->binding.force_general, + "Having image both as storage and render target is unsupported"); + runtime.FlushBarriers(); + needs_barrier |= + runtime.Transit(image, + instance.IsAttachmentFeedbackLoopLayoutSupported() + ? vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT + : vk::ImageLayout::eGeneral, + vk::PipelineStageFlagBits2::eColorAttachmentOutput, + vk::AccessFlagBits2::eColorAttachmentWrite | + vk::AccessFlagBits2::eColorAttachmentRead); + attachment_feedback_loop = true; + } else { + needs_barrier |= runtime.Transit(image, vk::ImageLayout::eColorAttachmentOptimal, + vk::PipelineStageFlagBits2::eColorAttachmentOutput, + vk::AccessFlagBits2::eColorAttachmentWrite | + vk::AccessFlagBits2::eColorAttachmentRead, + desc.view_info.range); + } + + state.width = std::min(state.width, std::max(image->info.size.width >> mip, 1u)); + state.height = std::min(state.height, std::max(image->info.size.height >> mip, 1u)); + state.num_layers = std::min(state.num_layers, image_view.info.range.extent.layers); + + const auto clear_value = + is_clear ? LiverpoolToVK::ColorBufferClearValue(col_buf) : vk::ClearValue{}; + auto& attachment = state.color_attachments[cb]; + attachment.image_view = *image_view.image_view; + attachment.image_layout = image->backing->state.layout; + attachment.clear_value = clear_value.color.uint32; + attachment.is_clear = is_clear; + + image->usage.render_target = 1u; + } + for (u32 cb = state.num_color_attachments; cb < state.color_attachments.size(); ++cb) { + state.color_attachments[cb] = {}; + } + + if (auto image_id = db_desc.first; image_id) { + auto& desc = db_desc.second; + const auto htile_address = regs.depth_htile_data_base.GetAddress(); + const auto& image_view = texture_cache.FindDepthTarget(image_id, desc); + auto& image = texture_cache.GetImage(image_id); + + const auto slice = image_view.info.range.base.layer; + const bool is_depth_clear = + (regs.depth_render_control.depth_clear_enable && regs.depth_control.depth_enable && + regs.depth_control.depth_write_enable) || + texture_cache.IsMetaCleared(htile_address, slice); + const bool is_stencil_clear = regs.depth_render_control.stencil_clear_enable; + texture_cache.TouchMeta(htile_address, slice, false); + ASSERT(desc.view_info.range.extent.levels == 1 && !image.binding.needs_rebind); + + const bool has_stencil = image.info.props.has_stencil; + // Stencil writes can be enabled while depth writes are off. + const bool stencil_write = + has_stencil && regs.depth_control.stencil_enable && !desc.view_info.is_storage; + const auto new_layout = desc.view_info.is_storage + ? has_stencil ? vk::ImageLayout::eDepthStencilAttachmentOptimal + : vk::ImageLayout::eDepthAttachmentOptimal + : stencil_write + ? vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal + : has_stencil ? vk::ImageLayout::eDepthStencilReadOnlyOptimal + : vk::ImageLayout::eDepthReadOnlyOptimal; + needs_barrier |= runtime.Transit(&image, new_layout, + vk::PipelineStageFlagBits2::eEarlyFragmentTests | + vk::PipelineStageFlagBits2::eLateFragmentTests, + vk::AccessFlagBits2::eDepthStencilAttachmentWrite | + vk::AccessFlagBits2::eDepthStencilAttachmentRead, + desc.view_info.range); + + state.width = std::min(state.width, image.info.size.width); + state.height = std::min(state.height, image.info.size.height); + state.num_layers = std::min(state.num_layers, image_view.info.range.extent.layers); + + auto& attachment = state.depth_stencil_attachment; + attachment.image_view = *image_view.image_view; + attachment.image_layout = image.backing->state.layout; + attachment.clear_value = {}; + attachment.is_clear = 0; + + if (regs.depth_buffer.DepthValid()) { + attachment.clear_value[0] = is_depth_clear ? std::bit_cast(regs.depth_clear) : 0u; + attachment.has_depth = true; + attachment.depth_clear = is_depth_clear; + } + if (regs.depth_buffer.StencilValid()) { + attachment.clear_value[1] = is_stencil_clear ? regs.stencil_clear : 0u; + attachment.has_stencil = true; + attachment.stencil_clear = is_stencil_clear; + } + + image.usage.depth_target = true; + } else { + state.depth_stencil_attachment = {}; + } + + if (state.num_layers == std::numeric_limits::max()) { + state.num_layers = 1; + } + + return state; +} + +void Rasterizer::Resolve() { + const auto& mrt0_hint = liverpool->last_cb_extent[0]; + const auto& mrt1_hint = liverpool->last_cb_extent[1]; + VideoCore::TextureCache::ImageDesc mrt0_desc{liverpool->regs.color_buffers[0], mrt0_hint}; + VideoCore::TextureCache::ImageDesc mrt1_desc{liverpool->regs.color_buffers[1], mrt1_hint}; + auto& mrt0_image = texture_cache.GetImage(texture_cache.FindImage(mrt0_desc, true)); + auto& mrt1_image = texture_cache.GetImage(texture_cache.FindImage(mrt1_desc, true)); + + ScopeMarkerBegin(fmt::format("Resolve:MRT0={:#x}:MRT1={:#x}", + liverpool->regs.color_buffers[0].Address(), + liverpool->regs.color_buffers[1].Address())); + runtime.ResolveImage(&mrt0_image, &mrt1_image, mrt0_desc.view_info.range, + mrt1_desc.view_info.range); + ScopeMarkerEnd(); +} + +void Rasterizer::DepthStencilCopy(bool is_depth, bool is_stencil) { + auto& regs = liverpool->regs; + + auto read_desc = VideoCore::TextureCache::ImageDesc( + regs.depth_buffer, regs.depth_view, regs.depth_control, + regs.depth_htile_data_base.GetAddress(), liverpool->last_db_extent, false); + auto write_desc = VideoCore::TextureCache::ImageDesc( + regs.depth_buffer, regs.depth_view, regs.depth_control, + regs.depth_htile_data_base.GetAddress(), liverpool->last_db_extent, true); + + auto& read_image = texture_cache.GetImage(texture_cache.FindImage(read_desc)); + auto& write_image = texture_cache.GetImage(texture_cache.FindImage(write_desc)); + + VideoCore::SubresourceRange sub_range; + sub_range.base.layer = liverpool->regs.depth_view.slice_start; + sub_range.extent.layers = liverpool->regs.depth_view.NumSlices() - sub_range.base.layer; + + ScopeMarkerBegin(fmt::format( + "DepthStencilCopy:DR={:#x}:SR={:#x}:DW={:#x}:SW={:#x}", regs.depth_buffer.DepthAddress(), + regs.depth_buffer.StencilAddress(), regs.depth_buffer.DepthWriteAddress(), + regs.depth_buffer.StencilWriteAddress())); + + runtime.CopyDepthStencil(&read_image, &write_image, sub_range); + + ScopeMarkerEnd(); +} + +void Rasterizer::FillBuffer(VAddr address, u32 num_bytes, u32 value, bool is_gds) { + ASSERT_MSG(address % 4 == 0 && num_bytes % 4 == 0, + "FillBuffer address and size must be a multiple of 4 bytes"); + if (!is_gds) { + texture_cache.ClearMeta(address); + if (!buffer_cache.IsRegionGpuModified(address, num_bytes)) { + u32* buffer = std::bit_cast(address); + std::fill(buffer, buffer + (num_bytes / sizeof(u32)), value); + return; + } + } + const auto [buffer, offset] = [&] -> std::pair { + if (is_gds) { + return {buffer_cache.GetGdsBuffer(), address}; + } + return buffer_cache.ObtainBuffer(address, num_bytes, true); + }(); + runtime.FillBuffer(buffer, offset, num_bytes, value); +} + +void Rasterizer::CopyBuffer(VAddr dst, VAddr src, u32 num_bytes, bool dst_gds, bool src_gds) { + if (!dst_gds && !buffer_cache.IsRegionGpuModified(dst, num_bytes)) { + if (!src_gds && !buffer_cache.IsRegionGpuModified(src, num_bytes) && + !texture_cache.FindImageFromRange(src, num_bytes)) { + // Both buffers were not transferred to GPU yet. Can safely copy in host memory. + std::memcpy(std::bit_cast(dst), std::bit_cast(src), num_bytes); + return; + } + } + texture_cache.InvalidateMemoryFromGPU(dst, num_bytes); + const auto* gds_buffer = buffer_cache.GetGdsBuffer(); + const auto [src_buffer, src_offset] = [&] -> std::pair { + if (src_gds) { + return {gds_buffer, src}; + } + return buffer_cache.ObtainBuffer(src, num_bytes, false, true); + }(); + const auto [dst_buffer, dst_offset] = [&] -> std::pair { + if (dst_gds) { + return {gds_buffer, dst}; + } + return buffer_cache.ObtainBuffer(dst, num_bytes, true, true); + }(); + const vk::BufferCopy copy = { + .srcOffset = src_offset, + .dstOffset = dst_offset, + .size = num_bytes, + }; + runtime.CopyBuffer(src_buffer, dst_buffer, std::span{©, 1}); +} + +u32 Rasterizer::ReadDataFromGds(u32 gds_offset) { + auto* gds_buf = buffer_cache.GetGdsBuffer(); + u32 value; + std::memcpy(&value, gds_buf->mapped_data.data() + gds_offset, sizeof(u32)); + return value; +} + +bool Rasterizer::InvalidateMemory(VAddr addr, u64 size, bool assume_locks) { + if (!IsMapped(addr, size)) { + // Not GPU mapped memory, can skip invalidation logic entirely. + return false; + } + buffer_cache.InvalidateMemory(addr, size, assume_locks); + texture_cache.InvalidateMemory(addr, size); + return true; +} + +bool Rasterizer::ReadMemory(VAddr addr, u64 size, bool assume_locks) { + if (!IsMapped(addr, size)) { + // Not GPU mapped memory, can skip invalidation logic entirely. + return false; + } + buffer_cache.ReadMemory(addr, size, false, assume_locks); + return true; +} + +void Rasterizer::ProcessDownloadImages() { + texture_cache.ProcessDownloadImages(); +} + +bool Rasterizer::IsMapped(VAddr addr, u64 size) { + if (size == 0) { + // There is no memory, so not mapped. + return false; + } + if (static_cast(addr) > std::numeric_limits::max() - size) { + // Memory range wrapped the address space, cannot be mapped. + return false; + } + const auto range = decltype(mapped_ranges)::interval_type::right_open(addr, addr + size); + + Common::RecursiveSharedLock lock{mapped_ranges_mutex}; + return boost::icl::contains(mapped_ranges, range); +} + +void Rasterizer::MapMemory(VAddr addr, u64 size) { + { + std::scoped_lock lock{mapped_ranges_mutex}; + mapped_ranges += decltype(mapped_ranges)::interval_type::right_open(addr, addr + size); + } +} + +void Rasterizer::RegisterMemory(VAddr addr, u64 size) { + page_manager.OnGpuMap(addr, size); +} + +void Rasterizer::UnmapMemory(VAddr addr, u64 size) { + buffer_cache.InvalidateMemory(addr, size); + texture_cache.UnmapMemory(addr, size); + { + std::scoped_lock lock{mapped_ranges_mutex}; + mapped_ranges -= decltype(mapped_ranges)::interval_type::right_open(addr, addr + size); + } +} + +void Rasterizer::UpdateDynamicState(const GraphicsPipeline* pipeline, const bool is_indexed) const { + UpdateViewportScissorState(); + UpdateDepthStencilState(); + UpdatePrimitiveState(is_indexed); + UpdateRasterizationState(); + UpdateColorBlendingState(pipeline); + + auto& dynamic_state = scheduler.GetDynamicState(); + if (dynamic_state.AnyDirty()) { + scheduler.Record([state = dynamic_state, &instance = instance](vk::CommandBuffer cmdbuf) mutable { + state.Commit(instance, cmdbuf); + }); + // Clears the dirty flags the recorded copy commits; deferred ones stay set. + dynamic_state.Commit(instance, vk::CommandBuffer{}); + } +} + +void Rasterizer::UpdateViewportScissorState() const { + const auto& regs = liverpool->regs; + + const auto combined_scissor_value_tl = [](s16 scr, s16 win, s16 gen, s16 win_offset) { + return std::max({scr, s16(win + win_offset), s16(gen + win_offset)}); + }; + const auto combined_scissor_value_br = [](s16 scr, s16 win, s16 gen, s16 win_offset) { + return std::min({scr, s16(win + win_offset), s16(gen + win_offset)}); + }; + const bool enable_offset = !regs.window_scissor.window_offset_disable; + + AmdGpu::Scissor scsr{}; + scsr.top_left_x = combined_scissor_value_tl( + regs.screen_scissor.top_left_x, s16(regs.window_scissor.top_left_x), + s16(regs.generic_scissor.top_left_x), + enable_offset ? regs.window_offset.window_x_offset : 0); + scsr.top_left_y = combined_scissor_value_tl( + regs.screen_scissor.top_left_y, s16(regs.window_scissor.top_left_y), + s16(regs.generic_scissor.top_left_y), + enable_offset ? regs.window_offset.window_y_offset : 0); + scsr.bottom_right_x = combined_scissor_value_br( + regs.screen_scissor.bottom_right_x, regs.window_scissor.bottom_right_x, + regs.generic_scissor.bottom_right_x, + enable_offset ? regs.window_offset.window_x_offset : 0); + scsr.bottom_right_y = combined_scissor_value_br( + regs.screen_scissor.bottom_right_y, regs.window_scissor.bottom_right_y, + regs.generic_scissor.bottom_right_y, + enable_offset ? regs.window_offset.window_y_offset : 0); + + boost::container::static_vector viewports; + boost::container::static_vector scissors; + + if (regs.polygon_control.enable_window_offset && + (regs.window_offset.window_x_offset != 0 || regs.window_offset.window_y_offset != 0)) { + LOG_ERROR(Render_Vulkan, + "PA_SU_SC_MODE_CNTL.VTX_WINDOW_OFFSET_ENABLE support is not yet implemented."); + } + + const auto& vp_ctl = regs.viewport_control; + for (u32 i = 0; i < AmdGpu::NUM_VIEWPORTS; i++) { + const auto& vp = regs.viewports[i]; + const auto& vp_d = regs.viewport_depths[i]; + if (vp.xscale == 0) { + continue; + } + + const auto zoffset = vp_ctl.zoffset_enable ? vp.zoffset : 0.f; + const auto zscale = vp_ctl.zscale_enable ? vp.zscale : 1.f; + + vk::Viewport viewport{}; + + // https://gitlab.freedesktop.org/mesa/mesa/-/blob/209a0ed/src/amd/vulkan/radv_pipeline_graphics.c#L688-689 + // https://gitlab.freedesktop.org/mesa/mesa/-/blob/209a0ed/src/amd/vulkan/radv_cmd_buffer.c#L3103-3109 + // When the clip space is ranged [-1...1], the zoffset is centered. + // By reversing the above viewport calculations, we get the following: + if (regs.clipper_control.clip_space == AmdGpu::ClipSpace::MinusWToW) { + viewport.minDepth = zoffset - zscale; + viewport.maxDepth = zoffset + zscale; + } else { + viewport.minDepth = zoffset; + viewport.maxDepth = zoffset + zscale; + } + + if (!instance.IsDepthRangeUnrestrictedSupported()) { + // Unrestricted depth range not supported by device. Restrict to valid range. + viewport.minDepth = std::max(viewport.minDepth, 0.f); + viewport.maxDepth = std::min(viewport.maxDepth, 1.f); + } + + if (regs.IsClipDisabled()) { + // In case if clipping is disabled we patch the shader to convert vertex position + // from screen space coordinates to NDC by defining a render space as full hardware + // window range [0..16383, 0..16383] and setting the viewport to its size. + viewport.x = 0.f; + viewport.y = 0.f; + viewport.width = float(std::min(instance.GetMaxViewportWidth(), 16_KB)); + viewport.height = float(std::min(instance.GetMaxViewportHeight(), 16_KB)); + } else { + const auto xoffset = vp_ctl.xoffset_enable ? vp.xoffset : 0.f; + const auto xscale = vp_ctl.xscale_enable ? vp.xscale : 1.f; + const auto yoffset = vp_ctl.yoffset_enable ? vp.yoffset : 0.f; + const auto yscale = vp_ctl.yscale_enable ? vp.yscale : 1.f; + + viewport.x = xoffset - xscale; + viewport.y = yoffset - yscale; + viewport.width = xscale * 2.0f; + viewport.height = yscale * 2.0f; + } + + viewports.push_back(viewport); + + auto vp_scsr = scsr; + if (regs.mode_control.vport_scissor_enable) { + vp_scsr.top_left_x = + std::max(vp_scsr.top_left_x, s16(regs.viewport_scissors[i].top_left_x)); + vp_scsr.top_left_y = + std::max(vp_scsr.top_left_y, s16(regs.viewport_scissors[i].top_left_y)); + vp_scsr.bottom_right_x = std::min(AmdGpu::Scissor::Clamp(vp_scsr.bottom_right_x), + regs.viewport_scissors[i].bottom_right_x); + vp_scsr.bottom_right_y = std::min(AmdGpu::Scissor::Clamp(vp_scsr.bottom_right_y), + regs.viewport_scissors[i].bottom_right_y); + } + scissors.push_back({ + .offset = {vp_scsr.top_left_x, vp_scsr.top_left_y}, + .extent = {vp_scsr.GetWidth(), vp_scsr.GetHeight()}, + }); + } + + if (viewports.empty()) { + // Vulkan requires providing at least one viewport. + constexpr vk::Viewport empty_viewport = { + .x = -1.0f, + .y = -1.0f, + .width = 1.0f, + .height = 1.0f, + .minDepth = 0.0f, + .maxDepth = 1.0f, + }; + constexpr vk::Rect2D empty_scissor = { + .offset = {0, 0}, + .extent = {1, 1}, + }; + viewports.push_back(empty_viewport); + scissors.push_back(empty_scissor); + } + + auto& dynamic_state = scheduler.GetDynamicState(); + dynamic_state.SetViewports(viewports); + dynamic_state.SetScissors(scissors); +} + +void Rasterizer::UpdateDepthStencilState() const { + const auto& regs = liverpool->regs; + auto& dynamic_state = scheduler.GetDynamicState(); + + const auto depth_test_enabled = + regs.depth_control.depth_enable && regs.depth_buffer.DepthValid(); + dynamic_state.SetDepthTestEnabled(depth_test_enabled); + if (depth_test_enabled) { + dynamic_state.SetDepthWriteEnabled(regs.depth_control.depth_write_enable && + !regs.depth_render_control.depth_clear_enable); + dynamic_state.SetDepthCompareOp(LiverpoolToVK::CompareOp(regs.depth_control.depth_func)); + } + + const auto depth_bounds_test_enabled = regs.depth_control.depth_bounds_enable; + dynamic_state.SetDepthBoundsTestEnabled(depth_bounds_test_enabled); + if (depth_bounds_test_enabled) { + dynamic_state.SetDepthBounds(regs.depth_bounds_min, regs.depth_bounds_max); + } + + const auto depth_bias_enabled = regs.polygon_control.NeedsBias(); + dynamic_state.SetDepthBiasEnabled(depth_bias_enabled); + if (depth_bias_enabled) { + const bool front = regs.polygon_control.enable_polygon_offset_front; + dynamic_state.SetDepthBias( + front ? regs.poly_offset.front_offset : regs.poly_offset.back_offset, + regs.poly_offset.depth_bias, + (front ? regs.poly_offset.front_scale : regs.poly_offset.back_scale) / 16.f); + } + + const auto stencil_test_enabled = + regs.depth_control.stencil_enable && regs.depth_buffer.StencilValid(); + dynamic_state.SetStencilTestEnabled(stencil_test_enabled); + if (stencil_test_enabled) { + const StencilOps front_ops{ + .fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_front), + .pass_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_front), + .depth_fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_front), + .compare_op = LiverpoolToVK::CompareOp(regs.depth_control.stencil_ref_func), + }; + const StencilOps back_ops = regs.depth_control.backface_enable ? StencilOps{ + .fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_back), + .pass_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_back), + .depth_fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_back), + .compare_op = LiverpoolToVK::CompareOp(regs.depth_control.stencil_bf_func), + } : front_ops; + dynamic_state.SetStencilOps(front_ops, back_ops); + + const bool stencil_clear = regs.depth_render_control.stencil_clear_enable; + const auto front = regs.stencil_ref_front; + const auto back = + regs.depth_control.backface_enable ? regs.stencil_ref_back : regs.stencil_ref_front; + // GCN REPLACE_OP writes DB_STENCILREFMASK.STENCILOPVAL, so a face whose stencil ops + // include ReplaceOp takes its Vulkan reference from op_val. + const auto& sc = regs.stencil_control; + const auto uses_op_val = [](AmdGpu::StencilFunc fail, AmdGpu::StencilFunc zpass, + AmdGpu::StencilFunc zfail) { + return fail == AmdGpu::StencilFunc::ReplaceOp || + zpass == AmdGpu::StencilFunc::ReplaceOp || + zfail == AmdGpu::StencilFunc::ReplaceOp; + }; + const bool front_op = + uses_op_val(sc.stencil_fail_front, sc.stencil_zpass_front, sc.stencil_zfail_front); + const bool back_op = + regs.depth_control.backface_enable + ? uses_op_val(sc.stencil_fail_back, sc.stencil_zpass_back, sc.stencil_zfail_back) + : front_op; + const auto ref_conflict = [](AmdGpu::CompareFunc func, const AmdGpu::StencilRefMask& ref) { + return func != AmdGpu::CompareFunc::Always && func != AmdGpu::CompareFunc::Never && + ref.stencil_test_val != ref.stencil_op_val; + }; + if ((front_op && ref_conflict(regs.depth_control.stencil_ref_func, front)) || + (back_op && regs.depth_control.backface_enable && + ref_conflict(regs.depth_control.stencil_bf_func, back))) { + LOG_WARNING(Render_Vulkan, "Stencil test requires test_val while ReplaceOp requires " + "op_val; the stencil test will use op_val"); + } + dynamic_state.SetStencilReferences(front_op ? front.stencil_op_val : front.stencil_test_val, + back_op ? back.stencil_op_val : back.stencil_test_val); + dynamic_state.SetStencilWriteMasks(!stencil_clear ? front.stencil_write_mask : 0U, + !stencil_clear ? back.stencil_write_mask : 0U); + dynamic_state.SetStencilCompareMasks(front.stencil_mask, back.stencil_mask); + } +} + +void Rasterizer::UpdatePrimitiveState(const bool is_indexed) const { + const auto& regs = liverpool->regs; + auto& dynamic_state = scheduler.GetDynamicState(); + + const auto is_list_topology = [](const AmdGpu::PrimitiveType type) { + const auto topology = LiverpoolToVK::PrimitiveType(type); + return topology == vk::PrimitiveTopology::ePointList || + topology == vk::PrimitiveTopology::eLineList || + topology == vk::PrimitiveTopology::eTriangleList || + topology == vk::PrimitiveTopology::eLineListWithAdjacency || + topology == vk::PrimitiveTopology::eTriangleListWithAdjacency; + }; + const auto is_patch_list_topology = [](const AmdGpu::PrimitiveType type) { + // Quad and rect lists are emulated using tessellation. + return type == AmdGpu::PrimitiveType::PatchPrimitive || + type == AmdGpu::PrimitiveType::QuadList || type == AmdGpu::PrimitiveType::RectList; + }; + + const auto prim_restart = + (regs.enable_primitive_restart & 1) != 0 && + (instance.IsListRestartSupported() || !is_list_topology(regs.primitive_type)) && + (instance.IsPatchListRestartSupported() || !is_patch_list_topology(regs.primitive_type)); + ASSERT_MSG(!is_indexed || !prim_restart || regs.primitive_restart_index == 0xFFFF || + regs.primitive_restart_index == 0xFFFFFFFF, + "Primitive restart index other than -1 is not supported yet"); + + const auto cull_mode = LiverpoolToVK::IsPrimitiveCulled(regs.primitive_type) + ? LiverpoolToVK::CullMode(regs.polygon_control.CullingMode()) + : vk::CullModeFlagBits::eNone; + const auto front_face = LiverpoolToVK::FrontFace(regs.polygon_control.front_face); + + dynamic_state.SetPrimitiveRestartEnabled(prim_restart); + dynamic_state.SetRasterizerDiscardEnabled(regs.clipper_control.dx_rasterization_kill); + dynamic_state.SetCullMode(cull_mode); + dynamic_state.SetFrontFace(front_face); +} + +void Rasterizer::UpdateRasterizationState() const { + const auto& regs = liverpool->regs; + auto& dynamic_state = scheduler.GetDynamicState(); + dynamic_state.SetLineWidth(regs.line_control.Width()); +} + +void Rasterizer::UpdateColorBlendingState(const GraphicsPipeline* pipeline) const { + const auto& regs = liverpool->regs; + auto& dynamic_state = scheduler.GetDynamicState(); + dynamic_state.SetBlendConstants(regs.blend_constants); + dynamic_state.SetColorWriteMasks(pipeline->GetGraphicsKey().write_masks); + dynamic_state.SetAttachmentFeedbackLoopEnabled(attachment_feedback_loop); +} + +void Rasterizer::ScopeMarkerBegin(const std::string_view& str, bool from_guest) { + if ((from_guest && !EmulatorSettings.IsVkGuestMarkersEnabled()) || + (!from_guest && !EmulatorSettings.IsVkHostMarkersEnabled())) { + return; + } + const auto cmdbuf = scheduler.CommandBuffer(); + cmdbuf.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ + .pLabelName = str.data(), + }); +} + +void Rasterizer::ScopeMarkerEnd(bool from_guest) { + if ((from_guest && !EmulatorSettings.IsVkGuestMarkersEnabled()) || + (!from_guest && !EmulatorSettings.IsVkHostMarkersEnabled())) { + return; + } + const auto cmdbuf = scheduler.CommandBuffer(); + cmdbuf.endDebugUtilsLabelEXT(); +} + +void Rasterizer::ScopedMarkerInsert(const std::string_view& str, bool from_guest) { + if ((from_guest && !EmulatorSettings.IsVkGuestMarkersEnabled()) || + (!from_guest && !EmulatorSettings.IsVkHostMarkersEnabled())) { + return; + } + const auto cmdbuf = scheduler.CommandBuffer(); + cmdbuf.insertDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ + .pLabelName = str.data(), + }); +} + +void Rasterizer::ScopedMarkerInsertColor(const std::string_view& str, const u32 color, + bool from_guest) { + if ((from_guest && !EmulatorSettings.IsVkGuestMarkersEnabled()) || + (!from_guest && !EmulatorSettings.IsVkHostMarkersEnabled())) { + return; + } + const auto cmdbuf = scheduler.CommandBuffer(); + cmdbuf.insertDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{ + .pLabelName = str.data(), + .color = std::array( + {(f32)((color >> 16) & 0xff) / 255.0f, (f32)((color >> 8) & 0xff) / 255.0f, + (f32)(color & 0xff) / 255.0f, (f32)((color >> 24) & 0xff) / 255.0f})}); +} + +std::thread::id Rasterizer::GetGpuCommandProcessorThread() { + return liverpool->GetGpuCommandProcessorThread(); +} + +#ifdef __linux__ +u32 Rasterizer::GetGpuCommandProcessorThreadId() { + return liverpool->GetGpuCommandProcessorThreadId(); +} +#endif + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_rasterizer.h b/gpu/shadps4/video_core/renderer_vulkan/vk_rasterizer.h new file mode 100644 index 0000000..5d93387 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_rasterizer.h @@ -0,0 +1,183 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/recursive_lock.h" +#include "common/shared_first_mutex.h" +#include "video_core/buffer_cache/buffer_cache.h" +#include "video_core/page_manager.h" +#include "video_core/renderer_vulkan/vk_pipeline_cache.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/texture_cache/texture_cache.h" + +namespace AmdGpu { +struct Liverpool; +} + +namespace Core { +class MemoryManager; +} + +namespace Vulkan { + +class GraphicsPipeline; +class Runtime; + +class Rasterizer { +public: + explicit Rasterizer(const Instance& instance, Scheduler& scheduler, Runtime& runtime, + AmdGpu::Liverpool* liverpool); + ~Rasterizer(); + + [[nodiscard]] Runtime& GetRuntime() noexcept { + return runtime; + } + + [[nodiscard]] VideoCore::BufferCache& GetBufferCache() noexcept { + return buffer_cache; + } + + [[nodiscard]] VideoCore::TextureCache& GetTextureCache() noexcept { + return texture_cache; + } + + void Draw(bool is_indexed, u32 index_offset = 0); + void DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u32 size, u32 max_count, + VAddr count_address, u16 vertex_sgpr_offset, u16 instance_sgpr_offset); + + void DispatchDirect(); + void DispatchIndirect(VAddr address, u32 offset, u32 size); + + void ScopeMarker(fmt::string_view fmt, fmt::format_args args, auto&& func) { + if (host_markers_enabled) { + ScopeMarkerBegin(fmt::vformat(fmt, args)); + func(); + ScopeMarkerEnd(); + } else { + func(); + } + } + + void ScopeMarkerBegin(const std::string_view& str, bool from_guest = false); + void ScopeMarkerEnd(bool from_guest = false); + void ScopedMarkerInsert(const std::string_view& str, bool from_guest = false); + void ScopedMarkerInsertColor(const std::string_view& str, const u32 color, + bool from_guest = false); + + void FillBuffer(VAddr address, u32 num_bytes, u32 value, bool is_gds); + void CopyBuffer(VAddr dst, VAddr src, u32 num_bytes, bool dst_gds, bool src_gds); + u32 ReadDataFromGds(u32 gsd_offset); + bool InvalidateMemory(VAddr addr, u64 size, bool assume_locks = false); + bool ReadMemory(VAddr addr, u64 size, bool assume_locks = false); + void ProcessDownloadImages(); + bool IsMapped(VAddr addr, u64 size); + void MapMemory(VAddr addr, u64 size); + void RegisterMemory(VAddr addr, u64 size); + void UnmapMemory(VAddr addr, u64 size); + + u64 Flush(); + void Finish(); + void OnSubmit(); + + PipelineCache& GetPipelineCache() { + return pipeline_cache; + } + + template + void ForEachMappedRangeInRange(VAddr addr, u64 size, Func&& func) { + const auto range = decltype(mapped_ranges)::interval_type::right_open(addr, addr + size); + Common::RecursiveSharedLock lock{mapped_ranges_mutex}; + for (const auto& mapped_range : (mapped_ranges & range)) { + func(mapped_range); + } + } + + std::thread::id GetGpuCommandProcessorThread(); +#ifdef __linux__ + u32 GetGpuCommandProcessorThreadId(); +#endif + +private: + void PrepareRenderState(const GraphicsPipeline* pipeline); + RenderState BeginRendering(const GraphicsPipeline* pipeline); + void Resolve(); + void DepthStencilCopy(bool is_depth, bool is_stencil); + void EliminateFastClear(); + + void UpdateDynamicState(const GraphicsPipeline* pipeline, bool is_indexed) const; + void UpdateViewportScissorState() const; + void UpdateDepthStencilState() const; + void UpdatePrimitiveState(bool is_indexed) const; + void UpdateRasterizationState() const; + void UpdateColorBlendingState(const GraphicsPipeline* pipeline) const; + + bool FilterDraw(); + + void BindBuffers(const Shader::Info& stage, Shader::Backend::Bindings& binding, + Shader::PushData& push_data); + void BindTextures(const Shader::Info& stage, Shader::Backend::Bindings& binding); + bool BindResources(const Pipeline* pipeline); + + void BindVertexBuffers(const GraphicsPipeline* pipeline); + void BindIndexBuffer(u32 index_offset = 0); + + void ResetBindings(bool is_compute); + + bool IsComputeMetaClear(const Pipeline* pipeline); + bool IsComputeImageCopy(const Pipeline* pipeline); + bool IsComputeImageClear(const Pipeline* pipeline); + +private: + friend class VideoCore::BufferCache; + + const Instance& instance; + Scheduler& scheduler; + Runtime& runtime; + VideoCore::PageManager page_manager; + VideoCore::BufferCache buffer_cache; + VideoCore::TextureCache texture_cache; + AmdGpu::Liverpool* liverpool; + Core::MemoryManager* memory; + boost::icl::interval_set mapped_ranges; + Common::SharedFirstMutex mapped_ranges_mutex; + PipelineCache pipeline_cache; + const bool host_markers_enabled; + const bool guest_markers_enabled; + + using RenderTargetInfo = std::pair; + std::array cb_descs; + std::pair db_desc; + boost::container::static_vector image_infos; + boost::container::static_vector buffer_infos; + boost::container::static_vector bound_images; + struct BoundBuffer { + const VideoCore::Buffer* buffer; + u64 offset; + u32 size; + bool is_written; + }; + boost::container::static_vector bound_buffers; + + u32 set_write_index{}; + Pipeline::DescriptorWrites set_writes; + Shader::PushData push_data; + + using ImageBindingInfo = std::pair; + // bbport: texture descriptions depend only on the T# and three resource flags; building + // them (mip layout sizes) for every binding of every draw was a hot spot. + struct ImageDescCacheEntry { + std::array sharp{}; + u32 flags = ~0u; + VideoCore::TextureCache::ImageDesc desc; + }; + std::array image_desc_cache{}; + const VideoCore::TextureCache::ImageDesc& CachedImageDesc(const AmdGpu::Image& sharp, + const Shader::ImageResource& res); + boost::container::static_vector image_bindings; + bool fault_process_pending{}; + bool attachment_feedback_loop{}; + bool needs_barrier{}; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_resource_pool.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_resource_pool.cpp new file mode 100644 index 0000000..157d282 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_resource_pool.cpp @@ -0,0 +1,194 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "common/assert.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_resource_pool.h" +#include "video_core/renderer_vulkan/vk_semaphore.h" + +namespace Vulkan { + +ResourcePool::ResourcePool(Semaphore* work_semaphore_, std::size_t grow_step_) + : work_semaphore{work_semaphore_}, grow_step{grow_step_} {} + +std::size_t ResourcePool::CommitResource() { + u64 gpu_tick = work_semaphore->KnownGpuTick(); + const auto search = [this, gpu_tick](std::size_t begin, + std::size_t end) -> std::optional { + for (std::size_t iterator = begin; iterator < end; ++iterator) { + if (gpu_tick >= ticks[iterator]) { + ticks[iterator] = work_semaphore->CurrentTick(); + return iterator; + } + } + return std::nullopt; + }; + + // Try to find a free resource from the hinted position to the end. + auto found = search(hint_iterator, ticks.size()); + if (!found) { + // Refresh semaphore to query updated results + work_semaphore->Refresh(); + gpu_tick = work_semaphore->KnownGpuTick(); + found = search(hint_iterator, ticks.size()); + } + if (!found) { + // Search from beginning to the hinted position. + found = search(0, hint_iterator); + if (!found) { + // Both searches failed, the pool is full; handle it. + const std::size_t free_resource = ManageOverflow(); + + ticks[free_resource] = work_semaphore->CurrentTick(); + found = free_resource; + } + } + + // Free iterator is hinted to the resource after the one that's been commited. + hint_iterator = (*found + 1) % ticks.size(); + return *found; +} + +std::size_t ResourcePool::ManageOverflow() { + const std::size_t old_capacity = ticks.size(); + ticks.resize(old_capacity + grow_step); + Allocate(old_capacity, old_capacity + grow_step); + return old_capacity; +} + +constexpr std::size_t COMMAND_BUFFER_POOL_SIZE = 4; + +CommandPool::CommandPool(const Instance& instance, Semaphore* work_semaphore) + : ResourcePool{work_semaphore, COMMAND_BUFFER_POOL_SIZE}, instance{instance} { + const vk::CommandPoolCreateInfo pool_create_info = { + .flags = vk::CommandPoolCreateFlagBits::eTransient | + vk::CommandPoolCreateFlagBits::eResetCommandBuffer, + .queueFamilyIndex = instance.GetGraphicsQueueFamilyIndex(), + }; + const vk::Device device = instance.GetDevice(); + auto [pool_result, pool] = device.createCommandPoolUnique(pool_create_info); + ASSERT_MSG(pool_result == vk::Result::eSuccess, "Failed to create command pool: {}", + vk::to_string(pool_result)); + cmd_pool = std::move(pool); + SetObjectName(device, *cmd_pool, "CommandPool"); +} + +CommandPool::~CommandPool() = default; + +void CommandPool::Allocate(std::size_t begin, std::size_t end) { + cmd_buffers.resize(end); + + const vk::CommandBufferAllocateInfo buffer_alloc_info = { + .commandPool = *cmd_pool, + .level = vk::CommandBufferLevel::ePrimary, + .commandBufferCount = COMMAND_BUFFER_POOL_SIZE, + }; + + const vk::Device device = instance.GetDevice(); + const auto result = + device.allocateCommandBuffers(&buffer_alloc_info, cmd_buffers.data() + begin); + ASSERT(result == vk::Result::eSuccess); + + for (std::size_t i = begin; i < end; ++i) { + SetObjectName(device, cmd_buffers[i], "CommandPool: Command Buffer {}", i); + } +} + +vk::CommandBuffer CommandPool::Commit() { + const std::size_t index = CommitResource(); + return cmd_buffers[index]; +} + +DescriptorHeap::DescriptorHeap(const Instance& instance, Semaphore* work_semaphore_, + std::span pool_sizes_, + u32 descriptor_heap_count_) + : device{instance.GetDevice()}, work_semaphore{work_semaphore_}, + descriptor_heap_count{descriptor_heap_count_}, pool_sizes{pool_sizes_} { + CreateDescriptorPool(); +} + +DescriptorHeap::~DescriptorHeap() { + device.destroyDescriptorPool(curr_pool); + for (const auto [pool, tick] : pending_pools) { + work_semaphore->Wait(tick); + device.destroyDescriptorPool(pool); + } +} + +vk::DescriptorSet DescriptorHeap::Commit(vk::DescriptorSetLayout set_layout) { + const u64 set_key = std::bit_cast(set_layout); + const auto [it, _] = descriptor_sets.try_emplace(set_key); + + // Check if allocated sets exist and pick one. + if (!it->second.empty()) { + const auto desc_set = it->second.back(); + it.value().pop_back(); + return desc_set; + } + + DescSetBatch desc_sets(DescriptorSetBatch); + std::array layouts; + layouts.fill(set_layout); + + vk::DescriptorSetAllocateInfo alloc_info = { + .descriptorPool = curr_pool, + .descriptorSetCount = DescriptorSetBatch, + .pSetLayouts = layouts.data(), + }; + + // Attempt to allocate the descriptor set batch. + auto result = device.allocateDescriptorSets(&alloc_info, desc_sets.data()); + if (result == vk::Result::eSuccess) { + const auto desc_set = desc_sets.back(); + desc_sets.pop_back(); + it.value() = std::move(desc_sets); + return desc_set; + } + + // The pool has run out. Record current tick and place it in pending list. + ASSERT_MSG(result == vk::Result::eErrorOutOfPoolMemory || + result == vk::Result::eErrorFragmentedPool, + "Unexpected error during descriptor set allocation: {}", vk::to_string(result)); + pending_pools.emplace_back(curr_pool, work_semaphore->CurrentTick()); + if (const auto [pool, tick] = pending_pools.front(); work_semaphore->IsFree(tick)) { + curr_pool = pool; + pending_pools.pop_front(); + + const auto reset_result = device.resetDescriptorPool(curr_pool); + ASSERT_MSG(reset_result == vk::Result::eSuccess, + "Unexpected error resetting descriptor pool: {}", vk::to_string(reset_result)); + } else { + CreateDescriptorPool(); + } + + // Attempt to allocate again with fresh pool. + alloc_info.descriptorPool = curr_pool; + result = device.allocateDescriptorSets(&alloc_info, desc_sets.data()); + ASSERT_MSG(result == vk::Result::eSuccess, + "Unexpected error during descriptor set allocation {}", vk::to_string(result)); + + // We've changed pool so also reset descriptor batch cache. + descriptor_sets.clear(); + const auto desc_set = desc_sets.back(); + desc_sets.pop_back(); + descriptor_sets[set_key] = std::move(desc_sets); + return desc_set; +} + +void DescriptorHeap::CreateDescriptorPool() { + const vk::DescriptorPoolCreateInfo pool_info = { + .flags = vk::DescriptorPoolCreateFlagBits::eUpdateAfterBind, + .maxSets = descriptor_heap_count, + .poolSizeCount = static_cast(pool_sizes.size()), + .pPoolSizes = pool_sizes.data(), + }; + auto [pool_result, pool] = device.createDescriptorPool(pool_info); + ASSERT_MSG(pool_result == vk::Result::eSuccess, "Failed to create descriptor pool: {}", + vk::to_string(pool_result)); + curr_pool = pool; +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_resource_pool.h b/gpu/shadps4/video_core/renderer_vulkan/vk_resource_pool.h new file mode 100644 index 0000000..fc2a1de --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_resource_pool.h @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan { + +class Instance; +class Semaphore; + +/** + * Handles a pool of resources protected by fences. Manages resource overflow allocating more + * resources. + */ +class ResourcePool { +public: + explicit ResourcePool() = default; + explicit ResourcePool(Semaphore* work_semaphore, std::size_t grow_step); + virtual ~ResourcePool() = default; + + ResourcePool& operator=(ResourcePool&&) noexcept = default; + ResourcePool(ResourcePool&&) noexcept = default; + + ResourcePool& operator=(const ResourcePool&) = default; + ResourcePool(const ResourcePool&) = default; + +protected: + std::size_t CommitResource(); + + /// Called when a chunk of resources have to be allocated. + virtual void Allocate(std::size_t begin, std::size_t end) = 0; + +private: + /// Manages pool overflow allocating new resources. + std::size_t ManageOverflow(); + +protected: + Semaphore* work_semaphore{}; + std::size_t grow_step = 0; ///< Number of new resources created after an overflow + std::size_t hint_iterator = 0; ///< Hint to where the next free resources is likely to be found + std::vector ticks; ///< Ticks for each resource +}; + +class CommandPool final : public ResourcePool { +public: + explicit CommandPool(const Instance& instance, Semaphore* work_semaphore); + ~CommandPool() override; + + void Allocate(std::size_t begin, std::size_t end) override; + + vk::CommandBuffer Commit(); + +private: + const Instance& instance; + vk::UniqueCommandPool cmd_pool; + std::vector cmd_buffers; +}; + +class DescriptorHeap final { + static constexpr u32 DescriptorSetBatch = 32; + +public: + explicit DescriptorHeap(const Instance& instance, Semaphore* work_semaphore, + std::span pool_sizes, + u32 descriptor_heap_count = 1024); + ~DescriptorHeap(); + + vk::DescriptorSet Commit(vk::DescriptorSetLayout set_layout); + +private: + void CreateDescriptorPool(); + +private: + vk::Device device; + Semaphore* work_semaphore; + u32 descriptor_heap_count; + std::span pool_sizes; + vk::DescriptorPool curr_pool; + std::deque> pending_pools; + using DescSetBatch = boost::container::static_vector; + tsl::robin_map descriptor_sets; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_runtime.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_runtime.cpp new file mode 100644 index 0000000..8de361f --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_runtime.cpp @@ -0,0 +1,786 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "video_core/buffer_cache/buffer.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/texture_cache/blit_helper.h" +#include "video_core/texture_cache/image.h" + +#include + +namespace Vulkan { + +static vk::ImageType ConvertImageType(AmdGpu::ImageType type) noexcept { + switch (type) { + case AmdGpu::ImageType::Color1D: + case AmdGpu::ImageType::Color1DArray: + return vk::ImageType::e1D; + case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color2DMsaa: + case AmdGpu::ImageType::Color2DArray: + return vk::ImageType::e2D; + case AmdGpu::ImageType::Color3D: + return vk::ImageType::e3D; + default: + UNREACHABLE_MSG("Unexpected image type {}", u32(type)); + } +} + +static std::pair SanitizeCopyLayers(const VideoCore::ImageInfo& src_info, + const VideoCore::ImageInfo& dst_info, + const u32 depth) { + const auto vk_src_type = ConvertImageType(src_info.type); + const auto vk_dst_type = ConvertImageType(dst_info.type); + + u32 src_layers = src_info.resources.layers; + u32 dst_layers = dst_info.resources.layers; + + // 3D images can only use 1 layer. + if (vk_src_type == vk::ImageType::e3D && src_layers != 1) { + LOG_WARNING(Render_Vulkan, "Coercing copy 3D source layers {} to 1.", src_layers); + src_layers = 1; + } + if (vk_dst_type == vk::ImageType::e3D && dst_layers != 1) { + LOG_WARNING(Render_Vulkan, "Coercing copy 3D destination layers {} to 1.", dst_layers); + dst_layers = 1; + } + + // If the image type is equal, layer count must match. Take the minimum of both. + if (vk_src_type == vk_dst_type) { + if (src_layers != dst_layers) { + LOG_WARNING(Render_Vulkan, + "Coercing copy source layers {} and destination layers {} to minimum.", + src_layers, dst_layers); + src_layers = dst_layers = std::min(src_layers, dst_layers); + } + } else { + // For 2D <-> 3D copies, 2D layer count must equal 3D depth. + if (vk_src_type == vk::ImageType::e2D && vk_dst_type == vk::ImageType::e3D && + src_layers != depth) { + LOG_WARNING(Render_Vulkan, + "Coercing copy 2D source layers {} to 3D destination depth {}", src_layers, + depth); + src_layers = depth; + } + if (vk_src_type == vk::ImageType::e3D && vk_dst_type == vk::ImageType::e2D && + dst_layers != depth) { + LOG_WARNING(Render_Vulkan, + "Coercing copy 2D destination layers {} to 3D source depth {}", dst_layers, + depth); + dst_layers = depth; + } + } + + return std::make_pair(src_layers, dst_layers); +} + +static u32 BufferImageCopySize(const vk::BufferImageCopy& copy, const vk::Format pixel_format) { + const u32 row_length = copy.bufferRowLength ? copy.bufferRowLength : copy.imageExtent.width; + const u32 height = copy.bufferImageHeight ? copy.bufferImageHeight : copy.imageExtent.height; + + const auto block = vk::blockExtent(pixel_format); + const u32 block_size = vk::blockSize(pixel_format); + const u32 row_pitch = (row_length / block[0]) * block_size; + const u32 slice_pitch = (height / block[1]) * row_pitch; + + const u32 width_in_blocks = (copy.imageExtent.width + block[0] - 1) / block[0]; + const u32 height_in_blocks = (copy.imageExtent.height + block[1] - 1) / block[1]; + const u32 num_slices = copy.imageExtent.depth * copy.imageSubresource.layerCount; + + return (num_slices - 1) * slice_pitch + (height_in_blocks - 1) * row_pitch + + width_in_blocks * block_size; +} + +Runtime::Runtime(const Instance& instance_, Scheduler& scheduler_) + : instance{instance_}, scheduler{scheduler_}, staging_pool{instance_, scheduler_} { + blit_helper = std::make_unique(instance, scheduler); + + memory_barrier.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands; + memory_barrier.dstAccessMask = + vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite; +} + +void Runtime::TickFrame() { + staging_pool.TickFrame(); +} + +void Runtime::CopyBuffer(const VideoCore::Buffer* src, const VideoCore::Buffer* dst, + std::span copies) { + scheduler.EndRendering(); + + bool needs_flush{}; + for (const auto& copy : copies) { + needs_flush |= IsBufferAccessed(src, copy.srcOffset, copy.size); + needs_flush |= IsBufferAccessed(dst, copy.dstOffset, copy.size, true); + } + if (needs_flush) { + FlushBarriers(); + } + + scheduler.Record([src_handle = src->Handle(), dst_handle = dst->Handle(), + regions = boost::container::small_vector( + copies.begin(), copies.end())](vk::CommandBuffer cmdbuf) { + cmdbuf.copyBuffer(src_handle, dst_handle, regions.size(), regions.data()); + }); + + for (const auto& copy : copies) { + AccessBuffer(src, copy.srcOffset, copy.size, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferRead); + AccessBuffer(dst, copy.dstOffset, copy.size, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferWrite); + } +} + +void Runtime::FillBuffer(const VideoCore::Buffer* dst, u64 offset, u64 size, u32 value) { + scheduler.EndRendering(); + + if (IsBufferAccessed(dst, offset, size, true)) { + FlushBarriers(); + } + + scheduler.Record([handle = dst->Handle(), offset, size, value](vk::CommandBuffer cmdbuf) { + cmdbuf.fillBuffer(handle, offset, size, value); + }); + + AccessBuffer(dst, offset, size, vk::PipelineStageFlagBits2::eClear, + vk::AccessFlagBits2::eTransferWrite); +} + +void Runtime::InlineData(VideoCore::Buffer* dst, u64 offset, u32 value) { + scheduler.EndRendering(); + + if (IsBufferAccessed(dst, offset, sizeof(value), true)) { + FlushBarriers(); + } + + scheduler.Record([handle = dst->Handle(), offset, value](vk::CommandBuffer cmdbuf) { + cmdbuf.updateBuffer(handle, offset, sizeof(value), &value); + }); + + AccessBuffer(dst, offset, sizeof(value), vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferWrite); +} + +bool Runtime::Transit(VideoCore::Image* image, vk::ImageLayout dst_layout, + vk::PipelineStageFlags2 dst_stage, vk::AccessFlags2 dst_access, + std::optional subres_range) { + const size_t prev_num_barriers = static_cast(image_barriers.size()); + image->GetBarriers(image_barriers, dst_layout, dst_access, dst_stage, subres_range); + return image_barriers.size() != prev_num_barriers; +} + +void Runtime::UploadImage(VideoCore::Image* dst, const VideoCore::Buffer* src, + std::span upload_copies) { + SetBackingSamples(dst, dst->info.num_samples, false); + scheduler.EndRendering(); + + bool needs_flush = + Transit(dst, vk::ImageLayout::eTransferDstOptimal, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferWrite); + for (const auto& copy : upload_copies) { + const auto copy_size = BufferImageCopySize(copy, dst->info.pixel_format); + needs_flush |= IsBufferAccessed(src, copy.bufferOffset, copy_size); + } + if (needs_flush) { + FlushBarriers(); + } + + scheduler.Record([src_handle = src->Handle(), image = dst->GetImage(), + regions = boost::container::small_vector( + upload_copies.begin(), upload_copies.end())](vk::CommandBuffer cmdbuf) { + cmdbuf.copyBufferToImage(src_handle, image, vk::ImageLayout::eTransferDstOptimal, + regions.size(), regions.data()); + }); + + for (const auto& copy : upload_copies) { + const auto copy_size = BufferImageCopySize(copy, dst->info.pixel_format); + AccessBuffer(src, copy.bufferOffset, copy_size, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferRead); + } + + dst->flags &= ~VideoCore::ImageFlagBits::Dirty; +} + +void Runtime::DownloadImage(VideoCore::Image* src, const VideoCore::Buffer* dst, + std::span download_copies) { + SetBackingSamples(src, src->info.num_samples); + scheduler.EndRendering(); + + bool needs_flush = + Transit(src, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferRead); + for (const auto& copy : download_copies) { + const auto copy_size = BufferImageCopySize(copy, src->info.pixel_format); + needs_flush |= IsBufferAccessed(dst, copy.bufferOffset, copy_size, true); + } + if (needs_flush) { + FlushBarriers(); + } + + scheduler.Record([image = src->GetImage(), buffer = dst->Handle(), + regions = boost::container::small_vector( + download_copies.begin(), download_copies.end())](vk::CommandBuffer cmdbuf) { + cmdbuf.copyImageToBuffer(image, vk::ImageLayout::eTransferSrcOptimal, buffer, + regions.size(), regions.data()); + }); + + for (const auto& copy : download_copies) { + const auto copy_size = BufferImageCopySize(copy, src->info.pixel_format); + AccessBuffer(dst, copy.bufferOffset, copy_size, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferWrite); + } +} + +void Runtime::CopyImage(VideoCore::Image* src, VideoCore::Image* dst) { + const u32 num_mips = std::min(src->info.resources.levels, dst->info.resources.levels); + + // Format mismatch warning (safe but useful) + if (src->info.pixel_format != dst->info.pixel_format) { + LOG_DEBUG(Render_Vulkan, + "Copy between different formats: src={}, dst={}. " + "Result may be undefined.", + vk::to_string(src->info.pixel_format), vk::to_string(dst->info.pixel_format)); + } + + const u32 base_width = src->info.size.width; + const u32 base_height = src->info.size.height; + const u32 base_depth = + dst->info.type == AmdGpu::ImageType::Color3D ? dst->info.size.depth : src->info.size.depth; + + // Match sample count before copying + SetBackingSamples(dst, dst->info.num_samples, false); + SetBackingSamples(src, src->info.num_samples); + + boost::container::small_vector regions; + + const vk::ImageAspectFlags src_aspect = src->aspect_mask & ~vk::ImageAspectFlagBits::eStencil; + const vk::ImageAspectFlags dst_aspect = dst->aspect_mask & ~vk::ImageAspectFlagBits::eStencil; + + const bool src_is_2d = ConvertImageType(src->info.type) == vk::ImageType::e2D; + const bool src_is_3d = ConvertImageType(src->info.type) == vk::ImageType::e3D; + + const bool dst_is_2d = ConvertImageType(dst->info.type) == vk::ImageType::e2D; + const bool dst_is_3d = ConvertImageType(dst->info.type) == vk::ImageType::e3D; + + const bool is_2d_to_3d = src_is_2d && dst_is_3d; + const bool is_3d_to_2d = src_is_3d && dst_is_2d; + const bool is_same_type = !is_2d_to_3d && !is_3d_to_2d; + + for (u32 mip = 0; mip < num_mips; ++mip) { + const u32 mip_w = std::max(base_width >> mip, 1u); + const u32 mip_h = std::max(base_height >> mip, 1u); + const u32 mip_d = std::max(base_depth >> mip, 1u); + + const auto [src_layers, dst_layers] = SanitizeCopyLayers(src->info, dst->info, mip_d); + + vk::ImageCopy region{}; + region.srcSubresource.aspectMask = src_aspect; + region.srcSubresource.mipLevel = mip; + region.srcSubresource.baseArrayLayer = 0; + region.dstSubresource.aspectMask = dst_aspect; + region.dstSubresource.mipLevel = mip; + region.dstSubresource.baseArrayLayer = 0; + + if (is_same_type) { + // 2D->2D OR 3D->3D + if (src_is_3d) { + // 3D images must use layerCount=1 + region.srcSubresource.layerCount = 1; + region.dstSubresource.layerCount = 1; + region.extent = vk::Extent3D(mip_w, mip_h, mip_d); + } else { + // Array images + const u32 copy_layers = std::min(src_layers, dst_layers); + region.srcSubresource.layerCount = copy_layers; + region.dstSubresource.layerCount = copy_layers; + region.extent = vk::Extent3D(mip_w, mip_h, 1); + } + } else if (is_2d_to_3d) { + // 2D array -> 3D volume + region.srcSubresource.layerCount = src_layers; + region.dstSubresource.layerCount = 1; + region.extent = vk::Extent3D(mip_w, mip_h, src_layers); + } else if (is_3d_to_2d) { + // 3D volume -> 2D array + region.srcSubresource.layerCount = 1; + region.dstSubresource.layerCount = dst_layers; + region.extent = vk::Extent3D(mip_w, mip_h, dst_layers); + } + + regions.push_back(region); + } + + scheduler.EndRendering(); + + bool needs_flush = + Transit(src, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferRead); + needs_flush |= Transit(dst, vk::ImageLayout::eTransferDstOptimal, + vk::PipelineStageFlagBits2::eCopy, vk::AccessFlagBits2::eTransferWrite); + if (needs_flush) { + FlushBarriers(); + } + + scheduler.Record([src_image = src->GetImage(), dst_image = dst->GetImage(), + regions](vk::CommandBuffer cmdbuf) { + cmdbuf.copyImage(src_image, vk::ImageLayout::eTransferSrcOptimal, dst_image, + vk::ImageLayout::eTransferDstOptimal, regions); + }); + + dst->flags |= (src->flags & VideoCore::ImageFlagBits::GpuModified); + dst->flags &= ~VideoCore::ImageFlagBits::Dirty; +} + +void Runtime::CopyImageWithBuffer(VideoCore::Image* src, VideoCore::Image* dst, + const VideoCore::Buffer* buffer, u64 offset) { + const u32 num_mips = std::min(src->info.resources.levels, dst->info.resources.levels); + const u32 num_layers = std::min(src->info.resources.layers, dst->info.resources.layers); + ASSERT(src->info.resources.layers == dst->info.resources.layers && num_mips == 1); + + SetBackingSamples(dst, dst->info.num_samples, false); + SetBackingSamples(src, src->info.num_samples); + + vk::BufferImageCopy buffer_copy = { + .bufferOffset = offset, + .bufferRowLength = 0, + .bufferImageHeight = 0, + .imageSubresource{ + .aspectMask = src->aspect_mask & ~vk::ImageAspectFlagBits::eStencil, + .mipLevel = 0u, + .baseArrayLayer = 0, + .layerCount = num_layers, + }, + .imageOffset = {0, 0, 0}, + .imageExtent = {src->info.size.width, src->info.size.height, src->info.size.depth}, + }; + const auto copy_size = BufferImageCopySize(buffer_copy, src->info.pixel_format); + + scheduler.EndRendering(); + + bool needs_flush = + Transit(src, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferRead); + needs_flush |= Transit(dst, vk::ImageLayout::eTransferDstOptimal, + vk::PipelineStageFlagBits2::eCopy, vk::AccessFlagBits2::eTransferWrite); + needs_flush |= IsBufferAccessed(buffer, offset, copy_size); + if (needs_flush) { + FlushBarriers(); + } + + const auto download_copy = buffer_copy; + buffer_copy.imageSubresource.aspectMask = dst->aspect_mask & ~vk::ImageAspectFlagBits::eStencil; + scheduler.Record([src_image = src->GetImage(), dst_image = dst->GetImage(), + handle = buffer->Handle(), download_copy, + upload_copy = buffer_copy](vk::CommandBuffer cmdbuf) { + cmdbuf.copyImageToBuffer(src_image, vk::ImageLayout::eTransferSrcOptimal, handle, + download_copy); + const vk::MemoryBarrier2 post_copy_barrier = { + .srcStageMask = vk::PipelineStageFlagBits2::eCopy, + .srcAccessMask = vk::AccessFlagBits2::eTransferWrite, + .dstStageMask = vk::PipelineStageFlagBits2::eCopy, + .dstAccessMask = vk::AccessFlagBits2::eTransferRead, + }; + cmdbuf.pipelineBarrier2(vk::DependencyInfo{ + .dependencyFlags = vk::DependencyFlagBits::eByRegion, + .memoryBarrierCount = 1u, + .pMemoryBarriers = &post_copy_barrier, + }); + cmdbuf.copyBufferToImage(handle, dst_image, vk::ImageLayout::eTransferDstOptimal, + upload_copy); + }); + + dst->flags |= (src->flags & VideoCore::ImageFlagBits::GpuModified); + dst->flags &= ~VideoCore::ImageFlagBits::Dirty; +} + +void Runtime::CopyMip(VideoCore::Image* src, VideoCore::Image* dst, u32 mip, u32 slice) { + const auto dst_dim = dst->info.props.is_block ? 2 : 0; + const auto mip_block_w = std::max(dst->info.size.width >> (mip + dst_dim), 1u); + const auto mip_block_h = std::max(dst->info.size.height >> (mip + dst_dim), 1u); + const auto mip_block_p = std::max(dst->info.mips_layout[mip].pitch >> dst_dim, 1u); + + const auto src_dim = src->info.props.is_block ? 2 : 0; + ASSERT(mip_block_w == (src->info.size.width >> src_dim)); + ASSERT(mip_block_h == (src->info.size.height >> src_dim)); + ASSERT(mip_block_p == (src->info.pitch >> src_dim)); + + const auto [src_layers, dst_layers] = + SanitizeCopyLayers(src->info, dst->info, src->info.size.depth); + + const vk::ImageCopy image_copy{ + .srcSubresource{ + .aspectMask = src->aspect_mask, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = src_layers, + }, + .dstSubresource{ + .aspectMask = src->aspect_mask, + .mipLevel = mip, + .baseArrayLayer = slice, + .layerCount = dst_layers, + }, + .extent = {src->info.size.width, src->info.size.height, src->info.size.depth}, + }; + + SetBackingSamples(dst, dst->info.num_samples); + SetBackingSamples(src, src->info.num_samples); + + scheduler.EndRendering(); + + bool needs_flush = + Transit(src, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferRead); + needs_flush |= Transit(dst, vk::ImageLayout::eTransferDstOptimal, + vk::PipelineStageFlagBits2::eCopy, vk::AccessFlagBits2::eTransferWrite); + if (needs_flush) { + FlushBarriers(); + } + + scheduler.Record([src_image = src->GetImage(), dst_image = dst->GetImage(), + image_copy](vk::CommandBuffer cmdbuf) { + cmdbuf.copyImage(src_image, vk::ImageLayout::eTransferSrcOptimal, dst_image, + vk::ImageLayout::eTransferDstOptimal, image_copy); + }); + + dst->flags |= (src->flags & VideoCore::ImageFlagBits::GpuModified); + dst->flags &= ~VideoCore::ImageFlagBits::Dirty; +} + +void Runtime::CopyColorAndDepth(VideoCore::Image* src, VideoCore::Image* dst) { + if (src->info.num_samples == 1 && dst->info.num_samples == 1) { + if (instance.IsMaintenance8Supported() || + src->info.props.is_depth == dst->info.props.is_depth) { + CopyImage(src, dst); + } else { + // Perform depth from/to color copy using the intermediate copy buffer. + static constexpr size_t COPY_BUFFER_SIZE = 128_MB; + const auto copy_ref = + staging_pool.Request(COPY_BUFFER_SIZE, VideoCore::MemoryType::DeviceLocal); + CopyImageWithBuffer(src, dst, copy_ref.buffer, copy_ref.offset); + } + } else if (src->info.num_samples == 1 && dst->info.num_samples > 1 && + dst->info.props.is_depth) { + // Perform a rendering pass to transfer the channels of source as samples in dest. + bool needs_flush = + Transit(src, vk::ImageLayout::eShaderReadOnlyOptimal, + vk::PipelineStageFlagBits2::eFragmentShader, vk::AccessFlagBits2::eShaderRead); + needs_flush |= Transit(dst, vk::ImageLayout::eDepthStencilAttachmentOptimal, + vk::PipelineStageFlagBits2::eEarlyFragmentTests | + vk::PipelineStageFlagBits2::eLateFragmentTests, + vk::AccessFlagBits2::eDepthStencilAttachmentWrite); + if (needs_flush) { + FlushBarriers(); + } + + blit_helper->ReinterpretColorAsMsDepth( + dst->info.size.width, dst->info.size.height, dst->info.num_samples, + src->info.pixel_format, dst->info.pixel_format, src->GetImage(), dst->GetImage()); + } else { + LOG_WARNING(Render_Vulkan, "Unimplemented depth overlap copy"); + } +} + +void Runtime::CopyDepthStencil(VideoCore::Image* src, VideoCore::Image* dst, + const VideoCore::SubresourceRange& sub_range) { + scheduler.EndRendering(); + + bool needs_flush = + Transit(src, vk::ImageLayout::eTransferSrcOptimal, vk::PipelineStageFlagBits2::eCopy, + vk::AccessFlagBits2::eTransferRead); + needs_flush |= Transit(dst, vk::ImageLayout::eTransferDstOptimal, + vk::PipelineStageFlagBits2::eCopy, vk::AccessFlagBits2::eTransferWrite); + if (needs_flush) { + FlushBarriers(); + } + + const auto aspect_mask = src->aspect_mask & dst->aspect_mask; + + const vk::ImageCopy region = { + .srcSubresource{ + .aspectMask = aspect_mask, + .mipLevel = 0, + .baseArrayLayer = sub_range.base.layer, + .layerCount = sub_range.extent.layers, + }, + .srcOffset = {0, 0, 0}, + .dstSubresource{ + .aspectMask = aspect_mask, + .mipLevel = 0, + .baseArrayLayer = sub_range.base.layer, + .layerCount = sub_range.extent.layers, + }, + .dstOffset = {0, 0, 0}, + .extent = {dst->info.size.width, dst->info.size.height, 1}, + }; + + scheduler.Record([src_image = src->GetImage(), dst_image = dst->GetImage(), + region](vk::CommandBuffer cmdbuf) { + cmdbuf.copyImage(src_image, vk::ImageLayout::eTransferSrcOptimal, dst_image, + vk::ImageLayout::eTransferDstOptimal, region); + }); + + dst->flags |= VideoCore::ImageFlagBits::GpuModified; + dst->flags &= ~VideoCore::ImageFlagBits::Dirty; +} + +void Runtime::ResolveImage(VideoCore::Image* src, VideoCore::Image* dst, + const VideoCore::SubresourceRange& src_range, + const VideoCore::SubresourceRange& dst_range) { + SetBackingSamples(dst, 1, false); + scheduler.EndRendering(); + + const bool needs_resolve = src->backing->num_samples != 1; + const auto dst_stage = + needs_resolve ? vk::PipelineStageFlagBits2::eResolve : vk::PipelineStageFlagBits2::eCopy; + + bool needs_flush = Transit(src, vk::ImageLayout::eTransferSrcOptimal, dst_stage, + vk::AccessFlagBits2::eTransferRead); + needs_flush |= Transit(dst, vk::ImageLayout::eTransferDstOptimal, dst_stage, + vk::AccessFlagBits2::eTransferWrite); + if (needs_flush) { + FlushBarriers(); + } + + const auto [src_layers, dst_layers] = SanitizeCopyLayers(src->info, dst->info, 1); + if (!needs_resolve) { + const vk::ImageCopy region = { + .srcSubresource{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .mipLevel = 0, + .baseArrayLayer = src_range.base.layer, + .layerCount = src_layers, + }, + .srcOffset = {0, 0, 0}, + .dstSubresource{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .mipLevel = 0, + .baseArrayLayer = dst_range.base.layer, + .layerCount = dst_layers, + }, + .dstOffset = {0, 0, 0}, + .extent = {src->info.size.width, src->info.size.height, 1}, + }; + scheduler.Record([src_image = src->GetImage(), dst_image = dst->GetImage(), + region](vk::CommandBuffer cmdbuf) { + cmdbuf.copyImage(src_image, vk::ImageLayout::eTransferSrcOptimal, dst_image, + vk::ImageLayout::eTransferDstOptimal, region); + }); + } else { + const vk::ImageResolve region = { + .srcSubresource{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .mipLevel = 0, + .baseArrayLayer = src_range.base.layer, + .layerCount = src_layers, + }, + .srcOffset = {0, 0, 0}, + .dstSubresource{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .mipLevel = 0, + .baseArrayLayer = dst_range.base.layer, + .layerCount = dst_layers, + }, + .dstOffset = {0, 0, 0}, + .extent = {src->info.size.width, src->info.size.height, 1}, + }; + scheduler.Record([src_image = src->GetImage(), dst_image = dst->GetImage(), + region](vk::CommandBuffer cmdbuf) { + cmdbuf.resolveImage(src_image, vk::ImageLayout::eTransferSrcOptimal, dst_image, + vk::ImageLayout::eTransferDstOptimal, region); + }); + } + + dst->flags |= VideoCore::ImageFlagBits::GpuModified; + dst->flags &= ~VideoCore::ImageFlagBits::Dirty; +} + +void Runtime::ClearImage(VideoCore::Image* dst, const VideoCore::SubresourceRange& range, + const vk::ClearValue& clear_value) { + scheduler.EndRendering(); + + const bool needs_flush = + Transit(dst, vk::ImageLayout::eTransferDstOptimal, vk::PipelineStageFlagBits2::eClear, + vk::AccessFlagBits2::eTransferWrite, range); + if (needs_flush) { + FlushBarriers(); + } + + const vk::ImageSubresourceRange vk_range = { + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = range.base.level, + .levelCount = range.extent.levels, + .baseArrayLayer = range.base.layer, + .layerCount = range.extent.layers, + }; + scheduler.Record([image = dst->GetImage(), color = clear_value.color, + vk_range](vk::CommandBuffer cmdbuf) { + cmdbuf.clearColorImage(image, vk::ImageLayout::eTransferDstOptimal, color, vk_range); + }); + + dst->flags |= VideoCore::ImageFlagBits::GpuModified; + dst->flags &= ~VideoCore::ImageFlagBits::Dirty; +} + +void Runtime::SetBackingSamples(VideoCore::Image* image, u32 num_samples, bool copy_backing) { + auto& backing = image->backing; + auto& backing_images = image->backing_images; + const auto& info = image->info; + if (!backing || backing->num_samples == num_samples) { + return; + } + ASSERT_MSG(!image->info.props.is_depth, "Swapping samples is only valid for color images"); + VideoCore::Image::BackingImage* new_backing; + auto it = std::ranges::find(backing_images, num_samples, + &VideoCore::Image::BackingImage::num_samples); + if (it == backing_images.end()) { + auto new_image_ci = backing->image.image_ci; + new_image_ci.samples = LiverpoolToVK::NumSamples(num_samples, image->supported_samples); + + new_backing = &backing_images.emplace_back(); + new_backing->num_samples = num_samples; + new_backing->image = VideoCore::UniqueImage{instance.GetDevice(), instance.GetAllocator()}; + new_backing->image.Create(new_image_ci); + + Vulkan::SetObjectName(instance.GetDevice(), new_backing->image.image, + "Image {}x{}x{} {} {} {:#x}:{:#x} L:{} M:{} S:{} (backing)", + info.size.width, info.size.height, info.size.depth, + AmdGpu::NameOf(info.tile_mode), vk::to_string(info.pixel_format), + info.guest_address, info.guest_size, info.resources.layers, + info.resources.levels, num_samples); + } else { + new_backing = std::addressof(*it); + } + + if (copy_backing) { + scheduler.EndRendering(); + ASSERT(image->info.resources.levels == 1 && image->info.resources.layers == 1); + + // Transition current backing to shader read layout + Transit(image, vk::ImageLayout::eShaderReadOnlyOptimal, + vk::PipelineStageFlagBits2::eFragmentShader, vk::AccessFlagBits2::eShaderRead); + + // Transition dest backing to color attachment layout, not caring of previous contents + constexpr auto dst_stage = vk::PipelineStageFlagBits2::eColorAttachmentOutput; + constexpr auto dst_access = + vk::AccessFlagBits2::eColorAttachmentRead | vk::AccessFlagBits2::eColorAttachmentWrite; + constexpr auto dst_layout = vk::ImageLayout::eColorAttachmentOptimal; + image_barriers.push_back(vk::ImageMemoryBarrier2{ + .srcStageMask = vk::PipelineStageFlagBits2::eAllCommands, + .srcAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite, + .dstStageMask = dst_stage, + .dstAccessMask = dst_access, + .oldLayout = vk::ImageLayout::eUndefined, + .newLayout = dst_layout, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = new_backing->image, + .subresourceRange{ + .aspectMask = image->aspect_mask, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = image->info.resources.layers, + }, + }); + FlushBarriers(); + + // Copy between ms and non ms backing images + blit_helper->CopyBetweenMsImages( + info.size.width, info.size.height, new_backing->num_samples, info.pixel_format, + backing->num_samples > 1, backing->image, new_backing->image); + + // Update current layout in tracker to new backings layout + new_backing->state.layout = dst_layout; + new_backing->state.access_mask = dst_access; + new_backing->state.pl_stage = dst_stage; + } + + backing = new_backing; +} + +bool Runtime::IsBufferAccessed(const VideoCore::Buffer* handle, u64 offset, u64 size, + bool check_read_access) { + const AddressRange range = { + .resource = reinterpret_cast(handle), + .range_start = offset, + .range_end = offset + size - 1, + }; + bool has_access = barrier_tracker.FindRange(range, Access::Write); + if (check_read_access && !has_access) { + has_access |= barrier_tracker.FindRange(range, Access::Read); + } + return has_access; +} + +void Runtime::AccessBuffer(const VideoCore::Buffer* handle, u64 offset, u64 size, + vk::PipelineStageFlags2 src_stage, vk::AccessFlags2 src_access) { + const AddressRange range = { + .resource = reinterpret_cast(handle), + .range_start = offset, + .range_end = offset + size - 1, + }; + + constexpr static vk::AccessFlags2 READ_MASK = + vk::AccessFlagBits2::eIndexRead | vk::AccessFlagBits2::eVertexAttributeRead | + vk::AccessFlagBits2::eUniformRead | vk::AccessFlagBits2::eShaderRead | + vk::AccessFlagBits2::eColorAttachmentRead | + vk::AccessFlagBits2::eDepthStencilAttachmentRead | vk::AccessFlagBits2::eTransferRead | + vk::AccessFlagBits2::eMemoryRead; + + constexpr static vk::AccessFlags2 WRITE_MASK = + vk::AccessFlagBits2::eShaderWrite | vk::AccessFlagBits2::eColorAttachmentWrite | + vk::AccessFlagBits2::eDepthStencilAttachmentWrite | vk::AccessFlagBits2::eTransferWrite | + vk::AccessFlagBits2::eMemoryWrite | vk::AccessFlagBits2::eTransformFeedbackWriteEXT; + + if (src_access & WRITE_MASK) { + barrier_tracker.InsertRange(range, Access::Write); + } + if (src_access & READ_MASK) { + barrier_tracker.InsertRange(range, Access::Read); + } + + memory_barrier.srcStageMask |= src_stage; + memory_barrier.srcAccessMask |= src_access & WRITE_MASK; +} + +void Runtime::FlushBarriers() { + vk::DependencyInfo dep_info{}; + + if (memory_barrier.srcStageMask) { + dep_info.pMemoryBarriers = &memory_barrier; + dep_info.memoryBarrierCount = 1U; + } + if (!image_barriers.empty()) { + dep_info.pImageMemoryBarriers = image_barriers.data(); + dep_info.imageMemoryBarrierCount = static_cast(image_barriers.size()); + } + + if (!dep_info.memoryBarrierCount && !dep_info.imageMemoryBarrierCount) { + return; + } + + scheduler.EndRendering(); + scheduler.Record([memory = memory_barrier, has_memory = dep_info.memoryBarrierCount != 0, + images = image_barriers](vk::CommandBuffer cmdbuf) { + const vk::DependencyInfo info = { + .memoryBarrierCount = has_memory ? 1U : 0U, + .pMemoryBarriers = has_memory ? &memory : nullptr, + .imageMemoryBarrierCount = static_cast(images.size()), + .pImageMemoryBarriers = images.data(), + }; + cmdbuf.pipelineBarrier2(info); + }); + + memory_barrier.srcStageMask = vk::PipelineStageFlagBits2::eNone; + memory_barrier.srcAccessMask = vk::AccessFlagBits2::eNone; + + image_barriers.clear(); + barrier_tracker.Clear(); +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_runtime.h b/gpu/shadps4/video_core/renderer_vulkan/vk_runtime.h new file mode 100644 index 0000000..6ac9f7b --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_runtime.h @@ -0,0 +1,89 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "video_core/buffer_cache/buffer.h" +#include "video_core/renderer_vulkan/vk_barrier_tracker.h" +#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" +#include "video_core/texture_cache/image.h" +#include "video_core/texture_cache/types.h" + +namespace VideoCore { +class BlitHelper; +} // namespace VideoCore + +namespace Vulkan { + +class Instance; +class Scheduler; + +class Runtime { +public: + explicit Runtime(const Instance& instance, Scheduler& scheduler); + ~Runtime() = default; + + const Instance& GetInstance() const { + return instance; + } + + StagingBufferPool& GetStagingPool() { + return staging_pool; + } + + void TickFrame(); + + void CopyBuffer(const VideoCore::Buffer* src, const VideoCore::Buffer* dst, + std::span copies); + + void FillBuffer(const VideoCore::Buffer* dst, u64 offset, u64 size, u32 value); + + void InlineData(VideoCore::Buffer* dst, u64 offset, u32 value); + + bool Transit(VideoCore::Image* image, vk::ImageLayout dst_layout, + vk::PipelineStageFlags2 dst_stage, vk::AccessFlags2 dst_access, + std::optional subres_range = {}); + + void UploadImage(VideoCore::Image* dst, const VideoCore::Buffer* src, + std::span upload_copies); + void DownloadImage(VideoCore::Image* src, const VideoCore::Buffer* dst, + std::span download_copies); + + void CopyImage(VideoCore::Image* src, VideoCore::Image* dst); + void CopyImageWithBuffer(VideoCore::Image* src, VideoCore::Image* dst, + const VideoCore::Buffer* buffer, u64 offset); + void CopyMip(VideoCore::Image* src, VideoCore::Image* dst, u32 mip, u32 slice); + + void CopyColorAndDepth(VideoCore::Image* src, VideoCore::Image* dst); + + void CopyDepthStencil(VideoCore::Image* src, VideoCore::Image* dst, + const VideoCore::SubresourceRange& sub_range); + + void ResolveImage(VideoCore::Image* src, VideoCore::Image* dst, + const VideoCore::SubresourceRange& src_range, + const VideoCore::SubresourceRange& dst_range); + void ClearImage(VideoCore::Image* dst, const VideoCore::SubresourceRange& range, + const vk::ClearValue& clear_value); + + void SetBackingSamples(VideoCore::Image* image, u32 num_samples, bool copy_backing = true); + + void AccessBuffer(const VideoCore::Buffer* handle, u64 offset, u64 size, + vk::PipelineStageFlags2 src_stage, vk::AccessFlags2 src_access); + + bool IsBufferAccessed(const VideoCore::Buffer* handle, u64 offset, u64 size, + bool check_read_access = false); + + void FlushBarriers(); + +private: + const Instance& instance; + Scheduler& scheduler; + std::unique_ptr blit_helper; + StagingBufferPool staging_pool; + BarrierTracker barrier_tracker; + VideoCore::Image::Barriers image_barriers; + vk::MemoryBarrier2 memory_barrier{}; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_scheduler.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_scheduler.cpp new file mode 100644 index 0000000..8887bf2 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_scheduler.cpp @@ -0,0 +1,567 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include + +#include "bbport_toggles.h" +#include "common/assert.h" +#include "common/debug.h" +#include "common/thread.h" +#include "imgui/renderer/texture_manager.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" + +namespace Vulkan { + +std::mutex Scheduler::submit_mutex; + +Scheduler::Scheduler(const Instance& instance, bool threaded_recording) + : instance{instance}, work_semaphore{instance}, command_pool{instance, &work_semaphore} { + // bbport: BB_VK_RECORD_THREAD=0 records on the calling thread. + const char* env = std::getenv("BB_VK_RECORD_THREAD"); + if (threaded_recording && !(env && env[0] == '0')) { + record_chunk = AcquireChunk(); + recorder_thread = std::jthread(std::bind_front(&Scheduler::RecorderThread, this)); + } +#if TRACY_GPU_ENABLED + profiler_scope = reinterpret_cast(std::malloc(sizeof(tracy::VkCtxScope))); +#endif + AllocateWorkerCommandBuffers(); + priority_pending_ops_thread = + std::jthread(std::bind_front(&Scheduler::PriorityPendingOpsThread, this)); +} + +Scheduler::~Scheduler() { + if (recorder_thread.joinable()) { + SyncRecording(); + recorder_thread.request_stop(); + recorder_cv.notify_all(); + recorder_thread.join(); + } +#if TRACY_GPU_ENABLED + std::free(profiler_scope); +#endif +} + +void Scheduler::BeginRendering(const RenderState& new_state) { + if (is_rendering && render_state == new_state) { + return; + } + EndRendering(); + is_rendering = true; + render_state = new_state; + + std::array color_attachments; + for (u32 i = 0; i < render_state.num_color_attachments; ++i) { + const auto& cb = render_state.color_attachments[i]; + color_attachments[i] = vk::RenderingAttachmentInfo{ + .imageView = cb.image_view, + .imageLayout = cb.image_layout, + .loadOp = cb.is_clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, + .storeOp = vk::AttachmentStoreOp::eStore, + .clearValue = vk::ClearValue{.color = vk::ClearColorValue{.uint32 = cb.clear_value}}, + }; + } + + const auto& db = render_state.depth_stencil_attachment; + const vk::RenderingAttachmentInfo depth_attachment = { + .imageView = db.image_view, + .imageLayout = db.image_layout, + .loadOp = db.depth_clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, + .storeOp = vk::AttachmentStoreOp::eStore, + .clearValue = + vk::ClearValue{.depthStencil = vk::ClearDepthStencilValue{.depth = std::bit_cast( + db.clear_value[0])}}, + }; + const vk::RenderingAttachmentInfo stencil_attachment = { + .imageView = db.image_view, + .imageLayout = db.image_layout, + .loadOp = db.stencil_clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, + .storeOp = vk::AttachmentStoreOp::eStore, + .clearValue = vk::ClearValue{.depthStencil = + vk::ClearDepthStencilValue{.stencil = db.clear_value[1]}}, + }; + + const vk::RenderingInfo rendering_info = { + .renderArea = + { + .offset = {0, 0}, + .extent = {render_state.width, render_state.height}, + }, + .layerCount = render_state.num_layers, + .colorAttachmentCount = render_state.num_color_attachments, + .pColorAttachments = color_attachments.data(), + .pDepthAttachment = db.has_depth ? &depth_attachment : nullptr, + .pStencilAttachment = db.has_stencil ? &stencil_attachment : nullptr, + }; + + if (!recorder_thread.joinable()) { + current_cmdbuf.beginRendering(rendering_info); + return; + } + // The attachment infos live on this stack frame: the recorded closure keeps copies. + Record([info = rendering_info, color_attachments, depth_attachment, + stencil_attachment](vk::CommandBuffer cmdbuf) mutable { + info.pColorAttachments = color_attachments.data(); + if (info.pDepthAttachment) { + info.pDepthAttachment = &depth_attachment; + } + if (info.pStencilAttachment) { + info.pStencilAttachment = &stencil_attachment; + } + cmdbuf.beginRendering(info); + }); +} + +void Scheduler::EndRendering() { + if (!is_rendering) { + return; + } + is_rendering = false; + Record([](vk::CommandBuffer cmdbuf) { cmdbuf.endRendering(); }); +} + +void Scheduler::TraceDirectRecording(void* caller) { + static const bool enabled = [] { + const char* env = std::getenv("BB_RECORDER_TRACE"); + return env && env[0] == '1'; + }(); + if (!enabled) { + return; + } + static std::mutex mutex; + static std::unordered_map callers; + static u64 calls; + std::scoped_lock lk{mutex}; + ++callers[caller]; + if (++calls % 2000) { + return; + } + std::vector> top; + for (const auto& [address, count] : callers) { + top.emplace_back(count, address); + } + std::ranges::sort(top, std::greater{}); + for (size_t i = 0; i < std::min(top.size(), 8); ++i) { + Dl_info info{}; + dladdr(top[i].second, &info); + std::printf("Recorder sync caller: %llu x %s+0x%lx\n", + static_cast(top[i].first), + info.dli_fname ? info.dli_fname : "?", + static_cast(reinterpret_cast(top[i].second) - + reinterpret_cast(info.dli_fbase))); + } + callers.clear(); +} + +std::unique_ptr Scheduler::AcquireChunk() { + std::scoped_lock lk{recorder_mutex}; + if (free_chunks.empty()) { + return std::make_unique(); + } + auto chunk = std::move(free_chunks.back()); + free_chunks.pop_back(); + return chunk; +} + +void Scheduler::KickRecording(bool force) { + if (!recorder_thread.joinable()) { + return; + } + // Callers kick where nobody holds the raw command buffer: deferral resumes. + direct_mode = false; + // Batches of tens of KiB keep the queue handoff cheap relative to the work it carries. + if (!force && full_chunks.empty() && record_chunk->Size() < 32 * 1024) { + return; + } + if (full_chunks.empty() && record_chunk->Empty()) { + return; + } + bool wake; + { + std::scoped_lock lk{recorder_mutex}; + for (auto& chunk : full_chunks) { + recorder_queue.push_back(std::move(chunk)); + } + if (!record_chunk->Empty()) { + recorder_queue.push_back(std::move(record_chunk)); + } + wake = recorder_sleeping; + queued_chunks.store(recorder_queue.size(), std::memory_order_release); + } + full_chunks.clear(); + // A busy recorder picks the new chunks up by itself: waking it is a syscall per draw. + if (wake) { + recorder_cv.notify_one(); + } + if (!record_chunk) { + record_chunk = AcquireChunk(); + } +} + +void Scheduler::SyncRecording() { + if (!recorder_thread.joinable()) { + return; + } + KickRecording(true); + std::unique_lock lk{recorder_mutex}; + recorder_idle_cv.wait(lk, [this] { return recorder_queue.empty() && !recorder_busy; }); +} + +void Scheduler::RecorderThread(std::stop_token stoken) { + Common::SetCurrentThreadName("bb:VkRecorder"); + while (true) { + // Spin briefly before sleeping: the next chunk usually follows within microseconds, + // and a sleeping recorder costs the GPU thread a wake-up syscall per kick. + const auto spin_until = std::chrono::steady_clock::now() + std::chrono::microseconds(200); + while (queued_chunks.load(std::memory_order_acquire) == 0 && !stoken.stop_requested() && + std::chrono::steady_clock::now() < spin_until) { + __builtin_ia32_pause(); + } + std::unique_ptr chunk; + { + std::unique_lock lk{recorder_mutex}; + recorder_sleeping = true; + recorder_cv.wait(lk, stoken, [this] { return !recorder_queue.empty(); }); + recorder_sleeping = false; + if (recorder_queue.empty()) { + return; // stop requested + } + chunk = std::move(recorder_queue.front()); + recorder_queue.pop_front(); + queued_chunks.store(recorder_queue.size(), std::memory_order_release); + recorder_busy = true; + } + // current_cmdbuf only changes after SyncRecording(), which waits for this thread. + chunk->Execute(current_cmdbuf); + { + std::scoped_lock lk{recorder_mutex}; + free_chunks.push_back(std::move(chunk)); + recorder_busy = false; + if (recorder_queue.empty()) { + recorder_idle_cv.notify_all(); + } + } + } +} + +void Scheduler::Flush(SubmitInfo& info) { + // When flushing, we only send data to the driver; no waiting is necessary. + SubmitExecution(info); +} + +void Scheduler::Flush() { + SubmitInfo info{}; + Flush(info); +} + +void Scheduler::Finish() { + // When finishing, we need to wait for the submission to have executed on the device. + const u64 presubmit_tick = CurrentTick(); + SubmitInfo info{}; + SubmitExecution(info); + Wait(presubmit_tick); +} + +void Scheduler::Wait(u64 tick) { + if (tick >= work_semaphore.CurrentTick()) { + // Make sure we are not waiting for the current tick without signalling + SubmitInfo info{}; + Flush(info); + } + work_semaphore.Wait(tick); +} + +void Scheduler::PopPendingOperations() { + std::unique_lock lk(pending_ops_mutex); + // bbport: this runs on every draw and dispatch. Querying the timeline semaphore is an + // ioctl, so it is skipped when nothing waits and limited to one query per 250 us. + if (pending_ops.empty()) { + return; + } + if (!work_semaphore.IsFree(pending_ops.front().gpu_tick)) { + const auto now = std::chrono::steady_clock::now(); + if (now - last_pending_refresh < std::chrono::microseconds(250) && + !BbToggle::Disabled(BbToggle::PendingPollLimit)) { + return; + } + last_pending_refresh = now; + work_semaphore.Refresh(); + } + while (!pending_ops.empty() && work_semaphore.IsFree(pending_ops.front().gpu_tick)) { + pending_ops.front().callback(); + pending_ops.pop(); + } +} + +void Scheduler::AllocateWorkerCommandBuffers() { + const vk::CommandBufferBeginInfo begin_info = { + .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit, + }; + + current_cmdbuf = command_pool.Commit(); + Check(current_cmdbuf.begin(begin_info)); + + // Invalidate dynamic state so it gets applied to the new command buffer. + dynamic_state.Invalidate(); + +#if TRACY_GPU_ENABLED + auto* profiler_ctx = instance.GetProfilerContext(); + if (profiler_ctx) { + static const auto scope_loc = + GPU_SCOPE_LOCATION("Guest Frame", MarkersPalette::GpuMarkerColor); + new (profiler_scope) tracy::VkCtxScope{profiler_ctx, &scope_loc, current_cmdbuf, true}; + } +#endif +} + +void Scheduler::SubmitExecution(SubmitInfo& info) { + std::scoped_lock lk{submit_mutex}; + const u64 signal_value = work_semaphore.NextTick(); + +#if TRACY_GPU_ENABLED + auto* profiler_ctx = instance.GetProfilerContext(); + if (profiler_ctx) { + profiler_scope->~VkCtxScope(); + TracyVkCollect(profiler_ctx, current_cmdbuf); + } +#endif + + if (on_submit) { + on_submit(info); + } + + EndRendering(); + SyncRecording(); + Check(current_cmdbuf.end()); + + const vk::Semaphore timeline = work_semaphore.Handle(); + info.AddSignal(timeline, signal_value); + + static constexpr std::array wait_stage_masks = { + vk::PipelineStageFlagBits::eAllCommands, + vk::PipelineStageFlagBits::eColorAttachmentOutput, + }; + + const vk::TimelineSemaphoreSubmitInfo timeline_si = { + .waitSemaphoreValueCount = info.num_wait_semas, + .pWaitSemaphoreValues = info.wait_ticks.data(), + .signalSemaphoreValueCount = info.num_signal_semas, + .pSignalSemaphoreValues = info.signal_ticks.data(), + }; + + const vk::SubmitInfo submit_info = { + .pNext = &timeline_si, + .waitSemaphoreCount = info.num_wait_semas, + .pWaitSemaphores = info.wait_semas.data(), + .pWaitDstStageMask = wait_stage_masks.data(), + .commandBufferCount = 1U, + .pCommandBuffers = ¤t_cmdbuf, + .signalSemaphoreCount = info.num_signal_semas, + .pSignalSemaphores = info.signal_semas.data(), + }; + + ImGui::Core::TextureManager::Submit(); + auto submit_result = instance.GetGraphicsQueue().submit(submit_info, info.fence); + ASSERT_MSG(submit_result != vk::Result::eErrorDeviceLost, "Device lost during submit"); + + work_semaphore.Refresh(); + AllocateWorkerCommandBuffers(); + + // Apply pending operations + PopPendingOperations(); +} + +void Scheduler::PriorityPendingOpsThread(std::stop_token stoken) { + Common::SetCurrentThreadName("shadPS4:GpuSchedPriorityPendingOpsRunner"); + + while (!stoken.stop_requested()) { + PendingOp op; + { + std::unique_lock lk(priority_pending_ops_mutex); + priority_pending_ops_cv.wait(lk, stoken, + [this] { return !priority_pending_ops.empty(); }); + if (stoken.stop_requested()) { + break; + } + + op = std::move(priority_pending_ops.front()); + priority_pending_ops.pop(); + } + + work_semaphore.Wait(op.gpu_tick); + if (stoken.stop_requested()) { + break; + } + + op.callback(); + } +} + +void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf) { + // bbport: a null command buffer only updates the dirty flags, exactly as recording would. + const bool record = static_cast(cmdbuf); + if (dirty_state.viewports) { + dirty_state.viewports = false; + if (record) cmdbuf.setViewportWithCount(viewports); + } + if (dirty_state.scissors) { + dirty_state.scissors = false; + if (record) cmdbuf.setScissorWithCount(scissors); + } + if (dirty_state.depth_test_enabled) { + dirty_state.depth_test_enabled = false; + if (record) cmdbuf.setDepthTestEnable(depth_test_enabled); + } + if (dirty_state.depth_write_enabled) { + dirty_state.depth_write_enabled = false; + // Note that this must be set in a command buffer even if depth test is disabled. + if (record) cmdbuf.setDepthWriteEnable(depth_write_enabled); + } + if (depth_test_enabled && dirty_state.depth_compare_op) { + dirty_state.depth_compare_op = false; + if (record) cmdbuf.setDepthCompareOp(depth_compare_op); + } + if (dirty_state.depth_bounds_test_enabled) { + dirty_state.depth_bounds_test_enabled = false; + if (instance.IsDepthBoundsSupported()) { + if (record) cmdbuf.setDepthBoundsTestEnable(depth_bounds_test_enabled); + } + } + if (depth_bounds_test_enabled && dirty_state.depth_bounds) { + dirty_state.depth_bounds = false; + if (instance.IsDepthBoundsSupported()) { + if (record) cmdbuf.setDepthBounds(depth_bounds_min, depth_bounds_max); + } + } + if (dirty_state.depth_bias_enabled) { + dirty_state.depth_bias_enabled = false; + if (record) cmdbuf.setDepthBiasEnable(depth_bias_enabled); + } + if (depth_bias_enabled && dirty_state.depth_bias) { + dirty_state.depth_bias = false; + if (record) cmdbuf.setDepthBias(depth_bias_constant, depth_bias_clamp, depth_bias_slope); + } + if (dirty_state.stencil_test_enabled) { + dirty_state.stencil_test_enabled = false; + if (record) cmdbuf.setStencilTestEnable(stencil_test_enabled); + } + if (stencil_test_enabled) { + if (dirty_state.stencil_front_ops && dirty_state.stencil_back_ops && + stencil_front_ops == stencil_back_ops) { + dirty_state.stencil_front_ops = false; + dirty_state.stencil_back_ops = false; + if (record) cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eFrontAndBack, stencil_front_ops.fail_op, + stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op, + stencil_front_ops.compare_op); + } else { + if (dirty_state.stencil_front_ops) { + dirty_state.stencil_front_ops = false; + if (record) cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eFront, stencil_front_ops.fail_op, + stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op, + stencil_front_ops.compare_op); + } + if (dirty_state.stencil_back_ops) { + dirty_state.stencil_back_ops = false; + if (record) cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eBack, stencil_back_ops.fail_op, + stencil_back_ops.pass_op, stencil_back_ops.depth_fail_op, + stencil_back_ops.compare_op); + } + } + if (dirty_state.stencil_front_reference && dirty_state.stencil_back_reference && + stencil_front_reference == stencil_back_reference) { + dirty_state.stencil_front_reference = false; + dirty_state.stencil_back_reference = false; + if (record) cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, + stencil_front_reference); + } else { + if (dirty_state.stencil_front_reference) { + dirty_state.stencil_front_reference = false; + if (record) cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFront, + stencil_front_reference); + } + if (dirty_state.stencil_back_reference) { + dirty_state.stencil_back_reference = false; + if (record) cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eBack, stencil_back_reference); + } + } + if (dirty_state.stencil_front_write_mask && dirty_state.stencil_back_write_mask && + stencil_front_write_mask == stencil_back_write_mask) { + dirty_state.stencil_front_write_mask = false; + dirty_state.stencil_back_write_mask = false; + if (record) cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, + stencil_front_write_mask); + } else { + if (dirty_state.stencil_front_write_mask) { + dirty_state.stencil_front_write_mask = false; + if (record) cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFront, + stencil_front_write_mask); + } + if (dirty_state.stencil_back_write_mask) { + dirty_state.stencil_back_write_mask = false; + if (record) cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eBack, stencil_back_write_mask); + } + } + if (dirty_state.stencil_front_compare_mask && dirty_state.stencil_back_compare_mask && + stencil_front_compare_mask == stencil_back_compare_mask) { + dirty_state.stencil_front_compare_mask = false; + dirty_state.stencil_back_compare_mask = false; + if (record) cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack, + stencil_front_compare_mask); + } else { + if (dirty_state.stencil_front_compare_mask) { + dirty_state.stencil_front_compare_mask = false; + if (record) cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFront, + stencil_front_compare_mask); + } + if (dirty_state.stencil_back_compare_mask) { + dirty_state.stencil_back_compare_mask = false; + if (record) cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eBack, + stencil_back_compare_mask); + } + } + } + if (dirty_state.primitive_restart_enable) { + dirty_state.primitive_restart_enable = false; + if (record) cmdbuf.setPrimitiveRestartEnable(primitive_restart_enable); + } + if (dirty_state.rasterizer_discard_enable) { + dirty_state.rasterizer_discard_enable = false; + if (record) cmdbuf.setRasterizerDiscardEnable(rasterizer_discard_enable); + } + if (dirty_state.cull_mode) { + dirty_state.cull_mode = false; + if (record) cmdbuf.setCullMode(cull_mode); + } + if (dirty_state.front_face) { + dirty_state.front_face = false; + if (record) cmdbuf.setFrontFace(front_face); + } + if (dirty_state.blend_constants) { + dirty_state.blend_constants = false; + if (record) cmdbuf.setBlendConstants(blend_constants.data()); + } + if (dirty_state.color_write_masks) { + dirty_state.color_write_masks = false; + if (instance.IsDynamicColorWriteMaskSupported()) { + if (record) cmdbuf.setColorWriteMaskEXT(0, color_write_masks); + } + } + if (dirty_state.line_width) { + dirty_state.line_width = false; + if (record) cmdbuf.setLineWidth(line_width); + } + if (dirty_state.feedback_loop_enabled && instance.IsAttachmentFeedbackLoopLayoutSupported()) { + dirty_state.feedback_loop_enabled = false; + if (record) cmdbuf.setAttachmentFeedbackLoopEnableEXT(feedback_loop_enabled + ? vk::ImageAspectFlagBits::eColor + : vk::ImageAspectFlagBits::eNone); + } +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_scheduler.h b/gpu/shadps4/video_core/renderer_vulkan/vk_scheduler.h new file mode 100644 index 0000000..746cb4f --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_scheduler.h @@ -0,0 +1,613 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bbport_toggles.h" +#include "common/assert.h" +#include "common/interval_set.h" +#include "common/unique_function.h" +#include "video_core/amdgpu/regs_color.h" +#include "video_core/amdgpu/regs_primitive.h" +#include "video_core/renderer_vulkan/vk_resource_pool.h" +#include "video_core/renderer_vulkan/vk_semaphore.h" + +namespace tracy { +class VkCtxScope; +} + +namespace Vulkan { + +class Instance; + +struct RenderAttachment { + vk::ImageView image_view; + vk::ImageLayout image_layout; + std::array clear_value; + union { + u32 is_clear; + struct { + bool has_depth; + bool depth_clear; + bool has_stencil; + bool stencil_clear; + }; + }; +}; +static_assert(std::has_unique_object_representations_v); + +struct RenderState { + std::array color_attachments; + RenderAttachment depth_stencil_attachment; + u16 width; + u16 height; + u16 num_layers; + u16 num_color_attachments; + + bool operator==(const RenderState& other) const noexcept { + return std::memcmp(this, &other, sizeof(RenderState)) == 0; + } +}; +static_assert(std::has_unique_object_representations_v); + +struct SubmitInfo { + std::array wait_semas; + std::array wait_ticks; + std::array signal_semas; + std::array signal_ticks; + vk::Fence fence; + u32 num_wait_semas; + u32 num_signal_semas; + + void AddWait(vk::Semaphore semaphore, u64 tick = 1) { + wait_semas[num_wait_semas] = semaphore; + wait_ticks[num_wait_semas++] = tick; + } + + void AddSignal(vk::Semaphore semaphore, u64 tick = 1) { + signal_semas[num_signal_semas] = semaphore; + signal_ticks[num_signal_semas++] = tick; + } + + void AddSignal(vk::Fence fence) { + this->fence = fence; + } +}; + +using Viewports = boost::container::static_vector; +using Scissors = boost::container::static_vector; +using ColorWriteMasks = std::array; +struct StencilOps { + vk::StencilOp fail_op{}; + vk::StencilOp pass_op{}; + vk::StencilOp depth_fail_op{}; + vk::CompareOp compare_op{}; + + bool operator==(const StencilOps& other) const { + return fail_op == other.fail_op && pass_op == other.pass_op && + depth_fail_op == other.depth_fail_op && compare_op == other.compare_op; + } +}; +struct DynamicState { + struct { + bool viewports : 1; + bool scissors : 1; + + bool depth_test_enabled : 1; + bool depth_write_enabled : 1; + bool depth_compare_op : 1; + + bool depth_bounds_test_enabled : 1; + bool depth_bounds : 1; + + bool depth_bias_enabled : 1; + bool depth_bias : 1; + + bool stencil_test_enabled : 1; + bool stencil_front_ops : 1; + bool stencil_front_reference : 1; + bool stencil_front_write_mask : 1; + bool stencil_front_compare_mask : 1; + bool stencil_back_ops : 1; + bool stencil_back_reference : 1; + bool stencil_back_write_mask : 1; + bool stencil_back_compare_mask : 1; + + bool primitive_restart_enable : 1; + bool rasterizer_discard_enable : 1; + bool cull_mode : 1; + bool front_face : 1; + + bool blend_constants : 1; + bool color_write_masks : 1; + bool line_width : 1; + bool feedback_loop_enabled : 1; + } dirty_state{}; + + Viewports viewports{}; + Scissors scissors{}; + + bool depth_test_enabled{}; + bool depth_write_enabled{}; + vk::CompareOp depth_compare_op{}; + + bool depth_bounds_test_enabled{}; + float depth_bounds_min{}; + float depth_bounds_max{}; + + bool depth_bias_enabled{}; + float depth_bias_constant{}; + float depth_bias_clamp{}; + float depth_bias_slope{}; + + bool stencil_test_enabled{}; + StencilOps stencil_front_ops{}; + u32 stencil_front_reference{}; + u32 stencil_front_write_mask{}; + u32 stencil_front_compare_mask{}; + StencilOps stencil_back_ops{}; + u32 stencil_back_reference{}; + u32 stencil_back_write_mask{}; + u32 stencil_back_compare_mask{}; + + bool primitive_restart_enable{}; + bool rasterizer_discard_enable{}; + vk::CullModeFlags cull_mode{}; + vk::FrontFace front_face{}; + + std::array blend_constants{}; + ColorWriteMasks color_write_masks{}; + float line_width{}; + bool feedback_loop_enabled{}; + + /// Commits the dynamic state to the provided command buffer (a null one only clears the + /// flags that committing clears). + void Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf); + + /// bbport: true when Commit() would record anything. + [[nodiscard]] bool AnyDirty() const noexcept { + static constexpr decltype(dirty_state) clean{}; + return std::memcmp(&dirty_state, &clean, sizeof(dirty_state)) != 0; + } + + /// Invalidates all dynamic state to be flushed into the next command buffer. + void Invalidate() { + std::memset(&dirty_state, 0xFF, sizeof(dirty_state)); + } + + void SetViewports(const Viewports& viewports_) { + if (!std::ranges::equal(viewports, viewports_)) { + viewports = viewports_; + dirty_state.viewports = true; + } + } + + void SetScissors(const Scissors& scissors_) { + if (!std::ranges::equal(scissors, scissors_)) { + scissors = scissors_; + dirty_state.scissors = true; + } + } + + void SetDepthTestEnabled(const bool enabled) { + if (depth_test_enabled != enabled) { + depth_test_enabled = enabled; + dirty_state.depth_test_enabled = true; + } + } + + void SetDepthWriteEnabled(const bool enabled) { + if (depth_write_enabled != enabled) { + depth_write_enabled = enabled; + dirty_state.depth_write_enabled = true; + } + } + + void SetDepthCompareOp(const vk::CompareOp compare_op) { + if (depth_compare_op != compare_op) { + depth_compare_op = compare_op; + dirty_state.depth_compare_op = true; + } + } + + void SetDepthBoundsTestEnabled(const bool enabled) { + if (depth_bounds_test_enabled != enabled) { + depth_bounds_test_enabled = enabled; + dirty_state.depth_bounds_test_enabled = true; + } + } + + void SetDepthBounds(const float min, const float max) { + if (depth_bounds_min != min || depth_bounds_max != max) { + depth_bounds_min = min; + depth_bounds_max = max; + dirty_state.depth_bounds = true; + } + } + + void SetDepthBiasEnabled(const bool enabled) { + if (depth_bias_enabled != enabled) { + depth_bias_enabled = enabled; + dirty_state.depth_bias_enabled = true; + } + } + + void SetDepthBias(const float constant, const float clamp, const float slope) { + if (depth_bias_constant != constant || depth_bias_clamp != clamp || + depth_bias_slope != slope) { + depth_bias_constant = constant; + depth_bias_clamp = clamp; + depth_bias_slope = slope; + dirty_state.depth_bias = true; + } + } + + void SetStencilTestEnabled(const bool enabled) { + if (stencil_test_enabled != enabled) { + stencil_test_enabled = enabled; + dirty_state.stencil_test_enabled = true; + } + } + + void SetStencilOps(const StencilOps& front_ops, const StencilOps& back_ops) { + if (stencil_front_ops != front_ops) { + stencil_front_ops = front_ops; + dirty_state.stencil_front_ops = true; + } + if (stencil_back_ops != back_ops) { + stencil_back_ops = back_ops; + dirty_state.stencil_back_ops = true; + } + } + + void SetStencilReferences(const u32 front_reference, const u32 back_reference) { + if (stencil_front_reference != front_reference) { + stencil_front_reference = front_reference; + dirty_state.stencil_front_reference = true; + } + if (stencil_back_reference != back_reference) { + stencil_back_reference = back_reference; + dirty_state.stencil_back_reference = true; + } + } + + void SetStencilWriteMasks(const u32 front_write_mask, const u32 back_write_mask) { + if (stencil_front_write_mask != front_write_mask) { + stencil_front_write_mask = front_write_mask; + dirty_state.stencil_front_write_mask = true; + } + if (stencil_back_write_mask != back_write_mask) { + stencil_back_write_mask = back_write_mask; + dirty_state.stencil_back_write_mask = true; + } + } + + void SetStencilCompareMasks(const u32 front_compare_mask, const u32 back_compare_mask) { + if (stencil_front_compare_mask != front_compare_mask) { + stencil_front_compare_mask = front_compare_mask; + dirty_state.stencil_front_compare_mask = true; + } + if (stencil_back_compare_mask != back_compare_mask) { + stencil_back_compare_mask = back_compare_mask; + dirty_state.stencil_back_compare_mask = true; + } + } + + void SetPrimitiveRestartEnabled(const bool enabled) { + if (primitive_restart_enable != enabled) { + primitive_restart_enable = enabled; + dirty_state.primitive_restart_enable = true; + } + } + + void SetCullMode(const vk::CullModeFlags cull_mode_) { + if (cull_mode != cull_mode_) { + cull_mode = cull_mode_; + dirty_state.cull_mode = true; + } + } + + void SetFrontFace(const vk::FrontFace front_face_) { + if (front_face != front_face_) { + front_face = front_face_; + dirty_state.front_face = true; + } + } + + void SetBlendConstants(const std::array blend_constants_) { + if (blend_constants != blend_constants_) { + blend_constants = blend_constants_; + dirty_state.blend_constants = true; + } + } + + void SetRasterizerDiscardEnabled(const bool enabled) { + if (rasterizer_discard_enable != enabled) { + rasterizer_discard_enable = enabled; + dirty_state.rasterizer_discard_enable = true; + } + } + + void SetColorWriteMasks(const ColorWriteMasks& color_write_masks_) { + if (!std::ranges::equal(color_write_masks, color_write_masks_)) { + color_write_masks = color_write_masks_; + dirty_state.color_write_masks = true; + } + } + + void SetLineWidth(const float width) { + if (line_width != width) { + line_width = width; + dirty_state.line_width = true; + } + } + + void SetAttachmentFeedbackLoopEnabled(const bool enabled) { + if (feedback_loop_enabled != enabled) { + feedback_loop_enabled = enabled; + dirty_state.feedback_loop_enabled = true; + } + } +}; + +using SubmitFunc = Common::UniqueFunction; + +/// bbport: a block of deferred Vulkan commands. Commands are closures placed in +/// fixed storage (no allocation per command) and run in order on the recording thread. +class RecordChunk { +public: + static constexpr size_t Capacity = 128 * 1024; + + /// Returns false (and leaves `func` untouched) when the chunk has no room. + template + bool Push(Func&& func) { + using Command = TypedCommand>; + static_assert(sizeof(Command) <= Capacity, "recorded command is too large"); + const size_t offset = (used + alignof(Command) - 1) & ~(alignof(Command) - 1); + if (offset + sizeof(Command) > Capacity) { + return false; + } + auto* command = new (storage + offset) Command(std::forward(func)); + if (last) { + last->next = command; + } else { + first = command; + } + last = command; + used = offset + sizeof(Command); + return true; + } + + void Execute(vk::CommandBuffer cmdbuf) { + for (CommandBase* command = first; command;) { + CommandBase* const next = command->next; + command->Execute(cmdbuf); + command->~CommandBase(); + command = next; + } + first = last = nullptr; + used = 0; + } + + [[nodiscard]] bool Empty() const noexcept { + return first == nullptr; + } + + [[nodiscard]] size_t Size() const noexcept { + return used; + } + +private: + struct CommandBase { + virtual ~CommandBase() = default; + virtual void Execute(vk::CommandBuffer cmdbuf) = 0; + CommandBase* next{}; + }; + template + struct TypedCommand final : CommandBase { + explicit TypedCommand(Func&& func_) : func{std::move(func_)} {} + explicit TypedCommand(const Func& func_) : func{func_} {} + void Execute(vk::CommandBuffer cmdbuf) override { + func(cmdbuf); + } + Func func; + }; + + alignas(64) std::byte storage[Capacity]; + size_t used = 0; + CommandBase* first{}; + CommandBase* last{}; +}; + +class Scheduler { +public: + /// `threaded_recording`: Vulkan commands passed to Record() are recorded by a worker thread. + explicit Scheduler(const Instance& instance, bool threaded_recording = false); + ~Scheduler(); + + /// Sends the current execution context to the GPU + /// and increments the scheduler timeline semaphore. + void Flush(SubmitInfo& info); + + /// Sends the current execution context to the GPU + /// and increments the scheduler timeline semaphore. + void Flush(); + + /// Sends the current execution context to the GPU and waits for it to complete. + void Finish(); + + /// Waits for the given tick to trigger on the GPU. + void Wait(u64 tick); + + /// Attempts to execute operations whose tick the GPU has caught up with. + void PopPendingOperations(); + + /// Starts a new rendering scope with provided state. + void BeginRendering(const RenderState& new_state); + + /// Ends current rendering scope. + void EndRendering(); + + /// Sets a function to be called on every scheduler submission. + void SetSubmitCallback(SubmitFunc&& on_submit) { + this->on_submit = std::move(on_submit); + } + + /// Returns the current render state. + const RenderState& GetRenderState() const { + return render_state; + } + + /// Returns the current pipeline dynamic state tracking. + DynamicState& GetDynamicState() { + return dynamic_state; + } + + /// Returns the current command buffer for recording on the calling thread. With threaded + /// recording this first waits until all commands passed to Record() are recorded, then + /// records directly (Record() included, so callers may mix both) until the next + /// KickRecording() or submission. + [[gnu::noinline]] vk::CommandBuffer CommandBuffer() { + if (recorder_thread.joinable() && !direct_mode) { + SyncRecording(); + direct_mode = true; + direct_recordings.fetch_add(1, std::memory_order_relaxed); + TraceDirectRecording(__builtin_return_address(0)); + } + return current_cmdbuf; + } + + /// BB_RECORDER_TRACE=1: prints the most frequent CommandBuffer() callers every 2000 calls. + static void TraceDirectRecording(void* caller); + + /// Records `func(vk::CommandBuffer)` in order with other commands. The closure must own + /// everything it uses (capture by value): it may run later on the recording thread. + template + void Record(Func&& func) { + if (!recorder_thread.joinable() || direct_mode) { + func(current_cmdbuf); + return; + } + if (BbToggle::Disabled(BbToggle::ThreadedRecording)) { + SyncRecording(); + direct_mode = true; + func(current_cmdbuf); + return; + } + if (!record_chunk->Push(std::forward(func))) { + full_chunks.push_back(std::move(record_chunk)); + record_chunk = AcquireChunk(); + const bool pushed = record_chunk->Push(std::forward(func)); + ASSERT(pushed); + } + } + + /// Hands recorded commands to the recording thread. Called at points where no caller holds + /// the raw command buffer (end of draws and dispatches); small batches are kept. + void KickRecording(bool force = false); + + /// Waits until every recorded command is in the command buffer. + void SyncRecording(); + + /// CommandBuffer() calls that waited for a recording thread (BB_FRAME_STATS). + static inline std::atomic direct_recordings{0}; + + /// Returns the current command buffer tick. + [[nodiscard]] u64 CurrentTick() const noexcept { + return work_semaphore.CurrentTick(); + } + + /// Returns true when a tick has been triggered by the GPU. + [[nodiscard]] bool IsFree(u64 tick) noexcept { + if (work_semaphore.IsFree(tick)) { + return true; + } + work_semaphore.Refresh(); + return work_semaphore.IsFree(tick); + } + + /// Returns the scheduler timeline semaphore. + [[nodiscard]] Semaphore* GetWorkSemaphore() noexcept { + return &work_semaphore; + } + + /// Defers an operation until the gpu has reached the current cpu tick. + /// Will be run when submitting or calling PopPendingOperations. + void DeferOperation(Common::UniqueFunction&& func) { + std::unique_lock lk(pending_ops_mutex); + pending_ops.emplace(std::move(func), CurrentTick()); + } + + /// Defers an operation until the gpu has reached the current cpu tick. + /// Runs as soon as possible in another thread. + void DeferPriorityOperation(Common::UniqueFunction&& func) { + { + std::unique_lock lk(priority_pending_ops_mutex); + priority_pending_ops.emplace(std::move(func), CurrentTick()); + } + priority_pending_ops_cv.notify_one(); + } + + static std::mutex submit_mutex; + +private: + void AllocateWorkerCommandBuffers(); + + std::unique_ptr AcquireChunk(); + + void RecorderThread(std::stop_token stoken); + + void SubmitExecution(SubmitInfo& info); + + void PriorityPendingOpsThread(std::stop_token stoken); + +private: + const Instance& instance; + Semaphore work_semaphore; + CommandPool command_pool; + DynamicState dynamic_state; + SubmitFunc on_submit{}; + vk::CommandBuffer current_cmdbuf; + std::condition_variable_any event_cv; + struct PendingOp { + Common::UniqueFunction callback; + u64 gpu_tick; + }; + std::queue pending_ops; + std::recursive_mutex pending_ops_mutex; + std::chrono::steady_clock::time_point last_pending_refresh{}; // bbport + std::queue priority_pending_ops; + std::mutex priority_pending_ops_mutex; + std::condition_variable_any priority_pending_ops_cv; + std::jthread priority_pending_ops_thread; + RenderState render_state; + bool is_rendering = false; + // bbport: threaded recording + std::unique_ptr record_chunk; + std::vector> full_chunks; + std::mutex recorder_mutex; + std::condition_variable_any recorder_cv; + std::condition_variable_any recorder_idle_cv; + std::deque> recorder_queue; + std::vector> free_chunks; + bool recorder_busy = false; + std::atomic queued_chunks{0}; ///< recorder_queue.size() for lock-free polling + bool recorder_sleeping = false; ///< waiting on recorder_cv (guarded by recorder_mutex) + bool direct_mode = false; ///< the command buffer is recorded on the caller's thread + std::jthread recorder_thread; + tracy::VkCtxScope* profiler_scope{}; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_semaphore.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_semaphore.cpp new file mode 100644 index 0000000..5b877d5 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_semaphore.cpp @@ -0,0 +1,70 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_semaphore.h" + +#include "common/assert.h" + +namespace Vulkan { + +constexpr u64 WAIT_TIMEOUT = std::numeric_limits::max(); + +Semaphore::Semaphore(const Instance& instance_) : instance{instance_} { + const vk::StructureChain semaphore_chain = { + vk::SemaphoreCreateInfo{}, + vk::SemaphoreTypeCreateInfo{ + .semaphoreType = vk::SemaphoreType::eTimeline, + .initialValue = 0, + }, + }; + auto [semaphore_result, sem] = + instance.GetDevice().createSemaphoreUnique(semaphore_chain.get()); + ASSERT_MSG(semaphore_result == vk::Result::eSuccess, "Failed to create master semaphore: {}", + vk::to_string(semaphore_result)); + semaphore = std::move(sem); +} + +Semaphore::~Semaphore() = default; + +void Semaphore::Refresh() { + u64 this_tick{}; + u64 counter{}; + do { + this_tick = gpu_tick.load(std::memory_order_acquire); + auto [counter_result, cntr] = instance.GetDevice().getSemaphoreCounterValue(*semaphore); + ASSERT_MSG(counter_result == vk::Result::eSuccess, + "Failed to get master semaphore value: {}", vk::to_string(counter_result)); + counter = cntr; + if (counter < this_tick) { + return; + } + } while (!gpu_tick.compare_exchange_weak(this_tick, counter, std::memory_order_release, + std::memory_order_relaxed)); +} + +void Semaphore::Wait(u64 tick) { + // No need to wait if the GPU is ahead of the tick + if (IsFree(tick)) { + return; + } + // Update the GPU tick and try again + Refresh(); + if (IsFree(tick)) { + return; + } + + // If none of the above is hit, fallback to a regular wait + const vk::SemaphoreWaitInfo wait_info = { + .semaphoreCount = 1, + .pSemaphores = &semaphore.get(), + .pValues = &tick, + }; + + while (instance.GetDevice().waitSemaphores(&wait_info, WAIT_TIMEOUT) != vk::Result::eSuccess) { + } + Refresh(); +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_semaphore.h b/gpu/shadps4/video_core/renderer_vulkan/vk_semaphore.h new file mode 100644 index 0000000..e08ad6c --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_semaphore.h @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan { + +class Instance; +class Scheduler; + +class Semaphore { +public: + explicit Semaphore(const Instance& instance_); + ~Semaphore(); + + [[nodiscard]] u64 CurrentTick() const noexcept { + return current_tick.load(std::memory_order_acquire); + } + + [[nodiscard]] u64 KnownGpuTick() const noexcept { + return gpu_tick.load(std::memory_order_acquire); + } + + [[nodiscard]] bool IsFree(u64 tick) const noexcept { + return KnownGpuTick() >= tick; + } + + [[nodiscard]] u64 NextTick() noexcept { + return current_tick.fetch_add(1, std::memory_order_release); + } + + [[nodiscard]] vk::Semaphore Handle() const noexcept { + return semaphore.get(); + } + + /// Refresh the known GPU tick + void Refresh(); + + /// Waits for a tick to be hit on the GPU + void Wait(u64 tick); + +protected: + const Instance& instance; + vk::UniqueSemaphore semaphore; ///< Timeline semaphore. + std::atomic gpu_tick{0}; ///< Current known GPU tick. + std::atomic current_tick{1}; ///< Current logical tick. +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_shader_hle.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_hle.cpp new file mode 100644 index 0000000..4999349 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_hle.cpp @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_recompiler/info.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_shader_hle.h" + +extern std::unique_ptr liverpool; + +namespace Vulkan { + +static constexpr u64 COPY_SHADER_HASH = 0xfefebf9f; + +static bool ExecuteCopyShaderHLE(const Shader::Info& info, const AmdGpu::ComputeProgram& cs_program, + Rasterizer& rasterizer) { + auto& runtime = rasterizer.GetRuntime(); + auto& buffer_cache = rasterizer.GetBufferCache(); + + // Copy shader defines three formatted buffers as inputs: control, source, and destination. + const auto ctl_buf_sharp = info.buffers[0].GetSharp(info); + const auto src_buf_sharp = info.buffers[1].GetSharp(info); + const auto dst_buf_sharp = info.buffers[2].GetSharp(info); + const auto buf_stride = src_buf_sharp.GetStride(); + ASSERT(buf_stride == dst_buf_sharp.GetStride()); + + struct CopyShaderControl { + u32 dst_idx; + u32 src_idx; + u32 end; + }; + static_assert(sizeof(CopyShaderControl) == 12); + ASSERT(ctl_buf_sharp.GetStride() == sizeof(CopyShaderControl)); + const auto ctl_buf = reinterpret_cast(ctl_buf_sharp.base_address); + + static std::vector copies; + copies.clear(); + copies.reserve(cs_program.dim_x); + + for (u32 i = 0; i < cs_program.dim_x; i++) { + const auto& [dst_idx, src_idx, end] = ctl_buf[i]; + const u32 local_dst_offset = dst_idx * buf_stride; + const u32 local_src_offset = src_idx * buf_stride; + const u32 local_size = (end + 1) * buf_stride; + copies.emplace_back(local_src_offset, local_dst_offset, local_size); + } + + static constexpr vk::DeviceSize MaxDistanceForMerge = 64_MB; + u32 batch_start = 0; + u32 batch_end = 0; + + while (batch_end < copies.size()) { + // Place first copy into the current batch + const auto& copy = copies[batch_start]; + auto src_offset_min = copy.srcOffset; + auto src_offset_max = copy.srcOffset + copy.size; + auto dst_offset_min = copy.dstOffset; + auto dst_offset_max = copy.dstOffset + copy.size; + + for (++batch_end; batch_end < copies.size(); batch_end++) { + // Compute new src and dst bounds if we were to batch this copy + const auto& [src_offset, dst_offset, size] = copies[batch_end]; + auto new_src_offset_min = std::min(src_offset_min, src_offset); + auto new_src_offset_max = std::max(src_offset_max, src_offset + size); + if (new_src_offset_max - new_src_offset_min > MaxDistanceForMerge) { + break; + } + + auto new_dst_offset_min = std::min(dst_offset_min, dst_offset); + auto new_dst_offset_max = std::max(dst_offset_max, dst_offset + size); + if (new_dst_offset_max - new_dst_offset_min > MaxDistanceForMerge) { + break; + } + + // We can batch this copy + src_offset_min = new_src_offset_min; + src_offset_max = new_src_offset_max; + dst_offset_min = new_dst_offset_min; + dst_offset_max = new_dst_offset_max; + } + + // Obtain buffers for the total source and destination ranges. + const auto [src_buf, src_buf_offset] = buffer_cache.ObtainBuffer( + src_buf_sharp.base_address + src_offset_min, src_offset_max - src_offset_min, false); + const auto [dst_buf, dst_buf_offset] = buffer_cache.ObtainBuffer( + dst_buf_sharp.base_address + dst_offset_min, dst_offset_max - dst_offset_min, true); + + // Apply found buffer base. + const auto vk_copies = std::span{copies}.subspan(batch_start, batch_end - batch_start); + for (auto& copy : vk_copies) { + copy.srcOffset = copy.srcOffset - src_offset_min + src_buf_offset; + copy.dstOffset = copy.dstOffset - dst_offset_min + dst_buf_offset; + } + + // Execute buffer copies. + LOG_TRACE(Render_Vulkan, "HLE buffer copy: src_size = {}, dst_size = {}", + src_offset_max - src_offset_min, dst_offset_max - dst_offset_min); + runtime.CopyBuffer(src_buf, dst_buf, vk_copies); + batch_start = batch_end; + } + + return true; +} + +bool ExecuteShaderHLE(const Shader::Info& info, const AmdGpu::Regs& regs, + const AmdGpu::ComputeProgram& cs_program, Rasterizer& rasterizer) { + switch (info.pgm_hash) { + case COPY_SHADER_HASH: + return ExecuteCopyShaderHLE(info, cs_program, rasterizer); + default: + return false; + } +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_shader_hle.h b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_hle.h new file mode 100644 index 0000000..393ef29 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_hle.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace AmdGpu { +struct ComputeProgram; +union Regs; +} // namespace AmdGpu + +namespace Shader { +struct Info; +} + +namespace Vulkan { + +class Rasterizer; + +/// Attempts to execute a shader using HLE if possible. +bool ExecuteShaderHLE(const Shader::Info& info, const AmdGpu::Regs& regs, + const AmdGpu::ComputeProgram& cs_program, Rasterizer& rasterizer); + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_shader_util.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_util.cpp new file mode 100644 index 0000000..b272941 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_util.cpp @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" + +namespace Vulkan { + +vk::ShaderModule CompileSPV(std::span code, vk::Device device) { + const vk::ShaderModuleCreateInfo shader_info = { + .codeSize = code.size() * sizeof(u32), + .pCode = code.data(), + }; + + auto [module_result, module] = device.createShaderModule(shader_info); + ASSERT_MSG(module_result == vk::Result::eSuccess, "Failed to compile SPIR-V shader: {}", + vk::to_string(module_result)); + return module; +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_shader_util.h b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_util.h new file mode 100644 index 0000000..9cc5423 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_shader_util.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan { + +/** + * @brief Creates a vulkan shader module from SPIR-V bytecode. + * @param code The SPIR-V bytecode data. + * @param device The vulkan device handle + */ +vk::ShaderModule CompileSPV(std::span code, vk::Device device); + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp new file mode 100644 index 0000000..95299cb --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -0,0 +1,201 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "common/alignment.h" +#include "common/assert.h" +#include "common/types.h" +#include "core/devtools/widget/gpu_memory.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" + +namespace Vulkan { + +using VideoCore::MemoryType; + +namespace { + +constexpr u64 RING_IDLE_FRAMES = 300; +constexpr u64 LARGE_IDLE_FRAMES = 120; +constexpr u64 LARGE_MIN_GRANULARITY = 64_KB; +constexpr u64 BLOCK_SIZE = 16_MB; + +u64 RoundAllocationSize(u64 size) { + const u64 step = std::max(std::bit_floor(size) / 4, LARGE_MIN_GRANULARITY); + return Common::AlignUp(size, step); +} + +} // Anonymous namespace + +StagingBufferPool::StagingBufferPool(const Instance& instance_, Scheduler& scheduler_) + : instance{instance_}, scheduler{scheduler_} {} + +StagingBufferPool::~StagingBufferPool() = default; + +StagingBufferRef StagingBufferPool::Request(u64 size, MemoryType type, u64 alignment, + bool deferred) { + Ring& ring = rings[u32(type)]; + if (deferred || size > BLOCK_SIZE) { + return RequestLarge(size, type, deferred); + } + return RequestFromRing(ring, size, alignment, type); +} + +StagingBufferRef StagingBufferPool::RequestFromRing(Ring& ring, u64 size, u64 alignment, + MemoryType type) { + Block* best{}; + u64 best_offset{}; + for (size_t i = 0; i < ring.blocks.size(); ++i) { + const size_t index = (ring.current + i) % ring.blocks.size(); + Block* block = &ring.blocks[index]; + if (const auto offset = block->buffer->Reserve(size, alignment, false)) { + ring.current = index; + best = block; + best_offset = *offset; + break; + } + } + + if (!best) { + best = &ring.blocks.emplace_back(Block{ + .buffer = + std::make_unique(instance, scheduler, type, BLOCK_SIZE), + .last_used_frame = frame, + }); + ring.current = ring.blocks.size() - 1; + best_offset = *best->buffer->Reserve(size, alignment, false); + } + + auto& buffer = *best->buffer; + best->last_used_frame = frame; + + StagingBufferRef ref{ + .buffer = &buffer, + .offset = best_offset, + .size = size, + .type = type, + }; + if (!buffer.mapped_data.empty()) { + ref.mapped = buffer.mapped_data.data() + best_offset; + } + return ref; +} + +StagingBufferRef StagingBufferPool::RequestLarge(u64 size, MemoryType type, bool deferred) { + auto& cache = large_caches[u32(type)]; + const u64 max_size = std::max(size + size / 4, RoundAllocationSize(size)); + + LargeBuffer* best{}; + for (LargeBuffer& entry : cache) { + const u64 entry_size = entry.buffer->SizeBytes(); + if (entry.held || entry_size < size || entry_size > max_size || + !scheduler.IsFree(entry.tick)) { + continue; + } + if (!best || entry_size < best->buffer->SizeBytes()) { + best = &entry; + } + } + + if (!best) { + best = &cache.emplace_back(LargeBuffer{ + .buffer = std::make_unique(instance, 0, RoundAllocationSize(size), + type, "StagingBufferPool:Dedicated"), + .tick = 0, + .last_used_frame = frame, + .held = false, + }); + } + + best->tick = scheduler.CurrentTick(); + best->last_used_frame = frame; + best->held = deferred; + + VideoCore::Buffer& buffer = *best->buffer; + StagingBufferRef ref{ + .buffer = &buffer, + .offset = 0, + .size = size, + .type = type, + }; + if (!buffer.mapped_data.empty()) { + ref.mapped = buffer.mapped_data.data(); + } + return ref; +} + +void StagingBufferPool::FreeDeferred(const StagingBufferRef& ref) { + auto& cache = large_caches[u32(ref.type)]; + const auto it = std::ranges::find_if( + cache, [&](const LargeBuffer& entry) { return entry.buffer.get() == ref.buffer; }); + ASSERT_MSG(it != cache.end() && it->held, "FreeDeferred on an allocation that is not held"); + it->held = false; + it->tick = scheduler.CurrentTick(); + it->last_used_frame = frame; +} + +void StagingBufferPool::TickFrame() { + ++frame; + for (Ring& ring : rings) { + TrimRing(ring); + } + for (auto& cache : large_caches) { + TrimLarge(cache); + } + PublishStats(); +} + +void StagingBufferPool::TrimRing(Ring& ring) { + auto& blocks = ring.blocks; + for (size_t i = blocks.size(); i-- > 0;) { + const Block& block = blocks[i]; + if (frame - block.last_used_frame < RING_IDLE_FRAMES || + !scheduler.IsFree(block.buffer->LastTick())) { + continue; + } + blocks.erase(blocks.begin() + i); + if (i < ring.current) { + --ring.current; + } else if (i == ring.current) { + ring.current = 0; + } + } + if (ring.current >= blocks.size()) { + ring.current = 0; + } +} + +void StagingBufferPool::TrimLarge(std::vector& cache) { + std::erase_if(cache, [this](const LargeBuffer& entry) { + return !entry.held && frame - entry.last_used_frame >= LARGE_IDLE_FRAMES && + scheduler.IsFree(entry.tick); + }); +} + +void StagingBufferPool::PublishStats() const { + using namespace Core::Devtools::Widget; + if (!GpuMemoryViewer::IsEnabled()) { + return; + } + static constexpr std::array names = {"DeviceLocal", "HostUncached", + "HostCached"}; + GpuMemoryGroup group{.name = "Staging"}; + for (size_t i = 0; i < NUM_TYPES; ++i) { + u64 bytes = 0; + for (const Block& block : rings[i].blocks) { + bytes += block.buffer->SizeBytes(); + } + for (const LargeBuffer& entry : large_caches[i]) { + bytes += entry.buffer->SizeBytes(); + } + if (bytes != 0) { + group.rows.push_back({.name = names[i], .bytes = bytes}); + } + } + GpuMemoryViewer::Publish(std::move(group)); +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/gpu/shadps4/video_core/renderer_vulkan/vk_staging_buffer_pool.h new file mode 100644 index 0000000..27aaf12 --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_staging_buffer_pool.h @@ -0,0 +1,89 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "common/types.h" +#include "video_core/buffer_cache/buffer.h" + +namespace Vulkan { + +class Instance; +class Scheduler; + +struct StagingBufferRef { + VideoCore::Buffer* buffer{}; + u64 offset{}; + u64 size{}; + u8* mapped{}; + VideoCore::MemoryType type{}; + + void Flush() const noexcept { + buffer->Flush(offset, size); + } + + void Invalidate() const noexcept { + buffer->Invalidate(offset, size); + } +}; + +class StagingBufferPool { +public: + explicit StagingBufferPool(const Instance& instance, Scheduler& scheduler); + ~StagingBufferPool(); + + StagingBufferPool(const StagingBufferPool&) = delete; + StagingBufferPool& operator=(const StagingBufferPool&) = delete; + + /// Requests size bytes of memory of the given type. + [[nodiscard]] StagingBufferRef Request(u64 size, VideoCore::MemoryType type, u64 alignment = 0, + bool deferred = false); + + /// Releases a deferred allocation. It becomes reusable once the current tick completes. + void FreeDeferred(const StagingBufferRef& ref); + + /// Releases idle memory. + void TickFrame(); + +private: + struct Block { + std::unique_ptr buffer; + u64 last_used_frame; + }; + + struct Ring { + std::vector blocks; + size_t current = 0; + }; + + struct LargeBuffer { + std::unique_ptr buffer; + u64 tick; + u64 last_used_frame; + bool held; + }; + + static constexpr size_t NUM_TYPES = 3; + + StagingBufferRef RequestFromRing(Ring& ring, u64 size, u64 alignment, + VideoCore::MemoryType type); + StagingBufferRef RequestLarge(u64 size, VideoCore::MemoryType type, bool deferred); + + void TrimRing(Ring& ring); + void TrimLarge(std::vector& cache); + + void PublishStats() const; + + const Instance& instance; + Scheduler& scheduler; + + std::array rings; + std::array, NUM_TYPES> large_caches; + u64 frame = 0; +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_swapchain.cpp b/gpu/shadps4/video_core/renderer_vulkan/vk_swapchain.cpp new file mode 100644 index 0000000..f2d6bba --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_swapchain.cpp @@ -0,0 +1,343 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/emulator_settings.h" +#include "imgui/renderer/imgui_core.h" +#include "sdl_window.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_swapchain.h" + +namespace Vulkan { + +static constexpr vk::SurfaceFormatKHR SURFACE_FORMAT_HDR = { + .format = vk::Format::eA2B10G10R10UnormPack32, + .colorSpace = vk::ColorSpaceKHR::eHdr10St2084EXT, +}; + +Swapchain::Swapchain(const Instance& instance_, const Frontend::WindowSDL& window_) + : instance{instance_}, window{window_}, surface{CreateSurface(instance.GetInstance(), window)} { + FindPresentFormat(); + FindPresentMode(); + + Create(window.GetWidth(), window.GetHeight()); + ImGui::Core::Initialize(instance, window, image_count, surface_format.format); +} + +Swapchain::~Swapchain() { + Destroy(); + instance.GetInstance().destroySurfaceKHR(surface); +} + +void Swapchain::Create(u32 width_, u32 height_) { + width = width_; + height = height_; + needs_recreation = false; + + Destroy(); + + SetSurfaceProperties(); + + const std::array queue_family_indices = { + instance.GetGraphicsQueueFamilyIndex(), + instance.GetPresentQueueFamilyIndex(), + }; + + const bool exclusive = queue_family_indices[0] == queue_family_indices[1]; + const u32 queue_family_indices_count = exclusive ? 1u : 2u; + const vk::SharingMode sharing_mode = + exclusive ? vk::SharingMode::eExclusive : vk::SharingMode::eConcurrent; + const auto format = needs_hdr ? SURFACE_FORMAT_HDR : surface_format; + const vk::SwapchainCreateInfoKHR swapchain_info = { + .surface = surface, + .minImageCount = image_count, + .imageFormat = format.format, + .imageColorSpace = format.colorSpace, + .imageExtent = extent, + .imageArrayLayers = 1, + .imageUsage = vk::ImageUsageFlagBits::eColorAttachment | + vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst, + .imageSharingMode = sharing_mode, + .queueFamilyIndexCount = queue_family_indices_count, + .pQueueFamilyIndices = queue_family_indices.data(), + .preTransform = transform, + .compositeAlpha = composite_alpha, + .presentMode = present_mode, + .clipped = true, + .oldSwapchain = nullptr, + }; + + auto [swapchain_result, chain] = instance.GetDevice().createSwapchainKHR(swapchain_info); + ASSERT_MSG(swapchain_result == vk::Result::eSuccess, "Failed to create swapchain: {}", + vk::to_string(swapchain_result)); + swapchain = chain; + + SetupImages(); + RefreshSemaphores(); +} + +void Swapchain::Recreate(u32 width_, u32 height_) { + LOG_DEBUG(Render_Vulkan, "Recreate the swapchain: width={} height={} HDR={}", width_, height_, + needs_hdr); + Create(width_, height_); +} + +void Swapchain::SetHDR(bool hdr) { + if (needs_hdr == hdr) { + return; + } + + auto result = instance.GetDevice().waitIdle(); + if (result != vk::Result::eSuccess) { + LOG_WARNING(ImGui, "Failed to wait for Vulkan device idle on mode change: {}", + vk::to_string(result)); + } + + needs_hdr = hdr; + Recreate(width, height); + ImGui::Core::OnSurfaceFormatChange(needs_hdr ? SURFACE_FORMAT_HDR.format + : surface_format.format); +} + +bool Swapchain::AcquireNextImage() { + vk::Device device = instance.GetDevice(); + vk::Result result = + device.acquireNextImageKHR(swapchain, std::numeric_limits::max(), + image_acquired[frame_index], VK_NULL_HANDLE, &image_index); + + switch (result) { + case vk::Result::eSuccess: + break; + case vk::Result::eSuboptimalKHR: + case vk::Result::eErrorSurfaceLostKHR: + case vk::Result::eErrorOutOfDateKHR: + case vk::Result::eErrorUnknown: + needs_recreation = true; + break; + default: + LOG_CRITICAL(Render_Vulkan, "Swapchain acquire returned unknown result {}", + vk::to_string(result)); + UNREACHABLE(); + break; + } + + return !needs_recreation; +} + +bool Swapchain::Present() { + const vk::PresentInfoKHR present_info = { + .waitSemaphoreCount = 1, + .pWaitSemaphores = &present_ready[image_index], + .swapchainCount = 1, + .pSwapchains = &swapchain, + .pImageIndices = &image_index, + }; + + auto result = instance.GetPresentQueue().presentKHR(present_info); + if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) { + needs_recreation = true; + } else { + ASSERT_MSG(result == vk::Result::eSuccess, "Swapchain presentation failed: {}", + vk::to_string(result)); + } + + frame_index = (frame_index + 1) % image_count; + + return !needs_recreation; +} + +void Swapchain::FindPresentFormat() { + const auto [formats_result, formats] = + instance.GetPhysicalDevice().getSurfaceFormatsKHR(surface); + ASSERT_MSG(formats_result == vk::Result::eSuccess, "Failed to query surface formats: {}", + vk::to_string(formats_result)); + + // Check if the device supports HDR formats. Here we care of Rec.2020 PQ only as it is expected + // game output. Other variants as e.g. linear Rec.2020 will require additional color space + // rotation + supports_hdr = + std::find_if(formats.begin(), formats.end(), [](const vk::SurfaceFormatKHR& format) { + return format == SURFACE_FORMAT_HDR; + }) != formats.end(); + // Also make sure that user allowed us to use HDR + supports_hdr &= EmulatorSettings.IsHdrAllowed(); + + // If there is a single undefined surface format, the device doesn't care, so we'll just use + // RGBA sRGB. + if (formats[0].format == vk::Format::eUndefined) { + surface_format.format = vk::Format::eR8G8B8A8Unorm; + surface_format.colorSpace = vk::ColorSpaceKHR::eSrgbNonlinear; + return; + } + + // Try to find a suitable format. + for (const vk::SurfaceFormatKHR& sformat : formats) { + vk::Format format = sformat.format; + if (format != vk::Format::eR8G8B8A8Unorm && format != vk::Format::eB8G8R8A8Unorm) { + continue; + } + + surface_format.format = format; + surface_format.colorSpace = sformat.colorSpace; + return; + } + + UNREACHABLE_MSG("Unable to find required swapchain format!"); +} + +void Swapchain::FindPresentMode() { + const auto [modes_result, modes] = + instance.GetPhysicalDevice().getSurfacePresentModesKHR(surface); + if (modes_result != vk::Result::eSuccess) { + LOG_ERROR(Render, "Failed to query available present modes, falling back to Fifo as " + "guaranteed supported option."); + present_mode = vk::PresentModeKHR::eFifo; + return; + } + + const auto requested_mode = EmulatorSettings.GetPresentMode(); + if (requested_mode == "Mailbox") { + present_mode = vk::PresentModeKHR::eMailbox; + } else if (requested_mode == "Fifo") { + present_mode = vk::PresentModeKHR::eFifo; + } else if (requested_mode == "Immediate") { + present_mode = vk::PresentModeKHR::eImmediate; + } else { + LOG_ERROR(Render_Vulkan, "Unknown present mode {}, defaulting to Mailbox.", + EmulatorSettings.GetPresentMode()); + present_mode = vk::PresentModeKHR::eMailbox; + } + + if (std::ranges::find(modes, present_mode) == modes.cend()) { + // FIFO is guaranteed to be supported by the Vulkan spec. + constexpr auto fallback = vk::PresentModeKHR::eFifo; + LOG_WARNING(Render, "Requested present mode {} is not supported, falling back to {}.", + vk::to_string(present_mode), vk::to_string(fallback)); + present_mode = fallback; + } +} + +void Swapchain::SetSurfaceProperties() { + const auto [capabilities_result, capabilities] = + instance.GetPhysicalDevice().getSurfaceCapabilitiesKHR(surface); + ASSERT_MSG(capabilities_result == vk::Result::eSuccess, + "Failed to query surface capabilities: {}", vk::to_string(capabilities_result)); + + extent = capabilities.currentExtent; + if (capabilities.currentExtent.width == std::numeric_limits::max()) { + extent.width = std::max(capabilities.minImageExtent.width, + std::min(capabilities.maxImageExtent.width, width)); + extent.height = std::max(capabilities.minImageExtent.height, + std::min(capabilities.maxImageExtent.height, height)); + } + + // Select number of images in swap chain, we prefer one buffer in the background to work on + image_count = capabilities.minImageCount + 1; + if (capabilities.maxImageCount > 0) { + image_count = std::min(image_count, capabilities.maxImageCount); + } + + // Prefer identity transform if possible + transform = vk::SurfaceTransformFlagBitsKHR::eIdentity; + if (!(capabilities.supportedTransforms & transform)) { + transform = capabilities.currentTransform; + } + + // Opaque is not supported everywhere. + composite_alpha = vk::CompositeAlphaFlagBitsKHR::eOpaque; + if (!(capabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eOpaque)) { + composite_alpha = vk::CompositeAlphaFlagBitsKHR::eInherit; + } +} + +void Swapchain::Destroy() { + vk::Device device = instance.GetDevice(); + const auto wait_result = device.waitIdle(); + if (wait_result != vk::Result::eSuccess) { + LOG_WARNING(Render_Vulkan, "Failed to wait for device to become idle: {}", + vk::to_string(wait_result)); + } + + for (auto& image_view : images_view) { + device.destroyImageView(image_view); + } + images_view.clear(); + + if (swapchain) { + device.destroySwapchainKHR(swapchain); + } + + for (const auto& sem : image_acquired) { + device.destroySemaphore(sem); + } + for (const auto& sem : present_ready) { + device.destroySemaphore(sem); + } + + image_acquired.clear(); + present_ready.clear(); +} + +void Swapchain::RefreshSemaphores() { + const vk::Device device = instance.GetDevice(); + image_acquired.resize(image_count); + present_ready.resize(image_count); + + for (vk::Semaphore& semaphore : image_acquired) { + auto [semaphore_result, sem] = device.createSemaphore({}); + ASSERT_MSG(semaphore_result == vk::Result::eSuccess, + "Failed to create image acquired semaphore: {}", + vk::to_string(semaphore_result)); + semaphore = sem; + } + for (vk::Semaphore& semaphore : present_ready) { + auto [semaphore_result, sem] = device.createSemaphore({}); + ASSERT_MSG(semaphore_result == vk::Result::eSuccess, + "Failed to create present ready semaphore: {}", vk::to_string(semaphore_result)); + semaphore = sem; + } + + for (u32 i = 0; i < image_count; ++i) { + SetObjectName(device, image_acquired[i], "Swapchain Semaphore: image_acquired {}", i); + SetObjectName(device, present_ready[i], "Swapchain Semaphore: present_ready {}", i); + } +} + +void Swapchain::SetupImages() { + vk::Device device = instance.GetDevice(); + auto [images_result, imgs] = device.getSwapchainImagesKHR(swapchain); + ASSERT_MSG(images_result == vk::Result::eSuccess, "Failed to create swapchain images: {}", + vk::to_string(images_result)); + images = std::move(imgs); + image_count = static_cast(images.size()); + images_view.resize(image_count); + for (u32 i = 0; i < image_count; ++i) { + if (images_view[i]) { + device.destroyImageView(images_view[i]); + } + auto [im_view_result, im_view] = device.createImageView(vk::ImageViewCreateInfo{ + .image = images[i], + .viewType = vk::ImageViewType::e2D, + .format = needs_hdr ? SURFACE_FORMAT_HDR.format : surface_format.format, + .subresourceRange = + { + .aspectMask = vk::ImageAspectFlagBits::eColor, + .levelCount = 1, + .layerCount = 1, + }, + }); + ASSERT_MSG(im_view_result == vk::Result::eSuccess, "Failed to create image view: {}", + vk::to_string(im_view_result)); + images_view[i] = im_view; + } + + for (u32 i = 0; i < image_count; ++i) { + SetObjectName(device, images[i], "Swapchain Image {}", i); + SetObjectName(device, images_view[i], "Swapchain ImageView {}", i); + } +} + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/renderer_vulkan/vk_swapchain.h b/gpu/shadps4/video_core/renderer_vulkan/vk_swapchain.h new file mode 100644 index 0000000..826705d --- /dev/null +++ b/gpu/shadps4/video_core/renderer_vulkan/vk_swapchain.h @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Frontend { +class WindowSDL; +} + +namespace Vulkan { + +class Instance; +class Scheduler; + +class Swapchain { +public: + explicit Swapchain(const Instance& instance, const Frontend::WindowSDL& window); + ~Swapchain(); + + /// Creates (or recreates) the swapchain with a given size. + void Create(u32 width, u32 height); + + /// Recreates the swapchain with a given size and current surface. + void Recreate(u32 width, u32 height); + + /// Acquires the next image in the swapchain. + bool AcquireNextImage(); + + /// Presents the current image and move to the next one + bool Present(); + + vk::SurfaceKHR GetSurface() const { + return surface; + } + + vk::Image Image() const { + return images[image_index]; + } + + vk::ImageView ImageView() const { + return images_view[image_index]; + } + + vk::SurfaceFormatKHR GetSurfaceFormat() const { + return surface_format; + } + + vk::SwapchainKHR GetHandle() const { + return swapchain; + } + + u32 GetWidth() const { + return width; + } + + u32 GetHeight() const { + return height; + } + + u32 GetImageCount() const { + return image_count; + } + + u32 GetFrameIndex() const { + return frame_index; + } + + vk::Extent2D GetExtent() const { + return extent; + } + + [[nodiscard]] vk::Semaphore GetImageAcquiredSemaphore() const { + return image_acquired[frame_index]; + } + + [[nodiscard]] vk::Semaphore GetPresentReadySemaphore() const { + return present_ready[image_index]; + } + + bool HasHDR() const { + return supports_hdr; + } + + void SetHDR(bool hdr); + + bool GetHDR() const { + return needs_hdr; + } + +private: + /// Selects the best available swapchain image format + void FindPresentFormat(); + + /// Selects the best available present mode + void FindPresentMode(); + + /// Sets the surface properties according to device capabilities + void SetSurfaceProperties(); + + /// Destroys current swapchain resources + void Destroy(); + + /// Performs creation of image views and framebuffers from the swapchain images + void SetupImages(); + + /// Creates the image acquired and present ready semaphores + void RefreshSemaphores(); + +private: + const Instance& instance; + const Frontend::WindowSDL& window; + vk::SwapchainKHR swapchain{}; + vk::SurfaceKHR surface{}; + vk::SurfaceFormatKHR surface_format; + vk::Format view_format; + vk::PresentModeKHR present_mode; + vk::Extent2D extent; + vk::SurfaceTransformFlagBitsKHR transform; + vk::CompositeAlphaFlagBitsKHR composite_alpha; + std::vector images; + std::vector images_view; + std::vector image_acquired; + std::vector present_ready; + u32 width = 0; + u32 height = 0; + u32 image_count = 0; + u32 image_index = 0; + u32 frame_index = 0; + bool needs_recreation = true; + bool needs_hdr = false; // The game requested HDR swapchain + bool supports_hdr = false; // SC supports HDR output +}; + +} // namespace Vulkan diff --git a/gpu/shadps4/video_core/texture_cache/blit_helper.cpp b/gpu/shadps4/video_core/texture_cache/blit_helper.cpp new file mode 100644 index 0000000..03427b7 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/blit_helper.cpp @@ -0,0 +1,435 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" +#include "video_core/texture_cache/blit_helper.h" +#include "video_core/texture_cache/image.h" + +#include "video_core/host_shaders/color_to_ms_depth_frag.h" +#include "video_core/host_shaders/fs_tri_vert.h" +#include "video_core/host_shaders/ms_image_blit_frag.h" +#include "video_core/host_shaders/ms_image_blit_msaa_frag.h" + +namespace VideoCore { + +static vk::SampleCountFlagBits ToSampleCount(u32 num_samples) { + switch (num_samples) { + case 1: + return vk::SampleCountFlagBits::e1; + case 2: + return vk::SampleCountFlagBits::e2; + case 4: + return vk::SampleCountFlagBits::e4; + case 8: + return vk::SampleCountFlagBits::e8; + case 16: + return vk::SampleCountFlagBits::e16; + default: + UNREACHABLE_MSG("Unknown samples count = {}", num_samples); + } +} + +BlitHelper::BlitHelper(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_) + : instance{instance_}, scheduler{scheduler_} { + CreateShaders(); + CreatePipelineLayouts(); +} + +BlitHelper::~BlitHelper() { + const auto device = instance.GetDevice(); + device.destroy(fs_tri_vertex); + device.destroy(color_to_ms_depth_frag); + device.destroy(src_msaa_copy_frag); + device.destroy(src_non_msaa_copy_frag); +} + +void BlitHelper::ReinterpretColorAsMsDepth(u32 width, u32 height, u32 num_samples, + vk::Format src_pixel_format, vk::Format dst_pixel_format, + vk::Image source, vk::Image dest) { + const vk::ImageViewUsageCreateInfo color_usage_ci{.usage = vk::ImageUsageFlagBits::eSampled}; + const vk::ImageViewCreateInfo color_view_ci = { + .pNext = &color_usage_ci, + .image = source, + .viewType = vk::ImageViewType::e2D, + .format = src_pixel_format, + .subresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0U, + .levelCount = 1U, + .baseArrayLayer = 0U, + .layerCount = 1U, + }, + }; + const auto [color_view_result, color_view] = + instance.GetDevice().createImageView(color_view_ci); + ASSERT_MSG(color_view_result == vk::Result::eSuccess, "Failed to create image view: {}", + vk::to_string(color_view_result)); + const vk::ImageViewUsageCreateInfo depth_usage_ci{ + .usage = vk::ImageUsageFlagBits::eDepthStencilAttachment}; + const vk::ImageViewCreateInfo depth_view_ci = { + .pNext = &depth_usage_ci, + .image = dest, + .viewType = vk::ImageViewType::e2D, + .format = dst_pixel_format, + .subresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eDepth, + .baseMipLevel = 0U, + .levelCount = 1U, + .baseArrayLayer = 0U, + .layerCount = 1U, + }, + }; + const auto [depth_view_result, depth_view] = + instance.GetDevice().createImageView(depth_view_ci); + ASSERT_MSG(depth_view_result == vk::Result::eSuccess, "Failed to create image view: {}", + vk::to_string(depth_view_result)); + scheduler.DeferOperation([device = instance.GetDevice(), color_view, depth_view] { + device.destroyImageView(color_view); + device.destroyImageView(depth_view); + }); + + Vulkan::RenderState state{}; + state.width = width; + state.height = height; + state.num_layers = 1; + state.depth_stencil_attachment.image_view = depth_view; + state.depth_stencil_attachment.image_layout = vk::ImageLayout::eDepthAttachmentOptimal; + state.depth_stencil_attachment.has_depth = true; + state.depth_stencil_attachment.depth_clear = true; + scheduler.BeginRendering(state); + + const auto cmdbuf = scheduler.CommandBuffer(); + const vk::DescriptorImageInfo image_info = { + .sampler = VK_NULL_HANDLE, + .imageView = color_view, + .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + }; + const vk::WriteDescriptorSet texture_write = { + .dstSet = VK_NULL_HANDLE, + .dstBinding = 0U, + .dstArrayElement = 0U, + .descriptorCount = 1U, + .descriptorType = vk::DescriptorType::eSampledImage, + .pImageInfo = &image_info, + }; + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *single_texture_pl_layout, 0U, + texture_write); + + const MsPipelineKey key{num_samples, dst_pixel_format, false}; + auto it = std::ranges::find(color_to_ms_depth_pl, key, &MsPipeline::first); + if (it == color_to_ms_depth_pl.end()) { + CreateColorToMSDepthPipeline(key); + it = --color_to_ms_depth_pl.end(); + } + cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, *it->second); + + const vk::Viewport viewport = { + .x = 0, + .y = 0, + .width = float(state.width), + .height = float(state.height), + .minDepth = 0.f, + .maxDepth = 1.f, + }; + cmdbuf.setViewportWithCount(viewport); + + const vk::Rect2D scissor = { + .offset = {0, 0}, + .extent = {state.width, state.height}, + }; + cmdbuf.setScissorWithCount(scissor); + + cmdbuf.draw(3, 1, 0, 0); + + scheduler.EndRendering(); + scheduler.GetDynamicState().Invalidate(); +} + +void BlitHelper::CopyBetweenMsImages(u32 width, u32 height, u32 num_samples, + vk::Format pixel_format, bool src_msaa, vk::Image source, + vk::Image dest) { + const vk::ImageViewUsageCreateInfo src_usage_ci{.usage = vk::ImageUsageFlagBits::eSampled}; + const vk::ImageViewCreateInfo src_view_ci = { + .pNext = &src_usage_ci, + .image = source, + .viewType = vk::ImageViewType::e2D, + .format = pixel_format, + .subresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0U, + .levelCount = 1U, + .baseArrayLayer = 0U, + .layerCount = 1U, + }, + }; + const auto [src_view_result, src_view] = instance.GetDevice().createImageView(src_view_ci); + ASSERT_MSG(src_view_result == vk::Result::eSuccess, "Failed to create image view: {}", + vk::to_string(src_view_result)); + + const vk::ImageViewUsageCreateInfo dst_usage_ci{.usage = + vk::ImageUsageFlagBits::eColorAttachment}; + const vk::ImageViewCreateInfo dst_view_ci = { + .pNext = &dst_usage_ci, + .image = dest, + .viewType = vk::ImageViewType::e2D, + .format = pixel_format, + .subresourceRange{ + .aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0U, + .levelCount = 1U, + .baseArrayLayer = 0U, + .layerCount = 1U, + }, + }; + const auto [dst_view_result, dst_view] = instance.GetDevice().createImageView(dst_view_ci); + ASSERT_MSG(dst_view_result == vk::Result::eSuccess, "Failed to create image view: {}", + vk::to_string(dst_view_result)); + scheduler.DeferOperation([device = instance.GetDevice(), src_view, dst_view] { + device.destroyImageView(src_view); + device.destroyImageView(dst_view); + }); + + Vulkan::RenderState state{}; + state.width = width; + state.height = height; + state.num_layers = 1; + state.num_color_attachments = 1; + state.color_attachments[0].image_view = dst_view; + state.color_attachments[0].image_layout = vk::ImageLayout::eColorAttachmentOptimal; + state.color_attachments[0].is_clear = true; + scheduler.BeginRendering(state); + + const auto cmdbuf = scheduler.CommandBuffer(); + const vk::DescriptorImageInfo image_info = { + .sampler = VK_NULL_HANDLE, + .imageView = src_view, + .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + }; + const vk::WriteDescriptorSet texture_write = { + .dstSet = VK_NULL_HANDLE, + .dstBinding = 0U, + .dstArrayElement = 0U, + .descriptorCount = 1U, + .descriptorType = vk::DescriptorType::eSampledImage, + .pImageInfo = &image_info, + }; + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *single_texture_pl_layout, 0U, + texture_write); + + const MsPipelineKey key{num_samples, pixel_format, src_msaa}; + auto it = std::ranges::find(ms_image_copy_pl, key, &MsPipeline::first); + if (it == ms_image_copy_pl.end()) { + CreateMsCopyPipeline(key); + it = --ms_image_copy_pl.end(); + } + cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, *it->second); + + const vk::Viewport viewport = { + .x = 0, + .y = 0, + .width = float(state.width), + .height = float(state.height), + .minDepth = 0.f, + .maxDepth = 1.f, + }; + cmdbuf.setViewportWithCount(viewport); + + const vk::Rect2D scissor = { + .offset = {0, 0}, + .extent = {state.width, state.height}, + }; + cmdbuf.setScissorWithCount(scissor); + + cmdbuf.draw(3, 1, 0, 0); + + scheduler.EndRendering(); + scheduler.GetDynamicState().Invalidate(); +} + +void BlitHelper::CreateShaders() { + const auto device = instance.GetDevice(); + fs_tri_vertex = Vulkan::CompileSPV(FS_TRI_VERT, device); + color_to_ms_depth_frag = Vulkan::CompileSPV(COLOR_TO_MS_DEPTH_FRAG, device); + src_msaa_copy_frag = Vulkan::CompileSPV(MS_IMAGE_BLIT_MSAA_FRAG, device); + src_non_msaa_copy_frag = Vulkan::CompileSPV(MS_IMAGE_BLIT_FRAG, device); +} + +void BlitHelper::CreatePipelineLayouts() { + const vk::DescriptorSetLayoutBinding texture_binding = { + .binding = 0, + .descriptorType = vk::DescriptorType::eSampledImage, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eFragment, + }; + const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = { + .flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR, + .bindingCount = 1U, + .pBindings = &texture_binding, + }; + auto [desc_layout_result, desc_layout] = + instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci); + single_texture_descriptor_set_layout = std::move(desc_layout); + const vk::DescriptorSetLayout set_layout = *single_texture_descriptor_set_layout; + const vk::PipelineLayoutCreateInfo layout_info = { + .setLayoutCount = 1U, + .pSetLayouts = &set_layout, + .pushConstantRangeCount = 0U, + .pPushConstantRanges = nullptr, + }; + auto [layout_result, pipeline_layout] = + instance.GetDevice().createPipelineLayoutUnique(layout_info); + ASSERT_MSG(layout_result == vk::Result::eSuccess, + "Failed to create graphics pipeline layout: {}", vk::to_string(layout_result)); + Vulkan::SetObjectName(instance.GetDevice(), *pipeline_layout, "Single texture pipeline layout"); + single_texture_pl_layout = std::move(pipeline_layout); +} + +void BlitHelper::CreateColorToMSDepthPipeline(const MsPipelineKey& key) { + const vk::PipelineInputAssemblyStateCreateInfo input_assembly = { + .topology = vk::PrimitiveTopology::eTriangleList, + }; + const vk::PipelineMultisampleStateCreateInfo multisampling = { + .rasterizationSamples = ToSampleCount(key.num_samples), + }; + const vk::PipelineDepthStencilStateCreateInfo depth_state = { + .depthTestEnable = true, + .depthWriteEnable = true, + .depthCompareOp = vk::CompareOp::eAlways, + }; + const std::array dynamic_states = {vk::DynamicState::eViewportWithCount, + vk::DynamicState::eScissorWithCount}; + const vk::PipelineDynamicStateCreateInfo dynamic_info = { + .dynamicStateCount = static_cast(dynamic_states.size()), + .pDynamicStates = dynamic_states.data(), + }; + + std::array shader_stages; + shader_stages[0] = { + .stage = vk::ShaderStageFlagBits::eVertex, + .module = fs_tri_vertex, + .pName = "main", + }; + shader_stages[1] = { + .stage = vk::ShaderStageFlagBits::eFragment, + .module = color_to_ms_depth_frag, + .pName = "main", + }; + + const vk::PipelineRenderingCreateInfo pipeline_rendering_ci = { + .colorAttachmentCount = 0U, + .pColorAttachmentFormats = nullptr, + .depthAttachmentFormat = key.attachment_format, + .stencilAttachmentFormat = vk::Format::eUndefined, + }; + + const vk::PipelineColorBlendStateCreateInfo color_blending{}; + const vk::PipelineViewportStateCreateInfo viewport_info{}; + const vk::PipelineVertexInputStateCreateInfo vertex_input_info{}; + const vk::PipelineRasterizationStateCreateInfo raster_state{.lineWidth = 1.f}; + + const vk::GraphicsPipelineCreateInfo pipeline_info = { + .pNext = &pipeline_rendering_ci, + .stageCount = static_cast(shader_stages.size()), + .pStages = shader_stages.data(), + .pVertexInputState = &vertex_input_info, + .pInputAssemblyState = &input_assembly, + .pViewportState = &viewport_info, + .pRasterizationState = &raster_state, + .pMultisampleState = &multisampling, + .pDepthStencilState = &depth_state, + .pColorBlendState = &color_blending, + .pDynamicState = &dynamic_info, + .layout = *single_texture_pl_layout, + }; + + auto [pipeline_result, pipeline] = + instance.GetDevice().createGraphicsPipelineUnique(VK_NULL_HANDLE, pipeline_info); + ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create graphics pipeline: {}", + vk::to_string(pipeline_result)); + Vulkan::SetObjectName(instance.GetDevice(), *pipeline, "Color to MS Depth {}", key.num_samples); + + color_to_ms_depth_pl.emplace_back(key, std::move(pipeline)); +} + +void BlitHelper::CreateMsCopyPipeline(const MsPipelineKey& key) { + const vk::PipelineInputAssemblyStateCreateInfo input_assembly = { + .topology = vk::PrimitiveTopology::eTriangleList, + }; + const vk::PipelineMultisampleStateCreateInfo multisampling = { + .rasterizationSamples = ToSampleCount(key.num_samples), + }; + const vk::PipelineDepthStencilStateCreateInfo depth_state = { + .depthTestEnable = false, + .depthWriteEnable = false, + .depthCompareOp = vk::CompareOp::eAlways, + }; + const std::array dynamic_states = {vk::DynamicState::eViewportWithCount, + vk::DynamicState::eScissorWithCount}; + const vk::PipelineDynamicStateCreateInfo dynamic_info = { + .dynamicStateCount = static_cast(dynamic_states.size()), + .pDynamicStates = dynamic_states.data(), + }; + + std::array shader_stages; + shader_stages[0] = { + .stage = vk::ShaderStageFlagBits::eVertex, + .module = fs_tri_vertex, + .pName = "main", + }; + shader_stages[1] = { + .stage = vk::ShaderStageFlagBits::eFragment, + .module = key.src_msaa ? src_msaa_copy_frag : src_non_msaa_copy_frag, + .pName = "main", + }; + + const vk::PipelineRenderingCreateInfo pipeline_rendering_ci = { + .colorAttachmentCount = 1u, + .pColorAttachmentFormats = &key.attachment_format, + .depthAttachmentFormat = vk::Format::eUndefined, + .stencilAttachmentFormat = vk::Format::eUndefined, + }; + + const vk::PipelineColorBlendAttachmentState attachment = { + .blendEnable = false, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA, + }; + + const vk::PipelineColorBlendStateCreateInfo color_blending = { + .logicOpEnable = false, + .logicOp = vk::LogicOp::eCopy, + .attachmentCount = 1u, + .pAttachments = &attachment, + }; + const vk::PipelineViewportStateCreateInfo viewport_info{}; + const vk::PipelineVertexInputStateCreateInfo vertex_input_info{}; + const vk::PipelineRasterizationStateCreateInfo raster_state{.lineWidth = 1.f}; + + const vk::GraphicsPipelineCreateInfo pipeline_info = { + .pNext = &pipeline_rendering_ci, + .stageCount = static_cast(shader_stages.size()), + .pStages = shader_stages.data(), + .pVertexInputState = &vertex_input_info, + .pInputAssemblyState = &input_assembly, + .pViewportState = &viewport_info, + .pRasterizationState = &raster_state, + .pMultisampleState = &multisampling, + .pDepthStencilState = &depth_state, + .pColorBlendState = &color_blending, + .pDynamicState = &dynamic_info, + .layout = *single_texture_pl_layout, + }; + + auto [pipeline_result, pipeline] = + instance.GetDevice().createGraphicsPipelineUnique(VK_NULL_HANDLE, pipeline_info); + ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create graphics pipeline: {}", + vk::to_string(pipeline_result)); + Vulkan::SetObjectName(instance.GetDevice(), *pipeline, "Non MS Image to MS Image {}", + key.num_samples); + + ms_image_copy_pl.emplace_back(key, std::move(pipeline)); +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/blit_helper.h b/gpu/shadps4/video_core/texture_cache/blit_helper.h new file mode 100644 index 0000000..5855a5c --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/blit_helper.h @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan { +class Instance; +class Scheduler; +} // namespace Vulkan + +namespace VideoCore { + +class Image; +class ImageView; +struct ImageInfo; + +class BlitHelper { + static constexpr size_t MaxMsPipelines = 6; + +public: + explicit BlitHelper(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler); + ~BlitHelper(); + + void ReinterpretColorAsMsDepth(u32 width, u32 height, u32 num_samples, + vk::Format src_pixel_format, vk::Format dst_pixel_format, + vk::Image source, vk::Image dest); + + void CopyBetweenMsImages(u32 width, u32 height, u32 num_samples, vk::Format pixel_format, + bool src_msaa, vk::Image source, vk::Image dest); + +private: + void CreateShaders(); + void CreatePipelineLayouts(); + + struct MsPipelineKey { + u32 num_samples; + vk::Format attachment_format; + bool src_msaa; + + auto operator<=>(const MsPipelineKey&) const noexcept = default; + }; + void CreateColorToMSDepthPipeline(const MsPipelineKey& key); + void CreateMsCopyPipeline(const MsPipelineKey& key); + +private: + const Vulkan::Instance& instance; + Vulkan::Scheduler& scheduler; + vk::UniqueDescriptorSetLayout single_texture_descriptor_set_layout; + vk::UniquePipelineLayout single_texture_pl_layout; + vk::ShaderModule fs_tri_vertex; + vk::ShaderModule color_to_ms_depth_frag; + vk::ShaderModule src_msaa_copy_frag; + vk::ShaderModule src_non_msaa_copy_frag; + + using MsPipeline = std::pair; + std::vector color_to_ms_depth_pl; + std::vector ms_image_copy_pl; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/host_compatibility.cpp b/gpu/shadps4/video_core/texture_cache/host_compatibility.cpp new file mode 100644 index 0000000..327709e --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/host_compatibility.cpp @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/) +// Copyright © 2015-2023 The Khronos Group Inc. +// Copyright © 2015-2023 Valve Corporation +// Copyright © 2015-2023 LunarG, Inc. + +#include +#include "common/enum.h" +#include "video_core/texture_cache/host_compatibility.h" + +namespace VideoCore { + +/** + * @brief All classes of format compatibility according to the Vulkan specification + * @url + * https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/d37c676f/layers/generated/vk_format_utils.h#L47-L131 + */ +enum class CompatibilityClass { + NONE = 0, + _128BIT = 1 << 0, + _16BIT = 1 << 1, + _192BIT = 1 << 2, + _24BIT = 1 << 3, + _256BIT = 1 << 4, + _32BIT = 1 << 5, + _48BIT = 1 << 6, + _64BIT = 1 << 7, + _8BIT = 1 << 8, + _96BIT = 1 << 9, + BC1_RGB = 1 << 10, + BC1_RGBA = 1 << 11, + BC2 = 1 << 12, + BC3 = 1 << 13, + BC4 = 1 << 14, + BC5 = 1 << 15, + BC6H = 1 << 16, + BC7 = 1 << 17, + D16 = 1 << 18, + D16S8 = 1 << 19, + D24 = 1 << 20, + D24S8 = 1 << 21, + D32 = 1 << 22, + D32S8 = 1 << 23, + S8 = 1 << 24, +}; +DECLARE_ENUM_FLAG_OPERATORS(CompatibilityClass) + +/** + * @brief The format compatibility class according to the Vulkan specification + * @url + * https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#formats-compatibility-classes + * @url + * https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/d37c676f/layers/generated/vk_format_utils.cpp#L70-L812 + */ +static const std::unordered_map FORMAT_TABLE = { + {vk::Format::eA1R5G5B5UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eA2B10G10R10SintPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2B10G10R10SnormPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2B10G10R10SscaledPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2B10G10R10UintPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2B10G10R10UnormPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2B10G10R10UscaledPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2R10G10B10SintPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2R10G10B10SnormPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2R10G10B10SscaledPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2R10G10B10UintPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2R10G10B10UnormPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA2R10G10B10UscaledPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA4B4G4R4UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eA4R4G4B4UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eA8B8G8R8SintPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA8B8G8R8SnormPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA8B8G8R8SrgbPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA8B8G8R8SscaledPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA8B8G8R8UintPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA8B8G8R8UnormPack32, CompatibilityClass::_32BIT}, + {vk::Format::eA8B8G8R8UscaledPack32, CompatibilityClass::_32BIT}, + {vk::Format::eB10G11R11UfloatPack32, CompatibilityClass::_32BIT}, + {vk::Format::eB4G4R4A4UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eB5G5R5A1UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eB5G6R5UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eB8G8R8A8Sint, CompatibilityClass::_32BIT}, + {vk::Format::eB8G8R8A8Snorm, CompatibilityClass::_32BIT}, + {vk::Format::eB8G8R8A8Srgb, CompatibilityClass::_32BIT}, + {vk::Format::eB8G8R8A8Sscaled, CompatibilityClass::_32BIT}, + {vk::Format::eB8G8R8A8Uint, CompatibilityClass::_32BIT}, + {vk::Format::eB8G8R8A8Unorm, CompatibilityClass::_32BIT}, + {vk::Format::eB8G8R8A8Uscaled, CompatibilityClass::_32BIT}, + {vk::Format::eB8G8R8Sint, CompatibilityClass::_24BIT}, + {vk::Format::eB8G8R8Snorm, CompatibilityClass::_24BIT}, + {vk::Format::eB8G8R8Srgb, CompatibilityClass::_24BIT}, + {vk::Format::eB8G8R8Sscaled, CompatibilityClass::_24BIT}, + {vk::Format::eB8G8R8Uint, CompatibilityClass::_24BIT}, + {vk::Format::eB8G8R8Unorm, CompatibilityClass::_24BIT}, + {vk::Format::eB8G8R8Uscaled, CompatibilityClass::_24BIT}, + {vk::Format::eBc1RgbaSrgbBlock, CompatibilityClass::BC1_RGBA | CompatibilityClass::_64BIT}, + {vk::Format::eBc1RgbaUnormBlock, CompatibilityClass::BC1_RGBA | CompatibilityClass::_64BIT}, + {vk::Format::eBc1RgbSrgbBlock, CompatibilityClass::BC1_RGB | CompatibilityClass::_64BIT}, + {vk::Format::eBc1RgbUnormBlock, CompatibilityClass::BC1_RGB | CompatibilityClass::_64BIT}, + {vk::Format::eBc2SrgbBlock, CompatibilityClass::BC2 | CompatibilityClass::_128BIT}, + {vk::Format::eBc2UnormBlock, CompatibilityClass::BC2 | CompatibilityClass::_128BIT}, + {vk::Format::eBc3SrgbBlock, CompatibilityClass::BC3 | CompatibilityClass::_128BIT}, + {vk::Format::eBc3UnormBlock, CompatibilityClass::BC3 | CompatibilityClass::_128BIT}, + {vk::Format::eBc4SnormBlock, CompatibilityClass::BC4 | CompatibilityClass::_64BIT}, + {vk::Format::eBc4UnormBlock, CompatibilityClass::BC4 | CompatibilityClass::_64BIT}, + {vk::Format::eBc5SnormBlock, CompatibilityClass::BC5 | CompatibilityClass::_128BIT}, + {vk::Format::eBc5UnormBlock, CompatibilityClass::BC5 | CompatibilityClass::_128BIT}, + {vk::Format::eBc6HSfloatBlock, CompatibilityClass::BC6H | CompatibilityClass::_128BIT}, + {vk::Format::eBc6HUfloatBlock, CompatibilityClass::BC6H | CompatibilityClass::_128BIT}, + {vk::Format::eBc7SrgbBlock, CompatibilityClass::BC7 | CompatibilityClass::_128BIT}, + {vk::Format::eBc7UnormBlock, CompatibilityClass::BC7 | CompatibilityClass::_128BIT}, + {vk::Format::eD16Unorm, CompatibilityClass::D16}, + {vk::Format::eD16UnormS8Uint, CompatibilityClass::D16S8}, + {vk::Format::eD24UnormS8Uint, CompatibilityClass::D24S8}, + {vk::Format::eD32Sfloat, CompatibilityClass::D32}, + {vk::Format::eD32SfloatS8Uint, CompatibilityClass::D32S8}, + {vk::Format::eE5B9G9R9UfloatPack32, CompatibilityClass::_32BIT}, + {vk::Format::eR10X6G10X6Unorm2Pack16, CompatibilityClass::_32BIT}, + {vk::Format::eR10X6UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eR12X4G12X4Unorm2Pack16, CompatibilityClass::_32BIT}, + {vk::Format::eR12X4UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eR16G16B16A16Sfloat, CompatibilityClass::_64BIT}, + {vk::Format::eR16G16B16A16Sint, CompatibilityClass::_64BIT}, + {vk::Format::eR16G16B16A16Snorm, CompatibilityClass::_64BIT}, + {vk::Format::eR16G16B16A16Sscaled, CompatibilityClass::_64BIT}, + {vk::Format::eR16G16B16A16Uint, CompatibilityClass::_64BIT}, + {vk::Format::eR16G16B16A16Unorm, CompatibilityClass::_64BIT}, + {vk::Format::eR16G16B16A16Uscaled, CompatibilityClass::_64BIT}, + {vk::Format::eR16G16B16Sfloat, CompatibilityClass::_48BIT}, + {vk::Format::eR16G16B16Sint, CompatibilityClass::_48BIT}, + {vk::Format::eR16G16B16Snorm, CompatibilityClass::_48BIT}, + {vk::Format::eR16G16B16Sscaled, CompatibilityClass::_48BIT}, + {vk::Format::eR16G16B16Uint, CompatibilityClass::_48BIT}, + {vk::Format::eR16G16B16Unorm, CompatibilityClass::_48BIT}, + {vk::Format::eR16G16B16Uscaled, CompatibilityClass::_48BIT}, + {vk::Format::eR16G16Sfloat, CompatibilityClass::_32BIT}, + {vk::Format::eR16G16Sint, CompatibilityClass::_32BIT}, + {vk::Format::eR16G16Snorm, CompatibilityClass::_32BIT}, + {vk::Format::eR16G16Sscaled, CompatibilityClass::_32BIT}, + {vk::Format::eR16G16Uint, CompatibilityClass::_32BIT}, + {vk::Format::eR16G16Unorm, CompatibilityClass::_32BIT}, + {vk::Format::eR16G16Uscaled, CompatibilityClass::_32BIT}, + {vk::Format::eR16Sfloat, CompatibilityClass::_16BIT}, + {vk::Format::eR16Sint, CompatibilityClass::_16BIT}, + {vk::Format::eR16Snorm, CompatibilityClass::_16BIT}, + {vk::Format::eR16Sscaled, CompatibilityClass::_16BIT}, + {vk::Format::eR16Uint, CompatibilityClass::_16BIT}, + {vk::Format::eR16Unorm, CompatibilityClass::_16BIT}, + {vk::Format::eR16Uscaled, CompatibilityClass::_16BIT}, + {vk::Format::eR32G32B32A32Sfloat, CompatibilityClass::_128BIT}, + {vk::Format::eR32G32B32A32Sint, CompatibilityClass::_128BIT}, + {vk::Format::eR32G32B32A32Uint, CompatibilityClass::_128BIT}, + {vk::Format::eR32G32B32Sfloat, CompatibilityClass::_96BIT}, + {vk::Format::eR32G32B32Sint, CompatibilityClass::_96BIT}, + {vk::Format::eR32G32B32Uint, CompatibilityClass::_96BIT}, + {vk::Format::eR32G32Sfloat, CompatibilityClass::_64BIT}, + {vk::Format::eR32G32Sint, CompatibilityClass::_64BIT}, + {vk::Format::eR32G32Uint, CompatibilityClass::_64BIT}, + {vk::Format::eR32Sfloat, CompatibilityClass::_32BIT}, + {vk::Format::eR32Sint, CompatibilityClass::_32BIT}, + {vk::Format::eR32Uint, CompatibilityClass::_32BIT}, + {vk::Format::eR4G4B4A4UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eR4G4UnormPack8, CompatibilityClass::_8BIT}, + {vk::Format::eR5G5B5A1UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eR5G6B5UnormPack16, CompatibilityClass::_16BIT}, + {vk::Format::eR64G64B64A64Sfloat, CompatibilityClass::_256BIT}, + {vk::Format::eR64G64B64A64Sint, CompatibilityClass::_256BIT}, + {vk::Format::eR64G64B64A64Uint, CompatibilityClass::_256BIT}, + {vk::Format::eR64G64B64Sfloat, CompatibilityClass::_192BIT}, + {vk::Format::eR64G64B64Sint, CompatibilityClass::_192BIT}, + {vk::Format::eR64G64B64Uint, CompatibilityClass::_192BIT}, + {vk::Format::eR64G64Sfloat, CompatibilityClass::_128BIT}, + {vk::Format::eR64G64Sint, CompatibilityClass::_128BIT}, + {vk::Format::eR64G64Uint, CompatibilityClass::_128BIT}, + {vk::Format::eR64Sfloat, CompatibilityClass::_64BIT}, + {vk::Format::eR64Sint, CompatibilityClass::_64BIT}, + {vk::Format::eR64Uint, CompatibilityClass::_64BIT}, + {vk::Format::eR8G8B8A8Sint, CompatibilityClass::_32BIT}, + {vk::Format::eR8G8B8A8Snorm, CompatibilityClass::_32BIT}, + {vk::Format::eR8G8B8A8Srgb, CompatibilityClass::_32BIT}, + {vk::Format::eR8G8B8A8Sscaled, CompatibilityClass::_32BIT}, + {vk::Format::eR8G8B8A8Uint, CompatibilityClass::_32BIT}, + {vk::Format::eR8G8B8A8Unorm, CompatibilityClass::_32BIT}, + {vk::Format::eR8G8B8A8Uscaled, CompatibilityClass::_32BIT}, + {vk::Format::eR8G8B8Sint, CompatibilityClass::_24BIT}, + {vk::Format::eR8G8B8Snorm, CompatibilityClass::_24BIT}, + {vk::Format::eR8G8B8Srgb, CompatibilityClass::_24BIT}, + {vk::Format::eR8G8B8Sscaled, CompatibilityClass::_24BIT}, + {vk::Format::eR8G8B8Uint, CompatibilityClass::_24BIT}, + {vk::Format::eR8G8B8Unorm, CompatibilityClass::_24BIT}, + {vk::Format::eR8G8B8Uscaled, CompatibilityClass::_24BIT}, + {vk::Format::eR8G8Sint, CompatibilityClass::_16BIT}, + {vk::Format::eR8G8Snorm, CompatibilityClass::_16BIT}, + {vk::Format::eR8G8Srgb, CompatibilityClass::_16BIT}, + {vk::Format::eR8G8Sscaled, CompatibilityClass::_16BIT}, + {vk::Format::eR8G8Uint, CompatibilityClass::_16BIT}, + {vk::Format::eR8G8Unorm, CompatibilityClass::_16BIT}, + {vk::Format::eR8G8Uscaled, CompatibilityClass::_16BIT}, + {vk::Format::eR8Sint, CompatibilityClass::_8BIT}, + {vk::Format::eR8Snorm, CompatibilityClass::_8BIT}, + {vk::Format::eR8Srgb, CompatibilityClass::_8BIT}, + {vk::Format::eR8Sscaled, CompatibilityClass::_8BIT}, + {vk::Format::eR8Uint, CompatibilityClass::_8BIT}, + {vk::Format::eR8Unorm, CompatibilityClass::_8BIT}, + {vk::Format::eR8Uscaled, CompatibilityClass::_8BIT}, + {vk::Format::eS8Uint, CompatibilityClass::S8}, + {vk::Format::eX8D24UnormPack32, CompatibilityClass::D24}, + {vk::Format::eUndefined, CompatibilityClass::NONE}, +}; + +bool IsVulkanFormatCompatible(vk::Format base, vk::Format view) { + if (base == view) { + return true; + } + const auto base_comp = FORMAT_TABLE.at(base); + const auto view_comp = FORMAT_TABLE.at(view); + return (base_comp & view_comp) == view_comp; +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/host_compatibility.h b/gpu/shadps4/video_core/texture_cache/host_compatibility.h new file mode 100644 index 0000000..b057913 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/host_compatibility.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/) +// Copyright © 2015-2023 The Khronos Group Inc. +// Copyright © 2015-2023 Valve Corporation +// Copyright © 2015-2023 LunarG, Inc. + +#pragma once + +#include "video_core/renderer_vulkan/vk_common.h" + +namespace VideoCore { + +/// Returns true if the two formats are compatible according to Vulkan's format compatibility rules +bool IsVulkanFormatCompatible(vk::Format base, vk::Format view); + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/image.cpp b/gpu/shadps4/video_core/texture_cache/image.cpp new file mode 100644 index 0000000..e1610f3 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/image.cpp @@ -0,0 +1,327 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/assert.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/texture_cache/blit_helper.h" +#include "video_core/texture_cache/image.h" + +#include + +namespace VideoCore { + +using namespace Vulkan; + +Common::IncrementalIdProvider Image::global_image_uid{}; + +static vk::ImageUsageFlags ImageUsageFlags(const Vulkan::Instance& instance, + const ImageInfo& info) { + vk::ImageUsageFlags usage = vk::ImageUsageFlagBits::eTransferSrc | + vk::ImageUsageFlagBits::eTransferDst | + vk::ImageUsageFlagBits::eSampled; + if (!info.props.is_block) { + if (info.props.is_depth) { + usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + } else { + usage |= vk::ImageUsageFlagBits::eColorAttachment; + if (instance.IsAttachmentFeedbackLoopLayoutSupported()) { + usage |= vk::ImageUsageFlagBits::eAttachmentFeedbackLoopEXT; + } + // Always create images with storage flag to avoid needing re-creation in case of e.g + // compute clears This sacrifices a bit of performance but is less work. ExtendedUsage + // flag is also used. + usage |= vk::ImageUsageFlagBits::eStorage; + } + } else { + // Similarly to above, we specify storage usage. This is typically not supported by + // compressed formats, but may be used for uncompressed views. In order to satisfy this, + // we will also specify the extended usage bit. + usage |= vk::ImageUsageFlagBits::eStorage; + } + + return usage; +} + +static vk::ImageType ConvertImageType(AmdGpu::ImageType type) noexcept { + switch (type) { + case AmdGpu::ImageType::Color1D: + case AmdGpu::ImageType::Color1DArray: + return vk::ImageType::e1D; + case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color2DMsaa: + case AmdGpu::ImageType::Color2DArray: + return vk::ImageType::e2D; + case AmdGpu::ImageType::Color3D: + return vk::ImageType::e3D; + default: + UNREACHABLE(); + } +} + +static vk::FormatFeatureFlags2 FormatFeatureFlags(const vk::ImageUsageFlags usage_flags) { + vk::FormatFeatureFlags2 feature_flags{}; + if (usage_flags & vk::ImageUsageFlagBits::eTransferSrc) { + feature_flags |= vk::FormatFeatureFlagBits2::eTransferSrc; + } + if (usage_flags & vk::ImageUsageFlagBits::eTransferDst) { + feature_flags |= vk::FormatFeatureFlagBits2::eTransferDst; + } + if (usage_flags & vk::ImageUsageFlagBits::eSampled) { + feature_flags |= vk::FormatFeatureFlagBits2::eSampledImage; + } + if (usage_flags & vk::ImageUsageFlagBits::eColorAttachment) { + feature_flags |= vk::FormatFeatureFlagBits2::eColorAttachment; + } + if (usage_flags & vk::ImageUsageFlagBits::eDepthStencilAttachment) { + feature_flags |= vk::FormatFeatureFlagBits2::eDepthStencilAttachment; + } + // Note: StorageImage is intentionally ignored for now since it is always set, and can mess up + // compatibility checks. + return feature_flags; +} + +UniqueImage::~UniqueImage() { + if (image) { + vmaDestroyImage(allocator, image, allocation); + } +} + +void UniqueImage::Destroy() { + if (image) { + vmaDestroyImage(allocator, image, allocation); + image = vk::Image{}; + allocation = {}; + } +} + +void UniqueImage::Create(const vk::ImageCreateInfo& image_ci) { + this->image_ci = image_ci; + ASSERT(!image); + const VmaAllocationCreateInfo alloc_ci = { + .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT, + .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + .requiredFlags = 0, + .preferredFlags = 0, + .pool = VK_NULL_HANDLE, + .pUserData = nullptr, + }; + + const VkImageCreateInfo image_ci_unsafe = static_cast(image_ci); + VkImage unsafe_image{}; + VmaAllocationInfo alloc_info{}; + VkResult result = vmaCreateImage(allocator, &image_ci_unsafe, &alloc_ci, &unsafe_image, + &allocation, &alloc_info); + ASSERT_MSG(result == VK_SUCCESS, "Failed allocating image with error {}", + vk::to_string(vk::Result{result})); + image = vk::Image{unsafe_image}; + size_bytes = alloc_info.size; +} + +Image::Image(const Vulkan::Instance& instance, Vulkan::Runtime& runtime_, + Common::SlotVector& slot_image_views_, const ImageInfo& info_) + : runtime{&runtime_}, slot_image_views{&slot_image_views_}, info{info_} { + if (info.pixel_format == vk::Format::eUndefined) { + return; + } + + image_uid = global_image_uid.Next(); + mip_hashes.resize(info.resources.levels); + vk::ImageCreateFlags flags{vk::ImageCreateFlagBits::eMutableFormat | + vk::ImageCreateFlagBits::eExtendedUsage}; + if (info.props.is_volume) { + flags |= vk::ImageCreateFlagBits::e2DArrayCompatible; + if (instance.Is2dViewOf3dSupported()) { + flags |= vk::ImageCreateFlagBits::e2DViewCompatibleEXT; + } + } + if (info.props.is_block && instance.IsBlockTexelViewSupported()) { + flags |= vk::ImageCreateFlagBits::eBlockTexelViewCompatible; + } + + usage_flags = ImageUsageFlags(instance, info); + format_features = FormatFeatureFlags(usage_flags); + if (info.props.is_depth) { + aspect_mask = vk::ImageAspectFlagBits::eDepth; + if (info.props.has_stencil) { + aspect_mask |= vk::ImageAspectFlagBits::eStencil; + } + } + + constexpr auto tiling = vk::ImageTiling::eOptimal; + const auto supported_format = instance.GetSupportedFormat(info.pixel_format, format_features); + const vk::PhysicalDeviceImageFormatInfo2 format_info{ + .format = supported_format, + .type = ConvertImageType(info.type), + .tiling = tiling, + .usage = usage_flags, + .flags = flags, + }; + const auto image_format_properties = + instance.GetPhysicalDevice().getImageFormatProperties2(format_info); + if (image_format_properties.result == vk::Result::eErrorFormatNotSupported) { + LOG_ERROR(Render_Vulkan, "image format {} type {} is not supported (flags {}, usage {})", + vk::to_string(supported_format), vk::to_string(format_info.type), + vk::to_string(format_info.flags), vk::to_string(format_info.usage)); + } + supported_samples = image_format_properties.result == vk::Result::eSuccess + ? image_format_properties.value.imageFormatProperties.sampleCounts + : vk::SampleCountFlagBits::e1; + + const vk::ImageCreateInfo image_ci = { + .flags = flags, + .imageType = ConvertImageType(info.type), + .format = supported_format, + .extent{ + .width = info.size.width, + .height = info.size.height, + .depth = info.size.depth, + }, + .mipLevels = static_cast(info.resources.levels), + .arrayLayers = static_cast(info.resources.layers), + .samples = LiverpoolToVK::NumSamples(info.num_samples, supported_samples), + .tiling = tiling, + .usage = usage_flags, + .initialLayout = vk::ImageLayout::eUndefined, + }; + + backing = &backing_images.emplace_back(); + backing->num_samples = info.num_samples; + backing->image = UniqueImage{instance.GetDevice(), instance.GetAllocator()}; + backing->image.Create(image_ci); + + Vulkan::SetObjectName(instance.GetDevice(), GetImage(), + "Image {}x{}x{} {} {} {:#x}:{:#x} L:{} M:{} S:{}", info.size.width, + info.size.height, info.size.depth, AmdGpu::NameOf(info.tile_mode), + vk::to_string(info.pixel_format), info.guest_address, info.guest_size, + info.resources.layers, info.resources.levels, info.num_samples); +} + +Image::~Image() = default; + +ImageView& Image::FindView(const ImageViewInfo& view_info, bool ensure_guest_samples) { + if (ensure_guest_samples && backing->num_samples > 1 != info.num_samples > 1) { + runtime->SetBackingSamples(this, info.num_samples); + } + const auto& view_infos = backing->image_view_infos; + const auto it = std::ranges::find(view_infos, view_info); + if (it != view_infos.end()) { + const auto view_id = backing->image_view_ids[std::distance(view_infos.begin(), it)]; + return (*slot_image_views)[view_id]; + } + const auto view_id = slot_image_views->insert(runtime->GetInstance(), view_info, *this); + backing->image_view_infos.emplace_back(view_info); + backing->image_view_ids.emplace_back(view_id); + return (*slot_image_views)[view_id]; +} + +void Image::GetBarriers(Barriers& barriers, vk::ImageLayout dst_layout, vk::AccessFlags2 dst_mask, + vk::PipelineStageFlags2 dst_stage, + std::optional subres_range) { + auto& last_state = backing->state; + auto& subresource_states = backing->subresource_states; + + const bool needs_partial_transition = + subres_range && + (subres_range->base != SubresourceBase{} || subres_range->extent != info.resources); + const bool partially_transited = !subresource_states.empty(); + + if (needs_partial_transition || partially_transited) { + if (!partially_transited) { + subresource_states.resize(info.resources.levels * info.resources.layers); + std::fill(subresource_states.begin(), subresource_states.end(), last_state); + } + + // In case of partial transition, we need to change the specified subresources only. + // Otherwise all subresources need to be set to the same state so we can use a full + // resource transition for the next time. + const auto mips = + needs_partial_transition + ? std::ranges::views::iota(subres_range->base.level, + subres_range->base.level + subres_range->extent.levels) + : std::views::iota(0u, info.resources.levels); + const auto layers = + needs_partial_transition + ? std::ranges::views::iota(subres_range->base.layer, + subres_range->base.layer + subres_range->extent.layers) + : std::views::iota(0u, info.resources.layers); + + for (u32 mip : mips) { + for (u32 layer : layers) { + // NOTE: these loops may produce a lot of small barriers. + // If this becomes a problem, we can optimize it by merging adjacent barriers. + const auto subres_idx = mip * info.resources.layers + layer; + ASSERT(subres_idx < subresource_states.size()); + auto& state = subresource_states[subres_idx]; + + constexpr auto write_flags = vk::AccessFlagBits2::eTransferWrite | + vk::AccessFlagBits2::eShaderWrite | + vk::AccessFlagBits2::eMemoryWrite; + const bool is_write = static_cast(state.access_mask & write_flags); + if (state.layout != dst_layout || state.access_mask != dst_mask || is_write) { + barriers.emplace_back(vk::ImageMemoryBarrier2{ + .srcStageMask = state.pl_stage, + .srcAccessMask = state.access_mask, + .dstStageMask = dst_stage, + .dstAccessMask = dst_mask, + .oldLayout = state.layout, + .newLayout = dst_layout, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = GetImage(), + .subresourceRange{ + .aspectMask = aspect_mask, + .baseMipLevel = mip, + .levelCount = 1, + .baseArrayLayer = layer, + .layerCount = 1, + }, + }); + state.layout = dst_layout; + state.access_mask = dst_mask; + state.pl_stage = dst_stage; + } + } + } + + if (!needs_partial_transition) { + subresource_states.clear(); + } + } else { // Full resource transition + constexpr auto write_flags = vk::AccessFlagBits2::eTransferWrite | + vk::AccessFlagBits2::eShaderWrite | + vk::AccessFlagBits2::eMemoryWrite; + const bool is_write = static_cast(last_state.access_mask & write_flags); + if (last_state.layout == dst_layout && last_state.access_mask == dst_mask && !is_write) { + return; + } + + barriers.emplace_back(vk::ImageMemoryBarrier2{ + .srcStageMask = last_state.pl_stage, + .srcAccessMask = last_state.access_mask, + .dstStageMask = dst_stage, + .dstAccessMask = dst_mask, + .oldLayout = last_state.layout, + .newLayout = dst_layout, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = GetImage(), + .subresourceRange{ + .aspectMask = aspect_mask, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }); + } + + last_state.layout = dst_layout; + last_state.access_mask = dst_mask; + last_state.pl_stage = dst_stage; +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/image.h b/gpu/shadps4/video_core/texture_cache/image.h new file mode 100644 index 0000000..e4a820f --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/image.h @@ -0,0 +1,187 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/enum.h" +#include "common/incremental_id.h" +#include "common/types.h" +#include "video_core/renderer_vulkan/vk_common.h" +#include "video_core/texture_cache/image_info.h" +#include "video_core/texture_cache/image_view.h" + +#include +#include +#include +#include + +namespace Vulkan { +class Instance; +class Runtime; +} // namespace Vulkan + +VK_DEFINE_HANDLE(VmaAllocation) +VK_DEFINE_HANDLE(VmaAllocator) + +namespace VideoCore { + +enum ImageFlagBits : u32 { + Empty = 0, + MaybeCpuDirty = 1 << 0, ///< The page this image is in was touched before the image address + CpuDirty = 1 << 1, ///< Contents have been modified from the CPU + GpuDirty = 1 << 2, ///< Contents have been modified from the GPU (valid data in buffer cache) + Dirty = MaybeCpuDirty | CpuDirty | GpuDirty, + GpuModified = 1 << 3, ///< Contents have been modified from the GPU + Registered = 1 << 6, ///< True when the image is registered + Picked = 1 << 7, ///< Temporary flag to mark the image as picked +}; +DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) + +struct UniqueImage { + explicit UniqueImage() = default; + explicit UniqueImage(vk::Device device, VmaAllocator allocator) + : device{device}, allocator{allocator} {} + ~UniqueImage(); + + UniqueImage(const UniqueImage&) = delete; + UniqueImage& operator=(const UniqueImage&) = delete; + + UniqueImage(UniqueImage&& other) + : allocator{std::exchange(other.allocator, VK_NULL_HANDLE)}, + allocation{std::exchange(other.allocation, VK_NULL_HANDLE)}, + image{std::exchange(other.image, VK_NULL_HANDLE)}, image_ci{std::move(other.image_ci)} {} + UniqueImage& operator=(UniqueImage&& other) { + image = std::exchange(other.image, VK_NULL_HANDLE); + allocator = std::exchange(other.allocator, VK_NULL_HANDLE); + allocation = std::exchange(other.allocation, VK_NULL_HANDLE); + image_ci = std::move(other.image_ci); + return *this; + } + + void Create(const vk::ImageCreateInfo& image_ci); + + void Destroy(); + + operator vk::Image() const { + return image; + } + + operator bool() const { + return image; + } + +public: + vk::Device device{}; + VmaAllocator allocator{}; + VmaAllocation allocation{}; + vk::Image image{}; + vk::ImageCreateInfo image_ci{}; + vk::DeviceSize size_bytes{}; +}; + +struct Image { + explicit Image(const Vulkan::Instance& instance, Vulkan::Runtime& runtime, + Common::SlotVector& slot_image_views, const ImageInfo& info); + ~Image(); + + Image(const Image&) = delete; + Image& operator=(const Image&) = delete; + + Image(Image&&) = default; + Image& operator=(Image&&) = default; + + bool Overlaps(VAddr overlap_cpu_addr, size_t overlap_size) const noexcept { + const VAddr overlap_end = overlap_cpu_addr + overlap_size; + const auto image_addr = info.guest_address; + const auto image_end = info.guest_address + info.guest_size; + return image_addr < overlap_end && overlap_cpu_addr < image_end; + } + + vk::Image GetImage() const { + return backing->image.image; + } + + vk::DeviceSize GetHostImageSize() const { + return backing->image.size_bytes; + } + + bool IsTracked() { + return track_addr != 0 && track_addr_end != 0; + } + + bool SafeToDownload() const { + return True(flags & ImageFlagBits::GpuModified) && False(flags & (ImageFlagBits::Dirty)); + } + + void AssociateDepth(ImageId depth_image_id, u64 depth_image_uid) { + depth_id = depth_image_id; + depth_uid = depth_image_uid; + } + + void DisassociateDepth() { + depth_id = {}; + depth_uid = {}; + } + + ImageView& FindView(const ImageViewInfo& view_info, bool ensure_guest_samples = true); + + using Barriers = boost::container::small_vector; + void GetBarriers(Barriers& out_barriers, vk::ImageLayout dst_layout, vk::AccessFlags2 dst_mask, + vk::PipelineStageFlags2 dst_stage, + std::optional subres_range = {}); + +public: + Vulkan::Runtime* runtime; + Common::SlotVector* slot_image_views; + ImageInfo info; + vk::ImageAspectFlags aspect_mask = vk::ImageAspectFlagBits::eColor; + vk::SampleCountFlags supported_samples = vk::SampleCountFlagBits::e1; + ImageFlagBits flags = ImageFlagBits::Dirty; + VAddr track_addr = 0; + VAddr track_addr_end = 0; + ImageId depth_id{}; + u64 depth_uid{}; + + vk::ImageUsageFlags usage_flags; + vk::FormatFeatureFlags2 format_features; + struct State { + vk::PipelineStageFlags2 pl_stage = vk::PipelineStageFlagBits2::eAllCommands; + vk::AccessFlags2 access_mask = vk::AccessFlagBits2::eNone; + vk::ImageLayout layout = vk::ImageLayout::eUndefined; + }; + struct BackingImage { + UniqueImage image; + State state; + std::vector subresource_states; + boost::container::small_vector image_view_infos; + boost::container::small_vector image_view_ids; + u32 num_samples; + }; + std::deque backing_images; + BackingImage* backing{}; + boost::container::static_vector mip_hashes{}; + u64 image_uid{}; + u64 lru_id{}; + u64 tick_accessed_last{}; + u64 hash{}; + + struct { + u32 texture : 1; + u32 storage : 1; + u32 render_target : 1; + u32 depth_target : 1; + u32 vo_surface : 1; + } usage{}; + + struct { + u32 is_bound : 1; + u32 is_target : 1; + u32 needs_rebind : 1; + u32 force_general : 1; + } binding{}; + +private: + static Common::IncrementalIdProvider global_image_uid; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/image_info.cpp b/gpu/shadps4/video_core/texture_cache/image_info.cpp new file mode 100644 index 0000000..2f4a4ff --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/image_info.cpp @@ -0,0 +1,302 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "core/libraries/kernel/process.h" +#include "core/libraries/videoout/buffer.h" +#include "shader_recompiler/resource.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/texture_cache/host_compatibility.h" +#include "video_core/texture_cache/image_info.h" +#include "video_core/texture_cache/tile.h" + +namespace VideoCore { + +using namespace Vulkan; +using Libraries::VideoOut::TilingMode; +using VideoOutFormat = Libraries::VideoOut::PixelFormat; + +static vk::Format ConvertPixelFormat(const VideoOutFormat format) { + switch (format) { + case VideoOutFormat::A8B8G8R8Srgb: + // Remaining formats are mapped to RGBA for internal consistency and changed to BGRA in the + // frame image view. + case VideoOutFormat::A8R8G8B8Srgb: + return vk::Format::eR8G8B8A8Srgb; + case VideoOutFormat::A2R10G10B10: + case VideoOutFormat::A2R10G10B10Srgb: + case VideoOutFormat::A2R10G10B10Bt2020Pq: + return vk::Format::eA2B10G10R10UnormPack32; + default: + break; + } + UNREACHABLE_MSG("Unknown format={}", static_cast(format)); + return {}; +} + +ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group, + VAddr cpu_address) noexcept { + const auto& attrib = group.attrib; + props.is_tiled = attrib.tiling_mode == TilingMode::Tile; + tile_mode = + props.is_tiled ? AmdGpu::TileMode::Display2DThin : AmdGpu::TileMode::DisplayLinearAligned; + array_mode = AmdGpu::GetArrayMode(tile_mode); + pixel_format = ConvertPixelFormat(attrib.pixel_format); + type = AmdGpu::ImageType::Color2D; + size.width = attrib.width; + size.height = attrib.height; + pitch = attrib.tiling_mode == TilingMode::Linear ? size.width : (size.width + 127) & (~127); + num_bits = attrib.pixel_format != VideoOutFormat::A16R16G16B16Float ? 32 : 64; + ASSERT(num_bits == 32); + + guest_address = cpu_address; + UpdateSize(); +} + +ImageInfo::ImageInfo(const AmdGpu::ColorBuffer& buffer, AmdGpu::CbDbExtent hint) noexcept { + props.is_tiled = buffer.IsTiled(); + tile_mode = buffer.GetTileMode(); + array_mode = AmdGpu::GetArrayMode(tile_mode); + pixel_format = LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt()); + num_samples = buffer.NumSamples(); + num_bits = NumBitsPerBlock(buffer.GetDataFmt()); + type = AmdGpu::ImageType::Color2D; + size.width = hint.Valid() ? hint.width : buffer.Pitch(); + size.height = hint.Valid() ? hint.height : buffer.Height(); + size.depth = 1; + pitch = buffer.Pitch(); + resources.layers = buffer.NumSlices(); + meta_info.cmask_addr = buffer.info.fast_clear ? buffer.CmaskAddress() : 0; + meta_info.fmask_addr = buffer.info.compression ? buffer.FmaskAddress() : 0; + + guest_address = buffer.Address(); + if (props.is_tiled) { + guest_size = buffer.GetColorSliceSize() * resources.layers; + mips_layout[0] = MipInfo(guest_size, pitch, buffer.Height(), 0); + } else { + std::tie(std::ignore, std::ignore, guest_size) = + ImageSizeLinearAligned(pitch, size.height, num_bits, num_samples); + guest_size *= resources.layers; + mips_layout[0] = MipInfo(guest_size, pitch, size.height, 0); + } + alt_tile = Libraries::Kernel::sceKernelIsNeoMode() && buffer.info.alt_tile_mode; +} + +ImageInfo::ImageInfo(const AmdGpu::DepthBuffer& buffer, u32 num_slices, VAddr htile_address, + AmdGpu::CbDbExtent hint, bool write_buffer) noexcept { + tile_mode = buffer.GetTileMode(); + array_mode = AmdGpu::GetArrayMode(tile_mode); + pixel_format = LiverpoolToVK::DepthFormat(buffer.z_info.format, buffer.stencil_info.format); + type = AmdGpu::ImageType::Color2D; + props.is_tiled = buffer.IsTiled(); + props.is_depth = true; + props.has_stencil = buffer.stencil_info.format != AmdGpu::DepthBuffer::StencilFormat::Invalid; + num_samples = buffer.NumSamples(); + num_bits = buffer.NumBits(); + size.width = hint.Valid() ? hint.width : buffer.Pitch(); + size.height = hint.Valid() ? hint.height : buffer.Height(); + size.depth = 1; + pitch = buffer.Pitch(); + resources.layers = num_slices; + meta_info.htile_addr = buffer.z_info.tile_surface_enable ? htile_address : 0; + + stencil_addr = write_buffer ? buffer.StencilWriteAddress() : buffer.StencilAddress(); + stencil_size = pitch * size.height * sizeof(u8); + + guest_address = write_buffer ? buffer.DepthWriteAddress() : buffer.DepthAddress(); + if (props.is_tiled) { + guest_size = buffer.GetDepthSliceSize() * resources.layers; + mips_layout[0] = MipInfo(guest_size, pitch, buffer.Height(), 0); + } else { + std::tie(std::ignore, std::ignore, guest_size) = + ImageSizeLinearAligned(pitch, size.height, num_bits, num_samples); + guest_size *= resources.layers; + mips_layout[0] = MipInfo(guest_size, pitch, size.height, 0); + } +} + +ImageInfo::ImageInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept { + tile_mode = image.GetTileMode(); + array_mode = AmdGpu::GetArrayMode(tile_mode); + pixel_format = LiverpoolToVK::SurfaceFormat(image.GetDataFmt(), image.GetNumberFmt()); + if (desc.is_depth) { + pixel_format = LiverpoolToVK::PromoteFormatToDepth(pixel_format); + props.is_depth = true; + } + type = image.GetBaseType(); + props.is_tiled = image.IsTiled(); + props.is_volume = type == AmdGpu::ImageType::Color3D; + props.is_pow2 = image.pow2pad; + props.is_block = AmdGpu::IsBlockCoded(image.GetDataFmt()); + size.width = image.width + 1; + size.height = image.height + 1; + size.depth = props.is_volume ? image.depth + 1 : 1; + pitch = image.Pitch(); + resources.levels = image.NumLevels(); + resources.layers = image.NumLayers(); + num_samples = image.NumSamples(); + num_bits = NumBitsPerBlock(image.GetDataFmt()); + bank_swizzle = image.GetBankSwizzle(); + + guest_address = image.Address(); + + alt_tile = Libraries::Kernel::sceKernelIsNeoMode() && image.alt_tile_mode; + UpdateSize(); +} + +bool ImageInfo::IsCompatible(const ImageInfo& info) const { + return (IsVulkanFormatCompatible(pixel_format, info.pixel_format) || + IsVulkanFormatCompatible(info.pixel_format, pixel_format)) && + num_samples == info.num_samples && num_bits == info.num_bits; +} + +void ImageInfo::UpdateSize() { + guest_size = 0; + for (s32 mip = 0; mip < resources.levels; ++mip) { + u32 mip_w = pitch >> mip; + u32 mip_h = size.height >> mip; + if (props.is_block) { + mip_w = (mip_w + 3) / 4; + mip_h = (mip_h + 3) / 4; + } + mip_w = std::max(mip_w, 1u); + mip_h = std::max(mip_h, 1u); + u32 mip_d = std::max(size.depth >> mip, 1u); + + if (props.is_pow2) { + mip_w = std::bit_ceil(mip_w); + mip_h = std::bit_ceil(mip_h); + mip_d = std::bit_ceil(mip_d); + } + + auto& mip_info = mips_layout[mip]; + if (array_mode == AmdGpu::ArrayMode::ArrayLinearAligned) { + std::tie(mip_info.pitch, mip_info.height, mip_info.size) = + ImageSizeLinearAligned(mip_w, mip_h, num_bits, num_samples); + } else if (array_mode == AmdGpu::ArrayMode::ArrayLinearGeneral) { + UNREACHABLE_MSG("Unhandled array mode: ArrayLinearGeneral"); + } else { + // Every tiled array mode (1D/2D/3D, thin/thick/xthick, PRT or not) groups + // GetMicroTileThickness() consecutive depth slices per tile; round mip_d up + // to a full group so it's counted correctly in mip_info.size below. + const u32 thickness = AmdGpu::GetMicroTileThickness(array_mode); + mip_d += (-mip_d) & (thickness - 1); + if (AmdGpu::IsMacroTiled(array_mode)) { + ASSERT(!props.is_block); + std::tie(mip_info.pitch, mip_info.height, mip_info.size) = ImageSizeMacroTiled( + mip_w, mip_h, thickness, num_bits, num_samples, tile_mode, mip, alt_tile); + } else { + std::tie(mip_info.pitch, mip_info.height, mip_info.size) = + ImageSizeMicroTiled(mip_w, mip_h, thickness, num_bits, num_samples); + } + } + if (props.is_block) { + mip_info.pitch = std::max(mip_info.pitch * 4, 32u); + mip_info.height = std::max(mip_info.height * 4, 32u); + } + mip_info.size *= mip_d * resources.layers; + mip_info.offset = guest_size; + guest_size += mip_info.size; + } +} + +s32 ImageInfo::MipOf(const ImageInfo& info) const { + if (!IsCompatible(info)) { + return -1; + } + + if (info.array_mode != array_mode) { + return -1; + } + + // Currently we expect only one level to be copied. + if (resources.levels != 1) { + return -1; + } + + const auto info_dim = info.props.is_block ? 2 : 0; + const auto this_dim = props.is_block ? 2 : 0; + + // Find mip + auto mip = -1; + for (auto m = 0; m < info.resources.levels; ++m) { + const auto& [mip_size, mip_pitch, mip_height, mip_ofs] = info.mips_layout[m]; + const VAddr mip_base = info.guest_address + mip_ofs; + const VAddr mip_end = mip_base + mip_size; + const u32 slice_size = mip_size / info.resources.layers; + if (guest_address >= mip_base && guest_address < mip_end && + (guest_address - mip_base) % slice_size == 0 && + (pitch >> this_dim) == (mip_pitch >> info_dim)) { + mip = m; + break; + } + } + + if (mip < 0) { + return -1; + } + + // 2D block dimensions of both images should be the same. + const auto mip_w = std::max(info.size.width >> (mip + info_dim), 1u); + const auto mip_h = std::max(info.size.height >> (mip + info_dim), 1u); + const auto this_w = std::max(size.width >> this_dim, 1u); + const auto this_h = std::max(size.height >> this_dim, 1u); + if ((this_w != mip_w) || (this_h != mip_h)) { + return -1; + } + + const auto mip_d = std::max(info.size.depth >> mip, 1u); + if (info.type == AmdGpu::ImageType::Color3D && type == AmdGpu::ImageType::Color2D) { + // In case of 2D array to 3D copy, make sure we have proper number of layers. + if (resources.layers != mip_d) { + return -1; + } + } else { + if (type != info.type) { + return -1; + } + } + + return mip; +} + +s32 ImageInfo::SliceOf(const ImageInfo& info, s32 mip) const { + if (!IsCompatible(info)) { + return -1; + } + + // Array slices should be of the same type. + if (type != info.type) { + return -1; + } + + // 2D block dimensions of both images should be the same. + const auto info_dim = info.props.is_block ? 2 : 0; + const auto mip_w = std::max(info.size.width >> (mip + info_dim), 1u); + const auto mip_h = std::max(info.size.height >> (mip + info_dim), 1u); + const auto mip_p = std::max(info.mips_layout[mip].pitch >> info_dim, 1u); + + const auto this_dim = props.is_block ? 2 : 0; + const auto this_w = std::max(size.width >> this_dim, 1u); + const auto this_h = std::max(size.height >> this_dim, 1u); + const auto this_p = std::max(pitch >> this_dim, 1u); + if ((this_w != mip_w) || (this_h != mip_h) || (this_p != mip_p)) { + return -1; + } + + // Check for size alignment. + const u32 slice_size = info.mips_layout[mip].size / info.resources.layers; + if (guest_size % slice_size != 0) { + return -1; + } + + // Ensure that address is aligned too. + const auto addr_diff = guest_address - (info.guest_address + info.mips_layout[mip].offset); + if ((addr_diff % guest_size) != 0) { + return -1; + } + + return addr_diff / guest_size; +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/image_info.h b/gpu/shadps4/video_core/texture_cache/image_info.h new file mode 100644 index 0000000..b1f6752 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/image_info.h @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "video_core/amdgpu/cb_db_extent.h" +#include "video_core/amdgpu/tiling.h" +#include "video_core/renderer_vulkan/vk_common.h" +#include "video_core/texture_cache/types.h" + +namespace AmdGpu { +struct ColorBuffer; +struct DepthBuffer; +struct Image; +enum class ImageType : u64; +} // namespace AmdGpu + +namespace Libraries::VideoOut { +struct BufferAttributeGroup; +} + +namespace Shader { +struct ImageResource; +} + +namespace VideoCore { + +struct ImageProperties { + u32 is_volume : 1; + u32 is_tiled : 1; + u32 is_pow2 : 1; + u32 is_block : 1; + u32 is_depth : 1; + u32 has_stencil : 1; +}; + +struct ImageInfo { + ImageInfo() = default; + ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group, VAddr cpu_address) noexcept; + ImageInfo(const AmdGpu::ColorBuffer& buffer, AmdGpu::CbDbExtent hint) noexcept; + ImageInfo(const AmdGpu::DepthBuffer& buffer, u32 num_slices, VAddr htile_address, + AmdGpu::CbDbExtent hint, bool write_buffer = false) noexcept; + ImageInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept; + + bool IsTiled() const { + return tile_mode != AmdGpu::TileMode::DisplayLinearAligned; + } + + Extent2D BlockDim() const { + const auto dim = props.is_block ? 2 : 0; + return Extent2D{pitch >> dim, size.height >> dim}; + } + + s32 MipOf(const ImageInfo& info) const; + s32 SliceOf(const ImageInfo& info, s32 mip) const; + + bool IsCompatible(const ImageInfo& info) const; + void UpdateSize(); + + struct { + VAddr cmask_addr; + VAddr fmask_addr; + VAddr htile_addr; + s32 htile_clear_mask = -1; + } meta_info{}; + + ImageProperties props{}; + vk::Format pixel_format = vk::Format::eUndefined; + AmdGpu::ImageType type; + SubresourceExtent resources; + Extent3D size{1, 1, 1}; + u32 num_bits{}; + u32 num_samples = 1; + u32 pitch{}; + AmdGpu::TileMode tile_mode = AmdGpu::TileMode::DisplayLinearAligned; + AmdGpu::ArrayMode array_mode = AmdGpu::ArrayMode::ArrayLinearAligned; + struct MipInfo { + u32 size; + u32 pitch; + u32 height; + u32 offset; + }; + std::array mips_layout; + VAddr guest_address{}; + u32 guest_size{}; + u8 bank_swizzle{}; + bool alt_tile{}; + + VAddr stencil_addr{}; + u32 stencil_size{}; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/image_view.cpp b/gpu/shadps4/video_core/texture_cache/image_view.cpp new file mode 100644 index 0000000..fad96c9 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/image_view.cpp @@ -0,0 +1,157 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "shader_recompiler/resource.h" +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/texture_cache/image.h" +#include "video_core/texture_cache/image_view.h" + +#include + +namespace VideoCore { + +vk::ImageViewType ConvertImageViewType(AmdGpu::ImageType type) { + switch (type) { + case AmdGpu::ImageType::Color1D: + return vk::ImageViewType::e1D; + case AmdGpu::ImageType::Color1DArray: + return vk::ImageViewType::e1DArray; + case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color2DMsaa: + return vk::ImageViewType::e2D; + case AmdGpu::ImageType::Color2DArray: + return vk::ImageViewType::e2DArray; + case AmdGpu::ImageType::Color3D: + return vk::ImageViewType::e3D; + default: + UNREACHABLE(); + } +} + +bool IsViewTypeCompatible(AmdGpu::ImageType view_type, AmdGpu::ImageType image_type) { + switch (view_type) { + case AmdGpu::ImageType::Color1D: + case AmdGpu::ImageType::Color1DArray: + return image_type == AmdGpu::ImageType::Color1D; + case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color2DArray: + case AmdGpu::ImageType::Color2DMsaa: + case AmdGpu::ImageType::Color2DMsaaArray: + return image_type == AmdGpu::ImageType::Color2D || image_type == AmdGpu::ImageType::Color3D; + case AmdGpu::ImageType::Color3D: + return image_type == AmdGpu::ImageType::Color3D; + default: + UNREACHABLE(); + } +} + +ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept + : is_storage{desc.is_written} { + const auto dfmt = image.GetDataFmt(); + auto nfmt = image.GetNumberFmt(); + if (is_storage && nfmt == AmdGpu::NumberFormat::Srgb) { + nfmt = AmdGpu::NumberFormat::Unorm; + } + format = Vulkan::LiverpoolToVK::SurfaceFormat(dfmt, nfmt); + if (desc.is_depth) { + format = Vulkan::LiverpoolToVK::PromoteFormatToDepth(format); + } + + range.base.level = image.base_level; + range.base.layer = std::min(image.base_array, image.NumLayers() - 1); + range.extent.levels = image.NumViewLevels(desc.is_array); + range.extent.layers = image.NumViewLayers(desc.is_array); + type = image.GetViewType(desc.is_array); + min_lod = static_cast(image.min_lod); + + if (!is_storage) { + mapping = Vulkan::LiverpoolToVK::ComponentMapping(image.DstSelect()); + } +} + +ImageViewInfo::ImageViewInfo(const AmdGpu::ColorBuffer& col_buffer) noexcept { + range.base.layer = col_buffer.BaseSlice(); + range.extent.layers = col_buffer.NumSlices() - range.base.layer; + type = range.extent.layers > 1 ? AmdGpu::ImageType::Color2DArray : AmdGpu::ImageType::Color2D; + format = + Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.GetDataFmt(), col_buffer.GetNumberFmt()); +} + +ImageViewInfo::ImageViewInfo(const AmdGpu::DepthBuffer& depth_buffer, AmdGpu::DepthView view, + AmdGpu::DepthControl ctl) { + format = Vulkan::LiverpoolToVK::DepthFormat(depth_buffer.z_info.format, + depth_buffer.stencil_info.format); + is_storage = ctl.depth_write_enable; + range.base.layer = view.slice_start; + range.extent.layers = view.NumSlices() - range.base.layer; + type = range.extent.layers > 1 ? AmdGpu::ImageType::Color2DArray : AmdGpu::ImageType::Color2D; +} + +ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info_, + const Image& image) + : info{info_} { + vk::ImageViewUsageCreateInfo usage_ci{.usage = image.usage_flags}; + if (!info.is_storage) { + usage_ci.usage &= ~vk::ImageUsageFlagBits::eStorage; + } + vk::ImageViewMinLodCreateInfoEXT min_lod_ci{}; + if (info.min_lod != 0 && instance.IsImageViewMinLodSupported()) { + const float last_level = + static_cast(info.range.base.level + info.range.extent.levels - 1); + min_lod_ci.minLod = std::min(static_cast(info.min_lod) / 256.f, last_level); + usage_ci.pNext = &min_lod_ci; + } + // When sampling D32/D16 texture from shader, the T# specifies R32/R16 format so adjust it. + vk::Format format = info.format; + vk::ImageAspectFlags aspect = image.aspect_mask; + if (image.aspect_mask & vk::ImageAspectFlagBits::eDepth && + Vulkan::LiverpoolToVK::IsFormatDepthCompatible(format)) { + format = image.info.pixel_format; + aspect = vk::ImageAspectFlagBits::eDepth; + } + if (image.aspect_mask & vk::ImageAspectFlagBits::eStencil && + Vulkan::LiverpoolToVK::IsFormatStencilCompatible(format)) { + format = image.info.pixel_format; + aspect = vk::ImageAspectFlagBits::eStencil; + } + + const vk::ImageViewCreateInfo image_view_ci = { + .pNext = &usage_ci, + .image = image.GetImage(), + .viewType = ConvertImageViewType(info.type), + .format = instance.GetSupportedFormat(format, image.format_features), + .components = info.mapping, + .subresourceRange{ + .aspectMask = aspect, + .baseMipLevel = info.range.base.level, + .levelCount = info.range.extent.levels, + .baseArrayLayer = info.range.base.layer, + .layerCount = info.range.extent.layers, + }, + }; + if (!IsViewTypeCompatible(info.type, image.info.type)) { + LOG_ERROR(Render_Vulkan, "image view type {} is incompatible with image type {}", + magic_enum::enum_name(info.type), magic_enum::enum_name(image.info.type)); + } + + auto [view_result, view] = instance.GetDevice().createImageViewUnique(image_view_ci); + ASSERT_MSG(view_result == vk::Result::eSuccess, "Failed to create image view: {}", + vk::to_string(view_result)); + image_view = std::move(view); + + const auto view_aspect = aspect & vk::ImageAspectFlagBits::eDepth ? "Depth" + : aspect & vk::ImageAspectFlagBits::eStencil ? "Stencil" + : "Color"; + Vulkan::SetObjectName( + instance.GetDevice(), *image_view, "ImageView {}x{}x{} {:#x}:{:#x} {}:{} {}:{} ({})", + image.info.size.width, image.info.size.height, image.info.size.depth, + image.info.guest_address, image.info.guest_size, info.range.base.level, + info.range.base.level + info.range.extent.levels - 1, info.range.base.layer, + info.range.base.layer + info.range.extent.layers - 1, view_aspect); +} + +ImageView::~ImageView() = default; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/image_view.h b/gpu/shadps4/video_core/texture_cache/image_view.h new file mode 100644 index 0000000..02155c6 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/image_view.h @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "video_core/amdgpu/regs_depth.h" +#include "video_core/amdgpu/resource.h" +#include "video_core/renderer_vulkan/vk_common.h" +#include "video_core/texture_cache/types.h" + +namespace AmdGpu { +struct ColorBuffer; +} + +namespace Shader { +struct ImageResource; +} + +namespace Vulkan { +class Instance; +class Scheduler; +} // namespace Vulkan + +namespace VideoCore { + +struct ImageViewInfo { + ImageViewInfo() = default; + ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept; + ImageViewInfo(const AmdGpu::ColorBuffer& col_buffer) noexcept; + ImageViewInfo(const AmdGpu::DepthBuffer& depth_buffer, AmdGpu::DepthView view, + AmdGpu::DepthControl ctl); + + AmdGpu::ImageType type = AmdGpu::ImageType::Color2D; + vk::Format format = vk::Format::eR8G8B8A8Unorm; + SubresourceRange range; + vk::ComponentMapping mapping{}; + u32 min_lod = 0; + bool is_storage = false; + + auto operator<=>(const ImageViewInfo&) const = default; +}; + +struct Image; + +struct ImageView { + ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info, const Image& image); + ~ImageView(); + + ImageView(const ImageView&) = delete; + ImageView& operator=(const ImageView&) = delete; + + ImageView(ImageView&&) = default; + ImageView& operator=(ImageView&&) = default; + + ImageViewInfo info; + vk::UniqueImageView image_view; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/sampler.cpp b/gpu/shadps4/video_core/texture_cache/sampler.cpp new file mode 100644 index 0000000..192ad33 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/sampler.cpp @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "video_core/renderer_vulkan/liverpool_to_vk.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/texture_cache/sampler.h" + +namespace VideoCore { + +Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler, + const AmdGpu::BorderColorBuffer border_color_base, const bool is_depth) { + using namespace Vulkan; + const bool anisotropy_enable = instance.IsAnisotropicFilteringSupported() && + (AmdGpu::IsAnisoFilter(sampler.xy_mag_filter) || + AmdGpu::IsAnisoFilter(sampler.xy_min_filter)); + const float max_anisotropy = + anisotropy_enable ? std::clamp(sampler.MaxAniso(), 1.0f, instance.MaxSamplerAnisotropy()) + : 1.0f; + auto border_color = LiverpoolToVK::BorderColor(sampler.border_color_type); + if (border_color == vk::BorderColor::eFloatCustomEXT && + !instance.IsCustomBorderColorSupported()) { + LOG_WARNING(Render_Vulkan, "Custom border color is not supported, falling back to black"); + border_color = vk::BorderColor::eFloatOpaqueBlack; + } + + const auto custom_color = [&]() -> std::optional { + if (border_color == vk::BorderColor::eFloatCustomEXT) { + const auto border_color_index = sampler.border_color_ptr.Value(); + const auto border_color_buffer = border_color_base.Address*>(); + const auto custom_border_color_array = border_color_buffer[border_color_index]; + + const vk::SamplerCustomBorderColorCreateInfoEXT ret{ + .customBorderColor = + vk::ClearColorValue{ + .float32 = custom_border_color_array, + }, + .format = vk::Format::eR32G32B32A32Sfloat, + }; + return ret; + } else { + return std::nullopt; + } + }(); + + const vk::SamplerCreateInfo sampler_ci = { + .pNext = custom_color ? &*custom_color : nullptr, + .magFilter = LiverpoolToVK::Filter(sampler.xy_mag_filter), + .minFilter = LiverpoolToVK::Filter(sampler.xy_min_filter), + .mipmapMode = LiverpoolToVK::MipFilter(sampler.mip_filter), + .addressModeU = LiverpoolToVK::ClampMode(sampler.clamp_x), + .addressModeV = LiverpoolToVK::ClampMode(sampler.clamp_y), + .addressModeW = LiverpoolToVK::ClampMode(sampler.clamp_z), + .mipLodBias = std::min(sampler.LodBias(), instance.MaxSamplerLodBias()), + .anisotropyEnable = anisotropy_enable, + .maxAnisotropy = max_anisotropy, + // GCN compares per instruction; a plain read of a compare sampler is undefined in Vulkan. + .compareEnable = is_depth, + .compareOp = LiverpoolToVK::DepthCompare(sampler.depth_compare_func), + .minLod = sampler.MinLod(), + .maxLod = sampler.MaxLod(), + .borderColor = border_color, + .unnormalizedCoordinates = false, // Handled in shader due to Vulkan limitations. + }; + auto [sampler_result, smplr] = instance.GetDevice().createSamplerUnique(sampler_ci); + ASSERT_MSG(sampler_result == vk::Result::eSuccess, "Failed to create sampler: {}", + vk::to_string(sampler_result)); + handle = std::move(smplr); +} + +Sampler::~Sampler() = default; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/sampler.h b/gpu/shadps4/video_core/texture_cache/sampler.h new file mode 100644 index 0000000..b68f4e8 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/sampler.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "video_core/amdgpu/regs_texture.h" +#include "video_core/amdgpu/resource.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace Vulkan { +class Instance; +} + +namespace VideoCore { + +class Sampler { +public: + explicit Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sampler, + const AmdGpu::BorderColorBuffer border_color_base, bool is_depth); + ~Sampler(); + + Sampler(const Sampler&) = delete; + Sampler& operator=(const Sampler&) = delete; + + Sampler(Sampler&&) = default; + Sampler& operator=(Sampler&&) = default; + + vk::Sampler Handle() const noexcept { + return *handle; + } + + size_t lru_id{}; + +private: + vk::UniqueSampler handle; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/texture_cache.cpp b/gpu/shadps4/video_core/texture_cache/texture_cache.cpp new file mode 100644 index 0000000..687fb3b --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/texture_cache.cpp @@ -0,0 +1,1090 @@ +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/assert.h" +#include "common/debug.h" +#include "common/div_ceil.h" +#include "common/hash.h" +#include "common/scope_exit.h" +#include "core/emulator_settings.h" +#include "core/memory.h" +#include "video_core/buffer_cache/buffer_cache.h" +#include "video_core/page_manager.h" +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/texture_cache/host_compatibility.h" +#include "video_core/texture_cache/texture_cache.h" +#include "video_core/texture_cache/tile_manager.h" + +namespace VideoCore { + +static constexpr u64 PageShift = 12; +static constexpr u64 NumFramesBeforeRemoval = 32; + +TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, + Vulkan::Runtime& runtime_, AmdGpu::Liverpool* liverpool_, + BufferCache& buffer_cache_, PageManager& tracker_) + : instance{instance_}, scheduler{scheduler_}, runtime{runtime_}, liverpool{liverpool_}, + buffer_cache{buffer_cache_}, tracker{tracker_}, blit_helper{instance, scheduler}, + tile_manager{instance, scheduler, runtime, buffer_cache.GetStreamBuffer()}, + readback_linear_images{EmulatorSettings.IsReadbackLinearImagesEnabled()} { + + u32 max_samplers = instance.GetMaxSamplerAllocationCount(); + trigger_gc_samplers = max_samplers * 3 / 4; + pressure_gc_samplers = max_samplers * 7 / 8; + critical_gc_samplers = max_samplers * 15 / 16; + + // Set up garbage collection parameters. + if (!instance.CanReportMemoryUsage()) { + trigger_gc_memory = 0; + pressure_gc_memory = DEFAULT_PRESSURE_GC_MEMORY; + critical_gc_memory = DEFAULT_CRITICAL_GC_MEMORY; + return; + } + + const s64 device_local_memory = static_cast(instance.GetTotalMemoryBudget()); + const s64 min_spacing_expected = device_local_memory - 1_GB; + const s64 min_spacing_critical = device_local_memory - 512_MB; + const s64 mem_threshold = std::min(device_local_memory, TARGET_GC_THRESHOLD); + const s64 min_vacancy_expected = (6 * mem_threshold) / 10; + const s64 min_vacancy_critical = (2 * mem_threshold) / 10; + pressure_gc_memory = static_cast( + std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), + DEFAULT_PRESSURE_GC_MEMORY)); + critical_gc_memory = static_cast( + std::max(std::min(device_local_memory - min_vacancy_critical, min_spacing_critical), + DEFAULT_CRITICAL_GC_MEMORY)); + trigger_gc_memory = static_cast((device_local_memory - mem_threshold) / 2); +} + +TextureCache::~TextureCache() = default; + +void TextureCache::ProcessDownloadImages() { + std::unique_lock lk{download_images_mutex}; + for (const ImageId image_id : download_images) { + DownloadImageMemory(image_id, true); + } + download_images.clear(); +} + +void TextureCache::DownloadImageMemory(ImageId image_id, bool sync) { + Image& image = slot_images[image_id]; + if (False(image.flags & ImageFlagBits::GpuModified)) { + return; + } + const u32 download_size = image.info.pitch * image.info.size.height * image.info.size.depth * + image.info.resources.layers * (image.info.num_bits / 8); + ASSERT(download_size <= image.info.guest_size); + const auto download = + runtime.GetStagingPool().Request(download_size, MemoryType::HostCached, 16, !sync); + const vk::BufferImageCopy image_download = { + .bufferOffset = download.offset, + .bufferRowLength = image.info.pitch, + .bufferImageHeight = image.info.size.height, + .imageSubresource = + { + .aspectMask = image.info.props.is_depth ? vk::ImageAspectFlagBits::eDepth + : vk::ImageAspectFlagBits::eColor, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = image.info.resources.layers, + }, + .imageOffset = {0, 0, 0}, + .imageExtent = {image.info.size.width, image.info.size.height, image.info.size.depth}, + }; + runtime.DownloadImage(&image, download.buffer, std::span{&image_download, 1}); + if (sync) { + scheduler.Finish(); + download.Invalidate(); + Core::Memory::Instance()->TryWriteBacking(std::bit_cast(image.info.guest_address), + download.mapped, download_size); + } else { + scheduler.DeferPriorityOperation( + [this, device_addr = image.info.guest_address, download, download_size] { + download.Invalidate(); + Core::Memory::Instance()->TryWriteBacking(std::bit_cast(device_addr), + download.mapped, download_size); + runtime.GetStagingPool().FreeDeferred(download); + }); + } +} + +void TextureCache::MarkAsMaybeDirty(ImageId image_id, Image& image) { + if (image.hash == 0) { + // Initialize hash + const u8* addr = std::bit_cast(image.info.guest_address); + image.hash = XXH3_64bits(addr, image.info.guest_size); + } + image.flags |= ImageFlagBits::MaybeCpuDirty; + UntrackImage(image_id); +} + +void TextureCache::InvalidateMemory(VAddr addr, size_t size) { + std::scoped_lock lock{mutex}; + const auto pages_start = PageManager::GetPageAddr(addr); + const auto pages_end = PageManager::GetNextPageAddr(addr + size - 1); + ForEachImageInRegion(pages_start, pages_end - pages_start, [&](ImageId image_id, Image& image) { + const auto image_begin = image.info.guest_address; + const auto image_end = image.info.guest_address + image.info.guest_size; + if (image.Overlaps(addr, size)) { + // Modified region overlaps image, so the image was definitely accessed by this fault. + // Untrack the image, so that the range is unprotected and the guest can write freely. + image.flags |= ImageFlagBits::CpuDirty; + UntrackImage(image_id); + } else if (pages_end < image_end) { + // This page access may or may not modify the image. + // We should not mark it as dirty now. If it really was modified + // it will receive more invalidations on its other pages. + // Remove tracking from this page only. + UntrackImageHead(image_id); + } else if (image_begin < pages_start) { + // This page access does not modify the image but the page should be untracked. + // We should not mark this image as dirty now. If it really was modified + // it will receive more invalidations on its other pages. + UntrackImageTail(image_id); + } else { + // Image begins and ends on this page so it can not receive any more invalidations. + // We will check it's hash later to see if it really was modified. + MarkAsMaybeDirty(image_id, image); + } + }); +} + +void TextureCache::InvalidateMemoryFromGPU(VAddr address, size_t max_size) { + std::scoped_lock lock{mutex}; + ForEachImageInRegion(address, max_size, [&](ImageId image_id, Image& image) { + // Only consider images that match base address. + // TODO: Maybe also consider subresources + if (image.info.guest_address != address) { + return; + } + // Ensure image is reuploaded when accessed again. + image.flags |= ImageFlagBits::GpuDirty; + }); +} + +void TextureCache::UnmapMemory(VAddr cpu_addr, size_t size) { + std::scoped_lock lk{mutex}; + + ImageIds deleted_images; + ForEachImageInRegion(cpu_addr, size, [&](ImageId id, Image&) { deleted_images.push_back(id); }); + for (const ImageId id : deleted_images) { + // TODO: Download image data back to host. + FreeImage(id); + } +} + +ImageId TextureCache::ResolveDepthOverlap(const ImageInfo& requested_info, BindingType binding, + ImageId cache_image_id) { + auto& cache_image = slot_images[cache_image_id]; + + if (!cache_image.info.props.is_depth && !requested_info.props.is_depth) { + return {}; + } + + const bool stencil_match = + requested_info.props.has_stencil == cache_image.info.props.has_stencil; + const bool bpp_match = requested_info.num_bits == cache_image.info.num_bits; + + // If an image in the cache has less slices we need to expand it + bool recreate = cache_image.info.resources < requested_info.resources; + + switch (binding) { + case BindingType::Texture: + // The guest requires a depth sampled texture, but cache can offer only Rxf. Need to + // recreate the image. + recreate |= requested_info.props.is_depth && !cache_image.info.props.is_depth; + break; + case BindingType::Storage: + // If the guest is going to use previously created depth as storage, the image needs to be + // recreated. (TODO: Probably a case with linear rgba8 aliasing is legit) + recreate |= cache_image.info.props.is_depth; + break; + case BindingType::RenderTarget: + // Render target can have only Rxf format. If the cache contains only Dx[S8] we need to + // re-create the image. + ASSERT(!requested_info.props.is_depth); + recreate |= cache_image.info.props.is_depth; + break; + case BindingType::DepthTarget: + // The guest has requested previously allocated texture to be bound as a depth target. + // In this case we need to convert Rx float to a Dx[S8] as requested + recreate |= !cache_image.info.props.is_depth; + + // The guest is trying to bind a depth target and cache has it. Need to be sure that aspects + // and bpp match + recreate |= cache_image.info.props.is_depth && !(stencil_match && bpp_match); + break; + default: + break; + } + + if (recreate) { + auto new_info = requested_info; + new_info.resources = std::max(requested_info.resources, cache_image.info.resources); + new_info.UpdateSize(); + const auto new_image_id = slot_images.insert(instance, runtime, slot_image_views, new_info); + RegisterImage(new_image_id); + + // Inherit image usage + auto& new_image = slot_images[new_image_id]; + new_image.usage = cache_image.usage; + new_image.flags &= ~ImageFlagBits::Dirty; + // When creating a depth buffer through overlap resolution don't clear it on first use. + new_image.info.meta_info.htile_clear_mask = 0; + runtime.CopyColorAndDepth(&cache_image, &new_image); + + // Free the cache image. + FreeImage(cache_image_id); + return new_image_id; + } + + // Will be handled by view + return cache_image_id; +} + +std::tuple TextureCache::ResolveOverlap(const ImageInfo& image_info, + BindingType binding, + ImageId cache_image_id, + ImageId merged_image_id) { + auto& cache_image = slot_images[cache_image_id]; + const bool safe_to_delete = + scheduler.CurrentTick() - cache_image.tick_accessed_last > NumFramesBeforeRemoval; + + // Equal address + if (image_info.guest_address == cache_image.info.guest_address) { + const u32 lhs_block_size = image_info.num_bits * image_info.num_samples; + const u32 rhs_block_size = cache_image.info.num_bits * cache_image.info.num_samples; + if (image_info.BlockDim() != cache_image.info.BlockDim() || + lhs_block_size != rhs_block_size) { + // Very likely this kind of overlap is caused by allocation from a pool. + if (safe_to_delete) { + FreeImage(cache_image_id); + } + return {merged_image_id, -1, -1}; + } + + if (const auto depth_image_id = ResolveDepthOverlap(image_info, binding, cache_image_id)) { + return {depth_image_id, -1, -1}; + } + + // Compressed view of uncompressed image with same block size. + if (image_info.props.is_block && !cache_image.info.props.is_block) { + return {ExpandImage(image_info, cache_image_id), -1, -1}; + } + + if (image_info.guest_size == cache_image.info.guest_size && + (image_info.type == AmdGpu::ImageType::Color3D || + cache_image.info.type == AmdGpu::ImageType::Color3D)) { + return {ExpandImage(image_info, cache_image_id), -1, -1}; + } + + const bool pow2_padding_only = + image_info.props.is_pow2 != cache_image.info.props.is_pow2 && + image_info.tile_mode == cache_image.info.tile_mode && + image_info.size == cache_image.info.size && + image_info.pitch == cache_image.info.pitch && image_info.resources.levels == 1 && + cache_image.info.resources.levels == 1 && image_info.resources.layers == 1 && + cache_image.info.resources.layers == 1; + + // Size and resources are less than or equal, use image view. + if (image_info.pixel_format != cache_image.info.pixel_format || + image_info.guest_size <= cache_image.info.guest_size || pow2_padding_only) { + auto result_id = merged_image_id ? merged_image_id : cache_image_id; + const auto& result_image = slot_images[result_id]; + const bool is_compatible = + IsVulkanFormatCompatible(result_image.info.pixel_format, image_info.pixel_format); + return {is_compatible ? result_id : ImageId{}, -1, -1}; + } + + // Size and resources are greater, expand the image. + if (image_info.type == cache_image.info.type && + image_info.resources > cache_image.info.resources) { + return {ExpandImage(image_info, cache_image_id), -1, -1}; + } + + // Size is greater but resources are not, because the tiling mode is different. + // Likely the address is reused for a image with a different tiling mode. + if (image_info.tile_mode != cache_image.info.tile_mode) { + if (safe_to_delete) { + FreeImage(cache_image_id); + } + return {merged_image_id, -1, -1}; + } + + // Enhanced debug logging for unreachable case + // Calculate expected size based on format and dimensions + u64 expected_size = + (static_cast(image_info.size.width) * static_cast(image_info.size.height) * + static_cast(image_info.size.depth) * static_cast(image_info.num_bits) / 8); + LOG_ERROR(Render_Vulkan, + "Unresolvable image overlap with equal memory address:\n" + "=== OLD IMAGE (cached) ===\n" + " Address: {:#x}\n" + " Size: {:#x} bytes\n" + " Format: {}\n" + " Type: {}\n" + " Width: {}\n" + " Height: {}\n" + " Depth: {}\n" + " Pitch: {}\n" + " Mip levels: {}\n" + " Array layers: {}\n" + " Samples: {}\n" + " Tile mode: {:#x}\n" + " Block size: {} bits\n" + " Is block-comp: {}\n" + " Guest size: {:#x}\n" + " Last accessed: tick {}\n" + " Safe to delete: {}\n" + " isPow2: {}\n" + " Alt tile: {}\n" + "\n" + "=== NEW IMAGE (requested) ===\n" + " Address: {:#x}\n" + " Size: {:#x} bytes\n" + " Format: {}\n" + " Type: {}\n" + " Width: {}\n" + " Height: {}\n" + " Depth: {}\n" + " Pitch: {}\n" + " Mip levels: {}\n" + " Array layers: {}\n" + " Samples: {}\n" + " Tile mode: {:#x}\n" + " Block size: {} bits\n" + " Is block-comp: {}\n" + " Guest size: {:#x}\n" + " isPow2: {}\n" + " Alt tile: {}\n" + "\n" + "=== COMPARISON ===\n" + " Same format: {}\n" + " Same type: {}\n" + " Same tile mode: {}\n" + " Same block size: {}\n" + " Same BlockDim: {}\n" + " Same pitch: {}\n" + " Same pow2: {}\n" + " Same alt tile: {}\n" + " Old resources <= new: {} (old: {}, new: {})\n" + " Old size <= new size: {}\n" + " Expected size (calc): {} bytes\n" + " Size ratio (new/expected): {:.2f}x\n" + " Size ratio (new/old): {:.2f}x\n" + " Old vs expected diff: {} bytes ({:+.2f}%)\n" + " New vs expected diff: {} bytes ({:+.2f}%)\n" + " Merged image ID: {}\n" + " Binding type: {}\n" + " Current tick: {}\n" + " Age (ticks since last access): {}", + + // Old image details + cache_image.info.guest_address, cache_image.info.guest_size, + vk::to_string(cache_image.info.pixel_format), + static_cast(cache_image.info.type), cache_image.info.size.width, + cache_image.info.size.height, cache_image.info.size.depth, cache_image.info.pitch, + cache_image.info.resources.levels, cache_image.info.resources.layers, + cache_image.info.num_samples, static_cast(cache_image.info.tile_mode), + cache_image.info.num_bits, +cache_image.info.props.is_block, + cache_image.info.guest_size, cache_image.tick_accessed_last, safe_to_delete, + bool(cache_image.info.props.is_pow2), cache_image.info.alt_tile, + + // New image details + image_info.guest_address, image_info.guest_size, + vk::to_string(image_info.pixel_format), static_cast(image_info.type), + image_info.size.width, image_info.size.height, image_info.size.depth, + image_info.pitch, image_info.resources.levels, image_info.resources.layers, + image_info.num_samples, static_cast(image_info.tile_mode), + image_info.num_bits, image_info.props.is_block, image_info.guest_size, + bool(image_info.props.is_pow2), image_info.alt_tile, + + // Comparison + (image_info.pixel_format == cache_image.info.pixel_format), + (image_info.type == cache_image.info.type), + (image_info.tile_mode == cache_image.info.tile_mode), + (image_info.num_bits == cache_image.info.num_bits), + (image_info.BlockDim() == cache_image.info.BlockDim()), + (image_info.pitch == cache_image.info.pitch), + (image_info.props.is_pow2 == cache_image.info.props.is_pow2), + (image_info.alt_tile == cache_image.info.alt_tile), + (cache_image.info.resources <= image_info.resources), + cache_image.info.resources.levels, image_info.resources.levels, + (cache_image.info.guest_size <= image_info.guest_size), expected_size, + + // Size ratios + static_cast(image_info.guest_size) / expected_size, + static_cast(image_info.guest_size) / cache_image.info.guest_size, + + // Difference between actual and expected sizes with percentages + static_cast(cache_image.info.guest_size) - static_cast(expected_size), + (static_cast(cache_image.info.guest_size) / expected_size - 1.0) * 100.0, + + static_cast(image_info.guest_size) - static_cast(expected_size), + (static_cast(image_info.guest_size) / expected_size - 1.0) * 100.0, + + merged_image_id.index, static_cast(binding), scheduler.CurrentTick(), + scheduler.CurrentTick() - cache_image.tick_accessed_last); + + UNREACHABLE_MSG("Encountered unresolvable image overlap with equal memory address."); + } + + // Right overlap, the image requested is a possible subresource of the image from cache. + if (image_info.guest_address > cache_image.info.guest_address) { + if (auto mip = image_info.MipOf(cache_image.info); mip >= 0) { + if (auto slice = image_info.SliceOf(cache_image.info, mip); slice >= 0) { + return {cache_image_id, mip, slice}; + } + } + + // Image isn't a subresource but a chance overlap. + if (safe_to_delete) { + FreeImage(cache_image_id); + } + + return {{}, -1, -1}; + } else { + // Left overlap, the image from cache is a possible subresource of the image requested + if (auto mip = cache_image.info.MipOf(image_info); mip >= 0) { + if (auto slice = cache_image.info.SliceOf(image_info, mip); slice >= 0) { + // We have a larger image created and a separate one, representing a subres of it + // bound as render target. In this case we need to rebind render target. + if (cache_image.binding.is_target) { + cache_image.binding.needs_rebind = 1u; + if (merged_image_id) { + GetImage(merged_image_id).binding.is_target = 1u; + } + + FreeImage(cache_image_id); + return {merged_image_id, -1, -1}; + } + + // We need to have a larger, already allocated image to copy this one into + if (merged_image_id) { + auto& merged_image = slot_images[merged_image_id]; + runtime.CopyMip(&cache_image, &merged_image, mip, slice); + FreeImage(cache_image_id); + } + } + } + } + + return {merged_image_id, -1, -1}; +} + +ImageId TextureCache::ExpandImage(const ImageInfo& info, ImageId image_id) { + const auto new_image_id = slot_images.insert(instance, runtime, slot_image_views, info); + RegisterImage(new_image_id); + + auto& src_image = slot_images[image_id]; + auto& new_image = slot_images[new_image_id]; + + RefreshImage(new_image); + runtime.CopyImage(&src_image, &new_image); + + if (src_image.binding.is_bound || src_image.binding.is_target) { + src_image.binding.needs_rebind = 1u; + } + + FreeImage(image_id); + TrackImage(new_image_id); + return new_image_id; +} + +ImageId TextureCache::FindImage(ImageDesc& desc, bool exact_fmt) { + const auto& info = desc.info; + ASSERT(info.guest_address != 0); + + std::scoped_lock lock{mutex}; + ImageIds image_ids; + ForEachImageInRegion(info.guest_address, info.guest_size, + [&](ImageId image_id, Image& image) { image_ids.push_back(image_id); }); + + ImageId image_id{}; + + // Check for a perfect match first + for (const auto& cache_id : image_ids) { + auto& cache_image = slot_images[cache_id]; + if (cache_image.info.guest_address != info.guest_address) { + continue; + } + if (cache_image.info.guest_size != info.guest_size) { + continue; + } + if (cache_image.info.size != info.size) { + continue; + } + if (!IsVulkanFormatCompatible(cache_image.info.pixel_format, info.pixel_format) || + (cache_image.info.type != info.type && info.size != Extent3D{1, 1, 1})) { + continue; + } + if (exact_fmt && info.pixel_format != cache_image.info.pixel_format) { + continue; + } + image_id = cache_id; + } + + // Try to resolve overlaps (if any) + int view_mip{-1}; + int view_slice{-1}; + if (!image_id) { + for (const auto& cache_id : image_ids) { + view_mip = -1; + view_slice = -1; + + const auto& merged_info = image_id ? slot_images[image_id].info : info; + auto [overlap_image_id, overlap_view_mip, overlap_view_slice] = + ResolveOverlap(merged_info, desc.type, cache_id, image_id); + if (overlap_image_id) { + image_id = overlap_image_id; + view_mip = overlap_view_mip; + view_slice = overlap_view_slice; + } + } + } + + if (image_id) { + Image& image_resolved = slot_images[image_id]; + if (exact_fmt && info.pixel_format != image_resolved.info.pixel_format) { + // Cannot reuse this image as we need the exact requested format. + image_id = {}; + } else if (image_resolved.info.resources < info.resources) { + // The image was clearly picked up wrong. + FreeImage(image_id); + image_id = {}; + LOG_WARNING(Render_Vulkan, "Image overlap resolve failed"); + } + } + // Create and register a new image + if (!image_id) { + image_id = slot_images.insert(instance, runtime, slot_image_views, info); + RegisterImage(image_id); + } + + Image& image = slot_images[image_id]; + image.tick_accessed_last = scheduler.CurrentTick(); + TouchImage(image); + + // If the image requested is a subresource of the image from cache record its location. + if (view_mip > 0) { + desc.view_info.range.base.level = view_mip; + } + if (view_slice > 0) { + desc.view_info.range.base.layer = view_slice; + } + + return image_id; +} + +ImageId TextureCache::FindImageFromRange(VAddr address, size_t size, bool ensure_valid) { + ImageIds image_ids; + ForEachImageInRegion(address, size, [&](ImageId image_id, Image& image) { + if (image.info.guest_address != address) { + return; + } + if (ensure_valid && !image.SafeToDownload()) { + return; + } + image_ids.push_back(image_id); + }); + if (image_ids.size() == 1) { + // Sometimes image size might not exactly match with requested buffer size + // If we only found 1 candidate image use it without too many questions. + return image_ids.back(); + } + if (!image_ids.empty()) { + for (s32 i = 0; i < image_ids.size(); ++i) { + Image& image = slot_images[image_ids[i]]; + if (image.info.guest_size == size) { + return image_ids[i]; + } + } + LOG_WARNING(Render_Vulkan, + "Failed to find exact image match for copy addr={:#x}, size={:#x}", address, + size); + } + return {}; +} + +ImageView& TextureCache::FindTexture(ImageId image_id, const ImageDesc& desc) { + Image& image = slot_images[image_id]; + if (desc.type == BindingType::Storage) { + image.flags |= ImageFlagBits::GpuModified; + if (readback_linear_images && (!image.info.props.is_tiled || image.info.size.width <= 8) && + image.info.guest_address != 0) { + std::unique_lock lk{download_images_mutex}; + download_images.emplace(image_id); + } + } + UpdateImage(image_id); + return image.FindView(desc.view_info); +} + +ImageView& TextureCache::FindRenderTarget(ImageId image_id, const ImageDesc& desc) { + Image& image = slot_images[image_id]; + image.flags |= ImageFlagBits::GpuModified; + if (readback_linear_images && (!image.info.props.is_tiled || image.info.size.width <= 8)) { + std::unique_lock lk{download_images_mutex}; + download_images.emplace(image_id); + } + image.usage.render_target = 1u; + UpdateImage(image_id); + + // Register meta data for this color buffer + if (desc.info.meta_info.cmask_addr) { + surface_metas.emplace(desc.info.meta_info.cmask_addr, + MetaDataInfo{.type = MetaType::CMask}); + image.info.meta_info.cmask_addr = desc.info.meta_info.cmask_addr; + } + + if (desc.info.meta_info.fmask_addr) { + surface_metas.emplace(desc.info.meta_info.fmask_addr, + MetaDataInfo{.type = MetaType::FMask}); + image.info.meta_info.fmask_addr = desc.info.meta_info.fmask_addr; + } + + return image.FindView(desc.view_info, false); +} + +ImageView& TextureCache::FindDepthTarget(ImageId image_id, const ImageDesc& desc) { + Image& image = slot_images[image_id]; + image.flags |= ImageFlagBits::GpuModified; + image.usage.depth_target = 1u; + UpdateImage(image_id); + + // Register meta data for this depth buffer + if (desc.info.meta_info.htile_addr) { + surface_metas.emplace(desc.info.meta_info.htile_addr, + MetaDataInfo{.type = MetaType::HTile, + .clear_mask = image.info.meta_info.htile_clear_mask}); + image.info.meta_info.htile_addr = desc.info.meta_info.htile_addr; + } + + // If there is a stencil attachment, link depth and stencil. + if (desc.info.stencil_addr != 0) { + ImageId stencil_id{}; + ForEachImageInRegion(desc.info.stencil_addr, desc.info.stencil_size, + [&](ImageId image_id, Image& image) { + if (image.info.guest_address == desc.info.stencil_addr) { + stencil_id = image_id; + } + }); + if (!stencil_id) { + ImageInfo info{}; + info.guest_address = desc.info.stencil_addr; + info.guest_size = desc.info.stencil_size; + info.size = desc.info.size; + stencil_id = slot_images.insert(instance, runtime, slot_image_views, info); + RegisterImage(stencil_id); + } + Image& stencil_image = slot_images[stencil_id]; + TouchImage(stencil_image); + stencil_image.AssociateDepth(image_id, image.image_uid); + } + + return image.FindView(desc.view_info, false); +} + +void TextureCache::RefreshImage(Image& image) { + if (False(image.flags & ImageFlagBits::Dirty) || image.info.num_samples > 1) { + return; + } + + RENDERER_TRACE; + TRACE_HINT(fmt::format("{:x}:{:x}", image.info.guest_address, image.info.guest_size)); + + if (True(image.flags & ImageFlagBits::MaybeCpuDirty) && + False(image.flags & ImageFlagBits::CpuDirty)) { + // The image size should be less than page size to be considered MaybeCpuDirty + // So this calculation should be very uncommon and reasonably fast + // For now we'll just check up to 64 first pixels + const auto addr = std::bit_cast(image.info.guest_address); + const u32 w = std::min(image.info.size.width, u32(8)); + const u32 h = std::min(image.info.size.height, u32(8)); + + const u32 s_w = image.info.props.is_block ? Common::DivCeil(w, 4u) : w; + const u32 s_h = image.info.props.is_block ? Common::DivCeil(h, 4u) : h; + const u32 size = s_w * s_h * (image.info.num_bits / 8); + const u64 hash = XXH3_64bits(addr, size); + if (image.hash == hash) { + image.flags &= ~ImageFlagBits::MaybeCpuDirty; + return; + } + image.hash = hash; + } + + const u32 num_layers = image.info.resources.layers; + const u32 num_mips = image.info.resources.levels; + const bool is_gpu_modified = True(image.flags & ImageFlagBits::GpuModified); + const bool is_gpu_dirty = True(image.flags & ImageFlagBits::GpuDirty); + + boost::container::small_vector image_copies; + for (u32 m = 0; m < num_mips; m++) { + const u32 width = std::max(image.info.size.width >> m, 1u); + const u32 height = std::max(image.info.size.height >> m, 1u); + const u32 depth = + image.info.props.is_volume ? std::max(image.info.size.depth >> m, 1u) : 1u; + const auto [mip_size, mip_pitch, mip_height, mip_offset] = image.info.mips_layout[m]; + + // Protect GPU modified resources from accidental CPU reuploads. + if (is_gpu_modified && !is_gpu_dirty) { + const u8* addr = std::bit_cast(image.info.guest_address); + const u64 hash = XXH3_64bits(addr + mip_offset, mip_size); + if (image.mip_hashes[m] == hash) { + continue; + } + image.mip_hashes[m] = hash; + } + + const u32 extent_width = mip_pitch ? std::min(mip_pitch, width) : width; + const u32 extent_height = mip_height ? std::min(mip_height, height) : height; + image_copies.push_back({ + .bufferOffset = mip_offset, + .bufferRowLength = mip_pitch, + .bufferImageHeight = mip_height, + .imageSubresource{ + .aspectMask = image.aspect_mask & ~vk::ImageAspectFlagBits::eStencil, + .mipLevel = m, + .baseArrayLayer = 0, + .layerCount = num_layers, + }, + .imageOffset = {0, 0, 0}, + .imageExtent = {extent_width, extent_height, depth}, + }); + } + + if (image_copies.empty()) { + image.flags &= ~ImageFlagBits::Dirty; + return; + } + + scheduler.EndRendering(); + + const auto [in_buffer, in_offset] = + buffer_cache.ObtainBufferForImage(image.info.guest_address, image.info.guest_size); + const auto [buffer, offset] = tile_manager.DetileImage(in_buffer, in_offset, image.info); + for (auto& copy : image_copies) { + copy.bufferOffset += offset; + } + + runtime.UploadImage(&image, buffer, image_copies); +} + +vk::Sampler TextureCache::GetSampler(const AmdGpu::Sampler& sampler, + AmdGpu::BorderColorBuffer border_color_base, + const bool is_depth) { + // Compare and plain uses of one S# need separate samplers. + const u64 hash = HashCombine(XXH3_64bits(&sampler, sizeof(sampler)), is_depth); + + std::scoped_lock lock{samplers_mutex}; + const auto [it, new_sampler] = + samplers.try_emplace(hash, instance, sampler, border_color_base, is_depth); + if (new_sampler) { + samplers.at(hash).lru_id = sampler_lru_cache.Insert(hash, gc_tick); + } else { + sampler_lru_cache.Touch(it->second.lru_id, gc_tick); + } + + return it->second.Handle(); +} + +void TextureCache::RegisterImage(ImageId image_id) { + Image& image = slot_images[image_id]; + ASSERT_MSG(False(image.flags & ImageFlagBits::Registered), + "Trying to register an already registered image"); + image.flags |= ImageFlagBits::Registered; + total_used_memory += Common::AlignUp(image.info.guest_size, 1024); + image.lru_id = lru_cache.Insert(image_id, gc_tick); + ForEachPage(image.info.guest_address, image.info.guest_size, + [this, image_id](u64 page) { page_table[page].push_back(image_id); }); +} + +void TextureCache::UnregisterImage(ImageId image_id) { + Image& image = slot_images[image_id]; + ASSERT_MSG(True(image.flags & ImageFlagBits::Registered), + "Trying to unregister an already unregistered image"); + image.flags &= ~ImageFlagBits::Registered; + lru_cache.Free(image.lru_id); + total_used_memory -= Common::AlignUp(image.info.guest_size, 1024); + ForEachPage(image.info.guest_address, image.info.guest_size, [this, image_id](u64 page) { + const auto page_it = page_table.find(page); + if (page_it == nullptr) { + UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PageShift); + return; + } + auto& image_ids = *page_it; + const auto vector_it = std::ranges::find(image_ids, image_id); + if (vector_it == image_ids.end()) { + ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}", page << PageShift); + return; + } + image_ids.erase(vector_it); + }); +} + +void TextureCache::TrackImage(ImageId image_id) { + auto& image = slot_images[image_id]; + if (!(image.flags & ImageFlagBits::Registered)) { + return; + } + const auto image_begin = image.info.guest_address; + const auto image_end = image.info.guest_address + image.info.guest_size; + if (image_begin == image.track_addr && image_end == image.track_addr_end) { + return; + } + + if (!image.IsTracked()) { + // Re-track the whole image + image.track_addr = image_begin; + image.track_addr_end = image_end; + tracker.UpdatePageWatchers<1>(image_begin, image.info.guest_size); + } else { + if (image_begin < image.track_addr) { + TrackImageHead(image_id); + } + if (image.track_addr_end < image_end) { + TrackImageTail(image_id); + } + } +} + +void TextureCache::TrackImageHead(ImageId image_id) { + auto& image = slot_images[image_id]; + if (!(image.flags & ImageFlagBits::Registered)) { + return; + } + const auto image_begin = image.info.guest_address; + if (image_begin == image.track_addr) { + return; + } + ASSERT(image.track_addr != 0 && image_begin < image.track_addr); + const auto size = image.track_addr - image_begin; + image.track_addr = image_begin; + tracker.UpdatePageWatchers<1>(image_begin, size); +} + +void TextureCache::TrackImageTail(ImageId image_id) { + auto& image = slot_images[image_id]; + if (!(image.flags & ImageFlagBits::Registered)) { + return; + } + const auto image_end = image.info.guest_address + image.info.guest_size; + if (image_end == image.track_addr_end) { + return; + } + ASSERT(image.track_addr_end != 0 && image.track_addr_end < image_end); + const auto addr = image.track_addr_end; + const auto size = image_end - image.track_addr_end; + image.track_addr_end = image_end; + tracker.UpdatePageWatchers<1>(addr, size); +} + +void TextureCache::UntrackImage(ImageId image_id) { + auto& image = slot_images[image_id]; + if (!image.IsTracked()) { + return; + } + const auto addr = image.track_addr; + const auto size = image.track_addr_end - image.track_addr; + image.track_addr = 0; + image.track_addr_end = 0; + if (size != 0) { + tracker.UpdatePageWatchers(addr, size); + } +} + +void TextureCache::UntrackImageHead(ImageId image_id) { + auto& image = slot_images[image_id]; + const auto image_begin = image.info.guest_address; + if (!image.IsTracked() || image_begin < image.track_addr) { + return; + } + const auto addr = tracker.GetNextPageAddr(image_begin); + const auto size = addr - image_begin; + image.track_addr = addr; + if (image.track_addr == image.track_addr_end) { + // This image spans only 2 pages and both are modified, + // but the image itself was not directly affected. + // Cehck its hash later. + MarkAsMaybeDirty(image_id, image); + } + tracker.UpdatePageWatchers(image_begin, size); +} + +void TextureCache::UntrackImageTail(ImageId image_id) { + auto& image = slot_images[image_id]; + const auto image_end = image.info.guest_address + image.info.guest_size; + if (!image.IsTracked() || image.track_addr_end < image_end) { + return; + } + ASSERT(image.track_addr_end != 0); + const auto addr = tracker.GetPageAddr(image_end); + const auto size = image_end - addr; + image.track_addr_end = addr; + if (image.track_addr == image.track_addr_end) { + // This image spans only 2 pages and both are modified, + // but the image itself was not directly affected. + // Cehck its hash later. + MarkAsMaybeDirty(image_id, image); + } + tracker.UpdatePageWatchers(addr, size); +} + +void TextureCache::GarbageCollectImages() { + if (instance.CanReportMemoryUsage()) { + total_used_memory = instance.GetDeviceMemoryUsage(); + } + if (total_used_memory < trigger_gc_memory) { + return; + } + std::scoped_lock lock{mutex}; + bool pressured = false; + bool aggresive = false; + u64 ticks_to_destroy = 0; + size_t num_deletions = 0; + + const auto configure = [&](bool allow_aggressive) { + pressured = total_used_memory >= pressure_gc_memory; + aggresive = allow_aggressive && total_used_memory >= critical_gc_memory; + ticks_to_destroy = aggresive ? 160 : pressured ? 80 : 16; + ticks_to_destroy = std::min(ticks_to_destroy, gc_tick); + num_deletions = aggresive ? 40 : pressured ? 20 : 10; + }; + const auto clean_up = [&](ImageId image_id) { + if (num_deletions == 0) { + return true; + } + --num_deletions; + auto& image = slot_images[image_id]; + const bool download = image.SafeToDownload(); + const bool tiled = image.info.IsTiled(); + if (tiled && download) { + // This is a workaround for now. We can't handle non-linear image downloads. + return false; + } + if (download && !pressured) { + return false; + } + if (download) { + DownloadImageMemory(image_id); + } + FreeImage(image_id); + if (total_used_memory < critical_gc_memory) { + if (aggresive) { + num_deletions >>= 2; + aggresive = false; + return false; + } + if (pressured && total_used_memory < pressure_gc_memory) { + num_deletions >>= 1; + pressured = false; + } + } + return false; + }; + + // Try to remove anything old enough and not high priority. + configure(false); + lru_cache.ForEachItemBelow(gc_tick - ticks_to_destroy, clean_up); + + if (total_used_memory >= critical_gc_memory) { + // If we are still over the critical limit, run an aggressive GC + configure(true); + lru_cache.ForEachItemBelow(gc_tick - ticks_to_destroy, clean_up); + } +} + +void TextureCache::GarbageCollectSamplers() { + total_used_samplers = samplers.size(); + if (total_used_samplers < trigger_gc_samplers) { + return; + } + std::scoped_lock lock{samplers_mutex}; + bool pressured = false; + bool aggresive = false; + u64 ticks_to_destroy = 0; + size_t num_deletions = 0; + + const auto configure = [&](bool allow_aggressive) { + pressured = total_used_samplers >= pressure_gc_samplers; + aggresive = allow_aggressive && total_used_samplers >= critical_gc_samplers; + ticks_to_destroy = aggresive ? 160 : pressured ? 80 : 16; + ticks_to_destroy = std::min(ticks_to_destroy, gc_tick); + num_deletions = aggresive ? 40 : pressured ? 20 : 10; + }; + const auto clean_up = [&](u64 hash) { + if (num_deletions == 0) { + return true; + } + --num_deletions; + const size_t lru_id = samplers.at(hash).lru_id; + samplers.erase(hash); + sampler_lru_cache.Free(lru_id); + return false; + }; + + // Try to remove anything old enough and not high priority. + configure(false); + sampler_lru_cache.ForEachItemBelow(gc_tick - ticks_to_destroy, clean_up); + + if (total_used_samplers >= critical_gc_samplers) { + // If we are still over the critical limit, run an aggressive GC + configure(true); + sampler_lru_cache.ForEachItemBelow(gc_tick - ticks_to_destroy, clean_up); + } +} + +void TextureCache::RunGarbageCollector() { + SCOPE_EXIT { + ++gc_tick; + }; + + GarbageCollectImages(); + GarbageCollectSamplers(); +} + +void TextureCache::TouchImage(const Image& image) { + lru_cache.Touch(image.lru_id, gc_tick); +} + +void TextureCache::DeleteImage(ImageId image_id) { + Image& image = slot_images[image_id]; + ASSERT_MSG(!image.IsTracked(), "Image was not untracked"); + ASSERT_MSG(False(image.flags & ImageFlagBits::Registered), "Image was not unregistered"); + + // Remove any registered meta areas. + const auto& meta_info = image.info.meta_info; + if (meta_info.cmask_addr) { + surface_metas.erase(meta_info.cmask_addr); + } + if (meta_info.fmask_addr) { + surface_metas.erase(meta_info.fmask_addr); + } + if (meta_info.htile_addr) { + surface_metas.erase(meta_info.htile_addr); + } + + { + std::unique_lock lk{download_images_mutex}; + if (download_images.contains(image_id)) { + download_images.erase(image_id); + } + } + + // Reclaim image and any image views it references. + scheduler.DeferOperation([this, image_id] { + Image& image = slot_images[image_id]; + for (auto& backing : image.backing_images) { + for (const ImageViewId image_view_id : backing.image_view_ids) { + slot_image_views.erase(image_view_id); + } + } + slot_images.erase(image_id); + }); +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/texture_cache.h b/gpu/shadps4/video_core/texture_cache/texture_cache.h new file mode 100644 index 0000000..69309d3 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/texture_cache.h @@ -0,0 +1,365 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "common/lru_cache.h" +#include "common/slot_vector.h" +#include "shader_recompiler/resource.h" +#include "video_core/multi_level_page_table.h" +#include "video_core/texture_cache/blit_helper.h" +#include "video_core/texture_cache/image.h" +#include "video_core/texture_cache/image_view.h" +#include "video_core/texture_cache/sampler.h" +#include "video_core/texture_cache/tile_manager.h" + +namespace AmdGpu { +struct Liverpool; +} + +namespace Vulkan { +class Runtime; +} + +namespace VideoCore { + +class BufferCache; +class PageManager; + +class TextureCache { + // Default values for garbage collection + static constexpr s64 DEFAULT_PRESSURE_GC_MEMORY = 1_GB + 512_MB; + static constexpr s64 DEFAULT_CRITICAL_GC_MEMORY = 3_GB; + static constexpr s64 TARGET_GC_THRESHOLD = 8_GB; + + using ImageIds = boost::container::small_vector; + + struct Traits { + using Entry = ImageIds; + static constexpr size_t AddressSpaceBits = 40; + static constexpr size_t FirstLevelBits = 10; + static constexpr size_t PageBits = 20; + }; + using PageTable = MultiLevelPageTable; + +public: + enum class BindingType : u32 { + Texture, + Storage, + RenderTarget, + DepthTarget, + VideoOut, + }; + + struct ImageDesc { + ImageInfo info; + ImageViewInfo view_info; + BindingType type{BindingType::Texture}; + + ImageDesc() = default; + ImageDesc(const AmdGpu::Image& image, const Shader::ImageResource& desc) + : info{image, desc}, view_info{image, desc}, + type{desc.is_written ? BindingType::Storage : BindingType::Texture} {} + ImageDesc(const AmdGpu::ColorBuffer& buffer, AmdGpu::CbDbExtent hint) + : info{buffer, hint}, view_info{buffer}, type{BindingType::RenderTarget} {} + ImageDesc(const AmdGpu::DepthBuffer& buffer, AmdGpu::DepthView view, + AmdGpu::DepthControl ctl, VAddr htile_address, AmdGpu::CbDbExtent hint, + bool write_buffer = false) + : info{buffer, view.NumSlices(), htile_address, hint, write_buffer}, + view_info{buffer, view, ctl}, type{BindingType::DepthTarget} {} + ImageDesc(const Libraries::VideoOut::BufferAttributeGroup& group, VAddr cpu_address) + : info{group, cpu_address}, type{BindingType::VideoOut} {} + }; + +public: + TextureCache(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler, + Vulkan::Runtime& runtime, AmdGpu::Liverpool* liverpool, BufferCache& buffer_cache, + PageManager& tracker); + ~TextureCache(); + + TileManager& GetTileManager() noexcept { + return tile_manager; + } + + /// Invalidates any image in the logical page range. + void InvalidateMemory(VAddr addr, size_t size); + + /// Marks an image as dirty if it exists at the provided address. + void InvalidateMemoryFromGPU(VAddr address, size_t max_size); + + /// Evicts any images that overlap the unmapped range. + void UnmapMemory(VAddr cpu_addr, size_t size); + + /// Schedules a copy of pending images for download back to CPU memory. + void ProcessDownloadImages(); + + /// Retrieves the image handle of the image with the provided attributes. + [[nodiscard]] ImageId FindImage(ImageDesc& desc, bool exact_fmt = false); + + /// Retrieves image whose address matches provided + [[nodiscard]] ImageId FindImageFromRange(VAddr address, size_t size, bool ensure_valid = true); + + /// Retrieves an image view with the properties of the specified image id. + [[nodiscard]] ImageView& FindTexture(ImageId image_id, const ImageDesc& desc); + + /// Retrieves the render target with specified properties + [[nodiscard]] ImageView& FindRenderTarget(ImageId image_id, const ImageDesc& desc); + + /// Retrieves the depth target with specified properties + [[nodiscard]] ImageView& FindDepthTarget(ImageId image_id, const ImageDesc& desc); + + /// Updates image contents if it was modified by CPU. + void UpdateImage(ImageId image_id) { + std::scoped_lock lock{mutex}; + Image& image = slot_images[image_id]; + TrackImage(image_id); + TouchImage(image); + RefreshImage(image); + } + + /// Resolves overlap between existing cache image and pending merged image + [[nodiscard]] std::tuple ResolveOverlap(const ImageInfo& info, + BindingType binding, + ImageId cache_img_id, + ImageId merged_image_id); + + /// Resolves depth overlap and either re-creates the image or returns existing one + [[nodiscard]] ImageId ResolveDepthOverlap(const ImageInfo& requested_info, BindingType binding, + ImageId cache_img_id); + + /// Creates a new image with provided image info and copies subresources from image_id + [[nodiscard]] ImageId ExpandImage(const ImageInfo& info, ImageId image_id); + + /// Reuploads image contents. + void RefreshImage(Image& image); + + /// Retrieves the sampler that matches the provided S# descriptor. + [[nodiscard]] vk::Sampler GetSampler(const AmdGpu::Sampler& sampler, + AmdGpu::BorderColorBuffer border_color_base, + bool is_depth); + + /// Retrieves the image with the specified id. + [[nodiscard]] Image& GetImage(ImageId id) { + auto& image = slot_images[id]; + TouchImage(image); + return image; + } + + /// Retrieves the image view with the specified id. + [[nodiscard]] ImageView& GetImageView(ImageId id) { + return slot_image_views[id]; + } + + /// Get the associated depth stencil image if it is still valid. + ImageId GetAssociatedDepth(Image& image) { + if (!image.depth_id) { + return {}; + } + if (slot_images.is_allocated(image.depth_id)) { + auto& depth_image = slot_images[image.depth_id]; + if (depth_image.image_uid == image.depth_uid && + depth_image.flags & ImageFlagBits::Registered) { + return image.depth_id; + } + } + // The linked depth image is no longer valid, disassociate it. + image.DisassociateDepth(); + return {}; + } + + enum class MetaType { + CMask, + FMask, + HTile, + }; + + /// Returns meta type if the specified address is a metadata surface. + std::optional IsMeta(VAddr address) const { + auto it = surface_metas.find(address); + if (it != surface_metas.end()) { + return it->second.type; + } + return std::nullopt; + } + + /// Returns true if a slice of the specified metadata surface has been cleared. + bool IsMetaCleared(VAddr address, u32 slice) const { + const auto& it = surface_metas.find(address); + if (it != surface_metas.end()) { + return it.value().clear_mask & (1u << slice); + } + return false; + } + + /// Clears all slices of the specified metadata surface. + bool ClearMeta(VAddr address) { + auto it = surface_metas.find(address); + if (it != surface_metas.end()) { + it.value().clear_mask = u32(-1); + return true; + } + return false; + } + + /// Updates the state of a slice of the specified metadata surface. + bool TouchMeta(VAddr address, u32 slice, bool is_clear) { + auto it = surface_metas.find(address); + if (it != surface_metas.end()) { + if (is_clear) { + it.value().clear_mask |= 1u << slice; + } else { + it.value().clear_mask &= ~(1u << slice); + } + return true; + } + return false; + } + + /// Runs the garbage collector. + void RunGarbageCollector(); + + template + void ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& func) { + using FuncReturn = typename std::invoke_result::type; + static constexpr bool BOOL_BREAK = std::is_same_v; + ImageIds images; + ForEachPage(cpu_addr, size, [this, &images, cpu_addr, size, func](u64 page) { + const auto it = page_table.find(page); + if (it == nullptr) { + if constexpr (BOOL_BREAK) { + return false; + } else { + return; + } + } + for (const ImageId image_id : *it) { + Image& image = slot_images[image_id]; + if (image.flags & ImageFlagBits::Picked) { + continue; + } + if (!image.Overlaps(cpu_addr, size)) { + continue; + } + image.flags |= ImageFlagBits::Picked; + images.push_back(image_id); + if constexpr (BOOL_BREAK) { + if (func(image_id, image)) { + return true; + } + } else { + func(image_id, image); + } + } + if constexpr (BOOL_BREAK) { + return false; + } + }); + for (const ImageId image_id : images) { + slot_images[image_id].flags &= ~ImageFlagBits::Picked; + } + } + +private: + /// Iterate over all page indices in a range + template + static void ForEachPage(PAddr addr, size_t size, Func&& func) { + static constexpr bool RETURNS_BOOL = std::is_same_v, bool>; + const u64 page_end = (addr + size - 1) >> Traits::PageBits; + for (u64 page = addr >> Traits::PageBits; page <= page_end; ++page) { + if constexpr (RETURNS_BOOL) { + if (func(page)) { + break; + } + } else { + func(page); + } + } + } + + /// Copies image memory back to CPU. + void DownloadImageMemory(ImageId image_id, bool sync = false); + + /// Thread function for copying downloaded images out to CPU memory. + void DownloadedImagesThread(const std::stop_token& token); + + /// Create an image from the given parameters + [[nodiscard]] ImageId InsertImage(const ImageInfo& info, VAddr cpu_addr); + + /// Register image in the page table + void RegisterImage(ImageId image); + + /// Unregister image from the page table + void UnregisterImage(ImageId image); + + /// Track CPU reads and writes for image + void TrackImage(ImageId image_id); + void TrackImageHead(ImageId image_id); + void TrackImageTail(ImageId image_id); + + /// Stop tracking CPU reads and writes for image + void UntrackImage(ImageId image_id); + void UntrackImageHead(ImageId image_id); + void UntrackImageTail(ImageId image_id); + + void MarkAsMaybeDirty(ImageId image_id, Image& image); + + /// Removes the image and any views/surface metas that reference it. + void DeleteImage(ImageId image_id); + + /// Touch the image in the LRU cache. + void TouchImage(const Image& image); + + void FreeImage(ImageId image_id) { + UntrackImage(image_id); + UnregisterImage(image_id); + DeleteImage(image_id); + } + + void GarbageCollectImages(); + void GarbageCollectSamplers(); + +private: + const Vulkan::Instance& instance; + Vulkan::Scheduler& scheduler; + Vulkan::Runtime& runtime; + AmdGpu::Liverpool* liverpool; + BufferCache& buffer_cache; + PageManager& tracker; + BlitHelper blit_helper; + TileManager tile_manager; + Common::SlotVector slot_images; + Common::SlotVector slot_image_views; + tsl::robin_map samplers; + std::unordered_set download_images; + u64 total_used_memory = 0; + u64 trigger_gc_memory = 0; + u64 pressure_gc_memory = 0; + u64 critical_gc_memory = 0; + u64 total_used_samplers = 0; + u64 trigger_gc_samplers = 0; + u64 pressure_gc_samplers = 0; + u64 critical_gc_samplers = 0; + u64 gc_tick = 0; + Common::LeastRecentlyUsedCache lru_cache; + Common::LeastRecentlyUsedCache sampler_lru_cache; + const bool readback_linear_images; + PageTable page_table; + std::mutex mutex; + std::mutex samplers_mutex; + std::mutex download_images_mutex; + struct MetaDataInfo { + MetaType type; + s32 clear_mask = -1; + }; + tsl::robin_map surface_metas; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/tile.h b/gpu/shadps4/video_core/texture_cache/tile.h new file mode 100644 index 0000000..68c9428 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/tile.h @@ -0,0 +1,351 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/assert.h" +#include "common/types.h" + +namespace AmdGpu { +enum class TileMode : u32; +} + +namespace VideoCore { + +// clang-format off +// The table of macro tiles parameters for given tiling index (row) and bpp (column) +/* Calculation: + * - Inputs: + * TileMode, BytesPerPixel, NumFragments + * - Constants: + * MicroTileWidth = 8, MicroTileHeight = 8, + * Tile Mode LUTs: IsDepth(), IsPrt(), TileThickness(), TileSplit(), SampleSplit(), NumPipes() + * Macro Tile Mode LUTs: BankWidth(), BankHeight(), NumBanks(), MacroTileAspect() + * - Determine the macro tile mode: + * TileBytes = MicroTileWidth * MicroTileHeight * TileThickness(TileMode) * BytesPerPixel + * TileSplit = min(IsDepth(TileMode) ? TileSplit(TileMode) : max(TileBytes * SampleSplit(TileMode), 256), NumFragments * TileBytes, 1024) + * MacroTileModeIndex = log2(TileSplit / 64) + * MacroTileMode = IsPrt(TileMode) ? MacroTileModeIndex + 8 : MacroTileModeIndex + * - Calculate macro tile width and height: + * Width = NumPipes(TileMode) * BankWidth(MacroTileMode) * MicroTileWidth * MacroTileAspect(MacroTileMode, AltTileMode) + * Height = NumBanks(MacroTileMode, AltTileMode) * BankHeight(MacroTileMode, AltTileMode) * MicroTileHeight / MacroTileAspect(MacroTileMode, AltTileMode) + */ + +constexpr std::array macro_tile_extents_x1{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 01 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 02 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 03 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 0A + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 0B + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 0E + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 0F + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 10 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 11 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 14 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 18 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 19 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents_x2{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 01 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 02 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 03 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0A + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0B + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0E + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0F + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 10 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 11 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 14 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 18 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 19 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents_x4{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 01 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 02 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 03 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0A + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0B + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0E + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0F + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 10 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 11 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 14 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 18 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 19 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents_x8{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 01 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 02 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 03 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0A + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0B + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0E + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 0F + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 10 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 11 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 14 + std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 18 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 19 + std::pair{128u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, std::pair{64u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents_alt_x1{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 01 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 02 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 03 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, // 0A + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, // 0B + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, // 0E + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, // 0F + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, // 10 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, // 11 + std::pair{256u, 256u}, std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 14 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 18 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 19 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents_alt_x2{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 01 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 02 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 03 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0A + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 0B + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0E + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0F + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 10 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 11 + std::pair{256u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 14 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 18 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 19 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents_alt_x4{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 01 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 02 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 03 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0A + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 0B + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0E + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0F + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 10 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 11 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 14 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 18 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 19 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents_alt_x8{ + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 00 + std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, std::pair{256u, 128u}, // 01 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 02 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 03 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 04 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 05 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, // 06 + std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 07 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 08 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 09 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0A + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 0B + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 0C + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 0D + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0E + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 0F + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 10 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 11 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 12 + std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, std::pair{0u, 0u}, // 13 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 14 + std::pair{128u, 128u}, std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 15 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 16 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 17 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 32u}, std::pair{128u, 32u}, std::pair{128u, 32u}, // 18 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 19 + std::pair{128u, 128u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, std::pair{128u, 64u}, // 1A +}; + +constexpr std::array macro_tile_extents{ + macro_tile_extents_x1, + macro_tile_extents_x2, + macro_tile_extents_x4, + macro_tile_extents_x8, +}; + +constexpr std::array macro_tile_extents_alt{ + macro_tile_extents_alt_x1, + macro_tile_extents_alt_x2, + macro_tile_extents_alt_x4, + macro_tile_extents_alt_x8, +}; +// clang-format on + +constexpr std::pair micro_tile_extent{8u, 8u}; +constexpr auto hw_pipe_interleave = 256u; + +constexpr std::pair GetMacroTileExtents(AmdGpu::TileMode tile_mode, u32 bpp, + u32 num_samples, bool alt) { + ASSERT(num_samples <= 8); + const auto samples_log = static_cast(std::log2(num_samples)); + const auto row = u32(tile_mode) * 5; + const auto column = std::bit_width(bpp) - 4; // bpps are 8, 16, 32, 64, 128 + return (alt ? macro_tile_extents_alt : macro_tile_extents)[samples_log][row + column]; +} + +constexpr std::tuple ImageSizeLinearAligned(u32 pitch, u32 height, u32 bpp, + u32 num_samples) { + const auto pitch_align = std::max(8u, 64u / ((bpp + 7) / 8)); + auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1); + const auto height_aligned = height; + size_t log_sz = pitch_aligned * height_aligned * num_samples; + const auto slice_align = std::max(64u, 256u / ((bpp + 7) / 8)); + while (log_sz % slice_align) { + pitch_aligned += pitch_align; + log_sz = pitch_aligned * height_aligned * num_samples; + } + return {pitch_aligned, height_aligned, (log_sz * bpp + 7) / 8}; +} + +constexpr std::tuple ImageSizeMicroTiled(u32 pitch, u32 height, u32 thickness, + u32 bpp, u32 num_samples) { + const auto& [pitch_align, height_align] = micro_tile_extent; + auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1); + const auto height_aligned = (height + height_align - 1) & ~(height_align - 1); + size_t log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8; + while ((log_sz * thickness) % 256) { + pitch_aligned += pitch_align; + log_sz = (pitch_aligned * height_aligned * bpp * num_samples + 7) / 8; + } + return {pitch_aligned, height_aligned, log_sz}; +} + +constexpr std::tuple ImageSizeMacroTiled(u32 pitch, u32 height, u32 thickness, + u32 bpp, u32 num_samples, + AmdGpu::TileMode tile_mode, u32 mip_n, + bool alt) { + const auto [pitch_align, height_align] = GetMacroTileExtents(tile_mode, bpp, num_samples, alt); + ASSERT(pitch_align != 0 && height_align != 0); + bool downgrade_to_micro = false; + if (mip_n > 0) { + const bool is_less_than_tile = pitch < pitch_align || height < height_align; + // TODO: threshold check + downgrade_to_micro = is_less_than_tile; + } + + if (downgrade_to_micro) { + return ImageSizeMicroTiled(pitch, height, thickness, bpp, num_samples); + } + + const auto pitch_aligned = (pitch + pitch_align - 1) & ~(pitch_align - 1); + const auto height_aligned = (height + height_align - 1) & ~(height_align - 1); + const auto log_sz = pitch_aligned * height_aligned * num_samples; + return {pitch_aligned, height_aligned, (log_sz * bpp + 7) / 8}; +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/tile_manager.cpp b/gpu/shadps4/video_core/texture_cache/tile_manager.cpp new file mode 100644 index 0000000..47ee198 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/tile_manager.cpp @@ -0,0 +1,337 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_runtime.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_shader_util.h" +#include "video_core/texture_cache/image.h" +#include "video_core/texture_cache/image_info.h" +#include "video_core/texture_cache/image_view.h" +#include "video_core/texture_cache/tile_manager.h" + +#include "video_core/host_shaders/tiling_macro_128_comp.h" +#include "video_core/host_shaders/tiling_macro_16_comp.h" +#include "video_core/host_shaders/tiling_macro_32_comp.h" +#include "video_core/host_shaders/tiling_macro_64_comp.h" +#include "video_core/host_shaders/tiling_macro_8_comp.h" +#include "video_core/host_shaders/tiling_macro_96_comp.h" +#include "video_core/host_shaders/tiling_micro_128_comp.h" +#include "video_core/host_shaders/tiling_micro_16_comp.h" +#include "video_core/host_shaders/tiling_micro_32_comp.h" +#include "video_core/host_shaders/tiling_micro_64_comp.h" +#include "video_core/host_shaders/tiling_micro_8_comp.h" +#include "video_core/host_shaders/tiling_micro_96_comp.h" + +#include +#include + +namespace VideoCore { + +struct TilingInfo { + u32 bank_swizzle; + u32 num_slices; + u32 num_mips; + std::array mips; +}; + +TileManager::TileManager(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, + Vulkan::Runtime& runtime_, StreamBuffer& stream_buffer_) + : instance{instance_}, scheduler{scheduler_}, runtime{runtime_}, stream_buffer{stream_buffer_} { + const auto device = instance.GetDevice(); + const std::array bindings = {{ + { + .binding = 0, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }, + { + .binding = 1, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }, + { + .binding = 2, + .descriptorType = vk::DescriptorType::eUniformBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute, + }, + }}; + + const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = { + .flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR, + .bindingCount = static_cast(bindings.size()), + .pBindings = bindings.data(), + }; + auto desc_layout_result = device.createDescriptorSetLayoutUnique(desc_layout_ci); + ASSERT_MSG(desc_layout_result.result == vk::Result::eSuccess, + "Failed to create descriptor set layout: {}", + vk::to_string(desc_layout_result.result)); + desc_layout = std::move(desc_layout_result.value); + + const vk::DescriptorSetLayout set_layout = *desc_layout; + const vk::PipelineLayoutCreateInfo layout_info = { + .setLayoutCount = 1U, + .pSetLayouts = &set_layout, + .pushConstantRangeCount = 0U, + .pPushConstantRanges = nullptr, + }; + auto [layout_result, layout] = device.createPipelineLayoutUnique(layout_info); + ASSERT_MSG(layout_result == vk::Result::eSuccess, "Failed to create pipeline layout: {}", + vk::to_string(layout_result)); + pl_layout = std::move(layout); +} + +TileManager::~TileManager() = default; + +vk::Pipeline TileManager::GetTilingPipeline(const ImageInfo& info, bool is_tiler) { + const TilingKey key{ + .tile_mode = info.tile_mode, + .num_bits = info.num_bits, + .num_samples = info.num_samples, + .is_tiler = is_tiler, + }; + if (const auto it = tiling_pipelines.find(key); it != tiling_pipelines.end()) { + return *it->second; + } + + const auto device = instance.GetDevice(); + const auto micro_tile_mode = AmdGpu::GetMicroTileMode(info.tile_mode); + const bool is_macro = AmdGpu::IsMacroTiled(info.array_mode); + std::array spec_data{ + info.num_samples, + u32(micro_tile_mode), + AmdGpu::GetMicroTileThickness(info.array_mode), + u32(is_tiler), + }; + if (is_macro) { + const auto macro_tile_mode = + AmdGpu::CalculateMacrotileMode(info.tile_mode, info.num_bits, info.num_samples); + spec_data[4] = u32(info.array_mode); + spec_data[5] = u32(AmdGpu::GetPipeConfig(info.tile_mode)); + spec_data[6] = AmdGpu::GetBankWidth(macro_tile_mode); + spec_data[7] = AmdGpu::GetBankHeight(macro_tile_mode); + spec_data[8] = AmdGpu::GetNumBanks(macro_tile_mode); + spec_data[9] = std::bit_width(spec_data[8]) - 1; + spec_data[10] = AmdGpu::CalculateTileSplit(info.tile_mode, info.array_mode, micro_tile_mode, + info.num_bits); + spec_data[11] = AmdGpu::GetMacrotileAspect(macro_tile_mode); + } + + std::span code; + switch (info.num_bits) { + case 8: + code = is_macro ? std::span{TILING_MACRO_8_COMP} + : std::span{TILING_MICRO_8_COMP}; + break; + case 16: + code = is_macro ? std::span{TILING_MACRO_16_COMP} + : std::span{TILING_MICRO_16_COMP}; + break; + case 32: + code = is_macro ? std::span{TILING_MACRO_32_COMP} + : std::span{TILING_MICRO_32_COMP}; + break; + case 64: + code = is_macro ? std::span{TILING_MACRO_64_COMP} + : std::span{TILING_MICRO_64_COMP}; + break; + case 96: + code = is_macro ? std::span{TILING_MACRO_96_COMP} + : std::span{TILING_MICRO_96_COMP}; + break; + case 128: + code = is_macro ? std::span{TILING_MACRO_128_COMP} + : std::span{TILING_MICRO_128_COMP}; + break; + default: + UNREACHABLE_MSG("Unsupported tiling pixel width {}", info.num_bits); + } + + const auto module = Vulkan::CompileSPV(code, device); + static constexpr auto spec_entries = [] { + std::array entries{}; + for (u32 i = 0; i < entries.size(); ++i) { + entries[i] = vk::SpecializationMapEntry{i, i * u32(sizeof(u32)), sizeof(u32)}; + } + return entries; + }(); + + const u32 spec_count = is_macro ? 12 : 4; + const vk::SpecializationInfo specialization{ + .mapEntryCount = spec_count, + .pMapEntries = spec_entries.data(), + .dataSize = spec_count * sizeof(u32), + .pData = spec_data.data(), + }; + + const auto module_name = fmt::format("{}_{} {}", magic_enum::enum_name(info.tile_mode), + info.num_bits, is_tiler ? "tiler" : "detiler"); + LOG_INFO(Render_Vulkan, "Creating tiling pipeline {}", module_name); + Vulkan::SetObjectName(device, module, module_name); + + const vk::PipelineShaderStageCreateInfo shader_ci = { + .stage = vk::ShaderStageFlagBits::eCompute, + .module = module, + .pName = "main", + .pSpecializationInfo = &specialization, + }; + const vk::ComputePipelineCreateInfo compute_pipeline_ci = { + .stage = shader_ci, + .layout = *pl_layout, + }; + + auto [result, pipeline] = + device.createComputePipelineUnique(VK_NULL_HANDLE, compute_pipeline_ci); + ASSERT_MSG(result == vk::Result::eSuccess, "Detiler pipeline creation failed {}", + vk::to_string(result)); + const auto handle = *pipeline; + tiling_pipelines.emplace(key, std::move(pipeline)); + device.destroyShaderModule(module); + return handle; +} + +void TileManager::RecordTilingDispatch(vk::Pipeline pipeline, const vk::DescriptorBufferInfo& tiled, + const vk::DescriptorBufferInfo& linear, + const vk::DescriptorBufferInfo& params, u32 dim_x) { + scheduler.Record([pipeline, layout = *pl_layout, tiled, linear, params, + dim_x](vk::CommandBuffer cmdbuf) { + cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, pipeline); + const std::array set_writes = {{ + { + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .pBufferInfo = &tiled, + }, + { + .dstBinding = 1, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageBuffer, + .pBufferInfo = &linear, + }, + { + .dstBinding = 2, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eUniformBuffer, + .pBufferInfo = ¶ms, + }, + }}; + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, layout, 0, set_writes); + cmdbuf.dispatch(dim_x, 1, 1); + }); +} + +std::pair TileManager::DetileImage(const VideoCore::Buffer* in_buffer, + u64 in_offset, const ImageInfo& info) { + if (!info.props.is_tiled) { + return {in_buffer, in_offset}; + } + + TilingInfo params{}; + params.bank_swizzle = info.bank_swizzle; + params.num_slices = info.props.is_volume ? info.size.depth : info.resources.layers; + params.num_mips = info.resources.levels; + for (u32 mip = 0; mip < params.num_mips; ++mip) { + auto& mip_info = params.mips[mip]; + mip_info = info.mips_layout[mip]; + if (info.props.is_block) { + mip_info.pitch = std::max((mip_info.pitch + 3) / 4, 1U); + mip_info.height = std::max((mip_info.height + 3) / 4, 1U); + } + } + + const vk::DescriptorBufferInfo params_buffer_info{ + .buffer = stream_buffer.Handle(), + .offset = stream_buffer.Copy(¶ms, sizeof(params), instance.UniformMinAlignment()), + .range = sizeof(params), + }; + + const auto staging = runtime.GetStagingPool().Request(info.guest_size, MemoryType::DeviceLocal); + + scheduler.EndRendering(); + runtime.FlushBarriers(); + + const vk::DescriptorBufferInfo tiled_buffer_info{ + .buffer = in_buffer->Handle(), + .offset = in_offset, + .range = info.guest_size, + }; + const vk::DescriptorBufferInfo linear_buffer_info{ + .buffer = staging.buffer->Handle(), + .offset = staging.offset, + .range = info.guest_size, + }; + const auto dim_x = static_cast((info.guest_size / (info.num_bits / 8)) / 64); + // bbport: recorded with copies of the descriptor infos (threaded recording). + RecordTilingDispatch(GetTilingPipeline(info, false), tiled_buffer_info, linear_buffer_info, + params_buffer_info, dim_x); + + runtime.AccessBuffer(staging.buffer, staging.offset, info.guest_size, + vk::PipelineStageFlagBits2::eComputeShader, + vk::AccessFlagBits2::eShaderWrite); + + return {staging.buffer, staging.offset}; +} + +void TileManager::TileImage(Image& in_image, std::span buffer_copies, + const VideoCore::Buffer* out_buffer, u64 out_offset) { + const auto& info = in_image.info; + if (!info.props.is_tiled) { + for (auto& copy : buffer_copies) { + copy.bufferOffset += out_offset; + } + runtime.DownloadImage(&in_image, out_buffer, buffer_copies); + return; + } + + TilingInfo params{}; + params.bank_swizzle = info.bank_swizzle; + params.num_slices = info.props.is_volume ? info.size.depth : info.resources.layers; + params.num_mips = static_cast(buffer_copies.size()); + for (u32 mip = 0; mip < params.num_mips; ++mip) { + auto& mip_info = params.mips[mip]; + mip_info = info.mips_layout[mip]; + if (info.props.is_block) { + mip_info.pitch = std::max((mip_info.pitch + 3) / 4, 1U); + mip_info.height = std::max((mip_info.height + 3) / 4, 1U); + } + } + + const vk::DescriptorBufferInfo params_buffer_info{ + .buffer = stream_buffer.Handle(), + .offset = stream_buffer.Copy(¶ms, sizeof(params), instance.UniformMinAlignment()), + .range = sizeof(params), + }; + + const auto staging = runtime.GetStagingPool().Request(info.guest_size, MemoryType::DeviceLocal); + for (auto& copy : buffer_copies) { + copy.bufferOffset += staging.offset; + } + + runtime.DownloadImage(&in_image, staging.buffer, buffer_copies); + runtime.FlushBarriers(); + + const vk::DescriptorBufferInfo tiled_buffer_info{ + .buffer = out_buffer->Handle(), + .offset = out_offset, + .range = info.guest_size, + }; + const vk::DescriptorBufferInfo linear_buffer_info{ + .buffer = staging.buffer->Handle(), + .offset = staging.offset, + .range = info.guest_size, + }; + const auto dim_x = static_cast((info.guest_size / (info.num_bits / 8)) / 64); + // bbport: recorded with copies of the descriptor infos (threaded recording). + RecordTilingDispatch(GetTilingPipeline(info, true), tiled_buffer_info, linear_buffer_info, + params_buffer_info, dim_x); + + runtime.AccessBuffer(out_buffer, out_offset, info.guest_size, + vk::PipelineStageFlagBits2::eComputeShader, + vk::AccessFlagBits2::eShaderWrite); +} + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/tile_manager.h b/gpu/shadps4/video_core/texture_cache/tile_manager.h new file mode 100644 index 0000000..36d0505 --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/tile_manager.h @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "common/types.h" +#include "video_core/amdgpu/tiling.h" +#include "video_core/buffer_cache/buffer.h" + +namespace Vulkan { +struct Runtime; +} + +namespace VideoCore { + +struct ImageInfo; +struct Image; + +class TileManager { + struct TilingKey { + AmdGpu::TileMode tile_mode; + u32 num_bits; + u32 num_samples; + bool is_tiler; + + bool operator==(const TilingKey&) const = default; + + struct Hash { + size_t operator()(const TilingKey& key) const { + size_t hash = 0; + boost::hash_combine(hash, key.tile_mode); + boost::hash_combine(hash, key.num_bits); + boost::hash_combine(hash, key.num_samples); + boost::hash_combine(hash, key.is_tiler); + return hash; + } + }; + }; + +public: + explicit TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler, + Vulkan::Runtime& runtime, StreamBuffer& stream_buffer); + ~TileManager(); + + void TileImage(Image& in_image, std::span buffer_copies, + const VideoCore::Buffer* out_buffer, u64 out_offset); + + std::pair DetileImage(const VideoCore::Buffer* in_buffer, u64 in_offset, + const ImageInfo& info); + +private: + void RecordTilingDispatch(vk::Pipeline pipeline, const vk::DescriptorBufferInfo& tiled, + const vk::DescriptorBufferInfo& linear, + const vk::DescriptorBufferInfo& params, u32 dim_x); + + vk::Pipeline GetTilingPipeline(const ImageInfo& info, bool is_tiler); + +private: + const Vulkan::Instance& instance; + Vulkan::Scheduler& scheduler; + Vulkan::Runtime& runtime; + StreamBuffer& stream_buffer; + vk::UniqueDescriptorSetLayout desc_layout; + vk::UniquePipelineLayout pl_layout; + std::unordered_map tiling_pipelines; +}; + +} // namespace VideoCore diff --git a/gpu/shadps4/video_core/texture_cache/types.h b/gpu/shadps4/video_core/texture_cache/types.h new file mode 100644 index 0000000..097fdcb --- /dev/null +++ b/gpu/shadps4/video_core/texture_cache/types.h @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/slot_vector.h" +#include "common/types.h" + +namespace VideoCore { + +using ImageId = Common::SlotId; +using ImageViewId = Common::SlotId; + +struct Offset2D { + s32 x; + s32 y; +}; + +struct Offset3D { + s32 x; + s32 y; + s32 z; +}; + +struct Region2D { + Offset2D start; + Offset2D end; +}; + +struct Extent2D { + u32 width; + u32 height; + + bool operator==(const Extent2D& other) const { + return width == other.width && height == other.height; + } +}; + +struct Extent3D { + u32 width; + u32 height; + u32 depth; + + bool operator==(const Extent3D& other) const { + return width == other.width && height == other.height && depth == other.depth; + } +}; + +struct SubresourceLayers { + s32 base_level = 0; + s32 base_layer = 0; + s32 num_layers = 1; +}; + +struct SubresourceBase { + u32 level = 0; + u32 layer = 0; + + auto operator<=>(const SubresourceBase&) const = default; +}; + +struct SubresourceExtent { + u32 levels = 1; + u32 layers = 1; + + auto operator<=>(const SubresourceExtent&) const = default; +}; + +struct SubresourceRange { + SubresourceBase base; + SubresourceExtent extent; + + auto operator<=>(const SubresourceRange&) const = default; +}; + +struct ImageCopy { + SubresourceLayers src_subresource; + SubresourceLayers dst_subresource; + Offset3D src_offset; + Offset3D dst_offset; + Extent3D extent; +}; + +struct BufferImageCopy { + std::size_t buffer_offset; + std::size_t buffer_size; + u32 buffer_row_length; + u32 buffer_image_height; + SubresourceLayers image_subresource; + Offset3D image_offset; + Extent3D image_extent; +}; + +struct BufferCopy { + u64 src_offset; + u64 dst_offset; + std::size_t size; +}; + +} // namespace VideoCore diff --git a/gpu/shim/bbgpu.cpp b/gpu/shim/bbgpu.cpp new file mode 100644 index 0000000..e27040e --- /dev/null +++ b/gpu/shim/bbgpu.cpp @@ -0,0 +1,290 @@ +// bbport: glue between the C loader and the vendored shadPS4 video core. +#include +#include +#include +#include +#include "common/polyfill_thread.h" +#include "video_core/renderdoc.h" +#include +#include +#include +#include +#include +#include +#include "../bbgpu.h" +#include "common/elf_info.h" +#include "common/logging/log.h" +#include "common/rdtsc.h" +#include "core/libraries/kernel/orbis_error.h" +#include "core/libraries/libs.h" +#include "core/memory.h" +#include "core/signals.h" +#include "sdl_window.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" + +extern "C" { +// runtime_memory.c +int runtime_memory_is_mapped(uintptr_t address, uint64_t size); +int runtime_memory_write_backing(uintptr_t address, const void* data, uint64_t size); +uint64_t runtime_memory_clamp(uintptr_t address, uint64_t size); +int runtime_memory_region(uintptr_t address, uintptr_t* start, uintptr_t* end, int* mapped); +void runtime_memory_gpu_protect(uintptr_t address, uint64_t size, int read, int write); +typedef void (*RuntimeGpuRange)(uintptr_t address, uint64_t size); +// runtime_kernel.c: one clock for guest and GPU timestamps +uint64_t runtime_process_time_us(void); +uint64_t runtime_process_time_counter(void); +uint64_t runtime_tsc_frequency(void); +int32_t* runtime_errno(void); +void runtime_memory_set_gpu_hooks(RuntimeGpuRange map, RuntimeGpuRange unmap, RuntimeGpuRange invalidate); +} + +Frontend::WindowSDL* g_window = nullptr; + +namespace Libraries::GnmDriver { void RegisterLib(Core::Loader::SymbolsResolver* sym); } +namespace Libraries::AvPlayer { void RegisterLib(Core::Loader::SymbolsResolver* sym); } +namespace Libraries::VideoOut { void RegisterLib(Core::Loader::SymbolsResolver* sym); } +namespace Libraries::Kernel { void RegisterEventQueue(Core::Loader::SymbolsResolver* sym); } + +namespace { +struct Symbol { + std::string nid, library, module; + u64 address; +}; +std::vector g_symbols; +u32 g_sdk_version; +} // namespace + +namespace Core::Loader { +void SymbolsResolver::AddSymbol(const char* nid, const char* library, const char* module, SymbolType, + u64 address) { + g_symbols.push_back({nid, library, module, address}); +} +} // namespace Core::Loader + +// ElfInfo's fields are private to Core::Emulator; the port fills them here. +namespace Core { +class Emulator { +public: + static void FillElfInfo(const BbGpuConfig& config) { + auto& info = Common::ElfInfo::Instance(); + info.initialized = true; + info.game_serial = config.serial ? config.serial : "UNKNOWN"; + info.title = config.title ? config.title : ""; + info.sdk_ver = config.sdk_version; + info.psf_attributes.raw = config.psf_attributes; + } +}; + +void MemoryManager::SetRasterizer(Vulkan::Rasterizer* rasterizer_) { + rasterizer = rasterizer_; + // Existing guest mappings are replayed by the runtime when hooks are installed. + runtime_memory_set_gpu_hooks( + [](uintptr_t address, uint64_t size) { + auto* r = Memory::Instance()->GetRasterizer(); + r->RegisterMemory(address, size); + r->MapMemory(address, size); + }, + [](uintptr_t address, uint64_t size) { Memory::Instance()->GetRasterizer()->UnmapMemory(address, size); }, + [](uintptr_t address, uint64_t size) { + Memory::Instance()->GetRasterizer()->InvalidateMemory(address, size); + }); +} +void MemoryManager::InvalidateMemory(VAddr address, u64 size) { + if (rasterizer) rasterizer->InvalidateMemory(address, size); +} +u64 MemoryManager::ClampRangeSize(VAddr virtual_addr, u64 size) { + return runtime_memory_clamp(virtual_addr, size); +} +void MemoryManager::CopySparseMemory(VAddr source, u8* dest, u64 size) { + while (size) { + uintptr_t start = 0, end = 0; + int mapped = 0; + if (!runtime_memory_region(source, &start, &end, &mapped)) { + end = source + size; + } + const u64 n = std::min(size, end - source); + if (mapped) std::memcpy(dest, reinterpret_cast(source), n); + else std::memset(dest, 0, n); + source += n; dest += n; size -= n; + } +} +bool MemoryManager::TryWriteBacking(void* address, const void* data, u64 size) { + return runtime_memory_write_backing(reinterpret_cast(address), data, size) != 0; +} +void AddressSpace::Protect(VAddr virtual_addr, u64 size, MemoryPermission perms) { + runtime_memory_gpu_protect(virtual_addr, size, True(perms & MemoryPermission::Read), + True(perms & MemoryPermission::Write)); +} +boost::icl::interval_set AddressSpace::GetUsableRegions() { + boost::icl::interval_set set; + set += boost::icl::interval::right_open(0x10'0000'0000ULL, 0xfc'0000'0000ULL); + return set; +} +} // namespace Core + +// Kernel services the vendored libraries call directly. +namespace Libraries::Kernel { +u64 PS4_SYSV_ABI sceKernelGetTscFrequency() { return runtime_tsc_frequency(); } +u64 PS4_SYSV_ABI sceKernelReadTsc() { return Common::FencedRDTSC(); } +u64 PS4_SYSV_ABI sceKernelGetProcessTime() { return runtime_process_time_us(); } +u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter() { return runtime_process_time_counter(); } +u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency() { return 1'000'000'000; } +s32 PS4_SYSV_ABI sceKernelIsNeoMode() { return 0; } // base PS4 +s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver) { + if (!ver) return ORBIS_KERNEL_ERROR_EINVAL; + *ver = s32(g_sdk_version); + return ORBIS_OK; +} +s32 PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) { + std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); + return ORBIS_OK; +} +} // namespace Libraries::Kernel + +namespace { +// SDL video must be driven from one thread: the window lives on its own host thread. +std::thread g_window_thread; +std::mutex g_window_mutex; +std::condition_variable g_window_cv; +bool g_window_ready; +} // namespace + +u32 BbDisplayRefreshHz() { + static const u32 hz = [] { + const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); + const u32 rate = mode && mode->refresh_rate > 0 ? u32(mode->refresh_rate + 0.5f) : 60; + std::printf("GPU: vblank follows the display refresh rate, %u Hz\n", rate); + return std::max(rate, 60); + }(); + return hz; +} + +extern "C" int bbgpu_init(const BbGpuConfig* config) { + g_sdk_version = config->sdk_version; + if (config->user_dir) setenv("BB_GPU_USER_DIR", config->user_dir, 0); + Core::Emulator::FillElfInfo(*config); + const std::string title = config->title ? config->title : "Bloodborne"; + const s32 width = config->width, height = config->height; + g_window_thread = std::thread([title, width, height] { + Common::SetCurrentThreadName("bb:window"); + auto* window = new Frontend::WindowSDL(width, height, title.c_str()); + { + std::scoped_lock lock{g_window_mutex}; + g_window = window; + g_window_ready = true; + } + g_window_cv.notify_all(); + while (window->PollEvents()) { + SDL_Delay(2); + } + LOG_INFO(Frontend, "Window closed by user"); + std::fflush(stdout); + std::_Exit(0); + }); + g_window_thread.detach(); + { + std::unique_lock lock{g_window_mutex}; + g_window_cv.wait(lock, [] { return g_window_ready; }); + } + Core::Loader::SymbolsResolver resolver; + // GnmDriver creates the presenter that the VideoOut present thread uses. + Libraries::GnmDriver::RegisterLib(&resolver); + Libraries::VideoOut::RegisterLib(&resolver); + return 0; +} + +namespace Libraries::Kernel { void StartKernelService(); } +extern "C" void bbgpu_register_kernel(void) { + Libraries::Kernel::StartKernelService(); + Core::Loader::SymbolsResolver resolver; + Libraries::Kernel::RegisterEventQueue(&resolver); + Libraries::AvPlayer::RegisterLib(&resolver); +} + +extern "C" uintptr_t bbgpu_resolve(const char* scoped_nid) { + const char* hash = std::strchr(scoped_nid, '#'); + const size_t length = hash ? size_t(hash - scoped_nid) : std::strlen(scoped_nid); + for (const auto& symbol : g_symbols) { + if (symbol.nid.size() == length && !std::memcmp(symbol.nid.data(), scoped_nid, length)) { + return uintptr_t(symbol.address); + } + } + return 0; +} + +extern "C" int bbgpu_handle_fault(void* ucontext, void* address) { + return Core::Signals::Instance()->DispatchAccessViolation(ucontext, address) ? 1 : 0; +} + +extern "C" unsigned bbgpu_symbol_count(void) { + return unsigned(g_symbols.size()); +} + +// Kernel service thread: runs boost::asio timers for equeue timer events. +namespace Libraries::Kernel { +boost::asio::io_context io_context; +static std::mutex m_asio_req; +static std::condition_variable_any cv_asio_req; +static std::atomic asio_requests; +static std::jthread service_thread; + +void KernelSignalRequest() { + std::unique_lock lock{m_asio_req}; + ++asio_requests; + cv_asio_req.notify_one(); +} + +static void KernelServiceThread(std::stop_token stoken) { + Common::SetCurrentThreadName("bb:kernel_service"); + while (!stoken.stop_requested()) { + { + std::unique_lock lock{m_asio_req}; + cv_asio_req.wait(lock, stoken, [] { return asio_requests != 0; }); + } + if (stoken.stop_requested()) break; + io_context.run(); + io_context.restart(); + asio_requests = 0; + } +} + +void StartKernelService() { + service_thread = std::jthread{KernelServiceThread}; +} + +int* PS4_SYSV_ABI __Error() { + return runtime_errno(); +} +} // namespace Libraries::Kernel + +// RenderDoc capture hooks: not used by the port. +namespace VideoCore { +void LoadRenderDoc() {} +void StartCapture() {} +void EndCapture() {} +void TriggerCapture() {} +void SetOutputDir(const std::filesystem::path&, const std::string&) {} +bool IsRenderDocLoaded() { return false; } +void RequestScreenshot(ScreenshotRequest) {} +u32 ConsumeGameOnlyScreenshotRequests() { return 0; } +u32 ConsumeWithOverlaysScreenshotRequests() { return 0; } +ScreenshotRequests ConsumeScreenshotRequests() { return {}; } +} // namespace VideoCore + +extern "C" int bbgpu_text_input_begin(const char* initial, const char* prompt) { + if (!g_window) return 0; + g_window->BeginTextInput(initial ? initial : "", prompt ? prompt : "Text"); + return 1; +} + +extern "C" int bbgpu_text_input_poll(char* out, uint64_t size) { + if (!g_window) return 2; + std::string text; + const int state = g_window->PollTextInput(text); + if (size) { + const size_t n = std::min(text.size(), size - 1); + std::memcpy(out, text.data(), n); + out[n] = 0; + } + return state; +} diff --git a/gpu/shim/bbport_toggles.h b/gpu/shim/bbport_toggles.h new file mode 100644 index 0000000..c99e3a9 --- /dev/null +++ b/gpu/shim/bbport_toggles.h @@ -0,0 +1,20 @@ +// bbport: optimizations that can be switched off while the game runs (BB_TOGGLE_FILE, +// see runtime_memory.c), to find which one changes rendering without restarting. +#pragma once +#include + +extern "C" std::uint32_t runtime_disabled_optimizations; + +namespace BbToggle { +enum : std::uint32_t { + RegionCache = 1, + FetchShaderCache = 2, + PageTrackingEarlyExit = 4, + PendingPollLimit = 8, + ThreadedRecording = 16, + ImageDescCache = 32, +}; +inline bool Disabled(std::uint32_t bit) { + return (__atomic_load_n(&runtime_disabled_optimizations, __ATOMIC_RELAXED) & bit) != 0; +} +} // namespace BbToggle diff --git a/gpu/shim/common/assert.cpp b/gpu/shim/common/assert.cpp new file mode 100644 index 0000000..2a5a5ba --- /dev/null +++ b/gpu/shim/common/assert.cpp @@ -0,0 +1,22 @@ +// bbport: GPU-side assertion failures stop the port with exit code 23. +#include +#include +#include +#include "common/assert.h" +#include "common/logging/log.h" + +void assert_fail_impl() { + std::fflush(stdout); + std::fputs("STOP: GPU library assertion failed (see GPU log above)\n", stderr); + std::_Exit(23); +} + +[[noreturn]] void unreachable_impl() { + assert_fail_impl(); + throw std::runtime_error("Unreachable code"); +} + +void assert_fail_debug_msg(const char* msg) { + LOG_CRITICAL(Debug, "Assertion Failed!\n{}", msg); + assert_fail_impl(); +} diff --git a/gpu/shim/common/debug.h b/gpu/shim/common/debug.h new file mode 100644 index 0000000..a127ccf --- /dev/null +++ b/gpu/shim/common/debug.h @@ -0,0 +1,28 @@ +// bbport: shadPS4 debug/profiler helpers without Tracy. +#pragma once +#include +#define BREAKPOINT __builtin_trap +static inline bool IsProfilerConnected() { return false; } +#define TRACY_GPU_ENABLED 0 +#define CUSTOM_LOCK(type, varname) type varname +#define TRACK_ALLOC(ptr, size, pool) ((void)(ptr), (void)(size)) +#define TRACK_FREE(ptr, pool) ((void)(ptr)) +enum MarkersPalette : int { + EmulatorMarkerColor = 0x264653, + RendererMarkerColor = 0x2a9d8f, + HleMarkerColor = 0xe9c46a, + GpuMarkerColor = 0xf4a261, + Reserved1 = 0xe76f51, +}; +#define EMULATOR_TRACE +#define RENDERER_TRACE +#define HLE_TRACE +#define TRACE_HINT(str) ((void)(str)) +#define TRACE_WARN(msg) ((void)(msg)) +#define TRACE_ERROR(msg) ((void)(msg)) +#define TRACE_CRIT(msg) ((void)(msg)) +#define GPU_SCOPE_LOCATION(name, color) tracy::SourceLocationData{name, TracyFunction, TracyFile, (uint32_t)TracyLine, color}; +#define MUTEX_LOCATION(name) tracy::SourceLocationData{nullptr, name, TracyFile, (uint32_t)TracyLine, 0}; +#define FRAME_END +#define FIBER_ENTER(name) +#define FIBER_EXIT diff --git a/gpu/shim/common/logging/log.cpp b/gpu/shim/common/logging/log.cpp new file mode 100644 index 0000000..cf5fd1b --- /dev/null +++ b/gpu/shim/common/logging/log.cpp @@ -0,0 +1,30 @@ +// bbport: see log.h. +#include +#include +#include +#include +#include "common/logging/log.h" + +namespace Common::Log { +static Level threshold() { + static const Level level = [] { + const char* v = std::getenv("BB_GPU_LOG"); + if (!v) return Level::warn; + static const char* names[] = {"trace", "debug", "info", "warning", "error", "critical"}; + for (int i = 0; i < 6; ++i) + if (!std::strcmp(v, names[i])) return Level(i); + return Level::warn; + }(); + return level; +} +bool ShouldLog(Level level) { return level >= threshold(); } +void Write(std::string_view log_class, Level level, const char* file, int line, const char* function, + std::string&& message) { + static std::mutex mutex; + static const char* names[] = {"Trace", "Debug", "Info", "Warning", "Error", "Critical"}; + const char* base = std::strrchr(file, '/'); + std::scoped_lock lock{mutex}; + std::fprintf(stderr, "GPU [%.*s] <%s> %s:%d %s: %s\n", int(log_class.size()), log_class.data(), + names[int(level)], base ? base + 1 : file, line, function, message.c_str()); +} +} // namespace Common::Log diff --git a/gpu/shim/common/logging/log.h b/gpu/shim/common/logging/log.h new file mode 100644 index 0000000..0cd7c9e --- /dev/null +++ b/gpu/shim/common/logging/log.h @@ -0,0 +1,45 @@ +// bbport: replaces shadPS4's spdlog-based logger with a small fmt sink. +// Level from BB_GPU_LOG (trace|debug|info|warning|error; default warning). +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/logging/classes.h" +#include "common/path_util.h" +#include "common/thread.h" + +// Level type keeps shadPS4's spdlog spelling so vendored callers compile unchanged. +namespace spdlog { +enum class level : int { trace, debug, info, warn, err, critical, off }; +} +namespace Common::Log { +using Level = spdlog::level; +bool ShouldLog(Level level); +void Write(std::string_view log_class, Level level, const char* file, int line, const char* function, + std::string&& message); +inline void Flush() {} +} // namespace Common::Log + +#define LOG_GENERIC(log_class, log_level, fmt_str, ...) \ + do { \ + if (Common::Log::ShouldLog(log_level)) { \ + Common::Log::Write(log_class, log_level, __FILE__, __LINE__, __func__, \ + fmt::format(fmt_str __VA_OPT__(, ) __VA_ARGS__)); \ + } \ + } while (false) +#define LOG_TRACE(log_class, ...) LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::trace, __VA_ARGS__) +#define LOG_DEBUG(log_class, ...) LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::debug, __VA_ARGS__) +#define LOG_INFO(log_class, ...) LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::info, __VA_ARGS__) +#define LOG_WARNING(log_class, ...) LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::warn, __VA_ARGS__) +#define LOG_ERROR(log_class, ...) LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::err, __VA_ARGS__) +#define LOG_CRITICAL(log_class, ...) LOG_GENERIC(Common::Log::Class::log_class, spdlog::level::critical, __VA_ARGS__) diff --git a/gpu/shim/core/address_space.h b/gpu/shim/core/address_space.h new file mode 100644 index 0000000..0574d4a --- /dev/null +++ b/gpu/shim/core/address_space.h @@ -0,0 +1,26 @@ +// bbport: address-space operations the video core needs, backed by the C +// runtime's VMA table (runtime_memory.c). +#pragma once +#include +#include "common/enum.h" +#include "common/types.h" + +namespace Core { +enum class MemoryPermission : u32 { + None = 0, + Read = 1 << 0, + Write = 1 << 1, + ReadWrite = Read | Write, + Execute = 1 << 2, + ReadWriteExecute = Read | Write | Execute, +}; +DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission) + +class AddressSpace { +public: + void Protect(VAddr virtual_addr, u64 size, MemoryPermission perms); + boost::icl::interval_set GetUsableRegions(); + VAddr SystemReservedVirtualBase() const { return 0x7'0000'0000ULL; } + u64 SystemReservedVirtualSize() const { return 0x1'0000'0000ULL; } +}; +} // namespace Core diff --git a/gpu/shim/core/debug_state.h b/gpu/shim/core/debug_state.h new file mode 100644 index 0000000..8ab414f --- /dev/null +++ b/gpu/shim/core/debug_state.h @@ -0,0 +1,43 @@ +// bbport: shadPS4's frame/register dump tooling is not part of this port. +#pragma once +#include +#include +#include "common/types.h" +#include "shader_recompiler/runtime_info.h" +#include "video_core/amdgpu/regs.h" +#include "video_core/renderer_vulkan/vk_common.h" + +namespace DebugStateType { +enum class QueueType { dcb = 0, ccb = 1, acb = 2 }; +struct QueueDump { + QueueType type; + u32 submit_num; + u32 num2; + std::vector data; + uintptr_t base_addr; +}; +class DebugStateImpl { +public: + using CsState = AmdGpu::ComputeProgram; + bool is_using_fsr{}; + void IncFlipFrameNum() {} + void IncDrawCall() noexcept {} + void IncDispatch() noexcept {} + void IncGnmFrameNum() {} + u32 GetFrameNum() const { return 0; } + bool DumpingCurrentFrame() const { return false; } + bool DumpingCurrentReg() { return false; } + bool ShouldPauseInSubmit() const { return false; } + void PushQueueDump(QueueDump) {} + void PushRegsDump(uintptr_t, uintptr_t, const AmdGpu::Regs&) {} + void PushRegsDumpCompute(uintptr_t, uintptr_t, const CsState&) {} + void CollectShader(const std::string&, Shader::SwStage, vk::ShaderModule, std::span, + std::span, std::span, bool) {} + void ShowDebugMessage(std::string) {} + bool IsGuestThreadsPaused() const { return false; } + void PauseGuestThreads() {} + void ResumeGuestThreads() {} +}; +} // namespace DebugStateType +inline DebugStateType::DebugStateImpl DebugStateInstance; +#define DebugState DebugStateInstance diff --git a/gpu/shim/core/devtools/widget/gpu_memory.h b/gpu/shim/core/devtools/widget/gpu_memory.h new file mode 100644 index 0000000..f98b5e6 --- /dev/null +++ b/gpu/shim/core/devtools/widget/gpu_memory.h @@ -0,0 +1,13 @@ +// bbport: devtools GPU memory viewer is not part of the port. +#pragma once +#include +#include +#include "common/types.h" +namespace Core::Devtools::Widget { +struct GpuMemoryRow { std::string name; u64 bytes; }; +struct GpuMemoryGroup { std::string name; std::vector rows; }; +struct GpuMemoryViewer { + static bool IsEnabled() { return false; } + static void Publish(GpuMemoryGroup&&) {} +}; +} // namespace Core::Devtools::Widget diff --git a/gpu/shim/core/emulator_settings.h b/gpu/shim/core/emulator_settings.h new file mode 100644 index 0000000..7303fd8 --- /dev/null +++ b/gpu/shim/core/emulator_settings.h @@ -0,0 +1,59 @@ +// bbport: shadPS4 settings used by the video core, read once from BB_* environment +// variables (defaults match shadPS4 except the pipeline cache, which is on). +#pragma once +#include +#include +#include "common/types.h" + +u32 BbDisplayRefreshHz(); // bbgpu.cpp: primary display refresh rate, 60 when unknown + +enum GpuReadbacksMode : int { Disabled, Relaxed, Precise }; + +class EmulatorSettingsImpl { +public: + static EmulatorSettingsImpl* GetInstance() { static EmulatorSettingsImpl s; return &s; } + static bool Flag(const char* name, bool fallback) { + const char* v = std::getenv(name); + return v ? (v[0] == '1' || v[0] == 'y' || v[0] == 't') : fallback; + } + static long Number(const char* name, long fallback) { + const char* v = std::getenv(name); + return v ? std::strtol(v, nullptr, 10) : fallback; + } + s32 GetGpuId() { static const auto value = s32(Number("BB_GPU_ID", -1)); return value; } + u32 GetInternalScreenWidth() { static const auto value = u32(Number("BB_INTERNAL_WIDTH", 1920)); return value; } + u32 GetInternalScreenHeight() { static const auto value = u32(Number("BB_INTERNAL_HEIGHT", 1080)); return value; } + std::string GetPresentMode() { const char* v = std::getenv("BB_PRESENT_MODE"); return v ? v : "Mailbox"; } + int GetRcasAttenuation() { static const auto value = int(Number("BB_RCAS_ATTENUATION", 250)); return value; } + u32 GetReadbacksMode() { static const auto value = u32(Number("BB_READBACKS", GpuReadbacksMode::Disabled)); return value; } + // bbport: 0 follows the display refresh rate (uncapped frame rate presets). + u32 GetVblankFrequency() { + static const u32 value = [] { + const long hz = Number("BB_VBLANK_HZ", 60); + return hz > 0 ? u32(hz) : BbDisplayRefreshHz(); + }(); + return value; + } + bool IsCopyGpuBuffers() { static const auto value = Flag("BB_COPY_GPU_BUFFERS", false); return value; } + bool IsDirectMemoryAccessEnabled() { static const auto value = Flag("BB_DIRECT_MEMORY_ACCESS", false); return value; } + bool IsDumpShaders() { static const auto value = Flag("BB_DUMP_SHADERS", false); return value; } + bool IsFsrEnabled() { static const auto value = Flag("BB_FSR1", false); return value; } + bool IsHdrAllowed() { static const auto value = Flag("BB_HDR", false); return value; } + bool IsNullGPU() { static const auto value = Flag("BB_NULL_GPU", false); return value; } + bool IsPatchShaders() { return false; } + bool IsPipelineCacheArchived() { return false; } + bool IsPipelineCacheEnabled() { static const auto value = Flag("BB_PIPELINE_CACHE", true); return value; } + bool IsRcasEnabled() { static const auto value = Flag("BB_RCAS", true); return value; } + bool IsReadbackLinearImagesEnabled() { static const auto value = Flag("BB_READBACK_LINEAR", false); return value; } + bool IsRenderdocEnabled() { return false; } + bool IsShaderCollect() { return false; } + bool IsUserfaultfdTracking() { return false; } + bool IsVkCrashDiagnosticEnabled() { return false; } + bool IsVkGuestMarkersEnabled() { static const auto value = Flag("BB_VK_MARKERS", false); return value; } + bool IsVkHostMarkersEnabled() { static const auto value = Flag("BB_VK_MARKERS", false); return value; } + bool IsVkValidationCoreEnabled() { return true; } + bool IsVkValidationEnabled() { static const auto value = Flag("BB_VK_VALIDATION", false); return value; } + bool IsVkValidationGpuEnabled() { return false; } + bool IsVkValidationSyncEnabled() { static const auto value = Flag("BB_VK_VALIDATION_SYNC", false); return value; } +}; +#define EmulatorSettings (*EmulatorSettingsImpl::GetInstance()) diff --git a/gpu/shim/core/libraries/kernel/kernel.h b/gpu/shim/core/libraries/kernel/kernel.h new file mode 100644 index 0000000..ecc2e6e --- /dev/null +++ b/gpu/shim/core/libraries/kernel/kernel.h @@ -0,0 +1,7 @@ +// bbport: the parts of shadPS4's kernel.h used by vendored libraries. +#pragma once +#include "common/types.h" +#include "core/libraries/kernel/orbis_error.h" +namespace Libraries::Kernel { +int* PS4_SYSV_ABI __Error(); +} // namespace Libraries::Kernel diff --git a/gpu/shim/core/libraries/kernel/threads.h b/gpu/shim/core/libraries/kernel/threads.h new file mode 100644 index 0000000..b7f36cd --- /dev/null +++ b/gpu/shim/core/libraries/kernel/threads.h @@ -0,0 +1,39 @@ +// bbport: host threads that may call guest code (AvPlayer allocator callbacks). +// Each thread gets a guest TCB (GS base, TLS) from the C runtime before running. +#pragma once +#include +#include +#include +#include "common/types.h" + +extern "C" void runtime_thread_attach_host(const char* name); + +namespace Libraries::Kernel { +class Thread { +public: + Thread() = default; + ~Thread() { Stop(); } + void Run(std::function&& func) { + thread = std::jthread([func = std::move(func)](std::stop_token stop) { + runtime_thread_attach_host("bb:hle"); + func(stop); + }); + } + // A thread may stop its own Thread object (AvPlayer does); it detaches instead of joining. + void Join() { + if (!thread.joinable()) return; + if (thread.get_id() == std::this_thread::get_id()) thread.detach(); + else thread.join(); + } + bool Joinable() const { return thread.joinable(); } + void Stop() { + if (thread.joinable()) { + thread.request_stop(); + Join(); + } + } + +private: + std::jthread thread; +}; +} // namespace Libraries::Kernel diff --git a/gpu/shim/core/libraries/libs.h b/gpu/shim/core/libraries/libs.h new file mode 100644 index 0000000..033c32a --- /dev/null +++ b/gpu/shim/core/libraries/libs.h @@ -0,0 +1,20 @@ +// bbport: shadPS4 registers HLE functions with LIB_FUNCTION(nid, library, +// version, module, fn). Here the registrations fill a table that the C +// loader queries by NID (see bbgpu.cpp: bbgpu_resolve). +#pragma once +#include +#include "common/types.h" + +namespace Core::Loader { +enum class SymbolType { Function, Object }; +class SymbolsResolver { +public: + void AddSymbol(const char* nid, const char* library, const char* module, SymbolType type, u64 address); +}; +} // namespace Core::Loader + +#define LIB_FUNCTION(nid, lib, libversion, mod, function) \ + sym->AddSymbol(nid, lib, mod, Core::Loader::SymbolType::Function, \ + reinterpret_cast(function)) +#define LIB_OBJ(nid, lib, libversion, mod, obj) \ + sym->AddSymbol(nid, lib, mod, Core::Loader::SymbolType::Object, reinterpret_cast(obj)) diff --git a/gpu/shim/core/memory.h b/gpu/shim/core/memory.h new file mode 100644 index 0000000..baeefba --- /dev/null +++ b/gpu/shim/core/memory.h @@ -0,0 +1,31 @@ +// bbport: the MemoryManager surface used by the video core and GnmDriver. +// Guest memory lives at identical host addresses; the C runtime owns the VMAs. +#pragma once +#include "common/types.h" +#include "common/singleton.h" +#include "core/address_space.h" + +namespace Vulkan { class Rasterizer; } + +namespace Core { +class MemoryManager { +public: + void SetRasterizer(Vulkan::Rasterizer* rasterizer_); + AddressSpace& GetAddressSpace() { return impl; } + bool IsValidGpuMapping(VAddr virtual_addr, u64 size) { + // The PS4's GPU can only handle 40 bit addresses. + return virtual_addr + size < 0x100'0000'0000ULL; + } + u64 ClampRangeSize(VAddr virtual_addr, u64 size); + void CopySparseMemory(VAddr source, u8* dest, u64 size); + bool TryWriteBacking(void* address, const void* data, u64 size); + /// CPU wrote guest memory outside page tracking (e.g. decoded video frames). + void InvalidateMemory(VAddr address, u64 size); + Vulkan::Rasterizer* GetRasterizer() const { return rasterizer; } + +private: + AddressSpace impl; + Vulkan::Rasterizer* rasterizer{}; +}; +using Memory = Common::Singleton; +} // namespace Core diff --git a/gpu/shim/core/signals.h b/gpu/shim/core/signals.h new file mode 100644 index 0000000..b94462c --- /dev/null +++ b/gpu/shim/core/signals.h @@ -0,0 +1,45 @@ +// bbport: fault-handler registry. The C loader's SIGSEGV handler calls +// bbgpu_handle_fault() first; registered handlers run in priority order. +#pragma once +#include +#include +#include +#include "common/singleton.h" +#include "common/types.h" + +namespace Core { +using AccessViolationHandler = bool (*)(void* context, void* fault_address); +using IllegalInstructionHandler = bool (*)(void* context); + +class SignalDispatch { +public: + void RemoveHandlers() { access_violation_handlers.clear(); illegal_instruction_handlers.clear(); } + void RegisterAccessViolationHandler(const AccessViolationHandler& handler, u32 priority) { + access_violation_handlers.emplace(handler, priority); + } + void RegisterIllegalInstructionHandler(const IllegalInstructionHandler& handler, u32 priority) { + illegal_instruction_handlers.emplace(handler, priority); + } + bool DispatchAccessViolation(void* context, void* fault_address) const { + for (const auto& entry : access_violation_handlers) + if (entry.handler(context, fault_address)) return true; + return false; + } + bool DispatchIllegalInstruction(void* context) const { + for (const auto& entry : illegal_instruction_handlers) + if (entry.handler(context)) return true; + return false; + } + +private: + template + struct HandlerEntry { + T handler; + u32 priority; + std::strong_ordering operator<=>(const HandlerEntry& right) const { return priority <=> right.priority; } + }; + std::set> access_violation_handlers; + std::set> illegal_instruction_handlers; +}; +using Signals = Common::Singleton; +} // namespace Core diff --git a/gpu/shim/imgui/renderer/imgui_core.h b/gpu/shim/imgui/renderer/imgui_core.h new file mode 100644 index 0000000..8a54f1c --- /dev/null +++ b/gpu/shim/imgui/renderer/imgui_core.h @@ -0,0 +1,12 @@ +// bbport: no ImGui overlay in the port; hooks used by the renderer are no-ops. +#pragma once +#include "video_core/renderer_vulkan/vk_common.h" +namespace Frontend { class WindowSDL; } +namespace Vulkan { class Instance; } +namespace ImGui::Core { +inline void Initialize(const Vulkan::Instance&, const Frontend::WindowSDL&, u32, vk::Format) {} +inline void OnSurfaceFormatChange(vk::Format) {} +inline void Shutdown(vk::Device) {} +inline bool MustKeepDrawing() { return false; } +struct TextureManager { static void Submit() {} }; +} // namespace ImGui::Core diff --git a/gpu/shim/imgui/renderer/texture_manager.h b/gpu/shim/imgui/renderer/texture_manager.h new file mode 100644 index 0000000..8a54f1c --- /dev/null +++ b/gpu/shim/imgui/renderer/texture_manager.h @@ -0,0 +1,12 @@ +// bbport: no ImGui overlay in the port; hooks used by the renderer are no-ops. +#pragma once +#include "video_core/renderer_vulkan/vk_common.h" +namespace Frontend { class WindowSDL; } +namespace Vulkan { class Instance; } +namespace ImGui::Core { +inline void Initialize(const Vulkan::Instance&, const Frontend::WindowSDL&, u32, vk::Format) {} +inline void OnSurfaceFormatChange(vk::Format) {} +inline void Shutdown(vk::Device) {} +inline bool MustKeepDrawing() { return false; } +struct TextureManager { static void Submit() {} }; +} // namespace ImGui::Core diff --git a/gpu/shim/sdl_window.h b/gpu/shim/sdl_window.h new file mode 100644 index 0000000..ebf5148 --- /dev/null +++ b/gpu/shim/sdl_window.h @@ -0,0 +1,50 @@ +// bbport: the game window. Created by the VideoOut driver on first open; the +// event pump runs on the port's window thread (see window.cpp). +#pragma once +#include +#include +#include +#include "common/types.h" + +struct SDL_Window; + +namespace Frontend { + +enum class WindowSystemType : u8 { Headless, Windows, X11, Wayland, Metal }; + +struct WindowSystemInfo { + void* display_connection = nullptr; + void* render_surface = nullptr; + float render_surface_scale = 1.0f; + WindowSystemType type = WindowSystemType::Headless; +}; + +class WindowSDL { +public: + WindowSDL(s32 width, s32 height, const char* title); + ~WindowSDL(); + s32 GetWidth() const { return width.load(std::memory_order_relaxed); } + s32 GetHeight() const { return height.load(std::memory_order_relaxed); } + SDL_Window* GetSDLWindow() const { return window; } + WindowSystemInfo GetWindowInfo() const { return window_info; } + bool IsOpen() const { return is_open.load(std::memory_order_relaxed); } + /// Processes pending window events. Returns false once the user closed the window. + bool PollEvents(); + /// Keyboard text entry for the system IME dialog; typed text shows in the title bar. + void BeginTextInput(const std::string& initial, const std::string& prompt); + /// 0 while typing, 1 confirmed (Enter), 2 cancelled (Escape); text is UTF-8. + int PollTextInput(std::string& text); + +private: + std::atomic width, height; + std::atomic is_open{true}; + std::mutex text_mutex; + bool text_requested{}, text_active{}; + int text_state{}; + std::string text, text_prompt, base_title; + void UpdateTextTitle(); + SDL_Window* window{}; + WindowSystemInfo window_info{}; +}; + +} // namespace Frontend diff --git a/gpu/shim/tracy/Tracy.hpp b/gpu/shim/tracy/Tracy.hpp new file mode 100644 index 0000000..8e01615 --- /dev/null +++ b/gpu/shim/tracy/Tracy.hpp @@ -0,0 +1,29 @@ +// bbport: profiler disabled; Tracy macros compile to nothing. +#pragma once +#include +#include +#define TracyFile __FILE__ +#define TracyLine __LINE__ +#define TracyFunction __func__ +#define ZoneScoped +#define ZoneScopedN(name) +#define ZoneScopedC(color) +#define ZoneScopedNC(name, color) +#define ZoneText(text, size) ((void)(text), (void)(size)) +#define ZoneName(text, size) +#define FrameMark +#define FrameMarkNamed(name) +#define TracyMessageC(text, size, color) ((void)(text), (void)(size)) +#define TracyMessageL(text) +#define TracyAllocN(ptr, size, name) ((void)(ptr), (void)(size)) +#define TracyFreeN(ptr, name) ((void)(ptr)) +#define TracyFiberEnter(name) +#define TracyFiberLeave +#define TracyPlot(name, value) +namespace tracy { +struct SourceLocationData { const char* name; const char* function; const char* file; uint32_t line; uint32_t color; }; +struct Color { enum : uint32_t { Red = 0xff0000, HotPink = 0xff69b4, DarkOrange = 0xff8c00 }; }; +struct LockableCtx { explicit LockableCtx(const SourceLocationData*) {} void BeforeLock() {} void AfterLock() {} void AfterUnlock() {} void AfterTryLock(bool) {} void Mark(const SourceLocationData*) {} void CustomName(const char*, size_t) {} }; +struct Profiler { bool IsConnected() const { return false; } }; +inline Profiler& GetProfiler() { static Profiler p; return p; } +} // namespace tracy diff --git a/gpu/shim/tracy/TracyVulkan.hpp b/gpu/shim/tracy/TracyVulkan.hpp new file mode 100644 index 0000000..2a92397 --- /dev/null +++ b/gpu/shim/tracy/TracyVulkan.hpp @@ -0,0 +1,10 @@ +// bbport: profiler disabled. +#pragma once +#include "Tracy.hpp" +#define TracyVkCtx void* +#define TracyVkCollect(ctx, cmdbuf) +#define TracyVkNamedZoneC(ctx, var, cmd, name, color, active) +#define TracyVkContextName(ctx, name, size) +#define TracyVkContextHostCalibrated(...) nullptr +#define TracyVkDestroy(ctx) +namespace tracy { struct VkCtxScope { template VkCtxScope(A&&...) {} }; } diff --git a/gpu/shim/window.cpp b/gpu/shim/window.cpp new file mode 100644 index 0000000..06c4ced --- /dev/null +++ b/gpu/shim/window.cpp @@ -0,0 +1,123 @@ +// bbport: SDL3 window for the Vulkan swapchain (X11 or Wayland). +#include +#include +#include +#include "common/assert.h" +#include "common/logging/log.h" +#include "sdl_window.h" + +namespace Frontend { + +WindowSDL::WindowSDL(s32 width_, s32 height_, const char* title) : width{width_}, height{height_} { + // Gamepads are sampled by runtime_pad.c; their events are pumped here with the window's. + if (!SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) { + UNREACHABLE_MSG("Failed to initialize SDL video: {}", SDL_GetError()); + } + SDL_PropertiesID props = SDL_CreateProperties(); + SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width_); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height_); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, true); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_VULKAN_BOOLEAN, true); + const char* fullscreen = std::getenv("BB_FULLSCREEN"); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, fullscreen && fullscreen[0] == '1'); + base_title = title; + window = SDL_CreateWindowWithProperties(props); + SDL_DestroyProperties(props); + ASSERT_MSG(window, "Failed to create window: {}", SDL_GetError()); + + const char* driver = SDL_GetCurrentVideoDriver(); + const SDL_PropertiesID wp = SDL_GetWindowProperties(window); + if (driver && !std::strcmp(driver, "x11")) { + window_info.type = WindowSystemType::X11; + window_info.display_connection = SDL_GetPointerProperty(wp, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr); + window_info.render_surface = reinterpret_cast(SDL_GetNumberProperty(wp, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0)); + } else if (driver && !std::strcmp(driver, "wayland")) { + window_info.type = WindowSystemType::Wayland; + window_info.display_connection = SDL_GetPointerProperty(wp, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr); + window_info.render_surface = SDL_GetPointerProperty(wp, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr); + } else { + UNREACHABLE_MSG("Unsupported SDL video driver {}", driver ? driver : "(none)"); + } + int w = 0, h = 0; + SDL_GetWindowSizeInPixels(window, &w, &h); + width = w; + height = h; + LOG_INFO(Frontend, "Window {}x{} on {}", w, h, driver); +} + +WindowSDL::~WindowSDL() { + SDL_DestroyWindow(window); +} + +void WindowSDL::BeginTextInput(const std::string& initial, const std::string& prompt) { + std::scoped_lock lock{text_mutex}; + text = initial; + text_prompt = prompt; + text_state = 0; + text_requested = true; +} + +int WindowSDL::PollTextInput(std::string& out) { + std::scoped_lock lock{text_mutex}; + out = text; + return text_state; +} + +void WindowSDL::UpdateTextTitle() { + const std::string title = text_active ? base_title + " \u2014 " + text_prompt + ": " + text + "_ (Enter = OK, Esc = cancel)" + : base_title; + SDL_SetWindowTitle(window, title.c_str()); +} + +bool WindowSDL::PollEvents() { + { + std::scoped_lock lock{text_mutex}; + if (text_requested) { // SDL text input must be toggled from the window thread + text_requested = false; + text_active = true; + SDL_StartTextInput(window); + UpdateTextTitle(); + } + } + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (text_active && (event.type == SDL_EVENT_TEXT_INPUT || event.type == SDL_EVENT_KEY_DOWN)) { + std::scoped_lock lock{text_mutex}; + if (event.type == SDL_EVENT_TEXT_INPUT) { + text += event.text.text; + } else if (event.key.key == SDLK_BACKSPACE && !text.empty()) { + size_t cut = text.size() - 1; // drop one UTF-8 code point + while (cut > 0 && (static_cast(text[cut]) & 0xC0) == 0x80) --cut; + text.erase(cut); + } else if (event.key.key == SDLK_RETURN || event.key.key == SDLK_KP_ENTER || event.key.key == SDLK_ESCAPE) { + text_state = event.key.key == SDLK_ESCAPE ? 2 : 1; + text_active = false; + SDL_StopTextInput(window); + } + UpdateTextTitle(); + continue; + } + switch (event.type) { + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + case SDL_EVENT_WINDOW_RESIZED: { + int w = 0, h = 0; + SDL_GetWindowSizeInPixels(window, &w, &h); + width = w; + height = h; + break; + } + case SDL_EVENT_QUIT: + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + is_open = false; + break; + default: + break; + } + } + return is_open; +} + +} // namespace Frontend diff --git a/gpu/third_party/gcn/include/gcn/si_ci_vi_merged_offset.h b/gpu/third_party/gcn/include/gcn/si_ci_vi_merged_offset.h new file mode 100644 index 0000000..589a58b --- /dev/null +++ b/gpu/third_party/gcn/include/gcn/si_ci_vi_merged_offset.h @@ -0,0 +1,15339 @@ +/* + *********************************************************************************************************************** + * + * Copyright (c) 2014-2021 Advanced Micro Devices, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * 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 Software. + * + * THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + **********************************************************************************************************************/ + +#if !defined __SI__CI__VIoffset_HEADER +#define __SI__CI__VIoffset_HEADER + +namespace Pal +{ +namespace Gfx6 +{ +inline namespace Chip +{ + +#define SI_CI_offset_HEADER__SI__CI +constexpr unsigned int cfgADAPTER_ID = 0x000B; +constexpr unsigned int cfgADAPTER_ID_W = 0x0013; +constexpr unsigned int cfgBASE_ADDR_1 = 0x0004; +constexpr unsigned int cfgBASE_ADDR_2 = 0x0005; +constexpr unsigned int cfgBASE_ADDR_3 = 0x0006; +constexpr unsigned int cfgBASE_ADDR_4 = 0x0007; +constexpr unsigned int cfgBASE_ADDR_5 = 0x0008; +constexpr unsigned int cfgBASE_ADDR_6 = 0x0009; +constexpr unsigned int cfgBASE_CLASS = 0x0002; +constexpr unsigned int cfgBIST = 0x0003; +constexpr unsigned int cfgCACHE_LINE = 0x0003; +constexpr unsigned int cfgCAP_PTR = 0x000D; +constexpr unsigned int cfgCOMMAND = 0x0001; +constexpr unsigned int cfgDEVICE_CAP = 0x0017; +constexpr unsigned int cfgDEVICE_CAP2 = 0x001F; +constexpr unsigned int cfgDEVICE_CNTL = 0x0018; +constexpr unsigned int cfgDEVICE_CNTL2 = 0x0020; +constexpr unsigned int cfgDEVICE_ID = 0x0000; +constexpr unsigned int cfgDEVICE_STATUS = 0x0018; +constexpr unsigned int cfgDEVICE_STATUS2 = 0x0020; +constexpr unsigned int cfgHEADER = 0x0003; +constexpr unsigned int cfgINTERRUPT_LINE = 0x000F; +constexpr unsigned int cfgINTERRUPT_PIN = 0x000F; +constexpr unsigned int cfgLATENCY = 0x0003; +constexpr unsigned int cfgLINK_CAP = 0x0019; +constexpr unsigned int cfgLINK_CAP2 = 0x0021; +constexpr unsigned int cfgLINK_CNTL = 0x001A; +constexpr unsigned int cfgLINK_CNTL2 = 0x0022; +constexpr unsigned int cfgLINK_STATUS = 0x001A; +constexpr unsigned int cfgLINK_STATUS2 = 0x0022; +constexpr unsigned int cfgMAX_LATENCY = 0x000F; +constexpr unsigned int cfgMIN_GRANT = 0x000F; +constexpr unsigned int cfgMSI_CAP_LIST = 0x0028; +constexpr unsigned int cfgMSI_MSG_ADDR_HI = 0x002A; +constexpr unsigned int cfgMSI_MSG_ADDR_LO = 0x0029; +constexpr unsigned int cfgMSI_MSG_CNTL = 0x0028; +constexpr unsigned int cfgMSI_MSG_DATA = 0x002A; +constexpr unsigned int cfgMSI_MSG_DATA_64 = 0x002B; +constexpr unsigned int cfgPCIE_ACS_CAP__CI__VI = 0x00A9; +constexpr unsigned int cfgPCIE_ACS_CNTL__CI__VI = 0x00A9; +constexpr unsigned int cfgPCIE_ACS_ENH_CAP_LIST__CI__VI = 0x00A8; +constexpr unsigned int cfgPCIE_ADV_ERR_CAP_CNTL = 0x005A; +constexpr unsigned int cfgPCIE_ADV_ERR_RPT_ENH_CAP_LIST = 0x0054; +constexpr unsigned int cfgPCIE_ATS_CAP__CI__VI = 0x00AD; +constexpr unsigned int cfgPCIE_ATS_CNTL__CI__VI = 0x00AD; +constexpr unsigned int cfgPCIE_ATS_ENH_CAP_LIST__CI__VI = 0x00AC; +constexpr unsigned int cfgPCIE_BAR1_CAP__CI__VI = 0x0081; +constexpr unsigned int cfgPCIE_BAR1_CNTL__CI__VI = 0x0082; +constexpr unsigned int cfgPCIE_BAR2_CAP__CI__VI = 0x0083; +constexpr unsigned int cfgPCIE_BAR2_CNTL__CI__VI = 0x0084; +constexpr unsigned int cfgPCIE_BAR3_CAP__CI__VI = 0x0085; +constexpr unsigned int cfgPCIE_BAR3_CNTL__CI__VI = 0x0086; +constexpr unsigned int cfgPCIE_BAR4_CAP__CI__VI = 0x0087; +constexpr unsigned int cfgPCIE_BAR4_CNTL__CI__VI = 0x0088; +constexpr unsigned int cfgPCIE_BAR5_CAP__CI__VI = 0x0089; +constexpr unsigned int cfgPCIE_BAR5_CNTL__CI__VI = 0x008A; +constexpr unsigned int cfgPCIE_BAR6_CAP__CI__VI = 0x008B; +constexpr unsigned int cfgPCIE_BAR6_CNTL__CI__VI = 0x008C; +constexpr unsigned int cfgPCIE_BAR_ENH_CAP_LIST__CI__VI = 0x0080; +constexpr unsigned int cfgPCIE_CAP = 0x0016; +constexpr unsigned int cfgPCIE_CAP_LIST = 0x0016; +constexpr unsigned int cfgPCIE_CORR_ERR_MASK = 0x0059; +constexpr unsigned int cfgPCIE_CORR_ERR_STATUS = 0x0058; +constexpr unsigned int cfgPCIE_DEV_SERIAL_NUM_DW1 = 0x0051; +constexpr unsigned int cfgPCIE_DEV_SERIAL_NUM_DW2 = 0x0052; +constexpr unsigned int cfgPCIE_DEV_SERIAL_NUM_ENH_CAP_LIST = 0x0050; +constexpr unsigned int cfgPCIE_DPA_CAP__CI__VI = 0x0095; +constexpr unsigned int cfgPCIE_DPA_CNTL__CI__VI = 0x0097; +constexpr unsigned int cfgPCIE_DPA_ENH_CAP_LIST__CI__VI = 0x0094; +constexpr unsigned int cfgPCIE_DPA_LATENCY_INDICATOR__CI__VI = 0x0096; +constexpr unsigned int cfgPCIE_DPA_STATUS__CI__VI = 0x0097; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_0__CI__VI = 0x0098; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_1__CI__VI = 0x0098; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_2__CI__VI = 0x0098; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_3__CI__VI = 0x0098; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_4__CI__VI = 0x0099; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_5__CI__VI = 0x0099; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_6__CI__VI = 0x0099; +constexpr unsigned int cfgPCIE_DPA_SUBSTATE_PWR_ALLOC_7__CI__VI = 0x0099; +constexpr unsigned int cfgPCIE_HDR_LOG0 = 0x005B; +constexpr unsigned int cfgPCIE_HDR_LOG1 = 0x005C; +constexpr unsigned int cfgPCIE_HDR_LOG2 = 0x005D; +constexpr unsigned int cfgPCIE_HDR_LOG3 = 0x005E; +constexpr unsigned int cfgPCIE_LANE_0_EQUALIZATION_CNTL__CI__VI = 0x009F; +constexpr unsigned int cfgPCIE_LANE_10_EQUALIZATION_CNTL__CI__VI = 0x00A4; +constexpr unsigned int cfgPCIE_LANE_11_EQUALIZATION_CNTL__CI__VI = 0x00A4; +constexpr unsigned int cfgPCIE_LANE_12_EQUALIZATION_CNTL__CI__VI = 0x00A5; +constexpr unsigned int cfgPCIE_LANE_13_EQUALIZATION_CNTL__CI__VI = 0x00A5; +constexpr unsigned int cfgPCIE_LANE_14_EQUALIZATION_CNTL__CI__VI = 0x00A6; +constexpr unsigned int cfgPCIE_LANE_15_EQUALIZATION_CNTL__CI__VI = 0x00A6; +constexpr unsigned int cfgPCIE_LANE_1_EQUALIZATION_CNTL__CI__VI = 0x009F; +constexpr unsigned int cfgPCIE_LANE_2_EQUALIZATION_CNTL__CI__VI = 0x00A0; +constexpr unsigned int cfgPCIE_LANE_3_EQUALIZATION_CNTL__CI__VI = 0x00A0; +constexpr unsigned int cfgPCIE_LANE_4_EQUALIZATION_CNTL__CI__VI = 0x00A1; +constexpr unsigned int cfgPCIE_LANE_5_EQUALIZATION_CNTL__CI__VI = 0x00A1; +constexpr unsigned int cfgPCIE_LANE_6_EQUALIZATION_CNTL__CI__VI = 0x00A2; +constexpr unsigned int cfgPCIE_LANE_7_EQUALIZATION_CNTL__CI__VI = 0x00A2; +constexpr unsigned int cfgPCIE_LANE_8_EQUALIZATION_CNTL__CI__VI = 0x00A3; +constexpr unsigned int cfgPCIE_LANE_9_EQUALIZATION_CNTL__CI__VI = 0x00A3; +constexpr unsigned int cfgPCIE_LANE_ERROR_STATUS__CI__VI = 0x009E; +constexpr unsigned int cfgPCIE_LINK_CNTL3__CI__VI = 0x009D; +constexpr unsigned int cfgPCIE_OUTSTAND_PAGE_REQ_ALLOC__CI__VI = 0x00B3; +constexpr unsigned int cfgPCIE_OUTSTAND_PAGE_REQ_CAPACITY__CI__VI = 0x00B2; +constexpr unsigned int cfgPCIE_PAGE_REQ_CNTL__CI__VI = 0x00B1; +constexpr unsigned int cfgPCIE_PAGE_REQ_ENH_CAP_LIST__CI__VI = 0x00B0; +constexpr unsigned int cfgPCIE_PAGE_REQ_STATUS__CI__VI = 0x00B1; +constexpr unsigned int cfgPCIE_PASID_CAP__CI__VI = 0x00B5; +constexpr unsigned int cfgPCIE_PASID_CNTL__CI__VI = 0x00B5; +constexpr unsigned int cfgPCIE_PASID_ENH_CAP_LIST__CI__VI = 0x00B4; +constexpr unsigned int cfgPCIE_PORT_VC_CAP_REG1 = 0x0045; +constexpr unsigned int cfgPCIE_PORT_VC_CAP_REG2 = 0x0046; +constexpr unsigned int cfgPCIE_PORT_VC_CNTL = 0x0047; +constexpr unsigned int cfgPCIE_PORT_VC_STATUS = 0x0047; +constexpr unsigned int cfgPCIE_PWR_BUDGET_CAP__CI__VI = 0x0093; +constexpr unsigned int cfgPCIE_PWR_BUDGET_DATA_SELECT__CI__VI = 0x0091; +constexpr unsigned int cfgPCIE_PWR_BUDGET_DATA__CI__VI = 0x0092; +constexpr unsigned int cfgPCIE_PWR_BUDGET_ENH_CAP_LIST__CI__VI = 0x0090; +constexpr unsigned int cfgPCIE_SECONDARY_ENH_CAP_LIST__CI__VI = 0x009C; +constexpr unsigned int cfgPCIE_TLP_PREFIX_LOG0__CI__VI = 0x0062; +constexpr unsigned int cfgPCIE_TLP_PREFIX_LOG1__CI__VI = 0x0063; +constexpr unsigned int cfgPCIE_TLP_PREFIX_LOG2__CI__VI = 0x0064; +constexpr unsigned int cfgPCIE_TLP_PREFIX_LOG3__CI__VI = 0x0065; +constexpr unsigned int cfgPCIE_UNCORR_ERR_MASK = 0x0056; +constexpr unsigned int cfgPCIE_UNCORR_ERR_SEVERITY = 0x0057; +constexpr unsigned int cfgPCIE_UNCORR_ERR_STATUS = 0x0055; +constexpr unsigned int cfgPCIE_VC0_RESOURCE_CAP = 0x0048; +constexpr unsigned int cfgPCIE_VC0_RESOURCE_CNTL = 0x0049; +constexpr unsigned int cfgPCIE_VC0_RESOURCE_STATUS = 0x004A; +constexpr unsigned int cfgPCIE_VC1_RESOURCE_CAP = 0x004B; +constexpr unsigned int cfgPCIE_VC1_RESOURCE_CNTL = 0x004C; +constexpr unsigned int cfgPCIE_VC1_RESOURCE_STATUS = 0x004D; +constexpr unsigned int cfgPCIE_VC_ENH_CAP_LIST = 0x0044; +constexpr unsigned int cfgPCIE_VENDOR_SPECIFIC1 = 0x0042; +constexpr unsigned int cfgPCIE_VENDOR_SPECIFIC2 = 0x0043; +constexpr unsigned int cfgPCIE_VENDOR_SPECIFIC_ENH_CAP_LIST = 0x0040; +constexpr unsigned int cfgPCIE_VENDOR_SPECIFIC_HDR = 0x0041; +constexpr unsigned int cfgPMI_CAP = 0x0014; +constexpr unsigned int cfgPMI_CAP_LIST = 0x0014; +constexpr unsigned int cfgPMI_STATUS_CNTL = 0x0015; +constexpr unsigned int cfgPROG_INTERFACE = 0x0002; +constexpr unsigned int cfgREVISION_ID = 0x0002; +constexpr unsigned int cfgROM_BASE_ADDR = 0x000C; +constexpr unsigned int cfgSTATUS = 0x0001; +constexpr unsigned int cfgSUB_CLASS = 0x0002; +constexpr unsigned int cfgVENDOR_CAP_LIST__CI__VI = 0x0012; +constexpr unsigned int cfgVENDOR_ID = 0x0000; +constexpr unsigned int ioATTRDR__SI__VI = 0x00F0; +constexpr unsigned int ioATTRDW__SI__VI = 0x00F0; +constexpr unsigned int ioATTRX__SI__VI = 0x00F0; +constexpr unsigned int ioBIF_RFE_SNOOP_REG__CI__VI = 0x0027; +constexpr unsigned int ioCRTC8_DATA__SI__VI = 0x00ED; +constexpr unsigned int ioCRTC8_IDX__SI__VI = 0x00ED; +constexpr unsigned int ioDAC_DATA__SI__VI = 0x00F2; +constexpr unsigned int ioDAC_MASK__SI__VI = 0x00F1; +constexpr unsigned int ioDAC_R_INDEX__SI__VI = 0x00F1; +constexpr unsigned int ioDAC_W_INDEX__SI__VI = 0x00F2; +constexpr unsigned int ioGENENB__SI__VI = 0x00F0; +constexpr unsigned int ioGENFC_RD__SI__VI = 0x00F2; +constexpr unsigned int ioGENFC_WT__SI__VI = 0x00EE; +constexpr unsigned int ioGENMO_RD__SI__VI = 0x00F3; +constexpr unsigned int ioGENMO_WT__SI__VI = 0x00F0; +constexpr unsigned int ioGENS0__SI__VI = 0x00F0; +constexpr unsigned int ioGENS1__SI__VI = 0x00EE; +constexpr unsigned int ioGRPH8_DATA__SI__VI = 0x00F3; +constexpr unsigned int ioGRPH8_IDX__SI__VI = 0x00F3; +constexpr unsigned int ioMM_DATA = 0x0001; +constexpr unsigned int ioMM_INDEX = 0x0000; +constexpr unsigned int ioMM_INDEX_HI__CI__VI = 0x0006; +constexpr unsigned int ioPCIE_DATA_2__CI__VI = 0x000D; +constexpr unsigned int ioPCIE_DATA__CI__VI = 0x000F; +constexpr unsigned int ioPCIE_DATA__SI = 0x000D; +constexpr unsigned int ioPCIE_INDEX_2__CI__VI = 0x000C; +constexpr unsigned int ioPCIE_INDEX__CI__VI = 0x000E; +constexpr unsigned int ioPCIE_INDEX__SI = 0x000C; +constexpr unsigned int ioROM_DATA__SI = 0x002B; +constexpr unsigned int ioROM_INDEX__SI = 0x002A; +constexpr unsigned int ioSEQ8_DATA__SI__VI = 0x00F1; +constexpr unsigned int ioSEQ8_IDX__SI__VI = 0x00F1; +constexpr unsigned int ioVGA_MEM_READ_PAGE_ADDR__SI__VI = 0x0013; +constexpr unsigned int ioVGA_MEM_WRITE_PAGE_ADDR__SI__VI = 0x0012; +constexpr unsigned int mmABM_TEST_DEBUG_DATA__SI__VI = 0x169F; +constexpr unsigned int mmABM_TEST_DEBUG_INDEX__SI__VI = 0x169E; +constexpr unsigned int mmACP_CONFIG__CI = 0x0F95; +constexpr unsigned int mmAFMT_60958_0__SI = 0x1C41; +constexpr unsigned int mmAFMT_60958_1__SI = 0x1C42; +constexpr unsigned int mmAFMT_60958_2__SI = 0x1C48; +constexpr unsigned int mmAFMT_AUDIO_CRC_CONTROL__SI = 0x1C43; +constexpr unsigned int mmAFMT_AUDIO_CRC_RESULT__SI = 0x1C49; +constexpr unsigned int mmAFMT_AUDIO_INFO0__SI = 0x1C3F; +constexpr unsigned int mmAFMT_AUDIO_INFO1__SI = 0x1C40; +constexpr unsigned int mmAFMT_AUDIO_PACKET_CONTROL2__SI = 0x1C17; +constexpr unsigned int mmAFMT_AUDIO_PACKET_CONTROL__SI = 0x1C4B; +constexpr unsigned int mmAFMT_AVI_INFO0__SI = 0x1C21; +constexpr unsigned int mmAFMT_AVI_INFO1__SI = 0x1C22; +constexpr unsigned int mmAFMT_AVI_INFO2__SI = 0x1C23; +constexpr unsigned int mmAFMT_AVI_INFO3__SI = 0x1C24; +constexpr unsigned int mmAFMT_INFOFRAME_CONTROL0__SI = 0x1C4D; +constexpr unsigned int mmAFMT_ISRC1_0__SI = 0x1C18; +constexpr unsigned int mmAFMT_ISRC1_1__SI = 0x1C19; +constexpr unsigned int mmAFMT_ISRC1_2__SI = 0x1C1A; +constexpr unsigned int mmAFMT_ISRC1_3__SI = 0x1C1B; +constexpr unsigned int mmAFMT_ISRC1_4__SI = 0x1C1C; +constexpr unsigned int mmAFMT_ISRC2_0__SI = 0x1C1D; +constexpr unsigned int mmAFMT_ISRC2_1__SI = 0x1C1E; +constexpr unsigned int mmAFMT_ISRC2_2__SI = 0x1C1F; +constexpr unsigned int mmAFMT_ISRC2_3__SI = 0x1C20; +constexpr unsigned int mmAFMT_MPEG_INFO0__SI = 0x1C25; +constexpr unsigned int mmAFMT_MPEG_INFO1__SI = 0x1C26; +constexpr unsigned int mmAFMT_RAMP_CONTROL0__SI = 0x1C44; +constexpr unsigned int mmAFMT_RAMP_CONTROL1__SI = 0x1C45; +constexpr unsigned int mmAFMT_RAMP_CONTROL2__SI = 0x1C46; +constexpr unsigned int mmAFMT_RAMP_CONTROL3__SI = 0x1C47; +constexpr unsigned int mmAFMT_STATUS__SI = 0x1C4A; +constexpr unsigned int mmAFMT_VBI_PACKET_CONTROL__SI = 0x1C4C; +constexpr unsigned int mmATC_ATS_CNTL__CI__VI = 0x0CC9; +constexpr unsigned int mmATC_ATS_DEBUG__CI__VI = 0x0CCA; +constexpr unsigned int mmATC_ATS_DEFAULT_PAGE_CNTL__CI__VI = 0x0CD1; +constexpr unsigned int mmATC_ATS_DEFAULT_PAGE_LOW__CI__VI = 0x0CD0; +constexpr unsigned int mmATC_ATS_FAULT_CNTL__CI__VI = 0x0CCD; +constexpr unsigned int mmATC_ATS_FAULT_DEBUG__CI__VI = 0x0CCB; +constexpr unsigned int mmATC_ATS_FAULT_STATUS_ADDR__CI__VI = 0x0CCF; +constexpr unsigned int mmATC_ATS_FAULT_STATUS_INFO__CI__VI = 0x0CCE; +constexpr unsigned int mmATC_ATS_STATUS__CI__VI = 0x0CCC; +constexpr unsigned int mmATC_L1RD_DEBUG_TLB__CI__VI = 0x0CDE; +constexpr unsigned int mmATC_L1RD_STATUS__CI__VI = 0x0CE0; +constexpr unsigned int mmATC_L1WR_DEBUG_TLB__CI__VI = 0x0CDF; +constexpr unsigned int mmATC_L1WR_STATUS__CI__VI = 0x0CE1; +constexpr unsigned int mmATC_L1_ADDRESS_OFFSET__CI__VI = 0x0CDD; +constexpr unsigned int mmATC_L1_CNTL__CI__VI = 0x0CDC; +constexpr unsigned int mmATC_L2_CNTL2__CI__VI = 0x0CD6; +constexpr unsigned int mmATC_L2_CNTL__CI__VI = 0x0CD5; +constexpr unsigned int mmATC_L2_DEBUG2__CI__VI = 0x0CD8; +constexpr unsigned int mmATC_L2_DEBUG__CI__VI = 0x0CD7; +constexpr unsigned int mmATC_MISC_CG__CI__VI = 0x0CD4; +constexpr unsigned int mmATC_PERFCOUNTER0_CFG__CI__VI = 0x07C8; +constexpr unsigned int mmATC_PERFCOUNTER1_CFG__CI__VI = 0x07C9; +constexpr unsigned int mmATC_PERFCOUNTER2_CFG__CI__VI = 0x07CA; +constexpr unsigned int mmATC_PERFCOUNTER3_CFG__CI__VI = 0x07CB; +constexpr unsigned int mmATC_PERFCOUNTER_HI__CI__VI = 0x07AF; +constexpr unsigned int mmATC_PERFCOUNTER_LO__CI__VI = 0x07A7; +constexpr unsigned int mmATC_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07D5; +constexpr unsigned int mmATC_VMID0_PASID_MAPPING__CI__VI = 0x0CE7; +constexpr unsigned int mmATC_VMID10_PASID_MAPPING__CI__VI = 0x0CF1; +constexpr unsigned int mmATC_VMID11_PASID_MAPPING__CI__VI = 0x0CF2; +constexpr unsigned int mmATC_VMID12_PASID_MAPPING__CI__VI = 0x0CF3; +constexpr unsigned int mmATC_VMID13_PASID_MAPPING__CI__VI = 0x0CF4; +constexpr unsigned int mmATC_VMID14_PASID_MAPPING__CI__VI = 0x0CF5; +constexpr unsigned int mmATC_VMID15_PASID_MAPPING__CI__VI = 0x0CF6; +constexpr unsigned int mmATC_VMID1_PASID_MAPPING__CI__VI = 0x0CE8; +constexpr unsigned int mmATC_VMID2_PASID_MAPPING__CI__VI = 0x0CE9; +constexpr unsigned int mmATC_VMID3_PASID_MAPPING__CI__VI = 0x0CEA; +constexpr unsigned int mmATC_VMID4_PASID_MAPPING__CI__VI = 0x0CEB; +constexpr unsigned int mmATC_VMID5_PASID_MAPPING__CI__VI = 0x0CEC; +constexpr unsigned int mmATC_VMID6_PASID_MAPPING__CI__VI = 0x0CED; +constexpr unsigned int mmATC_VMID7_PASID_MAPPING__CI__VI = 0x0CEE; +constexpr unsigned int mmATC_VMID8_PASID_MAPPING__CI__VI = 0x0CEF; +constexpr unsigned int mmATC_VMID9_PASID_MAPPING__CI__VI = 0x0CF0; +constexpr unsigned int mmATC_VMID_PASID_MAPPING_UPDATE_STATUS__CI__VI = 0x0CE6; +constexpr unsigned int mmATC_VM_APERTURE0_CNTL2__CI__VI = 0x0CC6; +constexpr unsigned int mmATC_VM_APERTURE0_CNTL__CI__VI = 0x0CC4; +constexpr unsigned int mmATC_VM_APERTURE0_HIGH_ADDR__CI__VI = 0x0CC2; +constexpr unsigned int mmATC_VM_APERTURE0_LOW_ADDR__CI__VI = 0x0CC0; +constexpr unsigned int mmATC_VM_APERTURE1_CNTL2__CI__VI = 0x0CC7; +constexpr unsigned int mmATC_VM_APERTURE1_CNTL__CI__VI = 0x0CC5; +constexpr unsigned int mmATC_VM_APERTURE1_HIGH_ADDR__CI__VI = 0x0CC3; +constexpr unsigned int mmATC_VM_APERTURE1_LOW_ADDR__CI__VI = 0x0CC1; +constexpr unsigned int mmATTRDR__SI__VI = 0x00F0; +constexpr unsigned int mmATTRDW__SI__VI = 0x00F0; +constexpr unsigned int mmATTRX__SI__VI = 0x00F0; +constexpr unsigned int mmAUXN_IMPCAL__SI = 0x194B; +constexpr unsigned int mmAUXP_IMPCAL__SI = 0x194A; +constexpr unsigned int mmAUX_ARB_CONTROL__SI = 0x1882; +constexpr unsigned int mmAUX_CONTROL__SI = 0x1880; +constexpr unsigned int mmAUX_DPHY_RX_CONTROL0__SI = 0x188A; +constexpr unsigned int mmAUX_DPHY_RX_CONTROL1__SI = 0x188B; +constexpr unsigned int mmAUX_DPHY_RX_STATUS__SI = 0x188D; +constexpr unsigned int mmAUX_DPHY_TX_CONTROL__SI = 0x1889; +constexpr unsigned int mmAUX_DPHY_TX_REF_CONTROL__SI = 0x1888; +constexpr unsigned int mmAUX_DPHY_TX_STATUS__SI = 0x188C; +constexpr unsigned int mmAUX_INTERRUPT_CONTROL__SI = 0x1883; +constexpr unsigned int mmAUX_LS_DATA__SI = 0x1887; +constexpr unsigned int mmAUX_LS_STATUS__SI = 0x1885; +constexpr unsigned int mmAUX_SW_CONTROL__SI = 0x1881; +constexpr unsigned int mmAUX_SW_DATA__SI = 0x1886; +constexpr unsigned int mmAUX_SW_STATUS__SI = 0x1884; +constexpr unsigned int mmAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER__SI = 0x17F6; +constexpr unsigned int mmAZALIA_AUDIO_DTO_CONTROL__SI = 0x173D; +constexpr unsigned int mmAZALIA_AUDIO_DTO__SI = 0x173C; +constexpr unsigned int mmAZALIA_BDL_DMA_CONTROL__SI = 0x1730; +constexpr unsigned int mmAZALIA_CORB_DMA_CONTROL__SI = 0x172F; +constexpr unsigned int mmAZALIA_CUMULATIVE_LATENCY_COUNT__SI = 0x1737; +constexpr unsigned int mmAZALIA_CUMULATIVE_REQUEST_COUNT__SI = 0x1738; +constexpr unsigned int mmAZALIA_CYCLIC_BUFFER_SYNC__SI = 0x17F7; +constexpr unsigned int mmAZALIA_DATA_DMA_CONTROL__SI = 0x1731; +constexpr unsigned int mmAZALIA_F0_CODEC_CONVERTER_CONTROL_CHANNEL_STREAM_ID__SI = 0x174F; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_CONTROL_POWER_STATE__SI = 0x174C; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_CONTROL_RESET__SI = 0x174D; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID__SI = 0x1750; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_GROUP_TYPE__SI = 0x1742; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES__SI = 0x1745; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS__SI = 0x1744; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES__SI = 0x1743; +constexpr unsigned int mmAZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE__SI = 0x174B; +constexpr unsigned int mmAZALIA_F0_CODEC_PIN_CONTROL_WIDGET_CONTROL__SI = 0x1753; +constexpr unsigned int mmAZALIA_F0_CODEC_ROOT_PARAMETER_REVISION_ID__SI = 0x173F; +constexpr unsigned int mmAZALIA_F0_CODEC_ROOT_PARAMETER_VENDOR_AND_DEVICE_ID__SI = 0x173E; +constexpr unsigned int mmAZALIA_LATENCY_COUNTER_CONTROL__SI = 0x1735; +constexpr unsigned int mmAZALIA_RIRB_AND_DP_CONTROL__SI = 0x172D; +constexpr unsigned int mmAZALIA_UNDERFLOW_FILLER_SAMPLE__SI = 0x1732; +constexpr unsigned int mmAZALIA_WORSTCASE_LATENCY_COUNT__SI = 0x1736; +constexpr unsigned int mmAZ_TEST_DEBUG_DATA__SI = 0x1756; +constexpr unsigned int mmAZ_TEST_DEBUG_INDEX__SI = 0x1755; +constexpr unsigned int mmBACO_CNTL_MISC__CI__VI = 0x14DB; +constexpr unsigned int mmBACO_CNTL__CI__VI = 0x14E5; +constexpr unsigned int mmBCI_DEBUG_READ__CI__VI = 0x24EB; +constexpr unsigned int mmBCI_DEBUG_READ__SI = 0x24E3; +constexpr unsigned int mmBIF_BACO_DEBUG_LATCH__CI__VI = 0x14DC; +constexpr unsigned int mmBIF_BACO_DEBUG__CI__VI = 0x14DF; +constexpr unsigned int mmBIF_BACO_MSIC__CI = 0x1480; +constexpr unsigned int mmBIF_BUSNUM_CNTL1 = 0x1525; +constexpr unsigned int mmBIF_BUSNUM_CNTL2 = 0x152B; +constexpr unsigned int mmBIF_BUSNUM_LIST0 = 0x1526; +constexpr unsigned int mmBIF_BUSNUM_LIST1 = 0x1527; +constexpr unsigned int mmBIF_BUSY_DELAY_CNTR = 0x1529; +constexpr unsigned int mmBIF_CC_RFE_IMP_OVERRIDECNTL__CI__VI = 0x1455; +constexpr unsigned int mmBIF_CLK_PDWN_DELAY_TIMER__CI = 0x1483; +constexpr unsigned int mmBIF_CLK_PDWN_DELAY_TIMER__SI = 0x151F; +constexpr unsigned int mmBIF_DEBUG_CNTL = 0x151C; +constexpr unsigned int mmBIF_DEBUG_MUX = 0x151D; +constexpr unsigned int mmBIF_DEBUG_OUT = 0x151E; +constexpr unsigned int mmBIF_DEVFUNCNUM_LIST0__CI__VI = 0x14E8; +constexpr unsigned int mmBIF_DEVFUNCNUM_LIST1__CI__VI = 0x14E7; +constexpr unsigned int mmBIF_DOORBELL_CNTL__CI__VI = 0x14C3; +constexpr unsigned int mmBIF_FB_EN = 0x1524; +constexpr unsigned int mmBIF_FEATURES_CONTROL_MISC__CI__VI = 0x14C2; +constexpr unsigned int mmBIF_IMPCTL_CONTINUOUS_CALIBRATION_PERIOD__CI__VI = 0x1454; +constexpr unsigned int mmBIF_IMPCTL_RXCNTL__CI__VI = 0x1451; +constexpr unsigned int mmBIF_IMPCTL_SMPLCNTL__CI__VI = 0x1450; +constexpr unsigned int mmBIF_IMPCTL_TXCNTL_pd__CI__VI = 0x1452; +constexpr unsigned int mmBIF_IMPCTL_TXCNTL_pu__CI__VI = 0x1453; +constexpr unsigned int mmBIF_LNCNT_RESET__CI = 0x1488; +constexpr unsigned int mmBIF_PERFCOUNTER0_RESULT__CI__VI = 0x152D; +constexpr unsigned int mmBIF_PERFCOUNTER1_RESULT__CI__VI = 0x152E; +constexpr unsigned int mmBIF_PERFMON_CNTL__CI__VI = 0x152C; +constexpr unsigned int mmBIF_PIF_TXCLK_SWITCH_TIMER__CI = 0x1481; +constexpr unsigned int mmBIF_PWDN_COMMAND__CI__VI = 0x1444; +constexpr unsigned int mmBIF_PWDN_STATUS__CI__VI = 0x1445; +constexpr unsigned int mmBIF_RESET_CNTL__CI = 0x1486; +constexpr unsigned int mmBIF_RESET_EN__CI = 0x1482; +constexpr unsigned int mmBIF_RESET_EN__SI = 0x1511; +constexpr unsigned int mmBIF_RFE_CLIENT_SOFTRST_TRIGGER__CI__VI = 0x1442; +constexpr unsigned int mmBIF_RFE_IMPRST_CNTL__CI__VI = 0x1458; +constexpr unsigned int mmBIF_RFE_MASTER_SOFTRST_TRIGGER__CI__VI = 0x1443; +constexpr unsigned int mmBIF_RFE_MMCFG_CNTL__CI__VI = 0x144C; +constexpr unsigned int mmBIF_RFE_MST_BU_CMDSTATUS__CI__VI = 0x1446; +constexpr unsigned int mmBIF_RFE_MST_BX_CMDSTATUS__CI = 0x1448; +constexpr unsigned int mmBIF_RFE_MST_RWREG_RFEWDBIF_CMDSTATUS__CI__VI = 0x1447; +constexpr unsigned int mmBIF_RFE_MST_TMOUT_STATUS__CI__VI = 0x144B; +constexpr unsigned int mmBIF_RFE_SNOOP_REG__CI__VI = 0x0027; +constexpr unsigned int mmBIF_RFE_SOFTRST_CNTL__CI__VI = 0x1441; +constexpr unsigned int mmBIF_SCRATCH0 = 0x150E; +constexpr unsigned int mmBIF_SCRATCH1 = 0x150F; +constexpr unsigned int mmBIF_SLVARB_MODE__CI__VI = 0x14C4; +constexpr unsigned int mmBIF_SSA_DISP_LOWER__CI = 0x14D2; +constexpr unsigned int mmBIF_SSA_DISP_UPPER__CI = 0x14D3; +constexpr unsigned int mmBIF_SSA_GFX0_LOWER__CI = 0x14CA; +constexpr unsigned int mmBIF_SSA_GFX0_UPPER__CI = 0x14CB; +constexpr unsigned int mmBIF_SSA_GFX1_LOWER__CI = 0x14CC; +constexpr unsigned int mmBIF_SSA_GFX1_UPPER__CI = 0x14CD; +constexpr unsigned int mmBIF_SSA_GFX2_LOWER__CI = 0x14CE; +constexpr unsigned int mmBIF_SSA_GFX2_UPPER__CI = 0x14CF; +constexpr unsigned int mmBIF_SSA_GFX3_LOWER__CI = 0x14D0; +constexpr unsigned int mmBIF_SSA_GFX3_UPPER__CI = 0x14D1; +constexpr unsigned int mmBIF_SSA_MC_LOWER__CI = 0x14D4; +constexpr unsigned int mmBIF_SSA_MC_UPPER__CI = 0x14D5; +constexpr unsigned int mmBIF_SSA_PWR_STATUS__CI = 0x14C8; +constexpr unsigned int mmBIF_XDMA_HI__CI__VI = 0x14C1; +constexpr unsigned int mmBIF_XDMA_LO__CI__VI = 0x14C0; +constexpr unsigned int mmBIOS_SCRATCH_0 = 0x05C9; +constexpr unsigned int mmBIOS_SCRATCH_1 = 0x05CA; +constexpr unsigned int mmBIOS_SCRATCH_10 = 0x05D3; +constexpr unsigned int mmBIOS_SCRATCH_11 = 0x05D4; +constexpr unsigned int mmBIOS_SCRATCH_12 = 0x05D5; +constexpr unsigned int mmBIOS_SCRATCH_13 = 0x05D6; +constexpr unsigned int mmBIOS_SCRATCH_14 = 0x05D7; +constexpr unsigned int mmBIOS_SCRATCH_15 = 0x05D8; +constexpr unsigned int mmBIOS_SCRATCH_2 = 0x05CB; +constexpr unsigned int mmBIOS_SCRATCH_3 = 0x05CC; +constexpr unsigned int mmBIOS_SCRATCH_4 = 0x05CD; +constexpr unsigned int mmBIOS_SCRATCH_5 = 0x05CE; +constexpr unsigned int mmBIOS_SCRATCH_6 = 0x05CF; +constexpr unsigned int mmBIOS_SCRATCH_7 = 0x05D0; +constexpr unsigned int mmBIOS_SCRATCH_8 = 0x05D1; +constexpr unsigned int mmBIOS_SCRATCH_9 = 0x05D2; +constexpr unsigned int mmBL1_PWM_ABM_CNTL__SI__VI = 0x162E; +constexpr unsigned int mmBL1_PWM_AMBIENT_LIGHT_LEVEL__SI__VI = 0x1628; +constexpr unsigned int mmBL1_PWM_BL_UPDATE_SAMPLE_RATE__SI__VI = 0x162F; +constexpr unsigned int mmBL1_PWM_CURRENT_ABM_LEVEL__SI__VI = 0x162B; +constexpr unsigned int mmBL1_PWM_FINAL_DUTY_CYCLE__SI__VI = 0x162C; +constexpr unsigned int mmBL1_PWM_GRP2_REG_LOCK__SI__VI = 0x1630; +constexpr unsigned int mmBL1_PWM_MINIMUM_DUTY_CYCLE__SI__VI = 0x162D; +constexpr unsigned int mmBL1_PWM_TARGET_ABM_LEVEL__SI__VI = 0x162A; +constexpr unsigned int mmBL1_PWM_USER_LEVEL__SI__VI = 0x1629; +constexpr unsigned int mmBL_PWM_CNTL2__SI = 0x1968; +constexpr unsigned int mmBL_PWM_CNTL__SI = 0x1967; +constexpr unsigned int mmBL_PWM_GRP1_REG_LOCK__SI = 0x196A; +constexpr unsigned int mmBL_PWM_PERIOD_CNTL__SI = 0x1969; +constexpr unsigned int mmBUS_CNTL = 0x1508; +constexpr unsigned int mmBX_RESET_EN__CI__VI = 0x1514; +constexpr unsigned int mmCAPTURE_HOST_BUSNUM = 0x153C; +constexpr unsigned int mmCB_BLEND0_CONTROL = 0xA1E0; +constexpr unsigned int mmCB_BLEND1_CONTROL = 0xA1E1; +constexpr unsigned int mmCB_BLEND2_CONTROL = 0xA1E2; +constexpr unsigned int mmCB_BLEND3_CONTROL = 0xA1E3; +constexpr unsigned int mmCB_BLEND4_CONTROL = 0xA1E4; +constexpr unsigned int mmCB_BLEND5_CONTROL = 0xA1E5; +constexpr unsigned int mmCB_BLEND6_CONTROL = 0xA1E6; +constexpr unsigned int mmCB_BLEND7_CONTROL = 0xA1E7; +constexpr unsigned int mmCB_BLEND_ALPHA = 0xA108; +constexpr unsigned int mmCB_BLEND_BLUE = 0xA107; +constexpr unsigned int mmCB_BLEND_GREEN = 0xA106; +constexpr unsigned int mmCB_BLEND_RED = 0xA105; +constexpr unsigned int mmCB_CGTT_SCLK_CTRL__CI__VI = 0xF0A8; +constexpr unsigned int mmCB_CGTT_SCLK_CTRL__SI = 0x2698; +constexpr unsigned int mmCB_COLOR0_ATTRIB = 0xA31D; +constexpr unsigned int mmCB_COLOR0_BASE = 0xA318; +constexpr unsigned int mmCB_COLOR0_CLEAR_WORD0 = 0xA323; +constexpr unsigned int mmCB_COLOR0_CLEAR_WORD1 = 0xA324; +constexpr unsigned int mmCB_COLOR0_CMASK = 0xA31F; +constexpr unsigned int mmCB_COLOR0_CMASK_SLICE = 0xA320; +constexpr unsigned int mmCB_COLOR0_FMASK = 0xA321; +constexpr unsigned int mmCB_COLOR0_FMASK_SLICE = 0xA322; +constexpr unsigned int mmCB_COLOR0_INFO = 0xA31C; +constexpr unsigned int mmCB_COLOR0_PITCH = 0xA319; +constexpr unsigned int mmCB_COLOR0_SLICE = 0xA31A; +constexpr unsigned int mmCB_COLOR0_VIEW = 0xA31B; +constexpr unsigned int mmCB_COLOR1_ATTRIB = 0xA32C; +constexpr unsigned int mmCB_COLOR1_BASE = 0xA327; +constexpr unsigned int mmCB_COLOR1_CLEAR_WORD0 = 0xA332; +constexpr unsigned int mmCB_COLOR1_CLEAR_WORD1 = 0xA333; +constexpr unsigned int mmCB_COLOR1_CMASK = 0xA32E; +constexpr unsigned int mmCB_COLOR1_CMASK_SLICE = 0xA32F; +constexpr unsigned int mmCB_COLOR1_FMASK = 0xA330; +constexpr unsigned int mmCB_COLOR1_FMASK_SLICE = 0xA331; +constexpr unsigned int mmCB_COLOR1_INFO = 0xA32B; +constexpr unsigned int mmCB_COLOR1_PITCH = 0xA328; +constexpr unsigned int mmCB_COLOR1_SLICE = 0xA329; +constexpr unsigned int mmCB_COLOR1_VIEW = 0xA32A; +constexpr unsigned int mmCB_COLOR2_ATTRIB = 0xA33B; +constexpr unsigned int mmCB_COLOR2_BASE = 0xA336; +constexpr unsigned int mmCB_COLOR2_CLEAR_WORD0 = 0xA341; +constexpr unsigned int mmCB_COLOR2_CLEAR_WORD1 = 0xA342; +constexpr unsigned int mmCB_COLOR2_CMASK = 0xA33D; +constexpr unsigned int mmCB_COLOR2_CMASK_SLICE = 0xA33E; +constexpr unsigned int mmCB_COLOR2_FMASK = 0xA33F; +constexpr unsigned int mmCB_COLOR2_FMASK_SLICE = 0xA340; +constexpr unsigned int mmCB_COLOR2_INFO = 0xA33A; +constexpr unsigned int mmCB_COLOR2_PITCH = 0xA337; +constexpr unsigned int mmCB_COLOR2_SLICE = 0xA338; +constexpr unsigned int mmCB_COLOR2_VIEW = 0xA339; +constexpr unsigned int mmCB_COLOR3_ATTRIB = 0xA34A; +constexpr unsigned int mmCB_COLOR3_BASE = 0xA345; +constexpr unsigned int mmCB_COLOR3_CLEAR_WORD0 = 0xA350; +constexpr unsigned int mmCB_COLOR3_CLEAR_WORD1 = 0xA351; +constexpr unsigned int mmCB_COLOR3_CMASK = 0xA34C; +constexpr unsigned int mmCB_COLOR3_CMASK_SLICE = 0xA34D; +constexpr unsigned int mmCB_COLOR3_FMASK = 0xA34E; +constexpr unsigned int mmCB_COLOR3_FMASK_SLICE = 0xA34F; +constexpr unsigned int mmCB_COLOR3_INFO = 0xA349; +constexpr unsigned int mmCB_COLOR3_PITCH = 0xA346; +constexpr unsigned int mmCB_COLOR3_SLICE = 0xA347; +constexpr unsigned int mmCB_COLOR3_VIEW = 0xA348; +constexpr unsigned int mmCB_COLOR4_ATTRIB = 0xA359; +constexpr unsigned int mmCB_COLOR4_BASE = 0xA354; +constexpr unsigned int mmCB_COLOR4_CLEAR_WORD0 = 0xA35F; +constexpr unsigned int mmCB_COLOR4_CLEAR_WORD1 = 0xA360; +constexpr unsigned int mmCB_COLOR4_CMASK = 0xA35B; +constexpr unsigned int mmCB_COLOR4_CMASK_SLICE = 0xA35C; +constexpr unsigned int mmCB_COLOR4_FMASK = 0xA35D; +constexpr unsigned int mmCB_COLOR4_FMASK_SLICE = 0xA35E; +constexpr unsigned int mmCB_COLOR4_INFO = 0xA358; +constexpr unsigned int mmCB_COLOR4_PITCH = 0xA355; +constexpr unsigned int mmCB_COLOR4_SLICE = 0xA356; +constexpr unsigned int mmCB_COLOR4_VIEW = 0xA357; +constexpr unsigned int mmCB_COLOR5_ATTRIB = 0xA368; +constexpr unsigned int mmCB_COLOR5_BASE = 0xA363; +constexpr unsigned int mmCB_COLOR5_CLEAR_WORD0 = 0xA36E; +constexpr unsigned int mmCB_COLOR5_CLEAR_WORD1 = 0xA36F; +constexpr unsigned int mmCB_COLOR5_CMASK = 0xA36A; +constexpr unsigned int mmCB_COLOR5_CMASK_SLICE = 0xA36B; +constexpr unsigned int mmCB_COLOR5_FMASK = 0xA36C; +constexpr unsigned int mmCB_COLOR5_FMASK_SLICE = 0xA36D; +constexpr unsigned int mmCB_COLOR5_INFO = 0xA367; +constexpr unsigned int mmCB_COLOR5_PITCH = 0xA364; +constexpr unsigned int mmCB_COLOR5_SLICE = 0xA365; +constexpr unsigned int mmCB_COLOR5_VIEW = 0xA366; +constexpr unsigned int mmCB_COLOR6_ATTRIB = 0xA377; +constexpr unsigned int mmCB_COLOR6_BASE = 0xA372; +constexpr unsigned int mmCB_COLOR6_CLEAR_WORD0 = 0xA37D; +constexpr unsigned int mmCB_COLOR6_CLEAR_WORD1 = 0xA37E; +constexpr unsigned int mmCB_COLOR6_CMASK = 0xA379; +constexpr unsigned int mmCB_COLOR6_CMASK_SLICE = 0xA37A; +constexpr unsigned int mmCB_COLOR6_FMASK = 0xA37B; +constexpr unsigned int mmCB_COLOR6_FMASK_SLICE = 0xA37C; +constexpr unsigned int mmCB_COLOR6_INFO = 0xA376; +constexpr unsigned int mmCB_COLOR6_PITCH = 0xA373; +constexpr unsigned int mmCB_COLOR6_SLICE = 0xA374; +constexpr unsigned int mmCB_COLOR6_VIEW = 0xA375; +constexpr unsigned int mmCB_COLOR7_ATTRIB = 0xA386; +constexpr unsigned int mmCB_COLOR7_BASE = 0xA381; +constexpr unsigned int mmCB_COLOR7_CLEAR_WORD0 = 0xA38C; +constexpr unsigned int mmCB_COLOR7_CLEAR_WORD1 = 0xA38D; +constexpr unsigned int mmCB_COLOR7_CMASK = 0xA388; +constexpr unsigned int mmCB_COLOR7_CMASK_SLICE = 0xA389; +constexpr unsigned int mmCB_COLOR7_FMASK = 0xA38A; +constexpr unsigned int mmCB_COLOR7_FMASK_SLICE = 0xA38B; +constexpr unsigned int mmCB_COLOR7_INFO = 0xA385; +constexpr unsigned int mmCB_COLOR7_PITCH = 0xA382; +constexpr unsigned int mmCB_COLOR7_SLICE = 0xA383; +constexpr unsigned int mmCB_COLOR7_VIEW = 0xA384; +constexpr unsigned int mmCB_COLOR_CONTROL = 0xA202; +constexpr unsigned int mmCB_DEBUG_BUS_1 = 0x2699; +constexpr unsigned int mmCB_DEBUG_BUS_13 = 0x26A5; +constexpr unsigned int mmCB_DEBUG_BUS_14 = 0x26A6; +constexpr unsigned int mmCB_DEBUG_BUS_15 = 0x26A7; +constexpr unsigned int mmCB_DEBUG_BUS_16 = 0x26A8; +constexpr unsigned int mmCB_DEBUG_BUS_17 = 0x26A9; +constexpr unsigned int mmCB_DEBUG_BUS_18 = 0x26AA; +constexpr unsigned int mmCB_DEBUG_BUS_2 = 0x269A; +constexpr unsigned int mmCB_HW_CONTROL = 0x2684; +constexpr unsigned int mmCB_HW_CONTROL_1 = 0x2685; +constexpr unsigned int mmCB_HW_CONTROL_2 = 0x2686; +constexpr unsigned int mmCB_HW_CONTROL_3__CI__VI = 0x2683; +constexpr unsigned int mmCB_PERFCOUNTER0_HI__CI__VI = 0xD407; +constexpr unsigned int mmCB_PERFCOUNTER0_HI__SI = 0x2691; +constexpr unsigned int mmCB_PERFCOUNTER0_LO__CI__VI = 0xD406; +constexpr unsigned int mmCB_PERFCOUNTER0_LO__SI = 0x2690; +constexpr unsigned int mmCB_PERFCOUNTER0_SELECT0__SI = 0x2688; +constexpr unsigned int mmCB_PERFCOUNTER0_SELECT1__CI__VI = 0xDC02; +constexpr unsigned int mmCB_PERFCOUNTER0_SELECT1__SI = 0x2689; +constexpr unsigned int mmCB_PERFCOUNTER0_SELECT__CI__VI = 0xDC01; +constexpr unsigned int mmCB_PERFCOUNTER1_HI__CI__VI = 0xD409; +constexpr unsigned int mmCB_PERFCOUNTER1_HI__SI = 0x2693; +constexpr unsigned int mmCB_PERFCOUNTER1_LO__CI__VI = 0xD408; +constexpr unsigned int mmCB_PERFCOUNTER1_LO__SI = 0x2692; +constexpr unsigned int mmCB_PERFCOUNTER1_SELECT0__SI = 0x268A; +constexpr unsigned int mmCB_PERFCOUNTER1_SELECT1__SI = 0x268B; +constexpr unsigned int mmCB_PERFCOUNTER1_SELECT__CI__VI = 0xDC03; +constexpr unsigned int mmCB_PERFCOUNTER2_HI__CI__VI = 0xD40B; +constexpr unsigned int mmCB_PERFCOUNTER2_HI__SI = 0x2695; +constexpr unsigned int mmCB_PERFCOUNTER2_LO__CI__VI = 0xD40A; +constexpr unsigned int mmCB_PERFCOUNTER2_LO__SI = 0x2694; +constexpr unsigned int mmCB_PERFCOUNTER2_SELECT0__SI = 0x268C; +constexpr unsigned int mmCB_PERFCOUNTER2_SELECT1__SI = 0x268D; +constexpr unsigned int mmCB_PERFCOUNTER2_SELECT__CI__VI = 0xDC04; +constexpr unsigned int mmCB_PERFCOUNTER3_HI__CI__VI = 0xD40D; +constexpr unsigned int mmCB_PERFCOUNTER3_HI__SI = 0x2697; +constexpr unsigned int mmCB_PERFCOUNTER3_LO__CI__VI = 0xD40C; +constexpr unsigned int mmCB_PERFCOUNTER3_LO__SI = 0x2696; +constexpr unsigned int mmCB_PERFCOUNTER3_SELECT0__SI = 0x268E; +constexpr unsigned int mmCB_PERFCOUNTER3_SELECT1__SI = 0x268F; +constexpr unsigned int mmCB_PERFCOUNTER3_SELECT__CI__VI = 0xDC05; +constexpr unsigned int mmCB_PERFCOUNTER_FILTER__CI__VI = 0xDC00; +constexpr unsigned int mmCB_SHADER_MASK = 0xA08F; +constexpr unsigned int mmCB_TARGET_MASK = 0xA08E; +constexpr unsigned int mmCC_DRM_ID_STRAPS = 0x1559; +constexpr unsigned int mmCC_GC_EDC_CONFIG__CI__VI = 0x3098; +constexpr unsigned int mmCC_GC_PRIM_CONFIG__CI__VI = 0x2240; +constexpr unsigned int mmCC_GC_SHADER_ARRAY_CONFIG = 0x226F; +constexpr unsigned int mmCC_MC_MAX_CHANNEL = 0x096E; +constexpr unsigned int mmCC_RB_BACKEND_DISABLE = 0x263D; +constexpr unsigned int mmCC_RB_DAISY_CHAIN = 0x2641; +constexpr unsigned int mmCC_RB_REDUNDANCY = 0x263C; +constexpr unsigned int mmCC_SQC_BANK_DISABLE = 0x2307; +constexpr unsigned int mmCC_SYS_RB_BACKEND_DISABLE = 0x03A0; +constexpr unsigned int mmCC_SYS_RB_REDUNDANCY = 0x039F; +constexpr unsigned int mmCGTS_CU0_LDS_SQ_CTRL_REG__CI__VI = 0xF009; +constexpr unsigned int mmCGTS_CU0_SP0_CTRL_REG__CI__VI = 0xF008; +constexpr unsigned int mmCGTS_CU0_SP1_CTRL_REG__CI__VI = 0xF00B; +constexpr unsigned int mmCGTS_CU0_TA_SQC_CTRL_REG__CI__VI = 0xF00A; +constexpr unsigned int mmCGTS_CU0_TD_TCP_CTRL_REG__CI__VI = 0xF00C; +constexpr unsigned int mmCGTS_CU10_LDS_SQ_CTRL_REG__CI__VI = 0xF03B; +constexpr unsigned int mmCGTS_CU10_SP0_CTRL_REG__CI__VI = 0xF03A; +constexpr unsigned int mmCGTS_CU10_SP1_CTRL_REG__CI__VI = 0xF03D; +constexpr unsigned int mmCGTS_CU10_TA_CTRL_REG__CI__VI = 0xF03C; +constexpr unsigned int mmCGTS_CU10_TD_TCP_CTRL_REG__CI__VI = 0xF03E; +constexpr unsigned int mmCGTS_CU11_LDS_SQ_CTRL_REG__CI__VI = 0xF040; +constexpr unsigned int mmCGTS_CU11_SP0_CTRL_REG__CI__VI = 0xF03F; +constexpr unsigned int mmCGTS_CU11_SP1_CTRL_REG__CI__VI = 0xF042; +constexpr unsigned int mmCGTS_CU11_TA_CTRL_REG__CI__VI = 0xF041; +constexpr unsigned int mmCGTS_CU11_TD_TCP_CTRL_REG__CI__VI = 0xF043; +constexpr unsigned int mmCGTS_CU12_LDS_SQ_CTRL_REG__CI__VI = 0xF045; +constexpr unsigned int mmCGTS_CU12_SP0_CTRL_REG__CI__VI = 0xF044; +constexpr unsigned int mmCGTS_CU12_SP1_CTRL_REG__CI__VI = 0xF047; +constexpr unsigned int mmCGTS_CU12_TA_SQC_CTRL_REG__CI__VI = 0xF046; +constexpr unsigned int mmCGTS_CU12_TD_TCP_CTRL_REG__CI__VI = 0xF048; +constexpr unsigned int mmCGTS_CU13_LDS_SQ_CTRL_REG__CI__VI = 0xF04A; +constexpr unsigned int mmCGTS_CU13_SP0_CTRL_REG__CI__VI = 0xF049; +constexpr unsigned int mmCGTS_CU13_SP1_CTRL_REG__CI__VI = 0xF04C; +constexpr unsigned int mmCGTS_CU13_TA_CTRL_REG__CI__VI = 0xF04B; +constexpr unsigned int mmCGTS_CU13_TD_TCP_CTRL_REG__CI__VI = 0xF04D; +constexpr unsigned int mmCGTS_CU14_LDS_SQ_CTRL_REG__CI__VI = 0xF04F; +constexpr unsigned int mmCGTS_CU14_SP0_CTRL_REG__CI__VI = 0xF04E; +constexpr unsigned int mmCGTS_CU14_SP1_CTRL_REG__CI__VI = 0xF051; +constexpr unsigned int mmCGTS_CU14_TA_CTRL_REG__CI__VI = 0xF050; +constexpr unsigned int mmCGTS_CU14_TD_TCP_CTRL_REG__CI__VI = 0xF052; +constexpr unsigned int mmCGTS_CU15_LDS_SQ_CTRL_REG__CI__VI = 0xF054; +constexpr unsigned int mmCGTS_CU15_SP0_CTRL_REG__CI__VI = 0xF053; +constexpr unsigned int mmCGTS_CU15_SP1_CTRL_REG__CI__VI = 0xF056; +constexpr unsigned int mmCGTS_CU15_TA_CTRL_REG__CI__VI = 0xF055; +constexpr unsigned int mmCGTS_CU15_TD_TCP_CTRL_REG__CI__VI = 0xF057; +constexpr unsigned int mmCGTS_CU1_LDS_SQ_CTRL_REG__CI__VI = 0xF00E; +constexpr unsigned int mmCGTS_CU1_SP0_CTRL_REG__CI__VI = 0xF00D; +constexpr unsigned int mmCGTS_CU1_SP1_CTRL_REG__CI__VI = 0xF010; +constexpr unsigned int mmCGTS_CU1_TA_CTRL_REG__CI__VI = 0xF00F; +constexpr unsigned int mmCGTS_CU1_TD_TCP_CTRL_REG__CI__VI = 0xF011; +constexpr unsigned int mmCGTS_CU2_LDS_SQ_CTRL_REG__CI__VI = 0xF013; +constexpr unsigned int mmCGTS_CU2_SP0_CTRL_REG__CI__VI = 0xF012; +constexpr unsigned int mmCGTS_CU2_SP1_CTRL_REG__CI__VI = 0xF015; +constexpr unsigned int mmCGTS_CU2_TA_CTRL_REG__CI__VI = 0xF014; +constexpr unsigned int mmCGTS_CU2_TD_TCP_CTRL_REG__CI__VI = 0xF016; +constexpr unsigned int mmCGTS_CU3_LDS_SQ_CTRL_REG__CI__VI = 0xF018; +constexpr unsigned int mmCGTS_CU3_SP0_CTRL_REG__CI__VI = 0xF017; +constexpr unsigned int mmCGTS_CU3_SP1_CTRL_REG__CI__VI = 0xF01A; +constexpr unsigned int mmCGTS_CU3_TA_CTRL_REG__CI__VI = 0xF019; +constexpr unsigned int mmCGTS_CU3_TD_TCP_CTRL_REG__CI__VI = 0xF01B; +constexpr unsigned int mmCGTS_CU4_LDS_SQ_CTRL_REG__CI__VI = 0xF01D; +constexpr unsigned int mmCGTS_CU4_SP0_CTRL_REG__CI__VI = 0xF01C; +constexpr unsigned int mmCGTS_CU4_SP1_CTRL_REG__CI__VI = 0xF01F; +constexpr unsigned int mmCGTS_CU4_TA_SQC_CTRL_REG__CI__VI = 0xF01E; +constexpr unsigned int mmCGTS_CU4_TD_TCP_CTRL_REG__CI__VI = 0xF020; +constexpr unsigned int mmCGTS_CU5_LDS_SQ_CTRL_REG__CI__VI = 0xF022; +constexpr unsigned int mmCGTS_CU5_SP0_CTRL_REG__CI__VI = 0xF021; +constexpr unsigned int mmCGTS_CU5_SP1_CTRL_REG__CI__VI = 0xF024; +constexpr unsigned int mmCGTS_CU5_TA_CTRL_REG__CI__VI = 0xF023; +constexpr unsigned int mmCGTS_CU5_TD_TCP_CTRL_REG__CI__VI = 0xF025; +constexpr unsigned int mmCGTS_CU6_LDS_SQ_CTRL_REG__CI__VI = 0xF027; +constexpr unsigned int mmCGTS_CU6_SP0_CTRL_REG__CI__VI = 0xF026; +constexpr unsigned int mmCGTS_CU6_SP1_CTRL_REG__CI__VI = 0xF029; +constexpr unsigned int mmCGTS_CU6_TA_CTRL_REG__CI__VI = 0xF028; +constexpr unsigned int mmCGTS_CU6_TD_TCP_CTRL_REG__CI__VI = 0xF02A; +constexpr unsigned int mmCGTS_CU7_LDS_SQ_CTRL_REG__CI__VI = 0xF02C; +constexpr unsigned int mmCGTS_CU7_SP0_CTRL_REG__CI__VI = 0xF02B; +constexpr unsigned int mmCGTS_CU7_SP1_CTRL_REG__CI__VI = 0xF02E; +constexpr unsigned int mmCGTS_CU7_TA_CTRL_REG__CI__VI = 0xF02D; +constexpr unsigned int mmCGTS_CU7_TD_TCP_CTRL_REG__CI__VI = 0xF02F; +constexpr unsigned int mmCGTS_CU8_LDS_SQ_CTRL_REG__CI__VI = 0xF031; +constexpr unsigned int mmCGTS_CU8_SP0_CTRL_REG__CI__VI = 0xF030; +constexpr unsigned int mmCGTS_CU8_SP1_CTRL_REG__CI__VI = 0xF033; +constexpr unsigned int mmCGTS_CU8_TA_SQC_CTRL_REG__CI__VI = 0xF032; +constexpr unsigned int mmCGTS_CU8_TD_TCP_CTRL_REG__CI__VI = 0xF034; +constexpr unsigned int mmCGTS_CU9_LDS_SQ_CTRL_REG__CI__VI = 0xF036; +constexpr unsigned int mmCGTS_CU9_SP0_CTRL_REG__CI__VI = 0xF035; +constexpr unsigned int mmCGTS_CU9_SP1_CTRL_REG__CI__VI = 0xF038; +constexpr unsigned int mmCGTS_CU9_TA_CTRL_REG__CI__VI = 0xF037; +constexpr unsigned int mmCGTS_CU9_TD_TCP_CTRL_REG__CI__VI = 0xF039; +constexpr unsigned int mmCGTS_RD_CTRL_REG__CI__VI = 0xF001; +constexpr unsigned int mmCGTS_RD_CTRL_REG__SI = 0x2455; +constexpr unsigned int mmCGTS_RD_REG__CI__VI = 0xF002; +constexpr unsigned int mmCGTS_RD_REG__SI = 0x2456; +constexpr unsigned int mmCGTS_SM_CTRL_REG__CI__VI = 0xF000; +constexpr unsigned int mmCGTS_SM_CTRL_REG__SI = 0x2454; +constexpr unsigned int mmCGTS_TCC_DISABLE__CI__VI = 0xF003; +constexpr unsigned int mmCGTS_TCC_DISABLE__SI = 0x2452; +constexpr unsigned int mmCGTS_USER_TCC_DISABLE__CI__VI = 0xF004; +constexpr unsigned int mmCGTS_USER_TCC_DISABLE__SI = 0x2453; +constexpr unsigned int mmCGTT_BCI_CLK_CTRL__CI__VI = 0xF082; +constexpr unsigned int mmCGTT_BCI_CLK_CTRL__SI = 0x24A9; +constexpr unsigned int mmCGTT_CPC_CLK_CTRL__CI__VI = 0xF0B2; +constexpr unsigned int mmCGTT_CPF_CLK_CTRL__CI__VI = 0xF0B1; +constexpr unsigned int mmCGTT_CP_CLK_CTRL__CI__VI = 0xF0B0; +constexpr unsigned int mmCGTT_CP_CLK_CTRL__SI = 0x3059; +constexpr unsigned int mmCGTT_GDS_CLK_CTRL__CI__VI = 0xF0A0; +constexpr unsigned int mmCGTT_GDS_CLK_CTRL__SI = 0x25DD; +constexpr unsigned int mmCGTT_IA_CLK_CTRL__CI__VI = 0xF085; +constexpr unsigned int mmCGTT_IA_CLK_CTRL__SI = 0x2261; +constexpr unsigned int mmCGTT_PA_CLK_CTRL__CI__VI = 0xF088; +constexpr unsigned int mmCGTT_PA_CLK_CTRL__SI = 0x2286; +constexpr unsigned int mmCGTT_PC_CLK_CTRL__CI__VI = 0xF081; +constexpr unsigned int mmCGTT_PC_CLK_CTRL__SI = 0x24A8; +constexpr unsigned int mmCGTT_RLC_CLK_CTRL__CI__VI = 0xF0B8; +constexpr unsigned int mmCGTT_RLC_CLK_CTRL__SI = 0x30E0; +constexpr unsigned int mmCGTT_ROM_CLK_CTRL0__SI = 0x0583; +constexpr unsigned int mmCGTT_SC_CLK_CTRL__CI__VI = 0xF089; +constexpr unsigned int mmCGTT_SC_CLK_CTRL__SI = 0x22CA; +constexpr unsigned int mmCGTT_SPI_CLK_CTRL__CI__VI = 0xF080; +constexpr unsigned int mmCGTT_SPI_CLK_CTRL__SI = 0x2451; +constexpr unsigned int mmCGTT_SQG_CLK_CTRL__CI__VI = 0xF08D; +constexpr unsigned int mmCGTT_SQG_CLK_CTRL__SI = 0x2363; +constexpr unsigned int mmCGTT_SQ_CLK_CTRL__CI__VI = 0xF08C; +constexpr unsigned int mmCGTT_SQ_CLK_CTRL__SI = 0x2362; +constexpr unsigned int mmCGTT_SX_CLK_CTRL0__CI__VI = 0xF094; +constexpr unsigned int mmCGTT_SX_CLK_CTRL0__SI = 0x240C; +constexpr unsigned int mmCGTT_SX_CLK_CTRL1__CI__VI = 0xF095; +constexpr unsigned int mmCGTT_SX_CLK_CTRL1__SI = 0x240D; +constexpr unsigned int mmCGTT_SX_CLK_CTRL2__CI__VI = 0xF096; +constexpr unsigned int mmCGTT_SX_CLK_CTRL2__SI = 0x240E; +constexpr unsigned int mmCGTT_SX_CLK_CTRL3__CI__VI = 0xF097; +constexpr unsigned int mmCGTT_SX_CLK_CTRL3__SI = 0x240F; +constexpr unsigned int mmCGTT_SX_CLK_CTRL4__CI__VI = 0xF098; +constexpr unsigned int mmCGTT_SX_CLK_CTRL4__SI = 0x2410; +constexpr unsigned int mmCGTT_TCI_CLK_CTRL__CI__VI = 0xF09F; +constexpr unsigned int mmCGTT_TCI_CLK_CTRL__SI = 0x2B60; +constexpr unsigned int mmCGTT_TCP_CLK_CTRL__CI__VI = 0xF09E; +constexpr unsigned int mmCGTT_TCP_CLK_CTRL__SI = 0x2B15; +constexpr unsigned int mmCGTT_VGT_CLK_CTRL__CI__VI = 0xF084; +constexpr unsigned int mmCGTT_VGT_CLK_CTRL__SI = 0x225F; +constexpr unsigned int mmCGTT_WD_CLK_CTRL__CI__VI = 0xF086; +constexpr unsigned int mmCG_CLKPIN_CNTL__SI = 0x0198; +constexpr unsigned int mmCG_DISPLAY_GAP_CNTL__SI = 0x020A; +constexpr unsigned int mmCG_FDO_CTRL0__SI = 0x01D5; +constexpr unsigned int mmCG_FDO_CTRL1__SI = 0x01D6; +constexpr unsigned int mmCG_FDO_CTRL2__SI = 0x01D7; +constexpr unsigned int mmCG_FPS_CNT__CI = 0x0194; +constexpr unsigned int mmCG_FREQ_TRAN_VOTING__SI = 0x01EF; +constexpr unsigned int mmCG_MULT_THERMAL_CTRL__SI = 0x01C4; +constexpr unsigned int mmCG_MULT_THERMAL_STATUS__SI = 0x01C5; +constexpr unsigned int mmCG_SPLL_FUNC_CNTL_2__SI = 0x0181; +constexpr unsigned int mmCG_SPLL_FUNC_CNTL_3__SI = 0x0182; +constexpr unsigned int mmCG_SPLL_FUNC_CNTL_4__SI = 0x0183; +constexpr unsigned int mmCG_SPLL_FUNC_CNTL_5__SI = 0x0184; +constexpr unsigned int mmCG_SPLL_FUNC_CNTL__SI = 0x0180; +constexpr unsigned int mmCG_SPLL_SPREAD_SPECTRUM_2__SI = 0x0189; +constexpr unsigned int mmCG_SPLL_SPREAD_SPECTRUM__SI = 0x0188; +constexpr unsigned int mmCG_STATIC_SCREEN_PARAMETER__SI = 0x0203; +constexpr unsigned int mmCG_TACH_CTRL__SI = 0x01DC; +constexpr unsigned int mmCG_TACH_STATUS__SI = 0x01DD; +constexpr unsigned int mmCG_THERMAL_CTRL__SI = 0x01C0; +constexpr unsigned int mmCG_THERMAL_INT__SI = 0x01C2; +constexpr unsigned int mmCG_THERMAL_STATUS__SI = 0x01C1; +constexpr unsigned int mmCG_ULV_PARAMETER__SI = 0x021F; +constexpr unsigned int mmCHUB_ATC_PERFCOUNTER0_CFG__CI__VI = 0x07D8; +constexpr unsigned int mmCHUB_ATC_PERFCOUNTER1_CFG__CI__VI = 0x07D9; +constexpr unsigned int mmCHUB_ATC_PERFCOUNTER_HI__CI__VI = 0x07D7; +constexpr unsigned int mmCHUB_ATC_PERFCOUNTER_LO__CI__VI = 0x07D6; +constexpr unsigned int mmCHUB_ATC_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07DA; +constexpr unsigned int mmCLKREQB_PAD_CNTL__CI__VI = 0x1521; +constexpr unsigned int mmCOHER_DEST_BASE_0 = 0xA092; +constexpr unsigned int mmCOHER_DEST_BASE_1 = 0xA093; +constexpr unsigned int mmCOHER_DEST_BASE_2 = 0xA07E; +constexpr unsigned int mmCOHER_DEST_BASE_3 = 0xA07F; +constexpr unsigned int mmCOHER_DEST_BASE_HI_0__CI__VI = 0xA07A; +constexpr unsigned int mmCOHER_DEST_BASE_HI_1__CI__VI = 0xA07B; +constexpr unsigned int mmCOHER_DEST_BASE_HI_2__CI__VI = 0xA07C; +constexpr unsigned int mmCOHER_DEST_BASE_HI_3__CI__VI = 0xA07D; +constexpr unsigned int mmCOMPUTE_DIM_X = 0x2E01; +constexpr unsigned int mmCOMPUTE_DIM_Y = 0x2E02; +constexpr unsigned int mmCOMPUTE_DIM_Z = 0x2E03; +constexpr unsigned int mmCOMPUTE_DISPATCH_INITIATOR = 0x2E00; +constexpr unsigned int mmCOMPUTE_MISC_RESERVED__CI__VI = 0x2E1F; +constexpr unsigned int mmCOMPUTE_NUM_THREAD_X = 0x2E07; +constexpr unsigned int mmCOMPUTE_NUM_THREAD_Y = 0x2E08; +constexpr unsigned int mmCOMPUTE_NUM_THREAD_Z = 0x2E09; +constexpr unsigned int mmCOMPUTE_PERFCOUNT_ENABLE__CI__VI = 0x2E0B; +constexpr unsigned int mmCOMPUTE_PGM_HI = 0x2E0D; +constexpr unsigned int mmCOMPUTE_PGM_LO = 0x2E0C; +constexpr unsigned int mmCOMPUTE_PGM_RSRC1 = 0x2E12; +constexpr unsigned int mmCOMPUTE_PGM_RSRC2 = 0x2E13; +constexpr unsigned int mmCOMPUTE_PIPELINESTAT_ENABLE__CI__VI = 0x2E0A; +constexpr unsigned int mmCOMPUTE_RESOURCE_LIMITS = 0x2E15; +constexpr unsigned int mmCOMPUTE_RESTART_X__CI__VI = 0x2E1B; +constexpr unsigned int mmCOMPUTE_RESTART_Y__CI__VI = 0x2E1C; +constexpr unsigned int mmCOMPUTE_RESTART_Z__CI__VI = 0x2E1D; +constexpr unsigned int mmCOMPUTE_START_X = 0x2E04; +constexpr unsigned int mmCOMPUTE_START_Y = 0x2E05; +constexpr unsigned int mmCOMPUTE_START_Z = 0x2E06; +constexpr unsigned int mmCOMPUTE_STATIC_THREAD_MGMT_SE0 = 0x2E16; +constexpr unsigned int mmCOMPUTE_STATIC_THREAD_MGMT_SE1 = 0x2E17; +constexpr unsigned int mmCOMPUTE_STATIC_THREAD_MGMT_SE2__CI__VI = 0x2E19; +constexpr unsigned int mmCOMPUTE_STATIC_THREAD_MGMT_SE3__CI__VI = 0x2E1A; +constexpr unsigned int mmCOMPUTE_TBA_HI = 0x2E0F; +constexpr unsigned int mmCOMPUTE_TBA_LO = 0x2E0E; +constexpr unsigned int mmCOMPUTE_THREAD_TRACE_ENABLE__CI__VI = 0x2E1E; +constexpr unsigned int mmCOMPUTE_TMA_HI = 0x2E11; +constexpr unsigned int mmCOMPUTE_TMA_LO = 0x2E10; +constexpr unsigned int mmCOMPUTE_TMPRING_SIZE = 0x2E18; +constexpr unsigned int mmCOMPUTE_USER_DATA_0 = 0x2E40; +constexpr unsigned int mmCOMPUTE_USER_DATA_1 = 0x2E41; +constexpr unsigned int mmCOMPUTE_USER_DATA_10 = 0x2E4A; +constexpr unsigned int mmCOMPUTE_USER_DATA_11 = 0x2E4B; +constexpr unsigned int mmCOMPUTE_USER_DATA_12 = 0x2E4C; +constexpr unsigned int mmCOMPUTE_USER_DATA_13 = 0x2E4D; +constexpr unsigned int mmCOMPUTE_USER_DATA_14 = 0x2E4E; +constexpr unsigned int mmCOMPUTE_USER_DATA_15 = 0x2E4F; +constexpr unsigned int mmCOMPUTE_USER_DATA_2 = 0x2E42; +constexpr unsigned int mmCOMPUTE_USER_DATA_3 = 0x2E43; +constexpr unsigned int mmCOMPUTE_USER_DATA_4 = 0x2E44; +constexpr unsigned int mmCOMPUTE_USER_DATA_5 = 0x2E45; +constexpr unsigned int mmCOMPUTE_USER_DATA_6 = 0x2E46; +constexpr unsigned int mmCOMPUTE_USER_DATA_7 = 0x2E47; +constexpr unsigned int mmCOMPUTE_USER_DATA_8 = 0x2E48; +constexpr unsigned int mmCOMPUTE_USER_DATA_9 = 0x2E49; +constexpr unsigned int mmCOMPUTE_VMID = 0x2E14; +constexpr unsigned int mmCONFIG_APER_SIZE = 0x150C; +constexpr unsigned int mmCONFIG_CNTL = 0x1509; +constexpr unsigned int mmCONFIG_F0_BASE = 0x150B; +constexpr unsigned int mmCONFIG_MEMSIZE = 0x150A; +constexpr unsigned int mmCONFIG_REG_APER_SIZE = 0x150D; +constexpr unsigned int mmCPC1_CONFIG__CI = 0x0F97; +constexpr unsigned int mmCPC2_CONFIG__CI = 0x0F98; +constexpr unsigned int mmCPC_INT_CNTL__CI__VI = 0x30B4; +constexpr unsigned int mmCPC_INT_CNTX_ID__CI__VI = 0x30B7; +constexpr unsigned int mmCPC_INT_STATUS__CI__VI = 0x30B5; +constexpr unsigned int mmCPC_PERFCOUNTER0_HI__CI__VI = 0xD007; +constexpr unsigned int mmCPC_PERFCOUNTER0_LO__CI__VI = 0xD006; +constexpr unsigned int mmCPC_PERFCOUNTER0_SELECT1__CI__VI = 0xD804; +constexpr unsigned int mmCPC_PERFCOUNTER0_SELECT__CI__VI = 0xD809; +constexpr unsigned int mmCPC_PERFCOUNTER1_HI__CI__VI = 0xD005; +constexpr unsigned int mmCPC_PERFCOUNTER1_LO__CI__VI = 0xD004; +constexpr unsigned int mmCPC_PERFCOUNTER1_SELECT__CI__VI = 0xD803; +constexpr unsigned int mmCPF_PERFCOUNTER0_HI__CI__VI = 0xD00B; +constexpr unsigned int mmCPF_PERFCOUNTER0_LO__CI__VI = 0xD00A; +constexpr unsigned int mmCPF_PERFCOUNTER0_SELECT1__CI__VI = 0xD806; +constexpr unsigned int mmCPF_PERFCOUNTER0_SELECT__CI__VI = 0xD807; +constexpr unsigned int mmCPF_PERFCOUNTER1_HI__CI__VI = 0xD009; +constexpr unsigned int mmCPF_PERFCOUNTER1_LO__CI__VI = 0xD008; +constexpr unsigned int mmCPF_PERFCOUNTER1_SELECT__CI__VI = 0xD805; +constexpr unsigned int mmCPG_CONFIG__CI = 0x0F96; +constexpr unsigned int mmCPG_PERFCOUNTER0_HI__CI__VI = 0xD003; +constexpr unsigned int mmCPG_PERFCOUNTER0_LO__CI__VI = 0xD002; +constexpr unsigned int mmCPG_PERFCOUNTER0_SELECT1__CI__VI = 0xD801; +constexpr unsigned int mmCPG_PERFCOUNTER0_SELECT__CI__VI = 0xD802; +constexpr unsigned int mmCPG_PERFCOUNTER1_HI__CI__VI = 0xD001; +constexpr unsigned int mmCPG_PERFCOUNTER1_LO__CI__VI = 0xD000; +constexpr unsigned int mmCPG_PERFCOUNTER1_SELECT__CI__VI = 0xD800; +constexpr unsigned int mmCP_APPEND_ADDR_HI__CI__VI = 0xC059; +constexpr unsigned int mmCP_APPEND_ADDR_HI__SI = 0x2159; +constexpr unsigned int mmCP_APPEND_ADDR_LO__CI__VI = 0xC058; +constexpr unsigned int mmCP_APPEND_ADDR_LO__SI = 0x2158; +constexpr unsigned int mmCP_APPEND_DATA__CI__VI = 0xC05A; +constexpr unsigned int mmCP_APPEND_DATA__SI = 0x215A; +constexpr unsigned int mmCP_APPEND_LAST_CS_FENCE__CI__VI = 0xC05B; +constexpr unsigned int mmCP_APPEND_LAST_CS_FENCE__SI = 0x215B; +constexpr unsigned int mmCP_APPEND_LAST_PS_FENCE__CI__VI = 0xC05C; +constexpr unsigned int mmCP_APPEND_LAST_PS_FENCE__SI = 0x215C; +constexpr unsigned int mmCP_ATOMIC_PREOP_HI__CI__VI = 0xC05E; +constexpr unsigned int mmCP_ATOMIC_PREOP_HI__SI = 0x215E; +constexpr unsigned int mmCP_ATOMIC_PREOP_LO__CI__VI = 0xC05D; +constexpr unsigned int mmCP_ATOMIC_PREOP_LO__SI = 0x215D; +constexpr unsigned int mmCP_BUSY_STAT = 0x219F; +constexpr unsigned int mmCP_CEQ1_AVAIL = 0x21E6; +constexpr unsigned int mmCP_CEQ2_AVAIL = 0x21E7; +constexpr unsigned int mmCP_CE_COMPARE_COUNT__CI__VI = 0x20C0; +constexpr unsigned int mmCP_CE_COUNTER__CI__VI = 0xC09A; +constexpr unsigned int mmCP_CE_DE_COUNT__CI__VI = 0x20C1; +constexpr unsigned int mmCP_CE_HEADER_DUMP = 0x21A4; +constexpr unsigned int mmCP_CE_IB1_BASE_HI__CI__VI = 0xC0C7; +constexpr unsigned int mmCP_CE_IB1_BASE_HI__SI = 0x21C7; +constexpr unsigned int mmCP_CE_IB1_BASE_LO__CI__VI = 0xC0C6; +constexpr unsigned int mmCP_CE_IB1_BASE_LO__SI = 0x21C6; +constexpr unsigned int mmCP_CE_IB1_BUFSZ__CI__VI = 0xC0C8; +constexpr unsigned int mmCP_CE_IB1_BUFSZ__SI = 0x21C8; +constexpr unsigned int mmCP_CE_IB1_OFFSET__CI__VI = 0xC098; +constexpr unsigned int mmCP_CE_IB2_BASE_HI__CI__VI = 0xC0CA; +constexpr unsigned int mmCP_CE_IB2_BASE_HI__SI = 0x21CA; +constexpr unsigned int mmCP_CE_IB2_BASE_LO__CI__VI = 0xC0C9; +constexpr unsigned int mmCP_CE_IB2_BASE_LO__SI = 0x21C9; +constexpr unsigned int mmCP_CE_IB2_BUFSZ__CI__VI = 0xC0CB; +constexpr unsigned int mmCP_CE_IB2_BUFSZ__SI = 0x21CB; +constexpr unsigned int mmCP_CE_IB2_OFFSET__CI__VI = 0xC099; +constexpr unsigned int mmCP_CE_INIT_BASE_HI__CI__VI = 0xC0C4; +constexpr unsigned int mmCP_CE_INIT_BASE_HI__SI = 0x21C4; +constexpr unsigned int mmCP_CE_INIT_BASE_LO__CI__VI = 0xC0C3; +constexpr unsigned int mmCP_CE_INIT_BASE_LO__SI = 0x21C3; +constexpr unsigned int mmCP_CE_INIT_BUFSZ__CI__VI = 0xC0C5; +constexpr unsigned int mmCP_CE_INIT_BUFSZ__SI = 0x21C5; +constexpr unsigned int mmCP_CE_INTR_ROUTINE_START__CI__VI = 0x30A8; +constexpr unsigned int mmCP_CE_PRGRM_CNTR_START__CI__VI = 0x30A3; +constexpr unsigned int mmCP_CE_ROQ_IB1_STAT = 0x21E9; +constexpr unsigned int mmCP_CE_ROQ_IB2_STAT = 0x21EA; +constexpr unsigned int mmCP_CE_ROQ_RB_STAT = 0x21E8; +constexpr unsigned int mmCP_CMD_DATA = 0x21DF; +constexpr unsigned int mmCP_CMD_INDEX = 0x21DE; +constexpr unsigned int mmCP_CNTX_STAT = 0x21B8; +constexpr unsigned int mmCP_COHER_BASE_HI__CI__VI = 0xC079; +constexpr unsigned int mmCP_COHER_BASE__CI__VI = 0xC07E; +constexpr unsigned int mmCP_COHER_BASE__SI = 0x217E; +constexpr unsigned int mmCP_COHER_CNTL__CI__VI = 0xC07C; +constexpr unsigned int mmCP_COHER_CNTL__SI = 0x217C; +constexpr unsigned int mmCP_COHER_SIZE_HI__CI__VI = 0xC08C; +constexpr unsigned int mmCP_COHER_SIZE__CI__VI = 0xC07D; +constexpr unsigned int mmCP_COHER_SIZE__SI = 0x217D; +constexpr unsigned int mmCP_COHER_START_DELAY__CI__VI = 0xC07B; +constexpr unsigned int mmCP_COHER_START_DELAY__SI = 0x217B; +constexpr unsigned int mmCP_COHER_STATUS__CI__VI = 0xC07F; +constexpr unsigned int mmCP_COHER_STATUS__SI = 0x217F; +constexpr unsigned int mmCP_CONFIG__SI = 0x0F92; +constexpr unsigned int mmCP_CONTEXT_CNTL__CI__VI = 0x30AD; +constexpr unsigned int mmCP_CPC_BUSY_STAT__CI__VI = 0x2085; +constexpr unsigned int mmCP_CPC_GRBM_FREE_COUNT__CI__VI = 0x208B; +constexpr unsigned int mmCP_CPC_HALT_HYST_COUNT__CI__VI = 0x20A7; +constexpr unsigned int mmCP_CPC_MC_CNTL__CI = 0x208A; +constexpr unsigned int mmCP_CPC_SCRATCH_DATA__CI__VI = 0x2091; +constexpr unsigned int mmCP_CPC_SCRATCH_INDEX__CI__VI = 0x2090; +constexpr unsigned int mmCP_CPC_STALLED_STAT1__CI__VI = 0x2086; +constexpr unsigned int mmCP_CPC_STATUS__CI__VI = 0x2084; +constexpr unsigned int mmCP_CPF_BUSY_STAT__CI__VI = 0x2088; +constexpr unsigned int mmCP_CPF_STALLED_STAT1__CI__VI = 0x2089; +constexpr unsigned int mmCP_CPF_STATUS__CI__VI = 0x2087; +constexpr unsigned int mmCP_CSF_CNTL = 0x21B5; +constexpr unsigned int mmCP_CSF_STAT = 0x21B4; +constexpr unsigned int mmCP_DEBUG = 0x307F; +constexpr unsigned int mmCP_DEVICE_ID__CI__VI = 0x304B; +constexpr unsigned int mmCP_DE_CE_COUNT__CI__VI = 0x20C2; +constexpr unsigned int mmCP_DE_DE_COUNT__CI__VI = 0x20C4; +constexpr unsigned int mmCP_DE_LAST_INVAL_COUNT__CI__VI = 0x20C3; +constexpr unsigned int mmCP_DFY_ADDR_HI__CI__VI = 0x3022; +constexpr unsigned int mmCP_DFY_ADDR_LO__CI__VI = 0x3023; +constexpr unsigned int mmCP_DFY_CNTL__CI__VI = 0x3020; +constexpr unsigned int mmCP_DFY_DATA_0__CI__VI = 0x3024; +constexpr unsigned int mmCP_DFY_DATA_10__CI__VI = 0x302E; +constexpr unsigned int mmCP_DFY_DATA_11__CI__VI = 0x302F; +constexpr unsigned int mmCP_DFY_DATA_12__CI__VI = 0x3030; +constexpr unsigned int mmCP_DFY_DATA_13__CI__VI = 0x3031; +constexpr unsigned int mmCP_DFY_DATA_14__CI__VI = 0x3032; +constexpr unsigned int mmCP_DFY_DATA_15__CI__VI = 0x3033; +constexpr unsigned int mmCP_DFY_DATA_1__CI__VI = 0x3025; +constexpr unsigned int mmCP_DFY_DATA_2__CI__VI = 0x3026; +constexpr unsigned int mmCP_DFY_DATA_3__CI__VI = 0x3027; +constexpr unsigned int mmCP_DFY_DATA_4__CI__VI = 0x3028; +constexpr unsigned int mmCP_DFY_DATA_5__CI__VI = 0x3029; +constexpr unsigned int mmCP_DFY_DATA_6__CI__VI = 0x302A; +constexpr unsigned int mmCP_DFY_DATA_7__CI__VI = 0x302B; +constexpr unsigned int mmCP_DFY_DATA_8__CI__VI = 0x302C; +constexpr unsigned int mmCP_DFY_DATA_9__CI__VI = 0x302D; +constexpr unsigned int mmCP_DFY_STAT__CI__VI = 0x3021; +constexpr unsigned int mmCP_DMA_CNTL__CI__VI = 0xC08A; +constexpr unsigned int mmCP_DMA_CNTL__SI = 0x218A; +constexpr unsigned int mmCP_DMA_ME_COMMAND__CI__VI = 0xC084; +constexpr unsigned int mmCP_DMA_ME_COMMAND__SI = 0x2184; +constexpr unsigned int mmCP_DMA_ME_CONTROL__CI__VI = 0xC078; +constexpr unsigned int mmCP_DMA_ME_DST_ADDR_HI__CI__VI = 0xC083; +constexpr unsigned int mmCP_DMA_ME_DST_ADDR_HI__SI = 0x2183; +constexpr unsigned int mmCP_DMA_ME_DST_ADDR__CI__VI = 0xC082; +constexpr unsigned int mmCP_DMA_ME_DST_ADDR__SI = 0x2182; +constexpr unsigned int mmCP_DMA_ME_SRC_ADDR_HI__CI__VI = 0xC081; +constexpr unsigned int mmCP_DMA_ME_SRC_ADDR_HI__SI = 0x2181; +constexpr unsigned int mmCP_DMA_ME_SRC_ADDR__CI__VI = 0xC080; +constexpr unsigned int mmCP_DMA_ME_SRC_ADDR__SI = 0x2180; +constexpr unsigned int mmCP_DMA_PFP_COMMAND__CI__VI = 0xC089; +constexpr unsigned int mmCP_DMA_PFP_COMMAND__SI = 0x2189; +constexpr unsigned int mmCP_DMA_PFP_CONTROL__CI__VI = 0xC077; +constexpr unsigned int mmCP_DMA_PFP_DST_ADDR_HI__CI__VI = 0xC088; +constexpr unsigned int mmCP_DMA_PFP_DST_ADDR_HI__SI = 0x2188; +constexpr unsigned int mmCP_DMA_PFP_DST_ADDR__CI__VI = 0xC087; +constexpr unsigned int mmCP_DMA_PFP_DST_ADDR__SI = 0x2187; +constexpr unsigned int mmCP_DMA_PFP_SRC_ADDR_HI__CI__VI = 0xC086; +constexpr unsigned int mmCP_DMA_PFP_SRC_ADDR_HI__SI = 0x2186; +constexpr unsigned int mmCP_DMA_PFP_SRC_ADDR__CI__VI = 0xC085; +constexpr unsigned int mmCP_DMA_PFP_SRC_ADDR__SI = 0x2185; +constexpr unsigned int mmCP_DMA_READ_TAGS__CI__VI = 0xC08B; +constexpr unsigned int mmCP_DMA_READ_TAGS__SI = 0x218B; +constexpr unsigned int mmCP_ECC_FIRSTOCCURRENCE = 0x307A; +constexpr unsigned int mmCP_ECC_FIRSTOCCURRENCE_RING0 = 0x307B; +constexpr unsigned int mmCP_ECC_FIRSTOCCURRENCE_RING1 = 0x307C; +constexpr unsigned int mmCP_ECC_FIRSTOCCURRENCE_RING2 = 0x307D; +constexpr unsigned int mmCP_ENDIAN_SWAP__CI__VI = 0x3050; +constexpr unsigned int mmCP_EOP_DONE_ADDR_HI__CI__VI = 0xC001; +constexpr unsigned int mmCP_EOP_DONE_ADDR_HI__SI = 0x2101; +constexpr unsigned int mmCP_EOP_DONE_ADDR_LO__CI__VI = 0xC000; +constexpr unsigned int mmCP_EOP_DONE_ADDR_LO__SI = 0x2100; +constexpr unsigned int mmCP_EOP_DONE_DATA_CNTL__CI__VI = 0xC0D6; +constexpr unsigned int mmCP_EOP_DONE_DATA_HI__CI__VI = 0xC003; +constexpr unsigned int mmCP_EOP_DONE_DATA_HI__SI = 0x2103; +constexpr unsigned int mmCP_EOP_DONE_DATA_LO__CI__VI = 0xC002; +constexpr unsigned int mmCP_EOP_DONE_DATA_LO__SI = 0x2102; +constexpr unsigned int mmCP_EOP_DONE_EVENT_CNTL__CI__VI = 0xC0D5; +constexpr unsigned int mmCP_EOP_LAST_FENCE_HI__CI__VI = 0xC005; +constexpr unsigned int mmCP_EOP_LAST_FENCE_HI__SI = 0x2105; +constexpr unsigned int mmCP_EOP_LAST_FENCE_LO__CI__VI = 0xC004; +constexpr unsigned int mmCP_EOP_LAST_FENCE_LO__SI = 0x2104; +constexpr unsigned int mmCP_FETCHER_SOURCE__CI = 0x3082; +constexpr unsigned int mmCP_GDS_ATOMIC0_PREOP_HI__CI__VI = 0xC060; +constexpr unsigned int mmCP_GDS_ATOMIC0_PREOP_HI__SI = 0x2160; +constexpr unsigned int mmCP_GDS_ATOMIC0_PREOP_LO__CI__VI = 0xC05F; +constexpr unsigned int mmCP_GDS_ATOMIC0_PREOP_LO__SI = 0x215F; +constexpr unsigned int mmCP_GDS_ATOMIC1_PREOP_HI__CI__VI = 0xC062; +constexpr unsigned int mmCP_GDS_ATOMIC1_PREOP_HI__SI = 0x2162; +constexpr unsigned int mmCP_GDS_ATOMIC1_PREOP_LO__CI__VI = 0xC061; +constexpr unsigned int mmCP_GDS_ATOMIC1_PREOP_LO__SI = 0x2161; +constexpr unsigned int mmCP_GRBM_FREE_COUNT = 0x21A3; +constexpr unsigned int mmCP_HPD_EOP_BASE_ADDR_HI__CI = 0x3242; +constexpr unsigned int mmCP_HPD_EOP_BASE_ADDR__CI = 0x3241; +constexpr unsigned int mmCP_HPD_EOP_CONTROL__CI = 0x3244; +constexpr unsigned int mmCP_HPD_EOP_VMID__CI = 0x3243; +constexpr unsigned int mmCP_HPD_ROQ_OFFSETS__CI__VI = 0x3240; +constexpr unsigned int mmCP_HQD_ACTIVE__CI__VI = 0x3247; +constexpr unsigned int mmCP_HQD_ATOMIC0_PREOP_HI__CI__VI = 0x3262; +constexpr unsigned int mmCP_HQD_ATOMIC0_PREOP_LO__CI__VI = 0x3261; +constexpr unsigned int mmCP_HQD_ATOMIC1_PREOP_HI__CI__VI = 0x3264; +constexpr unsigned int mmCP_HQD_ATOMIC1_PREOP_LO__CI__VI = 0x3263; +constexpr unsigned int mmCP_HQD_DEQUEUE_REQUEST__CI__VI = 0x325D; +constexpr unsigned int mmCP_HQD_DMA_OFFLOAD__CI__VI = 0x325E; +constexpr unsigned int mmCP_HQD_HQ_SCHEDULER0__CI__VI = 0x3265; +constexpr unsigned int mmCP_HQD_HQ_SCHEDULER1__CI__VI = 0x3266; +constexpr unsigned int mmCP_HQD_IB_BASE_ADDR_HI__CI__VI = 0x3258; +constexpr unsigned int mmCP_HQD_IB_BASE_ADDR__CI__VI = 0x3257; +constexpr unsigned int mmCP_HQD_IB_CONTROL__CI__VI = 0x325A; +constexpr unsigned int mmCP_HQD_IB_RPTR__CI__VI = 0x3259; +constexpr unsigned int mmCP_HQD_IQ_RPTR__CI__VI = 0x325C; +constexpr unsigned int mmCP_HQD_IQ_TIMER__CI__VI = 0x325B; +constexpr unsigned int mmCP_HQD_MSG_TYPE__CI__VI = 0x3260; +constexpr unsigned int mmCP_HQD_PERSISTENT_STATE__CI__VI = 0x3249; +constexpr unsigned int mmCP_HQD_PIPE_PRIORITY__CI__VI = 0x324A; +constexpr unsigned int mmCP_HQD_PQ_BASE_HI__CI__VI = 0x324E; +constexpr unsigned int mmCP_HQD_PQ_BASE__CI__VI = 0x324D; +constexpr unsigned int mmCP_HQD_PQ_CONTROL__CI__VI = 0x3256; +constexpr unsigned int mmCP_HQD_PQ_DOORBELL_CONTROL__CI__VI = 0x3254; +constexpr unsigned int mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI__CI__VI = 0x3251; +constexpr unsigned int mmCP_HQD_PQ_RPTR_REPORT_ADDR__CI__VI = 0x3250; +constexpr unsigned int mmCP_HQD_PQ_RPTR__CI__VI = 0x324F; +constexpr unsigned int mmCP_HQD_PQ_WPTR_POLL_ADDR_HI__CI__VI = 0x3253; +constexpr unsigned int mmCP_HQD_PQ_WPTR_POLL_ADDR__CI__VI = 0x3252; +constexpr unsigned int mmCP_HQD_PQ_WPTR__CI__VI = 0x3255; +constexpr unsigned int mmCP_HQD_QUANTUM__CI__VI = 0x324C; +constexpr unsigned int mmCP_HQD_QUEUE_PRIORITY__CI__VI = 0x324B; +constexpr unsigned int mmCP_HQD_SEMA_CMD__CI__VI = 0x325F; +constexpr unsigned int mmCP_HQD_VMID__CI__VI = 0x3248; +constexpr unsigned int mmCP_IB1_BASE_HI__CI__VI = 0xC0CD; +constexpr unsigned int mmCP_IB1_BASE_HI__SI = 0x21CD; +constexpr unsigned int mmCP_IB1_BASE_LO__CI__VI = 0xC0CC; +constexpr unsigned int mmCP_IB1_BASE_LO__SI = 0x21CC; +constexpr unsigned int mmCP_IB1_BUFSZ__CI__VI = 0xC0CE; +constexpr unsigned int mmCP_IB1_BUFSZ__SI = 0x21CE; +constexpr unsigned int mmCP_IB1_OFFSET__CI__VI = 0xC092; +constexpr unsigned int mmCP_IB1_OFFSET__SI = 0x2192; +constexpr unsigned int mmCP_IB1_PREAMBLE_BEGIN__CI__VI = 0xC094; +constexpr unsigned int mmCP_IB1_PREAMBLE_BEGIN__SI = 0x2194; +constexpr unsigned int mmCP_IB1_PREAMBLE_END__CI__VI = 0xC095; +constexpr unsigned int mmCP_IB1_PREAMBLE_END__SI = 0x2195; +constexpr unsigned int mmCP_IB2_BASE_HI__CI__VI = 0xC0D0; +constexpr unsigned int mmCP_IB2_BASE_HI__SI = 0x21D0; +constexpr unsigned int mmCP_IB2_BASE_LO__CI__VI = 0xC0CF; +constexpr unsigned int mmCP_IB2_BASE_LO__SI = 0x21CF; +constexpr unsigned int mmCP_IB2_BUFSZ__CI__VI = 0xC0D1; +constexpr unsigned int mmCP_IB2_BUFSZ__SI = 0x21D1; +constexpr unsigned int mmCP_IB2_OFFSET__CI__VI = 0xC093; +constexpr unsigned int mmCP_IB2_OFFSET__SI = 0x2193; +constexpr unsigned int mmCP_IB2_PREAMBLE_BEGIN__CI__VI = 0xC096; +constexpr unsigned int mmCP_IB2_PREAMBLE_BEGIN__SI = 0x2196; +constexpr unsigned int mmCP_IB2_PREAMBLE_END__CI__VI = 0xC097; +constexpr unsigned int mmCP_IB2_PREAMBLE_END__SI = 0x2197; +constexpr unsigned int mmCP_INT_CNTL = 0x3049; +constexpr unsigned int mmCP_INT_CNTL_RING0 = 0x306A; +constexpr unsigned int mmCP_INT_CNTL_RING1 = 0x306B; +constexpr unsigned int mmCP_INT_CNTL_RING2 = 0x306C; +constexpr unsigned int mmCP_INT_STATUS = 0x304A; +constexpr unsigned int mmCP_INT_STATUS_RING0 = 0x306D; +constexpr unsigned int mmCP_INT_STATUS_RING1 = 0x306E; +constexpr unsigned int mmCP_INT_STATUS_RING2 = 0x306F; +constexpr unsigned int mmCP_INT_STAT_DEBUG = 0x21F7; +constexpr unsigned int mmCP_IQ_WAIT_TIME1__CI__VI = 0x30AF; +constexpr unsigned int mmCP_IQ_WAIT_TIME2__CI__VI = 0x30B0; +constexpr unsigned int mmCP_MAX_CONTEXT__CI__VI = 0x30AE; +constexpr unsigned int mmCP_MC_PACK_DELAY_CNT__SI__CI = 0x21A7; +constexpr unsigned int mmCP_MC_TAG_CNTL__CI = 0x21A8; +constexpr unsigned int mmCP_MC_TAG_DATA__CI = 0x21A9; +constexpr unsigned int mmCP_ME0_PIPE0_PRIORITY__CI__VI = 0x304D; +constexpr unsigned int mmCP_ME0_PIPE0_VMID__CI__VI = 0x3052; +constexpr unsigned int mmCP_ME0_PIPE1_PRIORITY__CI__VI = 0x304E; +constexpr unsigned int mmCP_ME0_PIPE1_VMID__CI__VI = 0x3053; +constexpr unsigned int mmCP_ME0_PIPE2_PRIORITY__CI__VI = 0x304F; +constexpr unsigned int mmCP_ME0_PIPE_PRIORITY_CNTS__CI__VI = 0x304C; +constexpr unsigned int mmCP_ME1_INT_STAT_DEBUG__CI__VI = 0x3095; +constexpr unsigned int mmCP_ME1_PIPE0_INT_CNTL__CI__VI = 0x3085; +constexpr unsigned int mmCP_ME1_PIPE0_INT_STATUS__CI__VI = 0x308D; +constexpr unsigned int mmCP_ME1_PIPE0_PRIORITY__CI__VI = 0x309A; +constexpr unsigned int mmCP_ME1_PIPE1_INT_CNTL__CI__VI = 0x3086; +constexpr unsigned int mmCP_ME1_PIPE1_INT_STATUS__CI__VI = 0x308E; +constexpr unsigned int mmCP_ME1_PIPE1_PRIORITY__CI__VI = 0x309B; +constexpr unsigned int mmCP_ME1_PIPE2_INT_CNTL__CI__VI = 0x3087; +constexpr unsigned int mmCP_ME1_PIPE2_INT_STATUS__CI__VI = 0x308F; +constexpr unsigned int mmCP_ME1_PIPE2_PRIORITY__CI__VI = 0x309C; +constexpr unsigned int mmCP_ME1_PIPE3_INT_CNTL__CI__VI = 0x3088; +constexpr unsigned int mmCP_ME1_PIPE3_INT_STATUS__CI__VI = 0x3090; +constexpr unsigned int mmCP_ME1_PIPE3_PRIORITY__CI__VI = 0x309D; +constexpr unsigned int mmCP_ME1_PIPE_PRIORITY_CNTS__CI__VI = 0x3099; +constexpr unsigned int mmCP_ME2_INT_STAT_DEBUG__CI__VI = 0x3096; +constexpr unsigned int mmCP_ME2_PIPE0_INT_CNTL__CI__VI = 0x3089; +constexpr unsigned int mmCP_ME2_PIPE0_INT_STATUS__CI__VI = 0x3091; +constexpr unsigned int mmCP_ME2_PIPE0_PRIORITY__CI__VI = 0x309F; +constexpr unsigned int mmCP_ME2_PIPE1_INT_CNTL__CI__VI = 0x308A; +constexpr unsigned int mmCP_ME2_PIPE1_INT_STATUS__CI__VI = 0x3092; +constexpr unsigned int mmCP_ME2_PIPE1_PRIORITY__CI__VI = 0x30A0; +constexpr unsigned int mmCP_ME2_PIPE2_INT_CNTL__CI__VI = 0x308B; +constexpr unsigned int mmCP_ME2_PIPE2_INT_STATUS__CI__VI = 0x3093; +constexpr unsigned int mmCP_ME2_PIPE2_PRIORITY__CI__VI = 0x30A1; +constexpr unsigned int mmCP_ME2_PIPE3_INT_CNTL__CI__VI = 0x308C; +constexpr unsigned int mmCP_ME2_PIPE3_INT_STATUS__CI__VI = 0x3094; +constexpr unsigned int mmCP_ME2_PIPE3_PRIORITY__CI__VI = 0x30A2; +constexpr unsigned int mmCP_ME2_PIPE_PRIORITY_CNTS__CI__VI = 0x309E; +constexpr unsigned int mmCP_MEC1_INTR_ROUTINE_START__CI__VI = 0x30AB; +constexpr unsigned int mmCP_MEC1_PRGRM_CNTR_START__CI__VI = 0x30A6; +constexpr unsigned int mmCP_MEC2_INTR_ROUTINE_START__CI__VI = 0x30AC; +constexpr unsigned int mmCP_MEC2_PRGRM_CNTR_START__CI__VI = 0x30A7; +constexpr unsigned int mmCP_MEC_CNTL__CI__VI = 0x208D; +constexpr unsigned int mmCP_MEC_ME1_HEADER_DUMP__CI__VI = 0x208E; +constexpr unsigned int mmCP_MEC_ME1_UCODE_ADDR__CI = 0x305C; +constexpr unsigned int mmCP_MEC_ME1_UCODE_DATA__CI = 0x305D; +constexpr unsigned int mmCP_MEC_ME2_HEADER_DUMP__CI__VI = 0x208F; +constexpr unsigned int mmCP_MEC_ME2_UCODE_ADDR__CI = 0x305E; +constexpr unsigned int mmCP_MEC_ME2_UCODE_DATA__CI = 0x305F; +constexpr unsigned int mmCP_MEM_SLP_CNTL = 0x3079; +constexpr unsigned int mmCP_MEQ_AVAIL = 0x21DD; +constexpr unsigned int mmCP_MEQ_STAT = 0x21E5; +constexpr unsigned int mmCP_MEQ_STQ_THRESHOLD__CI__VI = 0x21BD; +constexpr unsigned int mmCP_MEQ_THRESHOLDS = 0x21D9; +constexpr unsigned int mmCP_ME_ATOMIC_PREOP_HI__CI__VI = 0xC05E; +constexpr unsigned int mmCP_ME_ATOMIC_PREOP_LO__CI__VI = 0xC05D; +constexpr unsigned int mmCP_ME_CNTL = 0x21B6; +constexpr unsigned int mmCP_ME_GDS_ATOMIC0_PREOP_HI__CI__VI = 0xC060; +constexpr unsigned int mmCP_ME_GDS_ATOMIC0_PREOP_LO__CI__VI = 0xC05F; +constexpr unsigned int mmCP_ME_GDS_ATOMIC1_PREOP_HI__CI__VI = 0xC062; +constexpr unsigned int mmCP_ME_GDS_ATOMIC1_PREOP_LO__CI__VI = 0xC061; +constexpr unsigned int mmCP_ME_HEADER_DUMP = 0x21A1; +constexpr unsigned int mmCP_ME_INTR_ROUTINE_START__CI__VI = 0x30AA; +constexpr unsigned int mmCP_ME_MC_RADDR_HI__CI__VI = 0xC06E; +constexpr unsigned int mmCP_ME_MC_RADDR_HI__SI = 0x216E; +constexpr unsigned int mmCP_ME_MC_RADDR_LO__CI__VI = 0xC06D; +constexpr unsigned int mmCP_ME_MC_RADDR_LO__SI = 0x216D; +constexpr unsigned int mmCP_ME_MC_WADDR_HI__CI__VI = 0xC06A; +constexpr unsigned int mmCP_ME_MC_WADDR_HI__SI = 0x216A; +constexpr unsigned int mmCP_ME_MC_WADDR_LO__CI__VI = 0xC069; +constexpr unsigned int mmCP_ME_MC_WADDR_LO__SI = 0x2169; +constexpr unsigned int mmCP_ME_MC_WDATA_HI__CI__VI = 0xC06C; +constexpr unsigned int mmCP_ME_MC_WDATA_HI__SI = 0x216C; +constexpr unsigned int mmCP_ME_MC_WDATA_LO__CI__VI = 0xC06B; +constexpr unsigned int mmCP_ME_MC_WDATA_LO__SI = 0x216B; +constexpr unsigned int mmCP_ME_PREEMPTION = 0x21B9; +constexpr unsigned int mmCP_ME_PRGRM_CNTR_START__CI__VI = 0x30A5; +constexpr unsigned int mmCP_MQD_BASE_ADDR_HI__CI__VI = 0x3246; +constexpr unsigned int mmCP_MQD_BASE_ADDR__CI__VI = 0x3245; +constexpr unsigned int mmCP_MQD_CONTROL__CI__VI = 0x3267; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT0_HI__CI__VI = 0xC00B; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT0_HI__SI = 0x210B; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT0_LO__CI__VI = 0xC00A; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT0_LO__SI = 0x210A; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT1_HI__CI__VI = 0xC00F; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT1_HI__SI = 0x210F; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT1_LO__CI__VI = 0xC00E; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT1_LO__SI = 0x210E; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT2_HI__CI__VI = 0xC013; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT2_HI__SI = 0x2113; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT2_LO__CI__VI = 0xC012; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT2_LO__SI = 0x2112; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT3_HI__CI__VI = 0xC017; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT3_HI__SI = 0x2117; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT3_LO__CI__VI = 0xC016; +constexpr unsigned int mmCP_NUM_PRIM_NEEDED_COUNT3_LO__SI = 0x2116; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT0_HI__CI__VI = 0xC009; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT0_HI__SI = 0x2109; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT0_LO__CI__VI = 0xC008; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT0_LO__SI = 0x2108; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT1_HI__CI__VI = 0xC00D; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT1_HI__SI = 0x210D; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT1_LO__CI__VI = 0xC00C; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT1_LO__SI = 0x210C; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT2_HI__CI__VI = 0xC011; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT2_HI__SI = 0x2111; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT2_LO__CI__VI = 0xC010; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT2_LO__SI = 0x2110; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT3_HI__CI__VI = 0xC015; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT3_HI__SI = 0x2115; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT3_LO__CI__VI = 0xC014; +constexpr unsigned int mmCP_NUM_PRIM_WRITTEN_COUNT3_LO__SI = 0x2114; +constexpr unsigned int mmCP_PA_CINVOC_COUNT_HI__CI__VI = 0xC029; +constexpr unsigned int mmCP_PA_CINVOC_COUNT_HI__SI = 0x2129; +constexpr unsigned int mmCP_PA_CINVOC_COUNT_LO__CI__VI = 0xC028; +constexpr unsigned int mmCP_PA_CINVOC_COUNT_LO__SI = 0x2128; +constexpr unsigned int mmCP_PA_CPRIM_COUNT_HI__CI__VI = 0xC02B; +constexpr unsigned int mmCP_PA_CPRIM_COUNT_HI__SI = 0x212B; +constexpr unsigned int mmCP_PA_CPRIM_COUNT_LO__CI__VI = 0xC02A; +constexpr unsigned int mmCP_PA_CPRIM_COUNT_LO__SI = 0x212A; +constexpr unsigned int mmCP_PERFCOUNTER_HI__SI = 0x21FE; +constexpr unsigned int mmCP_PERFCOUNTER_LO__SI = 0x21FD; +constexpr unsigned int mmCP_PERFCOUNTER_SELECT__SI = 0x21FC; +constexpr unsigned int mmCP_PERFMON_CNTL__CI__VI = 0xD808; +constexpr unsigned int mmCP_PERFMON_CNTL__SI = 0x21FF; +constexpr unsigned int mmCP_PERFMON_CNTX_CNTL = 0xA0D8; +constexpr unsigned int mmCP_PFP_ATOMIC_PREOP_HI__CI__VI = 0xC053; +constexpr unsigned int mmCP_PFP_ATOMIC_PREOP_LO__CI__VI = 0xC052; +constexpr unsigned int mmCP_PFP_GDS_ATOMIC0_PREOP_HI__CI__VI = 0xC055; +constexpr unsigned int mmCP_PFP_GDS_ATOMIC0_PREOP_LO__CI__VI = 0xC054; +constexpr unsigned int mmCP_PFP_GDS_ATOMIC1_PREOP_HI__CI__VI = 0xC057; +constexpr unsigned int mmCP_PFP_GDS_ATOMIC1_PREOP_LO__CI__VI = 0xC056; +constexpr unsigned int mmCP_PFP_HEADER_DUMP = 0x21A2; +constexpr unsigned int mmCP_PFP_IB_CONTROL__CI__VI = 0xC08D; +constexpr unsigned int mmCP_PFP_IB_CONTROL__SI = 0x218D; +constexpr unsigned int mmCP_PFP_INTR_ROUTINE_START__CI__VI = 0x30A9; +constexpr unsigned int mmCP_PFP_LOAD_CONTROL__CI__VI = 0xC08E; +constexpr unsigned int mmCP_PFP_LOAD_CONTROL__SI = 0x218E; +constexpr unsigned int mmCP_PFP_PRGRM_CNTR_START__CI__VI = 0x30A4; +constexpr unsigned int mmCP_PIPEID__CI__VI = 0xA0D9; +constexpr unsigned int mmCP_PIPE_STATS_ADDR_HI__CI__VI = 0xC019; +constexpr unsigned int mmCP_PIPE_STATS_ADDR_HI__SI = 0x2119; +constexpr unsigned int mmCP_PIPE_STATS_ADDR_LO__CI__VI = 0xC018; +constexpr unsigned int mmCP_PIPE_STATS_ADDR_LO__SI = 0x2118; +constexpr unsigned int mmCP_PQ_WPTR_POLL_CNTL1__CI__VI = 0x3084; +constexpr unsigned int mmCP_PQ_WPTR_POLL_CNTL__CI__VI = 0x3083; +constexpr unsigned int mmCP_PRT_LOD_STATS_CNTL0__CI__VI = 0x20AD; +constexpr unsigned int mmCP_PRT_LOD_STATS_CNTL1__CI__VI = 0x20AE; +constexpr unsigned int mmCP_PRT_LOD_STATS_CNTL2__CI__VI = 0x20AF; +constexpr unsigned int mmCP_PWR_CNTL = 0x3078; +constexpr unsigned int mmCP_QUEUE_THRESHOLDS = 0x21D8; +constexpr unsigned int mmCP_RB0_BASE = 0x3040; +constexpr unsigned int mmCP_RB0_BASE_HI__CI__VI = 0x30B1; +constexpr unsigned int mmCP_RB0_CNTL = 0x3041; +constexpr unsigned int mmCP_RB0_RPTR = 0x21C0; +constexpr unsigned int mmCP_RB0_RPTR_ADDR = 0x3043; +constexpr unsigned int mmCP_RB0_RPTR_ADDR_HI = 0x3044; +constexpr unsigned int mmCP_RB0_WPTR = 0x3045; +constexpr unsigned int mmCP_RB1_BASE = 0x3060; +constexpr unsigned int mmCP_RB1_BASE_HI__CI__VI = 0x30B2; +constexpr unsigned int mmCP_RB1_CNTL = 0x3061; +constexpr unsigned int mmCP_RB1_RPTR = 0x21BF; +constexpr unsigned int mmCP_RB1_RPTR_ADDR = 0x3062; +constexpr unsigned int mmCP_RB1_RPTR_ADDR_HI = 0x3063; +constexpr unsigned int mmCP_RB1_WPTR = 0x3064; +constexpr unsigned int mmCP_RB2_BASE = 0x3065; +constexpr unsigned int mmCP_RB2_CNTL = 0x3066; +constexpr unsigned int mmCP_RB2_RPTR = 0x21BE; +constexpr unsigned int mmCP_RB2_RPTR_ADDR = 0x3067; +constexpr unsigned int mmCP_RB2_RPTR_ADDR_HI = 0x3068; +constexpr unsigned int mmCP_RB2_WPTR = 0x3069; +constexpr unsigned int mmCP_RB_BASE = 0x3040; +constexpr unsigned int mmCP_RB_CNTL = 0x3041; +constexpr unsigned int mmCP_RB_OFFSET__CI__VI = 0xC091; +constexpr unsigned int mmCP_RB_OFFSET__SI = 0x2191; +constexpr unsigned int mmCP_RB_RPTR = 0x21C0; +constexpr unsigned int mmCP_RB_RPTR_ADDR = 0x3043; +constexpr unsigned int mmCP_RB_RPTR_ADDR_HI = 0x3044; +constexpr unsigned int mmCP_RB_RPTR_WR = 0x3042; +constexpr unsigned int mmCP_RB_VMID = 0x3051; +constexpr unsigned int mmCP_RB_WPTR = 0x3045; +constexpr unsigned int mmCP_RB_WPTR_DELAY = 0x21C1; +constexpr unsigned int mmCP_RB_WPTR_POLL_ADDR_HI = 0x3047; +constexpr unsigned int mmCP_RB_WPTR_POLL_ADDR_LO = 0x3046; +constexpr unsigned int mmCP_RB_WPTR_POLL_CNTL = 0x21C2; +constexpr unsigned int mmCP_RING0_PRIORITY = 0x304D; +constexpr unsigned int mmCP_RING1_PRIORITY = 0x304E; +constexpr unsigned int mmCP_RING2_PRIORITY = 0x304F; +constexpr unsigned int mmCP_RINGID = 0xA0D9; +constexpr unsigned int mmCP_RING_PRIORITY_CNTS = 0x304C; +constexpr unsigned int mmCP_ROQ1_THRESHOLDS = 0x21D5; +constexpr unsigned int mmCP_ROQ2_AVAIL = 0x21DC; +constexpr unsigned int mmCP_ROQ2_THRESHOLDS = 0x21D6; +constexpr unsigned int mmCP_ROQ_AVAIL = 0x21DA; +constexpr unsigned int mmCP_ROQ_IB1_STAT = 0x21E1; +constexpr unsigned int mmCP_ROQ_IB2_STAT = 0x21E2; +constexpr unsigned int mmCP_ROQ_RB_STAT = 0x21E0; +constexpr unsigned int mmCP_ROQ_THRESHOLDS__CI__VI = 0x21BC; +constexpr unsigned int mmCP_SCRATCH_DATA__CI__VI = 0xC090; +constexpr unsigned int mmCP_SCRATCH_DATA__SI = 0x2190; +constexpr unsigned int mmCP_SCRATCH_INDEX__CI__VI = 0xC08F; +constexpr unsigned int mmCP_SCRATCH_INDEX__SI = 0x218F; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT0_HI__CI__VI = 0xC02D; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT0_HI__SI = 0x212D; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT0_LO__CI__VI = 0xC02C; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT0_LO__SI = 0x212C; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT1_HI__CI__VI = 0xC02F; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT1_HI__SI = 0x212F; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT1_LO__CI__VI = 0xC02E; +constexpr unsigned int mmCP_SC_PSINVOC_COUNT1_LO__SI = 0x212E; +constexpr unsigned int mmCP_SEM_WAIT_TIMER__CI__VI = 0xC06F; +constexpr unsigned int mmCP_SEM_WAIT_TIMER__SI = 0x216F; +constexpr unsigned int mmCP_SIG_SEM_ADDR_HI__CI__VI = 0xC071; +constexpr unsigned int mmCP_SIG_SEM_ADDR_HI__SI = 0x2171; +constexpr unsigned int mmCP_SIG_SEM_ADDR_LO__CI__VI = 0xC070; +constexpr unsigned int mmCP_SIG_SEM_ADDR_LO__SI = 0x2170; +constexpr unsigned int mmCP_STALLED_STAT1 = 0x219D; +constexpr unsigned int mmCP_STALLED_STAT2 = 0x219E; +constexpr unsigned int mmCP_STALLED_STAT3 = 0x219C; +constexpr unsigned int mmCP_STAT = 0x21A0; +constexpr unsigned int mmCP_STQ_AVAIL = 0x21DB; +constexpr unsigned int mmCP_STQ_STAT = 0x21E3; +constexpr unsigned int mmCP_STQ_THRESHOLDS = 0x21D7; +constexpr unsigned int mmCP_STQ_WR_STAT__CI__VI = 0x21E4; +constexpr unsigned int mmCP_STREAM_OUT_ADDR_HI__CI__VI = 0xC007; +constexpr unsigned int mmCP_STREAM_OUT_ADDR_HI__SI = 0x2107; +constexpr unsigned int mmCP_STREAM_OUT_ADDR_LO__CI__VI = 0xC006; +constexpr unsigned int mmCP_STREAM_OUT_ADDR_LO__SI = 0x2106; +constexpr unsigned int mmCP_STRMOUT_CNTL__CI__VI = 0xC03F; +constexpr unsigned int mmCP_STRMOUT_CNTL__SI = 0x213F; +constexpr unsigned int mmCP_ST_BASE_HI__CI__VI = 0xC0D3; +constexpr unsigned int mmCP_ST_BASE_HI__SI = 0x21D3; +constexpr unsigned int mmCP_ST_BASE_LO__CI__VI = 0xC0D2; +constexpr unsigned int mmCP_ST_BASE_LO__SI = 0x21D2; +constexpr unsigned int mmCP_ST_BUFSZ__CI__VI = 0xC0D4; +constexpr unsigned int mmCP_ST_BUFSZ__SI = 0x21D4; +constexpr unsigned int mmCP_VGT_CSINVOC_COUNT_HI__CI__VI = 0xC031; +constexpr unsigned int mmCP_VGT_CSINVOC_COUNT_HI__SI = 0x2131; +constexpr unsigned int mmCP_VGT_CSINVOC_COUNT_LO__CI__VI = 0xC030; +constexpr unsigned int mmCP_VGT_CSINVOC_COUNT_LO__SI = 0x2130; +constexpr unsigned int mmCP_VGT_DSINVOC_COUNT_HI__CI__VI = 0xC027; +constexpr unsigned int mmCP_VGT_DSINVOC_COUNT_HI__SI = 0x2127; +constexpr unsigned int mmCP_VGT_DSINVOC_COUNT_LO__CI__VI = 0xC026; +constexpr unsigned int mmCP_VGT_DSINVOC_COUNT_LO__SI = 0x2126; +constexpr unsigned int mmCP_VGT_GSINVOC_COUNT_HI__CI__VI = 0xC023; +constexpr unsigned int mmCP_VGT_GSINVOC_COUNT_HI__SI = 0x2123; +constexpr unsigned int mmCP_VGT_GSINVOC_COUNT_LO__CI__VI = 0xC022; +constexpr unsigned int mmCP_VGT_GSINVOC_COUNT_LO__SI = 0x2122; +constexpr unsigned int mmCP_VGT_GSPRIM_COUNT_HI__CI__VI = 0xC01F; +constexpr unsigned int mmCP_VGT_GSPRIM_COUNT_HI__SI = 0x211F; +constexpr unsigned int mmCP_VGT_GSPRIM_COUNT_LO__CI__VI = 0xC01E; +constexpr unsigned int mmCP_VGT_GSPRIM_COUNT_LO__SI = 0x211E; +constexpr unsigned int mmCP_VGT_HSINVOC_COUNT_HI__CI__VI = 0xC025; +constexpr unsigned int mmCP_VGT_HSINVOC_COUNT_HI__SI = 0x2125; +constexpr unsigned int mmCP_VGT_HSINVOC_COUNT_LO__CI__VI = 0xC024; +constexpr unsigned int mmCP_VGT_HSINVOC_COUNT_LO__SI = 0x2124; +constexpr unsigned int mmCP_VGT_IAPRIM_COUNT_HI__CI__VI = 0xC01D; +constexpr unsigned int mmCP_VGT_IAPRIM_COUNT_HI__SI = 0x211D; +constexpr unsigned int mmCP_VGT_IAPRIM_COUNT_LO__CI__VI = 0xC01C; +constexpr unsigned int mmCP_VGT_IAPRIM_COUNT_LO__SI = 0x211C; +constexpr unsigned int mmCP_VGT_IAVERT_COUNT_HI__CI__VI = 0xC01B; +constexpr unsigned int mmCP_VGT_IAVERT_COUNT_HI__SI = 0x211B; +constexpr unsigned int mmCP_VGT_IAVERT_COUNT_LO__CI__VI = 0xC01A; +constexpr unsigned int mmCP_VGT_IAVERT_COUNT_LO__SI = 0x211A; +constexpr unsigned int mmCP_VGT_VSINVOC_COUNT_HI__CI__VI = 0xC021; +constexpr unsigned int mmCP_VGT_VSINVOC_COUNT_HI__SI = 0x2121; +constexpr unsigned int mmCP_VGT_VSINVOC_COUNT_LO__CI__VI = 0xC020; +constexpr unsigned int mmCP_VGT_VSINVOC_COUNT_LO__SI = 0x2120; +constexpr unsigned int mmCP_VMID = 0xA0DA; +constexpr unsigned int mmCP_VMID_PREEMPT__CI__VI = 0x30B6; +constexpr unsigned int mmCP_VMID_RESET__CI__VI = 0x30B3; +constexpr unsigned int mmCP_WAIT_REG_MEM_TIMEOUT__CI__VI = 0xC074; +constexpr unsigned int mmCP_WAIT_REG_MEM_TIMEOUT__SI = 0x2174; +constexpr unsigned int mmCP_WAIT_SEM_ADDR_HI__CI__VI = 0xC076; +constexpr unsigned int mmCP_WAIT_SEM_ADDR_HI__SI = 0x2176; +constexpr unsigned int mmCP_WAIT_SEM_ADDR_LO__CI__VI = 0xC075; +constexpr unsigned int mmCP_WAIT_SEM_ADDR_LO__SI = 0x2175; +constexpr unsigned int mmCRTC0_CRTC_ALLOW_STOP_OFF_V_CNT__SI__VI = 0x1BC3; +constexpr unsigned int mmCRTC0_CRTC_BLACK_COLOR__SI = 0x1BA2; +constexpr unsigned int mmCRTC0_CRTC_BLANK_CONTROL = 0x1B9D; +constexpr unsigned int mmCRTC0_CRTC_BLANK_DATA_COLOR__SI = 0x1BA1; +constexpr unsigned int mmCRTC0_CRTC_CONTROL__SI__VI = 0x1B9C; +constexpr unsigned int mmCRTC0_CRTC_COUNT_CONTROL__SI__VI = 0x1BA9; +constexpr unsigned int mmCRTC0_CRTC_COUNT_RESET__SI__VI = 0x1BAA; +constexpr unsigned int mmCRTC0_CRTC_DOUBLE_BUFFER_CONTROL__SI__VI = 0x1BB6; +constexpr unsigned int mmCRTC0_CRTC_DTMTEST_CNTL__SI__VI = 0x1B92; +constexpr unsigned int mmCRTC0_CRTC_DTMTEST_STATUS_POSITION__SI__VI = 0x1B93; +constexpr unsigned int mmCRTC0_CRTC_FLOW_CONTROL__SI__VI = 0x1B99; +constexpr unsigned int mmCRTC0_CRTC_FORCE_COUNT_NOW_CNTL__SI__VI = 0x1B98; +constexpr unsigned int mmCRTC0_CRTC_H_BLANK_START_END__SI__VI = 0x1B81; +constexpr unsigned int mmCRTC0_CRTC_H_SYNC_A_CNTL__SI__VI = 0x1B83; +constexpr unsigned int mmCRTC0_CRTC_H_SYNC_A__SI__VI = 0x1B82; +constexpr unsigned int mmCRTC0_CRTC_H_SYNC_B_CNTL__SI__VI = 0x1B85; +constexpr unsigned int mmCRTC0_CRTC_H_SYNC_B__SI__VI = 0x1B84; +constexpr unsigned int mmCRTC0_CRTC_H_TOTAL__SI__VI = 0x1B80; +constexpr unsigned int mmCRTC0_CRTC_INTERLACE_CONTROL__SI__VI = 0x1B9E; +constexpr unsigned int mmCRTC0_CRTC_INTERLACE_STATUS__SI__VI = 0x1B9F; +constexpr unsigned int mmCRTC0_CRTC_INTERRUPT_CONTROL__SI__VI = 0x1BB4; +constexpr unsigned int mmCRTC0_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__SI__VI = 0x1BAB; +constexpr unsigned int mmCRTC0_CRTC_MASTER_EN__SI__VI = 0x1BC2; +constexpr unsigned int mmCRTC0_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__SI__VI = 0x1BC0; +constexpr unsigned int mmCRTC0_CRTC_MVP_INBAND_CNTL_INSERT__SI__VI = 0x1BBF; +constexpr unsigned int mmCRTC0_CRTC_MVP_STATUS__SI__VI = 0x1BC1; +constexpr unsigned int mmCRTC0_CRTC_NOM_VERT_POSITION__SI__VI = 0x1BA5; +constexpr unsigned int mmCRTC0_CRTC_OVERSCAN_COLOR__SI = 0x1BA0; +constexpr unsigned int mmCRTC0_CRTC_PIXEL_DATA_READBACK__SI = 0x1B9A; +constexpr unsigned int mmCRTC0_CRTC_SNAPSHOT_CONTROL__SI__VI = 0x1BB0; +constexpr unsigned int mmCRTC0_CRTC_SNAPSHOT_FRAME__SI__VI = 0x1BB2; +constexpr unsigned int mmCRTC0_CRTC_SNAPSHOT_POSITION__SI__VI = 0x1BB1; +constexpr unsigned int mmCRTC0_CRTC_SNAPSHOT_STATUS__SI__VI = 0x1BAF; +constexpr unsigned int mmCRTC0_CRTC_START_LINE_CONTROL__SI__VI = 0x1BB3; +constexpr unsigned int mmCRTC0_CRTC_STATUS = 0x1BA3; +constexpr unsigned int mmCRTC0_CRTC_STATUS_FRAME_COUNT__SI__VI = 0x1BA6; +constexpr unsigned int mmCRTC0_CRTC_STATUS_HV_COUNT__SI__VI = 0x1BA8; +constexpr unsigned int mmCRTC0_CRTC_STATUS_POSITION = 0x1BA4; +constexpr unsigned int mmCRTC0_CRTC_STATUS_VF_COUNT__SI__VI = 0x1BA7; +constexpr unsigned int mmCRTC0_CRTC_STEREO_CONTROL__SI__VI = 0x1BAE; +constexpr unsigned int mmCRTC0_CRTC_STEREO_FORCE_NEXT_EYE__SI = 0x1B9B; +constexpr unsigned int mmCRTC0_CRTC_STEREO_STATUS__SI__VI = 0x1BAD; +constexpr unsigned int mmCRTC0_CRTC_TEST_DEBUG_DATA__SI__VI = 0x1BC7; +constexpr unsigned int mmCRTC0_CRTC_TEST_DEBUG_INDEX__SI__VI = 0x1BC6; +constexpr unsigned int mmCRTC0_CRTC_TEST_PATTERN_COLOR__SI__VI = 0x1BBC; +constexpr unsigned int mmCRTC0_CRTC_TEST_PATTERN_CONTROL__SI__VI = 0x1BBA; +constexpr unsigned int mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS__SI__VI = 0x1BBB; +constexpr unsigned int mmCRTC0_CRTC_TRIGA_CNTL__SI__VI = 0x1B94; +constexpr unsigned int mmCRTC0_CRTC_TRIGA_MANUAL_TRIG__SI__VI = 0x1B95; +constexpr unsigned int mmCRTC0_CRTC_TRIGB_CNTL__SI__VI = 0x1B96; +constexpr unsigned int mmCRTC0_CRTC_TRIGB_MANUAL_TRIG__SI__VI = 0x1B97; +constexpr unsigned int mmCRTC0_CRTC_UPDATE_LOCK__SI__VI = 0x1BB5; +constexpr unsigned int mmCRTC0_CRTC_VBI_END__SI__VI = 0x1B86; +constexpr unsigned int mmCRTC0_CRTC_VERT_SYNC_CONTROL__SI__VI = 0x1BAC; +constexpr unsigned int mmCRTC0_CRTC_VGA_PARAMETER_CAPTURE_MODE__SI__VI = 0x1BB7; +constexpr unsigned int mmCRTC0_CRTC_VSYNC_NOM_INT_STATUS__SI__VI = 0x1B8C; +constexpr unsigned int mmCRTC0_CRTC_V_BLANK_START_END__SI__VI = 0x1B8D; +constexpr unsigned int mmCRTC0_CRTC_V_SYNC_A_CNTL__SI__VI = 0x1B8F; +constexpr unsigned int mmCRTC0_CRTC_V_SYNC_A__SI__VI = 0x1B8E; +constexpr unsigned int mmCRTC0_CRTC_V_SYNC_B_CNTL__SI__VI = 0x1B91; +constexpr unsigned int mmCRTC0_CRTC_V_SYNC_B__SI__VI = 0x1B90; +constexpr unsigned int mmCRTC0_CRTC_V_TOTAL_CONTROL__SI__VI = 0x1B8A; +constexpr unsigned int mmCRTC0_CRTC_V_TOTAL_INT_STATUS__SI__VI = 0x1B8B; +constexpr unsigned int mmCRTC0_CRTC_V_TOTAL_MAX__SI__VI = 0x1B89; +constexpr unsigned int mmCRTC0_CRTC_V_TOTAL_MIN__SI__VI = 0x1B88; +constexpr unsigned int mmCRTC0_CRTC_V_TOTAL__SI__VI = 0x1B87; +constexpr unsigned int mmCRTC0_CRTC_V_UPDATE_INT_STATUS__SI__VI = 0x1BC4; +constexpr unsigned int mmCRTC0_MASTER_UPDATE_LOCK__SI__VI = 0x1BBD; +constexpr unsigned int mmCRTC0_MASTER_UPDATE_MODE = 0x1BBE; +constexpr unsigned int mmCRTC0_PIXEL_RATE_CNTL__SI = 0x0120; +constexpr unsigned int mmCRTC1_CRTC_ALLOW_STOP_OFF_V_CNT__SI = 0x1EC3; +constexpr unsigned int mmCRTC1_CRTC_BLACK_COLOR__SI = 0x1EA2; +constexpr unsigned int mmCRTC1_CRTC_BLANK_DATA_COLOR__SI = 0x1EA1; +constexpr unsigned int mmCRTC1_CRTC_CONTROL__SI = 0x1E9C; +constexpr unsigned int mmCRTC1_CRTC_COUNT_CONTROL__SI = 0x1EA9; +constexpr unsigned int mmCRTC1_CRTC_COUNT_RESET__SI = 0x1EAA; +constexpr unsigned int mmCRTC1_CRTC_DOUBLE_BUFFER_CONTROL__SI = 0x1EB6; +constexpr unsigned int mmCRTC1_CRTC_DTMTEST_CNTL__SI = 0x1E92; +constexpr unsigned int mmCRTC1_CRTC_DTMTEST_STATUS_POSITION__SI = 0x1E93; +constexpr unsigned int mmCRTC1_CRTC_FLOW_CONTROL__SI = 0x1E99; +constexpr unsigned int mmCRTC1_CRTC_FORCE_COUNT_NOW_CNTL__SI = 0x1E98; +constexpr unsigned int mmCRTC1_CRTC_H_BLANK_START_END__SI = 0x1E81; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_A_CNTL__SI = 0x1E83; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_A__SI = 0x1E82; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_B_CNTL__SI = 0x1E85; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_B__SI = 0x1E84; +constexpr unsigned int mmCRTC1_CRTC_H_TOTAL__SI = 0x1E80; +constexpr unsigned int mmCRTC1_CRTC_INTERLACE_CONTROL__SI = 0x1E9E; +constexpr unsigned int mmCRTC1_CRTC_INTERLACE_STATUS__SI = 0x1E9F; +constexpr unsigned int mmCRTC1_CRTC_INTERRUPT_CONTROL__SI = 0x1EB4; +constexpr unsigned int mmCRTC1_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__SI = 0x1EAB; +constexpr unsigned int mmCRTC1_CRTC_MASTER_EN__SI = 0x1EC2; +constexpr unsigned int mmCRTC1_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__SI = 0x1EC0; +constexpr unsigned int mmCRTC1_CRTC_MVP_INBAND_CNTL_INSERT__SI = 0x1EBF; +constexpr unsigned int mmCRTC1_CRTC_MVP_STATUS__SI = 0x1EC1; +constexpr unsigned int mmCRTC1_CRTC_NOM_VERT_POSITION__SI = 0x1EA5; +constexpr unsigned int mmCRTC1_CRTC_OVERSCAN_COLOR__SI = 0x1EA0; +constexpr unsigned int mmCRTC1_CRTC_PIXEL_DATA_READBACK__SI = 0x1E9A; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_CONTROL__SI = 0x1EB0; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_FRAME__SI = 0x1EB2; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_POSITION__SI = 0x1EB1; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_STATUS__SI = 0x1EAF; +constexpr unsigned int mmCRTC1_CRTC_START_LINE_CONTROL__SI = 0x1EB3; +constexpr unsigned int mmCRTC1_CRTC_STATUS_FRAME_COUNT__SI = 0x1EA6; +constexpr unsigned int mmCRTC1_CRTC_STATUS_HV_COUNT__SI = 0x1EA8; +constexpr unsigned int mmCRTC1_CRTC_STATUS_VF_COUNT__SI = 0x1EA7; +constexpr unsigned int mmCRTC1_CRTC_STEREO_CONTROL__SI = 0x1EAE; +constexpr unsigned int mmCRTC1_CRTC_STEREO_FORCE_NEXT_EYE__SI = 0x1E9B; +constexpr unsigned int mmCRTC1_CRTC_STEREO_STATUS__SI = 0x1EAD; +constexpr unsigned int mmCRTC1_CRTC_TEST_DEBUG_DATA__SI = 0x1EC7; +constexpr unsigned int mmCRTC1_CRTC_TEST_DEBUG_INDEX__SI = 0x1EC6; +constexpr unsigned int mmCRTC1_CRTC_TEST_PATTERN_COLOR__SI = 0x1EBC; +constexpr unsigned int mmCRTC1_CRTC_TEST_PATTERN_CONTROL__SI = 0x1EBA; +constexpr unsigned int mmCRTC1_CRTC_TEST_PATTERN_PARAMETERS__SI = 0x1EBB; +constexpr unsigned int mmCRTC1_CRTC_TRIGA_CNTL__SI = 0x1E94; +constexpr unsigned int mmCRTC1_CRTC_TRIGA_MANUAL_TRIG__SI = 0x1E95; +constexpr unsigned int mmCRTC1_CRTC_TRIGB_CNTL__SI = 0x1E96; +constexpr unsigned int mmCRTC1_CRTC_TRIGB_MANUAL_TRIG__SI = 0x1E97; +constexpr unsigned int mmCRTC1_CRTC_UPDATE_LOCK__SI = 0x1EB5; +constexpr unsigned int mmCRTC1_CRTC_VBI_END__SI = 0x1E86; +constexpr unsigned int mmCRTC1_CRTC_VERT_SYNC_CONTROL__SI = 0x1EAC; +constexpr unsigned int mmCRTC1_CRTC_VGA_PARAMETER_CAPTURE_MODE__SI = 0x1EB7; +constexpr unsigned int mmCRTC1_CRTC_VSYNC_NOM_INT_STATUS__SI = 0x1E8C; +constexpr unsigned int mmCRTC1_CRTC_V_BLANK_START_END__SI = 0x1E8D; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_A_CNTL__SI = 0x1E8F; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_A__SI = 0x1E8E; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_B_CNTL__SI = 0x1E91; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_B__SI = 0x1E90; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_CONTROL__SI = 0x1E8A; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_INT_STATUS__SI = 0x1E8B; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_MAX__SI = 0x1E89; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_MIN__SI = 0x1E88; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL__SI = 0x1E87; +constexpr unsigned int mmCRTC1_CRTC_V_UPDATE_INT_STATUS__SI = 0x1EC4; +constexpr unsigned int mmCRTC1_MASTER_UPDATE_LOCK__SI = 0x1EBD; +constexpr unsigned int mmCRTC1_PIXEL_RATE_CNTL__SI = 0x0121; +constexpr unsigned int mmCRTC2_CRTC_ALLOW_STOP_OFF_V_CNT__SI = 0x41C3; +constexpr unsigned int mmCRTC2_CRTC_BLACK_COLOR__SI = 0x41A2; +constexpr unsigned int mmCRTC2_CRTC_BLANK_DATA_COLOR__SI = 0x41A1; +constexpr unsigned int mmCRTC2_CRTC_CONTROL__SI = 0x419C; +constexpr unsigned int mmCRTC2_CRTC_COUNT_CONTROL__SI = 0x41A9; +constexpr unsigned int mmCRTC2_CRTC_COUNT_RESET__SI = 0x41AA; +constexpr unsigned int mmCRTC2_CRTC_DOUBLE_BUFFER_CONTROL__SI = 0x41B6; +constexpr unsigned int mmCRTC2_CRTC_DTMTEST_CNTL__SI = 0x4192; +constexpr unsigned int mmCRTC2_CRTC_DTMTEST_STATUS_POSITION__SI = 0x4193; +constexpr unsigned int mmCRTC2_CRTC_FLOW_CONTROL__SI = 0x4199; +constexpr unsigned int mmCRTC2_CRTC_FORCE_COUNT_NOW_CNTL__SI = 0x4198; +constexpr unsigned int mmCRTC2_CRTC_H_BLANK_START_END__SI = 0x4181; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_A_CNTL__SI = 0x4183; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_A__SI = 0x4182; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_B_CNTL__SI = 0x4185; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_B__SI = 0x4184; +constexpr unsigned int mmCRTC2_CRTC_H_TOTAL__SI = 0x4180; +constexpr unsigned int mmCRTC2_CRTC_INTERLACE_CONTROL__SI = 0x419E; +constexpr unsigned int mmCRTC2_CRTC_INTERLACE_STATUS__SI = 0x419F; +constexpr unsigned int mmCRTC2_CRTC_INTERRUPT_CONTROL__SI = 0x41B4; +constexpr unsigned int mmCRTC2_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__SI = 0x41AB; +constexpr unsigned int mmCRTC2_CRTC_MASTER_EN__SI = 0x41C2; +constexpr unsigned int mmCRTC2_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__SI = 0x41C0; +constexpr unsigned int mmCRTC2_CRTC_MVP_INBAND_CNTL_INSERT__SI = 0x41BF; +constexpr unsigned int mmCRTC2_CRTC_MVP_STATUS__SI = 0x41C1; +constexpr unsigned int mmCRTC2_CRTC_NOM_VERT_POSITION__SI = 0x41A5; +constexpr unsigned int mmCRTC2_CRTC_OVERSCAN_COLOR__SI = 0x41A0; +constexpr unsigned int mmCRTC2_CRTC_PIXEL_DATA_READBACK__SI = 0x419A; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_CONTROL__SI = 0x41B0; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_FRAME__SI = 0x41B2; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_POSITION__SI = 0x41B1; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_STATUS__SI = 0x41AF; +constexpr unsigned int mmCRTC2_CRTC_START_LINE_CONTROL__SI = 0x41B3; +constexpr unsigned int mmCRTC2_CRTC_STATUS_FRAME_COUNT__SI = 0x41A6; +constexpr unsigned int mmCRTC2_CRTC_STATUS_HV_COUNT__SI = 0x41A8; +constexpr unsigned int mmCRTC2_CRTC_STATUS_VF_COUNT__SI = 0x41A7; +constexpr unsigned int mmCRTC2_CRTC_STEREO_CONTROL__SI = 0x41AE; +constexpr unsigned int mmCRTC2_CRTC_STEREO_FORCE_NEXT_EYE__SI = 0x419B; +constexpr unsigned int mmCRTC2_CRTC_STEREO_STATUS__SI = 0x41AD; +constexpr unsigned int mmCRTC2_CRTC_TEST_DEBUG_DATA__SI = 0x41C7; +constexpr unsigned int mmCRTC2_CRTC_TEST_DEBUG_INDEX__SI = 0x41C6; +constexpr unsigned int mmCRTC2_CRTC_TEST_PATTERN_COLOR__SI = 0x41BC; +constexpr unsigned int mmCRTC2_CRTC_TEST_PATTERN_CONTROL__SI = 0x41BA; +constexpr unsigned int mmCRTC2_CRTC_TEST_PATTERN_PARAMETERS__SI = 0x41BB; +constexpr unsigned int mmCRTC2_CRTC_TRIGA_CNTL__SI = 0x4194; +constexpr unsigned int mmCRTC2_CRTC_TRIGA_MANUAL_TRIG__SI = 0x4195; +constexpr unsigned int mmCRTC2_CRTC_TRIGB_CNTL__SI = 0x4196; +constexpr unsigned int mmCRTC2_CRTC_TRIGB_MANUAL_TRIG__SI = 0x4197; +constexpr unsigned int mmCRTC2_CRTC_UPDATE_LOCK__SI = 0x41B5; +constexpr unsigned int mmCRTC2_CRTC_VBI_END__SI = 0x4186; +constexpr unsigned int mmCRTC2_CRTC_VERT_SYNC_CONTROL__SI = 0x41AC; +constexpr unsigned int mmCRTC2_CRTC_VGA_PARAMETER_CAPTURE_MODE__SI = 0x41B7; +constexpr unsigned int mmCRTC2_CRTC_VSYNC_NOM_INT_STATUS__SI = 0x418C; +constexpr unsigned int mmCRTC2_CRTC_V_BLANK_START_END__SI = 0x418D; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_A_CNTL__SI = 0x418F; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_A__SI = 0x418E; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_B_CNTL__SI = 0x4191; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_B__SI = 0x4190; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_CONTROL__SI = 0x418A; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_INT_STATUS__SI = 0x418B; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_MAX__SI = 0x4189; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_MIN__SI = 0x4188; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL__SI = 0x4187; +constexpr unsigned int mmCRTC2_CRTC_V_UPDATE_INT_STATUS__SI = 0x41C4; +constexpr unsigned int mmCRTC2_MASTER_UPDATE_LOCK__SI = 0x41BD; +constexpr unsigned int mmCRTC2_PIXEL_RATE_CNTL__SI = 0x0122; +constexpr unsigned int mmCRTC3_CRTC_ALLOW_STOP_OFF_V_CNT__SI = 0x44C3; +constexpr unsigned int mmCRTC3_CRTC_BLACK_COLOR__SI = 0x44A2; +constexpr unsigned int mmCRTC3_CRTC_BLANK_DATA_COLOR__SI = 0x44A1; +constexpr unsigned int mmCRTC3_CRTC_CONTROL__SI = 0x449C; +constexpr unsigned int mmCRTC3_CRTC_COUNT_CONTROL__SI = 0x44A9; +constexpr unsigned int mmCRTC3_CRTC_COUNT_RESET__SI = 0x44AA; +constexpr unsigned int mmCRTC3_CRTC_DOUBLE_BUFFER_CONTROL__SI = 0x44B6; +constexpr unsigned int mmCRTC3_CRTC_DTMTEST_CNTL__SI = 0x4492; +constexpr unsigned int mmCRTC3_CRTC_DTMTEST_STATUS_POSITION__SI = 0x4493; +constexpr unsigned int mmCRTC3_CRTC_FLOW_CONTROL__SI = 0x4499; +constexpr unsigned int mmCRTC3_CRTC_FORCE_COUNT_NOW_CNTL__SI = 0x4498; +constexpr unsigned int mmCRTC3_CRTC_H_BLANK_START_END__SI = 0x4481; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_A_CNTL__SI = 0x4483; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_A__SI = 0x4482; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_B_CNTL__SI = 0x4485; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_B__SI = 0x4484; +constexpr unsigned int mmCRTC3_CRTC_H_TOTAL__SI = 0x4480; +constexpr unsigned int mmCRTC3_CRTC_INTERLACE_CONTROL__SI = 0x449E; +constexpr unsigned int mmCRTC3_CRTC_INTERLACE_STATUS__SI = 0x449F; +constexpr unsigned int mmCRTC3_CRTC_INTERRUPT_CONTROL__SI = 0x44B4; +constexpr unsigned int mmCRTC3_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__SI = 0x44AB; +constexpr unsigned int mmCRTC3_CRTC_MASTER_EN__SI = 0x44C2; +constexpr unsigned int mmCRTC3_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__SI = 0x44C0; +constexpr unsigned int mmCRTC3_CRTC_MVP_INBAND_CNTL_INSERT__SI = 0x44BF; +constexpr unsigned int mmCRTC3_CRTC_MVP_STATUS__SI = 0x44C1; +constexpr unsigned int mmCRTC3_CRTC_NOM_VERT_POSITION__SI = 0x44A5; +constexpr unsigned int mmCRTC3_CRTC_OVERSCAN_COLOR__SI = 0x44A0; +constexpr unsigned int mmCRTC3_CRTC_PIXEL_DATA_READBACK__SI = 0x449A; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_CONTROL__SI = 0x44B0; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_FRAME__SI = 0x44B2; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_POSITION__SI = 0x44B1; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_STATUS__SI = 0x44AF; +constexpr unsigned int mmCRTC3_CRTC_START_LINE_CONTROL__SI = 0x44B3; +constexpr unsigned int mmCRTC3_CRTC_STATUS_FRAME_COUNT__SI = 0x44A6; +constexpr unsigned int mmCRTC3_CRTC_STATUS_HV_COUNT__SI = 0x44A8; +constexpr unsigned int mmCRTC3_CRTC_STATUS_VF_COUNT__SI = 0x44A7; +constexpr unsigned int mmCRTC3_CRTC_STEREO_CONTROL__SI = 0x44AE; +constexpr unsigned int mmCRTC3_CRTC_STEREO_FORCE_NEXT_EYE__SI = 0x449B; +constexpr unsigned int mmCRTC3_CRTC_STEREO_STATUS__SI = 0x44AD; +constexpr unsigned int mmCRTC3_CRTC_TEST_DEBUG_DATA__SI = 0x44C7; +constexpr unsigned int mmCRTC3_CRTC_TEST_DEBUG_INDEX__SI = 0x44C6; +constexpr unsigned int mmCRTC3_CRTC_TEST_PATTERN_COLOR__SI = 0x44BC; +constexpr unsigned int mmCRTC3_CRTC_TEST_PATTERN_CONTROL__SI = 0x44BA; +constexpr unsigned int mmCRTC3_CRTC_TEST_PATTERN_PARAMETERS__SI = 0x44BB; +constexpr unsigned int mmCRTC3_CRTC_TRIGA_CNTL__SI = 0x4494; +constexpr unsigned int mmCRTC3_CRTC_TRIGA_MANUAL_TRIG__SI = 0x4495; +constexpr unsigned int mmCRTC3_CRTC_TRIGB_CNTL__SI = 0x4496; +constexpr unsigned int mmCRTC3_CRTC_TRIGB_MANUAL_TRIG__SI = 0x4497; +constexpr unsigned int mmCRTC3_CRTC_UPDATE_LOCK__SI = 0x44B5; +constexpr unsigned int mmCRTC3_CRTC_VBI_END__SI = 0x4486; +constexpr unsigned int mmCRTC3_CRTC_VERT_SYNC_CONTROL__SI = 0x44AC; +constexpr unsigned int mmCRTC3_CRTC_VGA_PARAMETER_CAPTURE_MODE__SI = 0x44B7; +constexpr unsigned int mmCRTC3_CRTC_VSYNC_NOM_INT_STATUS__SI = 0x448C; +constexpr unsigned int mmCRTC3_CRTC_V_BLANK_START_END__SI = 0x448D; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_A_CNTL__SI = 0x448F; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_A__SI = 0x448E; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_B_CNTL__SI = 0x4491; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_B__SI = 0x4490; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_CONTROL__SI = 0x448A; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_INT_STATUS__SI = 0x448B; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_MAX__SI = 0x4489; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_MIN__SI = 0x4488; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL__SI = 0x4487; +constexpr unsigned int mmCRTC3_CRTC_V_UPDATE_INT_STATUS__SI = 0x44C4; +constexpr unsigned int mmCRTC3_MASTER_UPDATE_LOCK__SI = 0x44BD; +constexpr unsigned int mmCRTC3_PIXEL_RATE_CNTL__SI = 0x0123; +constexpr unsigned int mmCRTC4_CRTC_ALLOW_STOP_OFF_V_CNT__SI = 0x47C3; +constexpr unsigned int mmCRTC4_CRTC_BLACK_COLOR__SI = 0x47A2; +constexpr unsigned int mmCRTC4_CRTC_BLANK_DATA_COLOR__SI = 0x47A1; +constexpr unsigned int mmCRTC4_CRTC_CONTROL__SI = 0x479C; +constexpr unsigned int mmCRTC4_CRTC_COUNT_CONTROL__SI = 0x47A9; +constexpr unsigned int mmCRTC4_CRTC_COUNT_RESET__SI = 0x47AA; +constexpr unsigned int mmCRTC4_CRTC_DOUBLE_BUFFER_CONTROL__SI = 0x47B6; +constexpr unsigned int mmCRTC4_CRTC_DTMTEST_CNTL__SI = 0x4792; +constexpr unsigned int mmCRTC4_CRTC_DTMTEST_STATUS_POSITION__SI = 0x4793; +constexpr unsigned int mmCRTC4_CRTC_FLOW_CONTROL__SI = 0x4799; +constexpr unsigned int mmCRTC4_CRTC_FORCE_COUNT_NOW_CNTL__SI = 0x4798; +constexpr unsigned int mmCRTC4_CRTC_H_BLANK_START_END__SI = 0x4781; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_A_CNTL__SI = 0x4783; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_A__SI = 0x4782; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_B_CNTL__SI = 0x4785; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_B__SI = 0x4784; +constexpr unsigned int mmCRTC4_CRTC_H_TOTAL__SI = 0x4780; +constexpr unsigned int mmCRTC4_CRTC_INTERLACE_CONTROL__SI = 0x479E; +constexpr unsigned int mmCRTC4_CRTC_INTERLACE_STATUS__SI = 0x479F; +constexpr unsigned int mmCRTC4_CRTC_INTERRUPT_CONTROL__SI = 0x47B4; +constexpr unsigned int mmCRTC4_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__SI = 0x47AB; +constexpr unsigned int mmCRTC4_CRTC_MASTER_EN__SI = 0x47C2; +constexpr unsigned int mmCRTC4_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__SI = 0x47C0; +constexpr unsigned int mmCRTC4_CRTC_MVP_INBAND_CNTL_INSERT__SI = 0x47BF; +constexpr unsigned int mmCRTC4_CRTC_MVP_STATUS__SI = 0x47C1; +constexpr unsigned int mmCRTC4_CRTC_NOM_VERT_POSITION__SI = 0x47A5; +constexpr unsigned int mmCRTC4_CRTC_OVERSCAN_COLOR__SI = 0x47A0; +constexpr unsigned int mmCRTC4_CRTC_PIXEL_DATA_READBACK__SI = 0x479A; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_CONTROL__SI = 0x47B0; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_FRAME__SI = 0x47B2; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_POSITION__SI = 0x47B1; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_STATUS__SI = 0x47AF; +constexpr unsigned int mmCRTC4_CRTC_START_LINE_CONTROL__SI = 0x47B3; +constexpr unsigned int mmCRTC4_CRTC_STATUS_FRAME_COUNT__SI = 0x47A6; +constexpr unsigned int mmCRTC4_CRTC_STATUS_HV_COUNT__SI = 0x47A8; +constexpr unsigned int mmCRTC4_CRTC_STATUS_VF_COUNT__SI = 0x47A7; +constexpr unsigned int mmCRTC4_CRTC_STEREO_CONTROL__SI = 0x47AE; +constexpr unsigned int mmCRTC4_CRTC_STEREO_FORCE_NEXT_EYE__SI = 0x479B; +constexpr unsigned int mmCRTC4_CRTC_STEREO_STATUS__SI = 0x47AD; +constexpr unsigned int mmCRTC4_CRTC_TEST_DEBUG_DATA__SI = 0x47C7; +constexpr unsigned int mmCRTC4_CRTC_TEST_DEBUG_INDEX__SI = 0x47C6; +constexpr unsigned int mmCRTC4_CRTC_TEST_PATTERN_COLOR__SI = 0x47BC; +constexpr unsigned int mmCRTC4_CRTC_TEST_PATTERN_CONTROL__SI = 0x47BA; +constexpr unsigned int mmCRTC4_CRTC_TEST_PATTERN_PARAMETERS__SI = 0x47BB; +constexpr unsigned int mmCRTC4_CRTC_TRIGA_CNTL__SI = 0x4794; +constexpr unsigned int mmCRTC4_CRTC_TRIGA_MANUAL_TRIG__SI = 0x4795; +constexpr unsigned int mmCRTC4_CRTC_TRIGB_CNTL__SI = 0x4796; +constexpr unsigned int mmCRTC4_CRTC_TRIGB_MANUAL_TRIG__SI = 0x4797; +constexpr unsigned int mmCRTC4_CRTC_UPDATE_LOCK__SI = 0x47B5; +constexpr unsigned int mmCRTC4_CRTC_VBI_END__SI = 0x4786; +constexpr unsigned int mmCRTC4_CRTC_VERT_SYNC_CONTROL__SI = 0x47AC; +constexpr unsigned int mmCRTC4_CRTC_VGA_PARAMETER_CAPTURE_MODE__SI = 0x47B7; +constexpr unsigned int mmCRTC4_CRTC_VSYNC_NOM_INT_STATUS__SI = 0x478C; +constexpr unsigned int mmCRTC4_CRTC_V_BLANK_START_END__SI = 0x478D; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_A_CNTL__SI = 0x478F; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_A__SI = 0x478E; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_B_CNTL__SI = 0x4791; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_B__SI = 0x4790; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_CONTROL__SI = 0x478A; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_INT_STATUS__SI = 0x478B; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_MAX__SI = 0x4789; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_MIN__SI = 0x4788; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL__SI = 0x4787; +constexpr unsigned int mmCRTC4_CRTC_V_UPDATE_INT_STATUS__SI = 0x47C4; +constexpr unsigned int mmCRTC4_MASTER_UPDATE_LOCK__SI = 0x47BD; +constexpr unsigned int mmCRTC4_PIXEL_RATE_CNTL__SI = 0x0124; +constexpr unsigned int mmCRTC5_CRTC_ALLOW_STOP_OFF_V_CNT__SI = 0x4AC3; +constexpr unsigned int mmCRTC5_CRTC_BLACK_COLOR__SI = 0x4AA2; +constexpr unsigned int mmCRTC5_CRTC_BLANK_DATA_COLOR__SI = 0x4AA1; +constexpr unsigned int mmCRTC5_CRTC_CONTROL__SI = 0x4A9C; +constexpr unsigned int mmCRTC5_CRTC_COUNT_CONTROL__SI = 0x4AA9; +constexpr unsigned int mmCRTC5_CRTC_COUNT_RESET__SI = 0x4AAA; +constexpr unsigned int mmCRTC5_CRTC_DOUBLE_BUFFER_CONTROL__SI = 0x4AB6; +constexpr unsigned int mmCRTC5_CRTC_DTMTEST_CNTL__SI = 0x4A92; +constexpr unsigned int mmCRTC5_CRTC_DTMTEST_STATUS_POSITION__SI = 0x4A93; +constexpr unsigned int mmCRTC5_CRTC_FLOW_CONTROL__SI = 0x4A99; +constexpr unsigned int mmCRTC5_CRTC_FORCE_COUNT_NOW_CNTL__SI = 0x4A98; +constexpr unsigned int mmCRTC5_CRTC_H_BLANK_START_END__SI = 0x4A81; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_A_CNTL__SI = 0x4A83; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_A__SI = 0x4A82; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_B_CNTL__SI = 0x4A85; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_B__SI = 0x4A84; +constexpr unsigned int mmCRTC5_CRTC_H_TOTAL__SI = 0x4A80; +constexpr unsigned int mmCRTC5_CRTC_INTERLACE_CONTROL__SI = 0x4A9E; +constexpr unsigned int mmCRTC5_CRTC_INTERLACE_STATUS__SI = 0x4A9F; +constexpr unsigned int mmCRTC5_CRTC_INTERRUPT_CONTROL__SI = 0x4AB4; +constexpr unsigned int mmCRTC5_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__SI = 0x4AAB; +constexpr unsigned int mmCRTC5_CRTC_MASTER_EN__SI = 0x4AC2; +constexpr unsigned int mmCRTC5_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__SI = 0x4AC0; +constexpr unsigned int mmCRTC5_CRTC_MVP_INBAND_CNTL_INSERT__SI = 0x4ABF; +constexpr unsigned int mmCRTC5_CRTC_MVP_STATUS__SI = 0x4AC1; +constexpr unsigned int mmCRTC5_CRTC_NOM_VERT_POSITION__SI = 0x4AA5; +constexpr unsigned int mmCRTC5_CRTC_OVERSCAN_COLOR__SI = 0x4AA0; +constexpr unsigned int mmCRTC5_CRTC_PIXEL_DATA_READBACK__SI = 0x4A9A; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_CONTROL__SI = 0x4AB0; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_FRAME__SI = 0x4AB2; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_POSITION__SI = 0x4AB1; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_STATUS__SI = 0x4AAF; +constexpr unsigned int mmCRTC5_CRTC_START_LINE_CONTROL__SI = 0x4AB3; +constexpr unsigned int mmCRTC5_CRTC_STATUS_FRAME_COUNT__SI = 0x4AA6; +constexpr unsigned int mmCRTC5_CRTC_STATUS_HV_COUNT__SI = 0x4AA8; +constexpr unsigned int mmCRTC5_CRTC_STATUS_VF_COUNT__SI = 0x4AA7; +constexpr unsigned int mmCRTC5_CRTC_STEREO_CONTROL__SI = 0x4AAE; +constexpr unsigned int mmCRTC5_CRTC_STEREO_FORCE_NEXT_EYE__SI = 0x4A9B; +constexpr unsigned int mmCRTC5_CRTC_STEREO_STATUS__SI = 0x4AAD; +constexpr unsigned int mmCRTC5_CRTC_TEST_DEBUG_DATA__SI = 0x4AC7; +constexpr unsigned int mmCRTC5_CRTC_TEST_DEBUG_INDEX__SI = 0x4AC6; +constexpr unsigned int mmCRTC5_CRTC_TEST_PATTERN_COLOR__SI = 0x4ABC; +constexpr unsigned int mmCRTC5_CRTC_TEST_PATTERN_CONTROL__SI = 0x4ABA; +constexpr unsigned int mmCRTC5_CRTC_TEST_PATTERN_PARAMETERS__SI = 0x4ABB; +constexpr unsigned int mmCRTC5_CRTC_TRIGA_CNTL__SI = 0x4A94; +constexpr unsigned int mmCRTC5_CRTC_TRIGA_MANUAL_TRIG__SI = 0x4A95; +constexpr unsigned int mmCRTC5_CRTC_TRIGB_CNTL__SI = 0x4A96; +constexpr unsigned int mmCRTC5_CRTC_TRIGB_MANUAL_TRIG__SI = 0x4A97; +constexpr unsigned int mmCRTC5_CRTC_UPDATE_LOCK__SI = 0x4AB5; +constexpr unsigned int mmCRTC5_CRTC_VBI_END__SI = 0x4A86; +constexpr unsigned int mmCRTC5_CRTC_VERT_SYNC_CONTROL__SI = 0x4AAC; +constexpr unsigned int mmCRTC5_CRTC_VGA_PARAMETER_CAPTURE_MODE__SI = 0x4AB7; +constexpr unsigned int mmCRTC5_CRTC_VSYNC_NOM_INT_STATUS__SI = 0x4A8C; +constexpr unsigned int mmCRTC5_CRTC_V_BLANK_START_END__SI = 0x4A8D; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_A_CNTL__SI = 0x4A8F; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_A__SI = 0x4A8E; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_B_CNTL__SI = 0x4A91; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_B__SI = 0x4A90; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_CONTROL__SI = 0x4A8A; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_INT_STATUS__SI = 0x4A8B; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_MAX__SI = 0x4A89; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_MIN__SI = 0x4A88; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL__SI = 0x4A87; +constexpr unsigned int mmCRTC5_CRTC_V_UPDATE_INT_STATUS__SI = 0x4AC4; +constexpr unsigned int mmCRTC5_MASTER_UPDATE_LOCK__SI = 0x4ABD; +constexpr unsigned int mmCRTC5_PIXEL_RATE_CNTL__SI = 0x0125; +constexpr unsigned int mmCRTC8_DATA__SI__VI = 0x00ED; +constexpr unsigned int mmCRTC8_IDX__SI__VI = 0x00ED; +constexpr unsigned int mmCRTC_ALLOW_STOP_OFF_V_CNT__SI__VI = 0x1BC3; +constexpr unsigned int mmCRTC_BLACK_COLOR__SI = 0x1BA2; +constexpr unsigned int mmCRTC_BLANK_CONTROL = 0x1B9D; +constexpr unsigned int mmCRTC_BLANK_DATA_COLOR__SI = 0x1BA1; +constexpr unsigned int mmCRTC_CONTROL__SI__VI = 0x1B9C; +constexpr unsigned int mmCRTC_COUNT_CONTROL__SI__VI = 0x1BA9; +constexpr unsigned int mmCRTC_COUNT_RESET__SI__VI = 0x1BAA; +constexpr unsigned int mmCRTC_DOUBLE_BUFFER_CONTROL__SI__VI = 0x1BB6; +constexpr unsigned int mmCRTC_DTMTEST_CNTL__SI__VI = 0x1B92; +constexpr unsigned int mmCRTC_DTMTEST_STATUS_POSITION__SI__VI = 0x1B93; +constexpr unsigned int mmCRTC_FLOW_CONTROL__SI__VI = 0x1B99; +constexpr unsigned int mmCRTC_FORCE_COUNT_NOW_CNTL__SI__VI = 0x1B98; +constexpr unsigned int mmCRTC_H_BLANK_START_END__SI__VI = 0x1B81; +constexpr unsigned int mmCRTC_H_SYNC_A_CNTL__SI__VI = 0x1B83; +constexpr unsigned int mmCRTC_H_SYNC_A__SI__VI = 0x1B82; +constexpr unsigned int mmCRTC_H_SYNC_B_CNTL__SI__VI = 0x1B85; +constexpr unsigned int mmCRTC_H_SYNC_B__SI__VI = 0x1B84; +constexpr unsigned int mmCRTC_H_TOTAL__SI__VI = 0x1B80; +constexpr unsigned int mmCRTC_INTERLACE_CONTROL__SI__VI = 0x1B9E; +constexpr unsigned int mmCRTC_INTERLACE_STATUS__SI__VI = 0x1B9F; +constexpr unsigned int mmCRTC_INTERRUPT_CONTROL__SI__VI = 0x1BB4; +constexpr unsigned int mmCRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__SI__VI = 0x1BAB; +constexpr unsigned int mmCRTC_MASTER_EN__SI__VI = 0x1BC2; +constexpr unsigned int mmCRTC_MVP_INBAND_CNTL_INSERT_TIMER__SI__VI = 0x1BC0; +constexpr unsigned int mmCRTC_MVP_INBAND_CNTL_INSERT__SI__VI = 0x1BBF; +constexpr unsigned int mmCRTC_MVP_STATUS__SI__VI = 0x1BC1; +constexpr unsigned int mmCRTC_NOM_VERT_POSITION__SI__VI = 0x1BA5; +constexpr unsigned int mmCRTC_OVERSCAN_COLOR__SI = 0x1BA0; +constexpr unsigned int mmCRTC_PIXEL_DATA_READBACK__SI = 0x1B9A; +constexpr unsigned int mmCRTC_SNAPSHOT_CONTROL__SI__VI = 0x1BB0; +constexpr unsigned int mmCRTC_SNAPSHOT_FRAME__SI__VI = 0x1BB2; +constexpr unsigned int mmCRTC_SNAPSHOT_POSITION__SI__VI = 0x1BB1; +constexpr unsigned int mmCRTC_SNAPSHOT_STATUS__SI__VI = 0x1BAF; +constexpr unsigned int mmCRTC_START_LINE_CONTROL__SI__VI = 0x1BB3; +constexpr unsigned int mmCRTC_STATUS = 0x1BA3; +constexpr unsigned int mmCRTC_STATUS_FRAME_COUNT__SI__VI = 0x1BA6; +constexpr unsigned int mmCRTC_STATUS_HV_COUNT__SI__VI = 0x1BA8; +constexpr unsigned int mmCRTC_STATUS_POSITION__SI__VI = 0x1BA4; +constexpr unsigned int mmCRTC_STATUS_VF_COUNT__SI__VI = 0x1BA7; +constexpr unsigned int mmCRTC_STEREO_CONTROL__SI__VI = 0x1BAE; +constexpr unsigned int mmCRTC_STEREO_FORCE_NEXT_EYE__SI = 0x1B9B; +constexpr unsigned int mmCRTC_STEREO_STATUS__SI__VI = 0x1BAD; +constexpr unsigned int mmCRTC_TEST_DEBUG_DATA__SI__VI = 0x1BC7; +constexpr unsigned int mmCRTC_TEST_DEBUG_INDEX__SI__VI = 0x1BC6; +constexpr unsigned int mmCRTC_TEST_PATTERN_COLOR__SI__VI = 0x1BBC; +constexpr unsigned int mmCRTC_TEST_PATTERN_CONTROL__SI__VI = 0x1BBA; +constexpr unsigned int mmCRTC_TEST_PATTERN_PARAMETERS__SI__VI = 0x1BBB; +constexpr unsigned int mmCRTC_TRIGA_CNTL__SI__VI = 0x1B94; +constexpr unsigned int mmCRTC_TRIGA_MANUAL_TRIG__SI__VI = 0x1B95; +constexpr unsigned int mmCRTC_TRIGB_CNTL__SI__VI = 0x1B96; +constexpr unsigned int mmCRTC_TRIGB_MANUAL_TRIG__SI__VI = 0x1B97; +constexpr unsigned int mmCRTC_UPDATE_LOCK__SI__VI = 0x1BB5; +constexpr unsigned int mmCRTC_VBI_END__SI__VI = 0x1B86; +constexpr unsigned int mmCRTC_VERT_SYNC_CONTROL__SI__VI = 0x1BAC; +constexpr unsigned int mmCRTC_VGA_PARAMETER_CAPTURE_MODE__SI__VI = 0x1BB7; +constexpr unsigned int mmCRTC_VSYNC_NOM_INT_STATUS__SI__VI = 0x1B8C; +constexpr unsigned int mmCRTC_V_BLANK_START_END__SI__VI = 0x1B8D; +constexpr unsigned int mmCRTC_V_SYNC_A_CNTL__SI__VI = 0x1B8F; +constexpr unsigned int mmCRTC_V_SYNC_A__SI__VI = 0x1B8E; +constexpr unsigned int mmCRTC_V_SYNC_B_CNTL__SI__VI = 0x1B91; +constexpr unsigned int mmCRTC_V_SYNC_B__SI__VI = 0x1B90; +constexpr unsigned int mmCRTC_V_TOTAL_CONTROL__SI__VI = 0x1B8A; +constexpr unsigned int mmCRTC_V_TOTAL_INT_STATUS__SI__VI = 0x1B8B; +constexpr unsigned int mmCRTC_V_TOTAL_MAX__SI__VI = 0x1B89; +constexpr unsigned int mmCRTC_V_TOTAL_MIN__SI__VI = 0x1B88; +constexpr unsigned int mmCRTC_V_TOTAL__SI__VI = 0x1B87; +constexpr unsigned int mmCRTC_V_UPDATE_INT_STATUS__SI__VI = 0x1BC4; +constexpr unsigned int mmCS_COPY_STATE = 0xA1F3; +constexpr unsigned int mmCUR_COLOR1__SI__VI = 0x1A6C; +constexpr unsigned int mmCUR_COLOR2__SI__VI = 0x1A6D; +constexpr unsigned int mmCUR_CONTROL__SI__VI = 0x1A66; +constexpr unsigned int mmCUR_HOT_SPOT__SI__VI = 0x1A6B; +constexpr unsigned int mmCUR_POSITION__SI__VI = 0x1A6A; +constexpr unsigned int mmCUR_SIZE__SI__VI = 0x1A68; +constexpr unsigned int mmCUR_SURFACE_ADDRESS_HIGH__SI__VI = 0x1A69; +constexpr unsigned int mmCUR_SURFACE_ADDRESS__SI__VI = 0x1A67; +constexpr unsigned int mmCUR_UPDATE__SI__VI = 0x1A6E; +constexpr unsigned int mmD1VGA_CONTROL__SI__VI = 0x00CC; +constexpr unsigned int mmD2VGA_CONTROL__SI__VI = 0x00CE; +constexpr unsigned int mmD3VGA_CONTROL__SI__VI = 0x00F8; +constexpr unsigned int mmD4VGA_CONTROL__SI__VI = 0x00F9; +constexpr unsigned int mmD5VGA_CONTROL__SI__VI = 0x00FA; +constexpr unsigned int mmD6VGA_CONTROL__SI__VI = 0x00FB; +constexpr unsigned int mmDAC_AUTODETECT_CONTROL2__SI = 0x19AF; +constexpr unsigned int mmDAC_AUTODETECT_CONTROL3__SI = 0x19B0; +constexpr unsigned int mmDAC_AUTODETECT_CONTROL__SI = 0x19AE; +constexpr unsigned int mmDAC_AUTODETECT_INT_CONTROL__SI = 0x19B2; +constexpr unsigned int mmDAC_AUTODETECT_STATUS__SI = 0x19B1; +constexpr unsigned int mmDAC_COMPARATOR_ENABLE__SI = 0x19B7; +constexpr unsigned int mmDAC_COMPARATOR_OUTPUT__SI = 0x19B8; +constexpr unsigned int mmDAC_CONTROL__SI = 0x19B6; +constexpr unsigned int mmDAC_CRC_CONTROL__SI = 0x19A7; +constexpr unsigned int mmDAC_CRC_EN__SI = 0x19A6; +constexpr unsigned int mmDAC_CRC_SIG_CONTROL_MASK__SI = 0x19A9; +constexpr unsigned int mmDAC_CRC_SIG_CONTROL__SI = 0x19AB; +constexpr unsigned int mmDAC_CRC_SIG_RGB_MASK__SI = 0x19A8; +constexpr unsigned int mmDAC_CRC_SIG_RGB__SI = 0x19AA; +constexpr unsigned int mmDAC_DATA__SI__VI = 0x00F2; +constexpr unsigned int mmDAC_DFT_CONFIG__SI = 0x19BA; +constexpr unsigned int mmDAC_ENABLE__SI = 0x19A4; +constexpr unsigned int mmDAC_FORCE_DATA__SI = 0x19B4; +constexpr unsigned int mmDAC_FORCE_OUTPUT_CNTL__SI = 0x19B3; +constexpr unsigned int mmDAC_MACRO_CNTL__SI = 0x1939; +constexpr unsigned int mmDAC_MASK__SI__VI = 0x00F1; +constexpr unsigned int mmDAC_POWERDOWN__SI = 0x19B5; +constexpr unsigned int mmDAC_PWR_CNTL__SI = 0x19B9; +constexpr unsigned int mmDAC_R_INDEX__SI__VI = 0x00F1; +constexpr unsigned int mmDAC_SOURCE_SELECT__SI = 0x19A5; +constexpr unsigned int mmDAC_STEREOSYNC_SELECT__SI = 0x19AD; +constexpr unsigned int mmDAC_SYNC_TRISTATE_CONTROL__SI = 0x19AC; +constexpr unsigned int mmDAC_W_INDEX__SI__VI = 0x00F2; +constexpr unsigned int mmDATA_FORMAT__SI = 0x1AC0; +constexpr unsigned int mmDBG_BYPASS_SRBM_ACCESS__CI = 0x14EB; +constexpr unsigned int mmDB_ALPHA_TO_MASK = 0xA2DC; +constexpr unsigned int mmDB_CGTT_CLK_CTRL_0__CI__VI = 0xF0A4; +constexpr unsigned int mmDB_CGTT_CLK_CTRL_0__SI = 0x261A; +constexpr unsigned int mmDB_COUNT_CONTROL = 0xA001; +constexpr unsigned int mmDB_CREDIT_LIMIT = 0x2614; +constexpr unsigned int mmDB_DEBUG = 0x260C; +constexpr unsigned int mmDB_DEBUG2 = 0x260D; +constexpr unsigned int mmDB_DEBUG3 = 0x260E; +constexpr unsigned int mmDB_DEBUG4 = 0x260F; +constexpr unsigned int mmDB_DEPTH_BOUNDS_MAX = 0xA009; +constexpr unsigned int mmDB_DEPTH_BOUNDS_MIN = 0xA008; +constexpr unsigned int mmDB_DEPTH_CLEAR = 0xA00B; +constexpr unsigned int mmDB_DEPTH_CONTROL = 0xA200; +constexpr unsigned int mmDB_DEPTH_INFO = 0xA00F; +constexpr unsigned int mmDB_DEPTH_SIZE = 0xA016; +constexpr unsigned int mmDB_DEPTH_SLICE = 0xA017; +constexpr unsigned int mmDB_DEPTH_VIEW = 0xA002; +constexpr unsigned int mmDB_EQAA = 0xA201; +constexpr unsigned int mmDB_FIFO_DEPTH1 = 0x2618; +constexpr unsigned int mmDB_FIFO_DEPTH2 = 0x2619; +constexpr unsigned int mmDB_FREE_CACHELINES = 0x2617; +constexpr unsigned int mmDB_HTILE_DATA_BASE = 0xA005; +constexpr unsigned int mmDB_HTILE_SURFACE = 0xA2AF; +constexpr unsigned int mmDB_OCCLUSION_COUNT0_HI__CI__VI = 0xC3C1; +constexpr unsigned int mmDB_OCCLUSION_COUNT0_LOW__CI__VI = 0xC3C0; +constexpr unsigned int mmDB_OCCLUSION_COUNT1_HI__CI__VI = 0xC3C3; +constexpr unsigned int mmDB_OCCLUSION_COUNT1_LOW__CI__VI = 0xC3C2; +constexpr unsigned int mmDB_OCCLUSION_COUNT2_HI__CI__VI = 0xC3C5; +constexpr unsigned int mmDB_OCCLUSION_COUNT2_LOW__CI__VI = 0xC3C4; +constexpr unsigned int mmDB_OCCLUSION_COUNT3_HI__CI__VI = 0xC3C7; +constexpr unsigned int mmDB_OCCLUSION_COUNT3_LOW__CI__VI = 0xC3C6; +constexpr unsigned int mmDB_PERFCOUNTER0_HI__CI__VI = 0xD441; +constexpr unsigned int mmDB_PERFCOUNTER0_HI__SI = 0x2602; +constexpr unsigned int mmDB_PERFCOUNTER0_LO__CI__VI = 0xD440; +constexpr unsigned int mmDB_PERFCOUNTER0_LO__SI = 0x2601; +constexpr unsigned int mmDB_PERFCOUNTER0_SELECT1__CI__VI = 0xDC41; +constexpr unsigned int mmDB_PERFCOUNTER0_SELECT__CI__VI = 0xDC40; +constexpr unsigned int mmDB_PERFCOUNTER0_SELECT__SI = 0x2600; +constexpr unsigned int mmDB_PERFCOUNTER1_HI__CI__VI = 0xD443; +constexpr unsigned int mmDB_PERFCOUNTER1_HI__SI = 0x2605; +constexpr unsigned int mmDB_PERFCOUNTER1_LO__CI__VI = 0xD442; +constexpr unsigned int mmDB_PERFCOUNTER1_LO__SI = 0x2604; +constexpr unsigned int mmDB_PERFCOUNTER1_SELECT1__CI__VI = 0xDC43; +constexpr unsigned int mmDB_PERFCOUNTER1_SELECT__CI__VI = 0xDC42; +constexpr unsigned int mmDB_PERFCOUNTER1_SELECT__SI = 0x2603; +constexpr unsigned int mmDB_PERFCOUNTER2_HI__CI__VI = 0xD445; +constexpr unsigned int mmDB_PERFCOUNTER2_HI__SI = 0x2608; +constexpr unsigned int mmDB_PERFCOUNTER2_LO__CI__VI = 0xD444; +constexpr unsigned int mmDB_PERFCOUNTER2_LO__SI = 0x2607; +constexpr unsigned int mmDB_PERFCOUNTER2_SELECT__CI__VI = 0xDC44; +constexpr unsigned int mmDB_PERFCOUNTER2_SELECT__SI = 0x2606; +constexpr unsigned int mmDB_PERFCOUNTER3_HI__CI__VI = 0xD447; +constexpr unsigned int mmDB_PERFCOUNTER3_HI__SI = 0x260B; +constexpr unsigned int mmDB_PERFCOUNTER3_LO__CI__VI = 0xD446; +constexpr unsigned int mmDB_PERFCOUNTER3_LO__SI = 0x260A; +constexpr unsigned int mmDB_PERFCOUNTER3_SELECT__CI__VI = 0xDC46; +constexpr unsigned int mmDB_PERFCOUNTER3_SELECT__SI = 0x2609; +constexpr unsigned int mmDB_PRELOAD_CONTROL = 0xA2B2; +constexpr unsigned int mmDB_READ_DEBUG_0 = 0x2620; +constexpr unsigned int mmDB_READ_DEBUG_1 = 0x2621; +constexpr unsigned int mmDB_READ_DEBUG_2 = 0x2622; +constexpr unsigned int mmDB_READ_DEBUG_3 = 0x2623; +constexpr unsigned int mmDB_READ_DEBUG_4 = 0x2624; +constexpr unsigned int mmDB_READ_DEBUG_5 = 0x2625; +constexpr unsigned int mmDB_READ_DEBUG_6 = 0x2626; +constexpr unsigned int mmDB_READ_DEBUG_7 = 0x2627; +constexpr unsigned int mmDB_READ_DEBUG_8 = 0x2628; +constexpr unsigned int mmDB_READ_DEBUG_9 = 0x2629; +constexpr unsigned int mmDB_READ_DEBUG_A = 0x262A; +constexpr unsigned int mmDB_READ_DEBUG_B = 0x262B; +constexpr unsigned int mmDB_READ_DEBUG_C = 0x262C; +constexpr unsigned int mmDB_READ_DEBUG_D = 0x262D; +constexpr unsigned int mmDB_READ_DEBUG_E = 0x262E; +constexpr unsigned int mmDB_READ_DEBUG_F = 0x262F; +constexpr unsigned int mmDB_RENDER_CONTROL = 0xA000; +constexpr unsigned int mmDB_RENDER_OVERRIDE = 0xA003; +constexpr unsigned int mmDB_RENDER_OVERRIDE2 = 0xA004; +constexpr unsigned int mmDB_RING_CONTROL__CI__VI = 0x261B; +constexpr unsigned int mmDB_SHADER_CONTROL = 0xA203; +constexpr unsigned int mmDB_SRESULTS_COMPARE_STATE0 = 0xA2B0; +constexpr unsigned int mmDB_SRESULTS_COMPARE_STATE1 = 0xA2B1; +constexpr unsigned int mmDB_STENCILREFMASK = 0xA10C; +constexpr unsigned int mmDB_STENCILREFMASK_BF = 0xA10D; +constexpr unsigned int mmDB_STENCIL_CLEAR = 0xA00A; +constexpr unsigned int mmDB_STENCIL_CONTROL = 0xA10B; +constexpr unsigned int mmDB_STENCIL_INFO = 0xA011; +constexpr unsigned int mmDB_STENCIL_READ_BASE = 0xA013; +constexpr unsigned int mmDB_STENCIL_WRITE_BASE = 0xA015; +constexpr unsigned int mmDB_SUBTILE_CONTROL = 0x2616; +constexpr unsigned int mmDB_WATERMARKS = 0x2615; +constexpr unsigned int mmDB_ZPASS_COUNT_HI__CI__VI = 0xC3FF; +constexpr unsigned int mmDB_ZPASS_COUNT_HI__SI = 0x261D; +constexpr unsigned int mmDB_ZPASS_COUNT_LOW__CI__VI = 0xC3FE; +constexpr unsigned int mmDB_ZPASS_COUNT_LOW__SI = 0x261C; +constexpr unsigned int mmDB_Z_INFO = 0xA010; +constexpr unsigned int mmDB_Z_READ_BASE = 0xA012; +constexpr unsigned int mmDB_Z_WRITE_BASE = 0xA014; +constexpr unsigned int mmDCCG_AUDIO_DTO0_MODULE__SI = 0x0154; +constexpr unsigned int mmDCCG_AUDIO_DTO0_PHASE__SI = 0x0153; +constexpr unsigned int mmDCCG_GATE_DISABLE_CNTL__SI = 0x011F; +constexpr unsigned int mmDCCG_TEST_CLK_SEL__SI = 0x0147; +constexpr unsigned int mmDCCG_TEST_DEBUG_DATA__SI = 0x0159; +constexpr unsigned int mmDCCG_TEST_DEBUG_INDEX__SI = 0x0158; +constexpr unsigned int mmDCCG_VPCLK_CNTL__SI = 0x015E; +constexpr unsigned int mmDCDEBUG_BUS_CLK1_SEL__SI = 0x1860; +constexpr unsigned int mmDCDEBUG_BUS_CLK2_SEL__SI = 0x1861; +constexpr unsigned int mmDCDEBUG_BUS_CLK3_SEL__SI = 0x1862; +constexpr unsigned int mmDCDEBUG_BUS_CLK4_SEL__SI = 0x1863; +constexpr unsigned int mmDCDEBUG_OUT_CNTL__SI = 0x186B; +constexpr unsigned int mmDCDEBUG_OUT_PIN_OVERRIDE__SI = 0x186A; +constexpr unsigned int mmDCIO_DEBUG__SI = 0x196F; +constexpr unsigned int mmDCIO_IMPCAL_CNTL_AB__SI = 0x194C; +constexpr unsigned int mmDCIO_IMPCAL_CNTL_CD__SI = 0x194F; +constexpr unsigned int mmDCIO_IMPCAL_CNTL_EF__SI = 0x1952; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_DATA_SYNCHRONIZATION__SI = 0x1984; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_REG_TEST_OUTPUT__SI = 0x1986; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_DATA_SYNCHRONIZATION__SI = 0x1990; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_REG_TEST_OUTPUT__SI = 0x1992; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_DATA_SYNCHRONIZATION__SI = 0x199C; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_REG_TEST_OUTPUT__SI = 0x199E; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_DATA_SYNCHRONIZATION__SI = 0x19C4; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_REG_TEST_OUTPUT__SI = 0x19C6; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_DATA_SYNCHRONIZATION__SI = 0x19D0; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_REG_TEST_OUTPUT__SI = 0x19D2; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_DATA_SYNCHRONIZATION__SI = 0x19DC; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_REG_TEST_OUTPUT__SI = 0x19DE; +constexpr unsigned int mmDCI_TEST_DEBUG_DATA__SI = 0x0321; +constexpr unsigned int mmDCI_TEST_DEBUG_INDEX__SI = 0x0320; +constexpr unsigned int mmDCP0_CUR_COLOR1__SI__VI = 0x1A6C; +constexpr unsigned int mmDCP0_CUR_COLOR2__SI__VI = 0x1A6D; +constexpr unsigned int mmDCP0_CUR_CONTROL__SI__VI = 0x1A66; +constexpr unsigned int mmDCP0_CUR_HOT_SPOT__SI__VI = 0x1A6B; +constexpr unsigned int mmDCP0_CUR_POSITION__SI__VI = 0x1A6A; +constexpr unsigned int mmDCP0_CUR_SIZE__SI__VI = 0x1A68; +constexpr unsigned int mmDCP0_CUR_SURFACE_ADDRESS_HIGH__SI__VI = 0x1A69; +constexpr unsigned int mmDCP0_CUR_SURFACE_ADDRESS__SI__VI = 0x1A67; +constexpr unsigned int mmDCP0_CUR_UPDATE__SI__VI = 0x1A6E; +constexpr unsigned int mmDCP0_DCP_CRC_CONTROL__SI__VI = 0x1A87; +constexpr unsigned int mmDCP0_DCP_CRC_CURRENT__SI__VI = 0x1A89; +constexpr unsigned int mmDCP0_DCP_CRC_LAST__SI__VI = 0x1A8B; +constexpr unsigned int mmDCP0_DCP_CRC_MASK__SI__VI = 0x1A88; +constexpr unsigned int mmDCP0_DCP_DEBUG__SI__VI = 0x1A8D; +constexpr unsigned int mmDCP0_DCP_LB_DATA_GAP_BETWEEN_CHUNK__SI__VI = 0x1A91; +constexpr unsigned int mmDCP0_DCP_TEST_DEBUG_DATA__SI__VI = 0x1A96; +constexpr unsigned int mmDCP0_DCP_TEST_DEBUG_INDEX__SI__VI = 0x1A95; +constexpr unsigned int mmDCP0_DC_LUT_30_COLOR__SI__VI = 0x1A7C; +constexpr unsigned int mmDCP0_DC_LUT_AUTOFILL__SI__VI = 0x1A7F; +constexpr unsigned int mmDCP0_DC_LUT_BLACK_OFFSET_BLUE__SI__VI = 0x1A81; +constexpr unsigned int mmDCP0_DC_LUT_BLACK_OFFSET_GREEN__SI__VI = 0x1A82; +constexpr unsigned int mmDCP0_DC_LUT_BLACK_OFFSET_RED__SI__VI = 0x1A83; +constexpr unsigned int mmDCP0_DC_LUT_CONTROL__SI__VI = 0x1A80; +constexpr unsigned int mmDCP0_DC_LUT_PWL_DATA__SI__VI = 0x1A7B; +constexpr unsigned int mmDCP0_DC_LUT_RW_INDEX__SI__VI = 0x1A79; +constexpr unsigned int mmDCP0_DC_LUT_RW_MODE__SI__VI = 0x1A78; +constexpr unsigned int mmDCP0_DC_LUT_SEQ_COLOR__SI__VI = 0x1A7A; +constexpr unsigned int mmDCP0_DC_LUT_WHITE_OFFSET_BLUE__SI__VI = 0x1A84; +constexpr unsigned int mmDCP0_DC_LUT_WHITE_OFFSET_GREEN__SI__VI = 0x1A85; +constexpr unsigned int mmDCP0_DC_LUT_WHITE_OFFSET_RED__SI__VI = 0x1A86; +constexpr unsigned int mmDCP0_DC_LUT_WRITE_EN_MASK__SI__VI = 0x1A7E; +constexpr unsigned int mmDCP0_GRPH_COMPRESS_PITCH__SI__VI = 0x1A1A; +constexpr unsigned int mmDCP0_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__SI__VI = 0x1A1B; +constexpr unsigned int mmDCP0_GRPH_COMPRESS_SURFACE_ADDRESS__SI__VI = 0x1A19; +constexpr unsigned int mmDCP0_GRPH_CONTROL = 0x1A01; +constexpr unsigned int mmDCP0_GRPH_DFQ_CONTROL__SI__VI = 0x1A14; +constexpr unsigned int mmDCP0_GRPH_DFQ_STATUS__SI__VI = 0x1A15; +constexpr unsigned int mmDCP0_GRPH_ENABLE__SI__VI = 0x1A00; +constexpr unsigned int mmDCP0_GRPH_FLIP_CONTROL = 0x1A12; +constexpr unsigned int mmDCP0_GRPH_INTERRUPT_CONTROL__SI__VI = 0x1A17; +constexpr unsigned int mmDCP0_GRPH_INTERRUPT_STATUS__SI__VI = 0x1A16; +constexpr unsigned int mmDCP0_GRPH_LUT_10BIT_BYPASS__SI__VI = 0x1A02; +constexpr unsigned int mmDCP0_GRPH_PITCH = 0x1A06; +constexpr unsigned int mmDCP0_GRPH_PRIMARY_SURFACE_ADDRESS = 0x1A04; +constexpr unsigned int mmDCP0_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH = 0x1A07; +constexpr unsigned int mmDCP0_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__SI__VI = 0x1A08; +constexpr unsigned int mmDCP0_GRPH_SECONDARY_SURFACE_ADDRESS__SI__VI = 0x1A05; +constexpr unsigned int mmDCP0_GRPH_SURFACE_ADDRESS_HIGH_INUSE__SI__VI = 0x1A18; +constexpr unsigned int mmDCP0_GRPH_SURFACE_ADDRESS_INUSE__SI__VI = 0x1A13; +constexpr unsigned int mmDCP0_GRPH_SURFACE_OFFSET_X__SI__VI = 0x1A09; +constexpr unsigned int mmDCP0_GRPH_SURFACE_OFFSET_Y__SI__VI = 0x1A0A; +constexpr unsigned int mmDCP0_GRPH_SWAP_CNTL__SI__VI = 0x1A03; +constexpr unsigned int mmDCP0_GRPH_UPDATE = 0x1A11; +constexpr unsigned int mmDCP0_GRPH_X_END__SI__VI = 0x1A0D; +constexpr unsigned int mmDCP0_GRPH_X_START__SI__VI = 0x1A0B; +constexpr unsigned int mmDCP0_GRPH_Y_END__SI__VI = 0x1A0E; +constexpr unsigned int mmDCP0_GRPH_Y_START__SI__VI = 0x1A0C; +constexpr unsigned int mmDCP0_OVLSCL_EDGE_PIXEL_CNTL__SI__VI = 0x1A2C; +constexpr unsigned int mmDCP0_OVL_CONTROL1__SI__VI = 0x1A1D; +constexpr unsigned int mmDCP0_OVL_CONTROL2__SI__VI = 0x1A1E; +constexpr unsigned int mmDCP0_OVL_DFQ_CONTROL__SI__VI = 0x1A29; +constexpr unsigned int mmDCP0_OVL_DFQ_STATUS__SI__VI = 0x1A2A; +constexpr unsigned int mmDCP0_OVL_ENABLE__SI__VI = 0x1A1C; +constexpr unsigned int mmDCP0_OVL_END__SI__VI = 0x1A26; +constexpr unsigned int mmDCP0_OVL_PITCH__SI__VI = 0x1A21; +constexpr unsigned int mmDCP0_OVL_START__SI__VI = 0x1A25; +constexpr unsigned int mmDCP0_OVL_SURFACE_ADDRESS = 0x1A20; +constexpr unsigned int mmDCP0_OVL_SURFACE_ADDRESS_HIGH = 0x1A22; +constexpr unsigned int mmDCP0_OVL_SURFACE_ADDRESS_HIGH_INUSE__SI__VI = 0x1A2B; +constexpr unsigned int mmDCP0_OVL_SURFACE_ADDRESS_INUSE__SI__VI = 0x1A28; +constexpr unsigned int mmDCP0_OVL_SURFACE_OFFSET_X__SI__VI = 0x1A23; +constexpr unsigned int mmDCP0_OVL_SURFACE_OFFSET_Y__SI__VI = 0x1A24; +constexpr unsigned int mmDCP0_OVL_SWAP_CNTL__SI__VI = 0x1A1F; +constexpr unsigned int mmDCP0_OVL_UPDATE__SI__VI = 0x1A27; +constexpr unsigned int mmDCP1_CUR_COLOR1__SI = 0x1D6C; +constexpr unsigned int mmDCP1_CUR_COLOR2__SI = 0x1D6D; +constexpr unsigned int mmDCP1_CUR_CONTROL__SI = 0x1D66; +constexpr unsigned int mmDCP1_CUR_HOT_SPOT__SI = 0x1D6B; +constexpr unsigned int mmDCP1_CUR_POSITION__SI = 0x1D6A; +constexpr unsigned int mmDCP1_CUR_SIZE__SI = 0x1D68; +constexpr unsigned int mmDCP1_CUR_SURFACE_ADDRESS_HIGH__SI = 0x1D69; +constexpr unsigned int mmDCP1_CUR_SURFACE_ADDRESS__SI = 0x1D67; +constexpr unsigned int mmDCP1_CUR_UPDATE__SI = 0x1D6E; +constexpr unsigned int mmDCP1_DCP_CRC_CONTROL__SI = 0x1D87; +constexpr unsigned int mmDCP1_DCP_CRC_CURRENT__SI = 0x1D89; +constexpr unsigned int mmDCP1_DCP_CRC_LAST__SI = 0x1D8B; +constexpr unsigned int mmDCP1_DCP_CRC_MASK__SI = 0x1D88; +constexpr unsigned int mmDCP1_DCP_DEBUG__SI = 0x1D8D; +constexpr unsigned int mmDCP1_DCP_LB_DATA_GAP_BETWEEN_CHUNK__SI = 0x1D91; +constexpr unsigned int mmDCP1_DCP_TEST_DEBUG_DATA__SI = 0x1D96; +constexpr unsigned int mmDCP1_DCP_TEST_DEBUG_INDEX__SI = 0x1D95; +constexpr unsigned int mmDCP1_DC_LUT_30_COLOR__SI = 0x1D7C; +constexpr unsigned int mmDCP1_DC_LUT_AUTOFILL__SI = 0x1D7F; +constexpr unsigned int mmDCP1_DC_LUT_BLACK_OFFSET_BLUE__SI = 0x1D81; +constexpr unsigned int mmDCP1_DC_LUT_BLACK_OFFSET_GREEN__SI = 0x1D82; +constexpr unsigned int mmDCP1_DC_LUT_BLACK_OFFSET_RED__SI = 0x1D83; +constexpr unsigned int mmDCP1_DC_LUT_CONTROL__SI = 0x1D80; +constexpr unsigned int mmDCP1_DC_LUT_PWL_DATA__SI = 0x1D7B; +constexpr unsigned int mmDCP1_DC_LUT_RW_INDEX__SI = 0x1D79; +constexpr unsigned int mmDCP1_DC_LUT_RW_MODE__SI = 0x1D78; +constexpr unsigned int mmDCP1_DC_LUT_SEQ_COLOR__SI = 0x1D7A; +constexpr unsigned int mmDCP1_DC_LUT_WHITE_OFFSET_BLUE__SI = 0x1D84; +constexpr unsigned int mmDCP1_DC_LUT_WHITE_OFFSET_GREEN__SI = 0x1D85; +constexpr unsigned int mmDCP1_DC_LUT_WHITE_OFFSET_RED__SI = 0x1D86; +constexpr unsigned int mmDCP1_DC_LUT_WRITE_EN_MASK__SI = 0x1D7E; +constexpr unsigned int mmDCP1_GRPH_COMPRESS_PITCH__SI = 0x1D1A; +constexpr unsigned int mmDCP1_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__SI = 0x1D1B; +constexpr unsigned int mmDCP1_GRPH_COMPRESS_SURFACE_ADDRESS__SI = 0x1D19; +constexpr unsigned int mmDCP1_GRPH_DFQ_CONTROL__SI = 0x1D14; +constexpr unsigned int mmDCP1_GRPH_DFQ_STATUS__SI = 0x1D15; +constexpr unsigned int mmDCP1_GRPH_ENABLE__SI = 0x1D00; +constexpr unsigned int mmDCP1_GRPH_INTERRUPT_CONTROL__SI = 0x1D17; +constexpr unsigned int mmDCP1_GRPH_INTERRUPT_STATUS__SI = 0x1D16; +constexpr unsigned int mmDCP1_GRPH_LUT_10BIT_BYPASS__SI = 0x1D02; +constexpr unsigned int mmDCP1_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__SI = 0x1D07; +constexpr unsigned int mmDCP1_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__SI = 0x1D08; +constexpr unsigned int mmDCP1_GRPH_SECONDARY_SURFACE_ADDRESS__SI = 0x1D05; +constexpr unsigned int mmDCP1_GRPH_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x1D18; +constexpr unsigned int mmDCP1_GRPH_SURFACE_ADDRESS_INUSE__SI = 0x1D13; +constexpr unsigned int mmDCP1_GRPH_SURFACE_OFFSET_X__SI = 0x1D09; +constexpr unsigned int mmDCP1_GRPH_SURFACE_OFFSET_Y__SI = 0x1D0A; +constexpr unsigned int mmDCP1_GRPH_SWAP_CNTL__SI = 0x1D03; +constexpr unsigned int mmDCP1_GRPH_X_END__SI = 0x1D0D; +constexpr unsigned int mmDCP1_GRPH_X_START__SI = 0x1D0B; +constexpr unsigned int mmDCP1_GRPH_Y_END__SI = 0x1D0E; +constexpr unsigned int mmDCP1_GRPH_Y_START__SI = 0x1D0C; +constexpr unsigned int mmDCP1_OVLSCL_EDGE_PIXEL_CNTL__SI = 0x1D2C; +constexpr unsigned int mmDCP1_OVL_CONTROL1__SI = 0x1D1D; +constexpr unsigned int mmDCP1_OVL_CONTROL2__SI = 0x1D1E; +constexpr unsigned int mmDCP1_OVL_DFQ_CONTROL__SI = 0x1D29; +constexpr unsigned int mmDCP1_OVL_DFQ_STATUS__SI = 0x1D2A; +constexpr unsigned int mmDCP1_OVL_ENABLE__SI = 0x1D1C; +constexpr unsigned int mmDCP1_OVL_END__SI = 0x1D26; +constexpr unsigned int mmDCP1_OVL_PITCH__SI = 0x1D21; +constexpr unsigned int mmDCP1_OVL_START__SI = 0x1D25; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x1D2B; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS_HIGH__SI = 0x1D22; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS_INUSE__SI = 0x1D28; +constexpr unsigned int mmDCP1_OVL_SURFACE_OFFSET_X__SI = 0x1D23; +constexpr unsigned int mmDCP1_OVL_SURFACE_OFFSET_Y__SI = 0x1D24; +constexpr unsigned int mmDCP1_OVL_SWAP_CNTL__SI = 0x1D1F; +constexpr unsigned int mmDCP1_OVL_UPDATE__SI = 0x1D27; +constexpr unsigned int mmDCP2_CUR_COLOR1__SI = 0x406C; +constexpr unsigned int mmDCP2_CUR_COLOR2__SI = 0x406D; +constexpr unsigned int mmDCP2_CUR_CONTROL__SI = 0x4066; +constexpr unsigned int mmDCP2_CUR_HOT_SPOT__SI = 0x406B; +constexpr unsigned int mmDCP2_CUR_POSITION__SI = 0x406A; +constexpr unsigned int mmDCP2_CUR_SIZE__SI = 0x4068; +constexpr unsigned int mmDCP2_CUR_SURFACE_ADDRESS_HIGH__SI = 0x4069; +constexpr unsigned int mmDCP2_CUR_SURFACE_ADDRESS__SI = 0x4067; +constexpr unsigned int mmDCP2_CUR_UPDATE__SI = 0x406E; +constexpr unsigned int mmDCP2_DCP_CRC_CONTROL__SI = 0x4087; +constexpr unsigned int mmDCP2_DCP_CRC_CURRENT__SI = 0x4089; +constexpr unsigned int mmDCP2_DCP_CRC_LAST__SI = 0x408B; +constexpr unsigned int mmDCP2_DCP_CRC_MASK__SI = 0x4088; +constexpr unsigned int mmDCP2_DCP_DEBUG__SI = 0x408D; +constexpr unsigned int mmDCP2_DCP_LB_DATA_GAP_BETWEEN_CHUNK__SI = 0x4091; +constexpr unsigned int mmDCP2_DCP_TEST_DEBUG_DATA__SI = 0x4096; +constexpr unsigned int mmDCP2_DCP_TEST_DEBUG_INDEX__SI = 0x4095; +constexpr unsigned int mmDCP2_DC_LUT_30_COLOR__SI = 0x407C; +constexpr unsigned int mmDCP2_DC_LUT_AUTOFILL__SI = 0x407F; +constexpr unsigned int mmDCP2_DC_LUT_BLACK_OFFSET_BLUE__SI = 0x4081; +constexpr unsigned int mmDCP2_DC_LUT_BLACK_OFFSET_GREEN__SI = 0x4082; +constexpr unsigned int mmDCP2_DC_LUT_BLACK_OFFSET_RED__SI = 0x4083; +constexpr unsigned int mmDCP2_DC_LUT_CONTROL__SI = 0x4080; +constexpr unsigned int mmDCP2_DC_LUT_PWL_DATA__SI = 0x407B; +constexpr unsigned int mmDCP2_DC_LUT_RW_INDEX__SI = 0x4079; +constexpr unsigned int mmDCP2_DC_LUT_RW_MODE__SI = 0x4078; +constexpr unsigned int mmDCP2_DC_LUT_SEQ_COLOR__SI = 0x407A; +constexpr unsigned int mmDCP2_DC_LUT_WHITE_OFFSET_BLUE__SI = 0x4084; +constexpr unsigned int mmDCP2_DC_LUT_WHITE_OFFSET_GREEN__SI = 0x4085; +constexpr unsigned int mmDCP2_DC_LUT_WHITE_OFFSET_RED__SI = 0x4086; +constexpr unsigned int mmDCP2_DC_LUT_WRITE_EN_MASK__SI = 0x407E; +constexpr unsigned int mmDCP2_GRPH_COMPRESS_PITCH__SI = 0x401A; +constexpr unsigned int mmDCP2_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__SI = 0x401B; +constexpr unsigned int mmDCP2_GRPH_COMPRESS_SURFACE_ADDRESS__SI = 0x4019; +constexpr unsigned int mmDCP2_GRPH_DFQ_CONTROL__SI = 0x4014; +constexpr unsigned int mmDCP2_GRPH_DFQ_STATUS__SI = 0x4015; +constexpr unsigned int mmDCP2_GRPH_ENABLE__SI = 0x4000; +constexpr unsigned int mmDCP2_GRPH_INTERRUPT_CONTROL__SI = 0x4017; +constexpr unsigned int mmDCP2_GRPH_INTERRUPT_STATUS__SI = 0x4016; +constexpr unsigned int mmDCP2_GRPH_LUT_10BIT_BYPASS__SI = 0x4002; +constexpr unsigned int mmDCP2_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__SI = 0x4007; +constexpr unsigned int mmDCP2_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__SI = 0x4008; +constexpr unsigned int mmDCP2_GRPH_SECONDARY_SURFACE_ADDRESS__SI = 0x4005; +constexpr unsigned int mmDCP2_GRPH_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x4018; +constexpr unsigned int mmDCP2_GRPH_SURFACE_ADDRESS_INUSE__SI = 0x4013; +constexpr unsigned int mmDCP2_GRPH_SURFACE_OFFSET_X__SI = 0x4009; +constexpr unsigned int mmDCP2_GRPH_SURFACE_OFFSET_Y__SI = 0x400A; +constexpr unsigned int mmDCP2_GRPH_SWAP_CNTL__SI = 0x4003; +constexpr unsigned int mmDCP2_GRPH_X_END__SI = 0x400D; +constexpr unsigned int mmDCP2_GRPH_X_START__SI = 0x400B; +constexpr unsigned int mmDCP2_GRPH_Y_END__SI = 0x400E; +constexpr unsigned int mmDCP2_GRPH_Y_START__SI = 0x400C; +constexpr unsigned int mmDCP2_OVLSCL_EDGE_PIXEL_CNTL__SI = 0x402C; +constexpr unsigned int mmDCP2_OVL_CONTROL1__SI = 0x401D; +constexpr unsigned int mmDCP2_OVL_CONTROL2__SI = 0x401E; +constexpr unsigned int mmDCP2_OVL_DFQ_CONTROL__SI = 0x4029; +constexpr unsigned int mmDCP2_OVL_DFQ_STATUS__SI = 0x402A; +constexpr unsigned int mmDCP2_OVL_ENABLE__SI = 0x401C; +constexpr unsigned int mmDCP2_OVL_END__SI = 0x4026; +constexpr unsigned int mmDCP2_OVL_PITCH__SI = 0x4021; +constexpr unsigned int mmDCP2_OVL_START__SI = 0x4025; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x402B; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS_HIGH__SI = 0x4022; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS_INUSE__SI = 0x4028; +constexpr unsigned int mmDCP2_OVL_SURFACE_OFFSET_X__SI = 0x4023; +constexpr unsigned int mmDCP2_OVL_SURFACE_OFFSET_Y__SI = 0x4024; +constexpr unsigned int mmDCP2_OVL_SWAP_CNTL__SI = 0x401F; +constexpr unsigned int mmDCP2_OVL_UPDATE__SI = 0x4027; +constexpr unsigned int mmDCP3_CUR_COLOR1__SI = 0x436C; +constexpr unsigned int mmDCP3_CUR_COLOR2__SI = 0x436D; +constexpr unsigned int mmDCP3_CUR_CONTROL__SI = 0x4366; +constexpr unsigned int mmDCP3_CUR_HOT_SPOT__SI = 0x436B; +constexpr unsigned int mmDCP3_CUR_POSITION__SI = 0x436A; +constexpr unsigned int mmDCP3_CUR_SIZE__SI = 0x4368; +constexpr unsigned int mmDCP3_CUR_SURFACE_ADDRESS_HIGH__SI = 0x4369; +constexpr unsigned int mmDCP3_CUR_SURFACE_ADDRESS__SI = 0x4367; +constexpr unsigned int mmDCP3_CUR_UPDATE__SI = 0x436E; +constexpr unsigned int mmDCP3_DCP_CRC_CONTROL__SI = 0x4387; +constexpr unsigned int mmDCP3_DCP_CRC_CURRENT__SI = 0x4389; +constexpr unsigned int mmDCP3_DCP_CRC_LAST__SI = 0x438B; +constexpr unsigned int mmDCP3_DCP_CRC_MASK__SI = 0x4388; +constexpr unsigned int mmDCP3_DCP_DEBUG__SI = 0x438D; +constexpr unsigned int mmDCP3_DCP_LB_DATA_GAP_BETWEEN_CHUNK__SI = 0x4391; +constexpr unsigned int mmDCP3_DCP_TEST_DEBUG_DATA__SI = 0x4396; +constexpr unsigned int mmDCP3_DCP_TEST_DEBUG_INDEX__SI = 0x4395; +constexpr unsigned int mmDCP3_DC_LUT_30_COLOR__SI = 0x437C; +constexpr unsigned int mmDCP3_DC_LUT_AUTOFILL__SI = 0x437F; +constexpr unsigned int mmDCP3_DC_LUT_BLACK_OFFSET_BLUE__SI = 0x4381; +constexpr unsigned int mmDCP3_DC_LUT_BLACK_OFFSET_GREEN__SI = 0x4382; +constexpr unsigned int mmDCP3_DC_LUT_BLACK_OFFSET_RED__SI = 0x4383; +constexpr unsigned int mmDCP3_DC_LUT_CONTROL__SI = 0x4380; +constexpr unsigned int mmDCP3_DC_LUT_PWL_DATA__SI = 0x437B; +constexpr unsigned int mmDCP3_DC_LUT_RW_INDEX__SI = 0x4379; +constexpr unsigned int mmDCP3_DC_LUT_RW_MODE__SI = 0x4378; +constexpr unsigned int mmDCP3_DC_LUT_SEQ_COLOR__SI = 0x437A; +constexpr unsigned int mmDCP3_DC_LUT_WHITE_OFFSET_BLUE__SI = 0x4384; +constexpr unsigned int mmDCP3_DC_LUT_WHITE_OFFSET_GREEN__SI = 0x4385; +constexpr unsigned int mmDCP3_DC_LUT_WHITE_OFFSET_RED__SI = 0x4386; +constexpr unsigned int mmDCP3_DC_LUT_WRITE_EN_MASK__SI = 0x437E; +constexpr unsigned int mmDCP3_GRPH_COMPRESS_PITCH__SI = 0x431A; +constexpr unsigned int mmDCP3_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__SI = 0x431B; +constexpr unsigned int mmDCP3_GRPH_COMPRESS_SURFACE_ADDRESS__SI = 0x4319; +constexpr unsigned int mmDCP3_GRPH_DFQ_CONTROL__SI = 0x4314; +constexpr unsigned int mmDCP3_GRPH_DFQ_STATUS__SI = 0x4315; +constexpr unsigned int mmDCP3_GRPH_ENABLE__SI = 0x4300; +constexpr unsigned int mmDCP3_GRPH_INTERRUPT_CONTROL__SI = 0x4317; +constexpr unsigned int mmDCP3_GRPH_INTERRUPT_STATUS__SI = 0x4316; +constexpr unsigned int mmDCP3_GRPH_LUT_10BIT_BYPASS__SI = 0x4302; +constexpr unsigned int mmDCP3_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__SI = 0x4307; +constexpr unsigned int mmDCP3_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__SI = 0x4308; +constexpr unsigned int mmDCP3_GRPH_SECONDARY_SURFACE_ADDRESS__SI = 0x4305; +constexpr unsigned int mmDCP3_GRPH_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x4318; +constexpr unsigned int mmDCP3_GRPH_SURFACE_ADDRESS_INUSE__SI = 0x4313; +constexpr unsigned int mmDCP3_GRPH_SURFACE_OFFSET_X__SI = 0x4309; +constexpr unsigned int mmDCP3_GRPH_SURFACE_OFFSET_Y__SI = 0x430A; +constexpr unsigned int mmDCP3_GRPH_SWAP_CNTL__SI = 0x4303; +constexpr unsigned int mmDCP3_GRPH_X_END__SI = 0x430D; +constexpr unsigned int mmDCP3_GRPH_X_START__SI = 0x430B; +constexpr unsigned int mmDCP3_GRPH_Y_END__SI = 0x430E; +constexpr unsigned int mmDCP3_GRPH_Y_START__SI = 0x430C; +constexpr unsigned int mmDCP3_OVLSCL_EDGE_PIXEL_CNTL__SI = 0x432C; +constexpr unsigned int mmDCP3_OVL_CONTROL1__SI = 0x431D; +constexpr unsigned int mmDCP3_OVL_CONTROL2__SI = 0x431E; +constexpr unsigned int mmDCP3_OVL_DFQ_CONTROL__SI = 0x4329; +constexpr unsigned int mmDCP3_OVL_DFQ_STATUS__SI = 0x432A; +constexpr unsigned int mmDCP3_OVL_ENABLE__SI = 0x431C; +constexpr unsigned int mmDCP3_OVL_END__SI = 0x4326; +constexpr unsigned int mmDCP3_OVL_PITCH__SI = 0x4321; +constexpr unsigned int mmDCP3_OVL_START__SI = 0x4325; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x432B; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS_HIGH__SI = 0x4322; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS_INUSE__SI = 0x4328; +constexpr unsigned int mmDCP3_OVL_SURFACE_OFFSET_X__SI = 0x4323; +constexpr unsigned int mmDCP3_OVL_SURFACE_OFFSET_Y__SI = 0x4324; +constexpr unsigned int mmDCP3_OVL_SWAP_CNTL__SI = 0x431F; +constexpr unsigned int mmDCP3_OVL_UPDATE__SI = 0x4327; +constexpr unsigned int mmDCP4_CUR_COLOR1__SI = 0x466C; +constexpr unsigned int mmDCP4_CUR_COLOR2__SI = 0x466D; +constexpr unsigned int mmDCP4_CUR_CONTROL__SI = 0x4666; +constexpr unsigned int mmDCP4_CUR_HOT_SPOT__SI = 0x466B; +constexpr unsigned int mmDCP4_CUR_POSITION__SI = 0x466A; +constexpr unsigned int mmDCP4_CUR_SIZE__SI = 0x4668; +constexpr unsigned int mmDCP4_CUR_SURFACE_ADDRESS_HIGH__SI = 0x4669; +constexpr unsigned int mmDCP4_CUR_SURFACE_ADDRESS__SI = 0x4667; +constexpr unsigned int mmDCP4_CUR_UPDATE__SI = 0x466E; +constexpr unsigned int mmDCP4_DCP_CRC_CONTROL__SI = 0x4687; +constexpr unsigned int mmDCP4_DCP_CRC_CURRENT__SI = 0x4689; +constexpr unsigned int mmDCP4_DCP_CRC_LAST__SI = 0x468B; +constexpr unsigned int mmDCP4_DCP_CRC_MASK__SI = 0x4688; +constexpr unsigned int mmDCP4_DCP_DEBUG__SI = 0x468D; +constexpr unsigned int mmDCP4_DCP_LB_DATA_GAP_BETWEEN_CHUNK__SI = 0x4691; +constexpr unsigned int mmDCP4_DCP_TEST_DEBUG_DATA__SI = 0x4696; +constexpr unsigned int mmDCP4_DCP_TEST_DEBUG_INDEX__SI = 0x4695; +constexpr unsigned int mmDCP4_DC_LUT_30_COLOR__SI = 0x467C; +constexpr unsigned int mmDCP4_DC_LUT_AUTOFILL__SI = 0x467F; +constexpr unsigned int mmDCP4_DC_LUT_BLACK_OFFSET_BLUE__SI = 0x4681; +constexpr unsigned int mmDCP4_DC_LUT_BLACK_OFFSET_GREEN__SI = 0x4682; +constexpr unsigned int mmDCP4_DC_LUT_BLACK_OFFSET_RED__SI = 0x4683; +constexpr unsigned int mmDCP4_DC_LUT_CONTROL__SI = 0x4680; +constexpr unsigned int mmDCP4_DC_LUT_PWL_DATA__SI = 0x467B; +constexpr unsigned int mmDCP4_DC_LUT_RW_INDEX__SI = 0x4679; +constexpr unsigned int mmDCP4_DC_LUT_RW_MODE__SI = 0x4678; +constexpr unsigned int mmDCP4_DC_LUT_SEQ_COLOR__SI = 0x467A; +constexpr unsigned int mmDCP4_DC_LUT_WHITE_OFFSET_BLUE__SI = 0x4684; +constexpr unsigned int mmDCP4_DC_LUT_WHITE_OFFSET_GREEN__SI = 0x4685; +constexpr unsigned int mmDCP4_DC_LUT_WHITE_OFFSET_RED__SI = 0x4686; +constexpr unsigned int mmDCP4_DC_LUT_WRITE_EN_MASK__SI = 0x467E; +constexpr unsigned int mmDCP4_GRPH_COMPRESS_PITCH__SI = 0x461A; +constexpr unsigned int mmDCP4_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__SI = 0x461B; +constexpr unsigned int mmDCP4_GRPH_COMPRESS_SURFACE_ADDRESS__SI = 0x4619; +constexpr unsigned int mmDCP4_GRPH_DFQ_CONTROL__SI = 0x4614; +constexpr unsigned int mmDCP4_GRPH_DFQ_STATUS__SI = 0x4615; +constexpr unsigned int mmDCP4_GRPH_ENABLE__SI = 0x4600; +constexpr unsigned int mmDCP4_GRPH_INTERRUPT_CONTROL__SI = 0x4617; +constexpr unsigned int mmDCP4_GRPH_INTERRUPT_STATUS__SI = 0x4616; +constexpr unsigned int mmDCP4_GRPH_LUT_10BIT_BYPASS__SI = 0x4602; +constexpr unsigned int mmDCP4_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__SI = 0x4607; +constexpr unsigned int mmDCP4_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__SI = 0x4608; +constexpr unsigned int mmDCP4_GRPH_SECONDARY_SURFACE_ADDRESS__SI = 0x4605; +constexpr unsigned int mmDCP4_GRPH_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x4618; +constexpr unsigned int mmDCP4_GRPH_SURFACE_ADDRESS_INUSE__SI = 0x4613; +constexpr unsigned int mmDCP4_GRPH_SURFACE_OFFSET_X__SI = 0x4609; +constexpr unsigned int mmDCP4_GRPH_SURFACE_OFFSET_Y__SI = 0x460A; +constexpr unsigned int mmDCP4_GRPH_SWAP_CNTL__SI = 0x4603; +constexpr unsigned int mmDCP4_GRPH_X_END__SI = 0x460D; +constexpr unsigned int mmDCP4_GRPH_X_START__SI = 0x460B; +constexpr unsigned int mmDCP4_GRPH_Y_END__SI = 0x460E; +constexpr unsigned int mmDCP4_GRPH_Y_START__SI = 0x460C; +constexpr unsigned int mmDCP4_OVLSCL_EDGE_PIXEL_CNTL__SI = 0x462C; +constexpr unsigned int mmDCP4_OVL_CONTROL1__SI = 0x461D; +constexpr unsigned int mmDCP4_OVL_CONTROL2__SI = 0x461E; +constexpr unsigned int mmDCP4_OVL_DFQ_CONTROL__SI = 0x4629; +constexpr unsigned int mmDCP4_OVL_DFQ_STATUS__SI = 0x462A; +constexpr unsigned int mmDCP4_OVL_ENABLE__SI = 0x461C; +constexpr unsigned int mmDCP4_OVL_END__SI = 0x4626; +constexpr unsigned int mmDCP4_OVL_PITCH__SI = 0x4621; +constexpr unsigned int mmDCP4_OVL_START__SI = 0x4625; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x462B; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS_HIGH__SI = 0x4622; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS_INUSE__SI = 0x4628; +constexpr unsigned int mmDCP4_OVL_SURFACE_OFFSET_X__SI = 0x4623; +constexpr unsigned int mmDCP4_OVL_SURFACE_OFFSET_Y__SI = 0x4624; +constexpr unsigned int mmDCP4_OVL_SWAP_CNTL__SI = 0x461F; +constexpr unsigned int mmDCP4_OVL_UPDATE__SI = 0x4627; +constexpr unsigned int mmDCP5_CUR_COLOR1__SI = 0x496C; +constexpr unsigned int mmDCP5_CUR_COLOR2__SI = 0x496D; +constexpr unsigned int mmDCP5_CUR_CONTROL__SI = 0x4966; +constexpr unsigned int mmDCP5_CUR_HOT_SPOT__SI = 0x496B; +constexpr unsigned int mmDCP5_CUR_POSITION__SI = 0x496A; +constexpr unsigned int mmDCP5_CUR_SIZE__SI = 0x4968; +constexpr unsigned int mmDCP5_CUR_SURFACE_ADDRESS_HIGH__SI = 0x4969; +constexpr unsigned int mmDCP5_CUR_SURFACE_ADDRESS__SI = 0x4967; +constexpr unsigned int mmDCP5_CUR_UPDATE__SI = 0x496E; +constexpr unsigned int mmDCP5_DCP_CRC_CONTROL__SI = 0x4987; +constexpr unsigned int mmDCP5_DCP_CRC_CURRENT__SI = 0x4989; +constexpr unsigned int mmDCP5_DCP_CRC_LAST__SI = 0x498B; +constexpr unsigned int mmDCP5_DCP_CRC_MASK__SI = 0x4988; +constexpr unsigned int mmDCP5_DCP_DEBUG__SI = 0x498D; +constexpr unsigned int mmDCP5_DCP_LB_DATA_GAP_BETWEEN_CHUNK__SI = 0x4991; +constexpr unsigned int mmDCP5_DCP_TEST_DEBUG_DATA__SI = 0x4996; +constexpr unsigned int mmDCP5_DCP_TEST_DEBUG_INDEX__SI = 0x4995; +constexpr unsigned int mmDCP5_DC_LUT_30_COLOR__SI = 0x497C; +constexpr unsigned int mmDCP5_DC_LUT_AUTOFILL__SI = 0x497F; +constexpr unsigned int mmDCP5_DC_LUT_BLACK_OFFSET_BLUE__SI = 0x4981; +constexpr unsigned int mmDCP5_DC_LUT_BLACK_OFFSET_GREEN__SI = 0x4982; +constexpr unsigned int mmDCP5_DC_LUT_BLACK_OFFSET_RED__SI = 0x4983; +constexpr unsigned int mmDCP5_DC_LUT_CONTROL__SI = 0x4980; +constexpr unsigned int mmDCP5_DC_LUT_PWL_DATA__SI = 0x497B; +constexpr unsigned int mmDCP5_DC_LUT_RW_INDEX__SI = 0x4979; +constexpr unsigned int mmDCP5_DC_LUT_RW_MODE__SI = 0x4978; +constexpr unsigned int mmDCP5_DC_LUT_SEQ_COLOR__SI = 0x497A; +constexpr unsigned int mmDCP5_DC_LUT_WHITE_OFFSET_BLUE__SI = 0x4984; +constexpr unsigned int mmDCP5_DC_LUT_WHITE_OFFSET_GREEN__SI = 0x4985; +constexpr unsigned int mmDCP5_DC_LUT_WHITE_OFFSET_RED__SI = 0x4986; +constexpr unsigned int mmDCP5_DC_LUT_WRITE_EN_MASK__SI = 0x497E; +constexpr unsigned int mmDCP5_GRPH_COMPRESS_PITCH__SI = 0x491A; +constexpr unsigned int mmDCP5_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__SI = 0x491B; +constexpr unsigned int mmDCP5_GRPH_COMPRESS_SURFACE_ADDRESS__SI = 0x4919; +constexpr unsigned int mmDCP5_GRPH_DFQ_CONTROL__SI = 0x4914; +constexpr unsigned int mmDCP5_GRPH_DFQ_STATUS__SI = 0x4915; +constexpr unsigned int mmDCP5_GRPH_ENABLE__SI = 0x4900; +constexpr unsigned int mmDCP5_GRPH_INTERRUPT_CONTROL__SI = 0x4917; +constexpr unsigned int mmDCP5_GRPH_INTERRUPT_STATUS__SI = 0x4916; +constexpr unsigned int mmDCP5_GRPH_LUT_10BIT_BYPASS__SI = 0x4902; +constexpr unsigned int mmDCP5_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__SI = 0x4907; +constexpr unsigned int mmDCP5_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__SI = 0x4908; +constexpr unsigned int mmDCP5_GRPH_SECONDARY_SURFACE_ADDRESS__SI = 0x4905; +constexpr unsigned int mmDCP5_GRPH_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x4918; +constexpr unsigned int mmDCP5_GRPH_SURFACE_ADDRESS_INUSE__SI = 0x4913; +constexpr unsigned int mmDCP5_GRPH_SURFACE_OFFSET_X__SI = 0x4909; +constexpr unsigned int mmDCP5_GRPH_SURFACE_OFFSET_Y__SI = 0x490A; +constexpr unsigned int mmDCP5_GRPH_SWAP_CNTL__SI = 0x4903; +constexpr unsigned int mmDCP5_GRPH_X_END__SI = 0x490D; +constexpr unsigned int mmDCP5_GRPH_X_START__SI = 0x490B; +constexpr unsigned int mmDCP5_GRPH_Y_END__SI = 0x490E; +constexpr unsigned int mmDCP5_GRPH_Y_START__SI = 0x490C; +constexpr unsigned int mmDCP5_OVLSCL_EDGE_PIXEL_CNTL__SI = 0x492C; +constexpr unsigned int mmDCP5_OVL_CONTROL1__SI = 0x491D; +constexpr unsigned int mmDCP5_OVL_CONTROL2__SI = 0x491E; +constexpr unsigned int mmDCP5_OVL_DFQ_CONTROL__SI = 0x4929; +constexpr unsigned int mmDCP5_OVL_DFQ_STATUS__SI = 0x492A; +constexpr unsigned int mmDCP5_OVL_ENABLE__SI = 0x491C; +constexpr unsigned int mmDCP5_OVL_END__SI = 0x4926; +constexpr unsigned int mmDCP5_OVL_PITCH__SI = 0x4921; +constexpr unsigned int mmDCP5_OVL_START__SI = 0x4925; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS_HIGH_INUSE__SI = 0x492B; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS_HIGH__SI = 0x4922; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS_INUSE__SI = 0x4928; +constexpr unsigned int mmDCP5_OVL_SURFACE_OFFSET_X__SI = 0x4923; +constexpr unsigned int mmDCP5_OVL_SURFACE_OFFSET_Y__SI = 0x4924; +constexpr unsigned int mmDCP5_OVL_SWAP_CNTL__SI = 0x491F; +constexpr unsigned int mmDCP5_OVL_UPDATE__SI = 0x4927; +constexpr unsigned int mmDCP_CRC_CONTROL__SI__VI = 0x1A87; +constexpr unsigned int mmDCP_CRC_CURRENT__SI__VI = 0x1A89; +constexpr unsigned int mmDCP_CRC_LAST__SI__VI = 0x1A8B; +constexpr unsigned int mmDCP_CRC_MASK__SI__VI = 0x1A88; +constexpr unsigned int mmDCP_DEBUG__SI__VI = 0x1A8D; +constexpr unsigned int mmDCP_LB_DATA_GAP_BETWEEN_CHUNK__SI__VI = 0x1A91; +constexpr unsigned int mmDCP_TEST_DEBUG_DATA__SI__VI = 0x1A96; +constexpr unsigned int mmDCP_TEST_DEBUG_INDEX__SI__VI = 0x1A95; +constexpr unsigned int mmDC_ABM1_ACE_CNTL_MISC__SI__VI = 0x1641; +constexpr unsigned int mmDC_ABM1_ACE_OFFSET_SLOPE_0__SI__VI = 0x163A; +constexpr unsigned int mmDC_ABM1_ACE_OFFSET_SLOPE_1__SI__VI = 0x163B; +constexpr unsigned int mmDC_ABM1_ACE_OFFSET_SLOPE_2__SI__VI = 0x163C; +constexpr unsigned int mmDC_ABM1_ACE_OFFSET_SLOPE_3__SI__VI = 0x163D; +constexpr unsigned int mmDC_ABM1_ACE_OFFSET_SLOPE_4__SI__VI = 0x163E; +constexpr unsigned int mmDC_ABM1_ACE_THRES_12__SI__VI = 0x163F; +constexpr unsigned int mmDC_ABM1_ACE_THRES_34__SI__VI = 0x1640; +constexpr unsigned int mmDC_ABM1_BL_MASTER_LOCK__SI__VI = 0x169C; +constexpr unsigned int mmDC_ABM1_CNTL__SI__VI = 0x1638; +constexpr unsigned int mmDC_ABM1_DEBUG_MISC__SI__VI = 0x1649; +constexpr unsigned int mmDC_ABM1_HGLS_REG_READ_PROGRESS__SI__VI = 0x164A; +constexpr unsigned int mmDC_ABM1_HG_BIN_17_24_SHIFT_INDEX__SI__VI = 0x1659; +constexpr unsigned int mmDC_ABM1_HG_BIN_1_32_SHIFT_FLAG__SI__VI = 0x1656; +constexpr unsigned int mmDC_ABM1_HG_BIN_1_8_SHIFT_INDEX__SI__VI = 0x1657; +constexpr unsigned int mmDC_ABM1_HG_BIN_25_32_SHIFT_INDEX__SI__VI = 0x165A; +constexpr unsigned int mmDC_ABM1_HG_BIN_9_16_SHIFT_INDEX__SI__VI = 0x1658; +constexpr unsigned int mmDC_ABM1_HG_MISC_CTRL__SI__VI = 0x164B; +constexpr unsigned int mmDC_ABM1_HG_RESULT_10__SI__VI = 0x1664; +constexpr unsigned int mmDC_ABM1_HG_RESULT_11__SI__VI = 0x1665; +constexpr unsigned int mmDC_ABM1_HG_RESULT_12__SI__VI = 0x1666; +constexpr unsigned int mmDC_ABM1_HG_RESULT_13__SI__VI = 0x1667; +constexpr unsigned int mmDC_ABM1_HG_RESULT_14__SI__VI = 0x1668; +constexpr unsigned int mmDC_ABM1_HG_RESULT_15__SI__VI = 0x1669; +constexpr unsigned int mmDC_ABM1_HG_RESULT_16__SI__VI = 0x166A; +constexpr unsigned int mmDC_ABM1_HG_RESULT_17__SI__VI = 0x166B; +constexpr unsigned int mmDC_ABM1_HG_RESULT_18__SI__VI = 0x166C; +constexpr unsigned int mmDC_ABM1_HG_RESULT_19__SI__VI = 0x166D; +constexpr unsigned int mmDC_ABM1_HG_RESULT_1__SI__VI = 0x165B; +constexpr unsigned int mmDC_ABM1_HG_RESULT_20__SI__VI = 0x166E; +constexpr unsigned int mmDC_ABM1_HG_RESULT_21__SI__VI = 0x166F; +constexpr unsigned int mmDC_ABM1_HG_RESULT_22__SI__VI = 0x1670; +constexpr unsigned int mmDC_ABM1_HG_RESULT_23__SI__VI = 0x1671; +constexpr unsigned int mmDC_ABM1_HG_RESULT_24__SI__VI = 0x1672; +constexpr unsigned int mmDC_ABM1_HG_RESULT_2__SI__VI = 0x165C; +constexpr unsigned int mmDC_ABM1_HG_RESULT_3__SI__VI = 0x165D; +constexpr unsigned int mmDC_ABM1_HG_RESULT_4__SI__VI = 0x165E; +constexpr unsigned int mmDC_ABM1_HG_RESULT_5__SI__VI = 0x165F; +constexpr unsigned int mmDC_ABM1_HG_RESULT_6__SI__VI = 0x1660; +constexpr unsigned int mmDC_ABM1_HG_RESULT_7__SI__VI = 0x1661; +constexpr unsigned int mmDC_ABM1_HG_RESULT_8__SI__VI = 0x1662; +constexpr unsigned int mmDC_ABM1_HG_RESULT_9__SI__VI = 0x1663; +constexpr unsigned int mmDC_ABM1_HG_SAMPLE_RATE__SI__VI = 0x1654; +constexpr unsigned int mmDC_ABM1_IPCSC_COEFF_SEL__SI__VI = 0x1639; +constexpr unsigned int mmDC_ABM1_LS_FILTERED_MIN_MAX_LUMA__SI__VI = 0x164E; +constexpr unsigned int mmDC_ABM1_LS_MAX_PIXEL_VALUE_COUNT__SI__VI = 0x1653; +constexpr unsigned int mmDC_ABM1_LS_MIN_MAX_LUMA__SI__VI = 0x164D; +constexpr unsigned int mmDC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES__SI__VI = 0x1651; +constexpr unsigned int mmDC_ABM1_LS_MIN_PIXEL_VALUE_COUNT__SI__VI = 0x1652; +constexpr unsigned int mmDC_ABM1_LS_OVR_SCAN_BIN__SI__VI = 0x1650; +constexpr unsigned int mmDC_ABM1_LS_PIXEL_COUNT__SI__VI = 0x164F; +constexpr unsigned int mmDC_ABM1_LS_SAMPLE_RATE__SI__VI = 0x1655; +constexpr unsigned int mmDC_ABM1_LS_SUM_OF_LUMA__SI__VI = 0x164C; +constexpr unsigned int mmDC_DMCU_SCRATCH__SI__VI = 0x1618; +constexpr unsigned int mmDC_GENERICA__SI = 0x1900; +constexpr unsigned int mmDC_GENERICB__SI = 0x1901; +constexpr unsigned int mmDC_GPIO_DDC1_A__SI = 0x190D; +constexpr unsigned int mmDC_GPIO_DDC1_EN__SI = 0x190E; +constexpr unsigned int mmDC_GPIO_DDC1_MASK__SI = 0x190C; +constexpr unsigned int mmDC_GPIO_DDC1_Y__SI = 0x190F; +constexpr unsigned int mmDC_GPIO_DDC2_A__SI = 0x1911; +constexpr unsigned int mmDC_GPIO_DDC2_EN__SI = 0x1912; +constexpr unsigned int mmDC_GPIO_DDC2_MASK__SI = 0x1910; +constexpr unsigned int mmDC_GPIO_DDC2_Y__SI = 0x1913; +constexpr unsigned int mmDC_GPIO_DDC3_A__SI = 0x1915; +constexpr unsigned int mmDC_GPIO_DDC3_EN__SI = 0x1916; +constexpr unsigned int mmDC_GPIO_DDC3_MASK__SI = 0x1914; +constexpr unsigned int mmDC_GPIO_DDC3_Y__SI = 0x1917; +constexpr unsigned int mmDC_GPIO_DDC4_A__SI = 0x1919; +constexpr unsigned int mmDC_GPIO_DDC4_EN__SI = 0x191A; +constexpr unsigned int mmDC_GPIO_DDC4_MASK__SI = 0x1918; +constexpr unsigned int mmDC_GPIO_DDC4_Y__SI = 0x191B; +constexpr unsigned int mmDC_GPIO_DDC5_A__SI = 0x191D; +constexpr unsigned int mmDC_GPIO_DDC5_EN__SI = 0x191E; +constexpr unsigned int mmDC_GPIO_DDC5_MASK__SI = 0x191C; +constexpr unsigned int mmDC_GPIO_DDC5_Y__SI = 0x191F; +constexpr unsigned int mmDC_GPIO_DDC6_A__SI = 0x1921; +constexpr unsigned int mmDC_GPIO_DDC6_EN__SI = 0x1922; +constexpr unsigned int mmDC_GPIO_DDC6_MASK__SI = 0x1920; +constexpr unsigned int mmDC_GPIO_DDC6_Y__SI = 0x1923; +constexpr unsigned int mmDC_GPIO_DEBUG__SI = 0x1946; +constexpr unsigned int mmDC_GPIO_DVODATA_A__SI = 0x1909; +constexpr unsigned int mmDC_GPIO_DVODATA_EN__SI = 0x190A; +constexpr unsigned int mmDC_GPIO_DVODATA_MASK__SI = 0x1908; +constexpr unsigned int mmDC_GPIO_DVODATA_Y__SI = 0x190B; +constexpr unsigned int mmDC_GPIO_GENERIC_A__SI = 0x1905; +constexpr unsigned int mmDC_GPIO_GENERIC_EN__SI = 0x1906; +constexpr unsigned int mmDC_GPIO_GENERIC_MASK__SI = 0x1904; +constexpr unsigned int mmDC_GPIO_GENERIC_Y__SI = 0x1907; +constexpr unsigned int mmDC_GPIO_HPD_A__SI = 0x192D; +constexpr unsigned int mmDC_GPIO_HPD_EN__SI = 0x192E; +constexpr unsigned int mmDC_GPIO_HPD_MASK__SI = 0x192C; +constexpr unsigned int mmDC_GPIO_HPD_Y__SI = 0x192F; +constexpr unsigned int mmDC_GPIO_PAD_STRENGTH_1__SI = 0x1944; +constexpr unsigned int mmDC_GPIO_PAD_STRENGTH_2__SI = 0x1945; +constexpr unsigned int mmDC_GPIO_PWRSEQ_A__SI = 0x1941; +constexpr unsigned int mmDC_GPIO_PWRSEQ_EN__SI = 0x1942; +constexpr unsigned int mmDC_GPIO_PWRSEQ_MASK__SI = 0x1940; +constexpr unsigned int mmDC_GPIO_PWRSEQ_Y__SI = 0x1943; +constexpr unsigned int mmDC_GPIO_SYNCA_A__SI = 0x1925; +constexpr unsigned int mmDC_GPIO_SYNCA_EN__SI = 0x1926; +constexpr unsigned int mmDC_GPIO_SYNCA_MASK__SI = 0x1924; +constexpr unsigned int mmDC_GPIO_SYNCA_Y__SI = 0x1927; +constexpr unsigned int mmDC_GPU_TIMER_READ_CNTL__SI = 0x1972; +constexpr unsigned int mmDC_GPU_TIMER_READ__SI = 0x1971; +constexpr unsigned int mmDC_GPU_TIMER_START_POSITION__SI = 0x1970; +constexpr unsigned int mmDC_HPD1_CONTROL__SI = 0x1809; +constexpr unsigned int mmDC_HPD1_INT_CONTROL__SI = 0x1808; +constexpr unsigned int mmDC_HPD1_INT_STATUS__SI = 0x1807; +constexpr unsigned int mmDC_HPD2_CONTROL__SI = 0x180C; +constexpr unsigned int mmDC_HPD2_INT_CONTROL__SI = 0x180B; +constexpr unsigned int mmDC_HPD2_INT_STATUS__SI = 0x180A; +constexpr unsigned int mmDC_HPD3_CONTROL__SI = 0x180F; +constexpr unsigned int mmDC_HPD3_INT_CONTROL__SI = 0x180E; +constexpr unsigned int mmDC_HPD3_INT_STATUS__SI = 0x180D; +constexpr unsigned int mmDC_HPD4_CONTROL__SI = 0x1812; +constexpr unsigned int mmDC_HPD4_INT_CONTROL__SI = 0x1811; +constexpr unsigned int mmDC_HPD4_INT_STATUS__SI = 0x1810; +constexpr unsigned int mmDC_HPD5_CONTROL__SI = 0x1815; +constexpr unsigned int mmDC_HPD5_INT_CONTROL__SI = 0x1814; +constexpr unsigned int mmDC_HPD5_INT_STATUS__SI = 0x1813; +constexpr unsigned int mmDC_HPD6_CONTROL__SI = 0x1818; +constexpr unsigned int mmDC_HPD6_INT_CONTROL__SI = 0x1817; +constexpr unsigned int mmDC_HPD6_INT_STATUS__SI = 0x1816; +constexpr unsigned int mmDC_I2C_ARBITRATION__SI = 0x181A; +constexpr unsigned int mmDC_I2C_CONTROL__SI = 0x1819; +constexpr unsigned int mmDC_I2C_DATA__SI = 0x1833; +constexpr unsigned int mmDC_I2C_DDC1_HW_STATUS__SI = 0x181D; +constexpr unsigned int mmDC_I2C_DDC1_SETUP__SI = 0x1824; +constexpr unsigned int mmDC_I2C_DDC1_SPEED__SI = 0x1823; +constexpr unsigned int mmDC_I2C_DDC2_HW_STATUS__SI = 0x181E; +constexpr unsigned int mmDC_I2C_DDC2_SETUP__SI = 0x1826; +constexpr unsigned int mmDC_I2C_DDC2_SPEED__SI = 0x1825; +constexpr unsigned int mmDC_I2C_DDC3_HW_STATUS__SI = 0x181F; +constexpr unsigned int mmDC_I2C_DDC3_SETUP__SI = 0x1828; +constexpr unsigned int mmDC_I2C_DDC3_SPEED__SI = 0x1827; +constexpr unsigned int mmDC_I2C_DDC4_HW_STATUS__SI = 0x1820; +constexpr unsigned int mmDC_I2C_DDC4_SETUP__SI = 0x182A; +constexpr unsigned int mmDC_I2C_DDC4_SPEED__SI = 0x1829; +constexpr unsigned int mmDC_I2C_DDC5_HW_STATUS__SI = 0x1821; +constexpr unsigned int mmDC_I2C_DDC5_SETUP__SI = 0x182C; +constexpr unsigned int mmDC_I2C_DDC5_SPEED__SI = 0x182B; +constexpr unsigned int mmDC_I2C_DDC6_HW_STATUS__SI = 0x1822; +constexpr unsigned int mmDC_I2C_DDC6_SETUP__SI = 0x182E; +constexpr unsigned int mmDC_I2C_DDC6_SPEED__SI = 0x182D; +constexpr unsigned int mmDC_I2C_INTERRUPT_CONTROL__SI = 0x181B; +constexpr unsigned int mmDC_I2C_SW_STATUS__SI = 0x181C; +constexpr unsigned int mmDC_I2C_TRANSACTION0__SI = 0x182F; +constexpr unsigned int mmDC_I2C_TRANSACTION1__SI = 0x1830; +constexpr unsigned int mmDC_I2C_TRANSACTION2__SI = 0x1831; +constexpr unsigned int mmDC_I2C_TRANSACTION3__SI = 0x1832; +constexpr unsigned int mmDC_LUT_30_COLOR__SI__VI = 0x1A7C; +constexpr unsigned int mmDC_LUT_AUTOFILL__SI__VI = 0x1A7F; +constexpr unsigned int mmDC_LUT_BLACK_OFFSET_BLUE__SI__VI = 0x1A81; +constexpr unsigned int mmDC_LUT_BLACK_OFFSET_GREEN__SI__VI = 0x1A82; +constexpr unsigned int mmDC_LUT_BLACK_OFFSET_RED__SI__VI = 0x1A83; +constexpr unsigned int mmDC_LUT_CONTROL__SI__VI = 0x1A80; +constexpr unsigned int mmDC_LUT_PWL_DATA__SI__VI = 0x1A7B; +constexpr unsigned int mmDC_LUT_RW_INDEX__SI__VI = 0x1A79; +constexpr unsigned int mmDC_LUT_RW_MODE__SI__VI = 0x1A78; +constexpr unsigned int mmDC_LUT_SEQ_COLOR__SI__VI = 0x1A7A; +constexpr unsigned int mmDC_LUT_WHITE_OFFSET_BLUE__SI__VI = 0x1A84; +constexpr unsigned int mmDC_LUT_WHITE_OFFSET_GREEN__SI__VI = 0x1A85; +constexpr unsigned int mmDC_LUT_WHITE_OFFSET_RED__SI__VI = 0x1A86; +constexpr unsigned int mmDC_LUT_WRITE_EN_MASK__SI__VI = 0x1A7E; +constexpr unsigned int mmDC_MVP_LB_CONTROL__SI = 0x1ADB; +constexpr unsigned int mmDC_PAD_EXTERN_SIG__SI = 0x1902; +constexpr unsigned int mmDC_PINSTRAPS__SI = 0x1954; +constexpr unsigned int mmDC_REF_CLK_CNTL__SI = 0x1903; +constexpr unsigned int mmDC_TEST_DEBUG_DATA__SI = 0x186D; +constexpr unsigned int mmDC_TEST_DEBUG_INDEX__SI = 0x186C; +constexpr unsigned int mmDEBUG_DATA = 0x203D; +constexpr unsigned int mmDEBUG_INDEX = 0x203C; +constexpr unsigned int mmDENTIST_DISPCLK_CNTL__SI = 0x015F; +constexpr unsigned int mmDESKTOP_HEIGHT__SI = 0x1AC1; +constexpr unsigned int mmDIDT_IND_DATA__CI__VI = 0x3281; +constexpr unsigned int mmDIDT_IND_INDEX__CI__VI = 0x3280; +constexpr unsigned int mmDIG0_AFMT_60958_0__SI = 0x1C41; +constexpr unsigned int mmDIG0_AFMT_60958_1__SI = 0x1C42; +constexpr unsigned int mmDIG0_AFMT_60958_2__SI = 0x1C48; +constexpr unsigned int mmDIG0_AFMT_AUDIO_CRC_CONTROL__SI = 0x1C43; +constexpr unsigned int mmDIG0_AFMT_AUDIO_CRC_RESULT__SI = 0x1C49; +constexpr unsigned int mmDIG0_AFMT_AUDIO_INFO0__SI = 0x1C3F; +constexpr unsigned int mmDIG0_AFMT_AUDIO_INFO1__SI = 0x1C40; +constexpr unsigned int mmDIG0_AFMT_AUDIO_PACKET_CONTROL2__SI = 0x1C17; +constexpr unsigned int mmDIG0_AFMT_AUDIO_PACKET_CONTROL__SI = 0x1C4B; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO0__SI = 0x1C21; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO1__SI = 0x1C22; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO2__SI = 0x1C23; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO3__SI = 0x1C24; +constexpr unsigned int mmDIG0_AFMT_INFOFRAME_CONTROL0__SI = 0x1C4D; +constexpr unsigned int mmDIG0_AFMT_ISRC1_0__SI = 0x1C18; +constexpr unsigned int mmDIG0_AFMT_ISRC1_1__SI = 0x1C19; +constexpr unsigned int mmDIG0_AFMT_ISRC1_2__SI = 0x1C1A; +constexpr unsigned int mmDIG0_AFMT_ISRC1_3__SI = 0x1C1B; +constexpr unsigned int mmDIG0_AFMT_ISRC1_4__SI = 0x1C1C; +constexpr unsigned int mmDIG0_AFMT_ISRC2_0__SI = 0x1C1D; +constexpr unsigned int mmDIG0_AFMT_ISRC2_1__SI = 0x1C1E; +constexpr unsigned int mmDIG0_AFMT_ISRC2_2__SI = 0x1C1F; +constexpr unsigned int mmDIG0_AFMT_ISRC2_3__SI = 0x1C20; +constexpr unsigned int mmDIG0_AFMT_MPEG_INFO0__SI = 0x1C25; +constexpr unsigned int mmDIG0_AFMT_MPEG_INFO1__SI = 0x1C26; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL0__SI = 0x1C44; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL1__SI = 0x1C45; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL2__SI = 0x1C46; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL3__SI = 0x1C47; +constexpr unsigned int mmDIG0_AFMT_STATUS__SI = 0x1C4A; +constexpr unsigned int mmDIG0_AFMT_VBI_PACKET_CONTROL__SI = 0x1C4C; +constexpr unsigned int mmDIG0_DIG_CLOCK_PATTERN__SI = 0x1C03; +constexpr unsigned int mmDIG0_DIG_OUTPUT_CRC_CNTL__SI = 0x1C01; +constexpr unsigned int mmDIG0_DIG_OUTPUT_CRC_RESULT__SI = 0x1C02; +constexpr unsigned int mmDIG0_DIG_RANDOM_PATTERN_SEED__SI = 0x1C05; +constexpr unsigned int mmDIG0_DIG_TEST_PATTERN__SI = 0x1C04; +constexpr unsigned int mmDIG0_HDMI_ACR_32_0__SI = 0x1C37; +constexpr unsigned int mmDIG0_HDMI_ACR_32_1__SI = 0x1C38; +constexpr unsigned int mmDIG0_HDMI_ACR_44_0__SI = 0x1C39; +constexpr unsigned int mmDIG0_HDMI_ACR_44_1__SI = 0x1C3A; +constexpr unsigned int mmDIG0_HDMI_ACR_48_0__SI = 0x1C3B; +constexpr unsigned int mmDIG0_HDMI_ACR_48_1__SI = 0x1C3C; +constexpr unsigned int mmDIG0_HDMI_ACR_PACKET_CONTROL__SI = 0x1C0F; +constexpr unsigned int mmDIG0_HDMI_ACR_STATUS_0__SI = 0x1C3D; +constexpr unsigned int mmDIG0_HDMI_ACR_STATUS_1__SI = 0x1C3E; +constexpr unsigned int mmDIG0_HDMI_AUDIO_PACKET_CONTROL__SI = 0x1C0E; +constexpr unsigned int mmDIG0_HDMI_CONTROL__SI = 0x1C0C; +constexpr unsigned int mmDIG0_HDMI_GC__SI = 0x1C16; +constexpr unsigned int mmDIG0_HDMI_GENERIC_PACKET_CONTROL__SI = 0x1C13; +constexpr unsigned int mmDIG0_HDMI_INFOFRAME_CONTROL0__SI = 0x1C11; +constexpr unsigned int mmDIG0_HDMI_INFOFRAME_CONTROL1__SI = 0x1C12; +constexpr unsigned int mmDIG0_HDMI_STATUS__SI = 0x1C0D; +constexpr unsigned int mmDIG0_HDMI_VBI_PACKET_CONTROL__SI = 0x1C10; +constexpr unsigned int mmDIG0_LVDS_DATA_CNTL__SI = 0x1C8C; +constexpr unsigned int mmDIG0_TMDS_CNTL__SI = 0x1C7C; +constexpr unsigned int mmDIG0_TMDS_CONTROL0_FEEDBACK__SI = 0x1C7E; +constexpr unsigned int mmDIG0_TMDS_CONTROL_CHAR__SI = 0x1C7D; +constexpr unsigned int mmDIG0_TMDS_CTL0_1_GEN_CNTL__SI = 0x1C86; +constexpr unsigned int mmDIG0_TMDS_CTL2_3_GEN_CNTL__SI = 0x1C87; +constexpr unsigned int mmDIG0_TMDS_CTL_BITS__SI = 0x1C83; +constexpr unsigned int mmDIG0_TMDS_DCBALANCER_CONTROL__SI = 0x1C84; +constexpr unsigned int mmDIG0_TMDS_DEBUG__SI = 0x1C82; +constexpr unsigned int mmDIG0_TMDS_STEREOSYNC_CTL_SEL__SI = 0x1C7F; +constexpr unsigned int mmDIG0_TMDS_SYNC_CHAR_PATTERN_0_1__SI = 0x1C80; +constexpr unsigned int mmDIG0_TMDS_SYNC_CHAR_PATTERN_2_3__SI = 0x1C81; +constexpr unsigned int mmDIG1_AFMT_60958_0__SI = 0x1F41; +constexpr unsigned int mmDIG1_AFMT_60958_1__SI = 0x1F42; +constexpr unsigned int mmDIG1_AFMT_60958_2__SI = 0x1F48; +constexpr unsigned int mmDIG1_AFMT_AUDIO_CRC_CONTROL__SI = 0x1F43; +constexpr unsigned int mmDIG1_AFMT_AUDIO_CRC_RESULT__SI = 0x1F49; +constexpr unsigned int mmDIG1_AFMT_AUDIO_INFO0__SI = 0x1F3F; +constexpr unsigned int mmDIG1_AFMT_AUDIO_INFO1__SI = 0x1F40; +constexpr unsigned int mmDIG1_AFMT_AUDIO_PACKET_CONTROL2__SI = 0x1F17; +constexpr unsigned int mmDIG1_AFMT_AUDIO_PACKET_CONTROL__SI = 0x1F4B; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO0__SI = 0x1F21; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO1__SI = 0x1F22; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO2__SI = 0x1F23; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO3__SI = 0x1F24; +constexpr unsigned int mmDIG1_AFMT_INFOFRAME_CONTROL0__SI = 0x1F4D; +constexpr unsigned int mmDIG1_AFMT_ISRC1_0__SI = 0x1F18; +constexpr unsigned int mmDIG1_AFMT_ISRC1_1__SI = 0x1F19; +constexpr unsigned int mmDIG1_AFMT_ISRC1_2__SI = 0x1F1A; +constexpr unsigned int mmDIG1_AFMT_ISRC1_3__SI = 0x1F1B; +constexpr unsigned int mmDIG1_AFMT_ISRC1_4__SI = 0x1F1C; +constexpr unsigned int mmDIG1_AFMT_ISRC2_0__SI = 0x1F1D; +constexpr unsigned int mmDIG1_AFMT_ISRC2_1__SI = 0x1F1E; +constexpr unsigned int mmDIG1_AFMT_ISRC2_2__SI = 0x1F1F; +constexpr unsigned int mmDIG1_AFMT_ISRC2_3__SI = 0x1F20; +constexpr unsigned int mmDIG1_AFMT_MPEG_INFO0__SI = 0x1F25; +constexpr unsigned int mmDIG1_AFMT_MPEG_INFO1__SI = 0x1F26; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL0__SI = 0x1F44; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL1__SI = 0x1F45; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL2__SI = 0x1F46; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL3__SI = 0x1F47; +constexpr unsigned int mmDIG1_AFMT_STATUS__SI = 0x1F4A; +constexpr unsigned int mmDIG1_AFMT_VBI_PACKET_CONTROL__SI = 0x1F4C; +constexpr unsigned int mmDIG1_DIG_CLOCK_PATTERN__SI = 0x1F03; +constexpr unsigned int mmDIG1_DIG_OUTPUT_CRC_CNTL__SI = 0x1F01; +constexpr unsigned int mmDIG1_DIG_OUTPUT_CRC_RESULT__SI = 0x1F02; +constexpr unsigned int mmDIG1_DIG_RANDOM_PATTERN_SEED__SI = 0x1F05; +constexpr unsigned int mmDIG1_DIG_TEST_PATTERN__SI = 0x1F04; +constexpr unsigned int mmDIG1_HDMI_ACR_32_0__SI = 0x1F37; +constexpr unsigned int mmDIG1_HDMI_ACR_32_1__SI = 0x1F38; +constexpr unsigned int mmDIG1_HDMI_ACR_44_0__SI = 0x1F39; +constexpr unsigned int mmDIG1_HDMI_ACR_44_1__SI = 0x1F3A; +constexpr unsigned int mmDIG1_HDMI_ACR_48_0__SI = 0x1F3B; +constexpr unsigned int mmDIG1_HDMI_ACR_48_1__SI = 0x1F3C; +constexpr unsigned int mmDIG1_HDMI_ACR_PACKET_CONTROL__SI = 0x1F0F; +constexpr unsigned int mmDIG1_HDMI_ACR_STATUS_0__SI = 0x1F3D; +constexpr unsigned int mmDIG1_HDMI_ACR_STATUS_1__SI = 0x1F3E; +constexpr unsigned int mmDIG1_HDMI_AUDIO_PACKET_CONTROL__SI = 0x1F0E; +constexpr unsigned int mmDIG1_HDMI_CONTROL__SI = 0x1F0C; +constexpr unsigned int mmDIG1_HDMI_GC__SI = 0x1F16; +constexpr unsigned int mmDIG1_HDMI_GENERIC_PACKET_CONTROL__SI = 0x1F13; +constexpr unsigned int mmDIG1_HDMI_INFOFRAME_CONTROL0__SI = 0x1F11; +constexpr unsigned int mmDIG1_HDMI_INFOFRAME_CONTROL1__SI = 0x1F12; +constexpr unsigned int mmDIG1_HDMI_STATUS__SI = 0x1F0D; +constexpr unsigned int mmDIG1_HDMI_VBI_PACKET_CONTROL__SI = 0x1F10; +constexpr unsigned int mmDIG1_LVDS_DATA_CNTL__SI = 0x1F8C; +constexpr unsigned int mmDIG1_TMDS_CNTL__SI = 0x1F7C; +constexpr unsigned int mmDIG1_TMDS_CONTROL0_FEEDBACK__SI = 0x1F7E; +constexpr unsigned int mmDIG1_TMDS_CONTROL_CHAR__SI = 0x1F7D; +constexpr unsigned int mmDIG1_TMDS_CTL0_1_GEN_CNTL__SI = 0x1F86; +constexpr unsigned int mmDIG1_TMDS_CTL2_3_GEN_CNTL__SI = 0x1F87; +constexpr unsigned int mmDIG1_TMDS_CTL_BITS__SI = 0x1F83; +constexpr unsigned int mmDIG1_TMDS_DCBALANCER_CONTROL__SI = 0x1F84; +constexpr unsigned int mmDIG1_TMDS_DEBUG__SI = 0x1F82; +constexpr unsigned int mmDIG1_TMDS_STEREOSYNC_CTL_SEL__SI = 0x1F7F; +constexpr unsigned int mmDIG1_TMDS_SYNC_CHAR_PATTERN_0_1__SI = 0x1F80; +constexpr unsigned int mmDIG1_TMDS_SYNC_CHAR_PATTERN_2_3__SI = 0x1F81; +constexpr unsigned int mmDIG2_AFMT_60958_0__SI = 0x4241; +constexpr unsigned int mmDIG2_AFMT_60958_1__SI = 0x4242; +constexpr unsigned int mmDIG2_AFMT_60958_2__SI = 0x4248; +constexpr unsigned int mmDIG2_AFMT_AUDIO_CRC_CONTROL__SI = 0x4243; +constexpr unsigned int mmDIG2_AFMT_AUDIO_CRC_RESULT__SI = 0x4249; +constexpr unsigned int mmDIG2_AFMT_AUDIO_INFO0__SI = 0x423F; +constexpr unsigned int mmDIG2_AFMT_AUDIO_INFO1__SI = 0x4240; +constexpr unsigned int mmDIG2_AFMT_AUDIO_PACKET_CONTROL2__SI = 0x4217; +constexpr unsigned int mmDIG2_AFMT_AUDIO_PACKET_CONTROL__SI = 0x424B; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO0__SI = 0x4221; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO1__SI = 0x4222; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO2__SI = 0x4223; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO3__SI = 0x4224; +constexpr unsigned int mmDIG2_AFMT_INFOFRAME_CONTROL0__SI = 0x424D; +constexpr unsigned int mmDIG2_AFMT_ISRC1_0__SI = 0x4218; +constexpr unsigned int mmDIG2_AFMT_ISRC1_1__SI = 0x4219; +constexpr unsigned int mmDIG2_AFMT_ISRC1_2__SI = 0x421A; +constexpr unsigned int mmDIG2_AFMT_ISRC1_3__SI = 0x421B; +constexpr unsigned int mmDIG2_AFMT_ISRC1_4__SI = 0x421C; +constexpr unsigned int mmDIG2_AFMT_ISRC2_0__SI = 0x421D; +constexpr unsigned int mmDIG2_AFMT_ISRC2_1__SI = 0x421E; +constexpr unsigned int mmDIG2_AFMT_ISRC2_2__SI = 0x421F; +constexpr unsigned int mmDIG2_AFMT_ISRC2_3__SI = 0x4220; +constexpr unsigned int mmDIG2_AFMT_MPEG_INFO0__SI = 0x4225; +constexpr unsigned int mmDIG2_AFMT_MPEG_INFO1__SI = 0x4226; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL0__SI = 0x4244; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL1__SI = 0x4245; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL2__SI = 0x4246; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL3__SI = 0x4247; +constexpr unsigned int mmDIG2_AFMT_STATUS__SI = 0x424A; +constexpr unsigned int mmDIG2_AFMT_VBI_PACKET_CONTROL__SI = 0x424C; +constexpr unsigned int mmDIG2_DIG_CLOCK_PATTERN__SI = 0x4203; +constexpr unsigned int mmDIG2_DIG_OUTPUT_CRC_CNTL__SI = 0x4201; +constexpr unsigned int mmDIG2_DIG_OUTPUT_CRC_RESULT__SI = 0x4202; +constexpr unsigned int mmDIG2_DIG_RANDOM_PATTERN_SEED__SI = 0x4205; +constexpr unsigned int mmDIG2_DIG_TEST_PATTERN__SI = 0x4204; +constexpr unsigned int mmDIG2_HDMI_ACR_32_0__SI = 0x4237; +constexpr unsigned int mmDIG2_HDMI_ACR_32_1__SI = 0x4238; +constexpr unsigned int mmDIG2_HDMI_ACR_44_0__SI = 0x4239; +constexpr unsigned int mmDIG2_HDMI_ACR_44_1__SI = 0x423A; +constexpr unsigned int mmDIG2_HDMI_ACR_48_0__SI = 0x423B; +constexpr unsigned int mmDIG2_HDMI_ACR_48_1__SI = 0x423C; +constexpr unsigned int mmDIG2_HDMI_ACR_PACKET_CONTROL__SI = 0x420F; +constexpr unsigned int mmDIG2_HDMI_ACR_STATUS_0__SI = 0x423D; +constexpr unsigned int mmDIG2_HDMI_ACR_STATUS_1__SI = 0x423E; +constexpr unsigned int mmDIG2_HDMI_AUDIO_PACKET_CONTROL__SI = 0x420E; +constexpr unsigned int mmDIG2_HDMI_CONTROL__SI = 0x420C; +constexpr unsigned int mmDIG2_HDMI_GC__SI = 0x4216; +constexpr unsigned int mmDIG2_HDMI_GENERIC_PACKET_CONTROL__SI = 0x4213; +constexpr unsigned int mmDIG2_HDMI_INFOFRAME_CONTROL0__SI = 0x4211; +constexpr unsigned int mmDIG2_HDMI_INFOFRAME_CONTROL1__SI = 0x4212; +constexpr unsigned int mmDIG2_HDMI_STATUS__SI = 0x420D; +constexpr unsigned int mmDIG2_HDMI_VBI_PACKET_CONTROL__SI = 0x4210; +constexpr unsigned int mmDIG2_LVDS_DATA_CNTL__SI = 0x428C; +constexpr unsigned int mmDIG2_TMDS_CNTL__SI = 0x427C; +constexpr unsigned int mmDIG2_TMDS_CONTROL0_FEEDBACK__SI = 0x427E; +constexpr unsigned int mmDIG2_TMDS_CONTROL_CHAR__SI = 0x427D; +constexpr unsigned int mmDIG2_TMDS_CTL0_1_GEN_CNTL__SI = 0x4286; +constexpr unsigned int mmDIG2_TMDS_CTL2_3_GEN_CNTL__SI = 0x4287; +constexpr unsigned int mmDIG2_TMDS_CTL_BITS__SI = 0x4283; +constexpr unsigned int mmDIG2_TMDS_DCBALANCER_CONTROL__SI = 0x4284; +constexpr unsigned int mmDIG2_TMDS_DEBUG__SI = 0x4282; +constexpr unsigned int mmDIG2_TMDS_STEREOSYNC_CTL_SEL__SI = 0x427F; +constexpr unsigned int mmDIG2_TMDS_SYNC_CHAR_PATTERN_0_1__SI = 0x4280; +constexpr unsigned int mmDIG2_TMDS_SYNC_CHAR_PATTERN_2_3__SI = 0x4281; +constexpr unsigned int mmDIG3_AFMT_60958_0__SI = 0x4541; +constexpr unsigned int mmDIG3_AFMT_60958_1__SI = 0x4542; +constexpr unsigned int mmDIG3_AFMT_60958_2__SI = 0x4548; +constexpr unsigned int mmDIG3_AFMT_AUDIO_CRC_CONTROL__SI = 0x4543; +constexpr unsigned int mmDIG3_AFMT_AUDIO_CRC_RESULT__SI = 0x4549; +constexpr unsigned int mmDIG3_AFMT_AUDIO_INFO0__SI = 0x453F; +constexpr unsigned int mmDIG3_AFMT_AUDIO_INFO1__SI = 0x4540; +constexpr unsigned int mmDIG3_AFMT_AUDIO_PACKET_CONTROL2__SI = 0x4517; +constexpr unsigned int mmDIG3_AFMT_AUDIO_PACKET_CONTROL__SI = 0x454B; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO0__SI = 0x4521; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO1__SI = 0x4522; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO2__SI = 0x4523; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO3__SI = 0x4524; +constexpr unsigned int mmDIG3_AFMT_INFOFRAME_CONTROL0__SI = 0x454D; +constexpr unsigned int mmDIG3_AFMT_ISRC1_0__SI = 0x4518; +constexpr unsigned int mmDIG3_AFMT_ISRC1_1__SI = 0x4519; +constexpr unsigned int mmDIG3_AFMT_ISRC1_2__SI = 0x451A; +constexpr unsigned int mmDIG3_AFMT_ISRC1_3__SI = 0x451B; +constexpr unsigned int mmDIG3_AFMT_ISRC1_4__SI = 0x451C; +constexpr unsigned int mmDIG3_AFMT_ISRC2_0__SI = 0x451D; +constexpr unsigned int mmDIG3_AFMT_ISRC2_1__SI = 0x451E; +constexpr unsigned int mmDIG3_AFMT_ISRC2_2__SI = 0x451F; +constexpr unsigned int mmDIG3_AFMT_ISRC2_3__SI = 0x4520; +constexpr unsigned int mmDIG3_AFMT_MPEG_INFO0__SI = 0x4525; +constexpr unsigned int mmDIG3_AFMT_MPEG_INFO1__SI = 0x4526; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL0__SI = 0x4544; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL1__SI = 0x4545; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL2__SI = 0x4546; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL3__SI = 0x4547; +constexpr unsigned int mmDIG3_AFMT_STATUS__SI = 0x454A; +constexpr unsigned int mmDIG3_AFMT_VBI_PACKET_CONTROL__SI = 0x454C; +constexpr unsigned int mmDIG3_DIG_CLOCK_PATTERN__SI = 0x4503; +constexpr unsigned int mmDIG3_DIG_OUTPUT_CRC_CNTL__SI = 0x4501; +constexpr unsigned int mmDIG3_DIG_OUTPUT_CRC_RESULT__SI = 0x4502; +constexpr unsigned int mmDIG3_DIG_RANDOM_PATTERN_SEED__SI = 0x4505; +constexpr unsigned int mmDIG3_DIG_TEST_PATTERN__SI = 0x4504; +constexpr unsigned int mmDIG3_HDMI_ACR_32_0__SI = 0x4537; +constexpr unsigned int mmDIG3_HDMI_ACR_32_1__SI = 0x4538; +constexpr unsigned int mmDIG3_HDMI_ACR_44_0__SI = 0x4539; +constexpr unsigned int mmDIG3_HDMI_ACR_44_1__SI = 0x453A; +constexpr unsigned int mmDIG3_HDMI_ACR_48_0__SI = 0x453B; +constexpr unsigned int mmDIG3_HDMI_ACR_48_1__SI = 0x453C; +constexpr unsigned int mmDIG3_HDMI_ACR_PACKET_CONTROL__SI = 0x450F; +constexpr unsigned int mmDIG3_HDMI_ACR_STATUS_0__SI = 0x453D; +constexpr unsigned int mmDIG3_HDMI_ACR_STATUS_1__SI = 0x453E; +constexpr unsigned int mmDIG3_HDMI_AUDIO_PACKET_CONTROL__SI = 0x450E; +constexpr unsigned int mmDIG3_HDMI_CONTROL__SI = 0x450C; +constexpr unsigned int mmDIG3_HDMI_GC__SI = 0x4516; +constexpr unsigned int mmDIG3_HDMI_GENERIC_PACKET_CONTROL__SI = 0x4513; +constexpr unsigned int mmDIG3_HDMI_INFOFRAME_CONTROL0__SI = 0x4511; +constexpr unsigned int mmDIG3_HDMI_INFOFRAME_CONTROL1__SI = 0x4512; +constexpr unsigned int mmDIG3_HDMI_STATUS__SI = 0x450D; +constexpr unsigned int mmDIG3_HDMI_VBI_PACKET_CONTROL__SI = 0x4510; +constexpr unsigned int mmDIG3_LVDS_DATA_CNTL__SI = 0x458C; +constexpr unsigned int mmDIG3_TMDS_CNTL__SI = 0x457C; +constexpr unsigned int mmDIG3_TMDS_CONTROL0_FEEDBACK__SI = 0x457E; +constexpr unsigned int mmDIG3_TMDS_CONTROL_CHAR__SI = 0x457D; +constexpr unsigned int mmDIG3_TMDS_CTL0_1_GEN_CNTL__SI = 0x4586; +constexpr unsigned int mmDIG3_TMDS_CTL2_3_GEN_CNTL__SI = 0x4587; +constexpr unsigned int mmDIG3_TMDS_CTL_BITS__SI = 0x4583; +constexpr unsigned int mmDIG3_TMDS_DCBALANCER_CONTROL__SI = 0x4584; +constexpr unsigned int mmDIG3_TMDS_DEBUG__SI = 0x4582; +constexpr unsigned int mmDIG3_TMDS_STEREOSYNC_CTL_SEL__SI = 0x457F; +constexpr unsigned int mmDIG3_TMDS_SYNC_CHAR_PATTERN_0_1__SI = 0x4580; +constexpr unsigned int mmDIG3_TMDS_SYNC_CHAR_PATTERN_2_3__SI = 0x4581; +constexpr unsigned int mmDIG4_AFMT_60958_0__SI = 0x4841; +constexpr unsigned int mmDIG4_AFMT_60958_1__SI = 0x4842; +constexpr unsigned int mmDIG4_AFMT_60958_2__SI = 0x4848; +constexpr unsigned int mmDIG4_AFMT_AUDIO_CRC_CONTROL__SI = 0x4843; +constexpr unsigned int mmDIG4_AFMT_AUDIO_CRC_RESULT__SI = 0x4849; +constexpr unsigned int mmDIG4_AFMT_AUDIO_INFO0__SI = 0x483F; +constexpr unsigned int mmDIG4_AFMT_AUDIO_INFO1__SI = 0x4840; +constexpr unsigned int mmDIG4_AFMT_AUDIO_PACKET_CONTROL2__SI = 0x4817; +constexpr unsigned int mmDIG4_AFMT_AUDIO_PACKET_CONTROL__SI = 0x484B; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO0__SI = 0x4821; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO1__SI = 0x4822; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO2__SI = 0x4823; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO3__SI = 0x4824; +constexpr unsigned int mmDIG4_AFMT_INFOFRAME_CONTROL0__SI = 0x484D; +constexpr unsigned int mmDIG4_AFMT_ISRC1_0__SI = 0x4818; +constexpr unsigned int mmDIG4_AFMT_ISRC1_1__SI = 0x4819; +constexpr unsigned int mmDIG4_AFMT_ISRC1_2__SI = 0x481A; +constexpr unsigned int mmDIG4_AFMT_ISRC1_3__SI = 0x481B; +constexpr unsigned int mmDIG4_AFMT_ISRC1_4__SI = 0x481C; +constexpr unsigned int mmDIG4_AFMT_ISRC2_0__SI = 0x481D; +constexpr unsigned int mmDIG4_AFMT_ISRC2_1__SI = 0x481E; +constexpr unsigned int mmDIG4_AFMT_ISRC2_2__SI = 0x481F; +constexpr unsigned int mmDIG4_AFMT_ISRC2_3__SI = 0x4820; +constexpr unsigned int mmDIG4_AFMT_MPEG_INFO0__SI = 0x4825; +constexpr unsigned int mmDIG4_AFMT_MPEG_INFO1__SI = 0x4826; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL0__SI = 0x4844; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL1__SI = 0x4845; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL2__SI = 0x4846; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL3__SI = 0x4847; +constexpr unsigned int mmDIG4_AFMT_STATUS__SI = 0x484A; +constexpr unsigned int mmDIG4_AFMT_VBI_PACKET_CONTROL__SI = 0x484C; +constexpr unsigned int mmDIG4_DIG_CLOCK_PATTERN__SI = 0x4803; +constexpr unsigned int mmDIG4_DIG_OUTPUT_CRC_CNTL__SI = 0x4801; +constexpr unsigned int mmDIG4_DIG_OUTPUT_CRC_RESULT__SI = 0x4802; +constexpr unsigned int mmDIG4_DIG_RANDOM_PATTERN_SEED__SI = 0x4805; +constexpr unsigned int mmDIG4_DIG_TEST_PATTERN__SI = 0x4804; +constexpr unsigned int mmDIG4_HDMI_ACR_32_0__SI = 0x4837; +constexpr unsigned int mmDIG4_HDMI_ACR_32_1__SI = 0x4838; +constexpr unsigned int mmDIG4_HDMI_ACR_44_0__SI = 0x4839; +constexpr unsigned int mmDIG4_HDMI_ACR_44_1__SI = 0x483A; +constexpr unsigned int mmDIG4_HDMI_ACR_48_0__SI = 0x483B; +constexpr unsigned int mmDIG4_HDMI_ACR_48_1__SI = 0x483C; +constexpr unsigned int mmDIG4_HDMI_ACR_PACKET_CONTROL__SI = 0x480F; +constexpr unsigned int mmDIG4_HDMI_ACR_STATUS_0__SI = 0x483D; +constexpr unsigned int mmDIG4_HDMI_ACR_STATUS_1__SI = 0x483E; +constexpr unsigned int mmDIG4_HDMI_AUDIO_PACKET_CONTROL__SI = 0x480E; +constexpr unsigned int mmDIG4_HDMI_CONTROL__SI = 0x480C; +constexpr unsigned int mmDIG4_HDMI_GC__SI = 0x4816; +constexpr unsigned int mmDIG4_HDMI_GENERIC_PACKET_CONTROL__SI = 0x4813; +constexpr unsigned int mmDIG4_HDMI_INFOFRAME_CONTROL0__SI = 0x4811; +constexpr unsigned int mmDIG4_HDMI_INFOFRAME_CONTROL1__SI = 0x4812; +constexpr unsigned int mmDIG4_HDMI_STATUS__SI = 0x480D; +constexpr unsigned int mmDIG4_HDMI_VBI_PACKET_CONTROL__SI = 0x4810; +constexpr unsigned int mmDIG4_LVDS_DATA_CNTL__SI = 0x488C; +constexpr unsigned int mmDIG4_TMDS_CNTL__SI = 0x487C; +constexpr unsigned int mmDIG4_TMDS_CONTROL0_FEEDBACK__SI = 0x487E; +constexpr unsigned int mmDIG4_TMDS_CONTROL_CHAR__SI = 0x487D; +constexpr unsigned int mmDIG4_TMDS_CTL0_1_GEN_CNTL__SI = 0x4886; +constexpr unsigned int mmDIG4_TMDS_CTL2_3_GEN_CNTL__SI = 0x4887; +constexpr unsigned int mmDIG4_TMDS_CTL_BITS__SI = 0x4883; +constexpr unsigned int mmDIG4_TMDS_DCBALANCER_CONTROL__SI = 0x4884; +constexpr unsigned int mmDIG4_TMDS_DEBUG__SI = 0x4882; +constexpr unsigned int mmDIG4_TMDS_STEREOSYNC_CTL_SEL__SI = 0x487F; +constexpr unsigned int mmDIG4_TMDS_SYNC_CHAR_PATTERN_0_1__SI = 0x4880; +constexpr unsigned int mmDIG4_TMDS_SYNC_CHAR_PATTERN_2_3__SI = 0x4881; +constexpr unsigned int mmDIG5_AFMT_60958_0__SI = 0x4B41; +constexpr unsigned int mmDIG5_AFMT_60958_1__SI = 0x4B42; +constexpr unsigned int mmDIG5_AFMT_60958_2__SI = 0x4B48; +constexpr unsigned int mmDIG5_AFMT_AUDIO_CRC_CONTROL__SI = 0x4B43; +constexpr unsigned int mmDIG5_AFMT_AUDIO_CRC_RESULT__SI = 0x4B49; +constexpr unsigned int mmDIG5_AFMT_AUDIO_INFO0__SI = 0x4B3F; +constexpr unsigned int mmDIG5_AFMT_AUDIO_INFO1__SI = 0x4B40; +constexpr unsigned int mmDIG5_AFMT_AUDIO_PACKET_CONTROL2__SI = 0x4B17; +constexpr unsigned int mmDIG5_AFMT_AUDIO_PACKET_CONTROL__SI = 0x4B4B; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO0__SI = 0x4B21; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO1__SI = 0x4B22; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO2__SI = 0x4B23; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO3__SI = 0x4B24; +constexpr unsigned int mmDIG5_AFMT_INFOFRAME_CONTROL0__SI = 0x4B4D; +constexpr unsigned int mmDIG5_AFMT_ISRC1_0__SI = 0x4B18; +constexpr unsigned int mmDIG5_AFMT_ISRC1_1__SI = 0x4B19; +constexpr unsigned int mmDIG5_AFMT_ISRC1_2__SI = 0x4B1A; +constexpr unsigned int mmDIG5_AFMT_ISRC1_3__SI = 0x4B1B; +constexpr unsigned int mmDIG5_AFMT_ISRC1_4__SI = 0x4B1C; +constexpr unsigned int mmDIG5_AFMT_ISRC2_0__SI = 0x4B1D; +constexpr unsigned int mmDIG5_AFMT_ISRC2_1__SI = 0x4B1E; +constexpr unsigned int mmDIG5_AFMT_ISRC2_2__SI = 0x4B1F; +constexpr unsigned int mmDIG5_AFMT_ISRC2_3__SI = 0x4B20; +constexpr unsigned int mmDIG5_AFMT_MPEG_INFO0__SI = 0x4B25; +constexpr unsigned int mmDIG5_AFMT_MPEG_INFO1__SI = 0x4B26; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL0__SI = 0x4B44; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL1__SI = 0x4B45; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL2__SI = 0x4B46; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL3__SI = 0x4B47; +constexpr unsigned int mmDIG5_AFMT_STATUS__SI = 0x4B4A; +constexpr unsigned int mmDIG5_AFMT_VBI_PACKET_CONTROL__SI = 0x4B4C; +constexpr unsigned int mmDIG5_DIG_CLOCK_PATTERN__SI = 0x4B03; +constexpr unsigned int mmDIG5_DIG_OUTPUT_CRC_CNTL__SI = 0x4B01; +constexpr unsigned int mmDIG5_DIG_OUTPUT_CRC_RESULT__SI = 0x4B02; +constexpr unsigned int mmDIG5_DIG_RANDOM_PATTERN_SEED__SI = 0x4B05; +constexpr unsigned int mmDIG5_DIG_TEST_PATTERN__SI = 0x4B04; +constexpr unsigned int mmDIG5_HDMI_ACR_32_0__SI = 0x4B37; +constexpr unsigned int mmDIG5_HDMI_ACR_32_1__SI = 0x4B38; +constexpr unsigned int mmDIG5_HDMI_ACR_44_0__SI = 0x4B39; +constexpr unsigned int mmDIG5_HDMI_ACR_44_1__SI = 0x4B3A; +constexpr unsigned int mmDIG5_HDMI_ACR_48_0__SI = 0x4B3B; +constexpr unsigned int mmDIG5_HDMI_ACR_48_1__SI = 0x4B3C; +constexpr unsigned int mmDIG5_HDMI_ACR_PACKET_CONTROL__SI = 0x4B0F; +constexpr unsigned int mmDIG5_HDMI_ACR_STATUS_0__SI = 0x4B3D; +constexpr unsigned int mmDIG5_HDMI_ACR_STATUS_1__SI = 0x4B3E; +constexpr unsigned int mmDIG5_HDMI_AUDIO_PACKET_CONTROL__SI = 0x4B0E; +constexpr unsigned int mmDIG5_HDMI_CONTROL__SI = 0x4B0C; +constexpr unsigned int mmDIG5_HDMI_GC__SI = 0x4B16; +constexpr unsigned int mmDIG5_HDMI_GENERIC_PACKET_CONTROL__SI = 0x4B13; +constexpr unsigned int mmDIG5_HDMI_INFOFRAME_CONTROL0__SI = 0x4B11; +constexpr unsigned int mmDIG5_HDMI_INFOFRAME_CONTROL1__SI = 0x4B12; +constexpr unsigned int mmDIG5_HDMI_STATUS__SI = 0x4B0D; +constexpr unsigned int mmDIG5_HDMI_VBI_PACKET_CONTROL__SI = 0x4B10; +constexpr unsigned int mmDIG5_LVDS_DATA_CNTL__SI = 0x4B8C; +constexpr unsigned int mmDIG5_TMDS_CNTL__SI = 0x4B7C; +constexpr unsigned int mmDIG5_TMDS_CONTROL0_FEEDBACK__SI = 0x4B7E; +constexpr unsigned int mmDIG5_TMDS_CONTROL_CHAR__SI = 0x4B7D; +constexpr unsigned int mmDIG5_TMDS_CTL0_1_GEN_CNTL__SI = 0x4B86; +constexpr unsigned int mmDIG5_TMDS_CTL2_3_GEN_CNTL__SI = 0x4B87; +constexpr unsigned int mmDIG5_TMDS_CTL_BITS__SI = 0x4B83; +constexpr unsigned int mmDIG5_TMDS_DCBALANCER_CONTROL__SI = 0x4B84; +constexpr unsigned int mmDIG5_TMDS_DEBUG__SI = 0x4B82; +constexpr unsigned int mmDIG5_TMDS_STEREOSYNC_CTL_SEL__SI = 0x4B7F; +constexpr unsigned int mmDIG5_TMDS_SYNC_CHAR_PATTERN_0_1__SI = 0x4B80; +constexpr unsigned int mmDIG5_TMDS_SYNC_CHAR_PATTERN_2_3__SI = 0x4B81; +constexpr unsigned int mmDIG_CLOCK_PATTERN__SI = 0x1C03; +constexpr unsigned int mmDIG_OUTPUT_CRC_CNTL__SI = 0x1C01; +constexpr unsigned int mmDIG_OUTPUT_CRC_RESULT__SI = 0x1C02; +constexpr unsigned int mmDIG_RANDOM_PATTERN_SEED__SI = 0x1C05; +constexpr unsigned int mmDIG_TEST_PATTERN__SI = 0x1C04; +constexpr unsigned int mmDISPCLK_CGTT_BLK_CTRL_REG__SI = 0x0128; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE2__SI = 0x183F; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE__SI = 0x183E; +constexpr unsigned int mmDISP_INTERRUPT_STATUS__SI = 0x183D; +constexpr unsigned int mmDISP_TIMER_CONTROL__SI = 0x1842; +constexpr unsigned int mmDLL_CNTL__SI__CI = 0x0AE9; +constexpr unsigned int mmDMCU_CTRL__SI__VI = 0x1600; +constexpr unsigned int mmDMCU_ERAM_RD_CTRL__SI__VI = 0x160B; +constexpr unsigned int mmDMCU_ERAM_RD_DATA__SI__VI = 0x160C; +constexpr unsigned int mmDMCU_ERAM_WR_CTRL__SI__VI = 0x1609; +constexpr unsigned int mmDMCU_ERAM_WR_DATA__SI__VI = 0x160A; +constexpr unsigned int mmDMCU_EVENT_TRIGGER__SI__VI = 0x1611; +constexpr unsigned int mmDMCU_FW_CHECKSUM_SMPL_BYTE_POS__SI__VI = 0x161A; +constexpr unsigned int mmDMCU_FW_CS_HI__SI__VI = 0x1606; +constexpr unsigned int mmDMCU_FW_CS_LO__SI__VI = 0x1607; +constexpr unsigned int mmDMCU_FW_END_ADDR__SI__VI = 0x1604; +constexpr unsigned int mmDMCU_FW_ISR_START_ADDR__SI__VI = 0x1605; +constexpr unsigned int mmDMCU_FW_START_ADDR__SI__VI = 0x1603; +constexpr unsigned int mmDMCU_INTERRUPT_STATUS__SI__VI = 0x1614; +constexpr unsigned int mmDMCU_INTERRUPT_TO_HOST_EN_MASK__SI__VI = 0x1615; +constexpr unsigned int mmDMCU_INTERRUPT_TO_UC_EN_MASK__SI__VI = 0x1616; +constexpr unsigned int mmDMCU_INTERRUPT_TO_UC_XIRQ_IRQ_SEL__SI__VI = 0x1617; +constexpr unsigned int mmDMCU_INT_CNT__SI__VI = 0x1619; +constexpr unsigned int mmDMCU_IRAM_RD_CTRL__SI__VI = 0x160F; +constexpr unsigned int mmDMCU_IRAM_RD_DATA__SI__VI = 0x1610; +constexpr unsigned int mmDMCU_IRAM_WR_CTRL__SI__VI = 0x160D; +constexpr unsigned int mmDMCU_IRAM_WR_DATA__SI__VI = 0x160E; +constexpr unsigned int mmDMCU_PC_START_ADDR__SI__VI = 0x1602; +constexpr unsigned int mmDMCU_RAM_ACCESS_CTRL__SI__VI = 0x1608; +constexpr unsigned int mmDMCU_STATUS__SI__VI = 0x1601; +constexpr unsigned int mmDMCU_TEST_DEBUG_DATA__SI__VI = 0x1627; +constexpr unsigned int mmDMCU_TEST_DEBUG_INDEX__SI__VI = 0x1626; +constexpr unsigned int mmDMCU_UC_INTERNAL_INT_STATUS__SI__VI = 0x1612; +constexpr unsigned int mmDMIF_ARBITRATION_CONTROL__SI__VI = 0x02F9; +constexpr unsigned int mmDMIF_CONTROL__SI__VI = 0x02F6; +constexpr unsigned int mmDMIF_HW_DEBUG__SI__VI = 0x02F8; +constexpr unsigned int mmDMIF_STATUS__SI__VI = 0x02F7; +constexpr unsigned int mmDMIF_TEST_DEBUG_DATA__SI = 0x0313; +constexpr unsigned int mmDMIF_TEST_DEBUG_INDEX__SI = 0x0312; +constexpr unsigned int mmDOUT_POWER_MANAGEMENT_CNTL__SI = 0x1841; +constexpr unsigned int mmDOUT_SCRATCH0__SI = 0x1844; +constexpr unsigned int mmDOUT_SCRATCH1__SI = 0x1845; +constexpr unsigned int mmDOUT_SCRATCH2__SI = 0x1846; +constexpr unsigned int mmDOUT_SCRATCH3__SI = 0x1847; +constexpr unsigned int mmDOUT_SCRATCH4__SI = 0x1848; +constexpr unsigned int mmDOUT_SCRATCH5__SI = 0x1849; +constexpr unsigned int mmDOUT_SCRATCH6__SI = 0x184A; +constexpr unsigned int mmDOUT_SCRATCH7__SI = 0x184B; +constexpr unsigned int mmDOUT_TEST_DEBUG_DATA__SI = 0x184E; +constexpr unsigned int mmDOUT_TEST_DEBUG_INDEX__SI = 0x184D; +constexpr unsigned int mmDP0_DP_CONFIG__SI = 0x1CC2; +constexpr unsigned int mmDP0_DP_DPHY_8B10B_CNTL__SI = 0x1CD3; +constexpr unsigned int mmDP0_DP_DPHY_CNTL__SI = 0x1CD0; +constexpr unsigned int mmDP0_DP_DPHY_CRC_CNTL__SI = 0x1CD7; +constexpr unsigned int mmDP0_DP_DPHY_CRC_EN__SI = 0x1CD6; +constexpr unsigned int mmDP0_DP_DPHY_CRC_RESULT__SI = 0x1CD8; +constexpr unsigned int mmDP0_DP_DPHY_FAST_TRAINING__SI = 0x1CCE; +constexpr unsigned int mmDP0_DP_DPHY_PRBS_CNTL__SI = 0x1CD4; +constexpr unsigned int mmDP0_DP_DPHY_SYM__SI = 0x1CD2; +constexpr unsigned int mmDP0_DP_DPHY_TRAINING_PATTERN_SEL__SI = 0x1CD1; +constexpr unsigned int mmDP0_DP_LINK_CNTL__SI = 0x1CC0; +constexpr unsigned int mmDP0_DP_PIXEL_FORMAT__SI = 0x1CC1; +constexpr unsigned int mmDP0_DP_SEC_AUD_M_READBACK__SI = 0x1CA8; +constexpr unsigned int mmDP0_DP_SEC_AUD_M__SI = 0x1CA7; +constexpr unsigned int mmDP0_DP_SEC_AUD_N_READBACK__SI = 0x1CA6; +constexpr unsigned int mmDP0_DP_SEC_AUD_N__SI = 0x1CA5; +constexpr unsigned int mmDP0_DP_SEC_CNTL__SI = 0x1CA0; +constexpr unsigned int mmDP0_DP_SEC_FRAMING1__SI = 0x1CA1; +constexpr unsigned int mmDP0_DP_SEC_FRAMING2__SI = 0x1CA2; +constexpr unsigned int mmDP0_DP_SEC_FRAMING3__SI = 0x1CA3; +constexpr unsigned int mmDP0_DP_SEC_FRAMING4__SI = 0x1CA4; +constexpr unsigned int mmDP0_DP_SEC_PACKET_CNTL__SI = 0x1CAA; +constexpr unsigned int mmDP0_DP_SEC_TIMESTAMP__SI = 0x1CA9; +constexpr unsigned int mmDP0_DP_STEER_FIFO__SI = 0x1CC4; +constexpr unsigned int mmDP0_DP_TEST_DEBUG_DATA__SI = 0x1CFD; +constexpr unsigned int mmDP0_DP_TEST_DEBUG_INDEX__SI = 0x1CFC; +constexpr unsigned int mmDP0_DP_VID_INTERRUPT_CNTL__SI = 0x1CCF; +constexpr unsigned int mmDP0_DP_VID_MSA_VBID__SI = 0x1CCD; +constexpr unsigned int mmDP0_DP_VID_M__SI = 0x1CCB; +constexpr unsigned int mmDP0_DP_VID_N__SI = 0x1CCA; +constexpr unsigned int mmDP0_DP_VID_STREAM_CNTL__SI = 0x1CC3; +constexpr unsigned int mmDP0_DP_VID_TIMING__SI = 0x1CC9; +constexpr unsigned int mmDP1_DP_CONFIG__SI = 0x1FC2; +constexpr unsigned int mmDP1_DP_DPHY_8B10B_CNTL__SI = 0x1FD3; +constexpr unsigned int mmDP1_DP_DPHY_CNTL__SI = 0x1FD0; +constexpr unsigned int mmDP1_DP_DPHY_CRC_CNTL__SI = 0x1FD7; +constexpr unsigned int mmDP1_DP_DPHY_CRC_EN__SI = 0x1FD6; +constexpr unsigned int mmDP1_DP_DPHY_CRC_RESULT__SI = 0x1FD8; +constexpr unsigned int mmDP1_DP_DPHY_FAST_TRAINING__SI = 0x1FCE; +constexpr unsigned int mmDP1_DP_DPHY_PRBS_CNTL__SI = 0x1FD4; +constexpr unsigned int mmDP1_DP_DPHY_SYM__SI = 0x1FD2; +constexpr unsigned int mmDP1_DP_DPHY_TRAINING_PATTERN_SEL__SI = 0x1FD1; +constexpr unsigned int mmDP1_DP_LINK_CNTL__SI = 0x1FC0; +constexpr unsigned int mmDP1_DP_PIXEL_FORMAT__SI = 0x1FC1; +constexpr unsigned int mmDP1_DP_SEC_AUD_M_READBACK__SI = 0x1FA8; +constexpr unsigned int mmDP1_DP_SEC_AUD_M__SI = 0x1FA7; +constexpr unsigned int mmDP1_DP_SEC_AUD_N_READBACK__SI = 0x1FA6; +constexpr unsigned int mmDP1_DP_SEC_AUD_N__SI = 0x1FA5; +constexpr unsigned int mmDP1_DP_SEC_CNTL__SI = 0x1FA0; +constexpr unsigned int mmDP1_DP_SEC_FRAMING1__SI = 0x1FA1; +constexpr unsigned int mmDP1_DP_SEC_FRAMING2__SI = 0x1FA2; +constexpr unsigned int mmDP1_DP_SEC_FRAMING3__SI = 0x1FA3; +constexpr unsigned int mmDP1_DP_SEC_FRAMING4__SI = 0x1FA4; +constexpr unsigned int mmDP1_DP_SEC_PACKET_CNTL__SI = 0x1FAA; +constexpr unsigned int mmDP1_DP_SEC_TIMESTAMP__SI = 0x1FA9; +constexpr unsigned int mmDP1_DP_STEER_FIFO__SI = 0x1FC4; +constexpr unsigned int mmDP1_DP_TEST_DEBUG_DATA__SI = 0x1FFD; +constexpr unsigned int mmDP1_DP_TEST_DEBUG_INDEX__SI = 0x1FFC; +constexpr unsigned int mmDP1_DP_VID_INTERRUPT_CNTL__SI = 0x1FCF; +constexpr unsigned int mmDP1_DP_VID_MSA_VBID__SI = 0x1FCD; +constexpr unsigned int mmDP1_DP_VID_M__SI = 0x1FCB; +constexpr unsigned int mmDP1_DP_VID_N__SI = 0x1FCA; +constexpr unsigned int mmDP1_DP_VID_STREAM_CNTL__SI = 0x1FC3; +constexpr unsigned int mmDP1_DP_VID_TIMING__SI = 0x1FC9; +constexpr unsigned int mmDP2_DP_CONFIG__SI = 0x42C2; +constexpr unsigned int mmDP2_DP_DPHY_8B10B_CNTL__SI = 0x42D3; +constexpr unsigned int mmDP2_DP_DPHY_CNTL__SI = 0x42D0; +constexpr unsigned int mmDP2_DP_DPHY_CRC_CNTL__SI = 0x42D7; +constexpr unsigned int mmDP2_DP_DPHY_CRC_EN__SI = 0x42D6; +constexpr unsigned int mmDP2_DP_DPHY_CRC_RESULT__SI = 0x42D8; +constexpr unsigned int mmDP2_DP_DPHY_FAST_TRAINING__SI = 0x42CE; +constexpr unsigned int mmDP2_DP_DPHY_PRBS_CNTL__SI = 0x42D4; +constexpr unsigned int mmDP2_DP_DPHY_SYM__SI = 0x42D2; +constexpr unsigned int mmDP2_DP_DPHY_TRAINING_PATTERN_SEL__SI = 0x42D1; +constexpr unsigned int mmDP2_DP_LINK_CNTL__SI = 0x42C0; +constexpr unsigned int mmDP2_DP_PIXEL_FORMAT__SI = 0x42C1; +constexpr unsigned int mmDP2_DP_SEC_AUD_M_READBACK__SI = 0x42A8; +constexpr unsigned int mmDP2_DP_SEC_AUD_M__SI = 0x42A7; +constexpr unsigned int mmDP2_DP_SEC_AUD_N_READBACK__SI = 0x42A6; +constexpr unsigned int mmDP2_DP_SEC_AUD_N__SI = 0x42A5; +constexpr unsigned int mmDP2_DP_SEC_CNTL__SI = 0x42A0; +constexpr unsigned int mmDP2_DP_SEC_FRAMING1__SI = 0x42A1; +constexpr unsigned int mmDP2_DP_SEC_FRAMING2__SI = 0x42A2; +constexpr unsigned int mmDP2_DP_SEC_FRAMING3__SI = 0x42A3; +constexpr unsigned int mmDP2_DP_SEC_FRAMING4__SI = 0x42A4; +constexpr unsigned int mmDP2_DP_SEC_PACKET_CNTL__SI = 0x42AA; +constexpr unsigned int mmDP2_DP_SEC_TIMESTAMP__SI = 0x42A9; +constexpr unsigned int mmDP2_DP_STEER_FIFO__SI = 0x42C4; +constexpr unsigned int mmDP2_DP_TEST_DEBUG_DATA__SI = 0x42FD; +constexpr unsigned int mmDP2_DP_TEST_DEBUG_INDEX__SI = 0x42FC; +constexpr unsigned int mmDP2_DP_VID_INTERRUPT_CNTL__SI = 0x42CF; +constexpr unsigned int mmDP2_DP_VID_MSA_VBID__SI = 0x42CD; +constexpr unsigned int mmDP2_DP_VID_M__SI = 0x42CB; +constexpr unsigned int mmDP2_DP_VID_N__SI = 0x42CA; +constexpr unsigned int mmDP2_DP_VID_STREAM_CNTL__SI = 0x42C3; +constexpr unsigned int mmDP2_DP_VID_TIMING__SI = 0x42C9; +constexpr unsigned int mmDP3_DP_CONFIG__SI = 0x45C2; +constexpr unsigned int mmDP3_DP_DPHY_8B10B_CNTL__SI = 0x45D3; +constexpr unsigned int mmDP3_DP_DPHY_CNTL__SI = 0x45D0; +constexpr unsigned int mmDP3_DP_DPHY_CRC_CNTL__SI = 0x45D7; +constexpr unsigned int mmDP3_DP_DPHY_CRC_EN__SI = 0x45D6; +constexpr unsigned int mmDP3_DP_DPHY_CRC_RESULT__SI = 0x45D8; +constexpr unsigned int mmDP3_DP_DPHY_FAST_TRAINING__SI = 0x45CE; +constexpr unsigned int mmDP3_DP_DPHY_PRBS_CNTL__SI = 0x45D4; +constexpr unsigned int mmDP3_DP_DPHY_SYM__SI = 0x45D2; +constexpr unsigned int mmDP3_DP_DPHY_TRAINING_PATTERN_SEL__SI = 0x45D1; +constexpr unsigned int mmDP3_DP_LINK_CNTL__SI = 0x45C0; +constexpr unsigned int mmDP3_DP_PIXEL_FORMAT__SI = 0x45C1; +constexpr unsigned int mmDP3_DP_SEC_AUD_M_READBACK__SI = 0x45A8; +constexpr unsigned int mmDP3_DP_SEC_AUD_M__SI = 0x45A7; +constexpr unsigned int mmDP3_DP_SEC_AUD_N_READBACK__SI = 0x45A6; +constexpr unsigned int mmDP3_DP_SEC_AUD_N__SI = 0x45A5; +constexpr unsigned int mmDP3_DP_SEC_CNTL__SI = 0x45A0; +constexpr unsigned int mmDP3_DP_SEC_FRAMING1__SI = 0x45A1; +constexpr unsigned int mmDP3_DP_SEC_FRAMING2__SI = 0x45A2; +constexpr unsigned int mmDP3_DP_SEC_FRAMING3__SI = 0x45A3; +constexpr unsigned int mmDP3_DP_SEC_FRAMING4__SI = 0x45A4; +constexpr unsigned int mmDP3_DP_SEC_PACKET_CNTL__SI = 0x45AA; +constexpr unsigned int mmDP3_DP_SEC_TIMESTAMP__SI = 0x45A9; +constexpr unsigned int mmDP3_DP_STEER_FIFO__SI = 0x45C4; +constexpr unsigned int mmDP3_DP_TEST_DEBUG_DATA__SI = 0x45FD; +constexpr unsigned int mmDP3_DP_TEST_DEBUG_INDEX__SI = 0x45FC; +constexpr unsigned int mmDP3_DP_VID_INTERRUPT_CNTL__SI = 0x45CF; +constexpr unsigned int mmDP3_DP_VID_MSA_VBID__SI = 0x45CD; +constexpr unsigned int mmDP3_DP_VID_M__SI = 0x45CB; +constexpr unsigned int mmDP3_DP_VID_N__SI = 0x45CA; +constexpr unsigned int mmDP3_DP_VID_STREAM_CNTL__SI = 0x45C3; +constexpr unsigned int mmDP3_DP_VID_TIMING__SI = 0x45C9; +constexpr unsigned int mmDP4_DP_CONFIG__SI = 0x48C2; +constexpr unsigned int mmDP4_DP_DPHY_8B10B_CNTL__SI = 0x48D3; +constexpr unsigned int mmDP4_DP_DPHY_CNTL__SI = 0x48D0; +constexpr unsigned int mmDP4_DP_DPHY_CRC_CNTL__SI = 0x48D7; +constexpr unsigned int mmDP4_DP_DPHY_CRC_EN__SI = 0x48D6; +constexpr unsigned int mmDP4_DP_DPHY_CRC_RESULT__SI = 0x48D8; +constexpr unsigned int mmDP4_DP_DPHY_FAST_TRAINING__SI = 0x48CE; +constexpr unsigned int mmDP4_DP_DPHY_PRBS_CNTL__SI = 0x48D4; +constexpr unsigned int mmDP4_DP_DPHY_SYM__SI = 0x48D2; +constexpr unsigned int mmDP4_DP_DPHY_TRAINING_PATTERN_SEL__SI = 0x48D1; +constexpr unsigned int mmDP4_DP_LINK_CNTL__SI = 0x48C0; +constexpr unsigned int mmDP4_DP_PIXEL_FORMAT__SI = 0x48C1; +constexpr unsigned int mmDP4_DP_SEC_AUD_M_READBACK__SI = 0x48A8; +constexpr unsigned int mmDP4_DP_SEC_AUD_M__SI = 0x48A7; +constexpr unsigned int mmDP4_DP_SEC_AUD_N_READBACK__SI = 0x48A6; +constexpr unsigned int mmDP4_DP_SEC_AUD_N__SI = 0x48A5; +constexpr unsigned int mmDP4_DP_SEC_CNTL__SI = 0x48A0; +constexpr unsigned int mmDP4_DP_SEC_FRAMING1__SI = 0x48A1; +constexpr unsigned int mmDP4_DP_SEC_FRAMING2__SI = 0x48A2; +constexpr unsigned int mmDP4_DP_SEC_FRAMING3__SI = 0x48A3; +constexpr unsigned int mmDP4_DP_SEC_FRAMING4__SI = 0x48A4; +constexpr unsigned int mmDP4_DP_SEC_PACKET_CNTL__SI = 0x48AA; +constexpr unsigned int mmDP4_DP_SEC_TIMESTAMP__SI = 0x48A9; +constexpr unsigned int mmDP4_DP_STEER_FIFO__SI = 0x48C4; +constexpr unsigned int mmDP4_DP_TEST_DEBUG_DATA__SI = 0x48FD; +constexpr unsigned int mmDP4_DP_TEST_DEBUG_INDEX__SI = 0x48FC; +constexpr unsigned int mmDP4_DP_VID_INTERRUPT_CNTL__SI = 0x48CF; +constexpr unsigned int mmDP4_DP_VID_MSA_VBID__SI = 0x48CD; +constexpr unsigned int mmDP4_DP_VID_M__SI = 0x48CB; +constexpr unsigned int mmDP4_DP_VID_N__SI = 0x48CA; +constexpr unsigned int mmDP4_DP_VID_STREAM_CNTL__SI = 0x48C3; +constexpr unsigned int mmDP4_DP_VID_TIMING__SI = 0x48C9; +constexpr unsigned int mmDP5_DP_CONFIG__SI = 0x4BC2; +constexpr unsigned int mmDP5_DP_DPHY_8B10B_CNTL__SI = 0x4BD3; +constexpr unsigned int mmDP5_DP_DPHY_CNTL__SI = 0x4BD0; +constexpr unsigned int mmDP5_DP_DPHY_CRC_CNTL__SI = 0x4BD7; +constexpr unsigned int mmDP5_DP_DPHY_CRC_EN__SI = 0x4BD6; +constexpr unsigned int mmDP5_DP_DPHY_CRC_RESULT__SI = 0x4BD8; +constexpr unsigned int mmDP5_DP_DPHY_FAST_TRAINING__SI = 0x4BCE; +constexpr unsigned int mmDP5_DP_DPHY_PRBS_CNTL__SI = 0x4BD4; +constexpr unsigned int mmDP5_DP_DPHY_SYM__SI = 0x4BD2; +constexpr unsigned int mmDP5_DP_DPHY_TRAINING_PATTERN_SEL__SI = 0x4BD1; +constexpr unsigned int mmDP5_DP_LINK_CNTL__SI = 0x4BC0; +constexpr unsigned int mmDP5_DP_PIXEL_FORMAT__SI = 0x4BC1; +constexpr unsigned int mmDP5_DP_SEC_AUD_M_READBACK__SI = 0x4BA8; +constexpr unsigned int mmDP5_DP_SEC_AUD_M__SI = 0x4BA7; +constexpr unsigned int mmDP5_DP_SEC_AUD_N_READBACK__SI = 0x4BA6; +constexpr unsigned int mmDP5_DP_SEC_AUD_N__SI = 0x4BA5; +constexpr unsigned int mmDP5_DP_SEC_CNTL__SI = 0x4BA0; +constexpr unsigned int mmDP5_DP_SEC_FRAMING1__SI = 0x4BA1; +constexpr unsigned int mmDP5_DP_SEC_FRAMING2__SI = 0x4BA2; +constexpr unsigned int mmDP5_DP_SEC_FRAMING3__SI = 0x4BA3; +constexpr unsigned int mmDP5_DP_SEC_FRAMING4__SI = 0x4BA4; +constexpr unsigned int mmDP5_DP_SEC_PACKET_CNTL__SI = 0x4BAA; +constexpr unsigned int mmDP5_DP_SEC_TIMESTAMP__SI = 0x4BA9; +constexpr unsigned int mmDP5_DP_STEER_FIFO__SI = 0x4BC4; +constexpr unsigned int mmDP5_DP_TEST_DEBUG_DATA__SI = 0x4BFD; +constexpr unsigned int mmDP5_DP_TEST_DEBUG_INDEX__SI = 0x4BFC; +constexpr unsigned int mmDP5_DP_VID_INTERRUPT_CNTL__SI = 0x4BCF; +constexpr unsigned int mmDP5_DP_VID_MSA_VBID__SI = 0x4BCD; +constexpr unsigned int mmDP5_DP_VID_M__SI = 0x4BCB; +constexpr unsigned int mmDP5_DP_VID_N__SI = 0x4BCA; +constexpr unsigned int mmDP5_DP_VID_STREAM_CNTL__SI = 0x4BC3; +constexpr unsigned int mmDP5_DP_VID_TIMING__SI = 0x4BC9; +constexpr unsigned int mmDP_AUX0_AUX_ARB_CONTROL__SI = 0x1882; +constexpr unsigned int mmDP_AUX0_AUX_CONTROL__SI = 0x1880; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_RX_CONTROL0__SI = 0x188A; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_RX_CONTROL1__SI = 0x188B; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_RX_STATUS__SI = 0x188D; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_TX_CONTROL__SI = 0x1889; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_TX_REF_CONTROL__SI = 0x1888; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_TX_STATUS__SI = 0x188C; +constexpr unsigned int mmDP_AUX0_AUX_INTERRUPT_CONTROL__SI = 0x1883; +constexpr unsigned int mmDP_AUX0_AUX_LS_DATA__SI = 0x1887; +constexpr unsigned int mmDP_AUX0_AUX_LS_STATUS__SI = 0x1885; +constexpr unsigned int mmDP_AUX0_AUX_SW_CONTROL__SI = 0x1881; +constexpr unsigned int mmDP_AUX0_AUX_SW_DATA__SI = 0x1886; +constexpr unsigned int mmDP_AUX0_AUX_SW_STATUS__SI = 0x1884; +constexpr unsigned int mmDP_AUX1_AUX_ARB_CONTROL__SI = 0x1896; +constexpr unsigned int mmDP_AUX1_AUX_CONTROL__SI = 0x1894; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_RX_CONTROL0__SI = 0x189E; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_RX_CONTROL1__SI = 0x189F; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_RX_STATUS__SI = 0x18A1; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_TX_CONTROL__SI = 0x189D; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_TX_REF_CONTROL__SI = 0x189C; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_TX_STATUS__SI = 0x18A0; +constexpr unsigned int mmDP_AUX1_AUX_INTERRUPT_CONTROL__SI = 0x1897; +constexpr unsigned int mmDP_AUX1_AUX_LS_DATA__SI = 0x189B; +constexpr unsigned int mmDP_AUX1_AUX_LS_STATUS__SI = 0x1899; +constexpr unsigned int mmDP_AUX1_AUX_SW_CONTROL__SI = 0x1895; +constexpr unsigned int mmDP_AUX1_AUX_SW_DATA__SI = 0x189A; +constexpr unsigned int mmDP_AUX1_AUX_SW_STATUS__SI = 0x1898; +constexpr unsigned int mmDP_AUX2_AUX_ARB_CONTROL__SI = 0x18AA; +constexpr unsigned int mmDP_AUX2_AUX_CONTROL__SI = 0x18A8; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_RX_CONTROL0__SI = 0x18B2; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_RX_CONTROL1__SI = 0x18B3; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_RX_STATUS__SI = 0x18B5; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_TX_CONTROL__SI = 0x18B1; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_TX_REF_CONTROL__SI = 0x18B0; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_TX_STATUS__SI = 0x18B4; +constexpr unsigned int mmDP_AUX2_AUX_INTERRUPT_CONTROL__SI = 0x18AB; +constexpr unsigned int mmDP_AUX2_AUX_LS_DATA__SI = 0x18AF; +constexpr unsigned int mmDP_AUX2_AUX_LS_STATUS__SI = 0x18AD; +constexpr unsigned int mmDP_AUX2_AUX_SW_CONTROL__SI = 0x18A9; +constexpr unsigned int mmDP_AUX2_AUX_SW_DATA__SI = 0x18AE; +constexpr unsigned int mmDP_AUX2_AUX_SW_STATUS__SI = 0x18AC; +constexpr unsigned int mmDP_AUX3_AUX_ARB_CONTROL__SI = 0x18C2; +constexpr unsigned int mmDP_AUX3_AUX_CONTROL__SI = 0x18C0; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_RX_CONTROL0__SI = 0x18CA; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_RX_CONTROL1__SI = 0x18CB; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_RX_STATUS__SI = 0x18CD; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_TX_CONTROL__SI = 0x18C9; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_TX_REF_CONTROL__SI = 0x18C8; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_TX_STATUS__SI = 0x18CC; +constexpr unsigned int mmDP_AUX3_AUX_INTERRUPT_CONTROL__SI = 0x18C3; +constexpr unsigned int mmDP_AUX3_AUX_LS_DATA__SI = 0x18C7; +constexpr unsigned int mmDP_AUX3_AUX_LS_STATUS__SI = 0x18C5; +constexpr unsigned int mmDP_AUX3_AUX_SW_CONTROL__SI = 0x18C1; +constexpr unsigned int mmDP_AUX3_AUX_SW_DATA__SI = 0x18C6; +constexpr unsigned int mmDP_AUX3_AUX_SW_STATUS__SI = 0x18C4; +constexpr unsigned int mmDP_AUX4_AUX_ARB_CONTROL__SI = 0x18D6; +constexpr unsigned int mmDP_AUX4_AUX_CONTROL__SI = 0x18D4; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_RX_CONTROL0__SI = 0x18DE; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_RX_CONTROL1__SI = 0x18DF; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_RX_STATUS__SI = 0x18E1; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_TX_CONTROL__SI = 0x18DD; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_TX_REF_CONTROL__SI = 0x18DC; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_TX_STATUS__SI = 0x18E0; +constexpr unsigned int mmDP_AUX4_AUX_INTERRUPT_CONTROL__SI = 0x18D7; +constexpr unsigned int mmDP_AUX4_AUX_LS_DATA__SI = 0x18DB; +constexpr unsigned int mmDP_AUX4_AUX_LS_STATUS__SI = 0x18D9; +constexpr unsigned int mmDP_AUX4_AUX_SW_CONTROL__SI = 0x18D5; +constexpr unsigned int mmDP_AUX4_AUX_SW_DATA__SI = 0x18DA; +constexpr unsigned int mmDP_AUX4_AUX_SW_STATUS__SI = 0x18D8; +constexpr unsigned int mmDP_AUX5_AUX_ARB_CONTROL__SI = 0x18EA; +constexpr unsigned int mmDP_AUX5_AUX_CONTROL__SI = 0x18E8; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_RX_CONTROL0__SI = 0x18F2; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_RX_CONTROL1__SI = 0x18F3; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_RX_STATUS__SI = 0x18F5; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_TX_CONTROL__SI = 0x18F1; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_TX_REF_CONTROL__SI = 0x18F0; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_TX_STATUS__SI = 0x18F4; +constexpr unsigned int mmDP_AUX5_AUX_INTERRUPT_CONTROL__SI = 0x18EB; +constexpr unsigned int mmDP_AUX5_AUX_LS_DATA__SI = 0x18EF; +constexpr unsigned int mmDP_AUX5_AUX_LS_STATUS__SI = 0x18ED; +constexpr unsigned int mmDP_AUX5_AUX_SW_CONTROL__SI = 0x18E9; +constexpr unsigned int mmDP_AUX5_AUX_SW_DATA__SI = 0x18EE; +constexpr unsigned int mmDP_AUX5_AUX_SW_STATUS__SI = 0x18EC; +constexpr unsigned int mmDP_CONFIG__SI = 0x1CC2; +constexpr unsigned int mmDP_DPHY_8B10B_CNTL__SI = 0x1CD3; +constexpr unsigned int mmDP_DPHY_CNTL__SI = 0x1CD0; +constexpr unsigned int mmDP_DPHY_CRC_CNTL__SI = 0x1CD7; +constexpr unsigned int mmDP_DPHY_CRC_EN__SI = 0x1CD6; +constexpr unsigned int mmDP_DPHY_CRC_RESULT__SI = 0x1CD8; +constexpr unsigned int mmDP_DPHY_FAST_TRAINING__SI = 0x1CCE; +constexpr unsigned int mmDP_DPHY_PRBS_CNTL__SI = 0x1CD4; +constexpr unsigned int mmDP_DPHY_SYM__SI = 0x1CD2; +constexpr unsigned int mmDP_DPHY_TRAINING_PATTERN_SEL__SI = 0x1CD1; +constexpr unsigned int mmDP_DTO0_MODULO__SI = 0x0171; +constexpr unsigned int mmDP_DTO0_PHASE__SI = 0x0170; +constexpr unsigned int mmDP_DTO1_MODULO__SI = 0x0173; +constexpr unsigned int mmDP_DTO1_PHASE__SI = 0x0172; +constexpr unsigned int mmDP_DTO2_MODULO__SI = 0x0175; +constexpr unsigned int mmDP_DTO2_PHASE__SI = 0x0174; +constexpr unsigned int mmDP_DTO3_MODULO__SI = 0x0177; +constexpr unsigned int mmDP_DTO3_PHASE__SI = 0x0176; +constexpr unsigned int mmDP_DTO4_MODULO__SI = 0x0179; +constexpr unsigned int mmDP_DTO4_PHASE__SI = 0x0178; +constexpr unsigned int mmDP_DTO5_MODULO__SI = 0x017B; +constexpr unsigned int mmDP_DTO5_PHASE__SI = 0x017A; +constexpr unsigned int mmDP_LINK_CNTL__SI = 0x1CC0; +constexpr unsigned int mmDP_PIXEL_FORMAT__SI = 0x1CC1; +constexpr unsigned int mmDP_SEC_AUD_M_READBACK__SI = 0x1CA8; +constexpr unsigned int mmDP_SEC_AUD_M__SI = 0x1CA7; +constexpr unsigned int mmDP_SEC_AUD_N_READBACK__SI = 0x1CA6; +constexpr unsigned int mmDP_SEC_AUD_N__SI = 0x1CA5; +constexpr unsigned int mmDP_SEC_CNTL__SI = 0x1CA0; +constexpr unsigned int mmDP_SEC_FRAMING1__SI = 0x1CA1; +constexpr unsigned int mmDP_SEC_FRAMING2__SI = 0x1CA2; +constexpr unsigned int mmDP_SEC_FRAMING3__SI = 0x1CA3; +constexpr unsigned int mmDP_SEC_FRAMING4__SI = 0x1CA4; +constexpr unsigned int mmDP_SEC_PACKET_CNTL__SI = 0x1CAA; +constexpr unsigned int mmDP_SEC_TIMESTAMP__SI = 0x1CA9; +constexpr unsigned int mmDP_STEER_FIFO__SI = 0x1CC4; +constexpr unsigned int mmDP_TEST_DEBUG_DATA__SI = 0x1CFD; +constexpr unsigned int mmDP_TEST_DEBUG_INDEX__SI = 0x1CFC; +constexpr unsigned int mmDP_VID_INTERRUPT_CNTL__SI = 0x1CCF; +constexpr unsigned int mmDP_VID_MSA_VBID__SI = 0x1CCD; +constexpr unsigned int mmDP_VID_M__SI = 0x1CCB; +constexpr unsigned int mmDP_VID_N__SI = 0x1CCA; +constexpr unsigned int mmDP_VID_STREAM_CNTL__SI = 0x1CC3; +constexpr unsigned int mmDP_VID_TIMING__SI = 0x1CC9; +constexpr unsigned int mmDVOACLKC_CNTL__SI = 0x014E; +constexpr unsigned int mmDVOACLKC_MVP_CNTL__SI = 0x014D; +constexpr unsigned int mmDVOACLKD_CNTL__SI = 0x014C; +constexpr unsigned int mmDVO_CONTROL__SI = 0x185B; +constexpr unsigned int mmDVO_CRC2_SIG_MASK__SI = 0x185D; +constexpr unsigned int mmDVO_CRC2_SIG_RESULT__SI = 0x185E; +constexpr unsigned int mmDVO_CRC_EN__SI = 0x185C; +constexpr unsigned int mmDVO_ENABLE__SI = 0x1858; +constexpr unsigned int mmDVO_OUTPUT__SI = 0x185A; +constexpr unsigned int mmDVO_SOURCE_SELECT__SI = 0x1859; +constexpr unsigned int mmDVO_STRENGTH_CONTROL__SI = 0x195D; +constexpr unsigned int mmEXT_OVERSCAN_LEFT_RIGHT__SI__VI = 0x1B5E; +constexpr unsigned int mmEXT_OVERSCAN_TOP_BOTTOM__SI__VI = 0x1B5F; +constexpr unsigned int mmFBC_CLIENT_REGION_MASK__SI = 0x16EB; +constexpr unsigned int mmFBC_CNTL__SI = 0x16D0; +constexpr unsigned int mmFBC_COMP_CNTL__SI = 0x16D4; +constexpr unsigned int mmFBC_COMP_MODE__SI = 0x16D5; +constexpr unsigned int mmFBC_CSM_REGION_OFFSET_01__SI = 0x16E9; +constexpr unsigned int mmFBC_CSM_REGION_OFFSET_23__SI = 0x16EA; +constexpr unsigned int mmFBC_DEBUG0__SI = 0x16D6; +constexpr unsigned int mmFBC_DEBUG1__SI = 0x16D7; +constexpr unsigned int mmFBC_DEBUG2__SI = 0x16D8; +constexpr unsigned int mmFBC_DEBUG_COMP__SI = 0x16EC; +constexpr unsigned int mmFBC_DEBUG_CSR_RDATA__SI = 0x16EE; +constexpr unsigned int mmFBC_DEBUG_CSR_WDATA__SI = 0x16EF; +constexpr unsigned int mmFBC_DEBUG_CSR__SI = 0x16ED; +constexpr unsigned int mmFBC_IDLE_FORCE_CLEAR_MASK__SI = 0x16D2; +constexpr unsigned int mmFBC_IDLE_MASK__SI = 0x16D1; +constexpr unsigned int mmFBC_IND_LUT0__SI = 0x16D9; +constexpr unsigned int mmFBC_IND_LUT10__SI = 0x16E3; +constexpr unsigned int mmFBC_IND_LUT11__SI = 0x16E4; +constexpr unsigned int mmFBC_IND_LUT12__SI = 0x16E5; +constexpr unsigned int mmFBC_IND_LUT13__SI = 0x16E6; +constexpr unsigned int mmFBC_IND_LUT14__SI = 0x16E7; +constexpr unsigned int mmFBC_IND_LUT15__SI = 0x16E8; +constexpr unsigned int mmFBC_IND_LUT1__SI = 0x16DA; +constexpr unsigned int mmFBC_IND_LUT2__SI = 0x16DB; +constexpr unsigned int mmFBC_IND_LUT3__SI = 0x16DC; +constexpr unsigned int mmFBC_IND_LUT4__SI = 0x16DD; +constexpr unsigned int mmFBC_IND_LUT5__SI = 0x16DE; +constexpr unsigned int mmFBC_IND_LUT6__SI = 0x16DF; +constexpr unsigned int mmFBC_IND_LUT7__SI = 0x16E0; +constexpr unsigned int mmFBC_IND_LUT8__SI = 0x16E1; +constexpr unsigned int mmFBC_IND_LUT9__SI = 0x16E2; +constexpr unsigned int mmFBC_MISC__SI = 0x16F0; +constexpr unsigned int mmFBC_START_STOP_DELAY__SI = 0x16D3; +constexpr unsigned int mmFBC_TEST_DEBUG_DATA__SI = 0x16F5; +constexpr unsigned int mmFBC_TEST_DEBUG_INDEX__SI = 0x16F4; +constexpr unsigned int mmFMT0_FMT_BIT_DEPTH_CONTROL__SI__VI = 0x1BF2; +constexpr unsigned int mmFMT0_FMT_CLAMP_CNTL__SI__VI = 0x1BF9; +constexpr unsigned int mmFMT0_FMT_CONTROL__SI__VI = 0x1BEE; +constexpr unsigned int mmFMT0_FMT_CRC_CNTL__SI__VI = 0x1BFA; +constexpr unsigned int mmFMT0_FMT_CRC_SIG_BLUE_CONTROL_MASK__SI__VI = 0x1BFC; +constexpr unsigned int mmFMT0_FMT_CRC_SIG_BLUE_CONTROL__SI__VI = 0x1BFE; +constexpr unsigned int mmFMT0_FMT_CRC_SIG_RED_GREEN_MASK__SI__VI = 0x1BFB; +constexpr unsigned int mmFMT0_FMT_CRC_SIG_RED_GREEN__SI__VI = 0x1BFD; +constexpr unsigned int mmFMT0_FMT_DEBUG_CNTL__SI__VI = 0x1BFF; +constexpr unsigned int mmFMT0_FMT_DITHER_RAND_B_SEED__SI__VI = 0x1BF5; +constexpr unsigned int mmFMT0_FMT_DITHER_RAND_G_SEED__SI__VI = 0x1BF4; +constexpr unsigned int mmFMT0_FMT_DITHER_RAND_R_SEED__SI__VI = 0x1BF3; +constexpr unsigned int mmFMT0_FMT_DYNAMIC_EXP_CNTL__SI__VI = 0x1BED; +constexpr unsigned int mmFMT0_FMT_FORCE_DATA_0_1__SI__VI = 0x1BF0; +constexpr unsigned int mmFMT0_FMT_FORCE_DATA_2_3__SI__VI = 0x1BF1; +constexpr unsigned int mmFMT0_FMT_FORCE_OUTPUT_CNTL__SI__VI = 0x1BEF; +constexpr unsigned int mmFMT0_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__SI__VI = 0x1BF6; +constexpr unsigned int mmFMT0_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__SI__VI = 0x1BF7; +constexpr unsigned int mmFMT0_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__SI__VI = 0x1BF8; +constexpr unsigned int mmFMT1_FMT_BIT_DEPTH_CONTROL__SI = 0x1EF2; +constexpr unsigned int mmFMT1_FMT_CLAMP_CNTL__SI = 0x1EF9; +constexpr unsigned int mmFMT1_FMT_CONTROL__SI = 0x1EEE; +constexpr unsigned int mmFMT1_FMT_CRC_CNTL__SI = 0x1EFA; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_BLUE_CONTROL_MASK__SI = 0x1EFC; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_BLUE_CONTROL__SI = 0x1EFE; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_RED_GREEN_MASK__SI = 0x1EFB; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_RED_GREEN__SI = 0x1EFD; +constexpr unsigned int mmFMT1_FMT_DEBUG_CNTL__SI = 0x1EFF; +constexpr unsigned int mmFMT1_FMT_DITHER_RAND_B_SEED__SI = 0x1EF5; +constexpr unsigned int mmFMT1_FMT_DITHER_RAND_G_SEED__SI = 0x1EF4; +constexpr unsigned int mmFMT1_FMT_DITHER_RAND_R_SEED__SI = 0x1EF3; +constexpr unsigned int mmFMT1_FMT_DYNAMIC_EXP_CNTL__SI = 0x1EED; +constexpr unsigned int mmFMT1_FMT_FORCE_DATA_0_1__SI = 0x1EF0; +constexpr unsigned int mmFMT1_FMT_FORCE_DATA_2_3__SI = 0x1EF1; +constexpr unsigned int mmFMT1_FMT_FORCE_OUTPUT_CNTL__SI = 0x1EEF; +constexpr unsigned int mmFMT1_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__SI = 0x1EF6; +constexpr unsigned int mmFMT1_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__SI = 0x1EF7; +constexpr unsigned int mmFMT1_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__SI = 0x1EF8; +constexpr unsigned int mmFMT2_FMT_BIT_DEPTH_CONTROL__SI = 0x41F2; +constexpr unsigned int mmFMT2_FMT_CLAMP_CNTL__SI = 0x41F9; +constexpr unsigned int mmFMT2_FMT_CONTROL__SI = 0x41EE; +constexpr unsigned int mmFMT2_FMT_CRC_CNTL__SI = 0x41FA; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_BLUE_CONTROL_MASK__SI = 0x41FC; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_BLUE_CONTROL__SI = 0x41FE; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_RED_GREEN_MASK__SI = 0x41FB; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_RED_GREEN__SI = 0x41FD; +constexpr unsigned int mmFMT2_FMT_DEBUG_CNTL__SI = 0x41FF; +constexpr unsigned int mmFMT2_FMT_DITHER_RAND_B_SEED__SI = 0x41F5; +constexpr unsigned int mmFMT2_FMT_DITHER_RAND_G_SEED__SI = 0x41F4; +constexpr unsigned int mmFMT2_FMT_DITHER_RAND_R_SEED__SI = 0x41F3; +constexpr unsigned int mmFMT2_FMT_DYNAMIC_EXP_CNTL__SI = 0x41ED; +constexpr unsigned int mmFMT2_FMT_FORCE_DATA_0_1__SI = 0x41F0; +constexpr unsigned int mmFMT2_FMT_FORCE_DATA_2_3__SI = 0x41F1; +constexpr unsigned int mmFMT2_FMT_FORCE_OUTPUT_CNTL__SI = 0x41EF; +constexpr unsigned int mmFMT2_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__SI = 0x41F6; +constexpr unsigned int mmFMT2_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__SI = 0x41F7; +constexpr unsigned int mmFMT2_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__SI = 0x41F8; +constexpr unsigned int mmFMT3_FMT_BIT_DEPTH_CONTROL__SI = 0x44F2; +constexpr unsigned int mmFMT3_FMT_CLAMP_CNTL__SI = 0x44F9; +constexpr unsigned int mmFMT3_FMT_CONTROL__SI = 0x44EE; +constexpr unsigned int mmFMT3_FMT_CRC_CNTL__SI = 0x44FA; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_BLUE_CONTROL_MASK__SI = 0x44FC; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_BLUE_CONTROL__SI = 0x44FE; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_RED_GREEN_MASK__SI = 0x44FB; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_RED_GREEN__SI = 0x44FD; +constexpr unsigned int mmFMT3_FMT_DEBUG_CNTL__SI = 0x44FF; +constexpr unsigned int mmFMT3_FMT_DITHER_RAND_B_SEED__SI = 0x44F5; +constexpr unsigned int mmFMT3_FMT_DITHER_RAND_G_SEED__SI = 0x44F4; +constexpr unsigned int mmFMT3_FMT_DITHER_RAND_R_SEED__SI = 0x44F3; +constexpr unsigned int mmFMT3_FMT_DYNAMIC_EXP_CNTL__SI = 0x44ED; +constexpr unsigned int mmFMT3_FMT_FORCE_DATA_0_1__SI = 0x44F0; +constexpr unsigned int mmFMT3_FMT_FORCE_DATA_2_3__SI = 0x44F1; +constexpr unsigned int mmFMT3_FMT_FORCE_OUTPUT_CNTL__SI = 0x44EF; +constexpr unsigned int mmFMT3_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__SI = 0x44F6; +constexpr unsigned int mmFMT3_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__SI = 0x44F7; +constexpr unsigned int mmFMT3_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__SI = 0x44F8; +constexpr unsigned int mmFMT4_FMT_BIT_DEPTH_CONTROL__SI = 0x47F2; +constexpr unsigned int mmFMT4_FMT_CLAMP_CNTL__SI = 0x47F9; +constexpr unsigned int mmFMT4_FMT_CONTROL__SI = 0x47EE; +constexpr unsigned int mmFMT4_FMT_CRC_CNTL__SI = 0x47FA; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_BLUE_CONTROL_MASK__SI = 0x47FC; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_BLUE_CONTROL__SI = 0x47FE; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_RED_GREEN_MASK__SI = 0x47FB; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_RED_GREEN__SI = 0x47FD; +constexpr unsigned int mmFMT4_FMT_DEBUG_CNTL__SI = 0x47FF; +constexpr unsigned int mmFMT4_FMT_DITHER_RAND_B_SEED__SI = 0x47F5; +constexpr unsigned int mmFMT4_FMT_DITHER_RAND_G_SEED__SI = 0x47F4; +constexpr unsigned int mmFMT4_FMT_DITHER_RAND_R_SEED__SI = 0x47F3; +constexpr unsigned int mmFMT4_FMT_DYNAMIC_EXP_CNTL__SI = 0x47ED; +constexpr unsigned int mmFMT4_FMT_FORCE_DATA_0_1__SI = 0x47F0; +constexpr unsigned int mmFMT4_FMT_FORCE_DATA_2_3__SI = 0x47F1; +constexpr unsigned int mmFMT4_FMT_FORCE_OUTPUT_CNTL__SI = 0x47EF; +constexpr unsigned int mmFMT4_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__SI = 0x47F6; +constexpr unsigned int mmFMT4_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__SI = 0x47F7; +constexpr unsigned int mmFMT4_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__SI = 0x47F8; +constexpr unsigned int mmFMT5_FMT_BIT_DEPTH_CONTROL__SI = 0x4AF2; +constexpr unsigned int mmFMT5_FMT_CLAMP_CNTL__SI = 0x4AF9; +constexpr unsigned int mmFMT5_FMT_CONTROL__SI = 0x4AEE; +constexpr unsigned int mmFMT5_FMT_CRC_CNTL__SI = 0x4AFA; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_BLUE_CONTROL_MASK__SI = 0x4AFC; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_BLUE_CONTROL__SI = 0x4AFE; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_RED_GREEN_MASK__SI = 0x4AFB; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_RED_GREEN__SI = 0x4AFD; +constexpr unsigned int mmFMT5_FMT_DEBUG_CNTL__SI = 0x4AFF; +constexpr unsigned int mmFMT5_FMT_DITHER_RAND_B_SEED__SI = 0x4AF5; +constexpr unsigned int mmFMT5_FMT_DITHER_RAND_G_SEED__SI = 0x4AF4; +constexpr unsigned int mmFMT5_FMT_DITHER_RAND_R_SEED__SI = 0x4AF3; +constexpr unsigned int mmFMT5_FMT_DYNAMIC_EXP_CNTL__SI = 0x4AED; +constexpr unsigned int mmFMT5_FMT_FORCE_DATA_0_1__SI = 0x4AF0; +constexpr unsigned int mmFMT5_FMT_FORCE_DATA_2_3__SI = 0x4AF1; +constexpr unsigned int mmFMT5_FMT_FORCE_OUTPUT_CNTL__SI = 0x4AEF; +constexpr unsigned int mmFMT5_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__SI = 0x4AF6; +constexpr unsigned int mmFMT5_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__SI = 0x4AF7; +constexpr unsigned int mmFMT5_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__SI = 0x4AF8; +constexpr unsigned int mmFMT_BIT_DEPTH_CONTROL__SI__VI = 0x1BF2; +constexpr unsigned int mmFMT_CLAMP_CNTL__SI__VI = 0x1BF9; +constexpr unsigned int mmFMT_CONTROL__SI__VI = 0x1BEE; +constexpr unsigned int mmFMT_CRC_CNTL__SI__VI = 0x1BFA; +constexpr unsigned int mmFMT_CRC_SIG_BLUE_CONTROL_MASK__SI__VI = 0x1BFC; +constexpr unsigned int mmFMT_CRC_SIG_BLUE_CONTROL__SI__VI = 0x1BFE; +constexpr unsigned int mmFMT_CRC_SIG_RED_GREEN_MASK__SI__VI = 0x1BFB; +constexpr unsigned int mmFMT_CRC_SIG_RED_GREEN__SI__VI = 0x1BFD; +constexpr unsigned int mmFMT_DEBUG_CNTL__SI__VI = 0x1BFF; +constexpr unsigned int mmFMT_DITHER_RAND_B_SEED__SI__VI = 0x1BF5; +constexpr unsigned int mmFMT_DITHER_RAND_G_SEED__SI__VI = 0x1BF4; +constexpr unsigned int mmFMT_DITHER_RAND_R_SEED__SI__VI = 0x1BF3; +constexpr unsigned int mmFMT_DYNAMIC_EXP_CNTL__SI__VI = 0x1BED; +constexpr unsigned int mmFMT_FORCE_DATA_0_1__SI__VI = 0x1BF0; +constexpr unsigned int mmFMT_FORCE_DATA_2_3__SI__VI = 0x1BF1; +constexpr unsigned int mmFMT_FORCE_OUTPUT_CNTL__SI__VI = 0x1BEF; +constexpr unsigned int mmFMT_TEMPORAL_DITHER_PATTERN_CONTROL__SI__VI = 0x1BF6; +constexpr unsigned int mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__SI__VI = 0x1BF7; +constexpr unsigned int mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__SI__VI = 0x1BF8; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_0__CI__VI = 0x1403; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_1__CI__VI = 0x1405; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_2__CI__VI = 0x1407; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_3__CI__VI = 0x1409; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_4__CI__VI = 0x140B; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_5__CI__VI = 0x140D; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_6__CI__VI = 0x140F; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_END_7__CI__VI = 0x1411; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_0__CI__VI = 0x1402; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_1__CI__VI = 0x1404; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_2__CI__VI = 0x1406; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_3__CI__VI = 0x1408; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_4__CI__VI = 0x140A; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_5__CI__VI = 0x140C; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_6__CI__VI = 0x140E; +constexpr unsigned int mmGARLIC_FLUSH_ADDR_START_7__CI__VI = 0x1410; +constexpr unsigned int mmGARLIC_FLUSH_CNTL__CI__VI = 0x1401; +constexpr unsigned int mmGARLIC_FLUSH_REQ__CI__VI = 0x1412; +constexpr unsigned int mmGB_ADDR_CONFIG = 0x263E; +constexpr unsigned int mmGB_BACKEND_MAP = 0x263F; +constexpr unsigned int mmGB_EDC_MODE = 0x307E; +constexpr unsigned int mmGB_GPU_ID = 0x2640; +constexpr unsigned int mmGB_MACROTILE_MODE0__CI__VI = 0x2664; +constexpr unsigned int mmGB_MACROTILE_MODE10__CI__VI = 0x266E; +constexpr unsigned int mmGB_MACROTILE_MODE11__CI__VI = 0x266F; +constexpr unsigned int mmGB_MACROTILE_MODE12__CI__VI = 0x2670; +constexpr unsigned int mmGB_MACROTILE_MODE13__CI__VI = 0x2671; +constexpr unsigned int mmGB_MACROTILE_MODE14__CI__VI = 0x2672; +constexpr unsigned int mmGB_MACROTILE_MODE15__CI__VI = 0x2673; +constexpr unsigned int mmGB_MACROTILE_MODE1__CI__VI = 0x2665; +constexpr unsigned int mmGB_MACROTILE_MODE2__CI__VI = 0x2666; +constexpr unsigned int mmGB_MACROTILE_MODE3__CI__VI = 0x2667; +constexpr unsigned int mmGB_MACROTILE_MODE4__CI__VI = 0x2668; +constexpr unsigned int mmGB_MACROTILE_MODE5__CI__VI = 0x2669; +constexpr unsigned int mmGB_MACROTILE_MODE6__CI__VI = 0x266A; +constexpr unsigned int mmGB_MACROTILE_MODE7__CI__VI = 0x266B; +constexpr unsigned int mmGB_MACROTILE_MODE8__CI__VI = 0x266C; +constexpr unsigned int mmGB_MACROTILE_MODE9__CI__VI = 0x266D; +constexpr unsigned int mmGB_TILE_MODE0 = 0x2644; +constexpr unsigned int mmGB_TILE_MODE1 = 0x2645; +constexpr unsigned int mmGB_TILE_MODE10 = 0x264E; +constexpr unsigned int mmGB_TILE_MODE11 = 0x264F; +constexpr unsigned int mmGB_TILE_MODE12 = 0x2650; +constexpr unsigned int mmGB_TILE_MODE13 = 0x2651; +constexpr unsigned int mmGB_TILE_MODE14 = 0x2652; +constexpr unsigned int mmGB_TILE_MODE15 = 0x2653; +constexpr unsigned int mmGB_TILE_MODE16 = 0x2654; +constexpr unsigned int mmGB_TILE_MODE17 = 0x2655; +constexpr unsigned int mmGB_TILE_MODE18 = 0x2656; +constexpr unsigned int mmGB_TILE_MODE19 = 0x2657; +constexpr unsigned int mmGB_TILE_MODE2 = 0x2646; +constexpr unsigned int mmGB_TILE_MODE20 = 0x2658; +constexpr unsigned int mmGB_TILE_MODE21 = 0x2659; +constexpr unsigned int mmGB_TILE_MODE22 = 0x265A; +constexpr unsigned int mmGB_TILE_MODE23 = 0x265B; +constexpr unsigned int mmGB_TILE_MODE24 = 0x265C; +constexpr unsigned int mmGB_TILE_MODE25 = 0x265D; +constexpr unsigned int mmGB_TILE_MODE26 = 0x265E; +constexpr unsigned int mmGB_TILE_MODE27 = 0x265F; +constexpr unsigned int mmGB_TILE_MODE28 = 0x2660; +constexpr unsigned int mmGB_TILE_MODE29 = 0x2661; +constexpr unsigned int mmGB_TILE_MODE3 = 0x2647; +constexpr unsigned int mmGB_TILE_MODE30 = 0x2662; +constexpr unsigned int mmGB_TILE_MODE31 = 0x2663; +constexpr unsigned int mmGB_TILE_MODE4 = 0x2648; +constexpr unsigned int mmGB_TILE_MODE5 = 0x2649; +constexpr unsigned int mmGB_TILE_MODE6 = 0x264A; +constexpr unsigned int mmGB_TILE_MODE7 = 0x264B; +constexpr unsigned int mmGB_TILE_MODE8 = 0x264C; +constexpr unsigned int mmGB_TILE_MODE9 = 0x264D; +constexpr unsigned int mmGCK_SMC_IND_DATA__CI__VI = 0x0081; +constexpr unsigned int mmGCK_SMC_IND_INDEX__CI__VI = 0x0080; +constexpr unsigned int mmGC_USER_PRIM_CONFIG__CI__VI = 0x2241; +constexpr unsigned int mmGC_USER_RB_BACKEND_DISABLE = 0x26DF; +constexpr unsigned int mmGC_USER_RB_REDUNDANCY__CI__VI = 0x26DE; +constexpr unsigned int mmGC_USER_SHADER_ARRAY_CONFIG = 0x2270; +constexpr unsigned int mmGC_USER_SYS_RB_BACKEND_DISABLE = 0x03A1; +constexpr unsigned int mmGDS_ATOM_BASE__CI__VI = 0xC40C; +constexpr unsigned int mmGDS_ATOM_BASE__SI = 0x25CE; +constexpr unsigned int mmGDS_ATOM_CNTL__CI__VI = 0xC40A; +constexpr unsigned int mmGDS_ATOM_CNTL__SI = 0x25CC; +constexpr unsigned int mmGDS_ATOM_COMPLETE__CI__VI = 0xC40B; +constexpr unsigned int mmGDS_ATOM_COMPLETE__SI = 0x25CD; +constexpr unsigned int mmGDS_ATOM_DST__CI__VI = 0xC410; +constexpr unsigned int mmGDS_ATOM_DST__SI = 0x25D2; +constexpr unsigned int mmGDS_ATOM_OFFSET0__CI__VI = 0xC40E; +constexpr unsigned int mmGDS_ATOM_OFFSET0__SI = 0x25D0; +constexpr unsigned int mmGDS_ATOM_OFFSET1__CI__VI = 0xC40F; +constexpr unsigned int mmGDS_ATOM_OFFSET1__SI = 0x25D1; +constexpr unsigned int mmGDS_ATOM_OP__CI__VI = 0xC411; +constexpr unsigned int mmGDS_ATOM_OP__SI = 0x25D3; +constexpr unsigned int mmGDS_ATOM_READ0_U__CI__VI = 0xC417; +constexpr unsigned int mmGDS_ATOM_READ0_U__SI = 0x25D9; +constexpr unsigned int mmGDS_ATOM_READ0__CI__VI = 0xC416; +constexpr unsigned int mmGDS_ATOM_READ0__SI = 0x25D8; +constexpr unsigned int mmGDS_ATOM_READ1_U__CI__VI = 0xC419; +constexpr unsigned int mmGDS_ATOM_READ1_U__SI = 0x25DB; +constexpr unsigned int mmGDS_ATOM_READ1__CI__VI = 0xC418; +constexpr unsigned int mmGDS_ATOM_READ1__SI = 0x25DA; +constexpr unsigned int mmGDS_ATOM_SIZE__CI__VI = 0xC40D; +constexpr unsigned int mmGDS_ATOM_SIZE__SI = 0x25CF; +constexpr unsigned int mmGDS_ATOM_SRC0_U__CI__VI = 0xC413; +constexpr unsigned int mmGDS_ATOM_SRC0_U__SI = 0x25D5; +constexpr unsigned int mmGDS_ATOM_SRC0__CI__VI = 0xC412; +constexpr unsigned int mmGDS_ATOM_SRC0__SI = 0x25D4; +constexpr unsigned int mmGDS_ATOM_SRC1_U__CI__VI = 0xC415; +constexpr unsigned int mmGDS_ATOM_SRC1_U__SI = 0x25D7; +constexpr unsigned int mmGDS_ATOM_SRC1__CI__VI = 0xC414; +constexpr unsigned int mmGDS_ATOM_SRC1__SI = 0x25D6; +constexpr unsigned int mmGDS_CNTL_STATUS = 0x25C1; +constexpr unsigned int mmGDS_COMPUTE_MAX_WAVE_ID__CI__VI = 0x3348; +constexpr unsigned int mmGDS_CONFIG = 0x25C0; +constexpr unsigned int mmGDS_DEBUG_CNTL__CI__VI = 0x25C8; +constexpr unsigned int mmGDS_DEBUG_CNTL__SI = 0x25DE; +constexpr unsigned int mmGDS_DEBUG_DATA__CI__VI = 0x25C9; +constexpr unsigned int mmGDS_DEBUG_DATA__SI = 0x25DF; +constexpr unsigned int mmGDS_ENHANCE2__CI__VI = 0x25C2; +constexpr unsigned int mmGDS_ENHANCE__CI__VI = 0x334B; +constexpr unsigned int mmGDS_ENHANCE__SI = 0x25DC; +constexpr unsigned int mmGDS_GRBM_SECDED_CNT__CI = 0x25C6; +constexpr unsigned int mmGDS_GRBM_SECDED_CNT__SI = 0x25E3; +constexpr unsigned int mmGDS_GWS_RESET0__CI__VI = 0x3344; +constexpr unsigned int mmGDS_GWS_RESET1__CI__VI = 0x3345; +constexpr unsigned int mmGDS_GWS_RESOURCE_CNTL__CI__VI = 0xC41A; +constexpr unsigned int mmGDS_GWS_RESOURCE_CNTL__SI = 0x25E0; +constexpr unsigned int mmGDS_GWS_RESOURCE_CNT__CI__VI = 0xC41C; +constexpr unsigned int mmGDS_GWS_RESOURCE_RESET__CI__VI = 0x3346; +constexpr unsigned int mmGDS_GWS_RESOURCE__CI__VI = 0xC41B; +constexpr unsigned int mmGDS_GWS_RESOURCE__SI = 0x25E1; +constexpr unsigned int mmGDS_GWS_VMID0__CI__VI = 0x3320; +constexpr unsigned int mmGDS_GWS_VMID10__CI__VI = 0x332A; +constexpr unsigned int mmGDS_GWS_VMID11__CI__VI = 0x332B; +constexpr unsigned int mmGDS_GWS_VMID12__CI__VI = 0x332C; +constexpr unsigned int mmGDS_GWS_VMID13__CI__VI = 0x332D; +constexpr unsigned int mmGDS_GWS_VMID14__CI__VI = 0x332E; +constexpr unsigned int mmGDS_GWS_VMID15__CI__VI = 0x332F; +constexpr unsigned int mmGDS_GWS_VMID1__CI__VI = 0x3321; +constexpr unsigned int mmGDS_GWS_VMID2__CI__VI = 0x3322; +constexpr unsigned int mmGDS_GWS_VMID3__CI__VI = 0x3323; +constexpr unsigned int mmGDS_GWS_VMID4__CI__VI = 0x3324; +constexpr unsigned int mmGDS_GWS_VMID5__CI__VI = 0x3325; +constexpr unsigned int mmGDS_GWS_VMID6__CI__VI = 0x3326; +constexpr unsigned int mmGDS_GWS_VMID7__CI__VI = 0x3327; +constexpr unsigned int mmGDS_GWS_VMID8__CI__VI = 0x3328; +constexpr unsigned int mmGDS_GWS_VMID9__CI__VI = 0x3329; +constexpr unsigned int mmGDS_OA_ADDRESS__CI__VI = 0xC41F; +constexpr unsigned int mmGDS_OA_CGPG_RESTORE__CI__VI = 0x334C; +constexpr unsigned int mmGDS_OA_CNTL__CI__VI = 0xC41D; +constexpr unsigned int mmGDS_OA_COUNTER__CI__VI = 0xC41E; +constexpr unsigned int mmGDS_OA_DED__CI = 0x25C7; +constexpr unsigned int mmGDS_OA_DED__SI = 0x25E4; +constexpr unsigned int mmGDS_OA_INCDEC__CI__VI = 0xC420; +constexpr unsigned int mmGDS_OA_RESET_MASK__CI__VI = 0x3349; +constexpr unsigned int mmGDS_OA_RESET__CI__VI = 0x334A; +constexpr unsigned int mmGDS_OA_RING_SIZE__CI__VI = 0xC421; +constexpr unsigned int mmGDS_OA_VMID0__CI__VI = 0x3330; +constexpr unsigned int mmGDS_OA_VMID10__CI__VI = 0x333A; +constexpr unsigned int mmGDS_OA_VMID11__CI__VI = 0x333B; +constexpr unsigned int mmGDS_OA_VMID12__CI__VI = 0x333C; +constexpr unsigned int mmGDS_OA_VMID13__CI__VI = 0x333D; +constexpr unsigned int mmGDS_OA_VMID14__CI__VI = 0x333E; +constexpr unsigned int mmGDS_OA_VMID15__CI__VI = 0x333F; +constexpr unsigned int mmGDS_OA_VMID1__CI__VI = 0x3331; +constexpr unsigned int mmGDS_OA_VMID2__CI__VI = 0x3332; +constexpr unsigned int mmGDS_OA_VMID3__CI__VI = 0x3333; +constexpr unsigned int mmGDS_OA_VMID4__CI__VI = 0x3334; +constexpr unsigned int mmGDS_OA_VMID5__CI__VI = 0x3335; +constexpr unsigned int mmGDS_OA_VMID6__CI__VI = 0x3336; +constexpr unsigned int mmGDS_OA_VMID7__CI__VI = 0x3337; +constexpr unsigned int mmGDS_OA_VMID8__CI__VI = 0x3338; +constexpr unsigned int mmGDS_OA_VMID9__CI__VI = 0x3339; +constexpr unsigned int mmGDS_PERFCOUNTER0_HI__CI__VI = 0xD281; +constexpr unsigned int mmGDS_PERFCOUNTER0_HI__SI = 0x25E7; +constexpr unsigned int mmGDS_PERFCOUNTER0_LO__CI__VI = 0xD280; +constexpr unsigned int mmGDS_PERFCOUNTER0_LO__SI = 0x25E6; +constexpr unsigned int mmGDS_PERFCOUNTER0_SELECT1__CI__VI = 0xDA84; +constexpr unsigned int mmGDS_PERFCOUNTER0_SELECT__CI__VI = 0xDA80; +constexpr unsigned int mmGDS_PERFCOUNTER0_SELECT__SI = 0x25E5; +constexpr unsigned int mmGDS_PERFCOUNTER1_HI__CI__VI = 0xD283; +constexpr unsigned int mmGDS_PERFCOUNTER1_HI__SI = 0x25EA; +constexpr unsigned int mmGDS_PERFCOUNTER1_LO__CI__VI = 0xD282; +constexpr unsigned int mmGDS_PERFCOUNTER1_LO__SI = 0x25E9; +constexpr unsigned int mmGDS_PERFCOUNTER1_SELECT__CI__VI = 0xDA81; +constexpr unsigned int mmGDS_PERFCOUNTER1_SELECT__SI = 0x25E8; +constexpr unsigned int mmGDS_PERFCOUNTER2_HI__CI__VI = 0xD285; +constexpr unsigned int mmGDS_PERFCOUNTER2_HI__SI = 0x25ED; +constexpr unsigned int mmGDS_PERFCOUNTER2_LO__CI__VI = 0xD284; +constexpr unsigned int mmGDS_PERFCOUNTER2_LO__SI = 0x25EC; +constexpr unsigned int mmGDS_PERFCOUNTER2_SELECT__CI__VI = 0xDA82; +constexpr unsigned int mmGDS_PERFCOUNTER2_SELECT__SI = 0x25EB; +constexpr unsigned int mmGDS_PERFCOUNTER3_HI__CI__VI = 0xD287; +constexpr unsigned int mmGDS_PERFCOUNTER3_HI__SI = 0x25F0; +constexpr unsigned int mmGDS_PERFCOUNTER3_LO__CI__VI = 0xD286; +constexpr unsigned int mmGDS_PERFCOUNTER3_LO__SI = 0x25EF; +constexpr unsigned int mmGDS_PERFCOUNTER3_SELECT__CI__VI = 0xDA83; +constexpr unsigned int mmGDS_PERFCOUNTER3_SELECT__SI = 0x25EE; +constexpr unsigned int mmGDS_PROTECTION_FAULT__CI__VI = 0x25C3; +constexpr unsigned int mmGDS_RD_ADDR__CI__VI = 0xC400; +constexpr unsigned int mmGDS_RD_ADDR__SI = 0x25C2; +constexpr unsigned int mmGDS_RD_BURST_ADDR__CI__VI = 0xC402; +constexpr unsigned int mmGDS_RD_BURST_ADDR__SI = 0x25C4; +constexpr unsigned int mmGDS_RD_BURST_COUNT__CI__VI = 0xC403; +constexpr unsigned int mmGDS_RD_BURST_COUNT__SI = 0x25C5; +constexpr unsigned int mmGDS_RD_BURST_DATA__CI__VI = 0xC404; +constexpr unsigned int mmGDS_RD_BURST_DATA__SI = 0x25C6; +constexpr unsigned int mmGDS_RD_DATA__CI__VI = 0xC401; +constexpr unsigned int mmGDS_RD_DATA__SI = 0x25C3; +constexpr unsigned int mmGDS_SECDED_CNT__CI = 0x25C5; +constexpr unsigned int mmGDS_SECDED_CNT__SI = 0x25E2; +constexpr unsigned int mmGDS_VMID0_BASE__CI__VI = 0x3300; +constexpr unsigned int mmGDS_VMID0_SIZE__CI__VI = 0x3301; +constexpr unsigned int mmGDS_VMID10_BASE__CI__VI = 0x3314; +constexpr unsigned int mmGDS_VMID10_SIZE__CI__VI = 0x3315; +constexpr unsigned int mmGDS_VMID11_BASE__CI__VI = 0x3316; +constexpr unsigned int mmGDS_VMID11_SIZE__CI__VI = 0x3317; +constexpr unsigned int mmGDS_VMID12_BASE__CI__VI = 0x3318; +constexpr unsigned int mmGDS_VMID12_SIZE__CI__VI = 0x3319; +constexpr unsigned int mmGDS_VMID13_BASE__CI__VI = 0x331A; +constexpr unsigned int mmGDS_VMID13_SIZE__CI__VI = 0x331B; +constexpr unsigned int mmGDS_VMID14_BASE__CI__VI = 0x331C; +constexpr unsigned int mmGDS_VMID14_SIZE__CI__VI = 0x331D; +constexpr unsigned int mmGDS_VMID15_BASE__CI__VI = 0x331E; +constexpr unsigned int mmGDS_VMID15_SIZE__CI__VI = 0x331F; +constexpr unsigned int mmGDS_VMID1_BASE__CI__VI = 0x3302; +constexpr unsigned int mmGDS_VMID1_SIZE__CI__VI = 0x3303; +constexpr unsigned int mmGDS_VMID2_BASE__CI__VI = 0x3304; +constexpr unsigned int mmGDS_VMID2_SIZE__CI__VI = 0x3305; +constexpr unsigned int mmGDS_VMID3_BASE__CI__VI = 0x3306; +constexpr unsigned int mmGDS_VMID3_SIZE__CI__VI = 0x3307; +constexpr unsigned int mmGDS_VMID4_BASE__CI__VI = 0x3308; +constexpr unsigned int mmGDS_VMID4_SIZE__CI__VI = 0x3309; +constexpr unsigned int mmGDS_VMID5_BASE__CI__VI = 0x330A; +constexpr unsigned int mmGDS_VMID5_SIZE__CI__VI = 0x330B; +constexpr unsigned int mmGDS_VMID6_BASE__CI__VI = 0x330C; +constexpr unsigned int mmGDS_VMID6_SIZE__CI__VI = 0x330D; +constexpr unsigned int mmGDS_VMID7_BASE__CI__VI = 0x330E; +constexpr unsigned int mmGDS_VMID7_SIZE__CI__VI = 0x330F; +constexpr unsigned int mmGDS_VMID8_BASE__CI__VI = 0x3310; +constexpr unsigned int mmGDS_VMID8_SIZE__CI__VI = 0x3311; +constexpr unsigned int mmGDS_VMID9_BASE__CI__VI = 0x3312; +constexpr unsigned int mmGDS_VMID9_SIZE__CI__VI = 0x3313; +constexpr unsigned int mmGDS_VM_PROTECTION_FAULT__CI__VI = 0x25C4; +constexpr unsigned int mmGDS_WRITE_COMPLETE__CI__VI = 0xC409; +constexpr unsigned int mmGDS_WRITE_COMPLETE__SI = 0x25CB; +constexpr unsigned int mmGDS_WR_ADDR__CI__VI = 0xC405; +constexpr unsigned int mmGDS_WR_ADDR__SI = 0x25C7; +constexpr unsigned int mmGDS_WR_BURST_ADDR__CI__VI = 0xC407; +constexpr unsigned int mmGDS_WR_BURST_ADDR__SI = 0x25C9; +constexpr unsigned int mmGDS_WR_BURST_DATA__CI__VI = 0xC408; +constexpr unsigned int mmGDS_WR_BURST_DATA__SI = 0x25CA; +constexpr unsigned int mmGDS_WR_DATA__CI__VI = 0xC406; +constexpr unsigned int mmGDS_WR_DATA__SI = 0x25C8; +constexpr unsigned int mmGENENB__SI__VI = 0x00F0; +constexpr unsigned int mmGENERAL_PWRMGT__SI = 0x01E0; +constexpr unsigned int mmGENERIC_I2C_CONTROL__SI = 0x1834; +constexpr unsigned int mmGENERIC_I2C_DATA__SI = 0x183A; +constexpr unsigned int mmGENERIC_I2C_INTERRUPT_CONTROL__SI = 0x1835; +constexpr unsigned int mmGENERIC_I2C_PIN_DEBUG__SI = 0x183C; +constexpr unsigned int mmGENERIC_I2C_PIN_SELECTION__SI = 0x183B; +constexpr unsigned int mmGENERIC_I2C_SETUP__SI = 0x1838; +constexpr unsigned int mmGENERIC_I2C_SPEED__SI = 0x1837; +constexpr unsigned int mmGENERIC_I2C_STATUS__SI = 0x1836; +constexpr unsigned int mmGENERIC_I2C_TRANSACTION__SI = 0x1839; +constexpr unsigned int mmGENFC_RD__SI__VI = 0x00F2; +constexpr unsigned int mmGENFC_WT__SI__VI = 0x00EE; +constexpr unsigned int mmGENMO_RD__SI__VI = 0x00F3; +constexpr unsigned int mmGENMO_WT__SI__VI = 0x00F0; +constexpr unsigned int mmGENS0__SI__VI = 0x00F0; +constexpr unsigned int mmGENS1__SI__VI = 0x00EE; +constexpr unsigned int mmGFX_COPY_STATE = 0xA1F4; +constexpr unsigned int mmGFX_PIPE_CONTROL__CI__VI = 0x226D; +constexpr unsigned int mmGFX_PIPE_PRIORITY__CI__VI = 0xF87F; +constexpr unsigned int mmGMCON_DEBUG__CI__VI = 0x0D5F; +constexpr unsigned int mmGMCON_MASK__CI__VI = 0x0D52; +constexpr unsigned int mmGMCON_MISC2__CI__VI = 0x0D44; +constexpr unsigned int mmGMCON_MISC3__CI__VI = 0x0D51; +constexpr unsigned int mmGMCON_MISC__CI__VI = 0x0D43; +constexpr unsigned int mmGMCON_PERF_MON_CNTL0__CI__VI = 0x0D4A; +constexpr unsigned int mmGMCON_PERF_MON_CNTL1__CI__VI = 0x0D4B; +constexpr unsigned int mmGMCON_PERF_MON_RSLT0__CI__VI = 0x0D4C; +constexpr unsigned int mmGMCON_PERF_MON_RSLT1__CI__VI = 0x0D4D; +constexpr unsigned int mmGMCON_PGFSM_CONFIG__CI__VI = 0x0D4E; +constexpr unsigned int mmGMCON_PGFSM_READ__CI__VI = 0x0D50; +constexpr unsigned int mmGMCON_PGFSM_WRITE__CI__VI = 0x0D4F; +constexpr unsigned int mmGMCON_RENG_EXECUTE__CI__VI = 0x0D42; +constexpr unsigned int mmGMCON_RENG_RAM_DATA__CI__VI = 0x0D41; +constexpr unsigned int mmGMCON_RENG_RAM_INDEX__CI__VI = 0x0D40; +constexpr unsigned int mmGMCON_STCTRL_REGISTER_SAVE_EXCL_SET0__CI__VI = 0x0D48; +constexpr unsigned int mmGMCON_STCTRL_REGISTER_SAVE_EXCL_SET1__CI__VI = 0x0D49; +constexpr unsigned int mmGMCON_STCTRL_REGISTER_SAVE_RANGE0__CI__VI = 0x0D45; +constexpr unsigned int mmGMCON_STCTRL_REGISTER_SAVE_RANGE1__CI__VI = 0x0D46; +constexpr unsigned int mmGMCON_STCTRL_REGISTER_SAVE_RANGE2__CI__VI = 0x0D47; +constexpr unsigned int mmGPIOPAD_A__CI__VI = 0x0183; +constexpr unsigned int mmGPIOPAD_A__SI = 0x05E7; +constexpr unsigned int mmGPIOPAD_EN__CI__VI = 0x0184; +constexpr unsigned int mmGPIOPAD_EN__SI = 0x05E8; +constexpr unsigned int mmGPIOPAD_EXTERN_TRIG_CNTL__CI__VI = 0x018D; +constexpr unsigned int mmGPIOPAD_EXTERN_TRIG_CNTL__SI = 0x05F1; +constexpr unsigned int mmGPIOPAD_INT_EN__CI__VI = 0x018A; +constexpr unsigned int mmGPIOPAD_INT_EN__SI = 0x05EE; +constexpr unsigned int mmGPIOPAD_INT_POLARITY__CI__VI = 0x018C; +constexpr unsigned int mmGPIOPAD_INT_POLARITY__SI = 0x05F0; +constexpr unsigned int mmGPIOPAD_INT_STAT_AK__CI__VI = 0x0189; +constexpr unsigned int mmGPIOPAD_INT_STAT_AK__SI = 0x05ED; +constexpr unsigned int mmGPIOPAD_INT_STAT_EN__CI__VI = 0x0187; +constexpr unsigned int mmGPIOPAD_INT_STAT_EN__SI = 0x05EB; +constexpr unsigned int mmGPIOPAD_INT_STAT__CI__VI = 0x0188; +constexpr unsigned int mmGPIOPAD_INT_STAT__SI = 0x05EC; +constexpr unsigned int mmGPIOPAD_INT_TYPE__CI__VI = 0x018B; +constexpr unsigned int mmGPIOPAD_INT_TYPE__SI = 0x05EF; +constexpr unsigned int mmGPIOPAD_MASK__CI__VI = 0x0182; +constexpr unsigned int mmGPIOPAD_MASK__SI = 0x05E6; +constexpr unsigned int mmGPIOPAD_PD_EN__CI__VI = 0x0193; +constexpr unsigned int mmGPIOPAD_PD_EN__SI = 0x05F4; +constexpr unsigned int mmGPIOPAD_PINSTRAPS__CI__VI = 0x0186; +constexpr unsigned int mmGPIOPAD_PINSTRAPS__SI = 0x05EA; +constexpr unsigned int mmGPIOPAD_PU_EN__CI__VI = 0x0192; +constexpr unsigned int mmGPIOPAD_PU_EN__SI = 0x05F3; +constexpr unsigned int mmGPIOPAD_RCVR_SEL__CI__VI = 0x0191; +constexpr unsigned int mmGPIOPAD_RCVR_SEL__SI = 0x05F2; +constexpr unsigned int mmGPIOPAD_STRENGTH__CI__VI = 0x0181; +constexpr unsigned int mmGPIOPAD_STRENGTH__SI = 0x05E5; +constexpr unsigned int mmGPIOPAD_SW_INT_STAT__CI__VI = 0x0180; +constexpr unsigned int mmGPIOPAD_SW_INT_STAT__SI = 0x05E4; +constexpr unsigned int mmGPIOPAD_Y__CI__VI = 0x0185; +constexpr unsigned int mmGPIOPAD_Y__SI = 0x05E9; +constexpr unsigned int mmGPU_GARLIC_FLUSH_DONE__CI__VI = 0x1414; +constexpr unsigned int mmGPU_GARLIC_FLUSH_REQ__CI__VI = 0x1413; +constexpr unsigned int mmGPU_HDP_FLUSH_DONE__CI__VI = 0x1538; +constexpr unsigned int mmGPU_HDP_FLUSH_REQ__CI__VI = 0x1537; +constexpr unsigned int mmGRBM_CNTL = 0x2000; +constexpr unsigned int mmGRBM_DEBUG = 0x2014; +constexpr unsigned int mmGRBM_DEBUG_CNTL = 0x2009; +constexpr unsigned int mmGRBM_DEBUG_DATA = 0x200A; +constexpr unsigned int mmGRBM_DEBUG_SNAPSHOT = 0x2015; +constexpr unsigned int mmGRBM_GFX_CLKEN_CNTL = 0x200C; +constexpr unsigned int mmGRBM_GFX_INDEX__CI__VI = 0xC200; +constexpr unsigned int mmGRBM_GFX_INDEX__SI = 0x200B; +constexpr unsigned int mmGRBM_INT_CNTL = 0x2018; +constexpr unsigned int mmGRBM_NOWHERE = 0x203F; +constexpr unsigned int mmGRBM_PERFCOUNTER0_HI__CI__VI = 0xD041; +constexpr unsigned int mmGRBM_PERFCOUNTER0_HI__SI = 0x201F; +constexpr unsigned int mmGRBM_PERFCOUNTER0_LO__CI__VI = 0xD040; +constexpr unsigned int mmGRBM_PERFCOUNTER0_LO__SI = 0x201E; +constexpr unsigned int mmGRBM_PERFCOUNTER0_SELECT__CI__VI = 0xD840; +constexpr unsigned int mmGRBM_PERFCOUNTER0_SELECT__SI = 0x201C; +constexpr unsigned int mmGRBM_PERFCOUNTER1_HI__CI__VI = 0xD044; +constexpr unsigned int mmGRBM_PERFCOUNTER1_HI__SI = 0x2021; +constexpr unsigned int mmGRBM_PERFCOUNTER1_LO__CI__VI = 0xD043; +constexpr unsigned int mmGRBM_PERFCOUNTER1_LO__SI = 0x2020; +constexpr unsigned int mmGRBM_PERFCOUNTER1_SELECT__CI__VI = 0xD841; +constexpr unsigned int mmGRBM_PERFCOUNTER1_SELECT__SI = 0x201D; +constexpr unsigned int mmGRBM_PWR_CNTL = 0x2003; +constexpr unsigned int mmGRBM_READ_ERROR = 0x2016; +constexpr unsigned int mmGRBM_READ_ERROR2__CI__VI = 0x2017; +constexpr unsigned int mmGRBM_SCRATCH_REG0 = 0x2040; +constexpr unsigned int mmGRBM_SCRATCH_REG1 = 0x2041; +constexpr unsigned int mmGRBM_SCRATCH_REG2 = 0x2042; +constexpr unsigned int mmGRBM_SCRATCH_REG3 = 0x2043; +constexpr unsigned int mmGRBM_SCRATCH_REG4 = 0x2044; +constexpr unsigned int mmGRBM_SCRATCH_REG5 = 0x2045; +constexpr unsigned int mmGRBM_SCRATCH_REG6 = 0x2046; +constexpr unsigned int mmGRBM_SCRATCH_REG7 = 0x2047; +constexpr unsigned int mmGRBM_SE0_PERFCOUNTER_HI__CI__VI = 0xD046; +constexpr unsigned int mmGRBM_SE0_PERFCOUNTER_HI__SI = 0x202B; +constexpr unsigned int mmGRBM_SE0_PERFCOUNTER_LO__CI__VI = 0xD045; +constexpr unsigned int mmGRBM_SE0_PERFCOUNTER_LO__SI = 0x202A; +constexpr unsigned int mmGRBM_SE0_PERFCOUNTER_SELECT__CI__VI = 0xD842; +constexpr unsigned int mmGRBM_SE0_PERFCOUNTER_SELECT__SI = 0x2026; +constexpr unsigned int mmGRBM_SE1_PERFCOUNTER_HI__CI__VI = 0xD048; +constexpr unsigned int mmGRBM_SE1_PERFCOUNTER_HI__SI = 0x202D; +constexpr unsigned int mmGRBM_SE1_PERFCOUNTER_LO__CI__VI = 0xD047; +constexpr unsigned int mmGRBM_SE1_PERFCOUNTER_LO__SI = 0x202C; +constexpr unsigned int mmGRBM_SE1_PERFCOUNTER_SELECT__CI__VI = 0xD843; +constexpr unsigned int mmGRBM_SE1_PERFCOUNTER_SELECT__SI = 0x2027; +constexpr unsigned int mmGRBM_SE2_PERFCOUNTER_HI__CI__VI = 0xD04A; +constexpr unsigned int mmGRBM_SE2_PERFCOUNTER_LO__CI__VI = 0xD049; +constexpr unsigned int mmGRBM_SE2_PERFCOUNTER_SELECT__CI__VI = 0xD844; +constexpr unsigned int mmGRBM_SE3_PERFCOUNTER_HI__CI__VI = 0xD04C; +constexpr unsigned int mmGRBM_SE3_PERFCOUNTER_LO__CI__VI = 0xD04B; +constexpr unsigned int mmGRBM_SE3_PERFCOUNTER_SELECT__CI__VI = 0xD845; +constexpr unsigned int mmGRBM_SKEW_CNTL = 0x2001; +constexpr unsigned int mmGRBM_SOFT_RESET = 0x2008; +constexpr unsigned int mmGRBM_STATUS = 0x2004; +constexpr unsigned int mmGRBM_STATUS2 = 0x2002; +constexpr unsigned int mmGRBM_STATUS_SE0 = 0x2005; +constexpr unsigned int mmGRBM_STATUS_SE1 = 0x2006; +constexpr unsigned int mmGRBM_STATUS_SE2__CI__VI = 0x200E; +constexpr unsigned int mmGRBM_STATUS_SE3__CI__VI = 0x200F; +constexpr unsigned int mmGRBM_WAIT_IDLE_CLOCKS = 0x200D; +constexpr unsigned int mmGRPH8_DATA__SI__VI = 0x00F3; +constexpr unsigned int mmGRPH8_IDX__SI__VI = 0x00F3; +constexpr unsigned int mmGRPH_COMPRESS_PITCH__SI__VI = 0x1A1A; +constexpr unsigned int mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH__SI__VI = 0x1A1B; +constexpr unsigned int mmGRPH_COMPRESS_SURFACE_ADDRESS__SI__VI = 0x1A19; +constexpr unsigned int mmGRPH_CONTROL = 0x1A01; +constexpr unsigned int mmGRPH_DFQ_CONTROL__SI__VI = 0x1A14; +constexpr unsigned int mmGRPH_DFQ_STATUS__SI__VI = 0x1A15; +constexpr unsigned int mmGRPH_ENABLE__SI__VI = 0x1A00; +constexpr unsigned int mmGRPH_FLIP_CONTROL__SI__VI = 0x1A12; +constexpr unsigned int mmGRPH_INTERRUPT_CONTROL__SI__VI = 0x1A17; +constexpr unsigned int mmGRPH_INTERRUPT_STATUS__SI__VI = 0x1A16; +constexpr unsigned int mmGRPH_LUT_10BIT_BYPASS__SI__VI = 0x1A02; +constexpr unsigned int mmGRPH_PITCH__SI__VI = 0x1A06; +constexpr unsigned int mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH__SI__VI = 0x1A07; +constexpr unsigned int mmGRPH_PRIMARY_SURFACE_ADDRESS__SI__VI = 0x1A04; +constexpr unsigned int mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH__SI__VI = 0x1A08; +constexpr unsigned int mmGRPH_SECONDARY_SURFACE_ADDRESS__SI__VI = 0x1A05; +constexpr unsigned int mmGRPH_SURFACE_ADDRESS_HIGH_INUSE__SI__VI = 0x1A18; +constexpr unsigned int mmGRPH_SURFACE_ADDRESS_INUSE__SI__VI = 0x1A13; +constexpr unsigned int mmGRPH_SURFACE_OFFSET_X__SI__VI = 0x1A09; +constexpr unsigned int mmGRPH_SURFACE_OFFSET_Y__SI__VI = 0x1A0A; +constexpr unsigned int mmGRPH_SWAP_CNTL__SI__VI = 0x1A03; +constexpr unsigned int mmGRPH_UPDATE__SI__VI = 0x1A11; +constexpr unsigned int mmGRPH_X_END__SI__VI = 0x1A0D; +constexpr unsigned int mmGRPH_X_START__SI__VI = 0x1A0B; +constexpr unsigned int mmGRPH_Y_END__SI__VI = 0x1A0E; +constexpr unsigned int mmGRPH_Y_START__SI__VI = 0x1A0C; +constexpr unsigned int mmHDMI_ACR_32_0__SI = 0x1C37; +constexpr unsigned int mmHDMI_ACR_32_1__SI = 0x1C38; +constexpr unsigned int mmHDMI_ACR_44_0__SI = 0x1C39; +constexpr unsigned int mmHDMI_ACR_44_1__SI = 0x1C3A; +constexpr unsigned int mmHDMI_ACR_48_0__SI = 0x1C3B; +constexpr unsigned int mmHDMI_ACR_48_1__SI = 0x1C3C; +constexpr unsigned int mmHDMI_ACR_PACKET_CONTROL__SI = 0x1C0F; +constexpr unsigned int mmHDMI_ACR_STATUS_0__SI = 0x1C3D; +constexpr unsigned int mmHDMI_ACR_STATUS_1__SI = 0x1C3E; +constexpr unsigned int mmHDMI_AUDIO_PACKET_CONTROL__SI = 0x1C0E; +constexpr unsigned int mmHDMI_CONTROL__SI = 0x1C0C; +constexpr unsigned int mmHDMI_GC__SI = 0x1C16; +constexpr unsigned int mmHDMI_GENERIC_PACKET_CONTROL__SI = 0x1C13; +constexpr unsigned int mmHDMI_INFOFRAME_CONTROL0__SI = 0x1C11; +constexpr unsigned int mmHDMI_INFOFRAME_CONTROL1__SI = 0x1C12; +constexpr unsigned int mmHDMI_STATUS__SI = 0x1C0D; +constexpr unsigned int mmHDMI_VBI_PACKET_CONTROL__SI = 0x1C10; +constexpr unsigned int mmHDP_DEBUG0 = 0x0BCC; +constexpr unsigned int mmHDP_DEBUG1 = 0x0BCD; +constexpr unsigned int mmHDP_HOST_PATH_CNTL = 0x0B00; +constexpr unsigned int mmHDP_LAST_SURFACE_HIT = 0x0BCE; +constexpr unsigned int mmHDP_MEM_COHERENCY_FLUSH_CNTL = 0x1520; +constexpr unsigned int mmHDP_NONSURFACE_BASE = 0x0B01; +constexpr unsigned int mmHDP_NONSURFACE_INFO = 0x0B02; +constexpr unsigned int mmHDP_NONSURFACE_SIZE = 0x0B03; +constexpr unsigned int mmHDP_NONSURF_FLAGS = 0x0BC9; +constexpr unsigned int mmHDP_NONSURF_FLAGS_CLR = 0x0BCA; +constexpr unsigned int mmHDP_OUTSTANDING_REQ = 0x0BD1; +constexpr unsigned int mmHDP_REG_COHERENCY_FLUSH_CNTL = 0x1528; +constexpr unsigned int mmHDP_SC_MULTI_CHIP_CNTL = 0x0BD0; +constexpr unsigned int mmHDP_SW_SEMAPHORE = 0x0BCB; +constexpr unsigned int mmHDP_TILING_CONFIG = 0x0BCF; +constexpr unsigned int mmHDP_XDP_BUSY_STS = 0x0C3E; +constexpr unsigned int mmHDP_XDP_CGTT_BLK_CTRL = 0x0C33; +constexpr unsigned int mmHDP_XDP_CHKN = 0x0C40; +constexpr unsigned int mmHDP_XDP_D2H_BAR_UPDATE = 0x0C02; +constexpr unsigned int mmHDP_XDP_D2H_FLUSH = 0x0C01; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_10 = 0x0C0A; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_11 = 0x0C0B; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_12 = 0x0C0C; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_13 = 0x0C0D; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_14 = 0x0C0E; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_15 = 0x0C0F; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_16 = 0x0C10; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_17 = 0x0C11; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_18 = 0x0C12; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_19 = 0x0C13; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_20 = 0x0C14; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_21 = 0x0C15; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_22 = 0x0C16; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_23 = 0x0C17; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_24 = 0x0C18; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_25 = 0x0C19; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_26 = 0x0C1A; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_27 = 0x0C1B; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_28 = 0x0C1C; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_29 = 0x0C1D; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_3 = 0x0C03; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_30 = 0x0C1E; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_31 = 0x0C1F; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_32 = 0x0C20; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_33 = 0x0C21; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_34 = 0x0C22; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_4 = 0x0C04; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_5 = 0x0C05; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_6 = 0x0C06; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_7 = 0x0C07; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_8 = 0x0C08; +constexpr unsigned int mmHDP_XDP_D2H_RSVD_9 = 0x0C09; +constexpr unsigned int mmHDP_XDP_DBG_ADDR = 0x0C41; +constexpr unsigned int mmHDP_XDP_DBG_DATA = 0x0C42; +constexpr unsigned int mmHDP_XDP_DBG_MASK = 0x0C43; +constexpr unsigned int mmHDP_XDP_DIRECT2HDP_FIRST = 0x0C00; +constexpr unsigned int mmHDP_XDP_DIRECT2HDP_LAST = 0x0C23; +constexpr unsigned int mmHDP_XDP_FLUSH_ARMED_STS = 0x0C3C; +constexpr unsigned int mmHDP_XDP_FLUSH_CNTR0_STS = 0x0C3D; +constexpr unsigned int mmHDP_XDP_HDP_IPH_CFG = 0x0C31; +constexpr unsigned int mmHDP_XDP_HDP_MBX_MC_CFG = 0x0C2D; +constexpr unsigned int mmHDP_XDP_HDP_MC_CFG = 0x0C2E; +constexpr unsigned int mmHDP_XDP_HST_CFG = 0x0C2F; +constexpr unsigned int mmHDP_XDP_P2P_BAR0 = 0x0C34; +constexpr unsigned int mmHDP_XDP_P2P_BAR1 = 0x0C35; +constexpr unsigned int mmHDP_XDP_P2P_BAR2 = 0x0C36; +constexpr unsigned int mmHDP_XDP_P2P_BAR3 = 0x0C37; +constexpr unsigned int mmHDP_XDP_P2P_BAR4 = 0x0C38; +constexpr unsigned int mmHDP_XDP_P2P_BAR5 = 0x0C39; +constexpr unsigned int mmHDP_XDP_P2P_BAR6 = 0x0C3A; +constexpr unsigned int mmHDP_XDP_P2P_BAR7 = 0x0C3B; +constexpr unsigned int mmHDP_XDP_P2P_BAR_CFG = 0x0C24; +constexpr unsigned int mmHDP_XDP_P2P_MBX_ADDR0 = 0x0C26; +constexpr unsigned int mmHDP_XDP_P2P_MBX_ADDR1 = 0x0C27; +constexpr unsigned int mmHDP_XDP_P2P_MBX_ADDR2 = 0x0C28; +constexpr unsigned int mmHDP_XDP_P2P_MBX_ADDR3 = 0x0C29; +constexpr unsigned int mmHDP_XDP_P2P_MBX_ADDR4 = 0x0C2A; +constexpr unsigned int mmHDP_XDP_P2P_MBX_ADDR5 = 0x0C2B; +constexpr unsigned int mmHDP_XDP_P2P_MBX_ADDR6 = 0x0C2C; +constexpr unsigned int mmHDP_XDP_P2P_MBX_OFFSET = 0x0C25; +constexpr unsigned int mmHDP_XDP_SID_CFG = 0x0C30; +constexpr unsigned int mmHDP_XDP_SRBM_CFG = 0x0C32; +constexpr unsigned int mmHDP_XDP_STICKY = 0x0C3F; +constexpr unsigned int mmHOST_BUSNUM = 0x153D; +constexpr unsigned int mmHW_DEBUG = 0x1515; +constexpr unsigned int mmIA_CNTL_STATUS = 0x2237; +constexpr unsigned int mmIA_DEBUG_CNTL = 0x223A; +constexpr unsigned int mmIA_DEBUG_DATA = 0x223B; +constexpr unsigned int mmIA_ENHANCE = 0xA29C; +constexpr unsigned int mmIA_MULTI_VGT_PARAM = 0xA2AA; +constexpr unsigned int mmIA_PERFCOUNTER0_HI__CI__VI = 0xD089; +constexpr unsigned int mmIA_PERFCOUNTER0_HI__SI = 0x2225; +constexpr unsigned int mmIA_PERFCOUNTER0_LO__CI__VI = 0xD088; +constexpr unsigned int mmIA_PERFCOUNTER0_LO__SI = 0x2224; +constexpr unsigned int mmIA_PERFCOUNTER0_SELECT1__CI__VI = 0xD888; +constexpr unsigned int mmIA_PERFCOUNTER0_SELECT__CI__VI = 0xD884; +constexpr unsigned int mmIA_PERFCOUNTER0_SELECT__SI = 0x2220; +constexpr unsigned int mmIA_PERFCOUNTER1_HI__CI__VI = 0xD08B; +constexpr unsigned int mmIA_PERFCOUNTER1_HI__SI = 0x2227; +constexpr unsigned int mmIA_PERFCOUNTER1_LO__CI__VI = 0xD08A; +constexpr unsigned int mmIA_PERFCOUNTER1_LO__SI = 0x2226; +constexpr unsigned int mmIA_PERFCOUNTER1_SELECT__CI__VI = 0xD885; +constexpr unsigned int mmIA_PERFCOUNTER1_SELECT__SI = 0x2221; +constexpr unsigned int mmIA_PERFCOUNTER2_HI__CI__VI = 0xD08D; +constexpr unsigned int mmIA_PERFCOUNTER2_HI__SI = 0x2229; +constexpr unsigned int mmIA_PERFCOUNTER2_LO__CI__VI = 0xD08C; +constexpr unsigned int mmIA_PERFCOUNTER2_LO__SI = 0x2228; +constexpr unsigned int mmIA_PERFCOUNTER2_SELECT__CI__VI = 0xD886; +constexpr unsigned int mmIA_PERFCOUNTER2_SELECT__SI = 0x2222; +constexpr unsigned int mmIA_PERFCOUNTER3_HI__CI__VI = 0xD08F; +constexpr unsigned int mmIA_PERFCOUNTER3_HI__SI = 0x222B; +constexpr unsigned int mmIA_PERFCOUNTER3_LO__CI__VI = 0xD08E; +constexpr unsigned int mmIA_PERFCOUNTER3_LO__SI = 0x222A; +constexpr unsigned int mmIA_PERFCOUNTER3_SELECT__CI__VI = 0xD887; +constexpr unsigned int mmIA_PERFCOUNTER3_SELECT__SI = 0x2223; +constexpr unsigned int mmIA_VMID_OVERRIDE__SI__CI = 0x2260; +constexpr unsigned int mmIH_ADVFAULT_CNTL__SI__CI = 0x0F8C; +constexpr unsigned int mmIH_PERFCOUNTER0_RESULT__CI = 0x0F8A; +constexpr unsigned int mmIH_PERFCOUNTER1_RESULT__CI = 0x0F8B; +constexpr unsigned int mmIH_PERFMON_CNTL__CI = 0x0F89; +constexpr unsigned int mmIH_VMID_0_LUT__CI = 0x0F50; +constexpr unsigned int mmIH_VMID_10_LUT__CI = 0x0F5A; +constexpr unsigned int mmIH_VMID_11_LUT__CI = 0x0F5B; +constexpr unsigned int mmIH_VMID_12_LUT__CI = 0x0F5C; +constexpr unsigned int mmIH_VMID_13_LUT__CI = 0x0F5D; +constexpr unsigned int mmIH_VMID_14_LUT__CI = 0x0F5E; +constexpr unsigned int mmIH_VMID_15_LUT__CI = 0x0F5F; +constexpr unsigned int mmIH_VMID_1_LUT__CI = 0x0F51; +constexpr unsigned int mmIH_VMID_2_LUT__CI = 0x0F52; +constexpr unsigned int mmIH_VMID_3_LUT__CI = 0x0F53; +constexpr unsigned int mmIH_VMID_4_LUT__CI = 0x0F54; +constexpr unsigned int mmIH_VMID_5_LUT__CI = 0x0F55; +constexpr unsigned int mmIH_VMID_6_LUT__CI = 0x0F56; +constexpr unsigned int mmIH_VMID_7_LUT__CI = 0x0F57; +constexpr unsigned int mmIH_VMID_8_LUT__CI = 0x0F58; +constexpr unsigned int mmIH_VMID_9_LUT__CI = 0x0F59; +constexpr unsigned int mmIMPCTL_RESET__CI__VI = 0x14F5; +constexpr unsigned int mmINTERRUPT_CNTL = 0x151A; +constexpr unsigned int mmINTERRUPT_CNTL2 = 0x151B; +constexpr unsigned int mmINT_MASK__SI = 0x1AD0; +constexpr unsigned int mmLB0_DC_MVP_LB_CONTROL__SI = 0x1ADB; +constexpr unsigned int mmLB0_LB_DEBUG__SI = 0x1AFC; +constexpr unsigned int mmLB0_LB_SYNC_RESET_SEL__SI = 0x1ACA; +constexpr unsigned int mmLB0_LB_TEST_DEBUG_DATA__SI__VI = 0x1AFF; +constexpr unsigned int mmLB0_LB_TEST_DEBUG_INDEX__SI__VI = 0x1AFE; +constexpr unsigned int mmLB0_MVP_AFR_FLIP_FIFO_CNTL__SI = 0x1AD9; +constexpr unsigned int mmLB0_MVP_AFR_FLIP_MODE__SI = 0x1AD8; +constexpr unsigned int mmLB0_MVP_FLIP_LINE_NUM_INSERT__SI = 0x1ADA; +constexpr unsigned int mmLB1_DC_MVP_LB_CONTROL__SI = 0x1DDB; +constexpr unsigned int mmLB1_LB_DEBUG__SI = 0x1DFC; +constexpr unsigned int mmLB1_LB_SYNC_RESET_SEL__SI = 0x1DCA; +constexpr unsigned int mmLB1_LB_TEST_DEBUG_DATA__SI = 0x1DFF; +constexpr unsigned int mmLB1_LB_TEST_DEBUG_INDEX__SI = 0x1DFE; +constexpr unsigned int mmLB1_MVP_AFR_FLIP_FIFO_CNTL__SI = 0x1DD9; +constexpr unsigned int mmLB1_MVP_AFR_FLIP_MODE__SI = 0x1DD8; +constexpr unsigned int mmLB1_MVP_FLIP_LINE_NUM_INSERT__SI = 0x1DDA; +constexpr unsigned int mmLB2_DC_MVP_LB_CONTROL__SI = 0x40DB; +constexpr unsigned int mmLB2_LB_DEBUG__SI = 0x40FC; +constexpr unsigned int mmLB2_LB_SYNC_RESET_SEL__SI = 0x40CA; +constexpr unsigned int mmLB2_LB_TEST_DEBUG_DATA__SI = 0x40FF; +constexpr unsigned int mmLB2_LB_TEST_DEBUG_INDEX__SI = 0x40FE; +constexpr unsigned int mmLB2_MVP_AFR_FLIP_FIFO_CNTL__SI = 0x40D9; +constexpr unsigned int mmLB2_MVP_AFR_FLIP_MODE__SI = 0x40D8; +constexpr unsigned int mmLB2_MVP_FLIP_LINE_NUM_INSERT__SI = 0x40DA; +constexpr unsigned int mmLB3_DC_MVP_LB_CONTROL__SI = 0x43DB; +constexpr unsigned int mmLB3_LB_DEBUG__SI = 0x43FC; +constexpr unsigned int mmLB3_LB_SYNC_RESET_SEL__SI = 0x43CA; +constexpr unsigned int mmLB3_LB_TEST_DEBUG_DATA__SI = 0x43FF; +constexpr unsigned int mmLB3_LB_TEST_DEBUG_INDEX__SI = 0x43FE; +constexpr unsigned int mmLB3_MVP_AFR_FLIP_FIFO_CNTL__SI = 0x43D9; +constexpr unsigned int mmLB3_MVP_AFR_FLIP_MODE__SI = 0x43D8; +constexpr unsigned int mmLB3_MVP_FLIP_LINE_NUM_INSERT__SI = 0x43DA; +constexpr unsigned int mmLB4_DC_MVP_LB_CONTROL__SI = 0x46DB; +constexpr unsigned int mmLB4_LB_DEBUG__SI = 0x46FC; +constexpr unsigned int mmLB4_LB_SYNC_RESET_SEL__SI = 0x46CA; +constexpr unsigned int mmLB4_LB_TEST_DEBUG_DATA__SI = 0x46FF; +constexpr unsigned int mmLB4_LB_TEST_DEBUG_INDEX__SI = 0x46FE; +constexpr unsigned int mmLB4_MVP_AFR_FLIP_FIFO_CNTL__SI = 0x46D9; +constexpr unsigned int mmLB4_MVP_AFR_FLIP_MODE__SI = 0x46D8; +constexpr unsigned int mmLB4_MVP_FLIP_LINE_NUM_INSERT__SI = 0x46DA; +constexpr unsigned int mmLB5_DC_MVP_LB_CONTROL__SI = 0x49DB; +constexpr unsigned int mmLB5_LB_DEBUG__SI = 0x49FC; +constexpr unsigned int mmLB5_LB_SYNC_RESET_SEL__SI = 0x49CA; +constexpr unsigned int mmLB5_LB_TEST_DEBUG_DATA__SI = 0x49FF; +constexpr unsigned int mmLB5_LB_TEST_DEBUG_INDEX__SI = 0x49FE; +constexpr unsigned int mmLB5_MVP_AFR_FLIP_FIFO_CNTL__SI = 0x49D9; +constexpr unsigned int mmLB5_MVP_AFR_FLIP_MODE__SI = 0x49D8; +constexpr unsigned int mmLB5_MVP_FLIP_LINE_NUM_INSERT__SI = 0x49DA; +constexpr unsigned int mmLB_DEBUG__SI = 0x1AFC; +constexpr unsigned int mmLB_SYNC_RESET_SEL__SI = 0x1ACA; +constexpr unsigned int mmLB_TEST_DEBUG_DATA__SI__VI = 0x1AFF; +constexpr unsigned int mmLB_TEST_DEBUG_INDEX__SI__VI = 0x1AFE; +constexpr unsigned int mmLNCNT_CONTROL__CI = 0x1487; +constexpr unsigned int mmLVDS_DATA_CNTL__SI = 0x1C8C; +constexpr unsigned int mmLVTMA_PWRSEQ_CNTL__SI = 0x1962; +constexpr unsigned int mmLVTMA_PWRSEQ_DELAY1__SI = 0x1965; +constexpr unsigned int mmLVTMA_PWRSEQ_DELAY2__SI = 0x1966; +constexpr unsigned int mmLVTMA_PWRSEQ_REF_DIV__SI = 0x1964; +constexpr unsigned int mmLVTMA_PWRSEQ_STATE__SI = 0x1963; +constexpr unsigned int mmMASTER_COMM_CMD_REG__SI__VI = 0x161F; +constexpr unsigned int mmMASTER_COMM_CNTL_REG__SI__VI = 0x1620; +constexpr unsigned int mmMASTER_COMM_DATA_REG1__SI__VI = 0x161C; +constexpr unsigned int mmMASTER_COMM_DATA_REG2__SI__VI = 0x161D; +constexpr unsigned int mmMASTER_COMM_DATA_REG3__SI__VI = 0x161E; +constexpr unsigned int mmMASTER_CREDIT_CNTL = 0x1516; +constexpr unsigned int mmMASTER_UPDATE_LOCK__SI__VI = 0x1BBD; +constexpr unsigned int mmMASTER_UPDATE_MODE__SI__VI = 0x1BBE; +constexpr unsigned int mmMCIF_CONTROL__SI = 0x0314; +constexpr unsigned int mmMCIF_TEST_DEBUG_DATA__SI = 0x0317; +constexpr unsigned int mmMCIF_TEST_DEBUG_INDEX__SI = 0x0316; +constexpr unsigned int mmMCIF_WRITE_COMBINE_CONTROL__SI = 0x0315; +constexpr unsigned int mmMCLK_PWRMGT_CNTL__SI__CI = 0x0AE8; +constexpr unsigned int mmMC_ARB_ADDR_HASH = 0x09DC; +constexpr unsigned int mmMC_ARB_ADDR_SWIZ0__CI__VI = 0x09CB; +constexpr unsigned int mmMC_ARB_ADDR_SWIZ1__CI__VI = 0x09CC; +constexpr unsigned int mmMC_ARB_AGE_CNTL__CI__VI = 0x09BF; +constexpr unsigned int mmMC_ARB_AGE_RD = 0x09E9; +constexpr unsigned int mmMC_ARB_AGE_WR = 0x09EA; +constexpr unsigned int mmMC_ARB_BANKMAP = 0x09D7; +constexpr unsigned int mmMC_ARB_BURST_TIME = 0x0A02; +constexpr unsigned int mmMC_ARB_BUSY_STATUS__CI__VI = 0x09FD; +constexpr unsigned int mmMC_ARB_CAC_CNTL = 0x09D4; +constexpr unsigned int mmMC_ARB_CG = 0x09FA; +constexpr unsigned int mmMC_ARB_DRAM_TIMING = 0x09DD; +constexpr unsigned int mmMC_ARB_DRAM_TIMING2 = 0x09DE; +constexpr unsigned int mmMC_ARB_DRAM_TIMING2_1 = 0x09FF; +constexpr unsigned int mmMC_ARB_DRAM_TIMING_1 = 0x09FC; +constexpr unsigned int mmMC_ARB_FED_CNTL = 0x09C1; +constexpr unsigned int mmMC_ARB_GDEC_RD_CNTL = 0x09EE; +constexpr unsigned int mmMC_ARB_GDEC_WR_CNTL = 0x09EF; +constexpr unsigned int mmMC_ARB_GECC2 = 0x09C9; +constexpr unsigned int mmMC_ARB_GECC2_CLI = 0x09CA; +constexpr unsigned int mmMC_ARB_GECC2_DEBUG = 0x09C4; +constexpr unsigned int mmMC_ARB_GECC2_DEBUG2 = 0x09C5; +constexpr unsigned int mmMC_ARB_GECC2_MISC = 0x09C3; +constexpr unsigned int mmMC_ARB_GECC2_STATUS = 0x09C2; +constexpr unsigned int mmMC_ARB_HARSH_BWCNT0_RD__CI__VI = 0x0DCE; +constexpr unsigned int mmMC_ARB_HARSH_BWCNT0_WR__CI__VI = 0x0DCF; +constexpr unsigned int mmMC_ARB_HARSH_BWCNT1_RD__CI__VI = 0x0DD0; +constexpr unsigned int mmMC_ARB_HARSH_BWCNT1_WR__CI__VI = 0x0DD1; +constexpr unsigned int mmMC_ARB_HARSH_BWPERIOD0_RD__CI__VI = 0x0DCA; +constexpr unsigned int mmMC_ARB_HARSH_BWPERIOD0_WR__CI__VI = 0x0DCB; +constexpr unsigned int mmMC_ARB_HARSH_BWPERIOD1_RD__CI__VI = 0x0DCC; +constexpr unsigned int mmMC_ARB_HARSH_BWPERIOD1_WR__CI__VI = 0x0DCD; +constexpr unsigned int mmMC_ARB_HARSH_CTL_RD__CI__VI = 0x0DD6; +constexpr unsigned int mmMC_ARB_HARSH_CTL_WR__CI__VI = 0x0DD7; +constexpr unsigned int mmMC_ARB_HARSH_EN_RD__CI__VI = 0x0DC0; +constexpr unsigned int mmMC_ARB_HARSH_EN_WR__CI__VI = 0x0DC1; +constexpr unsigned int mmMC_ARB_HARSH_SAT0_RD__CI__VI = 0x0DD2; +constexpr unsigned int mmMC_ARB_HARSH_SAT0_WR__CI__VI = 0x0DD3; +constexpr unsigned int mmMC_ARB_HARSH_SAT1_RD__CI__VI = 0x0DD4; +constexpr unsigned int mmMC_ARB_HARSH_SAT1_WR__CI__VI = 0x0DD5; +constexpr unsigned int mmMC_ARB_HARSH_TX_HI0_RD__CI__VI = 0x0DC2; +constexpr unsigned int mmMC_ARB_HARSH_TX_HI0_WR__CI__VI = 0x0DC3; +constexpr unsigned int mmMC_ARB_HARSH_TX_HI1_RD__CI__VI = 0x0DC4; +constexpr unsigned int mmMC_ARB_HARSH_TX_HI1_WR__CI__VI = 0x0DC5; +constexpr unsigned int mmMC_ARB_HARSH_TX_LO0_RD__CI__VI = 0x0DC6; +constexpr unsigned int mmMC_ARB_HARSH_TX_LO0_WR__CI__VI = 0x0DC7; +constexpr unsigned int mmMC_ARB_HARSH_TX_LO1_RD__CI__VI = 0x0DC8; +constexpr unsigned int mmMC_ARB_HARSH_TX_LO1_WR__CI__VI = 0x0DC9; +constexpr unsigned int mmMC_ARB_LAZY0_RD = 0x09E5; +constexpr unsigned int mmMC_ARB_LAZY0_WR = 0x09E6; +constexpr unsigned int mmMC_ARB_LAZY1_RD = 0x09E7; +constexpr unsigned int mmMC_ARB_LAZY1_WR = 0x09E8; +constexpr unsigned int mmMC_ARB_LM_RD = 0x09F0; +constexpr unsigned int mmMC_ARB_LM_WR = 0x09F1; +constexpr unsigned int mmMC_ARB_MAX_LAT_CID__CI__VI = 0x09F6; +constexpr unsigned int mmMC_ARB_MAX_LAT_RSLT0__CI__VI = 0x09F7; +constexpr unsigned int mmMC_ARB_MAX_LAT_RSLT1__CI__VI = 0x09F8; +constexpr unsigned int mmMC_ARB_MINCLKS = 0x09DA; +constexpr unsigned int mmMC_ARB_MISC = 0x09D6; +constexpr unsigned int mmMC_ARB_MISC2 = 0x09D5; +constexpr unsigned int mmMC_ARB_MISC3__CI__VI = 0x09CD; +constexpr unsigned int mmMC_ARB_PERFCOUNTER0_CFG__CI__VI = 0x07BC; +constexpr unsigned int mmMC_ARB_PERFCOUNTER1_CFG__CI__VI = 0x07BD; +constexpr unsigned int mmMC_ARB_PERFCOUNTER2_CFG__CI__VI = 0x07BE; +constexpr unsigned int mmMC_ARB_PERFCOUNTER3_CFG__CI__VI = 0x07BF; +constexpr unsigned int mmMC_ARB_PERFCOUNTER_HI__CI__VI = 0x07AE; +constexpr unsigned int mmMC_ARB_PERFCOUNTER_LO__CI__VI = 0x07A6; +constexpr unsigned int mmMC_ARB_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07D4; +constexpr unsigned int mmMC_ARB_PERF_MON_CNTL0_ECC__CI = 0x07DB; +constexpr unsigned int mmMC_ARB_PERF_MON_CNTL0__SI = 0x09F6; +constexpr unsigned int mmMC_ARB_PM_CNTL = 0x09ED; +constexpr unsigned int mmMC_ARB_POP = 0x09D9; +constexpr unsigned int mmMC_ARB_RAMCFG = 0x09D8; +constexpr unsigned int mmMC_ARB_REMREQ = 0x09F2; +constexpr unsigned int mmMC_ARB_REPLAY = 0x09F3; +constexpr unsigned int mmMC_ARB_RET_CREDITS2__CI__VI = 0x09C0; +constexpr unsigned int mmMC_ARB_RET_CREDITS_RD = 0x09F4; +constexpr unsigned int mmMC_ARB_RET_CREDITS_WR = 0x09F5; +constexpr unsigned int mmMC_ARB_RFSH_CNTL = 0x09EB; +constexpr unsigned int mmMC_ARB_RFSH_RATE = 0x09EC; +constexpr unsigned int mmMC_ARB_RTT_CNTL0 = 0x09D0; +constexpr unsigned int mmMC_ARB_RTT_CNTL1 = 0x09D1; +constexpr unsigned int mmMC_ARB_RTT_CNTL2 = 0x09D2; +constexpr unsigned int mmMC_ARB_RTT_DATA = 0x09CF; +constexpr unsigned int mmMC_ARB_RTT_DEBUG = 0x09D3; +constexpr unsigned int mmMC_ARB_SQM_CNTL = 0x09DB; +constexpr unsigned int mmMC_ARB_SSM__CI = 0x09F9; +constexpr unsigned int mmMC_ARB_TM_CNTL_RD = 0x09E3; +constexpr unsigned int mmMC_ARB_TM_CNTL_WR = 0x09E4; +constexpr unsigned int mmMC_ARB_WCDR__SI__CI = 0x09FB; +constexpr unsigned int mmMC_ARB_WCDR_2__SI__CI = 0x09CE; +constexpr unsigned int mmMC_ARB_WTM_CNTL_RD = 0x09DF; +constexpr unsigned int mmMC_ARB_WTM_CNTL_WR = 0x09E0; +constexpr unsigned int mmMC_ARB_WTM_GRPWT_RD = 0x09E1; +constexpr unsigned int mmMC_ARB_WTM_GRPWT_WR = 0x09E2; +constexpr unsigned int mmMC_BIST_AUTO_CNTL__SI__CI = 0x0A06; +constexpr unsigned int mmMC_BIST_CMD_CNTL__SI__CI = 0x0A8E; +constexpr unsigned int mmMC_BIST_CMP_CNTL__SI__CI = 0x0A8D; +constexpr unsigned int mmMC_BIST_CMP_CNTL_2__SI__CI = 0x0AB6; +constexpr unsigned int mmMC_BIST_DATA_MASK__SI__CI = 0x0A12; +constexpr unsigned int mmMC_BIST_DIR_CNTL__SI__CI = 0x0A07; +constexpr unsigned int mmMC_BIST_EADDR__SI__CI = 0x0A09; +constexpr unsigned int mmMC_BIST_RDATA_EDC__SI__CI = 0x0A1D; +constexpr unsigned int mmMC_BIST_RDATA_MASK__SI__CI = 0x0A1C; +constexpr unsigned int mmMC_BIST_SADDR__SI__CI = 0x0A08; +constexpr unsigned int mmMC_CG_CONFIG = 0x096F; +constexpr unsigned int mmMC_CG_CONFIG_MCD = 0x0829; +constexpr unsigned int mmMC_CITF_CNTL = 0x0970; +constexpr unsigned int mmMC_CITF_CREDITS_ARB_RD = 0x0972; +constexpr unsigned int mmMC_CITF_CREDITS_ARB_WR = 0x0973; +constexpr unsigned int mmMC_CITF_CREDITS_VM = 0x0971; +constexpr unsigned int mmMC_CITF_CREDITS_XBAR = 0x0989; +constexpr unsigned int mmMC_CITF_DAGB_CNTL = 0x0974; +constexpr unsigned int mmMC_CITF_DAGB_DLY = 0x0977; +constexpr unsigned int mmMC_CITF_INT_CREDITS = 0x0975; +constexpr unsigned int mmMC_CITF_INT_CREDITS_WR__CI__VI = 0x097D; +constexpr unsigned int mmMC_CITF_MISC_RD_CG = 0x0992; +constexpr unsigned int mmMC_CITF_MISC_VM_CG = 0x0994; +constexpr unsigned int mmMC_CITF_MISC_WR_CG = 0x0993; +constexpr unsigned int mmMC_CITF_PERFCOUNTER0_CFG__CI__VI = 0x07B0; +constexpr unsigned int mmMC_CITF_PERFCOUNTER1_CFG__CI__VI = 0x07B1; +constexpr unsigned int mmMC_CITF_PERFCOUNTER2_CFG__CI__VI = 0x07B2; +constexpr unsigned int mmMC_CITF_PERFCOUNTER3_CFG__CI__VI = 0x07B3; +constexpr unsigned int mmMC_CITF_PERFCOUNTER_HI__CI__VI = 0x07A8; +constexpr unsigned int mmMC_CITF_PERFCOUNTER_LO__CI__VI = 0x07A0; +constexpr unsigned int mmMC_CITF_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07CE; +constexpr unsigned int mmMC_CITF_PERF_MON_CNTL2 = 0x098E; +constexpr unsigned int mmMC_CITF_PERF_MON_RSLT2 = 0x0991; +constexpr unsigned int mmMC_CITF_REMREQ = 0x097A; +constexpr unsigned int mmMC_CITF_RET_MODE = 0x0976; +constexpr unsigned int mmMC_CITF_WTM_RD_CNTL = 0x097F; +constexpr unsigned int mmMC_CITF_WTM_WR_CNTL = 0x0980; +constexpr unsigned int mmMC_CITF_XTRA_ENABLE = 0x096D; +constexpr unsigned int mmMC_CONFIG = 0x0800; +constexpr unsigned int mmMC_CONFIG_MCD = 0x0828; +constexpr unsigned int mmMC_DC_INTERFACE_NACK_STATUS__SI = 0x031C; +constexpr unsigned int mmMC_DLB_CONFIG0__CI = 0x0D93; +constexpr unsigned int mmMC_DLB_CONFIG1__CI = 0x0D94; +constexpr unsigned int mmMC_DLB_MISCCTRL0__CI = 0x0D90; +constexpr unsigned int mmMC_DLB_MISCCTRL1__CI = 0x0D91; +constexpr unsigned int mmMC_DLB_MISCCTRL2__CI = 0x0D92; +constexpr unsigned int mmMC_DLB_SETUPFIFO__CI = 0x0D97; +constexpr unsigned int mmMC_DLB_SETUPSWEEP__CI = 0x0D96; +constexpr unsigned int mmMC_DLB_SETUP__CI = 0x0D95; +constexpr unsigned int mmMC_DLB_STATUS_MISC0__CI = 0x0D9A; +constexpr unsigned int mmMC_DLB_STATUS_MISC1__CI = 0x0D9B; +constexpr unsigned int mmMC_DLB_STATUS_MISC2__CI = 0x0D9C; +constexpr unsigned int mmMC_DLB_STATUS_MISC3__CI = 0x0D9D; +constexpr unsigned int mmMC_DLB_STATUS_MISC4__CI = 0x0D9E; +constexpr unsigned int mmMC_DLB_STATUS_MISC5__CI = 0x0D9F; +constexpr unsigned int mmMC_DLB_STATUS_MISC6__CI = 0x0DA0; +constexpr unsigned int mmMC_DLB_STATUS_MISC7__CI = 0x0DA1; +constexpr unsigned int mmMC_DLB_STATUS__CI = 0x0D99; +constexpr unsigned int mmMC_DLB_WRITE_MASK__CI = 0x0D98; +constexpr unsigned int mmMC_HUB_MISC_DBG__SI__CI = 0x0831; +constexpr unsigned int mmMC_HUB_MISC_FRAMING = 0x0834; +constexpr unsigned int mmMC_HUB_MISC_HUB_CG = 0x082E; +constexpr unsigned int mmMC_HUB_MISC_IDLE_STATUS = 0x0847; +constexpr unsigned int mmMC_HUB_MISC_OVERRIDE = 0x0833; +constexpr unsigned int mmMC_HUB_MISC_POWER = 0x082D; +constexpr unsigned int mmMC_HUB_MISC_SIP_CG = 0x0830; +constexpr unsigned int mmMC_HUB_MISC_STATUS = 0x0832; +constexpr unsigned int mmMC_HUB_MISC_VM_CG = 0x082F; +constexpr unsigned int mmMC_HUB_PERFCOUNTER0_CFG__CI__VI = 0x07B4; +constexpr unsigned int mmMC_HUB_PERFCOUNTER1_CFG__CI__VI = 0x07B5; +constexpr unsigned int mmMC_HUB_PERFCOUNTER2_CFG__CI__VI = 0x07B6; +constexpr unsigned int mmMC_HUB_PERFCOUNTER3_CFG__CI__VI = 0x07B7; +constexpr unsigned int mmMC_HUB_PERFCOUNTER_HI__CI__VI = 0x07A9; +constexpr unsigned int mmMC_HUB_PERFCOUNTER_LO__CI__VI = 0x07A1; +constexpr unsigned int mmMC_HUB_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07CF; +constexpr unsigned int mmMC_HUB_RDREQ_ACPG_LIMIT__CI__VI = 0x0849; +constexpr unsigned int mmMC_HUB_RDREQ_ACPG__CI = 0x0887; +constexpr unsigned int mmMC_HUB_RDREQ_ACPO__CI = 0x0888; +constexpr unsigned int mmMC_HUB_RDREQ_CNTL = 0x083B; +constexpr unsigned int mmMC_HUB_RDREQ_CPC__CI = 0x085A; +constexpr unsigned int mmMC_HUB_RDREQ_CPF__CI = 0x085B; +constexpr unsigned int mmMC_HUB_RDREQ_CPG__CI = 0x0859; +constexpr unsigned int mmMC_HUB_RDREQ_CP__SI = 0x0859; +constexpr unsigned int mmMC_HUB_RDREQ_CREDITS = 0x0844; +constexpr unsigned int mmMC_HUB_RDREQ_CREDITS2 = 0x0845; +constexpr unsigned int mmMC_HUB_RDREQ_DMIF_LIMIT = 0x0848; +constexpr unsigned int mmMC_HUB_RDREQ_DMIF__CI = 0x0865; +constexpr unsigned int mmMC_HUB_RDREQ_DMIF__SI = 0x0863; +constexpr unsigned int mmMC_HUB_RDREQ_GBL0 = 0x0856; +constexpr unsigned int mmMC_HUB_RDREQ_GBL1 = 0x0857; +constexpr unsigned int mmMC_HUB_RDREQ_HDP__CI = 0x085E; +constexpr unsigned int mmMC_HUB_RDREQ_HDP__SI = 0x085B; +constexpr unsigned int mmMC_HUB_RDREQ_IA0__CI = 0x084F; +constexpr unsigned int mmMC_HUB_RDREQ_IA1__CI = 0x0850; +constexpr unsigned int mmMC_HUB_RDREQ_IA__CI = 0x0864; +constexpr unsigned int mmMC_HUB_RDREQ_MCDW = 0x0851; +constexpr unsigned int mmMC_HUB_RDREQ_MCDX = 0x0852; +constexpr unsigned int mmMC_HUB_RDREQ_MCDY = 0x0853; +constexpr unsigned int mmMC_HUB_RDREQ_MCDZ = 0x0854; +constexpr unsigned int mmMC_HUB_RDREQ_MCIF__CI = 0x0866; +constexpr unsigned int mmMC_HUB_RDREQ_MCIF__SI = 0x0864; +constexpr unsigned int mmMC_HUB_RDREQ_RLC__CI = 0x085F; +constexpr unsigned int mmMC_HUB_RDREQ_RLC__SI = 0x085D; +constexpr unsigned int mmMC_HUB_RDREQ_SAM__CI = 0x0889; +constexpr unsigned int mmMC_HUB_RDREQ_SDMA0__CI = 0x085C; +constexpr unsigned int mmMC_HUB_RDREQ_SDMA1__CI = 0x085D; +constexpr unsigned int mmMC_HUB_RDREQ_SEM__CI = 0x0860; +constexpr unsigned int mmMC_HUB_RDREQ_SEM__SI = 0x085E; +constexpr unsigned int mmMC_HUB_RDREQ_SIP = 0x0855; +constexpr unsigned int mmMC_HUB_RDREQ_SMU = 0x0858; +constexpr unsigned int mmMC_HUB_RDREQ_STATUS = 0x0839; +constexpr unsigned int mmMC_HUB_RDREQ_UMC__CI = 0x0862; +constexpr unsigned int mmMC_HUB_RDREQ_UMC__SI = 0x0860; +constexpr unsigned int mmMC_HUB_RDREQ_UVD__CI = 0x0863; +constexpr unsigned int mmMC_HUB_RDREQ_UVD__SI = 0x0861; +constexpr unsigned int mmMC_HUB_RDREQ_VCEU__CI = 0x0868; +constexpr unsigned int mmMC_HUB_RDREQ_VCEU__SI = 0x0866; +constexpr unsigned int mmMC_HUB_RDREQ_VCE__CI = 0x0861; +constexpr unsigned int mmMC_HUB_RDREQ_VCE__SI = 0x085F; +constexpr unsigned int mmMC_HUB_RDREQ_VMC__CI = 0x0867; +constexpr unsigned int mmMC_HUB_RDREQ_VMC__SI = 0x0865; +constexpr unsigned int mmMC_HUB_RDREQ_WTM_CNTL = 0x083D; +constexpr unsigned int mmMC_HUB_RDREQ_XDMAM__CI = 0x0886; +constexpr unsigned int mmMC_HUB_RDREQ_XDMAM__SI = 0x0882; +constexpr unsigned int mmMC_HUB_SHARED_DAGB_DLY = 0x0846; +constexpr unsigned int mmMC_HUB_WDP_ACPG__CI = 0x088A; +constexpr unsigned int mmMC_HUB_WDP_ACPO__CI = 0x088B; +constexpr unsigned int mmMC_HUB_WDP_BP = 0x0837; +constexpr unsigned int mmMC_HUB_WDP_CNTL = 0x0835; +constexpr unsigned int mmMC_HUB_WDP_CPC__CI = 0x086F; +constexpr unsigned int mmMC_HUB_WDP_CPF__CI = 0x0870; +constexpr unsigned int mmMC_HUB_WDP_CPG__CI = 0x086E; +constexpr unsigned int mmMC_HUB_WDP_CP__SI = 0x086C; +constexpr unsigned int mmMC_HUB_WDP_CREDITS = 0x083F; +constexpr unsigned int mmMC_HUB_WDP_ERR = 0x0836; +constexpr unsigned int mmMC_HUB_WDP_GBL0 = 0x0841; +constexpr unsigned int mmMC_HUB_WDP_GBL1 = 0x0842; +constexpr unsigned int mmMC_HUB_WDP_HDP__CI = 0x087C; +constexpr unsigned int mmMC_HUB_WDP_HDP__SI = 0x0879; +constexpr unsigned int mmMC_HUB_WDP_IH__CI = 0x0875; +constexpr unsigned int mmMC_HUB_WDP_IH__SI = 0x0872; +constexpr unsigned int mmMC_HUB_WDP_MCDW__CI = 0x0869; +constexpr unsigned int mmMC_HUB_WDP_MCDW__SI = 0x0867; +constexpr unsigned int mmMC_HUB_WDP_MCDX__CI = 0x086A; +constexpr unsigned int mmMC_HUB_WDP_MCDX__SI = 0x0868; +constexpr unsigned int mmMC_HUB_WDP_MCDY__CI = 0x086B; +constexpr unsigned int mmMC_HUB_WDP_MCDY__SI = 0x0869; +constexpr unsigned int mmMC_HUB_WDP_MCDZ__CI = 0x086C; +constexpr unsigned int mmMC_HUB_WDP_MCDZ__SI = 0x086A; +constexpr unsigned int mmMC_HUB_WDP_MCIF__CI = 0x0872; +constexpr unsigned int mmMC_HUB_WDP_MCIF__SI = 0x086F; +constexpr unsigned int mmMC_HUB_WDP_MGPU__SI__CI = 0x0843; +constexpr unsigned int mmMC_HUB_WDP_MGPU2__SI__CI = 0x0840; +constexpr unsigned int mmMC_HUB_WDP_RLC__CI = 0x0876; +constexpr unsigned int mmMC_HUB_WDP_RLC__SI = 0x0873; +constexpr unsigned int mmMC_HUB_WDP_SAM__CI = 0x088C; +constexpr unsigned int mmMC_HUB_WDP_SDMA0__CI = 0x087D; +constexpr unsigned int mmMC_HUB_WDP_SDMA1__CI = 0x087E; +constexpr unsigned int mmMC_HUB_WDP_SEM__CI = 0x0877; +constexpr unsigned int mmMC_HUB_WDP_SEM__SI = 0x0874; +constexpr unsigned int mmMC_HUB_WDP_SH0__CI = 0x0871; +constexpr unsigned int mmMC_HUB_WDP_SH0__SI = 0x086E; +constexpr unsigned int mmMC_HUB_WDP_SH1__CI = 0x0879; +constexpr unsigned int mmMC_HUB_WDP_SH1__SI = 0x0876; +constexpr unsigned int mmMC_HUB_WDP_SH2__CI__VI = 0x084D; +constexpr unsigned int mmMC_HUB_WDP_SH3__CI__VI = 0x084E; +constexpr unsigned int mmMC_HUB_WDP_SIP__CI = 0x086D; +constexpr unsigned int mmMC_HUB_WDP_SIP__SI = 0x086B; +constexpr unsigned int mmMC_HUB_WDP_SMU__CI = 0x0878; +constexpr unsigned int mmMC_HUB_WDP_SMU__SI = 0x0875; +constexpr unsigned int mmMC_HUB_WDP_STATUS = 0x0838; +constexpr unsigned int mmMC_HUB_WDP_UMC__CI = 0x087A; +constexpr unsigned int mmMC_HUB_WDP_UMC__SI = 0x0877; +constexpr unsigned int mmMC_HUB_WDP_UVD__CI = 0x087B; +constexpr unsigned int mmMC_HUB_WDP_UVD__SI = 0x0878; +constexpr unsigned int mmMC_HUB_WDP_VCEU__CI = 0x0883; +constexpr unsigned int mmMC_HUB_WDP_VCEU__SI = 0x087F; +constexpr unsigned int mmMC_HUB_WDP_VCE__CI = 0x0873; +constexpr unsigned int mmMC_HUB_WDP_VCE__SI = 0x0870; +constexpr unsigned int mmMC_HUB_WDP_WTM_CNTL = 0x083E; +constexpr unsigned int mmMC_HUB_WDP_XDMAM__CI = 0x0884; +constexpr unsigned int mmMC_HUB_WDP_XDMAM__SI = 0x0880; +constexpr unsigned int mmMC_HUB_WDP_XDMA__CI = 0x0885; +constexpr unsigned int mmMC_HUB_WDP_XDMA__SI = 0x0881; +constexpr unsigned int mmMC_HUB_WDP_XDP__CI = 0x0874; +constexpr unsigned int mmMC_HUB_WDP_XDP__SI = 0x0871; +constexpr unsigned int mmMC_HUB_WRRET_CNTL = 0x083C; +constexpr unsigned int mmMC_HUB_WRRET_MCDW__CI = 0x087F; +constexpr unsigned int mmMC_HUB_WRRET_MCDW__SI = 0x087B; +constexpr unsigned int mmMC_HUB_WRRET_MCDX__CI = 0x0880; +constexpr unsigned int mmMC_HUB_WRRET_MCDX__SI = 0x087C; +constexpr unsigned int mmMC_HUB_WRRET_MCDY__CI = 0x0881; +constexpr unsigned int mmMC_HUB_WRRET_MCDY__SI = 0x087D; +constexpr unsigned int mmMC_HUB_WRRET_MCDZ__CI = 0x0882; +constexpr unsigned int mmMC_HUB_WRRET_MCDZ__SI = 0x087E; +constexpr unsigned int mmMC_HUB_WRRET_STATUS = 0x083A; +constexpr unsigned int mmMC_IMP_CNTL__SI__CI = 0x0A36; +constexpr unsigned int mmMC_IMP_DEBUG__SI__CI = 0x0A37; +constexpr unsigned int mmMC_IMP_DQ_STATUS__SI__CI = 0x0ABC; +constexpr unsigned int mmMC_IMP_STATUS__SI__CI = 0x0A38; +constexpr unsigned int mmMC_IO_APHY_STR_CNTL_D0__SI__CI = 0x0A97; +constexpr unsigned int mmMC_IO_APHY_STR_CNTL_D1__SI__CI = 0x0A98; +constexpr unsigned int mmMC_IO_CDRCNTL1_D0__SI__CI = 0x0ADD; +constexpr unsigned int mmMC_IO_CDRCNTL1_D1__SI__CI = 0x0ADE; +constexpr unsigned int mmMC_IO_CDRCNTL2_D0__SI__CI = 0x0AE4; +constexpr unsigned int mmMC_IO_CDRCNTL2_D1__SI__CI = 0x0AE5; +constexpr unsigned int mmMC_IO_CDRCNTL_D0__SI__CI = 0x0A55; +constexpr unsigned int mmMC_IO_CDRCNTL_D1__SI__CI = 0x0A56; +constexpr unsigned int mmMC_IO_DPHY_STR_CNTL_D0__SI__CI = 0x0A4E; +constexpr unsigned int mmMC_IO_DPHY_STR_CNTL_D1__SI__CI = 0x0A54; +constexpr unsigned int mmMC_IO_PAD_CNTL__SI__CI = 0x0A73; +constexpr unsigned int mmMC_IO_PAD_CNTL_D0__SI__CI = 0x0A74; +constexpr unsigned int mmMC_IO_PAD_CNTL_D1__SI__CI = 0x0A75; +constexpr unsigned int mmMC_IO_RXCNTL1_DPHY0_D0__SI__CI = 0x0ADF; +constexpr unsigned int mmMC_IO_RXCNTL1_DPHY0_D1__SI__CI = 0x0AE1; +constexpr unsigned int mmMC_IO_RXCNTL1_DPHY1_D0__SI__CI = 0x0AE0; +constexpr unsigned int mmMC_IO_RXCNTL1_DPHY1_D1__SI__CI = 0x0AE2; +constexpr unsigned int mmMC_IO_RXCNTL_DPHY0_D0__SI__CI = 0x0A4C; +constexpr unsigned int mmMC_IO_RXCNTL_DPHY0_D1__SI__CI = 0x0A52; +constexpr unsigned int mmMC_IO_RXCNTL_DPHY1_D0__SI__CI = 0x0A4D; +constexpr unsigned int mmMC_IO_RXCNTL_DPHY1_D1__SI__CI = 0x0A53; +constexpr unsigned int mmMC_IO_TXCNTL_APHY_D0__SI__CI = 0x0A4B; +constexpr unsigned int mmMC_IO_TXCNTL_APHY_D1__SI__CI = 0x0A51; +constexpr unsigned int mmMC_IO_TXCNTL_DPHY0_D0__SI__CI = 0x0A49; +constexpr unsigned int mmMC_IO_TXCNTL_DPHY0_D1__SI__CI = 0x0A4F; +constexpr unsigned int mmMC_IO_TXCNTL_DPHY1_D0__SI__CI = 0x0A4A; +constexpr unsigned int mmMC_IO_TXCNTL_DPHY1_D1__SI__CI = 0x0A50; +constexpr unsigned int mmMC_MCBVM_PERFCOUNTER0_CFG__CI__VI = 0x07C0; +constexpr unsigned int mmMC_MCBVM_PERFCOUNTER1_CFG__CI__VI = 0x07C1; +constexpr unsigned int mmMC_MCBVM_PERFCOUNTER2_CFG__CI__VI = 0x07C2; +constexpr unsigned int mmMC_MCBVM_PERFCOUNTER3_CFG__CI__VI = 0x07C3; +constexpr unsigned int mmMC_MCBVM_PERFCOUNTER_HI__CI__VI = 0x07AA; +constexpr unsigned int mmMC_MCBVM_PERFCOUNTER_LO__CI__VI = 0x07A3; +constexpr unsigned int mmMC_MCBVM_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07D1; +constexpr unsigned int mmMC_MCDVM_PERFCOUNTER0_CFG__CI__VI = 0x07C4; +constexpr unsigned int mmMC_MCDVM_PERFCOUNTER1_CFG__CI__VI = 0x07C5; +constexpr unsigned int mmMC_MCDVM_PERFCOUNTER2_CFG__CI__VI = 0x07C6; +constexpr unsigned int mmMC_MCDVM_PERFCOUNTER3_CFG__CI__VI = 0x07C7; +constexpr unsigned int mmMC_MCDVM_PERFCOUNTER_HI__CI__VI = 0x07AB; +constexpr unsigned int mmMC_MCDVM_PERFCOUNTER_LO__CI__VI = 0x07A4; +constexpr unsigned int mmMC_MCDVM_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07D2; +constexpr unsigned int mmMC_MEM_POWER_LS = 0x082A; +constexpr unsigned int mmMC_NPL_STATUS__SI__CI = 0x0A76; +constexpr unsigned int mmMC_PHY_TIMING_2__SI__CI = 0x0ACE; +constexpr unsigned int mmMC_PHY_TIMING_D0__SI__CI = 0x0ACC; +constexpr unsigned int mmMC_PHY_TIMING_D1__SI__CI = 0x0ACD; +constexpr unsigned int mmMC_PMG_AUTO_CFG__SI__CI = 0x0A35; +constexpr unsigned int mmMC_PMG_AUTO_CMD__SI__CI = 0x0A34; +constexpr unsigned int mmMC_RD_CB = 0x0981; +constexpr unsigned int mmMC_RD_DB = 0x0982; +constexpr unsigned int mmMC_RD_GRP_EXT = 0x0978; +constexpr unsigned int mmMC_RD_GRP_GFX = 0x0803; +constexpr unsigned int mmMC_RD_GRP_LCL = 0x098A; +constexpr unsigned int mmMC_RD_GRP_OTH = 0x0807; +constexpr unsigned int mmMC_RD_GRP_SYS = 0x0805; +constexpr unsigned int mmMC_RD_HUB = 0x0985; +constexpr unsigned int mmMC_RD_TC0 = 0x0983; +constexpr unsigned int mmMC_RD_TC1 = 0x0984; +constexpr unsigned int mmMC_RPB_ARB_CNTL = 0x0951; +constexpr unsigned int mmMC_RPB_BIF_CNTL = 0x0952; +constexpr unsigned int mmMC_RPB_CID_QUEUE_EX = 0x095A; +constexpr unsigned int mmMC_RPB_CID_QUEUE_EX_DATA = 0x095B; +constexpr unsigned int mmMC_RPB_CID_QUEUE_RD = 0x0957; +constexpr unsigned int mmMC_RPB_CID_QUEUE_WR = 0x0956; +constexpr unsigned int mmMC_RPB_CONF = 0x094D; +constexpr unsigned int mmMC_RPB_DBG1 = 0x094F; +constexpr unsigned int mmMC_RPB_EFF_CNTL = 0x0950; +constexpr unsigned int mmMC_RPB_IF_CONF = 0x094E; +constexpr unsigned int mmMC_RPB_PERFCOUNTER0_CFG__CI__VI = 0x07B8; +constexpr unsigned int mmMC_RPB_PERFCOUNTER1_CFG__CI__VI = 0x07B9; +constexpr unsigned int mmMC_RPB_PERFCOUNTER2_CFG__CI__VI = 0x07BA; +constexpr unsigned int mmMC_RPB_PERFCOUNTER3_CFG__CI__VI = 0x07BB; +constexpr unsigned int mmMC_RPB_PERFCOUNTER_HI__CI__VI = 0x07AC; +constexpr unsigned int mmMC_RPB_PERFCOUNTER_LO__CI__VI = 0x07A2; +constexpr unsigned int mmMC_RPB_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07D0; +constexpr unsigned int mmMC_RPB_PERF_COUNTER_CNTL = 0x0958; +constexpr unsigned int mmMC_RPB_PERF_COUNTER_STATUS = 0x0959; +constexpr unsigned int mmMC_RPB_RD_SWITCH_CNTL = 0x0955; +constexpr unsigned int mmMC_RPB_WR_COMBINE_CNTL = 0x0954; +constexpr unsigned int mmMC_RPB_WR_SWITCH_CNTL = 0x0953; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B0_D0__SI__CI = 0x0AA3; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B0_D1__SI__CI = 0x0AA7; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B1_D0__SI__CI = 0x0AA4; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B1_D1__SI__CI = 0x0AA8; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B2_D0__SI__CI = 0x0AA5; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B2_D1__SI__CI = 0x0AA9; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B3_D0__SI__CI = 0x0AA6; +constexpr unsigned int mmMC_SEQ_BIT_REMAP_B3_D1__SI__CI = 0x0AAA; +constexpr unsigned int mmMC_SEQ_BYTE_REMAP_D0__SI__CI = 0x0A93; +constexpr unsigned int mmMC_SEQ_BYTE_REMAP_D1__SI__CI = 0x0A94; +constexpr unsigned int mmMC_SEQ_CNTL_3__CI = 0x0D80; +constexpr unsigned int mmMC_SEQ_DLL_STBY_LP__CI = 0x0D8F; +constexpr unsigned int mmMC_SEQ_DLL_STBY__CI = 0x0D8E; +constexpr unsigned int mmMC_SEQ_DRAM_ERROR_INSERTION__SI__CI = 0x0ACB; +constexpr unsigned int mmMC_SEQ_G5PDX_CMD0_LP__CI = 0x0D84; +constexpr unsigned int mmMC_SEQ_G5PDX_CMD0__CI = 0x0D83; +constexpr unsigned int mmMC_SEQ_G5PDX_CMD1_LP__CI = 0x0D86; +constexpr unsigned int mmMC_SEQ_G5PDX_CMD1__CI = 0x0D85; +constexpr unsigned int mmMC_SEQ_G5PDX_CTRL_LP__CI = 0x0D82; +constexpr unsigned int mmMC_SEQ_G5PDX_CTRL__CI = 0x0D81; +constexpr unsigned int mmMC_SEQ_IO_RDBI__SI__CI = 0x0AB4; +constexpr unsigned int mmMC_SEQ_IO_REDC__SI__CI = 0x0AB5; +constexpr unsigned int mmMC_SEQ_IO_RESERVE_D0__SI__CI = 0x0AB7; +constexpr unsigned int mmMC_SEQ_IO_RESERVE_D1__SI__CI = 0x0AB8; +constexpr unsigned int mmMC_SEQ_IO_RWORD0__SI__CI = 0x0AAC; +constexpr unsigned int mmMC_SEQ_IO_RWORD1__SI__CI = 0x0AAD; +constexpr unsigned int mmMC_SEQ_IO_RWORD2__SI__CI = 0x0AAE; +constexpr unsigned int mmMC_SEQ_IO_RWORD3__SI__CI = 0x0AAF; +constexpr unsigned int mmMC_SEQ_IO_RWORD4__SI__CI = 0x0AB0; +constexpr unsigned int mmMC_SEQ_IO_RWORD5__SI__CI = 0x0AB1; +constexpr unsigned int mmMC_SEQ_IO_RWORD6__SI__CI = 0x0AB2; +constexpr unsigned int mmMC_SEQ_IO_RWORD7__SI__CI = 0x0AB3; +constexpr unsigned int mmMC_SEQ_MPLL_OVERRIDE__SI__CI = 0x0A22; +constexpr unsigned int mmMC_SEQ_PERF_CNTL__SI__CI = 0x0A77; +constexpr unsigned int mmMC_SEQ_PERF_CNTL_1__SI__CI = 0x0AFD; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_A_I0__SI__CI = 0x0A79; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_A_I1__SI__CI = 0x0A7A; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_B_I0__SI__CI = 0x0A7B; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_B_I1__SI__CI = 0x0A7C; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_C_I0__SI__CI = 0x0AD9; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_C_I1__SI__CI = 0x0ADA; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_D_I0__SI__CI = 0x0ADB; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CNT_D_I1__SI__CI = 0x0ADC; +constexpr unsigned int mmMC_SEQ_PERF_SEQ_CTL__SI__CI = 0x0A78; +constexpr unsigned int mmMC_SEQ_PHYREG_BCAST__CI = 0x0D89; +constexpr unsigned int mmMC_SEQ_PMG_CMD_EMRS_LP__SI__CI = 0x0AA1; +constexpr unsigned int mmMC_SEQ_PMG_CMD_MRS1_LP__SI__CI = 0x0AD2; +constexpr unsigned int mmMC_SEQ_PMG_CMD_MRS2_LP__SI__CI = 0x0AD8; +constexpr unsigned int mmMC_SEQ_PMG_CMD_MRS_LP__SI__CI = 0x0AA2; +constexpr unsigned int mmMC_SEQ_PMG_DVS_CMD_LP__CI = 0x0D8D; +constexpr unsigned int mmMC_SEQ_PMG_DVS_CMD__CI = 0x0D8C; +constexpr unsigned int mmMC_SEQ_PMG_DVS_CTL_LP__CI = 0x0D8B; +constexpr unsigned int mmMC_SEQ_PMG_DVS_CTL__CI = 0x0D8A; +constexpr unsigned int mmMC_SEQ_PMG_PG_HWCNTL__SI__CI = 0x0AB9; +constexpr unsigned int mmMC_SEQ_PMG_PG_SWCNTL_0__SI__CI = 0x0ABA; +constexpr unsigned int mmMC_SEQ_PMG_PG_SWCNTL_1__SI__CI = 0x0ABB; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE0_D0__SI__CI = 0x0A67; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE0_D1__SI__CI = 0x0A6D; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE1_D0__SI__CI = 0x0A68; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE1_D1__SI__CI = 0x0A6E; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE2_D0__SI__CI = 0x0A69; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE2_D1__SI__CI = 0x0A6F; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE3_D0__SI__CI = 0x0A6A; +constexpr unsigned int mmMC_SEQ_RXFRAMING_BYTE3_D1__SI__CI = 0x0A70; +constexpr unsigned int mmMC_SEQ_RXFRAMING_DBI_D0__SI__CI = 0x0A6B; +constexpr unsigned int mmMC_SEQ_RXFRAMING_DBI_D1__SI__CI = 0x0A71; +constexpr unsigned int mmMC_SEQ_RXFRAMING_EDC_D0__SI__CI = 0x0A6C; +constexpr unsigned int mmMC_SEQ_RXFRAMING_EDC_D1__SI__CI = 0x0A72; +constexpr unsigned int mmMC_SEQ_SREG_READ__CI = 0x0D87; +constexpr unsigned int mmMC_SEQ_SREG_STATUS__CI = 0x0D88; +constexpr unsigned int mmMC_SEQ_TCG_CNTL__SI__CI = 0x0ABD; +constexpr unsigned int mmMC_SEQ_TRAIN_EDC_THRESHOLD__SI__CI = 0x0A3B; +constexpr unsigned int mmMC_SEQ_TRAIN_EDC_THRESHOLD2__SI__CI = 0x0AFE; +constexpr unsigned int mmMC_SEQ_TRAIN_EDC_THRESHOLD3__SI__CI = 0x0AFF; +constexpr unsigned int mmMC_SEQ_TRAIN_TIMING__SI__CI = 0x0A40; +constexpr unsigned int mmMC_SEQ_TSM_BCNT__SI__CI = 0x0AC2; +constexpr unsigned int mmMC_SEQ_TSM_CTRL__SI__CI = 0x0ABE; +constexpr unsigned int mmMC_SEQ_TSM_DBI__SI__CI = 0x0AC6; +constexpr unsigned int mmMC_SEQ_TSM_DEBUG_DATA__SI__CI = 0x0AD0; +constexpr unsigned int mmMC_SEQ_TSM_DEBUG_INDEX__SI__CI = 0x0ACF; +constexpr unsigned int mmMC_SEQ_TSM_EDC__SI__CI = 0x0AC5; +constexpr unsigned int mmMC_SEQ_TSM_FLAG__SI__CI = 0x0AC3; +constexpr unsigned int mmMC_SEQ_TSM_GCNT__SI__CI = 0x0ABF; +constexpr unsigned int mmMC_SEQ_TSM_MISC__SI__CI = 0x0AE6; +constexpr unsigned int mmMC_SEQ_TSM_NCNT__SI__CI = 0x0AC1; +constexpr unsigned int mmMC_SEQ_TSM_OCNT__SI__CI = 0x0AC0; +constexpr unsigned int mmMC_SEQ_TSM_UPDATE__SI__CI = 0x0AC4; +constexpr unsigned int mmMC_SEQ_TSM_WCDR__SI__CI = 0x0AE3; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE0_D0__SI__CI = 0x0A58; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE0_D1__SI__CI = 0x0A60; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE1_D0__SI__CI = 0x0A59; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE1_D1__SI__CI = 0x0A61; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE2_D0__SI__CI = 0x0A5A; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE2_D1__SI__CI = 0x0A62; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE3_D0__SI__CI = 0x0A5B; +constexpr unsigned int mmMC_SEQ_TXFRAMING_BYTE3_D1__SI__CI = 0x0A63; +constexpr unsigned int mmMC_SEQ_TXFRAMING_DBI_D0__SI__CI = 0x0A5C; +constexpr unsigned int mmMC_SEQ_TXFRAMING_DBI_D1__SI__CI = 0x0A64; +constexpr unsigned int mmMC_SEQ_TXFRAMING_EDC_D0__SI__CI = 0x0A5D; +constexpr unsigned int mmMC_SEQ_TXFRAMING_EDC_D1__SI__CI = 0x0A65; +constexpr unsigned int mmMC_SEQ_TXFRAMING_FCK_D0__SI__CI = 0x0A5E; +constexpr unsigned int mmMC_SEQ_TXFRAMING_FCK_D1__SI__CI = 0x0A66; +constexpr unsigned int mmMC_SEQ_VENDOR_ID_I0__SI__CI = 0x0A7E; +constexpr unsigned int mmMC_SEQ_VENDOR_ID_I1__SI__CI = 0x0A7F; +constexpr unsigned int mmMC_SEQ_WCDR_CTRL__SI__CI = 0x0A39; +constexpr unsigned int mmMC_SEQ_WR_CTL_2__SI__CI = 0x0AD5; +constexpr unsigned int mmMC_SEQ_WR_CTL_2_LP__SI__CI = 0x0AD6; +constexpr unsigned int mmMC_SHARED_BLACKOUT_CNTL = 0x082B; +constexpr unsigned int mmMC_SHARED_CHMAP = 0x0801; +constexpr unsigned int mmMC_SHARED_CHREMAP = 0x0802; +constexpr unsigned int mmMC_TRAIN_EDCCDR_R_D0__SI__CI = 0x0A41; +constexpr unsigned int mmMC_TRAIN_EDCCDR_R_D1__SI__CI = 0x0A42; +constexpr unsigned int mmMC_TRAIN_EDC_STATUS_D0__SI__CI = 0x0A45; +constexpr unsigned int mmMC_TRAIN_EDC_STATUS_D1__SI__CI = 0x0A48; +constexpr unsigned int mmMC_TRAIN_PRBSERR_0_D0__SI__CI = 0x0A43; +constexpr unsigned int mmMC_TRAIN_PRBSERR_0_D1__SI__CI = 0x0A46; +constexpr unsigned int mmMC_TRAIN_PRBSERR_1_D0__SI__CI = 0x0A44; +constexpr unsigned int mmMC_TRAIN_PRBSERR_1_D1__SI__CI = 0x0A47; +constexpr unsigned int mmMC_TRAIN_PRBSERR_2_D0__SI__CI = 0x0AFB; +constexpr unsigned int mmMC_TRAIN_PRBSERR_2_D1__SI__CI = 0x0AFC; +constexpr unsigned int mmMC_VM_AGP_BASE = 0x080C; +constexpr unsigned int mmMC_VM_AGP_BOT = 0x080B; +constexpr unsigned int mmMC_VM_AGP_TOP = 0x080A; +constexpr unsigned int mmMC_VM_DC_WRITE_CNTL = 0x0810; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_0_HIGH_ADDR = 0x0815; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_0_LOW_ADDR = 0x0811; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_1_HIGH_ADDR = 0x0816; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_1_LOW_ADDR = 0x0812; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_2_HIGH_ADDR = 0x0817; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_2_LOW_ADDR = 0x0813; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_3_HIGH_ADDR = 0x0818; +constexpr unsigned int mmMC_VM_DC_WRITE_HIT_REGION_3_LOW_ADDR = 0x0814; +constexpr unsigned int mmMC_VM_FB_LOCATION = 0x0809; +constexpr unsigned int mmMC_VM_FB_OFFSET = 0x081A; +constexpr unsigned int mmMC_VM_L2_PERFCOUNTER0_CFG__CI__VI = 0x07CC; +constexpr unsigned int mmMC_VM_L2_PERFCOUNTER1_CFG__CI__VI = 0x07CD; +constexpr unsigned int mmMC_VM_L2_PERFCOUNTER_HI__CI__VI = 0x07AD; +constexpr unsigned int mmMC_VM_L2_PERFCOUNTER_LO__CI__VI = 0x07A5; +constexpr unsigned int mmMC_VM_L2_PERFCOUNTER_RSLT_CNTL__CI__VI = 0x07D3; +constexpr unsigned int mmMC_VM_MB_L1_TLB0_DEBUG = 0x0891; +constexpr unsigned int mmMC_VM_MB_L1_TLB0_STATUS = 0x0895; +constexpr unsigned int mmMC_VM_MB_L1_TLB1_STATUS = 0x0896; +constexpr unsigned int mmMC_VM_MB_L1_TLB2_DEBUG = 0x0893; +constexpr unsigned int mmMC_VM_MB_L1_TLB2_STATUS = 0x0897; +constexpr unsigned int mmMC_VM_MB_L1_TLB3_DEBUG = 0x08A5; +constexpr unsigned int mmMC_VM_MB_L1_TLB3_STATUS = 0x08A6; +constexpr unsigned int mmMC_VM_MB_L2ARBITER_L2_CREDITS = 0x08A1; +constexpr unsigned int mmMC_VM_MD_L1_TLB0_DEBUG = 0x0998; +constexpr unsigned int mmMC_VM_MD_L1_TLB0_STATUS = 0x099B; +constexpr unsigned int mmMC_VM_MD_L1_TLB1_DEBUG = 0x0999; +constexpr unsigned int mmMC_VM_MD_L1_TLB1_STATUS = 0x099C; +constexpr unsigned int mmMC_VM_MD_L1_TLB2_DEBUG = 0x099A; +constexpr unsigned int mmMC_VM_MD_L1_TLB2_STATUS = 0x099D; +constexpr unsigned int mmMC_VM_MD_L1_TLB3_DEBUG = 0x09A7; +constexpr unsigned int mmMC_VM_MD_L1_TLB3_STATUS = 0x09A8; +constexpr unsigned int mmMC_VM_MD_L2ARBITER_L2_CREDITS = 0x09A4; +constexpr unsigned int mmMC_VM_MX_L1_TLB_CNTL = 0x0819; +constexpr unsigned int mmMC_VM_STEERING__CI__VI = 0x081B; +constexpr unsigned int mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR = 0x080F; +constexpr unsigned int mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR = 0x080E; +constexpr unsigned int mmMC_VM_SYSTEM_APERTURE_LOW_ADDR = 0x080D; +constexpr unsigned int mmMC_WR_CB = 0x0986; +constexpr unsigned int mmMC_WR_DB = 0x0987; +constexpr unsigned int mmMC_WR_GRP_EXT = 0x0979; +constexpr unsigned int mmMC_WR_GRP_GFX = 0x0804; +constexpr unsigned int mmMC_WR_GRP_LCL = 0x098B; +constexpr unsigned int mmMC_WR_GRP_OTH = 0x0808; +constexpr unsigned int mmMC_WR_GRP_SYS = 0x0806; +constexpr unsigned int mmMC_WR_HUB = 0x0988; +constexpr unsigned int mmMC_WR_TC0 = 0x097B; +constexpr unsigned int mmMC_WR_TC1 = 0x097C; +constexpr unsigned int mmMC_XBAR_ADDR_DEC = 0x0C80; +constexpr unsigned int mmMC_XBAR_ARB = 0x0C8D; +constexpr unsigned int mmMC_XBAR_ARB_MAX_BURST = 0x0C8E; +constexpr unsigned int mmMC_XBAR_CHTRIREMAP = 0x0C8B; +constexpr unsigned int mmMC_XBAR_PERF_MON_CNTL0__SI__CI = 0x0C8F; +constexpr unsigned int mmMC_XBAR_PERF_MON_CNTL1__SI__CI = 0x0C90; +constexpr unsigned int mmMC_XBAR_PERF_MON_CNTL2__SI__CI = 0x0C91; +constexpr unsigned int mmMC_XBAR_PERF_MON_MAX_THSH__SI__CI = 0x0C96; +constexpr unsigned int mmMC_XBAR_PERF_MON_RSLT0__SI__CI = 0x0C92; +constexpr unsigned int mmMC_XBAR_PERF_MON_RSLT1__SI__CI = 0x0C93; +constexpr unsigned int mmMC_XBAR_PERF_MON_RSLT2__SI__CI = 0x0C94; +constexpr unsigned int mmMC_XBAR_PERF_MON_RSLT3__SI__CI = 0x0C95; +constexpr unsigned int mmMC_XBAR_RDREQ_CREDIT = 0x0C83; +constexpr unsigned int mmMC_XBAR_RDREQ_PRI_CREDIT = 0x0C84; +constexpr unsigned int mmMC_XBAR_RDRET_CREDIT1 = 0x0C87; +constexpr unsigned int mmMC_XBAR_RDRET_CREDIT2 = 0x0C88; +constexpr unsigned int mmMC_XBAR_RDRET_PRI_CREDIT1 = 0x0C89; +constexpr unsigned int mmMC_XBAR_RDRET_PRI_CREDIT2 = 0x0C8A; +constexpr unsigned int mmMC_XBAR_REMOTE = 0x0C81; +constexpr unsigned int mmMC_XBAR_SPARE0 = 0x0C97; +constexpr unsigned int mmMC_XBAR_SPARE1 = 0x0C98; +constexpr unsigned int mmMC_XBAR_TWOCHAN = 0x0C8C; +constexpr unsigned int mmMC_XBAR_WRREQ_CREDIT = 0x0C82; +constexpr unsigned int mmMC_XBAR_WRRET_CREDIT1 = 0x0C85; +constexpr unsigned int mmMC_XBAR_WRRET_CREDIT2 = 0x0C86; +constexpr unsigned int mmMC_XPB_CLG_CFG0 = 0x08E9; +constexpr unsigned int mmMC_XPB_CLG_CFG1 = 0x08EA; +constexpr unsigned int mmMC_XPB_CLG_CFG10 = 0x08F3; +constexpr unsigned int mmMC_XPB_CLG_CFG11 = 0x08F4; +constexpr unsigned int mmMC_XPB_CLG_CFG12 = 0x08F5; +constexpr unsigned int mmMC_XPB_CLG_CFG13 = 0x08F6; +constexpr unsigned int mmMC_XPB_CLG_CFG14 = 0x08F7; +constexpr unsigned int mmMC_XPB_CLG_CFG15 = 0x08F8; +constexpr unsigned int mmMC_XPB_CLG_CFG16 = 0x08F9; +constexpr unsigned int mmMC_XPB_CLG_CFG17 = 0x08FA; +constexpr unsigned int mmMC_XPB_CLG_CFG18 = 0x08FB; +constexpr unsigned int mmMC_XPB_CLG_CFG19 = 0x08FC; +constexpr unsigned int mmMC_XPB_CLG_CFG2 = 0x08EB; +constexpr unsigned int mmMC_XPB_CLG_CFG20 = 0x0928; +constexpr unsigned int mmMC_XPB_CLG_CFG21 = 0x0929; +constexpr unsigned int mmMC_XPB_CLG_CFG22 = 0x092A; +constexpr unsigned int mmMC_XPB_CLG_CFG23 = 0x092B; +constexpr unsigned int mmMC_XPB_CLG_CFG24 = 0x092C; +constexpr unsigned int mmMC_XPB_CLG_CFG25 = 0x092D; +constexpr unsigned int mmMC_XPB_CLG_CFG26 = 0x092E; +constexpr unsigned int mmMC_XPB_CLG_CFG27 = 0x092F; +constexpr unsigned int mmMC_XPB_CLG_CFG28 = 0x0930; +constexpr unsigned int mmMC_XPB_CLG_CFG29 = 0x0931; +constexpr unsigned int mmMC_XPB_CLG_CFG3 = 0x08EC; +constexpr unsigned int mmMC_XPB_CLG_CFG30 = 0x0932; +constexpr unsigned int mmMC_XPB_CLG_CFG31 = 0x0933; +constexpr unsigned int mmMC_XPB_CLG_CFG32 = 0x0936; +constexpr unsigned int mmMC_XPB_CLG_CFG33 = 0x0937; +constexpr unsigned int mmMC_XPB_CLG_CFG34 = 0x0938; +constexpr unsigned int mmMC_XPB_CLG_CFG35 = 0x0939; +constexpr unsigned int mmMC_XPB_CLG_CFG36 = 0x093A; +constexpr unsigned int mmMC_XPB_CLG_CFG4 = 0x08ED; +constexpr unsigned int mmMC_XPB_CLG_CFG5 = 0x08EE; +constexpr unsigned int mmMC_XPB_CLG_CFG6 = 0x08EF; +constexpr unsigned int mmMC_XPB_CLG_CFG7 = 0x08F0; +constexpr unsigned int mmMC_XPB_CLG_CFG8 = 0x08F1; +constexpr unsigned int mmMC_XPB_CLG_CFG9 = 0x08F2; +constexpr unsigned int mmMC_XPB_CLG_EXTRA = 0x08FD; +constexpr unsigned int mmMC_XPB_CLG_EXTRA_RD = 0x0935; +constexpr unsigned int mmMC_XPB_CLK_GAT = 0x091E; +constexpr unsigned int mmMC_XPB_INTF_CFG = 0x091F; +constexpr unsigned int mmMC_XPB_INTF_CFG2 = 0x0934; +constexpr unsigned int mmMC_XPB_INTF_STS = 0x0920; +constexpr unsigned int mmMC_XPB_LB_ADDR = 0x08FE; +constexpr unsigned int mmMC_XPB_MAP_INVERT_FLUSH_NUM_LSB = 0x0923; +constexpr unsigned int mmMC_XPB_MISC_CFG = 0x0927; +constexpr unsigned int mmMC_XPB_P2P_BAR0 = 0x0904; +constexpr unsigned int mmMC_XPB_P2P_BAR1 = 0x0905; +constexpr unsigned int mmMC_XPB_P2P_BAR2 = 0x0906; +constexpr unsigned int mmMC_XPB_P2P_BAR3 = 0x0907; +constexpr unsigned int mmMC_XPB_P2P_BAR4 = 0x0908; +constexpr unsigned int mmMC_XPB_P2P_BAR5 = 0x0909; +constexpr unsigned int mmMC_XPB_P2P_BAR6 = 0x090A; +constexpr unsigned int mmMC_XPB_P2P_BAR7 = 0x090B; +constexpr unsigned int mmMC_XPB_P2P_BAR_CFG = 0x0903; +constexpr unsigned int mmMC_XPB_P2P_BAR_DEBUG = 0x090D; +constexpr unsigned int mmMC_XPB_P2P_BAR_DELTA_ABOVE = 0x090E; +constexpr unsigned int mmMC_XPB_P2P_BAR_DELTA_BELOW = 0x090F; +constexpr unsigned int mmMC_XPB_P2P_BAR_SETUP = 0x090C; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR0 = 0x0910; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR1 = 0x0911; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR2 = 0x0912; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR3 = 0x0913; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR4 = 0x0914; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR5 = 0x0915; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR6 = 0x0916; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR7 = 0x0917; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR8 = 0x0918; +constexpr unsigned int mmMC_XPB_PEER_SYS_BAR9 = 0x0919; +constexpr unsigned int mmMC_XPB_PERF_KNOBS = 0x0924; +constexpr unsigned int mmMC_XPB_PIPE_STS = 0x0921; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP0 = 0x08DB; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP1 = 0x08DC; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP2 = 0x08DD; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP3 = 0x08DE; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP4 = 0x08DF; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP5 = 0x08E0; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP6 = 0x08E1; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP7 = 0x08E2; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP8 = 0x08E3; +constexpr unsigned int mmMC_XPB_RTR_DEST_MAP9 = 0x08E4; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR0 = 0x08CD; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR1 = 0x08CE; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR2 = 0x08CF; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR3 = 0x08D0; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR4 = 0x08D1; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR5 = 0x08D2; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR6 = 0x08D3; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR7 = 0x08D4; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR8 = 0x08D5; +constexpr unsigned int mmMC_XPB_RTR_SRC_APRTR9 = 0x08D6; +constexpr unsigned int mmMC_XPB_STICKY = 0x0925; +constexpr unsigned int mmMC_XPB_STICKY_W1C = 0x0926; +constexpr unsigned int mmMC_XPB_SUB_CTRL = 0x0922; +constexpr unsigned int mmMC_XPB_UNC_THRESH_HST = 0x08FF; +constexpr unsigned int mmMC_XPB_UNC_THRESH_SID = 0x0900; +constexpr unsigned int mmMC_XPB_WCB_CFG = 0x0902; +constexpr unsigned int mmMC_XPB_WCB_STS = 0x0901; +constexpr unsigned int mmMC_XPB_XDMA_PEER_SYS_BAR0 = 0x091A; +constexpr unsigned int mmMC_XPB_XDMA_PEER_SYS_BAR1 = 0x091B; +constexpr unsigned int mmMC_XPB_XDMA_PEER_SYS_BAR2 = 0x091C; +constexpr unsigned int mmMC_XPB_XDMA_PEER_SYS_BAR3 = 0x091D; +constexpr unsigned int mmMC_XPB_XDMA_RTR_DEST_MAP0 = 0x08E5; +constexpr unsigned int mmMC_XPB_XDMA_RTR_DEST_MAP1 = 0x08E6; +constexpr unsigned int mmMC_XPB_XDMA_RTR_DEST_MAP2 = 0x08E7; +constexpr unsigned int mmMC_XPB_XDMA_RTR_DEST_MAP3 = 0x08E8; +constexpr unsigned int mmMC_XPB_XDMA_RTR_SRC_APRTR0 = 0x08D7; +constexpr unsigned int mmMC_XPB_XDMA_RTR_SRC_APRTR1 = 0x08D8; +constexpr unsigned int mmMC_XPB_XDMA_RTR_SRC_APRTR2 = 0x08D9; +constexpr unsigned int mmMC_XPB_XDMA_RTR_SRC_APRTR3 = 0x08DA; +constexpr unsigned int mmMEM_TYPE_CNTL__CI__VI = 0x14E4; +constexpr unsigned int mmMICROSECOND_TIME_BASE_DIV__SI = 0x0148; +constexpr unsigned int mmMM_CFGREGS_CNTL = 0x1513; +constexpr unsigned int mmMM_DATA = 0x0001; +constexpr unsigned int mmMM_INDEX = 0x0000; +constexpr unsigned int mmMM_INDEX_HI__CI__VI = 0x0006; +constexpr unsigned int mmMPLL_AD_FUNC_CNTL__SI__CI = 0x0AF0; +constexpr unsigned int mmMPLL_AD_STATUS__SI__CI = 0x0AF6; +constexpr unsigned int mmMPLL_BYPASSCLK_SEL__SI = 0x0197; +constexpr unsigned int mmMPLL_CNTL_MODE__SI__CI = 0x0AEC; +constexpr unsigned int mmMPLL_CONTROL__SI__CI = 0x0AF5; +constexpr unsigned int mmMPLL_DQ_0_0_STATUS__SI__CI = 0x0AF7; +constexpr unsigned int mmMPLL_DQ_0_1_STATUS__SI__CI = 0x0AF8; +constexpr unsigned int mmMPLL_DQ_1_0_STATUS__SI__CI = 0x0AF9; +constexpr unsigned int mmMPLL_DQ_1_1_STATUS__SI__CI = 0x0AFA; +constexpr unsigned int mmMPLL_DQ_FUNC_CNTL__SI__CI = 0x0AF1; +constexpr unsigned int mmMPLL_FUNC_CNTL__SI__CI = 0x0AED; +constexpr unsigned int mmMPLL_FUNC_CNTL_1__SI__CI = 0x0AEE; +constexpr unsigned int mmMPLL_FUNC_CNTL_2__SI__CI = 0x0AEF; +constexpr unsigned int mmMPLL_SEQ_UCODE_1__SI__CI = 0x0AEA; +constexpr unsigned int mmMPLL_SEQ_UCODE_2__SI__CI = 0x0AEB; +constexpr unsigned int mmMPLL_SS1__SI__CI = 0x0AF3; +constexpr unsigned int mmMPLL_SS2__SI__CI = 0x0AF4; +constexpr unsigned int mmMPLL_TIME__SI__CI = 0x0AF2; +constexpr unsigned int mmMVP_AFR_FLIP_FIFO_CNTL__SI = 0x1AD9; +constexpr unsigned int mmMVP_AFR_FLIP_MODE__SI = 0x1AD8; +constexpr unsigned int mmMVP_BLACK_KEYER__SI = 0x1686; +constexpr unsigned int mmMVP_CONTROL1__SI = 0x1680; +constexpr unsigned int mmMVP_CONTROL2__SI = 0x1681; +constexpr unsigned int mmMVP_CONTROL3__SI = 0x168A; +constexpr unsigned int mmMVP_CRC_CNTL__SI = 0x1687; +constexpr unsigned int mmMVP_CRC_RESULT_BLUE_GREEN__SI = 0x1688; +constexpr unsigned int mmMVP_CRC_RESULT_RED__SI = 0x1689; +constexpr unsigned int mmMVP_FIFO_CONTROL__SI = 0x1682; +constexpr unsigned int mmMVP_FIFO_STATUS__SI = 0x1683; +constexpr unsigned int mmMVP_FLIP_LINE_NUM_INSERT__SI = 0x1ADA; +constexpr unsigned int mmMVP_INBAND_CNTL_CAP__SI = 0x1685; +constexpr unsigned int mmMVP_RECEIVE_CNT_CNTL1__SI = 0x168B; +constexpr unsigned int mmMVP_RECEIVE_CNT_CNTL2__SI = 0x168C; +constexpr unsigned int mmMVP_SLAVE_STATUS__SI = 0x1684; +constexpr unsigned int mmMVP_TEST_DEBUG_DATA__SI = 0x168E; +constexpr unsigned int mmMVP_TEST_DEBUG_INDEX__SI = 0x168D; +constexpr unsigned int mmNEW_REFCLKB_TIMER_1__CI = 0x1484; +constexpr unsigned int mmNEW_REFCLKB_TIMER__CI = 0x1485; +constexpr unsigned int mmOVLSCL_EDGE_PIXEL_CNTL__SI__VI = 0x1A2C; +constexpr unsigned int mmOVL_CONTROL1__SI__VI = 0x1A1D; +constexpr unsigned int mmOVL_CONTROL2__SI__VI = 0x1A1E; +constexpr unsigned int mmOVL_DFQ_CONTROL__SI__VI = 0x1A29; +constexpr unsigned int mmOVL_DFQ_STATUS__SI__VI = 0x1A2A; +constexpr unsigned int mmOVL_ENABLE__SI__VI = 0x1A1C; +constexpr unsigned int mmOVL_END__SI__VI = 0x1A26; +constexpr unsigned int mmOVL_PITCH__SI__VI = 0x1A21; +constexpr unsigned int mmOVL_START__SI__VI = 0x1A25; +constexpr unsigned int mmOVL_SURFACE_ADDRESS = 0x1A20; +constexpr unsigned int mmOVL_SURFACE_ADDRESS_HIGH = 0x1A22; +constexpr unsigned int mmOVL_SURFACE_ADDRESS_HIGH_INUSE__SI__VI = 0x1A2B; +constexpr unsigned int mmOVL_SURFACE_ADDRESS_INUSE__SI__VI = 0x1A28; +constexpr unsigned int mmOVL_SURFACE_OFFSET_X__SI__VI = 0x1A23; +constexpr unsigned int mmOVL_SURFACE_OFFSET_Y__SI__VI = 0x1A24; +constexpr unsigned int mmOVL_SWAP_CNTL__SI__VI = 0x1A1F; +constexpr unsigned int mmOVL_UPDATE__SI__VI = 0x1A27; +constexpr unsigned int mmPAGE_MIRROR_CNTL__SI = 0x0581; +constexpr unsigned int mmPA_CL_CLIP_CNTL = 0xA204; +constexpr unsigned int mmPA_CL_CNTL_STATUS = 0x2284; +constexpr unsigned int mmPA_CL_ENHANCE = 0x2285; +constexpr unsigned int mmPA_CL_GB_HORZ_CLIP_ADJ = 0xA2FC; +constexpr unsigned int mmPA_CL_GB_HORZ_DISC_ADJ = 0xA2FD; +constexpr unsigned int mmPA_CL_GB_VERT_CLIP_ADJ = 0xA2FA; +constexpr unsigned int mmPA_CL_GB_VERT_DISC_ADJ = 0xA2FB; +constexpr unsigned int mmPA_CL_NANINF_CNTL = 0xA208; +constexpr unsigned int mmPA_CL_POINT_CULL_RAD = 0xA1F8; +constexpr unsigned int mmPA_CL_POINT_SIZE = 0xA1F7; +constexpr unsigned int mmPA_CL_POINT_X_RAD = 0xA1F5; +constexpr unsigned int mmPA_CL_POINT_Y_RAD = 0xA1F6; +constexpr unsigned int mmPA_CL_RESET_DEBUG__CI__VI = 0x2286; +constexpr unsigned int mmPA_CL_UCP_0_W = 0xA172; +constexpr unsigned int mmPA_CL_UCP_0_X = 0xA16F; +constexpr unsigned int mmPA_CL_UCP_0_Y = 0xA170; +constexpr unsigned int mmPA_CL_UCP_0_Z = 0xA171; +constexpr unsigned int mmPA_CL_UCP_1_W = 0xA176; +constexpr unsigned int mmPA_CL_UCP_1_X = 0xA173; +constexpr unsigned int mmPA_CL_UCP_1_Y = 0xA174; +constexpr unsigned int mmPA_CL_UCP_1_Z = 0xA175; +constexpr unsigned int mmPA_CL_UCP_2_W = 0xA17A; +constexpr unsigned int mmPA_CL_UCP_2_X = 0xA177; +constexpr unsigned int mmPA_CL_UCP_2_Y = 0xA178; +constexpr unsigned int mmPA_CL_UCP_2_Z = 0xA179; +constexpr unsigned int mmPA_CL_UCP_3_W = 0xA17E; +constexpr unsigned int mmPA_CL_UCP_3_X = 0xA17B; +constexpr unsigned int mmPA_CL_UCP_3_Y = 0xA17C; +constexpr unsigned int mmPA_CL_UCP_3_Z = 0xA17D; +constexpr unsigned int mmPA_CL_UCP_4_W = 0xA182; +constexpr unsigned int mmPA_CL_UCP_4_X = 0xA17F; +constexpr unsigned int mmPA_CL_UCP_4_Y = 0xA180; +constexpr unsigned int mmPA_CL_UCP_4_Z = 0xA181; +constexpr unsigned int mmPA_CL_UCP_5_W = 0xA186; +constexpr unsigned int mmPA_CL_UCP_5_X = 0xA183; +constexpr unsigned int mmPA_CL_UCP_5_Y = 0xA184; +constexpr unsigned int mmPA_CL_UCP_5_Z = 0xA185; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET = 0xA110; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_1 = 0xA116; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_10 = 0xA14C; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_11 = 0xA152; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_12 = 0xA158; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_13 = 0xA15E; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_14 = 0xA164; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_15 = 0xA16A; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_2 = 0xA11C; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_3 = 0xA122; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_4 = 0xA128; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_5 = 0xA12E; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_6 = 0xA134; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_7 = 0xA13A; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_8 = 0xA140; +constexpr unsigned int mmPA_CL_VPORT_XOFFSET_9 = 0xA146; +constexpr unsigned int mmPA_CL_VPORT_XSCALE = 0xA10F; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_1 = 0xA115; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_10 = 0xA14B; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_11 = 0xA151; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_12 = 0xA157; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_13 = 0xA15D; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_14 = 0xA163; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_15 = 0xA169; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_2 = 0xA11B; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_3 = 0xA121; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_4 = 0xA127; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_5 = 0xA12D; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_6 = 0xA133; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_7 = 0xA139; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_8 = 0xA13F; +constexpr unsigned int mmPA_CL_VPORT_XSCALE_9 = 0xA145; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET = 0xA112; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_1 = 0xA118; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_10 = 0xA14E; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_11 = 0xA154; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_12 = 0xA15A; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_13 = 0xA160; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_14 = 0xA166; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_15 = 0xA16C; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_2 = 0xA11E; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_3 = 0xA124; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_4 = 0xA12A; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_5 = 0xA130; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_6 = 0xA136; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_7 = 0xA13C; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_8 = 0xA142; +constexpr unsigned int mmPA_CL_VPORT_YOFFSET_9 = 0xA148; +constexpr unsigned int mmPA_CL_VPORT_YSCALE = 0xA111; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_1 = 0xA117; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_10 = 0xA14D; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_11 = 0xA153; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_12 = 0xA159; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_13 = 0xA15F; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_14 = 0xA165; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_15 = 0xA16B; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_2 = 0xA11D; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_3 = 0xA123; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_4 = 0xA129; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_5 = 0xA12F; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_6 = 0xA135; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_7 = 0xA13B; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_8 = 0xA141; +constexpr unsigned int mmPA_CL_VPORT_YSCALE_9 = 0xA147; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET = 0xA114; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_1 = 0xA11A; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_10 = 0xA150; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_11 = 0xA156; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_12 = 0xA15C; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_13 = 0xA162; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_14 = 0xA168; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_15 = 0xA16E; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_2 = 0xA120; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_3 = 0xA126; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_4 = 0xA12C; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_5 = 0xA132; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_6 = 0xA138; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_7 = 0xA13E; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_8 = 0xA144; +constexpr unsigned int mmPA_CL_VPORT_ZOFFSET_9 = 0xA14A; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE = 0xA113; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_1 = 0xA119; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_10 = 0xA14F; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_11 = 0xA155; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_12 = 0xA15B; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_13 = 0xA161; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_14 = 0xA167; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_15 = 0xA16D; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_2 = 0xA11F; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_3 = 0xA125; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_4 = 0xA12B; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_5 = 0xA131; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_6 = 0xA137; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_7 = 0xA13D; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_8 = 0xA143; +constexpr unsigned int mmPA_CL_VPORT_ZSCALE_9 = 0xA149; +constexpr unsigned int mmPA_CL_VS_OUT_CNTL = 0xA207; +constexpr unsigned int mmPA_CL_VTE_CNTL = 0xA206; +constexpr unsigned int mmPA_SC_AA_CONFIG = 0xA2F8; +constexpr unsigned int mmPA_SC_AA_MASK_X0Y0_X1Y0 = 0xA30E; +constexpr unsigned int mmPA_SC_AA_MASK_X0Y1_X1Y1 = 0xA30F; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 = 0xA2FE; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1 = 0xA2FF; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2 = 0xA300; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3 = 0xA301; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0 = 0xA306; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1 = 0xA307; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2 = 0xA308; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3 = 0xA309; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0 = 0xA302; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1 = 0xA303; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2 = 0xA304; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3 = 0xA305; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0 = 0xA30A; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1 = 0xA30B; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2 = 0xA30C; +constexpr unsigned int mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3 = 0xA30D; +constexpr unsigned int mmPA_SC_CENTROID_PRIORITY_0 = 0xA2F5; +constexpr unsigned int mmPA_SC_CENTROID_PRIORITY_1 = 0xA2F6; +constexpr unsigned int mmPA_SC_CLIPRECT_0_BR = 0xA085; +constexpr unsigned int mmPA_SC_CLIPRECT_0_TL = 0xA084; +constexpr unsigned int mmPA_SC_CLIPRECT_1_BR = 0xA087; +constexpr unsigned int mmPA_SC_CLIPRECT_1_TL = 0xA086; +constexpr unsigned int mmPA_SC_CLIPRECT_2_BR = 0xA089; +constexpr unsigned int mmPA_SC_CLIPRECT_2_TL = 0xA088; +constexpr unsigned int mmPA_SC_CLIPRECT_3_BR = 0xA08B; +constexpr unsigned int mmPA_SC_CLIPRECT_3_TL = 0xA08A; +constexpr unsigned int mmPA_SC_CLIPRECT_RULE = 0xA083; +constexpr unsigned int mmPA_SC_DEBUG_CNTL = 0x22F6; +constexpr unsigned int mmPA_SC_DEBUG_DATA = 0x22F7; +constexpr unsigned int mmPA_SC_EDGERULE = 0xA08C; +constexpr unsigned int mmPA_SC_ENHANCE = 0x22FC; +constexpr unsigned int mmPA_SC_FIFO_DEPTH_CNTL = 0x2295; +constexpr unsigned int mmPA_SC_FIFO_SIZE = 0x22F3; +constexpr unsigned int mmPA_SC_FORCE_EOV_MAX_CNTS = 0x22C9; +constexpr unsigned int mmPA_SC_GENERIC_SCISSOR_BR = 0xA091; +constexpr unsigned int mmPA_SC_GENERIC_SCISSOR_TL = 0xA090; +constexpr unsigned int mmPA_SC_HP3D_TRAP_SCREEN_COUNT__CI__VI = 0xC2AC; +constexpr unsigned int mmPA_SC_HP3D_TRAP_SCREEN_HV_EN__CI__VI = 0xC2A8; +constexpr unsigned int mmPA_SC_HP3D_TRAP_SCREEN_HV_LOCK__CI__VI = 0x22C1; +constexpr unsigned int mmPA_SC_HP3D_TRAP_SCREEN_H__CI__VI = 0xC2A9; +constexpr unsigned int mmPA_SC_HP3D_TRAP_SCREEN_OCCURRENCE__CI__VI = 0xC2AB; +constexpr unsigned int mmPA_SC_HP3D_TRAP_SCREEN_V__CI__VI = 0xC2AA; +constexpr unsigned int mmPA_SC_IF_FIFO_SIZE = 0x22F5; +constexpr unsigned int mmPA_SC_LINE_CNTL = 0xA2F7; +constexpr unsigned int mmPA_SC_LINE_STIPPLE = 0xA283; +constexpr unsigned int mmPA_SC_LINE_STIPPLE_STATE__CI__VI = 0xC281; +constexpr unsigned int mmPA_SC_LINE_STIPPLE_STATE__SI = 0x22C4; +constexpr unsigned int mmPA_SC_MODE_CNTL_0 = 0xA292; +constexpr unsigned int mmPA_SC_MODE_CNTL_1 = 0xA293; +constexpr unsigned int mmPA_SC_P3D_TRAP_SCREEN_COUNT__CI__VI = 0xC2A4; +constexpr unsigned int mmPA_SC_P3D_TRAP_SCREEN_HV_EN__CI__VI = 0xC2A0; +constexpr unsigned int mmPA_SC_P3D_TRAP_SCREEN_HV_LOCK__CI__VI = 0x22C0; +constexpr unsigned int mmPA_SC_P3D_TRAP_SCREEN_H__CI__VI = 0xC2A1; +constexpr unsigned int mmPA_SC_P3D_TRAP_SCREEN_OCCURRENCE__CI__VI = 0xC2A3; +constexpr unsigned int mmPA_SC_P3D_TRAP_SCREEN_V__CI__VI = 0xC2A2; +constexpr unsigned int mmPA_SC_PERFCOUNTER0_HI__CI__VI = 0xD141; +constexpr unsigned int mmPA_SC_PERFCOUNTER0_HI__SI = 0x22A9; +constexpr unsigned int mmPA_SC_PERFCOUNTER0_LO__CI__VI = 0xD140; +constexpr unsigned int mmPA_SC_PERFCOUNTER0_LO__SI = 0x22A8; +constexpr unsigned int mmPA_SC_PERFCOUNTER0_SELECT1__CI__VI = 0xD941; +constexpr unsigned int mmPA_SC_PERFCOUNTER0_SELECT__CI__VI = 0xD940; +constexpr unsigned int mmPA_SC_PERFCOUNTER0_SELECT__SI = 0x22A0; +constexpr unsigned int mmPA_SC_PERFCOUNTER1_HI__CI__VI = 0xD143; +constexpr unsigned int mmPA_SC_PERFCOUNTER1_HI__SI = 0x22AB; +constexpr unsigned int mmPA_SC_PERFCOUNTER1_LO__CI__VI = 0xD142; +constexpr unsigned int mmPA_SC_PERFCOUNTER1_LO__SI = 0x22AA; +constexpr unsigned int mmPA_SC_PERFCOUNTER1_SELECT__CI__VI = 0xD942; +constexpr unsigned int mmPA_SC_PERFCOUNTER1_SELECT__SI = 0x22A1; +constexpr unsigned int mmPA_SC_PERFCOUNTER2_HI__CI__VI = 0xD145; +constexpr unsigned int mmPA_SC_PERFCOUNTER2_HI__SI = 0x22AD; +constexpr unsigned int mmPA_SC_PERFCOUNTER2_LO__CI__VI = 0xD144; +constexpr unsigned int mmPA_SC_PERFCOUNTER2_LO__SI = 0x22AC; +constexpr unsigned int mmPA_SC_PERFCOUNTER2_SELECT__CI__VI = 0xD943; +constexpr unsigned int mmPA_SC_PERFCOUNTER2_SELECT__SI = 0x22A2; +constexpr unsigned int mmPA_SC_PERFCOUNTER3_HI__CI__VI = 0xD147; +constexpr unsigned int mmPA_SC_PERFCOUNTER3_HI__SI = 0x22AF; +constexpr unsigned int mmPA_SC_PERFCOUNTER3_LO__CI__VI = 0xD146; +constexpr unsigned int mmPA_SC_PERFCOUNTER3_LO__SI = 0x22AE; +constexpr unsigned int mmPA_SC_PERFCOUNTER3_SELECT__CI__VI = 0xD944; +constexpr unsigned int mmPA_SC_PERFCOUNTER3_SELECT__SI = 0x22A3; +constexpr unsigned int mmPA_SC_PERFCOUNTER4_HI__CI__VI = 0xD149; +constexpr unsigned int mmPA_SC_PERFCOUNTER4_HI__SI = 0x22B1; +constexpr unsigned int mmPA_SC_PERFCOUNTER4_LO__CI__VI = 0xD148; +constexpr unsigned int mmPA_SC_PERFCOUNTER4_LO__SI = 0x22B0; +constexpr unsigned int mmPA_SC_PERFCOUNTER4_SELECT__CI__VI = 0xD945; +constexpr unsigned int mmPA_SC_PERFCOUNTER4_SELECT__SI = 0x22A4; +constexpr unsigned int mmPA_SC_PERFCOUNTER5_HI__CI__VI = 0xD14B; +constexpr unsigned int mmPA_SC_PERFCOUNTER5_HI__SI = 0x22B3; +constexpr unsigned int mmPA_SC_PERFCOUNTER5_LO__CI__VI = 0xD14A; +constexpr unsigned int mmPA_SC_PERFCOUNTER5_LO__SI = 0x22B2; +constexpr unsigned int mmPA_SC_PERFCOUNTER5_SELECT__CI__VI = 0xD946; +constexpr unsigned int mmPA_SC_PERFCOUNTER5_SELECT__SI = 0x22A5; +constexpr unsigned int mmPA_SC_PERFCOUNTER6_HI__CI__VI = 0xD14D; +constexpr unsigned int mmPA_SC_PERFCOUNTER6_HI__SI = 0x22B5; +constexpr unsigned int mmPA_SC_PERFCOUNTER6_LO__CI__VI = 0xD14C; +constexpr unsigned int mmPA_SC_PERFCOUNTER6_LO__SI = 0x22B4; +constexpr unsigned int mmPA_SC_PERFCOUNTER6_SELECT__CI__VI = 0xD947; +constexpr unsigned int mmPA_SC_PERFCOUNTER6_SELECT__SI = 0x22A6; +constexpr unsigned int mmPA_SC_PERFCOUNTER7_HI__CI__VI = 0xD14F; +constexpr unsigned int mmPA_SC_PERFCOUNTER7_HI__SI = 0x22B7; +constexpr unsigned int mmPA_SC_PERFCOUNTER7_LO__CI__VI = 0xD14E; +constexpr unsigned int mmPA_SC_PERFCOUNTER7_LO__SI = 0x22B6; +constexpr unsigned int mmPA_SC_PERFCOUNTER7_SELECT__CI__VI = 0xD948; +constexpr unsigned int mmPA_SC_PERFCOUNTER7_SELECT__SI = 0x22A7; +constexpr unsigned int mmPA_SC_RASTER_CONFIG = 0xA0D4; +constexpr unsigned int mmPA_SC_RASTER_CONFIG_1__CI__VI = 0xA0D5; +constexpr unsigned int mmPA_SC_SCREEN_SCISSOR_BR = 0xA00D; +constexpr unsigned int mmPA_SC_SCREEN_SCISSOR_TL = 0xA00C; +constexpr unsigned int mmPA_SC_TRAP_SCREEN_COUNT__CI__VI = 0xC2B4; +constexpr unsigned int mmPA_SC_TRAP_SCREEN_HV_EN__CI__VI = 0xC2B0; +constexpr unsigned int mmPA_SC_TRAP_SCREEN_HV_LOCK__CI__VI = 0x22C2; +constexpr unsigned int mmPA_SC_TRAP_SCREEN_H__CI__VI = 0xC2B1; +constexpr unsigned int mmPA_SC_TRAP_SCREEN_OCCURRENCE__CI__VI = 0xC2B3; +constexpr unsigned int mmPA_SC_TRAP_SCREEN_V__CI__VI = 0xC2B2; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_0_BR = 0xA095; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_0_TL = 0xA094; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_10_BR = 0xA0A9; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_10_TL = 0xA0A8; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_11_BR = 0xA0AB; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_11_TL = 0xA0AA; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_12_BR = 0xA0AD; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_12_TL = 0xA0AC; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_13_BR = 0xA0AF; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_13_TL = 0xA0AE; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_14_BR = 0xA0B1; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_14_TL = 0xA0B0; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_15_BR = 0xA0B3; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_15_TL = 0xA0B2; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_1_BR = 0xA097; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_1_TL = 0xA096; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_2_BR = 0xA099; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_2_TL = 0xA098; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_3_BR = 0xA09B; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_3_TL = 0xA09A; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_4_BR = 0xA09D; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_4_TL = 0xA09C; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_5_BR = 0xA09F; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_5_TL = 0xA09E; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_6_BR = 0xA0A1; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_6_TL = 0xA0A0; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_7_BR = 0xA0A3; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_7_TL = 0xA0A2; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_8_BR = 0xA0A5; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_8_TL = 0xA0A4; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_9_BR = 0xA0A7; +constexpr unsigned int mmPA_SC_VPORT_SCISSOR_9_TL = 0xA0A6; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_0 = 0xA0B5; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_1 = 0xA0B7; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_10 = 0xA0C9; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_11 = 0xA0CB; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_12 = 0xA0CD; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_13 = 0xA0CF; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_14 = 0xA0D1; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_15 = 0xA0D3; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_2 = 0xA0B9; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_3 = 0xA0BB; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_4 = 0xA0BD; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_5 = 0xA0BF; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_6 = 0xA0C1; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_7 = 0xA0C3; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_8 = 0xA0C5; +constexpr unsigned int mmPA_SC_VPORT_ZMAX_9 = 0xA0C7; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_0 = 0xA0B4; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_1 = 0xA0B6; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_10 = 0xA0C8; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_11 = 0xA0CA; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_12 = 0xA0CC; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_13 = 0xA0CE; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_14 = 0xA0D0; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_15 = 0xA0D2; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_2 = 0xA0B8; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_3 = 0xA0BA; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_4 = 0xA0BC; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_5 = 0xA0BE; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_6 = 0xA0C0; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_7 = 0xA0C2; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_8 = 0xA0C4; +constexpr unsigned int mmPA_SC_VPORT_ZMIN_9 = 0xA0C6; +constexpr unsigned int mmPA_SC_WINDOW_OFFSET = 0xA080; +constexpr unsigned int mmPA_SC_WINDOW_SCISSOR_BR = 0xA082; +constexpr unsigned int mmPA_SC_WINDOW_SCISSOR_TL = 0xA081; +constexpr unsigned int mmPA_SU_CNTL_STATUS = 0x2294; +constexpr unsigned int mmPA_SU_DEBUG_CNTL = 0x2280; +constexpr unsigned int mmPA_SU_DEBUG_DATA = 0x2281; +constexpr unsigned int mmPA_SU_HARDWARE_SCREEN_OFFSET = 0xA08D; +constexpr unsigned int mmPA_SU_LINE_CNTL = 0xA282; +constexpr unsigned int mmPA_SU_LINE_STIPPLE_CNTL = 0xA209; +constexpr unsigned int mmPA_SU_LINE_STIPPLE_SCALE = 0xA20A; +constexpr unsigned int mmPA_SU_LINE_STIPPLE_VALUE__CI__VI = 0xC280; +constexpr unsigned int mmPA_SU_LINE_STIPPLE_VALUE__SI = 0x2298; +constexpr unsigned int mmPA_SU_PERFCOUNTER0_HI__CI__VI = 0xD101; +constexpr unsigned int mmPA_SU_PERFCOUNTER0_HI__SI = 0x228D; +constexpr unsigned int mmPA_SU_PERFCOUNTER0_LO__CI__VI = 0xD100; +constexpr unsigned int mmPA_SU_PERFCOUNTER0_LO__SI = 0x228C; +constexpr unsigned int mmPA_SU_PERFCOUNTER0_SELECT1__CI__VI = 0xD901; +constexpr unsigned int mmPA_SU_PERFCOUNTER0_SELECT__CI__VI = 0xD900; +constexpr unsigned int mmPA_SU_PERFCOUNTER0_SELECT__SI = 0x2288; +constexpr unsigned int mmPA_SU_PERFCOUNTER1_HI__CI__VI = 0xD103; +constexpr unsigned int mmPA_SU_PERFCOUNTER1_HI__SI = 0x228F; +constexpr unsigned int mmPA_SU_PERFCOUNTER1_LO__CI__VI = 0xD102; +constexpr unsigned int mmPA_SU_PERFCOUNTER1_LO__SI = 0x228E; +constexpr unsigned int mmPA_SU_PERFCOUNTER1_SELECT1__CI__VI = 0xD903; +constexpr unsigned int mmPA_SU_PERFCOUNTER1_SELECT__CI__VI = 0xD902; +constexpr unsigned int mmPA_SU_PERFCOUNTER1_SELECT__SI = 0x2289; +constexpr unsigned int mmPA_SU_PERFCOUNTER2_HI__CI__VI = 0xD105; +constexpr unsigned int mmPA_SU_PERFCOUNTER2_HI__SI = 0x2291; +constexpr unsigned int mmPA_SU_PERFCOUNTER2_LO__CI__VI = 0xD104; +constexpr unsigned int mmPA_SU_PERFCOUNTER2_LO__SI = 0x2290; +constexpr unsigned int mmPA_SU_PERFCOUNTER2_SELECT__CI__VI = 0xD904; +constexpr unsigned int mmPA_SU_PERFCOUNTER2_SELECT__SI = 0x228A; +constexpr unsigned int mmPA_SU_PERFCOUNTER3_HI__CI__VI = 0xD107; +constexpr unsigned int mmPA_SU_PERFCOUNTER3_HI__SI = 0x2293; +constexpr unsigned int mmPA_SU_PERFCOUNTER3_LO__CI__VI = 0xD106; +constexpr unsigned int mmPA_SU_PERFCOUNTER3_LO__SI = 0x2292; +constexpr unsigned int mmPA_SU_PERFCOUNTER3_SELECT__CI__VI = 0xD905; +constexpr unsigned int mmPA_SU_PERFCOUNTER3_SELECT__SI = 0x228B; +constexpr unsigned int mmPA_SU_POINT_MINMAX = 0xA281; +constexpr unsigned int mmPA_SU_POINT_SIZE = 0xA280; +constexpr unsigned int mmPA_SU_POLY_OFFSET_BACK_OFFSET = 0xA2E3; +constexpr unsigned int mmPA_SU_POLY_OFFSET_BACK_SCALE = 0xA2E2; +constexpr unsigned int mmPA_SU_POLY_OFFSET_CLAMP = 0xA2DF; +constexpr unsigned int mmPA_SU_POLY_OFFSET_DB_FMT_CNTL = 0xA2DE; +constexpr unsigned int mmPA_SU_POLY_OFFSET_FRONT_OFFSET = 0xA2E1; +constexpr unsigned int mmPA_SU_POLY_OFFSET_FRONT_SCALE = 0xA2E0; +constexpr unsigned int mmPA_SU_PRIM_FILTER_CNTL = 0xA20B; +constexpr unsigned int mmPA_SU_SC_MODE_CNTL = 0xA205; +constexpr unsigned int mmPA_SU_VTX_CNTL = 0xA2F9; +constexpr unsigned int mmPCIE_DATA_2__CI__VI = 0x000D; +constexpr unsigned int mmPCIE_DATA__CI__VI = 0x000F; +constexpr unsigned int mmPCIE_DATA__SI = 0x000D; +constexpr unsigned int mmPCIE_INDEX_2__CI__VI = 0x000C; +constexpr unsigned int mmPCIE_INDEX__CI__VI = 0x000E; +constexpr unsigned int mmPCIE_INDEX__SI = 0x000C; +constexpr unsigned int mmPEER0_FB_OFFSET_HI__CI__VI = 0x14F3; +constexpr unsigned int mmPEER0_FB_OFFSET_LO__CI__VI = 0x14F2; +constexpr unsigned int mmPEER1_FB_OFFSET_HI__CI__VI = 0x14F1; +constexpr unsigned int mmPEER1_FB_OFFSET_LO__CI__VI = 0x14F0; +constexpr unsigned int mmPEER2_FB_OFFSET_HI__CI__VI = 0x14EF; +constexpr unsigned int mmPEER2_FB_OFFSET_LO__CI__VI = 0x14EE; +constexpr unsigned int mmPEER3_FB_OFFSET_HI__CI__VI = 0x14ED; +constexpr unsigned int mmPEER3_FB_OFFSET_LO__CI__VI = 0x14EC; +constexpr unsigned int mmPEER_REG_RANGE0 = 0x153E; +constexpr unsigned int mmPEER_REG_RANGE1 = 0x153F; +constexpr unsigned int mmPHY_AUX_CNTL__SI = 0x1953; +constexpr unsigned int mmPIPE0_ARBITRATION_CONTROL3__SI = 0x02FC; +constexpr unsigned int mmPIPE1_ARBITRATION_CONTROL3__SI = 0x0300; +constexpr unsigned int mmPIPE2_ARBITRATION_CONTROL3__SI = 0x0304; +constexpr unsigned int mmPIPE3_ARBITRATION_CONTROL3__SI = 0x0308; +constexpr unsigned int mmPIPE4_ARBITRATION_CONTROL3__SI = 0x030C; +constexpr unsigned int mmPIPE5_ARBITRATION_CONTROL3__SI = 0x0310; +constexpr unsigned int mmPIXCLK1_RESYNC_CNTL__SI = 0x0126; +constexpr unsigned int mmPIXCLK2_RESYNC_CNTL__SI = 0x0127; +constexpr unsigned int mmPLL_TEST_CNTL__SI = 0x0199; +constexpr unsigned int mmRAS_BCI_SIGNATURE0 = 0x339E; +constexpr unsigned int mmRAS_BCI_SIGNATURE1 = 0x339F; +constexpr unsigned int mmRAS_CB_SIGNATURE0 = 0x339D; +constexpr unsigned int mmRAS_DB_SIGNATURE0 = 0x338B; +constexpr unsigned int mmRAS_IA_SIGNATURE0 = 0x3397; +constexpr unsigned int mmRAS_IA_SIGNATURE1 = 0x3398; +constexpr unsigned int mmRAS_PA_SIGNATURE0 = 0x338C; +constexpr unsigned int mmRAS_SC_SIGNATURE0 = 0x338F; +constexpr unsigned int mmRAS_SC_SIGNATURE1 = 0x3390; +constexpr unsigned int mmRAS_SC_SIGNATURE2 = 0x3391; +constexpr unsigned int mmRAS_SC_SIGNATURE3 = 0x3392; +constexpr unsigned int mmRAS_SC_SIGNATURE4 = 0x3393; +constexpr unsigned int mmRAS_SC_SIGNATURE5 = 0x3394; +constexpr unsigned int mmRAS_SC_SIGNATURE6 = 0x3395; +constexpr unsigned int mmRAS_SC_SIGNATURE7 = 0x3396; +constexpr unsigned int mmRAS_SIGNATURE_CONTROL = 0x3380; +constexpr unsigned int mmRAS_SIGNATURE_MASK = 0x3381; +constexpr unsigned int mmRAS_SPI_SIGNATURE0 = 0x3399; +constexpr unsigned int mmRAS_SPI_SIGNATURE1 = 0x339A; +constexpr unsigned int mmRAS_SQ_SIGNATURE0 = 0x338E; +constexpr unsigned int mmRAS_SX_SIGNATURE0 = 0x3382; +constexpr unsigned int mmRAS_SX_SIGNATURE1 = 0x3383; +constexpr unsigned int mmRAS_SX_SIGNATURE2 = 0x3384; +constexpr unsigned int mmRAS_SX_SIGNATURE3 = 0x3385; +constexpr unsigned int mmRAS_TA_SIGNATURE0 = 0x339B; +constexpr unsigned int mmRAS_TD_SIGNATURE0 = 0x339C; +constexpr unsigned int mmRAS_VGT_SIGNATURE0 = 0x338D; +constexpr unsigned int mmRCU_MISC_CTRL__SI = 0x0043; +constexpr unsigned int mmRCU_UC_EVENTS__SI = 0x0045; +constexpr unsigned int mmRLC_AUTO_PG_CTRL__CI = 0x3115; +constexpr unsigned int mmRLC_AUTO_PG_CTRL__SI = 0x310D; +constexpr unsigned int mmRLC_CAPTURE_GPU_CLOCK_COUNT__CI = 0x30E6; +constexpr unsigned int mmRLC_CAPTURE_GPU_CLOCK_COUNT__SI = 0x30D0; +constexpr unsigned int mmRLC_CGCG_CGLS_CTRL__CI = 0x3109; +constexpr unsigned int mmRLC_CGCG_CGLS_CTRL__SI = 0x3101; +constexpr unsigned int mmRLC_CGCG_RAMP_CTRL__CI = 0x310A; +constexpr unsigned int mmRLC_CGCG_RAMP_CTRL__SI = 0x3102; +constexpr unsigned int mmRLC_CGTT_MGCG_OVERRIDE__CI = 0x3108; +constexpr unsigned int mmRLC_CGTT_MGCG_OVERRIDE__SI = 0x3100; +constexpr unsigned int mmRLC_CU_STATUS__CI = 0x310E; +constexpr unsigned int mmRLC_CU_STATUS__SI = 0x3106; +constexpr unsigned int mmRLC_DEBUG_SELECT__CI = 0x30C1; +constexpr unsigned int mmRLC_DEBUG_SELECT__SI = 0x30C9; +constexpr unsigned int mmRLC_DEBUG__CI = 0x30C2; +constexpr unsigned int mmRLC_DEBUG__SI = 0x30CA; +constexpr unsigned int mmRLC_DRIVER_CPDMA_STATUS__CI = 0x30DE; +constexpr unsigned int mmRLC_DRIVER_CPDMA_STATUS__SI = 0x30C7; +constexpr unsigned int mmRLC_DYN_PG_REQUEST__CI = 0x310C; +constexpr unsigned int mmRLC_DYN_PG_REQUEST__SI = 0x3104; +constexpr unsigned int mmRLC_DYN_PG_STATUS__CI = 0x310B; +constexpr unsigned int mmRLC_DYN_PG_STATUS__SI = 0x3103; +constexpr unsigned int mmRLC_GPM_CU_PD_TIMEOUT__CI = 0x312B; +constexpr unsigned int mmRLC_GPM_DEBUG_SELECT__CI = 0x30E0; +constexpr unsigned int mmRLC_GPM_DEBUG__CI = 0x30E1; +constexpr unsigned int mmRLC_GPM_GENERAL_0__CI = 0x3123; +constexpr unsigned int mmRLC_GPM_GENERAL_1__CI = 0x3124; +constexpr unsigned int mmRLC_GPM_GENERAL_2__CI = 0x3125; +constexpr unsigned int mmRLC_GPM_GENERAL_3__CI = 0x3126; +constexpr unsigned int mmRLC_GPM_GENERAL_4__CI = 0x3127; +constexpr unsigned int mmRLC_GPM_GENERAL_5__CI = 0x3128; +constexpr unsigned int mmRLC_GPM_GENERAL_6__CI = 0x3129; +constexpr unsigned int mmRLC_GPM_GENERAL_7__CI = 0x312A; +constexpr unsigned int mmRLC_GPM_LOG_ADDR__CI = 0x3136; +constexpr unsigned int mmRLC_GPM_LOG_CONT__CI = 0x3138; +constexpr unsigned int mmRLC_GPM_LOG_SIZE__CI = 0x3137; +constexpr unsigned int mmRLC_GPM_PERF_COUNT_0__CI = 0x312F; +constexpr unsigned int mmRLC_GPM_PERF_COUNT_1__CI = 0x3130; +constexpr unsigned int mmRLC_GPM_SCRATCH_ADDR__CI = 0x312C; +constexpr unsigned int mmRLC_GPM_SCRATCH_DATA__CI = 0x312D; +constexpr unsigned int mmRLC_GPM_STAT__CI = 0x3100; +constexpr unsigned int mmRLC_GPM_THREAD_ENABLE__CI = 0x3105; +constexpr unsigned int mmRLC_GPM_THREAD_PRIORITY__CI = 0x3104; +constexpr unsigned int mmRLC_GPM_UCODE_ADDR__CI = 0x30E2; +constexpr unsigned int mmRLC_GPM_UCODE_DATA__CI = 0x30E3; +constexpr unsigned int mmRLC_GPM_VMID_THREAD0__CI = 0x3106; +constexpr unsigned int mmRLC_GPM_VMID_THREAD1__CI = 0x3107; +constexpr unsigned int mmRLC_GPR_REG1__CI = 0x3139; +constexpr unsigned int mmRLC_GPR_REG2__CI = 0x313A; +constexpr unsigned int mmRLC_GPU_CLOCK_32_RES_SEL__CI = 0x3101; +constexpr unsigned int mmRLC_GPU_CLOCK_32_RES_SEL__SI = 0x30D4; +constexpr unsigned int mmRLC_GPU_CLOCK_32__CI = 0x3102; +constexpr unsigned int mmRLC_GPU_CLOCK_32__SI = 0x30D5; +constexpr unsigned int mmRLC_GPU_CLOCK_COUNT_LSB__CI = 0x30E4; +constexpr unsigned int mmRLC_GPU_CLOCK_COUNT_LSB__SI = 0x30CE; +constexpr unsigned int mmRLC_GPU_CLOCK_COUNT_MSB__CI = 0x30E5; +constexpr unsigned int mmRLC_GPU_CLOCK_COUNT_MSB__SI = 0x30CF; +constexpr unsigned int mmRLC_JUMP_TABLE_RESTORE__CI = 0x30DE; +constexpr unsigned int mmRLC_LB_ALWAYS_ACTIVE_CU_MASK__CI = 0x3110; +constexpr unsigned int mmRLC_LB_ALWAYS_ACTIVE_CU_MASK__SI = 0x3108; +constexpr unsigned int mmRLC_LB_CNTL__CI = 0x30D9; +constexpr unsigned int mmRLC_LB_CNTL__SI = 0x30C3; +constexpr unsigned int mmRLC_LB_CNTR_INIT__CI = 0x30DB; +constexpr unsigned int mmRLC_LB_CNTR_INIT__SI = 0x30C6; +constexpr unsigned int mmRLC_LB_CNTR_MAX__CI = 0x30D2; +constexpr unsigned int mmRLC_LB_CNTR_MAX__SI = 0x30C5; +constexpr unsigned int mmRLC_LB_INIT_CU_MASK__CI = 0x310F; +constexpr unsigned int mmRLC_LB_INIT_CU_MASK__SI = 0x3107; +constexpr unsigned int mmRLC_LB_PARAMS__CI = 0x3111; +constexpr unsigned int mmRLC_LB_PARAMS__SI = 0x3109; +constexpr unsigned int mmRLC_LOAD_BALANCE_CNTR__CI = 0x30DC; +constexpr unsigned int mmRLC_LOAD_BALANCE_CNTR__SI = 0x30F6; +constexpr unsigned int mmRLC_MAX_PG_CU__CI = 0x3114; +constexpr unsigned int mmRLC_MAX_PG_CU__SI = 0x310C; +constexpr unsigned int mmRLC_MC_CNTL__CI = 0x30C3; +constexpr unsigned int mmRLC_MC_CNTL__SI = 0x30D1; +constexpr unsigned int mmRLC_MEM_SLP_CNTL__CI = 0x30C6; +constexpr unsigned int mmRLC_MEM_SLP_CNTL__SI = 0x30D8; +constexpr unsigned int mmRLC_PERFCOUNTER0_HI__CI__VI = 0xD481; +constexpr unsigned int mmRLC_PERFCOUNTER0_HI__SI = 0x30DC; +constexpr unsigned int mmRLC_PERFCOUNTER0_LO__CI__VI = 0xD480; +constexpr unsigned int mmRLC_PERFCOUNTER0_LO__SI = 0x30DB; +constexpr unsigned int mmRLC_PERFCOUNTER0_SELECT__CI__VI = 0xDCC1; +constexpr unsigned int mmRLC_PERFCOUNTER0_SELECT__SI = 0x30DA; +constexpr unsigned int mmRLC_PERFCOUNTER1_HI__CI__VI = 0xD483; +constexpr unsigned int mmRLC_PERFCOUNTER1_HI__SI = 0x30DF; +constexpr unsigned int mmRLC_PERFCOUNTER1_LO__CI__VI = 0xD482; +constexpr unsigned int mmRLC_PERFCOUNTER1_LO__SI = 0x30DE; +constexpr unsigned int mmRLC_PERFCOUNTER1_SELECT__CI__VI = 0xDCC2; +constexpr unsigned int mmRLC_PERFCOUNTER1_SELECT__SI = 0x30DD; +constexpr unsigned int mmRLC_PERFMON_CNTL__CI__VI = 0xDCC0; +constexpr unsigned int mmRLC_PERFMON_CNTL__SI = 0x30D9; +constexpr unsigned int mmRLC_PG_ALWAYS_ON_CU_MASK__CI = 0x3113; +constexpr unsigned int mmRLC_PG_ALWAYS_ON_CU_MASK__SI = 0x310B; +constexpr unsigned int mmRLC_PG_CNTL__CI = 0x3103; +constexpr unsigned int mmRLC_PG_CNTL__SI = 0x30D7; +constexpr unsigned int mmRLC_PG_DELAY_2__CI = 0x30DF; +constexpr unsigned int mmRLC_PG_DELAY__CI = 0x310D; +constexpr unsigned int mmRLC_SAFE_MODE__CI = 0x313A; +constexpr unsigned int mmRLC_SAVE_AND_RESTORE_BASE__CI = 0x30DD; +constexpr unsigned int mmRLC_SAVE_AND_RESTORE_BASE__SI = 0x30C4; +constexpr unsigned int mmRLC_SERDES_CU_MASTER_BUSY__CI = 0x3121; +constexpr unsigned int mmRLC_SERDES_NONCU_MASTER_BUSY__CI = 0x3122; +constexpr unsigned int mmRLC_SERDES_RD_DATA_0__CI = 0x311A; +constexpr unsigned int mmRLC_SERDES_RD_DATA_0__SI = 0x3112; +constexpr unsigned int mmRLC_SERDES_RD_DATA_1__CI = 0x311B; +constexpr unsigned int mmRLC_SERDES_RD_DATA_1__SI = 0x3113; +constexpr unsigned int mmRLC_SERDES_RD_DATA_2__CI = 0x311C; +constexpr unsigned int mmRLC_SERDES_RD_DATA_2__SI = 0x3114; +constexpr unsigned int mmRLC_SERDES_RD_MASTER_INDEX__CI = 0x3119; +constexpr unsigned int mmRLC_SERDES_RD_MASTER_INDEX__SI = 0x3111; +constexpr unsigned int mmRLC_SERDES_WR_CTRL__CI = 0x311F; +constexpr unsigned int mmRLC_SERDES_WR_CTRL__SI = 0x3117; +constexpr unsigned int mmRLC_SERDES_WR_CU_MASTER_MASK__CI = 0x311D; +constexpr unsigned int mmRLC_SERDES_WR_DATA__CI = 0x3120; +constexpr unsigned int mmRLC_SERDES_WR_DATA__SI = 0x3118; +constexpr unsigned int mmRLC_SERDES_WR_NONCU_MASTER_MASK__CI = 0x311E; +constexpr unsigned int mmRLC_SMU_GRBM_REG_SAVE_CTRL__CI = 0x3116; +constexpr unsigned int mmRLC_SMU_GRBM_REG_SAVE_CTRL__SI = 0x310E; +constexpr unsigned int mmRLC_SMU_PG_CTRL__CI = 0x3117; +constexpr unsigned int mmRLC_SMU_PG_CTRL__SI = 0x310F; +constexpr unsigned int mmRLC_SMU_PG_WAKE_UP_CTRL__CI = 0x3118; +constexpr unsigned int mmRLC_SMU_PG_WAKE_UP_CTRL__SI = 0x3110; +constexpr unsigned int mmRLC_SOFT_RESET_GPU__CI = 0x30C5; +constexpr unsigned int mmRLC_SOFT_RESET_GPU__SI = 0x30D6; +constexpr unsigned int mmRLC_SPM_CB_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC8A; +constexpr unsigned int mmRLC_SPM_CPC_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC88; +constexpr unsigned int mmRLC_SPM_CPF_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC89; +constexpr unsigned int mmRLC_SPM_CPG_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC87; +constexpr unsigned int mmRLC_SPM_DB_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC8B; +constexpr unsigned int mmRLC_SPM_DEBUG_SELECT__CI = 0x3134; +constexpr unsigned int mmRLC_SPM_DEBUG__CI = 0x3135; +constexpr unsigned int mmRLC_SPM_GDS_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC8D; +constexpr unsigned int mmRLC_SPM_GLOBAL_MUXSEL_ADDR__CI__VI = 0xDC9B; +constexpr unsigned int mmRLC_SPM_GLOBAL_MUXSEL_DATA__CI__VI = 0xDC9C; +constexpr unsigned int mmRLC_SPM_IA_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC8E; +constexpr unsigned int mmRLC_SPM_INT_CNTL__CI = 0x3132; +constexpr unsigned int mmRLC_SPM_INT_STATUS__CI = 0x3133; +constexpr unsigned int mmRLC_SPM_PA_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC8C; +constexpr unsigned int mmRLC_SPM_PERFMON_CNTL__CI__VI = 0xDC80; +constexpr unsigned int mmRLC_SPM_PERFMON_RING_BASE_HI__CI__VI = 0xDC82; +constexpr unsigned int mmRLC_SPM_PERFMON_RING_BASE_LO__CI__VI = 0xDC81; +constexpr unsigned int mmRLC_SPM_PERFMON_RING_SIZE__CI__VI = 0xDC83; +constexpr unsigned int mmRLC_SPM_PERFMON_SEGMENT_SIZE__CI__VI = 0xDC84; +constexpr unsigned int mmRLC_SPM_RING_RDPTR__CI__VI = 0xDC9D; +constexpr unsigned int mmRLC_SPM_SC_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC90; +constexpr unsigned int mmRLC_SPM_SEGMENT_THRESHOLD__CI__VI = 0xDC9E; +constexpr unsigned int mmRLC_SPM_SE_MUXSEL_ADDR__CI__VI = 0xDC85; +constexpr unsigned int mmRLC_SPM_SE_MUXSEL_DATA__CI__VI = 0xDC86; +constexpr unsigned int mmRLC_SPM_SPI_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC97; +constexpr unsigned int mmRLC_SPM_SQG_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC98; +constexpr unsigned int mmRLC_SPM_SX_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC9A; +constexpr unsigned int mmRLC_SPM_TA_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC94; +constexpr unsigned int mmRLC_SPM_TCA_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC92; +constexpr unsigned int mmRLC_SPM_TCC_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC91; +constexpr unsigned int mmRLC_SPM_TCP_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC93; +constexpr unsigned int mmRLC_SPM_TCS_PERFMON_SAMPLE_DELAY__CI = 0xDC99; +constexpr unsigned int mmRLC_SPM_TD_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC95; +constexpr unsigned int mmRLC_SPM_VGT_PERFMON_SAMPLE_DELAY__CI__VI = 0xDC96; +constexpr unsigned int mmRLC_SPM_VMID__CI = 0x3131; +constexpr unsigned int mmRLC_STATIC_PG_STATUS__CI = 0x312E; +constexpr unsigned int mmRLC_STAT__CI = 0x30C4; +constexpr unsigned int mmRLC_STAT__SI = 0x30D3; +constexpr unsigned int mmRLC_THREAD1_DELAY__CI = 0x3112; +constexpr unsigned int mmRLC_THREAD1_DELAY__SI = 0x310A; +constexpr unsigned int mmRLC_UCODE_CNTL__CI = 0x30E7; +constexpr unsigned int mmRLC_UCODE_CNTL__SI = 0x30D2; +constexpr unsigned int mmROM_CNTL__SI = 0x0580; +constexpr unsigned int mmROM_DATA__SI = 0x002B; +constexpr unsigned int mmROM_INDEX__SI = 0x002A; +constexpr unsigned int mmROM_SMC_IND_DATA__CI__VI = 0x0081; +constexpr unsigned int mmROM_SMC_IND_INDEX__CI__VI = 0x0080; +constexpr unsigned int mmROM_START__SI = 0x0585; +constexpr unsigned int mmROM_STATUS__SI = 0x0582; +constexpr unsigned int mmROM_SW_CNTL__SI = 0x0586; +constexpr unsigned int mmROM_SW_COMMAND__SI = 0x0588; +constexpr unsigned int mmROM_SW_DATA_10__SI = 0x0592; +constexpr unsigned int mmROM_SW_DATA_11__SI = 0x0593; +constexpr unsigned int mmROM_SW_DATA_12__SI = 0x0594; +constexpr unsigned int mmROM_SW_DATA_13__SI = 0x0595; +constexpr unsigned int mmROM_SW_DATA_14__SI = 0x0596; +constexpr unsigned int mmROM_SW_DATA_15__SI = 0x0597; +constexpr unsigned int mmROM_SW_DATA_16__SI = 0x0598; +constexpr unsigned int mmROM_SW_DATA_17__SI = 0x0599; +constexpr unsigned int mmROM_SW_DATA_18__SI = 0x059A; +constexpr unsigned int mmROM_SW_DATA_19__SI = 0x059B; +constexpr unsigned int mmROM_SW_DATA_1__SI = 0x0589; +constexpr unsigned int mmROM_SW_DATA_20__SI = 0x059C; +constexpr unsigned int mmROM_SW_DATA_21__SI = 0x059D; +constexpr unsigned int mmROM_SW_DATA_22__SI = 0x059E; +constexpr unsigned int mmROM_SW_DATA_23__SI = 0x059F; +constexpr unsigned int mmROM_SW_DATA_24__SI = 0x05A0; +constexpr unsigned int mmROM_SW_DATA_25__SI = 0x05A1; +constexpr unsigned int mmROM_SW_DATA_26__SI = 0x05A2; +constexpr unsigned int mmROM_SW_DATA_27__SI = 0x05A3; +constexpr unsigned int mmROM_SW_DATA_28__SI = 0x05A4; +constexpr unsigned int mmROM_SW_DATA_29__SI = 0x05A5; +constexpr unsigned int mmROM_SW_DATA_2__SI = 0x058A; +constexpr unsigned int mmROM_SW_DATA_30__SI = 0x05A6; +constexpr unsigned int mmROM_SW_DATA_31__SI = 0x05A7; +constexpr unsigned int mmROM_SW_DATA_32__SI = 0x05A8; +constexpr unsigned int mmROM_SW_DATA_33__SI = 0x05A9; +constexpr unsigned int mmROM_SW_DATA_34__SI = 0x05AA; +constexpr unsigned int mmROM_SW_DATA_35__SI = 0x05AB; +constexpr unsigned int mmROM_SW_DATA_36__SI = 0x05AC; +constexpr unsigned int mmROM_SW_DATA_37__SI = 0x05AD; +constexpr unsigned int mmROM_SW_DATA_38__SI = 0x05AE; +constexpr unsigned int mmROM_SW_DATA_39__SI = 0x05AF; +constexpr unsigned int mmROM_SW_DATA_3__SI = 0x058B; +constexpr unsigned int mmROM_SW_DATA_40__SI = 0x05B0; +constexpr unsigned int mmROM_SW_DATA_41__SI = 0x05B1; +constexpr unsigned int mmROM_SW_DATA_42__SI = 0x05B2; +constexpr unsigned int mmROM_SW_DATA_43__SI = 0x05B3; +constexpr unsigned int mmROM_SW_DATA_44__SI = 0x05B4; +constexpr unsigned int mmROM_SW_DATA_45__SI = 0x05B5; +constexpr unsigned int mmROM_SW_DATA_46__SI = 0x05B6; +constexpr unsigned int mmROM_SW_DATA_47__SI = 0x05B7; +constexpr unsigned int mmROM_SW_DATA_48__SI = 0x05B8; +constexpr unsigned int mmROM_SW_DATA_49__SI = 0x05B9; +constexpr unsigned int mmROM_SW_DATA_4__SI = 0x058C; +constexpr unsigned int mmROM_SW_DATA_50__SI = 0x05BA; +constexpr unsigned int mmROM_SW_DATA_51__SI = 0x05BB; +constexpr unsigned int mmROM_SW_DATA_52__SI = 0x05BC; +constexpr unsigned int mmROM_SW_DATA_53__SI = 0x05BD; +constexpr unsigned int mmROM_SW_DATA_54__SI = 0x05BE; +constexpr unsigned int mmROM_SW_DATA_55__SI = 0x05BF; +constexpr unsigned int mmROM_SW_DATA_56__SI = 0x05C0; +constexpr unsigned int mmROM_SW_DATA_57__SI = 0x05C1; +constexpr unsigned int mmROM_SW_DATA_58__SI = 0x05C2; +constexpr unsigned int mmROM_SW_DATA_59__SI = 0x05C3; +constexpr unsigned int mmROM_SW_DATA_5__SI = 0x058D; +constexpr unsigned int mmROM_SW_DATA_60__SI = 0x05C4; +constexpr unsigned int mmROM_SW_DATA_61__SI = 0x05C5; +constexpr unsigned int mmROM_SW_DATA_62__SI = 0x05C6; +constexpr unsigned int mmROM_SW_DATA_63__SI = 0x05C7; +constexpr unsigned int mmROM_SW_DATA_64__SI = 0x05C8; +constexpr unsigned int mmROM_SW_DATA_6__SI = 0x058E; +constexpr unsigned int mmROM_SW_DATA_7__SI = 0x058F; +constexpr unsigned int mmROM_SW_DATA_8__SI = 0x0590; +constexpr unsigned int mmROM_SW_DATA_9__SI = 0x0591; +constexpr unsigned int mmROM_SW_STATUS__SI = 0x0587; +constexpr unsigned int mmSCL0_EXT_OVERSCAN_LEFT_RIGHT__SI__VI = 0x1B5E; +constexpr unsigned int mmSCL0_EXT_OVERSCAN_TOP_BOTTOM__SI__VI = 0x1B5F; +constexpr unsigned int mmSCL0_SCL_ALU_CONTROL__SI__VI = 0x1B54; +constexpr unsigned int mmSCL0_SCL_AUTOMATIC_MODE_CONTROL__SI__VI = 0x1B47; +constexpr unsigned int mmSCL0_SCL_BYPASS_CONTROL__SI__VI = 0x1B45; +constexpr unsigned int mmSCL0_SCL_COEF_RAM_CONFLICT_STATUS__SI__VI = 0x1B55; +constexpr unsigned int mmSCL0_SCL_COEF_RAM_SELECT__SI__VI = 0x1B40; +constexpr unsigned int mmSCL0_SCL_COEF_RAM_TAP_DATA__SI__VI = 0x1B41; +constexpr unsigned int mmSCL0_SCL_CONTROL__SI__VI = 0x1B44; +constexpr unsigned int mmSCL0_SCL_DEBUG__SI__VI = 0x1B6A; +constexpr unsigned int mmSCL0_SCL_F_SHARP_CONTROL__SI__VI = 0x1B53; +constexpr unsigned int mmSCL0_SCL_HORZ_FILTER_CONTROL__SI = 0x1B4A; +constexpr unsigned int mmSCL0_SCL_HORZ_FILTER_SCALE_RATIO__SI = 0x1B4B; +constexpr unsigned int mmSCL0_SCL_MANUAL_REPLICATE_CONTROL__SI__VI = 0x1B46; +constexpr unsigned int mmSCL0_SCL_MODE_CHANGE_DET1__SI__VI = 0x1B60; +constexpr unsigned int mmSCL0_SCL_MODE_CHANGE_DET2__SI__VI = 0x1B61; +constexpr unsigned int mmSCL0_SCL_MODE_CHANGE_DET3__SI__VI = 0x1B62; +constexpr unsigned int mmSCL0_SCL_MODE_CHANGE_MASK__SI__VI = 0x1B63; +constexpr unsigned int mmSCL0_SCL_TAP_CONTROL__SI__VI = 0x1B43; +constexpr unsigned int mmSCL0_SCL_TEST_DEBUG_DATA__SI__VI = 0x1B6C; +constexpr unsigned int mmSCL0_SCL_TEST_DEBUG_INDEX__SI__VI = 0x1B6B; +constexpr unsigned int mmSCL0_SCL_UPDATE__SI__VI = 0x1B51; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_CONTROL__SI = 0x1B4E; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_INIT_BOT__SI = 0x1B57; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_INIT__SI = 0x1B50; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_SCALE_RATIO__SI = 0x1B4F; +constexpr unsigned int mmSCL0_VIEWPORT_SIZE__SI__VI = 0x1B5D; +constexpr unsigned int mmSCL0_VIEWPORT_START__SI__VI = 0x1B5C; +constexpr unsigned int mmSCL1_EXT_OVERSCAN_LEFT_RIGHT__SI = 0x1E5E; +constexpr unsigned int mmSCL1_EXT_OVERSCAN_TOP_BOTTOM__SI = 0x1E5F; +constexpr unsigned int mmSCL1_SCL_ALU_CONTROL__SI = 0x1E54; +constexpr unsigned int mmSCL1_SCL_AUTOMATIC_MODE_CONTROL__SI = 0x1E47; +constexpr unsigned int mmSCL1_SCL_BYPASS_CONTROL__SI = 0x1E45; +constexpr unsigned int mmSCL1_SCL_COEF_RAM_CONFLICT_STATUS__SI = 0x1E55; +constexpr unsigned int mmSCL1_SCL_COEF_RAM_SELECT__SI = 0x1E40; +constexpr unsigned int mmSCL1_SCL_COEF_RAM_TAP_DATA__SI = 0x1E41; +constexpr unsigned int mmSCL1_SCL_CONTROL__SI = 0x1E44; +constexpr unsigned int mmSCL1_SCL_DEBUG__SI = 0x1E6A; +constexpr unsigned int mmSCL1_SCL_F_SHARP_CONTROL__SI = 0x1E53; +constexpr unsigned int mmSCL1_SCL_HORZ_FILTER_CONTROL__SI = 0x1E4A; +constexpr unsigned int mmSCL1_SCL_HORZ_FILTER_SCALE_RATIO__SI = 0x1E4B; +constexpr unsigned int mmSCL1_SCL_MANUAL_REPLICATE_CONTROL__SI = 0x1E46; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_DET1__SI = 0x1E60; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_DET2__SI = 0x1E61; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_DET3__SI = 0x1E62; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_MASK__SI = 0x1E63; +constexpr unsigned int mmSCL1_SCL_TAP_CONTROL__SI = 0x1E43; +constexpr unsigned int mmSCL1_SCL_TEST_DEBUG_DATA__SI = 0x1E6C; +constexpr unsigned int mmSCL1_SCL_TEST_DEBUG_INDEX__SI = 0x1E6B; +constexpr unsigned int mmSCL1_SCL_UPDATE__SI = 0x1E51; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_CONTROL__SI = 0x1E4E; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_INIT_BOT__SI = 0x1E57; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_INIT__SI = 0x1E50; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_SCALE_RATIO__SI = 0x1E4F; +constexpr unsigned int mmSCL1_VIEWPORT_SIZE__SI = 0x1E5D; +constexpr unsigned int mmSCL1_VIEWPORT_START__SI = 0x1E5C; +constexpr unsigned int mmSCL2_EXT_OVERSCAN_LEFT_RIGHT__SI = 0x415E; +constexpr unsigned int mmSCL2_EXT_OVERSCAN_TOP_BOTTOM__SI = 0x415F; +constexpr unsigned int mmSCL2_SCL_ALU_CONTROL__SI = 0x4154; +constexpr unsigned int mmSCL2_SCL_AUTOMATIC_MODE_CONTROL__SI = 0x4147; +constexpr unsigned int mmSCL2_SCL_BYPASS_CONTROL__SI = 0x4145; +constexpr unsigned int mmSCL2_SCL_COEF_RAM_CONFLICT_STATUS__SI = 0x4155; +constexpr unsigned int mmSCL2_SCL_COEF_RAM_SELECT__SI = 0x4140; +constexpr unsigned int mmSCL2_SCL_COEF_RAM_TAP_DATA__SI = 0x4141; +constexpr unsigned int mmSCL2_SCL_CONTROL__SI = 0x4144; +constexpr unsigned int mmSCL2_SCL_DEBUG__SI = 0x416A; +constexpr unsigned int mmSCL2_SCL_F_SHARP_CONTROL__SI = 0x4153; +constexpr unsigned int mmSCL2_SCL_HORZ_FILTER_CONTROL__SI = 0x414A; +constexpr unsigned int mmSCL2_SCL_HORZ_FILTER_SCALE_RATIO__SI = 0x414B; +constexpr unsigned int mmSCL2_SCL_MANUAL_REPLICATE_CONTROL__SI = 0x4146; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_DET1__SI = 0x4160; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_DET2__SI = 0x4161; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_DET3__SI = 0x4162; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_MASK__SI = 0x4163; +constexpr unsigned int mmSCL2_SCL_TAP_CONTROL__SI = 0x4143; +constexpr unsigned int mmSCL2_SCL_TEST_DEBUG_DATA__SI = 0x416C; +constexpr unsigned int mmSCL2_SCL_TEST_DEBUG_INDEX__SI = 0x416B; +constexpr unsigned int mmSCL2_SCL_UPDATE__SI = 0x4151; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_CONTROL__SI = 0x414E; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_INIT_BOT__SI = 0x4157; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_INIT__SI = 0x4150; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_SCALE_RATIO__SI = 0x414F; +constexpr unsigned int mmSCL2_VIEWPORT_SIZE__SI = 0x415D; +constexpr unsigned int mmSCL2_VIEWPORT_START__SI = 0x415C; +constexpr unsigned int mmSCL3_EXT_OVERSCAN_LEFT_RIGHT__SI = 0x445E; +constexpr unsigned int mmSCL3_EXT_OVERSCAN_TOP_BOTTOM__SI = 0x445F; +constexpr unsigned int mmSCL3_SCL_ALU_CONTROL__SI = 0x4454; +constexpr unsigned int mmSCL3_SCL_AUTOMATIC_MODE_CONTROL__SI = 0x4447; +constexpr unsigned int mmSCL3_SCL_BYPASS_CONTROL__SI = 0x4445; +constexpr unsigned int mmSCL3_SCL_COEF_RAM_CONFLICT_STATUS__SI = 0x4455; +constexpr unsigned int mmSCL3_SCL_COEF_RAM_SELECT__SI = 0x4440; +constexpr unsigned int mmSCL3_SCL_COEF_RAM_TAP_DATA__SI = 0x4441; +constexpr unsigned int mmSCL3_SCL_CONTROL__SI = 0x4444; +constexpr unsigned int mmSCL3_SCL_DEBUG__SI = 0x446A; +constexpr unsigned int mmSCL3_SCL_F_SHARP_CONTROL__SI = 0x4453; +constexpr unsigned int mmSCL3_SCL_HORZ_FILTER_CONTROL__SI = 0x444A; +constexpr unsigned int mmSCL3_SCL_HORZ_FILTER_SCALE_RATIO__SI = 0x444B; +constexpr unsigned int mmSCL3_SCL_MANUAL_REPLICATE_CONTROL__SI = 0x4446; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_DET1__SI = 0x4460; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_DET2__SI = 0x4461; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_DET3__SI = 0x4462; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_MASK__SI = 0x4463; +constexpr unsigned int mmSCL3_SCL_TAP_CONTROL__SI = 0x4443; +constexpr unsigned int mmSCL3_SCL_TEST_DEBUG_DATA__SI = 0x446C; +constexpr unsigned int mmSCL3_SCL_TEST_DEBUG_INDEX__SI = 0x446B; +constexpr unsigned int mmSCL3_SCL_UPDATE__SI = 0x4451; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_CONTROL__SI = 0x444E; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_INIT_BOT__SI = 0x4457; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_INIT__SI = 0x4450; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_SCALE_RATIO__SI = 0x444F; +constexpr unsigned int mmSCL3_VIEWPORT_SIZE__SI = 0x445D; +constexpr unsigned int mmSCL3_VIEWPORT_START__SI = 0x445C; +constexpr unsigned int mmSCL4_EXT_OVERSCAN_LEFT_RIGHT__SI = 0x475E; +constexpr unsigned int mmSCL4_EXT_OVERSCAN_TOP_BOTTOM__SI = 0x475F; +constexpr unsigned int mmSCL4_SCL_ALU_CONTROL__SI = 0x4754; +constexpr unsigned int mmSCL4_SCL_AUTOMATIC_MODE_CONTROL__SI = 0x4747; +constexpr unsigned int mmSCL4_SCL_BYPASS_CONTROL__SI = 0x4745; +constexpr unsigned int mmSCL4_SCL_COEF_RAM_CONFLICT_STATUS__SI = 0x4755; +constexpr unsigned int mmSCL4_SCL_COEF_RAM_SELECT__SI = 0x4740; +constexpr unsigned int mmSCL4_SCL_COEF_RAM_TAP_DATA__SI = 0x4741; +constexpr unsigned int mmSCL4_SCL_CONTROL__SI = 0x4744; +constexpr unsigned int mmSCL4_SCL_DEBUG__SI = 0x476A; +constexpr unsigned int mmSCL4_SCL_F_SHARP_CONTROL__SI = 0x4753; +constexpr unsigned int mmSCL4_SCL_HORZ_FILTER_CONTROL__SI = 0x474A; +constexpr unsigned int mmSCL4_SCL_HORZ_FILTER_SCALE_RATIO__SI = 0x474B; +constexpr unsigned int mmSCL4_SCL_MANUAL_REPLICATE_CONTROL__SI = 0x4746; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_DET1__SI = 0x4760; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_DET2__SI = 0x4761; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_DET3__SI = 0x4762; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_MASK__SI = 0x4763; +constexpr unsigned int mmSCL4_SCL_TAP_CONTROL__SI = 0x4743; +constexpr unsigned int mmSCL4_SCL_TEST_DEBUG_DATA__SI = 0x476C; +constexpr unsigned int mmSCL4_SCL_TEST_DEBUG_INDEX__SI = 0x476B; +constexpr unsigned int mmSCL4_SCL_UPDATE__SI = 0x4751; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_CONTROL__SI = 0x474E; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_INIT_BOT__SI = 0x4757; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_INIT__SI = 0x4750; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_SCALE_RATIO__SI = 0x474F; +constexpr unsigned int mmSCL4_VIEWPORT_SIZE__SI = 0x475D; +constexpr unsigned int mmSCL4_VIEWPORT_START__SI = 0x475C; +constexpr unsigned int mmSCL5_EXT_OVERSCAN_LEFT_RIGHT__SI = 0x4A5E; +constexpr unsigned int mmSCL5_EXT_OVERSCAN_TOP_BOTTOM__SI = 0x4A5F; +constexpr unsigned int mmSCL5_SCL_ALU_CONTROL__SI = 0x4A54; +constexpr unsigned int mmSCL5_SCL_AUTOMATIC_MODE_CONTROL__SI = 0x4A47; +constexpr unsigned int mmSCL5_SCL_BYPASS_CONTROL__SI = 0x4A45; +constexpr unsigned int mmSCL5_SCL_COEF_RAM_CONFLICT_STATUS__SI = 0x4A55; +constexpr unsigned int mmSCL5_SCL_COEF_RAM_SELECT__SI = 0x4A40; +constexpr unsigned int mmSCL5_SCL_COEF_RAM_TAP_DATA__SI = 0x4A41; +constexpr unsigned int mmSCL5_SCL_CONTROL__SI = 0x4A44; +constexpr unsigned int mmSCL5_SCL_DEBUG__SI = 0x4A6A; +constexpr unsigned int mmSCL5_SCL_F_SHARP_CONTROL__SI = 0x4A53; +constexpr unsigned int mmSCL5_SCL_HORZ_FILTER_CONTROL__SI = 0x4A4A; +constexpr unsigned int mmSCL5_SCL_HORZ_FILTER_SCALE_RATIO__SI = 0x4A4B; +constexpr unsigned int mmSCL5_SCL_MANUAL_REPLICATE_CONTROL__SI = 0x4A46; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_DET1__SI = 0x4A60; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_DET2__SI = 0x4A61; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_DET3__SI = 0x4A62; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_MASK__SI = 0x4A63; +constexpr unsigned int mmSCL5_SCL_TAP_CONTROL__SI = 0x4A43; +constexpr unsigned int mmSCL5_SCL_TEST_DEBUG_DATA__SI = 0x4A6C; +constexpr unsigned int mmSCL5_SCL_TEST_DEBUG_INDEX__SI = 0x4A6B; +constexpr unsigned int mmSCL5_SCL_UPDATE__SI = 0x4A51; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_CONTROL__SI = 0x4A4E; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_INIT_BOT__SI = 0x4A57; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_INIT__SI = 0x4A50; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_SCALE_RATIO__SI = 0x4A4F; +constexpr unsigned int mmSCL5_VIEWPORT_SIZE__SI = 0x4A5D; +constexpr unsigned int mmSCL5_VIEWPORT_START__SI = 0x4A5C; +constexpr unsigned int mmSCLK_CGTT_BLK_CTRL_REG__SI = 0x0129; +constexpr unsigned int mmSCLK_PWRMGT_CNTL__SI = 0x01E2; +constexpr unsigned int mmSCL_ALU_CONTROL__SI__VI = 0x1B54; +constexpr unsigned int mmSCL_AUTOMATIC_MODE_CONTROL__SI__VI = 0x1B47; +constexpr unsigned int mmSCL_BYPASS_CONTROL__SI__VI = 0x1B45; +constexpr unsigned int mmSCL_COEF_RAM_CONFLICT_STATUS__SI__VI = 0x1B55; +constexpr unsigned int mmSCL_COEF_RAM_SELECT__SI__VI = 0x1B40; +constexpr unsigned int mmSCL_COEF_RAM_TAP_DATA__SI__VI = 0x1B41; +constexpr unsigned int mmSCL_CONTROL__SI__VI = 0x1B44; +constexpr unsigned int mmSCL_DEBUG__SI__VI = 0x1B6A; +constexpr unsigned int mmSCL_F_SHARP_CONTROL__SI__VI = 0x1B53; +constexpr unsigned int mmSCL_HORZ_FILTER_CONTROL__SI = 0x1B4A; +constexpr unsigned int mmSCL_HORZ_FILTER_SCALE_RATIO__SI = 0x1B4B; +constexpr unsigned int mmSCL_MANUAL_REPLICATE_CONTROL__SI__VI = 0x1B46; +constexpr unsigned int mmSCL_MODE_CHANGE_DET1__SI__VI = 0x1B60; +constexpr unsigned int mmSCL_MODE_CHANGE_DET2__SI__VI = 0x1B61; +constexpr unsigned int mmSCL_MODE_CHANGE_DET3__SI__VI = 0x1B62; +constexpr unsigned int mmSCL_MODE_CHANGE_MASK__SI__VI = 0x1B63; +constexpr unsigned int mmSCL_TAP_CONTROL__SI__VI = 0x1B43; +constexpr unsigned int mmSCL_TEST_DEBUG_DATA__SI__VI = 0x1B6C; +constexpr unsigned int mmSCL_TEST_DEBUG_INDEX__SI__VI = 0x1B6B; +constexpr unsigned int mmSCL_UPDATE__SI__VI = 0x1B51; +constexpr unsigned int mmSCL_VERT_FILTER_CONTROL__SI = 0x1B4E; +constexpr unsigned int mmSCL_VERT_FILTER_INIT_BOT__SI = 0x1B57; +constexpr unsigned int mmSCL_VERT_FILTER_INIT__SI = 0x1B50; +constexpr unsigned int mmSCL_VERT_FILTER_SCALE_RATIO__SI = 0x1B4F; +constexpr unsigned int mmSCRATCH_ADDR__CI__VI = 0xC051; +constexpr unsigned int mmSCRATCH_ADDR__SI = 0x2151; +constexpr unsigned int mmSCRATCH_REG0__CI__VI = 0xC040; +constexpr unsigned int mmSCRATCH_REG0__SI = 0x2140; +constexpr unsigned int mmSCRATCH_REG1__CI__VI = 0xC041; +constexpr unsigned int mmSCRATCH_REG1__SI = 0x2141; +constexpr unsigned int mmSCRATCH_REG2__CI__VI = 0xC042; +constexpr unsigned int mmSCRATCH_REG2__SI = 0x2142; +constexpr unsigned int mmSCRATCH_REG3__CI__VI = 0xC043; +constexpr unsigned int mmSCRATCH_REG3__SI = 0x2143; +constexpr unsigned int mmSCRATCH_REG4__CI__VI = 0xC044; +constexpr unsigned int mmSCRATCH_REG4__SI = 0x2144; +constexpr unsigned int mmSCRATCH_REG5__CI__VI = 0xC045; +constexpr unsigned int mmSCRATCH_REG5__SI = 0x2145; +constexpr unsigned int mmSCRATCH_REG6__CI__VI = 0xC046; +constexpr unsigned int mmSCRATCH_REG6__SI = 0x2146; +constexpr unsigned int mmSCRATCH_REG7__CI__VI = 0xC047; +constexpr unsigned int mmSCRATCH_REG7__SI = 0x2147; +constexpr unsigned int mmSCRATCH_UMSK__CI__VI = 0xC050; +constexpr unsigned int mmSCRATCH_UMSK__SI = 0x2150; +constexpr unsigned int mmSDMA0_CHICKEN_BITS__CI__VI = 0x3405; +constexpr unsigned int mmSDMA0_CLK_CTRL__CI__VI = 0x3403; +constexpr unsigned int mmSDMA0_CNTL__CI__VI = 0x3404; +constexpr unsigned int mmSDMA0_F32_CNTL__CI__VI = 0x3412; +constexpr unsigned int mmSDMA0_FREEZE__CI__VI = 0x3413; +constexpr unsigned int mmSDMA0_GFX_APE1_CNTL__CI__VI = 0x34A8; +constexpr unsigned int mmSDMA0_GFX_CONTEXT_CNTL__CI__VI = 0x3493; +constexpr unsigned int mmSDMA0_GFX_CONTEXT_STATUS__CI__VI = 0x3491; +constexpr unsigned int mmSDMA0_GFX_IB_BASE_HI__CI__VI = 0x348E; +constexpr unsigned int mmSDMA0_GFX_IB_BASE_LO__CI__VI = 0x348D; +constexpr unsigned int mmSDMA0_GFX_IB_CNTL__CI__VI = 0x348A; +constexpr unsigned int mmSDMA0_GFX_IB_OFFSET__CI__VI = 0x348C; +constexpr unsigned int mmSDMA0_GFX_IB_RPTR__CI__VI = 0x348B; +constexpr unsigned int mmSDMA0_GFX_IB_SIZE__CI__VI = 0x348F; +constexpr unsigned int mmSDMA0_GFX_RB_BASE_HI__CI__VI = 0x3482; +constexpr unsigned int mmSDMA0_GFX_RB_BASE__CI__VI = 0x3481; +constexpr unsigned int mmSDMA0_GFX_RB_CNTL__CI__VI = 0x3480; +constexpr unsigned int mmSDMA0_GFX_RB_RPTR_ADDR_HI__CI__VI = 0x3488; +constexpr unsigned int mmSDMA0_GFX_RB_RPTR_ADDR_LO__CI__VI = 0x3489; +constexpr unsigned int mmSDMA0_GFX_RB_RPTR__CI__VI = 0x3483; +constexpr unsigned int mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI__CI__VI = 0x3486; +constexpr unsigned int mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO__CI__VI = 0x3487; +constexpr unsigned int mmSDMA0_GFX_RB_WPTR_POLL_CNTL__CI__VI = 0x3485; +constexpr unsigned int mmSDMA0_GFX_RB_WPTR__CI__VI = 0x3484; +constexpr unsigned int mmSDMA0_GFX_SKIP_CNTL__CI__VI = 0x3490; +constexpr unsigned int mmSDMA0_GFX_VIRTUAL_ADDR__CI__VI = 0x34A7; +constexpr unsigned int mmSDMA0_HASH__CI__VI = 0x3407; +constexpr unsigned int mmSDMA0_IB_OFFSET_FETCH__CI__VI = 0x340B; +constexpr unsigned int mmSDMA0_PERFCOUNTER0_RESULT__CI = 0x3410; +constexpr unsigned int mmSDMA0_PERFCOUNTER1_RESULT__CI = 0x3411; +constexpr unsigned int mmSDMA0_PERFMON_CNTL__CI = 0x340F; +constexpr unsigned int mmSDMA0_PHASE0_QUANTUM__CI__VI = 0x3414; +constexpr unsigned int mmSDMA0_PHASE1_QUANTUM__CI__VI = 0x3415; +constexpr unsigned int mmSDMA0_POWER_CNTL__CI__VI = 0x3402; +constexpr unsigned int mmSDMA0_PROGRAM__CI__VI = 0x340C; +constexpr unsigned int mmSDMA0_RB_RPTR_FETCH__CI__VI = 0x340A; +constexpr unsigned int mmSDMA0_RLC0_APE1_CNTL__CI__VI = 0x3528; +constexpr unsigned int mmSDMA0_RLC0_CONTEXT_STATUS__CI__VI = 0x3511; +constexpr unsigned int mmSDMA0_RLC0_DOORBELL_LOG__CI__VI = 0x3529; +constexpr unsigned int mmSDMA0_RLC0_DOORBELL__CI__VI = 0x3512; +constexpr unsigned int mmSDMA0_RLC0_IB_BASE_HI__CI__VI = 0x350E; +constexpr unsigned int mmSDMA0_RLC0_IB_BASE_LO__CI__VI = 0x350D; +constexpr unsigned int mmSDMA0_RLC0_IB_CNTL__CI__VI = 0x350A; +constexpr unsigned int mmSDMA0_RLC0_IB_OFFSET__CI__VI = 0x350C; +constexpr unsigned int mmSDMA0_RLC0_IB_RPTR__CI__VI = 0x350B; +constexpr unsigned int mmSDMA0_RLC0_IB_SIZE__CI__VI = 0x350F; +constexpr unsigned int mmSDMA0_RLC0_RB_BASE_HI__CI__VI = 0x3502; +constexpr unsigned int mmSDMA0_RLC0_RB_BASE__CI__VI = 0x3501; +constexpr unsigned int mmSDMA0_RLC0_RB_CNTL__CI__VI = 0x3500; +constexpr unsigned int mmSDMA0_RLC0_RB_RPTR_ADDR_HI__CI__VI = 0x3508; +constexpr unsigned int mmSDMA0_RLC0_RB_RPTR_ADDR_LO__CI__VI = 0x3509; +constexpr unsigned int mmSDMA0_RLC0_RB_RPTR__CI__VI = 0x3503; +constexpr unsigned int mmSDMA0_RLC0_RB_WPTR_POLL_ADDR_HI__CI__VI = 0x3506; +constexpr unsigned int mmSDMA0_RLC0_RB_WPTR_POLL_ADDR_LO__CI__VI = 0x3507; +constexpr unsigned int mmSDMA0_RLC0_RB_WPTR_POLL_CNTL__CI__VI = 0x3505; +constexpr unsigned int mmSDMA0_RLC0_RB_WPTR__CI__VI = 0x3504; +constexpr unsigned int mmSDMA0_RLC0_SKIP_CNTL__CI__VI = 0x3510; +constexpr unsigned int mmSDMA0_RLC0_VIRTUAL_ADDR__CI__VI = 0x3527; +constexpr unsigned int mmSDMA0_RLC1_APE1_CNTL__CI__VI = 0x35A8; +constexpr unsigned int mmSDMA0_RLC1_CONTEXT_STATUS__CI__VI = 0x3591; +constexpr unsigned int mmSDMA0_RLC1_DOORBELL_LOG__CI__VI = 0x35A9; +constexpr unsigned int mmSDMA0_RLC1_DOORBELL__CI__VI = 0x3592; +constexpr unsigned int mmSDMA0_RLC1_IB_BASE_HI__CI__VI = 0x358E; +constexpr unsigned int mmSDMA0_RLC1_IB_BASE_LO__CI__VI = 0x358D; +constexpr unsigned int mmSDMA0_RLC1_IB_CNTL__CI__VI = 0x358A; +constexpr unsigned int mmSDMA0_RLC1_IB_OFFSET__CI__VI = 0x358C; +constexpr unsigned int mmSDMA0_RLC1_IB_RPTR__CI__VI = 0x358B; +constexpr unsigned int mmSDMA0_RLC1_IB_SIZE__CI__VI = 0x358F; +constexpr unsigned int mmSDMA0_RLC1_RB_BASE_HI__CI__VI = 0x3582; +constexpr unsigned int mmSDMA0_RLC1_RB_BASE__CI__VI = 0x3581; +constexpr unsigned int mmSDMA0_RLC1_RB_CNTL__CI__VI = 0x3580; +constexpr unsigned int mmSDMA0_RLC1_RB_RPTR_ADDR_HI__CI__VI = 0x3588; +constexpr unsigned int mmSDMA0_RLC1_RB_RPTR_ADDR_LO__CI__VI = 0x3589; +constexpr unsigned int mmSDMA0_RLC1_RB_RPTR__CI__VI = 0x3583; +constexpr unsigned int mmSDMA0_RLC1_RB_WPTR_POLL_ADDR_HI__CI__VI = 0x3586; +constexpr unsigned int mmSDMA0_RLC1_RB_WPTR_POLL_ADDR_LO__CI__VI = 0x3587; +constexpr unsigned int mmSDMA0_RLC1_RB_WPTR_POLL_CNTL__CI__VI = 0x3585; +constexpr unsigned int mmSDMA0_RLC1_RB_WPTR__CI__VI = 0x3584; +constexpr unsigned int mmSDMA0_RLC1_SKIP_CNTL__CI__VI = 0x3590; +constexpr unsigned int mmSDMA0_RLC1_VIRTUAL_ADDR__CI__VI = 0x35A7; +constexpr unsigned int mmSDMA0_SEM_INCOMPLETE_TIMER_CNTL__CI = 0x3408; +constexpr unsigned int mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL__CI__VI = 0x3409; +constexpr unsigned int mmSDMA0_STATUS1_REG__CI__VI = 0x340E; +constexpr unsigned int mmSDMA0_STATUS_REG__CI__VI = 0x340D; +constexpr unsigned int mmSDMA0_TILING_CONFIG__CI__VI = 0x3406; +constexpr unsigned int mmSDMA0_UCODE_ADDR__CI__VI = 0x3400; +constexpr unsigned int mmSDMA0_UCODE_DATA__CI__VI = 0x3401; +constexpr unsigned int mmSDMA1_CHICKEN_BITS__CI__VI = 0x3605; +constexpr unsigned int mmSDMA1_CLK_CTRL__CI__VI = 0x3603; +constexpr unsigned int mmSDMA1_CNTL__CI__VI = 0x3604; +constexpr unsigned int mmSDMA1_CONFIG__CI__VI = 0x0F92; +constexpr unsigned int mmSDMA1_F32_CNTL__CI__VI = 0x3612; +constexpr unsigned int mmSDMA1_FREEZE__CI__VI = 0x3613; +constexpr unsigned int mmSDMA1_GFX_APE1_CNTL__CI__VI = 0x36A8; +constexpr unsigned int mmSDMA1_GFX_CONTEXT_CNTL__CI__VI = 0x3693; +constexpr unsigned int mmSDMA1_GFX_CONTEXT_STATUS__CI__VI = 0x3691; +constexpr unsigned int mmSDMA1_GFX_IB_BASE_HI__CI__VI = 0x368E; +constexpr unsigned int mmSDMA1_GFX_IB_BASE_LO__CI__VI = 0x368D; +constexpr unsigned int mmSDMA1_GFX_IB_CNTL__CI__VI = 0x368A; +constexpr unsigned int mmSDMA1_GFX_IB_OFFSET__CI__VI = 0x368C; +constexpr unsigned int mmSDMA1_GFX_IB_RPTR__CI__VI = 0x368B; +constexpr unsigned int mmSDMA1_GFX_IB_SIZE__CI__VI = 0x368F; +constexpr unsigned int mmSDMA1_GFX_RB_BASE_HI__CI__VI = 0x3682; +constexpr unsigned int mmSDMA1_GFX_RB_BASE__CI__VI = 0x3681; +constexpr unsigned int mmSDMA1_GFX_RB_CNTL__CI__VI = 0x3680; +constexpr unsigned int mmSDMA1_GFX_RB_RPTR_ADDR_HI__CI__VI = 0x3688; +constexpr unsigned int mmSDMA1_GFX_RB_RPTR_ADDR_LO__CI__VI = 0x3689; +constexpr unsigned int mmSDMA1_GFX_RB_RPTR__CI__VI = 0x3683; +constexpr unsigned int mmSDMA1_GFX_RB_WPTR_POLL_ADDR_HI__CI__VI = 0x3686; +constexpr unsigned int mmSDMA1_GFX_RB_WPTR_POLL_ADDR_LO__CI__VI = 0x3687; +constexpr unsigned int mmSDMA1_GFX_RB_WPTR_POLL_CNTL__CI__VI = 0x3685; +constexpr unsigned int mmSDMA1_GFX_RB_WPTR__CI__VI = 0x3684; +constexpr unsigned int mmSDMA1_GFX_SKIP_CNTL__CI__VI = 0x3690; +constexpr unsigned int mmSDMA1_GFX_VIRTUAL_ADDR__CI__VI = 0x36A7; +constexpr unsigned int mmSDMA1_HASH__CI__VI = 0x3607; +constexpr unsigned int mmSDMA1_IB_OFFSET_FETCH__CI__VI = 0x360B; +constexpr unsigned int mmSDMA1_PERFCOUNTER0_RESULT__CI = 0x3610; +constexpr unsigned int mmSDMA1_PERFCOUNTER1_RESULT__CI = 0x3611; +constexpr unsigned int mmSDMA1_PERFMON_CNTL__CI = 0x360F; +constexpr unsigned int mmSDMA1_PHASE0_QUANTUM__CI__VI = 0x3614; +constexpr unsigned int mmSDMA1_PHASE1_QUANTUM__CI__VI = 0x3615; +constexpr unsigned int mmSDMA1_POWER_CNTL__CI__VI = 0x3602; +constexpr unsigned int mmSDMA1_PROGRAM__CI__VI = 0x360C; +constexpr unsigned int mmSDMA1_RB_RPTR_FETCH__CI__VI = 0x360A; +constexpr unsigned int mmSDMA1_RLC0_APE1_CNTL__CI__VI = 0x3728; +constexpr unsigned int mmSDMA1_RLC0_CONTEXT_STATUS__CI__VI = 0x3711; +constexpr unsigned int mmSDMA1_RLC0_DOORBELL_LOG__CI__VI = 0x3729; +constexpr unsigned int mmSDMA1_RLC0_DOORBELL__CI__VI = 0x3712; +constexpr unsigned int mmSDMA1_RLC0_IB_BASE_HI__CI__VI = 0x370E; +constexpr unsigned int mmSDMA1_RLC0_IB_BASE_LO__CI__VI = 0x370D; +constexpr unsigned int mmSDMA1_RLC0_IB_CNTL__CI__VI = 0x370A; +constexpr unsigned int mmSDMA1_RLC0_IB_OFFSET__CI__VI = 0x370C; +constexpr unsigned int mmSDMA1_RLC0_IB_RPTR__CI__VI = 0x370B; +constexpr unsigned int mmSDMA1_RLC0_IB_SIZE__CI__VI = 0x370F; +constexpr unsigned int mmSDMA1_RLC0_RB_BASE_HI__CI__VI = 0x3702; +constexpr unsigned int mmSDMA1_RLC0_RB_BASE__CI__VI = 0x3701; +constexpr unsigned int mmSDMA1_RLC0_RB_CNTL__CI__VI = 0x3700; +constexpr unsigned int mmSDMA1_RLC0_RB_RPTR_ADDR_HI__CI__VI = 0x3708; +constexpr unsigned int mmSDMA1_RLC0_RB_RPTR_ADDR_LO__CI__VI = 0x3709; +constexpr unsigned int mmSDMA1_RLC0_RB_RPTR__CI__VI = 0x3703; +constexpr unsigned int mmSDMA1_RLC0_RB_WPTR_POLL_ADDR_HI__CI__VI = 0x3706; +constexpr unsigned int mmSDMA1_RLC0_RB_WPTR_POLL_ADDR_LO__CI__VI = 0x3707; +constexpr unsigned int mmSDMA1_RLC0_RB_WPTR_POLL_CNTL__CI__VI = 0x3705; +constexpr unsigned int mmSDMA1_RLC0_RB_WPTR__CI__VI = 0x3704; +constexpr unsigned int mmSDMA1_RLC0_SKIP_CNTL__CI__VI = 0x3710; +constexpr unsigned int mmSDMA1_RLC0_VIRTUAL_ADDR__CI__VI = 0x3727; +constexpr unsigned int mmSDMA1_RLC1_APE1_CNTL__CI__VI = 0x37A8; +constexpr unsigned int mmSDMA1_RLC1_CONTEXT_STATUS__CI__VI = 0x3791; +constexpr unsigned int mmSDMA1_RLC1_DOORBELL_LOG__CI__VI = 0x37A9; +constexpr unsigned int mmSDMA1_RLC1_DOORBELL__CI__VI = 0x3792; +constexpr unsigned int mmSDMA1_RLC1_IB_BASE_HI__CI__VI = 0x378E; +constexpr unsigned int mmSDMA1_RLC1_IB_BASE_LO__CI__VI = 0x378D; +constexpr unsigned int mmSDMA1_RLC1_IB_CNTL__CI__VI = 0x378A; +constexpr unsigned int mmSDMA1_RLC1_IB_OFFSET__CI__VI = 0x378C; +constexpr unsigned int mmSDMA1_RLC1_IB_RPTR__CI__VI = 0x378B; +constexpr unsigned int mmSDMA1_RLC1_IB_SIZE__CI__VI = 0x378F; +constexpr unsigned int mmSDMA1_RLC1_RB_BASE_HI__CI__VI = 0x3782; +constexpr unsigned int mmSDMA1_RLC1_RB_BASE__CI__VI = 0x3781; +constexpr unsigned int mmSDMA1_RLC1_RB_CNTL__CI__VI = 0x3780; +constexpr unsigned int mmSDMA1_RLC1_RB_RPTR_ADDR_HI__CI__VI = 0x3788; +constexpr unsigned int mmSDMA1_RLC1_RB_RPTR_ADDR_LO__CI__VI = 0x3789; +constexpr unsigned int mmSDMA1_RLC1_RB_RPTR__CI__VI = 0x3783; +constexpr unsigned int mmSDMA1_RLC1_RB_WPTR_POLL_ADDR_HI__CI__VI = 0x3786; +constexpr unsigned int mmSDMA1_RLC1_RB_WPTR_POLL_ADDR_LO__CI__VI = 0x3787; +constexpr unsigned int mmSDMA1_RLC1_RB_WPTR_POLL_CNTL__CI__VI = 0x3785; +constexpr unsigned int mmSDMA1_RLC1_RB_WPTR__CI__VI = 0x3784; +constexpr unsigned int mmSDMA1_RLC1_SKIP_CNTL__CI__VI = 0x3790; +constexpr unsigned int mmSDMA1_RLC1_VIRTUAL_ADDR__CI__VI = 0x37A7; +constexpr unsigned int mmSDMA1_SEM_INCOMPLETE_TIMER_CNTL__CI = 0x3608; +constexpr unsigned int mmSDMA1_SEM_WAIT_FAIL_TIMER_CNTL__CI__VI = 0x3609; +constexpr unsigned int mmSDMA1_STATUS1_REG__CI__VI = 0x360E; +constexpr unsigned int mmSDMA1_STATUS_REG__CI__VI = 0x360D; +constexpr unsigned int mmSDMA1_TILING_CONFIG__CI__VI = 0x3606; +constexpr unsigned int mmSDMA1_UCODE_ADDR__CI__VI = 0x3600; +constexpr unsigned int mmSDMA1_UCODE_DATA__CI__VI = 0x3601; +constexpr unsigned int mmSDMA_CONFIG__CI__VI = 0x0F91; +constexpr unsigned int mmSDMA_PGFSM_CONFIG__CI__VI = 0x3417; +constexpr unsigned int mmSDMA_PGFSM_READ__CI__VI = 0x3419; +constexpr unsigned int mmSDMA_PGFSM_WRITE__CI__VI = 0x3418; +constexpr unsigned int mmSDMA_POWER_GATING__CI__VI = 0x3416; +constexpr unsigned int mmSEM_CHICKEN_BITS__CI__VI = 0x0F9E; +constexpr unsigned int mmSEM_EDC_CONFIG__CI__VI = 0x0F9A; +constexpr unsigned int mmSEM_MAILBOX_CLIENTCONFIG__CI__VI = 0x0F9B; +constexpr unsigned int mmSEM_MAILBOX_CLIENTCONFIG__SI = 0x0F9A; +constexpr unsigned int mmSEM_MAILBOX_CONTROL__CI__VI = 0x0F9D; +constexpr unsigned int mmSEM_MAILBOX_CONTROL__SI = 0x0F9C; +constexpr unsigned int mmSEM_MAILBOX__CI__VI = 0x0F9C; +constexpr unsigned int mmSEM_MAILBOX__SI = 0x0F9B; +constexpr unsigned int mmSEM_MCIF_CONFIG = 0x0F90; +constexpr unsigned int mmSEM_STATUS__CI__VI = 0x0F99; +constexpr unsigned int mmSEQ8_DATA__SI__VI = 0x00F1; +constexpr unsigned int mmSEQ8_IDX__SI__VI = 0x00F1; +constexpr unsigned int mmSH_HIDDEN_PRIVATE_BASE_VMID__CI__VI = 0x2580; +constexpr unsigned int mmSH_MEM_APE1_BASE__CI__VI = 0x230B; +constexpr unsigned int mmSH_MEM_APE1_LIMIT__CI__VI = 0x230C; +constexpr unsigned int mmSH_MEM_BASES__CI__VI = 0x230A; +constexpr unsigned int mmSH_MEM_CONFIG__CI__VI = 0x230D; +constexpr unsigned int mmSH_STATIC_MEM_CONFIG__CI__VI = 0x2581; +constexpr unsigned int mmSLAVE_COMM_CMD_REG__SI__VI = 0x1624; +constexpr unsigned int mmSLAVE_COMM_CNTL_REG__SI__VI = 0x1625; +constexpr unsigned int mmSLAVE_COMM_DATA_REG1__SI__VI = 0x1621; +constexpr unsigned int mmSLAVE_COMM_DATA_REG2__SI__VI = 0x1622; +constexpr unsigned int mmSLAVE_COMM_DATA_REG3__SI__VI = 0x1623; +constexpr unsigned int mmSLAVE_HANG_ERROR = 0x153B; +constexpr unsigned int mmSLAVE_HANG_PROTECTION_CNTL = 0x1536; +constexpr unsigned int mmSLAVE_REQ_CREDIT_CNTL = 0x1517; +constexpr unsigned int mmSMBCLK_PAD_CNTL__CI = 0x1523; +constexpr unsigned int mmSMBDAT_PAD_CNTL__CI = 0x1522; +constexpr unsigned int mmSMBUS_SLV_CNTL__CI = 0x14FD; +constexpr unsigned int mmSMC_IND_ACCESS_CNTL__CI__VI = 0x0090; +constexpr unsigned int mmSMC_IND_ACCESS_CNTL__SI = 0x008A; +constexpr unsigned int mmSMC_IND_DATA = 0x0081; +constexpr unsigned int mmSMC_IND_DATA_0__CI__VI = 0x0081; +constexpr unsigned int mmSMC_IND_DATA_1__CI__VI = 0x0083; +constexpr unsigned int mmSMC_IND_DATA_2__CI__VI = 0x0085; +constexpr unsigned int mmSMC_IND_DATA_3__CI__VI = 0x0087; +constexpr unsigned int mmSMC_IND_DATA_4__CI__VI = 0x0089; +constexpr unsigned int mmSMC_IND_DATA_5__CI__VI = 0x008B; +constexpr unsigned int mmSMC_IND_DATA_6__CI__VI = 0x008D; +constexpr unsigned int mmSMC_IND_DATA_7__CI__VI = 0x008F; +constexpr unsigned int mmSMC_IND_INDEX = 0x0080; +constexpr unsigned int mmSMC_IND_INDEX_0__CI__VI = 0x0080; +constexpr unsigned int mmSMC_IND_INDEX_1__CI__VI = 0x0082; +constexpr unsigned int mmSMC_IND_INDEX_2__CI__VI = 0x0084; +constexpr unsigned int mmSMC_IND_INDEX_3__CI__VI = 0x0086; +constexpr unsigned int mmSMC_IND_INDEX_4__CI__VI = 0x0088; +constexpr unsigned int mmSMC_IND_INDEX_5__CI__VI = 0x008A; +constexpr unsigned int mmSMC_IND_INDEX_6__CI__VI = 0x008C; +constexpr unsigned int mmSMC_IND_INDEX_7__CI__VI = 0x008E; +constexpr unsigned int mmSMC_MESSAGE_0__CI__VI = 0x0094; +constexpr unsigned int mmSMC_MESSAGE_0__SI = 0x008B; +constexpr unsigned int mmSMC_MESSAGE_10__CI__VI = 0x00B9; +constexpr unsigned int mmSMC_MESSAGE_11__CI__VI = 0x00BB; +constexpr unsigned int mmSMC_MESSAGE_1__CI__VI = 0x0096; +constexpr unsigned int mmSMC_MESSAGE_1__SI = 0x008D; +constexpr unsigned int mmSMC_MESSAGE_2__CI__VI = 0x0098; +constexpr unsigned int mmSMC_MESSAGE_3__CI__VI = 0x009A; +constexpr unsigned int mmSMC_MESSAGE_4__CI__VI = 0x009C; +constexpr unsigned int mmSMC_MESSAGE_5__CI__VI = 0x009E; +constexpr unsigned int mmSMC_MESSAGE_6__CI__VI = 0x00A0; +constexpr unsigned int mmSMC_MESSAGE_7__CI__VI = 0x00A2; +constexpr unsigned int mmSMC_MESSAGE_8__CI__VI = 0x00B5; +constexpr unsigned int mmSMC_MESSAGE_9__CI__VI = 0x00B7; +constexpr unsigned int mmSMC_MSG_ARG_0__CI__VI = 0x00A4; +constexpr unsigned int mmSMC_MSG_ARG_10__CI__VI = 0x00BF; +constexpr unsigned int mmSMC_MSG_ARG_11__CI = 0x0091; +constexpr unsigned int mmSMC_MSG_ARG_1__CI__VI = 0x00A5; +constexpr unsigned int mmSMC_MSG_ARG_2__CI__VI = 0x00A6; +constexpr unsigned int mmSMC_MSG_ARG_3__CI__VI = 0x00A7; +constexpr unsigned int mmSMC_MSG_ARG_4__CI__VI = 0x00A8; +constexpr unsigned int mmSMC_MSG_ARG_5__CI__VI = 0x00A9; +constexpr unsigned int mmSMC_MSG_ARG_6__CI__VI = 0x00AA; +constexpr unsigned int mmSMC_MSG_ARG_7__CI__VI = 0x00AB; +constexpr unsigned int mmSMC_MSG_ARG_8__CI__VI = 0x00BD; +constexpr unsigned int mmSMC_MSG_ARG_9__CI__VI = 0x00BE; +constexpr unsigned int mmSMC_RESP_0__CI__VI = 0x0095; +constexpr unsigned int mmSMC_RESP_0__SI = 0x008C; +constexpr unsigned int mmSMC_RESP_10__CI__VI = 0x00BA; +constexpr unsigned int mmSMC_RESP_11__CI__VI = 0x00BC; +constexpr unsigned int mmSMC_RESP_1__CI__VI = 0x0097; +constexpr unsigned int mmSMC_RESP_1__SI = 0x008E; +constexpr unsigned int mmSMC_RESP_2__CI__VI = 0x0099; +constexpr unsigned int mmSMC_RESP_3__CI__VI = 0x009B; +constexpr unsigned int mmSMC_RESP_4__CI__VI = 0x009D; +constexpr unsigned int mmSMC_RESP_5__CI__VI = 0x009F; +constexpr unsigned int mmSMC_RESP_6__CI__VI = 0x00A1; +constexpr unsigned int mmSMC_RESP_7__CI__VI = 0x00A3; +constexpr unsigned int mmSMC_RESP_8__CI__VI = 0x00B6; +constexpr unsigned int mmSMC_RESP_9__CI__VI = 0x00B8; +constexpr unsigned int mmSMC_SCRATCH9__SI = 0x022A; +constexpr unsigned int mmSMU_SMC_IND_DATA__CI__VI = 0x0081; +constexpr unsigned int mmSMU_SMC_IND_INDEX__CI__VI = 0x0080; +constexpr unsigned int mmSPI_ARB_CYCLES_0__CI__VI = 0x31C1; +constexpr unsigned int mmSPI_ARB_CYCLES_0__SI = 0x243D; +constexpr unsigned int mmSPI_ARB_CYCLES_1__CI__VI = 0x31C2; +constexpr unsigned int mmSPI_ARB_CYCLES_1__SI = 0x243E; +constexpr unsigned int mmSPI_ARB_PRIORITY__CI__VI = 0x31C0; +constexpr unsigned int mmSPI_ARB_PRIORITY__SI = 0x243C; +constexpr unsigned int mmSPI_BARYC_CNTL = 0xA1B8; +constexpr unsigned int mmSPI_CDBG_SYS_CS0__CI__VI = 0x31C5; +constexpr unsigned int mmSPI_CDBG_SYS_CS1__CI__VI = 0x31C6; +constexpr unsigned int mmSPI_CDBG_SYS_GFX__CI__VI = 0x31C3; +constexpr unsigned int mmSPI_CDBG_SYS_HP3D__CI__VI = 0x31C4; +constexpr unsigned int mmSPI_COMPUTE_QUEUE_RESET__CI__VI = 0x31DB; +constexpr unsigned int mmSPI_CONFIG_CNTL = 0x2440; +constexpr unsigned int mmSPI_CONFIG_CNTL_1 = 0x244F; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_0__CI__VI = 0x24DC; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_1__CI__VI = 0x24DD; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_2__CI__VI = 0x24DE; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_3__CI__VI = 0x24DF; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_4__CI__VI = 0x24E0; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_5__CI__VI = 0x24E1; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_6__CI__VI = 0x24E2; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_COUNT_7__CI__VI = 0x24E3; +constexpr unsigned int mmSPI_CSQ_WF_ACTIVE_STATUS__CI__VI = 0x24DB; +constexpr unsigned int mmSPI_DEBUG_BUSY = 0x2450; +constexpr unsigned int mmSPI_DEBUG_CNTL = 0x2441; +constexpr unsigned int mmSPI_DEBUG_READ = 0x2442; +constexpr unsigned int mmSPI_GDBG_TBA_HI__CI__VI = 0x31D5; +constexpr unsigned int mmSPI_GDBG_TBA_LO__CI__VI = 0x31D4; +constexpr unsigned int mmSPI_GDBG_TMA_HI__CI__VI = 0x31D7; +constexpr unsigned int mmSPI_GDBG_TMA_LO__CI__VI = 0x31D6; +constexpr unsigned int mmSPI_GDBG_TRAP_CONFIG__CI__VI = 0x31D2; +constexpr unsigned int mmSPI_GDBG_TRAP_DATA0__CI__VI = 0x31D8; +constexpr unsigned int mmSPI_GDBG_TRAP_DATA1__CI__VI = 0x31D9; +constexpr unsigned int mmSPI_GDBG_TRAP_MASK__CI__VI = 0x31D3; +constexpr unsigned int mmSPI_GDBG_WAVE_CNTL__CI__VI = 0x31D1; +constexpr unsigned int mmSPI_GDS_CREDITS = 0x24D8; +constexpr unsigned int mmSPI_INTERP_CONTROL_0 = 0xA1B5; +constexpr unsigned int mmSPI_LB_CTR_CTRL = 0x24D4; +constexpr unsigned int mmSPI_LB_CU_MASK = 0x24D5; +constexpr unsigned int mmSPI_LB_DATA_REG = 0x24D6; +constexpr unsigned int mmSPI_P0_TRAP_SCREEN_GPR_MIN__CI__VI = 0x24F0; +constexpr unsigned int mmSPI_P0_TRAP_SCREEN_PSBA_HI__CI__VI = 0x24ED; +constexpr unsigned int mmSPI_P0_TRAP_SCREEN_PSBA_LO__CI__VI = 0x24EC; +constexpr unsigned int mmSPI_P0_TRAP_SCREEN_PSMA_HI__CI__VI = 0x24EF; +constexpr unsigned int mmSPI_P0_TRAP_SCREEN_PSMA_LO__CI__VI = 0x24EE; +constexpr unsigned int mmSPI_P1_TRAP_SCREEN_GPR_MIN__CI__VI = 0x24F5; +constexpr unsigned int mmSPI_P1_TRAP_SCREEN_PSBA_HI__CI__VI = 0x24F2; +constexpr unsigned int mmSPI_P1_TRAP_SCREEN_PSBA_LO__CI__VI = 0x24F1; +constexpr unsigned int mmSPI_P1_TRAP_SCREEN_PSMA_HI__CI__VI = 0x24F4; +constexpr unsigned int mmSPI_P1_TRAP_SCREEN_PSMA_LO__CI__VI = 0x24F3; +constexpr unsigned int mmSPI_PERFCOUNTER0_HI__CI__VI = 0xD180; +constexpr unsigned int mmSPI_PERFCOUNTER0_HI__SI = 0x2447; +constexpr unsigned int mmSPI_PERFCOUNTER0_LO__CI__VI = 0xD181; +constexpr unsigned int mmSPI_PERFCOUNTER0_LO__SI = 0x2448; +constexpr unsigned int mmSPI_PERFCOUNTER0_SELECT1__CI__VI = 0xD984; +constexpr unsigned int mmSPI_PERFCOUNTER0_SELECT__CI__VI = 0xD980; +constexpr unsigned int mmSPI_PERFCOUNTER0_SELECT__SI = 0x2443; +constexpr unsigned int mmSPI_PERFCOUNTER1_HI__CI__VI = 0xD182; +constexpr unsigned int mmSPI_PERFCOUNTER1_HI__SI = 0x2449; +constexpr unsigned int mmSPI_PERFCOUNTER1_LO__CI__VI = 0xD183; +constexpr unsigned int mmSPI_PERFCOUNTER1_LO__SI = 0x244A; +constexpr unsigned int mmSPI_PERFCOUNTER1_SELECT1__CI__VI = 0xD985; +constexpr unsigned int mmSPI_PERFCOUNTER1_SELECT__CI__VI = 0xD981; +constexpr unsigned int mmSPI_PERFCOUNTER1_SELECT__SI = 0x2444; +constexpr unsigned int mmSPI_PERFCOUNTER2_HI__CI__VI = 0xD184; +constexpr unsigned int mmSPI_PERFCOUNTER2_HI__SI = 0x244B; +constexpr unsigned int mmSPI_PERFCOUNTER2_LO__CI__VI = 0xD185; +constexpr unsigned int mmSPI_PERFCOUNTER2_LO__SI = 0x244C; +constexpr unsigned int mmSPI_PERFCOUNTER2_SELECT1__CI__VI = 0xD986; +constexpr unsigned int mmSPI_PERFCOUNTER2_SELECT__CI__VI = 0xD982; +constexpr unsigned int mmSPI_PERFCOUNTER2_SELECT__SI = 0x2445; +constexpr unsigned int mmSPI_PERFCOUNTER3_HI__CI__VI = 0xD186; +constexpr unsigned int mmSPI_PERFCOUNTER3_HI__SI = 0x244D; +constexpr unsigned int mmSPI_PERFCOUNTER3_LO__CI__VI = 0xD187; +constexpr unsigned int mmSPI_PERFCOUNTER3_LO__SI = 0x244E; +constexpr unsigned int mmSPI_PERFCOUNTER3_SELECT1__CI__VI = 0xD987; +constexpr unsigned int mmSPI_PERFCOUNTER3_SELECT__CI__VI = 0xD983; +constexpr unsigned int mmSPI_PERFCOUNTER3_SELECT__SI = 0x2446; +constexpr unsigned int mmSPI_PERFCOUNTER4_HI__CI__VI = 0xD188; +constexpr unsigned int mmSPI_PERFCOUNTER4_LO__CI__VI = 0xD189; +constexpr unsigned int mmSPI_PERFCOUNTER4_SELECT__CI__VI = 0xD988; +constexpr unsigned int mmSPI_PERFCOUNTER5_HI__CI__VI = 0xD18A; +constexpr unsigned int mmSPI_PERFCOUNTER5_LO__CI__VI = 0xD18B; +constexpr unsigned int mmSPI_PERFCOUNTER5_SELECT__CI__VI = 0xD989; +constexpr unsigned int mmSPI_PERFCOUNTER_BINS__CI__VI = 0xD98A; +constexpr unsigned int mmSPI_PERFCOUNTER_BINS__SI = 0x243F; +constexpr unsigned int mmSPI_PG_ENABLE_STATIC_CU_MASK = 0x24D7; +constexpr unsigned int mmSPI_PS_INPUT_ADDR = 0xA1B4; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_0 = 0xA191; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_1 = 0xA192; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_10 = 0xA19B; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_11 = 0xA19C; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_12 = 0xA19D; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_13 = 0xA19E; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_14 = 0xA19F; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_15 = 0xA1A0; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_16 = 0xA1A1; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_17 = 0xA1A2; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_18 = 0xA1A3; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_19 = 0xA1A4; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_2 = 0xA193; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_20 = 0xA1A5; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_21 = 0xA1A6; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_22 = 0xA1A7; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_23 = 0xA1A8; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_24 = 0xA1A9; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_25 = 0xA1AA; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_26 = 0xA1AB; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_27 = 0xA1AC; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_28 = 0xA1AD; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_29 = 0xA1AE; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_3 = 0xA194; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_30 = 0xA1AF; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_31 = 0xA1B0; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_4 = 0xA195; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_5 = 0xA196; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_6 = 0xA197; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_7 = 0xA198; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_8 = 0xA199; +constexpr unsigned int mmSPI_PS_INPUT_CNTL_9 = 0xA19A; +constexpr unsigned int mmSPI_PS_INPUT_ENA = 0xA1B3; +constexpr unsigned int mmSPI_PS_IN_CONTROL = 0xA1B6; +constexpr unsigned int mmSPI_PS_MAX_WAVE_ID__CI__VI = 0x243A; +constexpr unsigned int mmSPI_PS_MAX_WAVE_ID__SI = 0x243B; +constexpr unsigned int mmSPI_RESET_DEBUG__CI__VI = 0x31DA; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_0__CI__VI = 0x31DC; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_10__CI__VI = 0x31F0; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_11__CI__VI = 0x31F1; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_1__CI__VI = 0x31DD; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_2__CI__VI = 0x31DE; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_3__CI__VI = 0x31DF; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_4__CI__VI = 0x31E0; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_5__CI__VI = 0x31E1; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_6__CI__VI = 0x31E2; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_7__CI__VI = 0x31E3; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_8__CI__VI = 0x31E4; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_9__CI__VI = 0x31E5; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_0__CI__VI = 0x31E6; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_10__CI__VI = 0x31F2; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_11__CI__VI = 0x31F3; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_1__CI__VI = 0x31E7; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_2__CI__VI = 0x31E8; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_3__CI__VI = 0x31E9; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_4__CI__VI = 0x31EA; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_5__CI__VI = 0x31EB; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_6__CI__VI = 0x31EC; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_7__CI__VI = 0x31ED; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_8__CI__VI = 0x31EE; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_9__CI__VI = 0x31EF; +constexpr unsigned int mmSPI_SHADER_COL_FORMAT = 0xA1C5; +constexpr unsigned int mmSPI_SHADER_LATE_ALLOC_VS__CI__VI = 0x2C47; +constexpr unsigned int mmSPI_SHADER_PGM_HI_ES = 0x2CC9; +constexpr unsigned int mmSPI_SHADER_PGM_HI_GS = 0x2C89; +constexpr unsigned int mmSPI_SHADER_PGM_HI_HS = 0x2D09; +constexpr unsigned int mmSPI_SHADER_PGM_HI_LS = 0x2D49; +constexpr unsigned int mmSPI_SHADER_PGM_HI_PS = 0x2C09; +constexpr unsigned int mmSPI_SHADER_PGM_HI_VS = 0x2C49; +constexpr unsigned int mmSPI_SHADER_PGM_LO_ES = 0x2CC8; +constexpr unsigned int mmSPI_SHADER_PGM_LO_GS = 0x2C88; +constexpr unsigned int mmSPI_SHADER_PGM_LO_HS = 0x2D08; +constexpr unsigned int mmSPI_SHADER_PGM_LO_LS = 0x2D48; +constexpr unsigned int mmSPI_SHADER_PGM_LO_PS = 0x2C08; +constexpr unsigned int mmSPI_SHADER_PGM_LO_VS = 0x2C48; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC1_ES = 0x2CCA; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC1_GS = 0x2C8A; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC1_HS = 0x2D0A; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC1_LS = 0x2D4A; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC1_PS = 0x2C0A; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC1_VS = 0x2C4A; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_ES = 0x2CCB; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_ES_GS__CI__VI = 0x2CBC; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_ES_VS__CI__VI = 0x2C7C; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_GS = 0x2C8B; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_HS = 0x2D0B; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_LS = 0x2D4B; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_LS_ES__CI__VI = 0x2CFD; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_LS_HS__CI__VI = 0x2D3D; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_LS_VS__CI__VI = 0x2C7D; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_PS = 0x2C0B; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC2_VS = 0x2C4B; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC3_ES__CI__VI = 0x2CC7; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC3_GS__CI__VI = 0x2C87; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC3_HS__CI__VI = 0x2D07; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC3_LS__CI__VI = 0x2D47; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC3_PS__CI__VI = 0x2C07; +constexpr unsigned int mmSPI_SHADER_PGM_RSRC3_VS__CI__VI = 0x2C46; +constexpr unsigned int mmSPI_SHADER_POS_FORMAT = 0xA1C3; +constexpr unsigned int mmSPI_SHADER_TBA_HI_ES = 0x2CC1; +constexpr unsigned int mmSPI_SHADER_TBA_HI_GS = 0x2C81; +constexpr unsigned int mmSPI_SHADER_TBA_HI_HS = 0x2D01; +constexpr unsigned int mmSPI_SHADER_TBA_HI_LS = 0x2D41; +constexpr unsigned int mmSPI_SHADER_TBA_HI_PS = 0x2C01; +constexpr unsigned int mmSPI_SHADER_TBA_HI_VS = 0x2C41; +constexpr unsigned int mmSPI_SHADER_TBA_LO_ES = 0x2CC0; +constexpr unsigned int mmSPI_SHADER_TBA_LO_GS = 0x2C80; +constexpr unsigned int mmSPI_SHADER_TBA_LO_HS = 0x2D00; +constexpr unsigned int mmSPI_SHADER_TBA_LO_LS = 0x2D40; +constexpr unsigned int mmSPI_SHADER_TBA_LO_PS = 0x2C00; +constexpr unsigned int mmSPI_SHADER_TBA_LO_VS = 0x2C40; +constexpr unsigned int mmSPI_SHADER_TMA_HI_ES = 0x2CC3; +constexpr unsigned int mmSPI_SHADER_TMA_HI_GS = 0x2C83; +constexpr unsigned int mmSPI_SHADER_TMA_HI_HS = 0x2D03; +constexpr unsigned int mmSPI_SHADER_TMA_HI_LS = 0x2D43; +constexpr unsigned int mmSPI_SHADER_TMA_HI_PS = 0x2C03; +constexpr unsigned int mmSPI_SHADER_TMA_HI_VS = 0x2C43; +constexpr unsigned int mmSPI_SHADER_TMA_LO_ES = 0x2CC2; +constexpr unsigned int mmSPI_SHADER_TMA_LO_GS = 0x2C82; +constexpr unsigned int mmSPI_SHADER_TMA_LO_HS = 0x2D02; +constexpr unsigned int mmSPI_SHADER_TMA_LO_LS = 0x2D42; +constexpr unsigned int mmSPI_SHADER_TMA_LO_PS = 0x2C02; +constexpr unsigned int mmSPI_SHADER_TMA_LO_VS = 0x2C42; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_0 = 0x2CCC; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_1 = 0x2CCD; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_10 = 0x2CD6; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_11 = 0x2CD7; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_12 = 0x2CD8; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_13 = 0x2CD9; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_14 = 0x2CDA; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_15 = 0x2CDB; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_2 = 0x2CCE; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_3 = 0x2CCF; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_4 = 0x2CD0; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_5 = 0x2CD1; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_6 = 0x2CD2; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_7 = 0x2CD3; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_8 = 0x2CD4; +constexpr unsigned int mmSPI_SHADER_USER_DATA_ES_9 = 0x2CD5; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_0 = 0x2C8C; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_1 = 0x2C8D; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_10 = 0x2C96; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_11 = 0x2C97; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_12 = 0x2C98; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_13 = 0x2C99; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_14 = 0x2C9A; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_15 = 0x2C9B; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_2 = 0x2C8E; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_3 = 0x2C8F; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_4 = 0x2C90; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_5 = 0x2C91; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_6 = 0x2C92; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_7 = 0x2C93; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_8 = 0x2C94; +constexpr unsigned int mmSPI_SHADER_USER_DATA_GS_9 = 0x2C95; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_0 = 0x2D0C; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_1 = 0x2D0D; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_10 = 0x2D16; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_11 = 0x2D17; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_12 = 0x2D18; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_13 = 0x2D19; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_14 = 0x2D1A; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_15 = 0x2D1B; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_2 = 0x2D0E; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_3 = 0x2D0F; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_4 = 0x2D10; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_5 = 0x2D11; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_6 = 0x2D12; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_7 = 0x2D13; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_8 = 0x2D14; +constexpr unsigned int mmSPI_SHADER_USER_DATA_HS_9 = 0x2D15; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_0 = 0x2D4C; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_1 = 0x2D4D; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_10 = 0x2D56; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_11 = 0x2D57; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_12 = 0x2D58; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_13 = 0x2D59; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_14 = 0x2D5A; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_15 = 0x2D5B; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_2 = 0x2D4E; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_3 = 0x2D4F; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_4 = 0x2D50; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_5 = 0x2D51; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_6 = 0x2D52; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_7 = 0x2D53; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_8 = 0x2D54; +constexpr unsigned int mmSPI_SHADER_USER_DATA_LS_9 = 0x2D55; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_0 = 0x2C0C; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_1 = 0x2C0D; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_10 = 0x2C16; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_11 = 0x2C17; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_12 = 0x2C18; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_13 = 0x2C19; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_14 = 0x2C1A; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_15 = 0x2C1B; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_2 = 0x2C0E; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_3 = 0x2C0F; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_4 = 0x2C10; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_5 = 0x2C11; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_6 = 0x2C12; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_7 = 0x2C13; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_8 = 0x2C14; +constexpr unsigned int mmSPI_SHADER_USER_DATA_PS_9 = 0x2C15; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_0 = 0x2C4C; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_1 = 0x2C4D; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_10 = 0x2C56; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_11 = 0x2C57; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_12 = 0x2C58; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_13 = 0x2C59; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_14 = 0x2C5A; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_15 = 0x2C5B; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_2 = 0x2C4E; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_3 = 0x2C4F; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_4 = 0x2C50; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_5 = 0x2C51; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_6 = 0x2C52; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_7 = 0x2C53; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_8 = 0x2C54; +constexpr unsigned int mmSPI_SHADER_USER_DATA_VS_9 = 0x2C55; +constexpr unsigned int mmSPI_SHADER_Z_FORMAT = 0xA1C4; +constexpr unsigned int mmSPI_SLAVE_DEBUG_BUSY = 0x24D3; +constexpr unsigned int mmSPI_STATIC_THREAD_MGMT_3__SI = 0x243A; +constexpr unsigned int mmSPI_SX_EXPORT_BUFFER_SIZES = 0x24D9; +constexpr unsigned int mmSPI_SX_SCOREBOARD_BUFFER_SIZES = 0x24DA; +constexpr unsigned int mmSPI_TMPRING_SIZE = 0xA1BA; +constexpr unsigned int mmSPI_VS_OUT_CONFIG = 0xA1B1; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS0__CI__VI = 0x31C9; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS1__CI__VI = 0x31CA; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS2__CI__VI = 0x31CB; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS3__CI__VI = 0x31CC; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS4__CI__VI = 0x31CD; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS5__CI__VI = 0x31CE; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS6__CI__VI = 0x31CF; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_CS7__CI__VI = 0x31D0; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_GFX__CI__VI = 0x31C7; +constexpr unsigned int mmSPI_WCL_PIPE_PERCENT_HP3D__CI__VI = 0x31C8; +constexpr unsigned int mmSPI_WF_LIFETIME_CNTL__CI__VI = 0x24AA; +constexpr unsigned int mmSPI_WF_LIFETIME_DEBUG__CI__VI = 0x24CA; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_0__CI__VI = 0x24AB; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_1__CI__VI = 0x24AC; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_2__CI__VI = 0x24AD; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_3__CI__VI = 0x24AE; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_4__CI__VI = 0x24AF; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_5__CI__VI = 0x24B0; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_6__CI__VI = 0x24B1; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_7__CI__VI = 0x24B2; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_8__CI__VI = 0x24B3; +constexpr unsigned int mmSPI_WF_LIFETIME_LIMIT_9__CI__VI = 0x24B4; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_0__CI__VI = 0x24B5; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_10__CI__VI = 0x24BF; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_11__CI__VI = 0x24C0; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_12__CI__VI = 0x24C1; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_13__CI__VI = 0x24C2; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_14__CI__VI = 0x24C3; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_15__CI__VI = 0x24C4; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_16__CI__VI = 0x24C5; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_17__CI__VI = 0x24C6; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_18__CI__VI = 0x24C7; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_19__CI__VI = 0x24C8; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_1__CI__VI = 0x24B6; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_20__CI__VI = 0x24C9; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_2__CI__VI = 0x24B7; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_3__CI__VI = 0x24B8; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_4__CI__VI = 0x24B9; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_5__CI__VI = 0x24BA; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_6__CI__VI = 0x24BB; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_7__CI__VI = 0x24BC; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_8__CI__VI = 0x24BD; +constexpr unsigned int mmSPI_WF_LIFETIME_STATUS_9__CI__VI = 0x24BE; +constexpr unsigned int mmSPLL_CNTL_MODE__SI = 0x0186; +constexpr unsigned int mmSQC_CACHES__CI__VI = 0xC348; +constexpr unsigned int mmSQC_CACHES__SI = 0x2302; +constexpr unsigned int mmSQC_CONFIG = 0x2301; +constexpr unsigned int mmSQC_POLICY__CI = 0x230E; +constexpr unsigned int mmSQC_SECDED_CNT__SI__CI = 0x23A0; +constexpr unsigned int mmSQC_VOLATILE__CI = 0x230F; +constexpr unsigned int mmSQ_ALU_CLK_CTRL__CI__VI = 0xF08E; +constexpr unsigned int mmSQ_ALU_CLK_CTRL__SI = 0x2360; +constexpr unsigned int mmSQ_BUF_RSRC_WORD0 = 0x23C0; +constexpr unsigned int mmSQ_BUF_RSRC_WORD1 = 0x23C1; +constexpr unsigned int mmSQ_BUF_RSRC_WORD2 = 0x23C2; +constexpr unsigned int mmSQ_BUF_RSRC_WORD3 = 0x23C3; +constexpr unsigned int mmSQ_CMD_TIMESTAMP__CI__VI = 0x2375; +constexpr unsigned int mmSQ_CMD__CI__VI = 0x237B; +constexpr unsigned int mmSQ_CONFIG = 0x2300; +constexpr unsigned int mmSQ_DEBUG_STS_GLOBAL = 0x2309; +constexpr unsigned int mmSQ_DEBUG_STS_GLOBAL2__CI__VI = 0x2310; +constexpr unsigned int mmSQ_DEBUG_STS_GLOBAL3__CI__VI = 0x2311; +constexpr unsigned int mmSQ_DED_CNT__SI__CI = 0x23A2; +constexpr unsigned int mmSQ_DED_INFO__SI__CI = 0x23A3; +constexpr unsigned int mmSQ_DS_0 = 0x237F; +constexpr unsigned int mmSQ_DS_1 = 0x237F; +constexpr unsigned int mmSQ_EXP_0 = 0x237F; +constexpr unsigned int mmSQ_EXP_1 = 0x237F; +constexpr unsigned int mmSQ_FIFO_SIZES = 0x2305; +constexpr unsigned int mmSQ_FLAT_0__CI__VI = 0x237F; +constexpr unsigned int mmSQ_FLAT_1__CI__VI = 0x237F; +constexpr unsigned int mmSQ_FLAT_SCRATCH_WORD0__CI__VI = 0x23D0; +constexpr unsigned int mmSQ_FLAT_SCRATCH_WORD1__CI__VI = 0x23D1; +constexpr unsigned int mmSQ_HV_VMID_CTRL__CI__VI = 0xF840; +constexpr unsigned int mmSQ_IMG_RSRC_WORD0 = 0x23C4; +constexpr unsigned int mmSQ_IMG_RSRC_WORD1 = 0x23C5; +constexpr unsigned int mmSQ_IMG_RSRC_WORD2 = 0x23C6; +constexpr unsigned int mmSQ_IMG_RSRC_WORD3 = 0x23C7; +constexpr unsigned int mmSQ_IMG_RSRC_WORD4 = 0x23C8; +constexpr unsigned int mmSQ_IMG_RSRC_WORD5 = 0x23C9; +constexpr unsigned int mmSQ_IMG_RSRC_WORD6 = 0x23CA; +constexpr unsigned int mmSQ_IMG_RSRC_WORD7 = 0x23CB; +constexpr unsigned int mmSQ_IMG_SAMP_WORD0 = 0x23CC; +constexpr unsigned int mmSQ_IMG_SAMP_WORD1 = 0x23CD; +constexpr unsigned int mmSQ_IMG_SAMP_WORD2 = 0x23CE; +constexpr unsigned int mmSQ_IMG_SAMP_WORD3 = 0x23CF; +constexpr unsigned int mmSQ_IND_DATA = 0x2379; +constexpr unsigned int mmSQ_IND_INDEX = 0x2378; +constexpr unsigned int mmSQ_INST = 0x237F; +constexpr unsigned int mmSQ_INTERRUPT_AUTO_MASK__CI__VI = 0x2314; +constexpr unsigned int mmSQ_INTERRUPT_MSG_CTRL__CI__VI = 0x2315; +constexpr unsigned int mmSQ_LB_CTR_CTRL = 0x2398; +constexpr unsigned int mmSQ_LB_DATA_ALU_CYCLES = 0x2399; +constexpr unsigned int mmSQ_LB_DATA_ALU_STALLS = 0x239B; +constexpr unsigned int mmSQ_LB_DATA_TEX_CYCLES = 0x239A; +constexpr unsigned int mmSQ_LB_DATA_TEX_STALLS = 0x239C; +constexpr unsigned int mmSQ_LDS_CLK_CTRL__CI__VI = 0xF090; +constexpr unsigned int mmSQ_MIMG_0 = 0x237F; +constexpr unsigned int mmSQ_MIMG_1 = 0x237F; +constexpr unsigned int mmSQ_MTBUF_0 = 0x237F; +constexpr unsigned int mmSQ_MTBUF_1 = 0x237F; +constexpr unsigned int mmSQ_MUBUF_0 = 0x237F; +constexpr unsigned int mmSQ_MUBUF_1 = 0x237F; +constexpr unsigned int mmSQ_PERFCOUNTER0_HI__CI__VI = 0xD1C1; +constexpr unsigned int mmSQ_PERFCOUNTER0_HI__SI = 0x2321; +constexpr unsigned int mmSQ_PERFCOUNTER0_LO__CI__VI = 0xD1C0; +constexpr unsigned int mmSQ_PERFCOUNTER0_LO__SI = 0x2320; +constexpr unsigned int mmSQ_PERFCOUNTER0_SELECT__CI__VI = 0xD9C0; +constexpr unsigned int mmSQ_PERFCOUNTER0_SELECT__SI = 0x2340; +constexpr unsigned int mmSQ_PERFCOUNTER10_HI__CI__VI = 0xD1D5; +constexpr unsigned int mmSQ_PERFCOUNTER10_HI__SI = 0x2335; +constexpr unsigned int mmSQ_PERFCOUNTER10_LO__CI__VI = 0xD1D4; +constexpr unsigned int mmSQ_PERFCOUNTER10_LO__SI = 0x2334; +constexpr unsigned int mmSQ_PERFCOUNTER10_SELECT__CI__VI = 0xD9CA; +constexpr unsigned int mmSQ_PERFCOUNTER10_SELECT__SI = 0x234A; +constexpr unsigned int mmSQ_PERFCOUNTER11_HI__CI__VI = 0xD1D7; +constexpr unsigned int mmSQ_PERFCOUNTER11_HI__SI = 0x2337; +constexpr unsigned int mmSQ_PERFCOUNTER11_LO__CI__VI = 0xD1D6; +constexpr unsigned int mmSQ_PERFCOUNTER11_LO__SI = 0x2336; +constexpr unsigned int mmSQ_PERFCOUNTER11_SELECT__CI__VI = 0xD9CB; +constexpr unsigned int mmSQ_PERFCOUNTER11_SELECT__SI = 0x234B; +constexpr unsigned int mmSQ_PERFCOUNTER12_HI__CI__VI = 0xD1D9; +constexpr unsigned int mmSQ_PERFCOUNTER12_HI__SI = 0x2339; +constexpr unsigned int mmSQ_PERFCOUNTER12_LO__CI__VI = 0xD1D8; +constexpr unsigned int mmSQ_PERFCOUNTER12_LO__SI = 0x2338; +constexpr unsigned int mmSQ_PERFCOUNTER12_SELECT__CI__VI = 0xD9CC; +constexpr unsigned int mmSQ_PERFCOUNTER12_SELECT__SI = 0x234C; +constexpr unsigned int mmSQ_PERFCOUNTER13_HI__CI__VI = 0xD1DB; +constexpr unsigned int mmSQ_PERFCOUNTER13_HI__SI = 0x233B; +constexpr unsigned int mmSQ_PERFCOUNTER13_LO__CI__VI = 0xD1DA; +constexpr unsigned int mmSQ_PERFCOUNTER13_LO__SI = 0x233A; +constexpr unsigned int mmSQ_PERFCOUNTER13_SELECT__CI__VI = 0xD9CD; +constexpr unsigned int mmSQ_PERFCOUNTER13_SELECT__SI = 0x234D; +constexpr unsigned int mmSQ_PERFCOUNTER14_HI__CI__VI = 0xD1DD; +constexpr unsigned int mmSQ_PERFCOUNTER14_HI__SI = 0x233D; +constexpr unsigned int mmSQ_PERFCOUNTER14_LO__CI__VI = 0xD1DC; +constexpr unsigned int mmSQ_PERFCOUNTER14_LO__SI = 0x233C; +constexpr unsigned int mmSQ_PERFCOUNTER14_SELECT__CI__VI = 0xD9CE; +constexpr unsigned int mmSQ_PERFCOUNTER14_SELECT__SI = 0x234E; +constexpr unsigned int mmSQ_PERFCOUNTER15_HI__CI__VI = 0xD1DF; +constexpr unsigned int mmSQ_PERFCOUNTER15_HI__SI = 0x233F; +constexpr unsigned int mmSQ_PERFCOUNTER15_LO__CI__VI = 0xD1DE; +constexpr unsigned int mmSQ_PERFCOUNTER15_LO__SI = 0x233E; +constexpr unsigned int mmSQ_PERFCOUNTER15_SELECT__CI__VI = 0xD9CF; +constexpr unsigned int mmSQ_PERFCOUNTER15_SELECT__SI = 0x234F; +constexpr unsigned int mmSQ_PERFCOUNTER1_HI__CI__VI = 0xD1C3; +constexpr unsigned int mmSQ_PERFCOUNTER1_HI__SI = 0x2323; +constexpr unsigned int mmSQ_PERFCOUNTER1_LO__CI__VI = 0xD1C2; +constexpr unsigned int mmSQ_PERFCOUNTER1_LO__SI = 0x2322; +constexpr unsigned int mmSQ_PERFCOUNTER1_SELECT__CI__VI = 0xD9C1; +constexpr unsigned int mmSQ_PERFCOUNTER1_SELECT__SI = 0x2341; +constexpr unsigned int mmSQ_PERFCOUNTER2_HI__CI__VI = 0xD1C5; +constexpr unsigned int mmSQ_PERFCOUNTER2_HI__SI = 0x2325; +constexpr unsigned int mmSQ_PERFCOUNTER2_LO__CI__VI = 0xD1C4; +constexpr unsigned int mmSQ_PERFCOUNTER2_LO__SI = 0x2324; +constexpr unsigned int mmSQ_PERFCOUNTER2_SELECT__CI__VI = 0xD9C2; +constexpr unsigned int mmSQ_PERFCOUNTER2_SELECT__SI = 0x2342; +constexpr unsigned int mmSQ_PERFCOUNTER3_HI__CI__VI = 0xD1C7; +constexpr unsigned int mmSQ_PERFCOUNTER3_HI__SI = 0x2327; +constexpr unsigned int mmSQ_PERFCOUNTER3_LO__CI__VI = 0xD1C6; +constexpr unsigned int mmSQ_PERFCOUNTER3_LO__SI = 0x2326; +constexpr unsigned int mmSQ_PERFCOUNTER3_SELECT__CI__VI = 0xD9C3; +constexpr unsigned int mmSQ_PERFCOUNTER3_SELECT__SI = 0x2343; +constexpr unsigned int mmSQ_PERFCOUNTER4_HI__CI__VI = 0xD1C9; +constexpr unsigned int mmSQ_PERFCOUNTER4_HI__SI = 0x2329; +constexpr unsigned int mmSQ_PERFCOUNTER4_LO__CI__VI = 0xD1C8; +constexpr unsigned int mmSQ_PERFCOUNTER4_LO__SI = 0x2328; +constexpr unsigned int mmSQ_PERFCOUNTER4_SELECT__CI__VI = 0xD9C4; +constexpr unsigned int mmSQ_PERFCOUNTER4_SELECT__SI = 0x2344; +constexpr unsigned int mmSQ_PERFCOUNTER5_HI__CI__VI = 0xD1CB; +constexpr unsigned int mmSQ_PERFCOUNTER5_HI__SI = 0x232B; +constexpr unsigned int mmSQ_PERFCOUNTER5_LO__CI__VI = 0xD1CA; +constexpr unsigned int mmSQ_PERFCOUNTER5_LO__SI = 0x232A; +constexpr unsigned int mmSQ_PERFCOUNTER5_SELECT__CI__VI = 0xD9C5; +constexpr unsigned int mmSQ_PERFCOUNTER5_SELECT__SI = 0x2345; +constexpr unsigned int mmSQ_PERFCOUNTER6_HI__CI__VI = 0xD1CD; +constexpr unsigned int mmSQ_PERFCOUNTER6_HI__SI = 0x232D; +constexpr unsigned int mmSQ_PERFCOUNTER6_LO__CI__VI = 0xD1CC; +constexpr unsigned int mmSQ_PERFCOUNTER6_LO__SI = 0x232C; +constexpr unsigned int mmSQ_PERFCOUNTER6_SELECT__CI__VI = 0xD9C6; +constexpr unsigned int mmSQ_PERFCOUNTER6_SELECT__SI = 0x2346; +constexpr unsigned int mmSQ_PERFCOUNTER7_HI__CI__VI = 0xD1CF; +constexpr unsigned int mmSQ_PERFCOUNTER7_HI__SI = 0x232F; +constexpr unsigned int mmSQ_PERFCOUNTER7_LO__CI__VI = 0xD1CE; +constexpr unsigned int mmSQ_PERFCOUNTER7_LO__SI = 0x232E; +constexpr unsigned int mmSQ_PERFCOUNTER7_SELECT__CI__VI = 0xD9C7; +constexpr unsigned int mmSQ_PERFCOUNTER7_SELECT__SI = 0x2347; +constexpr unsigned int mmSQ_PERFCOUNTER8_HI__CI__VI = 0xD1D1; +constexpr unsigned int mmSQ_PERFCOUNTER8_HI__SI = 0x2331; +constexpr unsigned int mmSQ_PERFCOUNTER8_LO__CI__VI = 0xD1D0; +constexpr unsigned int mmSQ_PERFCOUNTER8_LO__SI = 0x2330; +constexpr unsigned int mmSQ_PERFCOUNTER8_SELECT__CI__VI = 0xD9C8; +constexpr unsigned int mmSQ_PERFCOUNTER8_SELECT__SI = 0x2348; +constexpr unsigned int mmSQ_PERFCOUNTER9_HI__CI__VI = 0xD1D3; +constexpr unsigned int mmSQ_PERFCOUNTER9_HI__SI = 0x2333; +constexpr unsigned int mmSQ_PERFCOUNTER9_LO__CI__VI = 0xD1D2; +constexpr unsigned int mmSQ_PERFCOUNTER9_LO__SI = 0x2332; +constexpr unsigned int mmSQ_PERFCOUNTER9_SELECT__CI__VI = 0xD9C9; +constexpr unsigned int mmSQ_PERFCOUNTER9_SELECT__SI = 0x2349; +constexpr unsigned int mmSQ_PERFCOUNTER_CTRL2__CI__VI = 0xD9E2; +constexpr unsigned int mmSQ_PERFCOUNTER_CTRL__CI__VI = 0xD9E0; +constexpr unsigned int mmSQ_PERFCOUNTER_CTRL__SI = 0x2306; +constexpr unsigned int mmSQ_PERFCOUNTER_MASK__CI__VI = 0xD9E1; +constexpr unsigned int mmSQ_POWER_THROTTLE2__CI__VI = 0xF092; +constexpr unsigned int mmSQ_POWER_THROTTLE2__SI = 0x2397; +constexpr unsigned int mmSQ_POWER_THROTTLE__CI__VI = 0xF091; +constexpr unsigned int mmSQ_POWER_THROTTLE__SI = 0x2396; +constexpr unsigned int mmSQ_RANDOM_WAVE_PRI = 0x2303; +constexpr unsigned int mmSQ_REG_CREDITS = 0x2304; +constexpr unsigned int mmSQ_REG_TIMESTAMP__CI__VI = 0x2374; +constexpr unsigned int mmSQ_SEC_CNT__SI__CI = 0x23A1; +constexpr unsigned int mmSQ_SMRD__SI__CI = 0x237F; +constexpr unsigned int mmSQ_SOP1 = 0x237F; +constexpr unsigned int mmSQ_SOP2 = 0x237F; +constexpr unsigned int mmSQ_SOPC = 0x237F; +constexpr unsigned int mmSQ_SOPK = 0x237F; +constexpr unsigned int mmSQ_SOPP = 0x237F; +constexpr unsigned int mmSQ_TEX_CLK_CTRL__CI__VI = 0xF08F; +constexpr unsigned int mmSQ_TEX_CLK_CTRL__SI = 0x2361; +constexpr unsigned int mmSQ_THREAD_TRACE_BASE2__CI = 0x2385; +constexpr unsigned int mmSQ_THREAD_TRACE_CNTR = 0x2390; +constexpr unsigned int mmSQ_THREAD_TRACE_TOKEN_MASK2__CI = 0x2386; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_0__CI__VI = 0xC340; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_0__SI = 0x2388; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_1__CI__VI = 0xC341; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_1__SI = 0x2389; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_2__CI__VI = 0xC342; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_2__SI = 0x238A; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_3__CI__VI = 0xC343; +constexpr unsigned int mmSQ_THREAD_TRACE_USERDATA_3__SI = 0x238B; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_CMN = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_EVENT = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_INST = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_INST_PC_1_OF_2 = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_INST_PC_2_OF_2 = 0x23B1; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2 = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_INST_USERDATA_2_OF_2 = 0x23B1; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_ISSUE = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_MISC = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_PERF_1_OF_2 = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_PERF_2_OF_2 = 0x23B1; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_REG_1_OF_2 = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_REG_2_OF_2 = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__CI__VI = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_REG_CS_2_OF_2__CI__VI = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_TIMESTAMP_1_OF_2 = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_TIMESTAMP_2_OF_2 = 0x23B1; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_TIME__SI = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_WAVE = 0x23B0; +constexpr unsigned int mmSQ_THREAD_TRACE_WORD_WAVE_START = 0x23B0; +constexpr unsigned int mmSQ_TIME_HI = 0x237C; +constexpr unsigned int mmSQ_TIME_LO = 0x237D; +constexpr unsigned int mmSQ_VINTRP = 0x237F; +constexpr unsigned int mmSQ_VOP1 = 0x237F; +constexpr unsigned int mmSQ_VOP2 = 0x237F; +constexpr unsigned int mmSQ_VOP3_0 = 0x237F; +constexpr unsigned int mmSQ_VOP3_0_SDST_ENC = 0x237F; +constexpr unsigned int mmSQ_VOP3_1 = 0x237F; +constexpr unsigned int mmSQ_VOPC = 0x237F; +constexpr unsigned int mmSRBM_CHIP_REVISION = 0x039B; +constexpr unsigned int mmSRBM_CNTL = 0x0390; +constexpr unsigned int mmSRBM_DEBUG = 0x03A4; +constexpr unsigned int mmSRBM_DEBUG_CNTL = 0x0399; +constexpr unsigned int mmSRBM_DEBUG_DATA = 0x039A; +constexpr unsigned int mmSRBM_DEBUG_SNAPSHOT = 0x03A5; +constexpr unsigned int mmSRBM_GFX_CNTL = 0x0391; +constexpr unsigned int mmSRBM_INT_ACK = 0x03AA; +constexpr unsigned int mmSRBM_INT_CNTL = 0x03A8; +constexpr unsigned int mmSRBM_INT_STATUS = 0x03A9; +constexpr unsigned int mmSRBM_MC_CLKEN_CNTL__CI__VI = 0x03B3; +constexpr unsigned int mmSRBM_READ_ERROR = 0x03A6; +constexpr unsigned int mmSRBM_SAM_CLKEN_CNTL__CI__VI = 0x03B8; +constexpr unsigned int mmSRBM_SDMA_CLKEN_CNTL__CI__VI = 0x03B7; +constexpr unsigned int mmSRBM_SOFT_RESET = 0x0398; +constexpr unsigned int mmSRBM_STATUS = 0x0394; +constexpr unsigned int mmSRBM_STATUS2 = 0x0393; +constexpr unsigned int mmSRBM_SYS_CLKEN_CNTL = 0x03B4; +constexpr unsigned int mmSRBM_UVD_CLKEN_CNTL = 0x03B6; +constexpr unsigned int mmSRBM_VCE_CLKEN_CNTL = 0x03B5; +constexpr unsigned int mmSX_DEBUG_1 = 0x2418; +constexpr unsigned int mmSX_DEBUG_BUSY = 0x2414; +constexpr unsigned int mmSX_DEBUG_BUSY_2 = 0x2415; +constexpr unsigned int mmSX_DEBUG_BUSY_3 = 0x2416; +constexpr unsigned int mmSX_DEBUG_BUSY_4 = 0x2417; +constexpr unsigned int mmSX_PERFCOUNTER0_HI__CI__VI = 0xD241; +constexpr unsigned int mmSX_PERFCOUNTER0_HI__SI = 0x2421; +constexpr unsigned int mmSX_PERFCOUNTER0_LO__CI__VI = 0xD240; +constexpr unsigned int mmSX_PERFCOUNTER0_LO__SI = 0x2420; +constexpr unsigned int mmSX_PERFCOUNTER0_SELECT1__CI__VI = 0xDA44; +constexpr unsigned int mmSX_PERFCOUNTER0_SELECT__CI__VI = 0xDA40; +constexpr unsigned int mmSX_PERFCOUNTER0_SELECT__SI = 0x241C; +constexpr unsigned int mmSX_PERFCOUNTER1_HI__CI__VI = 0xD243; +constexpr unsigned int mmSX_PERFCOUNTER1_HI__SI = 0x2423; +constexpr unsigned int mmSX_PERFCOUNTER1_LO__CI__VI = 0xD242; +constexpr unsigned int mmSX_PERFCOUNTER1_LO__SI = 0x2422; +constexpr unsigned int mmSX_PERFCOUNTER1_SELECT1__CI__VI = 0xDA45; +constexpr unsigned int mmSX_PERFCOUNTER1_SELECT__CI__VI = 0xDA41; +constexpr unsigned int mmSX_PERFCOUNTER1_SELECT__SI = 0x241D; +constexpr unsigned int mmSX_PERFCOUNTER2_HI__CI__VI = 0xD245; +constexpr unsigned int mmSX_PERFCOUNTER2_HI__SI = 0x2425; +constexpr unsigned int mmSX_PERFCOUNTER2_LO__CI__VI = 0xD244; +constexpr unsigned int mmSX_PERFCOUNTER2_LO__SI = 0x2424; +constexpr unsigned int mmSX_PERFCOUNTER2_SELECT__CI__VI = 0xDA42; +constexpr unsigned int mmSX_PERFCOUNTER2_SELECT__SI = 0x241E; +constexpr unsigned int mmSX_PERFCOUNTER3_HI__CI__VI = 0xD247; +constexpr unsigned int mmSX_PERFCOUNTER3_HI__SI = 0x2427; +constexpr unsigned int mmSX_PERFCOUNTER3_LO__CI__VI = 0xD246; +constexpr unsigned int mmSX_PERFCOUNTER3_LO__SI = 0x2426; +constexpr unsigned int mmSX_PERFCOUNTER3_SELECT__CI__VI = 0xDA43; +constexpr unsigned int mmSX_PERFCOUNTER3_SELECT__SI = 0x241F; +constexpr unsigned int mmTARGET_AND_CURRENT_PROFILE_INDEX_1__SI = 0x021D; +constexpr unsigned int mmTARGET_AND_CURRENT_PROFILE_INDEX__SI = 0x01E6; +constexpr unsigned int mmTA_BC_BASE_ADDR = 0xA020; +constexpr unsigned int mmTA_BC_BASE_ADDR_HI__CI__VI = 0xA021; +constexpr unsigned int mmTA_CGTT_CTRL__CI__VI = 0xF09D; +constexpr unsigned int mmTA_CGTT_CTRL__SI = 0x2544; +constexpr unsigned int mmTA_CNTL = 0x2541; +constexpr unsigned int mmTA_CNTL_AUX = 0x2542; +constexpr unsigned int mmTA_CS_BC_BASE_ADDR_HI__CI__VI = 0xC381; +constexpr unsigned int mmTA_CS_BC_BASE_ADDR__CI__VI = 0xC380; +constexpr unsigned int mmTA_CS_BC_BASE_ADDR__SI = 0x2543; +constexpr unsigned int mmTA_DEBUG_DATA = 0x254D; +constexpr unsigned int mmTA_DEBUG_INDEX = 0x254C; +constexpr unsigned int mmTA_PERFCOUNTER0_HI__CI__VI = 0xD2C1; +constexpr unsigned int mmTA_PERFCOUNTER0_HI__SI = 0x2556; +constexpr unsigned int mmTA_PERFCOUNTER0_LO__CI__VI = 0xD2C0; +constexpr unsigned int mmTA_PERFCOUNTER0_LO__SI = 0x2555; +constexpr unsigned int mmTA_PERFCOUNTER0_SELECT1__CI__VI = 0xDAC1; +constexpr unsigned int mmTA_PERFCOUNTER0_SELECT__CI__VI = 0xDAC0; +constexpr unsigned int mmTA_PERFCOUNTER0_SELECT__SI = 0x2554; +constexpr unsigned int mmTA_PERFCOUNTER1_HI__CI__VI = 0xD2C3; +constexpr unsigned int mmTA_PERFCOUNTER1_HI__SI = 0x2562; +constexpr unsigned int mmTA_PERFCOUNTER1_LO__CI__VI = 0xD2C2; +constexpr unsigned int mmTA_PERFCOUNTER1_LO__SI = 0x2561; +constexpr unsigned int mmTA_PERFCOUNTER1_SELECT__CI__VI = 0xDAC2; +constexpr unsigned int mmTA_PERFCOUNTER1_SELECT__SI = 0x2560; +constexpr unsigned int mmTA_RESERVED_010C__CI__VI = 0x2543; +constexpr unsigned int mmTA_SCRATCH = 0x2564; +constexpr unsigned int mmTA_STATUS = 0x2548; +constexpr unsigned int mmTCA_CGTT_SCLK_CTRL__CI__VI = 0xF0AD; +constexpr unsigned int mmTCA_CGTT_SCLK_CTRL__SI = 0x2BC1; +constexpr unsigned int mmTCA_CTRL = 0x2BC0; +constexpr unsigned int mmTCA_PERFCOUNTER0_HI__CI__VI = 0xD391; +constexpr unsigned int mmTCA_PERFCOUNTER0_HI__SI = 0x2BD2; +constexpr unsigned int mmTCA_PERFCOUNTER0_LO__CI__VI = 0xD390; +constexpr unsigned int mmTCA_PERFCOUNTER0_LO__SI = 0x2BD1; +constexpr unsigned int mmTCA_PERFCOUNTER0_SELECT1__CI__VI = 0xDB91; +constexpr unsigned int mmTCA_PERFCOUNTER0_SELECT__CI__VI = 0xDB90; +constexpr unsigned int mmTCA_PERFCOUNTER0_SELECT__SI = 0x2BD0; +constexpr unsigned int mmTCA_PERFCOUNTER1_HI__CI__VI = 0xD393; +constexpr unsigned int mmTCA_PERFCOUNTER1_HI__SI = 0x2BD5; +constexpr unsigned int mmTCA_PERFCOUNTER1_LO__CI__VI = 0xD392; +constexpr unsigned int mmTCA_PERFCOUNTER1_LO__SI = 0x2BD4; +constexpr unsigned int mmTCA_PERFCOUNTER1_SELECT1__CI__VI = 0xDB93; +constexpr unsigned int mmTCA_PERFCOUNTER1_SELECT__CI__VI = 0xDB92; +constexpr unsigned int mmTCA_PERFCOUNTER1_SELECT__SI = 0x2BD3; +constexpr unsigned int mmTCA_PERFCOUNTER2_HI__CI__VI = 0xD395; +constexpr unsigned int mmTCA_PERFCOUNTER2_HI__SI = 0x2BD8; +constexpr unsigned int mmTCA_PERFCOUNTER2_LO__CI__VI = 0xD394; +constexpr unsigned int mmTCA_PERFCOUNTER2_LO__SI = 0x2BD7; +constexpr unsigned int mmTCA_PERFCOUNTER2_SELECT__CI__VI = 0xDB94; +constexpr unsigned int mmTCA_PERFCOUNTER2_SELECT__SI = 0x2BD6; +constexpr unsigned int mmTCA_PERFCOUNTER3_HI__CI__VI = 0xD397; +constexpr unsigned int mmTCA_PERFCOUNTER3_HI__SI = 0x2BDB; +constexpr unsigned int mmTCA_PERFCOUNTER3_LO__CI__VI = 0xD396; +constexpr unsigned int mmTCA_PERFCOUNTER3_LO__SI = 0x2BDA; +constexpr unsigned int mmTCA_PERFCOUNTER3_SELECT__CI__VI = 0xDB95; +constexpr unsigned int mmTCA_PERFCOUNTER3_SELECT__SI = 0x2BD9; +constexpr unsigned int mmTCC_CGTT_SCLK_CTRL__CI__VI = 0xF0AC; +constexpr unsigned int mmTCC_CGTT_SCLK_CTRL__SI = 0x2B81; +constexpr unsigned int mmTCC_CTRL = 0x2B80; +constexpr unsigned int mmTCC_EDC_COUNTER__SI__CI = 0x2B82; +constexpr unsigned int mmTCC_PERFCOUNTER0_HI__CI__VI = 0xD381; +constexpr unsigned int mmTCC_PERFCOUNTER0_HI__SI = 0x2B92; +constexpr unsigned int mmTCC_PERFCOUNTER0_LO__CI__VI = 0xD380; +constexpr unsigned int mmTCC_PERFCOUNTER0_LO__SI = 0x2B91; +constexpr unsigned int mmTCC_PERFCOUNTER0_SELECT1__CI__VI = 0xDB81; +constexpr unsigned int mmTCC_PERFCOUNTER0_SELECT__CI__VI = 0xDB80; +constexpr unsigned int mmTCC_PERFCOUNTER0_SELECT__SI = 0x2B90; +constexpr unsigned int mmTCC_PERFCOUNTER1_HI__CI__VI = 0xD383; +constexpr unsigned int mmTCC_PERFCOUNTER1_HI__SI = 0x2B95; +constexpr unsigned int mmTCC_PERFCOUNTER1_LO__CI__VI = 0xD382; +constexpr unsigned int mmTCC_PERFCOUNTER1_LO__SI = 0x2B94; +constexpr unsigned int mmTCC_PERFCOUNTER1_SELECT1__CI__VI = 0xDB83; +constexpr unsigned int mmTCC_PERFCOUNTER1_SELECT__CI__VI = 0xDB82; +constexpr unsigned int mmTCC_PERFCOUNTER1_SELECT__SI = 0x2B93; +constexpr unsigned int mmTCC_PERFCOUNTER2_HI__CI__VI = 0xD385; +constexpr unsigned int mmTCC_PERFCOUNTER2_HI__SI = 0x2B98; +constexpr unsigned int mmTCC_PERFCOUNTER2_LO__CI__VI = 0xD384; +constexpr unsigned int mmTCC_PERFCOUNTER2_LO__SI = 0x2B97; +constexpr unsigned int mmTCC_PERFCOUNTER2_SELECT__CI__VI = 0xDB84; +constexpr unsigned int mmTCC_PERFCOUNTER2_SELECT__SI = 0x2B96; +constexpr unsigned int mmTCC_PERFCOUNTER3_HI__CI__VI = 0xD387; +constexpr unsigned int mmTCC_PERFCOUNTER3_HI__SI = 0x2B9B; +constexpr unsigned int mmTCC_PERFCOUNTER3_LO__CI__VI = 0xD386; +constexpr unsigned int mmTCC_PERFCOUNTER3_LO__SI = 0x2B9A; +constexpr unsigned int mmTCC_PERFCOUNTER3_SELECT__CI__VI = 0xDB85; +constexpr unsigned int mmTCC_PERFCOUNTER3_SELECT__SI = 0x2B99; +constexpr unsigned int mmTCC_REDUNDANCY__CI__VI = 0x2B83; +constexpr unsigned int mmTCI_CNTL_1 = 0x2B62; +constexpr unsigned int mmTCI_CNTL_2 = 0x2B63; +constexpr unsigned int mmTCI_STATUS = 0x2B61; +constexpr unsigned int mmTCP_ADDR_CONFIG = 0x2B05; +constexpr unsigned int mmTCP_BUFFER_ADDR_HASH_CNTL = 0x2B16; +constexpr unsigned int mmTCP_CHAN_STEER_HI = 0x2B04; +constexpr unsigned int mmTCP_CHAN_STEER_LO = 0x2B03; +constexpr unsigned int mmTCP_CNTL = 0x2B02; +constexpr unsigned int mmTCP_CREDIT = 0x2B06; +constexpr unsigned int mmTCP_EDC_COUNTER__SI__CI = 0x2B17; +constexpr unsigned int mmTCP_INVALIDATE = 0x2B00; +constexpr unsigned int mmTCP_PERFCOUNTER0_HI__CI__VI = 0xD341; +constexpr unsigned int mmTCP_PERFCOUNTER0_HI__SI = 0x2B0A; +constexpr unsigned int mmTCP_PERFCOUNTER0_LO__CI__VI = 0xD340; +constexpr unsigned int mmTCP_PERFCOUNTER0_LO__SI = 0x2B0B; +constexpr unsigned int mmTCP_PERFCOUNTER0_SELECT1__CI__VI = 0xDB41; +constexpr unsigned int mmTCP_PERFCOUNTER0_SELECT__CI__VI = 0xDB40; +constexpr unsigned int mmTCP_PERFCOUNTER0_SELECT__SI = 0x2B09; +constexpr unsigned int mmTCP_PERFCOUNTER1_HI__CI__VI = 0xD343; +constexpr unsigned int mmTCP_PERFCOUNTER1_HI__SI = 0x2B0D; +constexpr unsigned int mmTCP_PERFCOUNTER1_LO__CI__VI = 0xD342; +constexpr unsigned int mmTCP_PERFCOUNTER1_LO__SI = 0x2B0E; +constexpr unsigned int mmTCP_PERFCOUNTER1_SELECT1__CI__VI = 0xDB43; +constexpr unsigned int mmTCP_PERFCOUNTER1_SELECT__CI__VI = 0xDB42; +constexpr unsigned int mmTCP_PERFCOUNTER1_SELECT__SI = 0x2B0C; +constexpr unsigned int mmTCP_PERFCOUNTER2_HI__CI__VI = 0xD345; +constexpr unsigned int mmTCP_PERFCOUNTER2_HI__SI = 0x2B10; +constexpr unsigned int mmTCP_PERFCOUNTER2_LO__CI__VI = 0xD344; +constexpr unsigned int mmTCP_PERFCOUNTER2_LO__SI = 0x2B11; +constexpr unsigned int mmTCP_PERFCOUNTER2_SELECT__CI__VI = 0xDB44; +constexpr unsigned int mmTCP_PERFCOUNTER2_SELECT__SI = 0x2B0F; +constexpr unsigned int mmTCP_PERFCOUNTER3_HI__CI__VI = 0xD347; +constexpr unsigned int mmTCP_PERFCOUNTER3_HI__SI = 0x2B13; +constexpr unsigned int mmTCP_PERFCOUNTER3_LO__CI__VI = 0xD346; +constexpr unsigned int mmTCP_PERFCOUNTER3_LO__SI = 0x2B14; +constexpr unsigned int mmTCP_PERFCOUNTER3_SELECT__CI__VI = 0xDB45; +constexpr unsigned int mmTCP_PERFCOUNTER3_SELECT__SI = 0x2B12; +constexpr unsigned int mmTCP_STATUS = 0x2B01; +constexpr unsigned int mmTCP_WATCH0_ADDR_H__CI__VI = 0x32A0; +constexpr unsigned int mmTCP_WATCH0_ADDR_L__CI__VI = 0x32A1; +constexpr unsigned int mmTCP_WATCH0_CNTL__CI__VI = 0x32A2; +constexpr unsigned int mmTCP_WATCH1_ADDR_H__CI__VI = 0x32A3; +constexpr unsigned int mmTCP_WATCH1_ADDR_L__CI__VI = 0x32A4; +constexpr unsigned int mmTCP_WATCH1_CNTL__CI__VI = 0x32A5; +constexpr unsigned int mmTCP_WATCH2_ADDR_H__CI__VI = 0x32A6; +constexpr unsigned int mmTCP_WATCH2_ADDR_L__CI__VI = 0x32A7; +constexpr unsigned int mmTCP_WATCH2_CNTL__CI__VI = 0x32A8; +constexpr unsigned int mmTCP_WATCH3_ADDR_H__CI__VI = 0x32A9; +constexpr unsigned int mmTCP_WATCH3_ADDR_L__CI__VI = 0x32AA; +constexpr unsigned int mmTCP_WATCH3_CNTL__CI__VI = 0x32AB; +constexpr unsigned int mmTCS_CGTT_SCLK_CTRL__CI = 0xF0AE; +constexpr unsigned int mmTCS_CTRL__CI = 0x2BE0; +constexpr unsigned int mmTCS_PERFCOUNTER0_HI__CI = 0xD3A1; +constexpr unsigned int mmTCS_PERFCOUNTER0_LO__CI = 0xD3A0; +constexpr unsigned int mmTCS_PERFCOUNTER0_SELECT1__CI = 0xDBA1; +constexpr unsigned int mmTCS_PERFCOUNTER0_SELECT__CI = 0xDBA0; +constexpr unsigned int mmTCS_PERFCOUNTER1_HI__CI = 0xD3A3; +constexpr unsigned int mmTCS_PERFCOUNTER1_LO__CI = 0xD3A2; +constexpr unsigned int mmTCS_PERFCOUNTER1_SELECT__CI = 0xDBA2; +constexpr unsigned int mmTCS_PERFCOUNTER2_HI__CI = 0xD3A5; +constexpr unsigned int mmTCS_PERFCOUNTER2_LO__CI = 0xD3A4; +constexpr unsigned int mmTCS_PERFCOUNTER2_SELECT__CI = 0xDBA3; +constexpr unsigned int mmTCS_PERFCOUNTER3_HI__CI = 0xD3A7; +constexpr unsigned int mmTCS_PERFCOUNTER3_LO__CI = 0xD3A6; +constexpr unsigned int mmTCS_PERFCOUNTER3_SELECT__CI = 0xDBA4; +constexpr unsigned int mmTC_CFG_L1_LOAD_POLICY0__CI__VI = 0x2B1A; +constexpr unsigned int mmTC_CFG_L1_LOAD_POLICY1__CI__VI = 0x2B1B; +constexpr unsigned int mmTC_CFG_L1_STORE_POLICY__CI__VI = 0x2B1C; +constexpr unsigned int mmTC_CFG_L1_VOLATILE__CI__VI = 0x2B22; +constexpr unsigned int mmTC_CFG_L2_ATOMIC_POLICY__CI__VI = 0x2B21; +constexpr unsigned int mmTC_CFG_L2_LOAD_POLICY0__CI__VI = 0x2B1D; +constexpr unsigned int mmTC_CFG_L2_LOAD_POLICY1__CI__VI = 0x2B1E; +constexpr unsigned int mmTC_CFG_L2_STORE_POLICY0__CI__VI = 0x2B1F; +constexpr unsigned int mmTC_CFG_L2_STORE_POLICY1__CI__VI = 0x2B20; +constexpr unsigned int mmTC_CFG_L2_VOLATILE__CI__VI = 0x2B23; +constexpr unsigned int mmTD_CGTT_CTRL__CI__VI = 0xF09C; +constexpr unsigned int mmTD_CGTT_CTRL__SI = 0x2527; +constexpr unsigned int mmTD_CNTL = 0x2525; +constexpr unsigned int mmTD_DEBUG_DATA = 0x2529; +constexpr unsigned int mmTD_DEBUG_INDEX = 0x2528; +constexpr unsigned int mmTD_PERFCOUNTER0_HI__CI__VI = 0xD301; +constexpr unsigned int mmTD_PERFCOUNTER0_HI__SI = 0x252E; +constexpr unsigned int mmTD_PERFCOUNTER0_LO__CI__VI = 0xD300; +constexpr unsigned int mmTD_PERFCOUNTER0_LO__SI = 0x252D; +constexpr unsigned int mmTD_PERFCOUNTER0_SELECT1__CI__VI = 0xDB01; +constexpr unsigned int mmTD_PERFCOUNTER0_SELECT__CI__VI = 0xDB00; +constexpr unsigned int mmTD_PERFCOUNTER0_SELECT__SI = 0x252C; +constexpr unsigned int mmTD_PERFCOUNTER1_HI__CI__VI = 0xD303; +constexpr unsigned int mmTD_PERFCOUNTER1_LO__CI__VI = 0xD302; +constexpr unsigned int mmTD_PERFCOUNTER1_SELECT__CI__VI = 0xDB02; +constexpr unsigned int mmTD_SCRATCH__CI__VI = 0x2533; +constexpr unsigned int mmTD_SCRATCH__SI = 0x2530; +constexpr unsigned int mmTD_STATUS = 0x2526; +constexpr unsigned int mmTHM_CLK_CNTL__SI = 0x019A; +constexpr unsigned int mmTMDS_CNTL__SI = 0x1C7C; +constexpr unsigned int mmTMDS_CONTROL0_FEEDBACK__SI = 0x1C7E; +constexpr unsigned int mmTMDS_CONTROL_CHAR__SI = 0x1C7D; +constexpr unsigned int mmTMDS_CTL0_1_GEN_CNTL__SI = 0x1C86; +constexpr unsigned int mmTMDS_CTL2_3_GEN_CNTL__SI = 0x1C87; +constexpr unsigned int mmTMDS_CTL_BITS__SI = 0x1C83; +constexpr unsigned int mmTMDS_DCBALANCER_CONTROL__SI = 0x1C84; +constexpr unsigned int mmTMDS_DEBUG__SI = 0x1C82; +constexpr unsigned int mmTMDS_STEREOSYNC_CTL_SEL__SI = 0x1C7F; +constexpr unsigned int mmTMDS_SYNC_CHAR_PATTERN_0_1__SI = 0x1C80; +constexpr unsigned int mmTMDS_SYNC_CHAR_PATTERN_2_3__SI = 0x1C81; +constexpr unsigned int mmUNIPHY_DATA_SYNCHRONIZATION__SI = 0x1984; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKA__SI = 0x1947; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKB__SI = 0x1948; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKC__SI = 0x194D; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKD__SI = 0x194E; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKE__SI = 0x1950; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKF__SI = 0x1951; +constexpr unsigned int mmUNIPHY_IMPCAL_PERIOD__SI = 0x1949; +constexpr unsigned int mmUNIPHY_REG_TEST_OUTPUT__SI = 0x1986; +constexpr unsigned int mmUSER_SQC_BANK_DISABLE = 0x2308; +constexpr unsigned int mmUVD_CGC_CTRL__SI__VI = 0x3D2C; +constexpr unsigned int mmUVD_CGC_GATE__SI__VI = 0x3D2A; +constexpr unsigned int mmUVD_CGC_STATUS__SI__VI = 0x3D2B; +constexpr unsigned int mmUVD_CONFIG__CI__VI = 0x0F93; +constexpr unsigned int mmUVD_CONFIG__SI = 0x0F98; +constexpr unsigned int mmUVD_CONTEXT_ID__SI__VI = 0x3DBD; +constexpr unsigned int mmUVD_CTX_DATA__SI__VI = 0x3D29; +constexpr unsigned int mmUVD_CTX_INDEX__SI__VI = 0x3D28; +constexpr unsigned int mmUVD_ENGINE_CNTL__SI__VI = 0x3BC6; +constexpr unsigned int mmUVD_GPCOM_VCPU_CMD__SI__VI = 0x3BC3; +constexpr unsigned int mmUVD_GPCOM_VCPU_DATA0__SI__VI = 0x3BC4; +constexpr unsigned int mmUVD_GPCOM_VCPU_DATA1__SI__VI = 0x3BC5; +constexpr unsigned int mmUVD_LMI_ADDR_EXT__SI__VI = 0x3D65; +constexpr unsigned int mmUVD_LMI_CTRL2__SI__VI = 0x3D3D; +constexpr unsigned int mmUVD_LMI_CTRL__SI__VI = 0x3D66; +constexpr unsigned int mmUVD_LMI_EXT40_ADDR__SI__VI = 0x3D26; +constexpr unsigned int mmUVD_LMI_STATUS__SI__VI = 0x3D67; +constexpr unsigned int mmUVD_LMI_SWAP_CNTL__SI__VI = 0x3D6D; +constexpr unsigned int mmUVD_MASTINT_EN__SI__VI = 0x3D40; +constexpr unsigned int mmUVD_MPC_CNTL__SI__VI = 0x3D77; +constexpr unsigned int mmUVD_MPC_SET_ALU__SI__VI = 0x3D7E; +constexpr unsigned int mmUVD_MPC_SET_MUXA0__SI__VI = 0x3D79; +constexpr unsigned int mmUVD_MPC_SET_MUXA1__SI__VI = 0x3D7A; +constexpr unsigned int mmUVD_MPC_SET_MUXB0__SI__VI = 0x3D7B; +constexpr unsigned int mmUVD_MPC_SET_MUXB1__SI__VI = 0x3D7C; +constexpr unsigned int mmUVD_MPC_SET_MUX__SI__VI = 0x3D7D; +constexpr unsigned int mmUVD_MP_SWAP_CNTL__SI__VI = 0x3D6F; +constexpr unsigned int mmUVD_RBC_IB_BASE__SI = 0x3DA1; +constexpr unsigned int mmUVD_RBC_IB_SIZE__SI__VI = 0x3DA2; +constexpr unsigned int mmUVD_RBC_RB_BASE__SI = 0x3DA3; +constexpr unsigned int mmUVD_RBC_RB_CNTL__SI__VI = 0x3DA9; +constexpr unsigned int mmUVD_RBC_RB_RPTR_ADDR__SI__VI = 0x3DAA; +constexpr unsigned int mmUVD_RBC_RB_RPTR__SI__VI = 0x3DA4; +constexpr unsigned int mmUVD_RBC_RB_WPTR__SI__VI = 0x3DA5; +constexpr unsigned int mmUVD_SEMA_ADDR_HIGH__SI__VI = 0x3BC1; +constexpr unsigned int mmUVD_SEMA_ADDR_LOW__SI__VI = 0x3BC0; +constexpr unsigned int mmUVD_SEMA_CMD__SI__VI = 0x3BC2; +constexpr unsigned int mmUVD_SEMA_CNTL__SI__VI = 0x3D00; +constexpr unsigned int mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL__SI__VI = 0x3DB3; +constexpr unsigned int mmUVD_SEMA_TIMEOUT_STATUS__SI__VI = 0x3DB0; +constexpr unsigned int mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL__SI__VI = 0x3DB2; +constexpr unsigned int mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL__SI__VI = 0x3DB1; +constexpr unsigned int mmUVD_SOFT_RESET__SI__VI = 0x3DA0; +constexpr unsigned int mmUVD_STATUS__SI__VI = 0x3DAF; +constexpr unsigned int mmUVD_VCPU_CACHE_OFFSET0__SI__VI = 0x3D82; +constexpr unsigned int mmUVD_VCPU_CACHE_OFFSET1__SI__VI = 0x3D84; +constexpr unsigned int mmUVD_VCPU_CACHE_OFFSET2__SI__VI = 0x3D86; +constexpr unsigned int mmUVD_VCPU_CACHE_SIZE0__SI__VI = 0x3D83; +constexpr unsigned int mmUVD_VCPU_CACHE_SIZE1__SI__VI = 0x3D85; +constexpr unsigned int mmUVD_VCPU_CACHE_SIZE2__SI__VI = 0x3D87; +constexpr unsigned int mmUVD_VCPU_CNTL__SI__VI = 0x3D98; +constexpr unsigned int mmVBLANK_STATUS__SI = 0x1AEF; +constexpr unsigned int mmVCE_CONFIG__CI__VI = 0x0F94; +constexpr unsigned int mmVGA25_PPLL_FB_DIV__SI = 0x00DE; +constexpr unsigned int mmVGA25_PPLL_POST_DIV__SI = 0x00E2; +constexpr unsigned int mmVGA25_PPLL_REF_DIV__SI = 0x00D9; +constexpr unsigned int mmVGA28_PPLL_FB_DIV__SI = 0x00DF; +constexpr unsigned int mmVGA28_PPLL_POST_DIV__SI = 0x00E4; +constexpr unsigned int mmVGA28_PPLL_REF_DIV__SI = 0x00DB; +constexpr unsigned int mmVGA41_PPLL_FB_DIV__SI = 0x00E0; +constexpr unsigned int mmVGA41_PPLL_POST_DIV__SI = 0x00E6; +constexpr unsigned int mmVGA41_PPLL_REF_DIV__SI = 0x00DD; +constexpr unsigned int mmVGA_CACHE_CONTROL__SI__VI = 0x00CB; +constexpr unsigned int mmVGA_DEBUG_READBACK_DATA__SI__VI = 0x00D7; +constexpr unsigned int mmVGA_DEBUG_READBACK_INDEX__SI__VI = 0x00D6; +constexpr unsigned int mmVGA_DISPBUF1_SURFACE_ADDR__SI__VI = 0x00C6; +constexpr unsigned int mmVGA_DISPBUF2_SURFACE_ADDR__SI__VI = 0x00C8; +constexpr unsigned int mmVGA_HDP_CONTROL__SI__VI = 0x00CA; +constexpr unsigned int mmVGA_HW_DEBUG__SI__VI = 0x00CF; +constexpr unsigned int mmVGA_INTERRUPT_CONTROL__SI__VI = 0x00D1; +constexpr unsigned int mmVGA_INTERRUPT_STATUS__SI__VI = 0x00D3; +constexpr unsigned int mmVGA_MAIN_CONTROL__SI__VI = 0x00D4; +constexpr unsigned int mmVGA_MEMORY_BASE_ADDRESS_HIGH__SI__VI = 0x00C9; +constexpr unsigned int mmVGA_MEMORY_BASE_ADDRESS__SI__VI = 0x00C4; +constexpr unsigned int mmVGA_MEM_READ_PAGE_ADDR__SI__VI = 0x0013; +constexpr unsigned int mmVGA_MEM_WRITE_PAGE_ADDR__SI__VI = 0x0012; +constexpr unsigned int mmVGA_MODE_CONTROL__SI__VI = 0x00C2; +constexpr unsigned int mmVGA_RENDER_CONTROL__SI__VI = 0x00C0; +constexpr unsigned int mmVGA_SEQUENCER_RESET_CONTROL__SI__VI = 0x00C1; +constexpr unsigned int mmVGA_SOURCE_SELECT__SI__VI = 0x00FC; +constexpr unsigned int mmVGA_STATUS_CLEAR__SI__VI = 0x00D2; +constexpr unsigned int mmVGA_STATUS__SI__VI = 0x00D0; +constexpr unsigned int mmVGA_SURFACE_PITCH_SELECT__SI__VI = 0x00C3; +constexpr unsigned int mmVGA_TEST_CONTROL__SI__VI = 0x00D5; +constexpr unsigned int mmVGA_TEST_DEBUG_DATA__SI__VI = 0x00C7; +constexpr unsigned int mmVGA_TEST_DEBUG_INDEX__SI__VI = 0x00C5; +constexpr unsigned int mmVGT_CACHE_INVALIDATION = 0x2231; +constexpr unsigned int mmVGT_CNTL_STATUS = 0x223C; +constexpr unsigned int mmVGT_DEBUG_CNTL = 0x2238; +constexpr unsigned int mmVGT_DEBUG_DATA = 0x2239; +constexpr unsigned int mmVGT_DMA_BASE = 0xA1FA; +constexpr unsigned int mmVGT_DMA_BASE_HI = 0xA1F9; +constexpr unsigned int mmVGT_DMA_CONTROL__CI__VI = 0x2272; +constexpr unsigned int mmVGT_DMA_DATA_FIFO_DEPTH = 0x222D; +constexpr unsigned int mmVGT_DMA_INDEX_TYPE = 0xA29F; +constexpr unsigned int mmVGT_DMA_LS_HS_CONFIG__CI__VI = 0x2273; +constexpr unsigned int mmVGT_DMA_MAX_SIZE = 0xA29E; +constexpr unsigned int mmVGT_DMA_NUM_INSTANCES = 0xA2A2; +constexpr unsigned int mmVGT_DMA_PRIMITIVE_TYPE__CI__VI = 0x2271; +constexpr unsigned int mmVGT_DMA_REQ_FIFO_DEPTH = 0x222E; +constexpr unsigned int mmVGT_DMA_SIZE = 0xA29D; +constexpr unsigned int mmVGT_DRAW_INITIATOR = 0xA1FC; +constexpr unsigned int mmVGT_DRAW_INIT_FIFO_DEPTH = 0x222F; +constexpr unsigned int mmVGT_ENHANCE = 0xA294; +constexpr unsigned int mmVGT_ESGS_RING_ITEMSIZE = 0xA2AB; +constexpr unsigned int mmVGT_ESGS_RING_SIZE__CI__VI = 0xC240; +constexpr unsigned int mmVGT_ESGS_RING_SIZE__SI = 0x2232; +constexpr unsigned int mmVGT_ES_PER_GS = 0xA296; +constexpr unsigned int mmVGT_EVENT_ADDRESS_REG = 0xA1FE; +constexpr unsigned int mmVGT_EVENT_INITIATOR = 0xA2A4; +constexpr unsigned int mmVGT_FIFO_DEPTHS = 0x2234; +constexpr unsigned int mmVGT_GROUP_DECR = 0xA28B; +constexpr unsigned int mmVGT_GROUP_FIRST_DECR = 0xA28A; +constexpr unsigned int mmVGT_GROUP_PRIM_TYPE = 0xA289; +constexpr unsigned int mmVGT_GROUP_VECT_0_CNTL = 0xA28C; +constexpr unsigned int mmVGT_GROUP_VECT_0_FMT_CNTL = 0xA28E; +constexpr unsigned int mmVGT_GROUP_VECT_1_CNTL = 0xA28D; +constexpr unsigned int mmVGT_GROUP_VECT_1_FMT_CNTL = 0xA28F; +constexpr unsigned int mmVGT_GSVS_RING_ITEMSIZE = 0xA2AC; +constexpr unsigned int mmVGT_GSVS_RING_OFFSET_1 = 0xA298; +constexpr unsigned int mmVGT_GSVS_RING_OFFSET_2 = 0xA299; +constexpr unsigned int mmVGT_GSVS_RING_OFFSET_3 = 0xA29A; +constexpr unsigned int mmVGT_GSVS_RING_SIZE__CI__VI = 0xC241; +constexpr unsigned int mmVGT_GSVS_RING_SIZE__SI = 0x2233; +constexpr unsigned int mmVGT_GS_INSTANCE_CNT = 0xA2E4; +constexpr unsigned int mmVGT_GS_MAX_VERT_OUT = 0xA2CE; +constexpr unsigned int mmVGT_GS_MODE = 0xA290; +constexpr unsigned int mmVGT_GS_ONCHIP_CNTL__CI__VI = 0xA291; +constexpr unsigned int mmVGT_GS_OUT_PRIM_TYPE = 0xA29B; +constexpr unsigned int mmVGT_GS_PER_ES = 0xA295; +constexpr unsigned int mmVGT_GS_PER_VS = 0xA297; +constexpr unsigned int mmVGT_GS_VERTEX_REUSE = 0x2235; +constexpr unsigned int mmVGT_GS_VERT_ITEMSIZE = 0xA2D7; +constexpr unsigned int mmVGT_GS_VERT_ITEMSIZE_1 = 0xA2D8; +constexpr unsigned int mmVGT_GS_VERT_ITEMSIZE_2 = 0xA2D9; +constexpr unsigned int mmVGT_GS_VERT_ITEMSIZE_3 = 0xA2DA; +constexpr unsigned int mmVGT_HOS_CNTL = 0xA285; +constexpr unsigned int mmVGT_HOS_MAX_TESS_LEVEL = 0xA286; +constexpr unsigned int mmVGT_HOS_MIN_TESS_LEVEL = 0xA287; +constexpr unsigned int mmVGT_HOS_REUSE_DEPTH = 0xA288; +constexpr unsigned int mmVGT_HS_OFFCHIP_PARAM__CI__VI = 0xC24F; +constexpr unsigned int mmVGT_HS_OFFCHIP_PARAM__SI = 0x226C; +constexpr unsigned int mmVGT_IMMED_DATA = 0xA1FD; +constexpr unsigned int mmVGT_INDEX_TYPE__CI__VI = 0xC243; +constexpr unsigned int mmVGT_INDEX_TYPE__SI = 0x2257; +constexpr unsigned int mmVGT_INDX_OFFSET = 0xA102; +constexpr unsigned int mmVGT_INSTANCE_STEP_RATE_0 = 0xA2A8; +constexpr unsigned int mmVGT_INSTANCE_STEP_RATE_1 = 0xA2A9; +constexpr unsigned int mmVGT_LAST_COPY_STATE = 0x2230; +constexpr unsigned int mmVGT_LS_HS_CONFIG = 0xA2D6; +constexpr unsigned int mmVGT_MAX_VTX_INDX = 0xA100; +constexpr unsigned int mmVGT_MC_LAT_CNTL = 0x2236; +constexpr unsigned int mmVGT_MIN_VTX_INDX = 0xA101; +constexpr unsigned int mmVGT_MULTI_PRIM_IB_RESET_EN = 0xA2A5; +constexpr unsigned int mmVGT_MULTI_PRIM_IB_RESET_INDX = 0xA103; +constexpr unsigned int mmVGT_NUM_INDICES__CI__VI = 0xC24C; +constexpr unsigned int mmVGT_NUM_INDICES__SI = 0x225C; +constexpr unsigned int mmVGT_NUM_INSTANCES__CI__VI = 0xC24D; +constexpr unsigned int mmVGT_NUM_INSTANCES__SI = 0x225D; +constexpr unsigned int mmVGT_OUTPUT_PATH_CNTL = 0xA284; +constexpr unsigned int mmVGT_OUT_DEALLOC_CNTL = 0xA317; +constexpr unsigned int mmVGT_PERFCOUNTER0_HI__CI__VI = 0xD091; +constexpr unsigned int mmVGT_PERFCOUNTER0_HI__SI = 0x224D; +constexpr unsigned int mmVGT_PERFCOUNTER0_LO__CI__VI = 0xD090; +constexpr unsigned int mmVGT_PERFCOUNTER0_LO__SI = 0x224C; +constexpr unsigned int mmVGT_PERFCOUNTER0_SELECT1__CI__VI = 0xD890; +constexpr unsigned int mmVGT_PERFCOUNTER0_SELECT__CI__VI = 0xD88C; +constexpr unsigned int mmVGT_PERFCOUNTER0_SELECT__SI = 0x2248; +constexpr unsigned int mmVGT_PERFCOUNTER1_HI__CI__VI = 0xD093; +constexpr unsigned int mmVGT_PERFCOUNTER1_HI__SI = 0x224F; +constexpr unsigned int mmVGT_PERFCOUNTER1_LO__CI__VI = 0xD092; +constexpr unsigned int mmVGT_PERFCOUNTER1_LO__SI = 0x224E; +constexpr unsigned int mmVGT_PERFCOUNTER1_SELECT1__CI__VI = 0xD891; +constexpr unsigned int mmVGT_PERFCOUNTER1_SELECT__CI__VI = 0xD88D; +constexpr unsigned int mmVGT_PERFCOUNTER1_SELECT__SI = 0x2249; +constexpr unsigned int mmVGT_PERFCOUNTER2_HI__CI__VI = 0xD095; +constexpr unsigned int mmVGT_PERFCOUNTER2_HI__SI = 0x2251; +constexpr unsigned int mmVGT_PERFCOUNTER2_LO__CI__VI = 0xD094; +constexpr unsigned int mmVGT_PERFCOUNTER2_LO__SI = 0x2250; +constexpr unsigned int mmVGT_PERFCOUNTER2_SELECT__CI__VI = 0xD88E; +constexpr unsigned int mmVGT_PERFCOUNTER2_SELECT__SI = 0x224A; +constexpr unsigned int mmVGT_PERFCOUNTER3_HI__CI__VI = 0xD097; +constexpr unsigned int mmVGT_PERFCOUNTER3_HI__SI = 0x2253; +constexpr unsigned int mmVGT_PERFCOUNTER3_LO__CI__VI = 0xD096; +constexpr unsigned int mmVGT_PERFCOUNTER3_LO__SI = 0x2252; +constexpr unsigned int mmVGT_PERFCOUNTER3_SELECT__CI__VI = 0xD88F; +constexpr unsigned int mmVGT_PERFCOUNTER3_SELECT__SI = 0x224B; +constexpr unsigned int mmVGT_PERFCOUNTER_SEID_MASK__CI__VI = 0xD894; +constexpr unsigned int mmVGT_PERFCOUNTER_SEID_MASK__SI = 0x2247; +constexpr unsigned int mmVGT_PRIMITIVEID_EN = 0xA2A1; +constexpr unsigned int mmVGT_PRIMITIVEID_RESET = 0xA2A3; +constexpr unsigned int mmVGT_PRIMITIVE_TYPE__CI__VI = 0xC242; +constexpr unsigned int mmVGT_PRIMITIVE_TYPE__SI = 0x2256; +constexpr unsigned int mmVGT_RESET_DEBUG__CI__VI = 0x2232; +constexpr unsigned int mmVGT_REUSE_OFF = 0xA2AD; +constexpr unsigned int mmVGT_SHADER_STAGES_EN = 0xA2D5; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_CONFIG = 0xA2E6; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_0__CI__VI = 0xC244; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_0__SI = 0x2258; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_1__CI__VI = 0xC245; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_1__SI = 0x2259; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_2__CI__VI = 0xC246; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_2__SI = 0x225A; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_3__CI__VI = 0xC247; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_FILLED_SIZE_3__SI = 0x225B; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_OFFSET_0 = 0xA2B7; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_OFFSET_1 = 0xA2BB; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_OFFSET_2 = 0xA2BF; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_OFFSET_3 = 0xA2C3; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_SIZE_0 = 0xA2B4; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_SIZE_1 = 0xA2B8; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_SIZE_2 = 0xA2BC; +constexpr unsigned int mmVGT_STRMOUT_BUFFER_SIZE_3 = 0xA2C0; +constexpr unsigned int mmVGT_STRMOUT_CONFIG = 0xA2E5; +constexpr unsigned int mmVGT_STRMOUT_DELAY__CI__VI = 0x2233; +constexpr unsigned int mmVGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE = 0xA2CB; +constexpr unsigned int mmVGT_STRMOUT_DRAW_OPAQUE_OFFSET = 0xA2CA; +constexpr unsigned int mmVGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE = 0xA2CC; +constexpr unsigned int mmVGT_STRMOUT_VTX_STRIDE_0 = 0xA2B5; +constexpr unsigned int mmVGT_STRMOUT_VTX_STRIDE_1 = 0xA2B9; +constexpr unsigned int mmVGT_STRMOUT_VTX_STRIDE_2 = 0xA2BD; +constexpr unsigned int mmVGT_STRMOUT_VTX_STRIDE_3 = 0xA2C1; +constexpr unsigned int mmVGT_SYS_CONFIG = 0x2263; +constexpr unsigned int mmVGT_TF_MEMORY_BASE__CI__VI = 0xC250; +constexpr unsigned int mmVGT_TF_MEMORY_BASE__SI = 0x226E; +constexpr unsigned int mmVGT_TF_PARAM = 0xA2DB; +constexpr unsigned int mmVGT_TF_RING_SIZE__CI__VI = 0xC24E; +constexpr unsigned int mmVGT_TF_RING_SIZE__SI = 0x2262; +constexpr unsigned int mmVGT_VERTEX_REUSE_BLOCK_CNTL = 0xA316; +constexpr unsigned int mmVGT_VS_MAX_WAVE_ID__CI__VI = 0x2268; +constexpr unsigned int mmVGT_VTX_CNT_EN = 0xA2AE; +constexpr unsigned int mmVGT_VTX_VECT_EJECT_REG = 0x222C; +constexpr unsigned int mmVIEWPORT_SIZE__SI__VI = 0x1B5D; +constexpr unsigned int mmVIEWPORT_START__SI__VI = 0x1B5C; +constexpr unsigned int mmVLINE_STATUS__SI = 0x1AEE; +constexpr unsigned int mmVM_CONTEXT0_CNTL = 0x0504; +constexpr unsigned int mmVM_CONTEXT0_CNTL2 = 0x050C; +constexpr unsigned int mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR = 0x054F; +constexpr unsigned int mmVM_CONTEXT0_PAGE_TABLE_END_ADDR = 0x055F; +constexpr unsigned int mmVM_CONTEXT0_PAGE_TABLE_START_ADDR = 0x0557; +constexpr unsigned int mmVM_CONTEXT0_PROTECTION_FAULT_ADDR = 0x053E; +constexpr unsigned int mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR = 0x0546; +constexpr unsigned int mmVM_CONTEXT0_PROTECTION_FAULT_MCCLIENT__CI__VI = 0x0538; +constexpr unsigned int mmVM_CONTEXT0_PROTECTION_FAULT_STATUS = 0x0536; +constexpr unsigned int mmVM_CONTEXT10_PAGE_TABLE_BASE_ADDR = 0x0510; +constexpr unsigned int mmVM_CONTEXT11_PAGE_TABLE_BASE_ADDR = 0x0511; +constexpr unsigned int mmVM_CONTEXT12_PAGE_TABLE_BASE_ADDR = 0x0512; +constexpr unsigned int mmVM_CONTEXT13_PAGE_TABLE_BASE_ADDR = 0x0513; +constexpr unsigned int mmVM_CONTEXT14_PAGE_TABLE_BASE_ADDR = 0x0514; +constexpr unsigned int mmVM_CONTEXT15_PAGE_TABLE_BASE_ADDR = 0x0515; +constexpr unsigned int mmVM_CONTEXT1_CNTL = 0x0505; +constexpr unsigned int mmVM_CONTEXT1_CNTL2 = 0x050D; +constexpr unsigned int mmVM_CONTEXT1_PAGE_TABLE_BASE_ADDR = 0x0550; +constexpr unsigned int mmVM_CONTEXT1_PAGE_TABLE_END_ADDR = 0x0560; +constexpr unsigned int mmVM_CONTEXT1_PAGE_TABLE_START_ADDR = 0x0558; +constexpr unsigned int mmVM_CONTEXT1_PROTECTION_FAULT_ADDR = 0x053F; +constexpr unsigned int mmVM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR = 0x0547; +constexpr unsigned int mmVM_CONTEXT1_PROTECTION_FAULT_MCCLIENT__CI__VI = 0x0539; +constexpr unsigned int mmVM_CONTEXT1_PROTECTION_FAULT_STATUS = 0x0537; +constexpr unsigned int mmVM_CONTEXT2_PAGE_TABLE_BASE_ADDR = 0x0551; +constexpr unsigned int mmVM_CONTEXT3_PAGE_TABLE_BASE_ADDR = 0x0552; +constexpr unsigned int mmVM_CONTEXT4_PAGE_TABLE_BASE_ADDR = 0x0553; +constexpr unsigned int mmVM_CONTEXT5_PAGE_TABLE_BASE_ADDR = 0x0554; +constexpr unsigned int mmVM_CONTEXT6_PAGE_TABLE_BASE_ADDR = 0x0555; +constexpr unsigned int mmVM_CONTEXT7_PAGE_TABLE_BASE_ADDR = 0x0556; +constexpr unsigned int mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR = 0x050E; +constexpr unsigned int mmVM_CONTEXT9_PAGE_TABLE_BASE_ADDR = 0x050F; +constexpr unsigned int mmVM_CONTEXTS_DISABLE = 0x0535; +constexpr unsigned int mmVM_DEBUG = 0x056F; +constexpr unsigned int mmVM_DUMMY_PAGE_FAULT_ADDR = 0x0507; +constexpr unsigned int mmVM_DUMMY_PAGE_FAULT_CNTL = 0x0506; +constexpr unsigned int mmVM_FAULT_CLIENT_ID = 0x054E; +constexpr unsigned int mmVM_INVALIDATE_REQUEST = 0x051E; +constexpr unsigned int mmVM_INVALIDATE_RESPONSE = 0x051F; +constexpr unsigned int mmVM_L2_BANK_SELECT_MASKA = 0x0572; +constexpr unsigned int mmVM_L2_BANK_SELECT_MASKB = 0x0573; +constexpr unsigned int mmVM_L2_CG = 0x0570; +constexpr unsigned int mmVM_L2_CNTL = 0x0500; +constexpr unsigned int mmVM_L2_CNTL2 = 0x0501; +constexpr unsigned int mmVM_L2_CNTL3 = 0x0502; +constexpr unsigned int mmVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR = 0x0576; +constexpr unsigned int mmVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR = 0x0575; +constexpr unsigned int mmVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET = 0x0577; +constexpr unsigned int mmVM_L2_STATUS = 0x0503; +constexpr unsigned int mmVM_PRT_APERTURE0_HIGH_ADDR = 0x0530; +constexpr unsigned int mmVM_PRT_APERTURE0_LOW_ADDR = 0x052C; +constexpr unsigned int mmVM_PRT_APERTURE1_HIGH_ADDR = 0x0531; +constexpr unsigned int mmVM_PRT_APERTURE1_LOW_ADDR = 0x052D; +constexpr unsigned int mmVM_PRT_APERTURE2_HIGH_ADDR = 0x0532; +constexpr unsigned int mmVM_PRT_APERTURE2_LOW_ADDR = 0x052E; +constexpr unsigned int mmVM_PRT_APERTURE3_HIGH_ADDR = 0x0533; +constexpr unsigned int mmVM_PRT_APERTURE3_LOW_ADDR = 0x052F; +constexpr unsigned int mmVM_PRT_CNTL = 0x0534; +constexpr unsigned int mmWD_CNTL_STATUS__CI__VI = 0x223F; +constexpr unsigned int mmWD_DEBUG_CNTL__CI__VI = 0x223D; +constexpr unsigned int mmWD_DEBUG_DATA__CI__VI = 0x223E; +constexpr unsigned int mmWD_ENHANCE__CI__VI = 0xA2A0; +constexpr unsigned int mmWD_PERFCOUNTER0_HI__CI__VI = 0xD081; +constexpr unsigned int mmWD_PERFCOUNTER0_LO__CI__VI = 0xD080; +constexpr unsigned int mmWD_PERFCOUNTER0_SELECT__CI__VI = 0xD880; +constexpr unsigned int mmWD_PERFCOUNTER1_HI__CI__VI = 0xD083; +constexpr unsigned int mmWD_PERFCOUNTER1_LO__CI__VI = 0xD082; +constexpr unsigned int mmWD_PERFCOUNTER1_SELECT__CI__VI = 0xD881; +constexpr unsigned int mmWD_PERFCOUNTER2_HI__CI__VI = 0xD085; +constexpr unsigned int mmWD_PERFCOUNTER2_LO__CI__VI = 0xD084; +constexpr unsigned int mmWD_PERFCOUNTER2_SELECT__CI__VI = 0xD882; +constexpr unsigned int mmWD_PERFCOUNTER3_HI__CI__VI = 0xD087; +constexpr unsigned int mmWD_PERFCOUNTER3_LO__CI__VI = 0xD086; +constexpr unsigned int mmWD_PERFCOUNTER3_SELECT__CI__VI = 0xD883; +constexpr unsigned int mmXDMA_SLV_FLIP_PENDING__CI__VI = 0x046C; +constexpr unsigned int mmXDMA_SLV_FLIP_PENDING__SI = 0x0407; +constexpr unsigned int pciADAPTER_ID = 0x000B; +constexpr unsigned int pciADAPTER_ID_W = 0x0013; +constexpr unsigned int pciBASE_ADDR_1 = 0x0004; +constexpr unsigned int pciBASE_ADDR_2 = 0x0005; +constexpr unsigned int pciBASE_ADDR_3 = 0x0006; +constexpr unsigned int pciBASE_ADDR_4 = 0x0007; +constexpr unsigned int pciBASE_ADDR_5 = 0x0008; +constexpr unsigned int pciBASE_ADDR_6 = 0x0009; +constexpr unsigned int pciBASE_CLASS = 0x0002; +constexpr unsigned int pciBIST = 0x0003; +constexpr unsigned int pciCACHE_LINE = 0x0003; +constexpr unsigned int pciCAP_PTR = 0x000D; +constexpr unsigned int pciCOMMAND = 0x0001; +constexpr unsigned int pciDEVICE_CAP = 0x0017; +constexpr unsigned int pciDEVICE_CAP2 = 0x001F; +constexpr unsigned int pciDEVICE_CNTL = 0x0018; +constexpr unsigned int pciDEVICE_CNTL2 = 0x0020; +constexpr unsigned int pciDEVICE_ID = 0x0000; +constexpr unsigned int pciDEVICE_STATUS = 0x0018; +constexpr unsigned int pciDEVICE_STATUS2 = 0x0020; +constexpr unsigned int pciHEADER = 0x0003; +constexpr unsigned int pciINTERRUPT_LINE = 0x000F; +constexpr unsigned int pciINTERRUPT_PIN = 0x000F; +constexpr unsigned int pciLATENCY = 0x0003; +constexpr unsigned int pciLINK_CAP = 0x0019; +constexpr unsigned int pciLINK_CAP2 = 0x0021; +constexpr unsigned int pciLINK_CNTL = 0x001A; +constexpr unsigned int pciLINK_CNTL2 = 0x0022; +constexpr unsigned int pciLINK_STATUS = 0x001A; +constexpr unsigned int pciLINK_STATUS2 = 0x0022; +constexpr unsigned int pciMAX_LATENCY = 0x000F; +constexpr unsigned int pciMIN_GRANT = 0x000F; +constexpr unsigned int pciMSI_CAP_LIST = 0x0028; +constexpr unsigned int pciMSI_MSG_ADDR_HI = 0x002A; +constexpr unsigned int pciMSI_MSG_ADDR_LO = 0x0029; +constexpr unsigned int pciMSI_MSG_CNTL = 0x0028; +constexpr unsigned int pciMSI_MSG_DATA = 0x002A; +constexpr unsigned int pciMSI_MSG_DATA_64 = 0x002B; +constexpr unsigned int pciPCIE_ACS_CAP__CI__VI = 0x00A9; +constexpr unsigned int pciPCIE_ACS_CNTL__CI__VI = 0x00A9; +constexpr unsigned int pciPCIE_ACS_ENH_CAP_LIST__CI__VI = 0x00A8; +constexpr unsigned int pciPCIE_ADV_ERR_CAP_CNTL = 0x005A; +constexpr unsigned int pciPCIE_ADV_ERR_RPT_ENH_CAP_LIST = 0x0054; +constexpr unsigned int pciPCIE_ATS_CAP__CI__VI = 0x00AD; +constexpr unsigned int pciPCIE_ATS_CNTL__CI__VI = 0x00AD; +constexpr unsigned int pciPCIE_ATS_ENH_CAP_LIST__CI__VI = 0x00AC; +constexpr unsigned int pciPCIE_BAR1_CAP__CI__VI = 0x0081; +constexpr unsigned int pciPCIE_BAR1_CNTL__CI__VI = 0x0082; +constexpr unsigned int pciPCIE_BAR2_CAP__CI__VI = 0x0083; +constexpr unsigned int pciPCIE_BAR2_CNTL__CI__VI = 0x0084; +constexpr unsigned int pciPCIE_BAR3_CAP__CI__VI = 0x0085; +constexpr unsigned int pciPCIE_BAR3_CNTL__CI__VI = 0x0086; +constexpr unsigned int pciPCIE_BAR4_CAP__CI__VI = 0x0087; +constexpr unsigned int pciPCIE_BAR4_CNTL__CI__VI = 0x0088; +constexpr unsigned int pciPCIE_BAR5_CAP__CI__VI = 0x0089; +constexpr unsigned int pciPCIE_BAR5_CNTL__CI__VI = 0x008A; +constexpr unsigned int pciPCIE_BAR6_CAP__CI__VI = 0x008B; +constexpr unsigned int pciPCIE_BAR6_CNTL__CI__VI = 0x008C; +constexpr unsigned int pciPCIE_BAR_ENH_CAP_LIST__CI__VI = 0x0080; +constexpr unsigned int pciPCIE_CAP = 0x0016; +constexpr unsigned int pciPCIE_CAP_LIST = 0x0016; +constexpr unsigned int pciPCIE_CORR_ERR_MASK = 0x0059; +constexpr unsigned int pciPCIE_CORR_ERR_STATUS = 0x0058; +constexpr unsigned int pciPCIE_DEV_SERIAL_NUM_DW1 = 0x0051; +constexpr unsigned int pciPCIE_DEV_SERIAL_NUM_DW2 = 0x0052; +constexpr unsigned int pciPCIE_DEV_SERIAL_NUM_ENH_CAP_LIST = 0x0050; +constexpr unsigned int pciPCIE_DPA_CAP__CI__VI = 0x0095; +constexpr unsigned int pciPCIE_DPA_CNTL__CI__VI = 0x0097; +constexpr unsigned int pciPCIE_DPA_ENH_CAP_LIST__CI__VI = 0x0094; +constexpr unsigned int pciPCIE_DPA_LATENCY_INDICATOR__CI__VI = 0x0096; +constexpr unsigned int pciPCIE_DPA_STATUS__CI__VI = 0x0097; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_0__CI__VI = 0x0098; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_1__CI__VI = 0x0098; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_2__CI__VI = 0x0098; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_3__CI__VI = 0x0098; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_4__CI__VI = 0x0099; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_5__CI__VI = 0x0099; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_6__CI__VI = 0x0099; +constexpr unsigned int pciPCIE_DPA_SUBSTATE_PWR_ALLOC_7__CI__VI = 0x0099; +constexpr unsigned int pciPCIE_HDR_LOG0 = 0x005B; +constexpr unsigned int pciPCIE_HDR_LOG1 = 0x005C; +constexpr unsigned int pciPCIE_HDR_LOG2 = 0x005D; +constexpr unsigned int pciPCIE_HDR_LOG3 = 0x005E; +constexpr unsigned int pciPCIE_LANE_0_EQUALIZATION_CNTL__CI__VI = 0x009F; +constexpr unsigned int pciPCIE_LANE_10_EQUALIZATION_CNTL__CI__VI = 0x00A4; +constexpr unsigned int pciPCIE_LANE_11_EQUALIZATION_CNTL__CI__VI = 0x00A4; +constexpr unsigned int pciPCIE_LANE_12_EQUALIZATION_CNTL__CI__VI = 0x00A5; +constexpr unsigned int pciPCIE_LANE_13_EQUALIZATION_CNTL__CI__VI = 0x00A5; +constexpr unsigned int pciPCIE_LANE_14_EQUALIZATION_CNTL__CI__VI = 0x00A6; +constexpr unsigned int pciPCIE_LANE_15_EQUALIZATION_CNTL__CI__VI = 0x00A6; +constexpr unsigned int pciPCIE_LANE_1_EQUALIZATION_CNTL__CI__VI = 0x009F; +constexpr unsigned int pciPCIE_LANE_2_EQUALIZATION_CNTL__CI__VI = 0x00A0; +constexpr unsigned int pciPCIE_LANE_3_EQUALIZATION_CNTL__CI__VI = 0x00A0; +constexpr unsigned int pciPCIE_LANE_4_EQUALIZATION_CNTL__CI__VI = 0x00A1; +constexpr unsigned int pciPCIE_LANE_5_EQUALIZATION_CNTL__CI__VI = 0x00A1; +constexpr unsigned int pciPCIE_LANE_6_EQUALIZATION_CNTL__CI__VI = 0x00A2; +constexpr unsigned int pciPCIE_LANE_7_EQUALIZATION_CNTL__CI__VI = 0x00A2; +constexpr unsigned int pciPCIE_LANE_8_EQUALIZATION_CNTL__CI__VI = 0x00A3; +constexpr unsigned int pciPCIE_LANE_9_EQUALIZATION_CNTL__CI__VI = 0x00A3; +constexpr unsigned int pciPCIE_LANE_ERROR_STATUS__CI__VI = 0x009E; +constexpr unsigned int pciPCIE_LINK_CNTL3__CI__VI = 0x009D; +constexpr unsigned int pciPCIE_OUTSTAND_PAGE_REQ_ALLOC__CI__VI = 0x00B3; +constexpr unsigned int pciPCIE_OUTSTAND_PAGE_REQ_CAPACITY__CI__VI = 0x00B2; +constexpr unsigned int pciPCIE_PAGE_REQ_CNTL__CI__VI = 0x00B1; +constexpr unsigned int pciPCIE_PAGE_REQ_ENH_CAP_LIST__CI__VI = 0x00B0; +constexpr unsigned int pciPCIE_PAGE_REQ_STATUS__CI__VI = 0x00B1; +constexpr unsigned int pciPCIE_PASID_CAP__CI__VI = 0x00B5; +constexpr unsigned int pciPCIE_PASID_CNTL__CI__VI = 0x00B5; +constexpr unsigned int pciPCIE_PASID_ENH_CAP_LIST__CI__VI = 0x00B4; +constexpr unsigned int pciPCIE_PORT_VC_CAP_REG1 = 0x0045; +constexpr unsigned int pciPCIE_PORT_VC_CAP_REG2 = 0x0046; +constexpr unsigned int pciPCIE_PORT_VC_CNTL = 0x0047; +constexpr unsigned int pciPCIE_PORT_VC_STATUS = 0x0047; +constexpr unsigned int pciPCIE_PWR_BUDGET_CAP__CI__VI = 0x0093; +constexpr unsigned int pciPCIE_PWR_BUDGET_DATA_SELECT__CI__VI = 0x0091; +constexpr unsigned int pciPCIE_PWR_BUDGET_DATA__CI__VI = 0x0092; +constexpr unsigned int pciPCIE_PWR_BUDGET_ENH_CAP_LIST__CI__VI = 0x0090; +constexpr unsigned int pciPCIE_SECONDARY_ENH_CAP_LIST__CI__VI = 0x009C; +constexpr unsigned int pciPCIE_TLP_PREFIX_LOG0__CI__VI = 0x0062; +constexpr unsigned int pciPCIE_TLP_PREFIX_LOG1__CI__VI = 0x0063; +constexpr unsigned int pciPCIE_TLP_PREFIX_LOG2__CI__VI = 0x0064; +constexpr unsigned int pciPCIE_TLP_PREFIX_LOG3__CI__VI = 0x0065; +constexpr unsigned int pciPCIE_UNCORR_ERR_MASK = 0x0056; +constexpr unsigned int pciPCIE_UNCORR_ERR_SEVERITY = 0x0057; +constexpr unsigned int pciPCIE_UNCORR_ERR_STATUS = 0x0055; +constexpr unsigned int pciPCIE_VC0_RESOURCE_CAP = 0x0048; +constexpr unsigned int pciPCIE_VC0_RESOURCE_CNTL = 0x0049; +constexpr unsigned int pciPCIE_VC0_RESOURCE_STATUS = 0x004A; +constexpr unsigned int pciPCIE_VC1_RESOURCE_CAP = 0x004B; +constexpr unsigned int pciPCIE_VC1_RESOURCE_CNTL = 0x004C; +constexpr unsigned int pciPCIE_VC1_RESOURCE_STATUS = 0x004D; +constexpr unsigned int pciPCIE_VC_ENH_CAP_LIST = 0x0044; +constexpr unsigned int pciPCIE_VENDOR_SPECIFIC1 = 0x0042; +constexpr unsigned int pciPCIE_VENDOR_SPECIFIC2 = 0x0043; +constexpr unsigned int pciPCIE_VENDOR_SPECIFIC_ENH_CAP_LIST = 0x0040; +constexpr unsigned int pciPCIE_VENDOR_SPECIFIC_HDR = 0x0041; +constexpr unsigned int pciPMI_CAP = 0x0014; +constexpr unsigned int pciPMI_CAP_LIST = 0x0014; +constexpr unsigned int pciPMI_STATUS_CNTL = 0x0015; +constexpr unsigned int pciPROG_INTERFACE = 0x0002; +constexpr unsigned int pciREVISION_ID = 0x0002; +constexpr unsigned int pciROM_BASE_ADDR = 0x000C; +constexpr unsigned int pciSTATUS = 0x0001; +constexpr unsigned int pciSUB_CLASS = 0x0002; +constexpr unsigned int pciVENDOR_CAP_LIST__CI__VI = 0x0012; +constexpr unsigned int pciVENDOR_ID = 0x0000; + +//Merged Defines + +constexpr unsigned int cfgMSI_MASK__VI = 0x002B; +constexpr unsigned int cfgMSI_MASK_64__VI = 0x002C; +constexpr unsigned int cfgMSI_PENDING__VI = 0x002C; +constexpr unsigned int cfgMSI_PENDING_64__VI = 0x002D; +constexpr unsigned int cfgPCIE_ARI_CAP__VI = 0x00CB; +constexpr unsigned int cfgPCIE_ARI_CNTL__VI = 0x00CB; +constexpr unsigned int cfgPCIE_ARI_ENH_CAP_LIST__VI = 0x00CA; +constexpr unsigned int cfgPCIE_LTR_CAP__VI = 0x00C9; +constexpr unsigned int cfgPCIE_LTR_ENH_CAP_LIST__VI = 0x00C8; +constexpr unsigned int cfgPCIE_MC_ADDR0__VI = 0x00BE; +constexpr unsigned int cfgPCIE_MC_ADDR1__VI = 0x00BF; +constexpr unsigned int cfgPCIE_MC_BLOCK_ALL0__VI = 0x00C2; +constexpr unsigned int cfgPCIE_MC_BLOCK_ALL1__VI = 0x00C3; +constexpr unsigned int cfgPCIE_MC_BLOCK_UNTRANSLATED_0__VI = 0x00C4; +constexpr unsigned int cfgPCIE_MC_BLOCK_UNTRANSLATED_1__VI = 0x00C5; +constexpr unsigned int cfgPCIE_MC_CAP__VI = 0x00BD; +constexpr unsigned int cfgPCIE_MC_CNTL__VI = 0x00BD; +constexpr unsigned int cfgPCIE_MC_ENH_CAP_LIST__VI = 0x00BC; +constexpr unsigned int cfgPCIE_MC_RCV0__VI = 0x00C0; +constexpr unsigned int cfgPCIE_MC_RCV1__VI = 0x00C1; +constexpr unsigned int cfgPCIE_SRIOV_CAP__VI = 0x00CD; +constexpr unsigned int cfgPCIE_SRIOV_CONTROL__VI = 0x00CE; +constexpr unsigned int cfgPCIE_SRIOV_ENH_CAP_LIST__VI = 0x00CC; +constexpr unsigned int cfgPCIE_SRIOV_FIRST_VF_OFFSET__VI = 0x00D1; +constexpr unsigned int cfgPCIE_SRIOV_FUNC_DEP_LINK__VI = 0x00D0; +constexpr unsigned int cfgPCIE_SRIOV_INITIAL_VFS__VI = 0x00CF; +constexpr unsigned int cfgPCIE_SRIOV_NUM_VFS__VI = 0x00D0; +constexpr unsigned int cfgPCIE_SRIOV_STATUS__VI = 0x00CE; +constexpr unsigned int cfgPCIE_SRIOV_SUPPORTED_PAGE_SIZE__VI = 0x00D3; +constexpr unsigned int cfgPCIE_SRIOV_SYSTEM_PAGE_SIZE__VI = 0x00D4; +constexpr unsigned int cfgPCIE_SRIOV_TOTAL_VFS__VI = 0x00CF; +constexpr unsigned int cfgPCIE_SRIOV_VF_BASE_ADDR_0__VI = 0x00D5; +constexpr unsigned int cfgPCIE_SRIOV_VF_BASE_ADDR_1__VI = 0x00D6; +constexpr unsigned int cfgPCIE_SRIOV_VF_BASE_ADDR_2__VI = 0x00D7; +constexpr unsigned int cfgPCIE_SRIOV_VF_BASE_ADDR_3__VI = 0x00D8; +constexpr unsigned int cfgPCIE_SRIOV_VF_BASE_ADDR_4__VI = 0x00D9; +constexpr unsigned int cfgPCIE_SRIOV_VF_BASE_ADDR_5__VI = 0x00DA; +constexpr unsigned int cfgPCIE_SRIOV_VF_DEVICE_ID__VI = 0x00D2; +constexpr unsigned int cfgPCIE_SRIOV_VF_MIGRATION_STATE_ARRAY_OFFSET__VI = 0x00DB; +constexpr unsigned int cfgPCIE_SRIOV_VF_STRIDE__VI = 0x00D1; +constexpr unsigned int cfgPCIE_TPH_REQR_CAP__VI = 0x00B9; +constexpr unsigned int cfgPCIE_TPH_REQR_CNTL__VI = 0x00BA; +constexpr unsigned int cfgPCIE_TPH_REQR_ENH_CAP_LIST__VI = 0x00B8; +constexpr unsigned int cfgPCIE_VENDOR_SPECIFIC_ENH_CAP_LIST_GPUIOV__VI = 0x0100; +constexpr unsigned int cfgPCIE_VENDOR_SPECIFIC_HDR_GPUIOV__VI = 0x0101; +constexpr unsigned int cfgPCIE_VENDOR_SPECIFIC_HDR_GPUIOV_RESET_CONTROL__VI = 0x0105; +constexpr unsigned int mmAFMT_60958_0__VI = 0x4A38; +constexpr unsigned int mmAFMT_60958_1__VI = 0x4A39; +constexpr unsigned int mmAFMT_60958_2__VI = 0x4A3F; +constexpr unsigned int mmAFMT_AUDIO_CRC_CONTROL__VI = 0x4A3A; +constexpr unsigned int mmAFMT_AUDIO_CRC_RESULT__VI = 0x4A40; +constexpr unsigned int mmAFMT_AUDIO_DBG_DTO_CNTL__VI = 0x4A46; +constexpr unsigned int mmAFMT_AUDIO_INFO0__VI = 0x4A36; +constexpr unsigned int mmAFMT_AUDIO_INFO1__VI = 0x4A37; +constexpr unsigned int mmAFMT_AUDIO_PACKET_CONTROL__VI = 0x4A42; +constexpr unsigned int mmAFMT_AUDIO_PACKET_CONTROL2__VI = 0x4A14; +constexpr unsigned int mmAFMT_AUDIO_SRC_CONTROL__VI = 0x4A45; +constexpr unsigned int mmAFMT_AVI_INFO0__VI = 0x4A1E; +constexpr unsigned int mmAFMT_AVI_INFO1__VI = 0x4A1F; +constexpr unsigned int mmAFMT_AVI_INFO2__VI = 0x4A20; +constexpr unsigned int mmAFMT_AVI_INFO3__VI = 0x4A21; +constexpr unsigned int mmAFMT_GENERIC_0__VI = 0x4A25; +constexpr unsigned int mmAFMT_GENERIC_1__VI = 0x4A26; +constexpr unsigned int mmAFMT_GENERIC_2__VI = 0x4A27; +constexpr unsigned int mmAFMT_GENERIC_3__VI = 0x4A28; +constexpr unsigned int mmAFMT_GENERIC_4__VI = 0x4A29; +constexpr unsigned int mmAFMT_GENERIC_5__VI = 0x4A2A; +constexpr unsigned int mmAFMT_GENERIC_6__VI = 0x4A2B; +constexpr unsigned int mmAFMT_GENERIC_7__VI = 0x4A2C; +constexpr unsigned int mmAFMT_GENERIC_HDR__VI = 0x4A24; +constexpr unsigned int mmAFMT_INFOFRAME_CONTROL0__VI = 0x4A44; +constexpr unsigned int mmAFMT_ISRC1_0__VI = 0x4A15; +constexpr unsigned int mmAFMT_ISRC1_1__VI = 0x4A16; +constexpr unsigned int mmAFMT_ISRC1_2__VI = 0x4A17; +constexpr unsigned int mmAFMT_ISRC1_3__VI = 0x4A18; +constexpr unsigned int mmAFMT_ISRC1_4__VI = 0x4A19; +constexpr unsigned int mmAFMT_ISRC2_0__VI = 0x4A1A; +constexpr unsigned int mmAFMT_ISRC2_1__VI = 0x4A1B; +constexpr unsigned int mmAFMT_ISRC2_2__VI = 0x4A1C; +constexpr unsigned int mmAFMT_ISRC2_3__VI = 0x4A1D; +constexpr unsigned int mmAFMT_MPEG_INFO0__VI = 0x4A22; +constexpr unsigned int mmAFMT_MPEG_INFO1__VI = 0x4A23; +constexpr unsigned int mmAFMT_RAMP_CONTROL0__VI = 0x4A3B; +constexpr unsigned int mmAFMT_RAMP_CONTROL1__VI = 0x4A3C; +constexpr unsigned int mmAFMT_RAMP_CONTROL2__VI = 0x4A3D; +constexpr unsigned int mmAFMT_RAMP_CONTROL3__VI = 0x4A3E; +constexpr unsigned int mmAFMT_STATUS__VI = 0x4A41; +constexpr unsigned int mmAFMT_VBI_PACKET_CONTROL__VI = 0x4A43; +constexpr unsigned int mmALPHA_CONTROL__VI = 0x1ABC; +constexpr unsigned int mmATC_ATS_FAULT_STATUS_INFO2__VI = 0x0CD2; +constexpr unsigned int mmATC_ATS_SMU_STATUS__VI = 0x0D08; +constexpr unsigned int mmATC_ATS_VMID_STATUS__VI = 0x0D07; +constexpr unsigned int mmATC_L1RD_DEBUG2_TLB__VI = 0x0CE2; +constexpr unsigned int mmATC_L1WR_DEBUG2_TLB__VI = 0x0CE3; +constexpr unsigned int mmATC_L2_CACHE_DATA0__VI = 0x0CD9; +constexpr unsigned int mmATC_L2_CACHE_DATA1__VI = 0x0CDA; +constexpr unsigned int mmATC_L2_CACHE_DATA2__VI = 0x0CDB; +constexpr unsigned int mmATC_L2_CNTL3__VI = 0x0D08; +constexpr unsigned int mmATC_L2_STATUS__VI = 0x0D09; +constexpr unsigned int mmATC_L2_STATUS2__VI = 0x0D0A; +constexpr unsigned int mmAUXN_IMPCAL__VI = 0x483C; +constexpr unsigned int mmAUXP_IMPCAL__VI = 0x483B; +constexpr unsigned int mmAUX_ARB_CONTROL__VI = 0x5C02; +constexpr unsigned int mmAUX_CONTROL__VI = 0x5C00; +constexpr unsigned int mmAUX_DPHY_RX_CONTROL0__VI = 0x5C0A; +constexpr unsigned int mmAUX_DPHY_RX_CONTROL1__VI = 0x5C0B; +constexpr unsigned int mmAUX_DPHY_RX_STATUS__VI = 0x5C0D; +constexpr unsigned int mmAUX_DPHY_TX_CONTROL__VI = 0x5C09; +constexpr unsigned int mmAUX_DPHY_TX_REF_CONTROL__VI = 0x5C08; +constexpr unsigned int mmAUX_DPHY_TX_STATUS__VI = 0x5C0C; +constexpr unsigned int mmAUX_GTC_SYNC_CONTROL__VI = 0x5C0E; +constexpr unsigned int mmAUX_GTC_SYNC_CONTROLLER_STATUS__VI = 0x5C10; +constexpr unsigned int mmAUX_GTC_SYNC_DATA__VI = 0x5C12; +constexpr unsigned int mmAUX_GTC_SYNC_ERROR_CONTROL__VI = 0x5C0F; +constexpr unsigned int mmAUX_GTC_SYNC_PHASE_OFFSET_OVERRIDE__VI = 0x5C13; +constexpr unsigned int mmAUX_GTC_SYNC_STATUS__VI = 0x5C11; +constexpr unsigned int mmAUX_INTERRUPT_CONTROL__VI = 0x5C03; +constexpr unsigned int mmAUX_LS_DATA__VI = 0x5C07; +constexpr unsigned int mmAUX_LS_STATUS__VI = 0x5C05; +constexpr unsigned int mmAUX_SW_CONTROL__VI = 0x5C01; +constexpr unsigned int mmAUX_SW_DATA__VI = 0x5C06; +constexpr unsigned int mmAUX_SW_STATUS__VI = 0x5C04; +constexpr unsigned int mmAUX_TEST_DEBUG_DATA__VI = 0x5C15; +constexpr unsigned int mmAUX_TEST_DEBUG_INDEX__VI = 0x5C14; +constexpr unsigned int mmAVSYNC_COUNTER_CONTROL__VI = 0x012B; +constexpr unsigned int mmAVSYNC_COUNTER_READ__VI = 0x012F; +constexpr unsigned int mmAVSYNC_COUNTER_WRITE__VI = 0x012A; +constexpr unsigned int mmAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER__VI = 0x17F3; +constexpr unsigned int mmAZALIA_AUDIO_DTO__VI = 0x17E5; +constexpr unsigned int mmAZALIA_AUDIO_DTO_CONTROL__VI = 0x17E6; +constexpr unsigned int mmAZALIA_BDL_DMA_CONTROL__VI = 0x17EA; +constexpr unsigned int mmAZALIA_CONTROLLER_CLOCK_GATING__VI = 0x17E4; +constexpr unsigned int mmAZALIA_CONTROLLER_DEBUG__VI = 0x17F9; +constexpr unsigned int mmAZALIA_CORB_DMA_CONTROL__VI = 0x17EC; +constexpr unsigned int mmAZALIA_CRC0_CONTROL0__VI = 0x1805; +constexpr unsigned int mmAZALIA_CRC0_CONTROL1__VI = 0x1806; +constexpr unsigned int mmAZALIA_CRC0_CONTROL2__VI = 0x1807; +constexpr unsigned int mmAZALIA_CRC0_CONTROL3__VI = 0x1808; +constexpr unsigned int mmAZALIA_CRC0_RESULT__VI = 0x1809; +constexpr unsigned int mmAZALIA_CRC1_CONTROL0__VI = 0x180A; +constexpr unsigned int mmAZALIA_CRC1_CONTROL1__VI = 0x180B; +constexpr unsigned int mmAZALIA_CRC1_CONTROL2__VI = 0x180C; +constexpr unsigned int mmAZALIA_CRC1_CONTROL3__VI = 0x180D; +constexpr unsigned int mmAZALIA_CRC1_RESULT__VI = 0x180E; +constexpr unsigned int mmAZALIA_CYCLIC_BUFFER_SYNC__VI = 0x17F4; +constexpr unsigned int mmAZALIA_DATA_DMA_CONTROL__VI = 0x17E9; +constexpr unsigned int mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL__VI = 0x182A; +constexpr unsigned int mmAZALIA_F0_CODEC_DEBUG__VI = 0x1836; +constexpr unsigned int mmAZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17A9; +constexpr unsigned int mmAZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17A8; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_CONTROL_CONVERTER_SYNCHRONIZATION__VI = 0x1833; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_CONTROL_POWER_STATE__VI = 0x1830; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_CONTROL_RESET__VI = 0x1831; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_CONTROL_RESPONSE_SUBSYSTEM_ID__VI = 0x1832; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_GROUP_TYPE__VI = 0x182C; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES__VI = 0x182F; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS__VI = 0x182E; +constexpr unsigned int mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES__VI = 0x182D; +constexpr unsigned int mmAZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59D5; +constexpr unsigned int mmAZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59D4; +constexpr unsigned int mmAZALIA_F0_CODEC_RESYNC_FIFO_CONTROL__VI = 0x182B; +constexpr unsigned int mmAZALIA_F0_CODEC_ROOT_PARAMETER_REVISION_ID__VI = 0x1829; +constexpr unsigned int mmAZALIA_F0_CODEC_ROOT_PARAMETER_VENDOR_AND_DEVICE_ID__VI = 0x1828; +constexpr unsigned int mmAZALIA_F0_GTC_GROUP_OFFSET0__VI = 0x1837; +constexpr unsigned int mmAZALIA_F0_GTC_GROUP_OFFSET1__VI = 0x1838; +constexpr unsigned int mmAZALIA_F0_GTC_GROUP_OFFSET2__VI = 0x1839; +constexpr unsigned int mmAZALIA_F0_GTC_GROUP_OFFSET3__VI = 0x183A; +constexpr unsigned int mmAZALIA_F0_GTC_GROUP_OFFSET4__VI = 0x183B; +constexpr unsigned int mmAZALIA_F0_GTC_GROUP_OFFSET5__VI = 0x183C; +constexpr unsigned int mmAZALIA_F0_GTC_GROUP_OFFSET6__VI = 0x183D; +constexpr unsigned int mmAZALIA_GLOBAL_CAPABILITIES__VI = 0x17F5; +constexpr unsigned int mmAZALIA_INPUT_CRC0_CONTROL0__VI = 0x17FB; +constexpr unsigned int mmAZALIA_INPUT_CRC0_CONTROL1__VI = 0x17FC; +constexpr unsigned int mmAZALIA_INPUT_CRC0_CONTROL2__VI = 0x17FD; +constexpr unsigned int mmAZALIA_INPUT_CRC0_CONTROL3__VI = 0x17FE; +constexpr unsigned int mmAZALIA_INPUT_CRC0_RESULT__VI = 0x17FF; +constexpr unsigned int mmAZALIA_INPUT_CRC1_CONTROL0__VI = 0x1800; +constexpr unsigned int mmAZALIA_INPUT_CRC1_CONTROL1__VI = 0x1801; +constexpr unsigned int mmAZALIA_INPUT_CRC1_CONTROL2__VI = 0x1802; +constexpr unsigned int mmAZALIA_INPUT_CRC1_CONTROL3__VI = 0x1803; +constexpr unsigned int mmAZALIA_INPUT_CRC1_RESULT__VI = 0x1804; +constexpr unsigned int mmAZALIA_INPUT_PAYLOAD_CAPABILITY__VI = 0x17F8; +constexpr unsigned int mmAZALIA_MEM_PWR_CTRL__VI = 0x1810; +constexpr unsigned int mmAZALIA_MEM_PWR_STATUS__VI = 0x1811; +constexpr unsigned int mmAZALIA_OUTPUT_PAYLOAD_CAPABILITY__VI = 0x17F6; +constexpr unsigned int mmAZALIA_OUTPUT_STREAM_ARBITER_CONTROL__VI = 0x17F7; +constexpr unsigned int mmAZALIA_RIRB_AND_DP_CONTROL__VI = 0x17EB; +constexpr unsigned int mmAZALIA_SCLK_CONTROL__VI = 0x17E7; +constexpr unsigned int mmAZALIA_STREAM_DATA__VI = 0x1781; +constexpr unsigned int mmAZALIA_STREAM_INDEX__VI = 0x1780; +constexpr unsigned int mmAZALIA_UNDERFLOW_FILLER_SAMPLE__VI = 0x17E8; +constexpr unsigned int mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17A9; +constexpr unsigned int mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17A8; +constexpr unsigned int mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17AD; +constexpr unsigned int mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17AC; +constexpr unsigned int mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17B1; +constexpr unsigned int mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17B0; +constexpr unsigned int mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17B5; +constexpr unsigned int mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17B4; +constexpr unsigned int mmAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17B9; +constexpr unsigned int mmAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17B8; +constexpr unsigned int mmAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17BD; +constexpr unsigned int mmAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17BC; +constexpr unsigned int mmAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17C1; +constexpr unsigned int mmAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17C0; +constexpr unsigned int mmAZF0ENDPOINT7_AZALIA_F0_CODEC_ENDPOINT_DATA__VI = 0x17C5; +constexpr unsigned int mmAZF0ENDPOINT7_AZALIA_F0_CODEC_ENDPOINT_INDEX__VI = 0x17C4; +constexpr unsigned int mmAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59D5; +constexpr unsigned int mmAZF0INPUTENDPOINT0_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59D4; +constexpr unsigned int mmAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59D9; +constexpr unsigned int mmAZF0INPUTENDPOINT1_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59D8; +constexpr unsigned int mmAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59DD; +constexpr unsigned int mmAZF0INPUTENDPOINT2_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59DC; +constexpr unsigned int mmAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59E1; +constexpr unsigned int mmAZF0INPUTENDPOINT3_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59E0; +constexpr unsigned int mmAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59E5; +constexpr unsigned int mmAZF0INPUTENDPOINT4_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59E4; +constexpr unsigned int mmAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59E9; +constexpr unsigned int mmAZF0INPUTENDPOINT5_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59E8; +constexpr unsigned int mmAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59ED; +constexpr unsigned int mmAZF0INPUTENDPOINT6_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59EC; +constexpr unsigned int mmAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_ENDPOINT_DATA__VI = 0x59F1; +constexpr unsigned int mmAZF0INPUTENDPOINT7_AZALIA_F0_CODEC_INPUT_ENDPOINT_INDEX__VI = 0x59F0; +constexpr unsigned int mmAZF0STREAM0_AZALIA_STREAM_DATA__VI = 0x1781; +constexpr unsigned int mmAZF0STREAM0_AZALIA_STREAM_INDEX__VI = 0x1780; +constexpr unsigned int mmAZF0STREAM10_AZALIA_STREAM_DATA__VI = 0x59C5; +constexpr unsigned int mmAZF0STREAM10_AZALIA_STREAM_INDEX__VI = 0x59C4; +constexpr unsigned int mmAZF0STREAM11_AZALIA_STREAM_DATA__VI = 0x59C7; +constexpr unsigned int mmAZF0STREAM11_AZALIA_STREAM_INDEX__VI = 0x59C6; +constexpr unsigned int mmAZF0STREAM12_AZALIA_STREAM_DATA__VI = 0x59C9; +constexpr unsigned int mmAZF0STREAM12_AZALIA_STREAM_INDEX__VI = 0x59C8; +constexpr unsigned int mmAZF0STREAM13_AZALIA_STREAM_DATA__VI = 0x59CB; +constexpr unsigned int mmAZF0STREAM13_AZALIA_STREAM_INDEX__VI = 0x59CA; +constexpr unsigned int mmAZF0STREAM14_AZALIA_STREAM_DATA__VI = 0x59CD; +constexpr unsigned int mmAZF0STREAM14_AZALIA_STREAM_INDEX__VI = 0x59CC; +constexpr unsigned int mmAZF0STREAM15_AZALIA_STREAM_DATA__VI = 0x59CF; +constexpr unsigned int mmAZF0STREAM15_AZALIA_STREAM_INDEX__VI = 0x59CE; +constexpr unsigned int mmAZF0STREAM1_AZALIA_STREAM_DATA__VI = 0x1783; +constexpr unsigned int mmAZF0STREAM1_AZALIA_STREAM_INDEX__VI = 0x1782; +constexpr unsigned int mmAZF0STREAM2_AZALIA_STREAM_DATA__VI = 0x1785; +constexpr unsigned int mmAZF0STREAM2_AZALIA_STREAM_INDEX__VI = 0x1784; +constexpr unsigned int mmAZF0STREAM3_AZALIA_STREAM_DATA__VI = 0x1787; +constexpr unsigned int mmAZF0STREAM3_AZALIA_STREAM_INDEX__VI = 0x1786; +constexpr unsigned int mmAZF0STREAM4_AZALIA_STREAM_DATA__VI = 0x1789; +constexpr unsigned int mmAZF0STREAM4_AZALIA_STREAM_INDEX__VI = 0x1788; +constexpr unsigned int mmAZF0STREAM5_AZALIA_STREAM_DATA__VI = 0x178B; +constexpr unsigned int mmAZF0STREAM5_AZALIA_STREAM_INDEX__VI = 0x178A; +constexpr unsigned int mmAZF0STREAM6_AZALIA_STREAM_DATA__VI = 0x178D; +constexpr unsigned int mmAZF0STREAM6_AZALIA_STREAM_INDEX__VI = 0x178C; +constexpr unsigned int mmAZF0STREAM7_AZALIA_STREAM_DATA__VI = 0x178F; +constexpr unsigned int mmAZF0STREAM7_AZALIA_STREAM_INDEX__VI = 0x178E; +constexpr unsigned int mmAZF0STREAM8_AZALIA_STREAM_DATA__VI = 0x59C1; +constexpr unsigned int mmAZF0STREAM8_AZALIA_STREAM_INDEX__VI = 0x59C0; +constexpr unsigned int mmAZF0STREAM9_AZALIA_STREAM_DATA__VI = 0x59C3; +constexpr unsigned int mmAZF0STREAM9_AZALIA_STREAM_INDEX__VI = 0x59C2; +constexpr unsigned int mmAZ_TEST_DEBUG_DATA__VI = 0x1820; +constexpr unsigned int mmAZ_TEST_DEBUG_INDEX__VI = 0x181F; +constexpr unsigned int mmBF_ANA_ISO_CNTL__VI = 0x14C7; +constexpr unsigned int mmBIF_ATOMIC_ERR_LOG__VI = 0x1512; +constexpr unsigned int mmBIF_BME_STATUS__VI = 0x1511; +constexpr unsigned int mmBIF_CLK_CTRL__VI = 0x14C5; +constexpr unsigned int mmBIF_DOORBELL_APER_EN__VI = 0x1501; +constexpr unsigned int mmBIF_DOORBELL_GBLAPER1_LOWER__VI = 0x14FC; +constexpr unsigned int mmBIF_DOORBELL_GBLAPER1_UPPER__VI = 0x14FD; +constexpr unsigned int mmBIF_DOORBELL_GBLAPER2_LOWER__VI = 0x14FE; +constexpr unsigned int mmBIF_DOORBELL_GBLAPER2_UPPER__VI = 0x14FF; +constexpr unsigned int mmBIF_GPUIOV_FB_TOTAL_FB_INFO__VI = 0x14D8; +constexpr unsigned int mmBIF_GPUIOV_RESET_NOTIFICATION__VI = 0x14D5; +constexpr unsigned int mmBIF_GPUIOV_VM_INIT_STATUS__VI = 0x14D6; +constexpr unsigned int mmBIF_IOV_FUNC_IDENTIFIER__VI = 0x1503; +constexpr unsigned int mmBIF_MM_INDACCESS_CNTL__VI = 0x1500; +constexpr unsigned int mmBIF_MST_TRANS_PENDING__VI = 0x14EA; +constexpr unsigned int mmBIF_RB_BASE__VI = 0x1531; +constexpr unsigned int mmBIF_RB_CNTL__VI = 0x1530; +constexpr unsigned int mmBIF_RB_RPTR__VI = 0x1532; +constexpr unsigned int mmBIF_RB_WPTR__VI = 0x1533; +constexpr unsigned int mmBIF_RB_WPTR_ADDR_HI__VI = 0x1534; +constexpr unsigned int mmBIF_RB_WPTR_ADDR_LO__VI = 0x1535; +constexpr unsigned int mmBIF_RFE_MST_BX_CMDSTATUS__VI = 0x1449; +constexpr unsigned int mmBIF_RFE_MST_SMBUS_CMDSTATUS__VI = 0x1448; +constexpr unsigned int mmBIF_RFE_WARMRST_CNTL__VI = 0x1459; +constexpr unsigned int mmBIF_RLC_INTR_CNTL__VI = 0x1510; +constexpr unsigned int mmBIF_SLV_TRANS_PENDING__VI = 0x14E9; +constexpr unsigned int mmBIF_SMU_DATA__VI = 0x143E; +constexpr unsigned int mmBIF_SMU_INDEX__VI = 0x143D; +constexpr unsigned int mmBIF_VDDGFX_FB_CMP__VI = 0x143C; +constexpr unsigned int mmBIF_VDDGFX_GFX0_LOWER__VI = 0x1428; +constexpr unsigned int mmBIF_VDDGFX_GFX0_UPPER__VI = 0x1429; +constexpr unsigned int mmBIF_VDDGFX_GFX1_LOWER__VI = 0x142A; +constexpr unsigned int mmBIF_VDDGFX_GFX1_UPPER__VI = 0x142B; +constexpr unsigned int mmBIF_VDDGFX_GFX2_LOWER__VI = 0x142C; +constexpr unsigned int mmBIF_VDDGFX_GFX2_UPPER__VI = 0x142D; +constexpr unsigned int mmBIF_VDDGFX_GFX3_LOWER__VI = 0x142E; +constexpr unsigned int mmBIF_VDDGFX_GFX3_UPPER__VI = 0x142F; +constexpr unsigned int mmBIF_VDDGFX_GFX4_LOWER__VI = 0x1430; +constexpr unsigned int mmBIF_VDDGFX_GFX4_UPPER__VI = 0x1431; +constexpr unsigned int mmBIF_VDDGFX_GFX5_LOWER__VI = 0x1432; +constexpr unsigned int mmBIF_VDDGFX_GFX5_UPPER__VI = 0x1433; +constexpr unsigned int mmBIF_VDDGFX_RSV1_LOWER__VI = 0x1434; +constexpr unsigned int mmBIF_VDDGFX_RSV1_UPPER__VI = 0x1435; +constexpr unsigned int mmBIF_VDDGFX_RSV2_LOWER__VI = 0x1436; +constexpr unsigned int mmBIF_VDDGFX_RSV2_UPPER__VI = 0x1437; +constexpr unsigned int mmBIF_VDDGFX_RSV3_LOWER__VI = 0x1438; +constexpr unsigned int mmBIF_VDDGFX_RSV3_UPPER__VI = 0x1439; +constexpr unsigned int mmBIF_VDDGFX_RSV4_LOWER__VI = 0x143A; +constexpr unsigned int mmBIF_VDDGFX_RSV4_UPPER__VI = 0x143B; +constexpr unsigned int mmBIF_VIRT_RESET_REQ__VI = 0x14D2; +constexpr unsigned int mmBLND0_BLND_CONTROL__VI = 0x1B6D; +constexpr unsigned int mmBLND0_BLND_CONTROL2__VI = 0x1B6F; +constexpr unsigned int mmBLND0_BLND_DEBUG__VI = 0x1B74; +constexpr unsigned int mmBLND0_BLND_REG_UPDATE_STATUS__VI = 0x1B77; +constexpr unsigned int mmBLND0_BLND_TEST_DEBUG_DATA__VI = 0x1B76; +constexpr unsigned int mmBLND0_BLND_TEST_DEBUG_INDEX__VI = 0x1B75; +constexpr unsigned int mmBLND0_BLND_UNDERFLOW_INTERRUPT__VI = 0x1B71; +constexpr unsigned int mmBLND0_BLND_UPDATE__VI = 0x1B70; +constexpr unsigned int mmBLND0_BLND_V_UPDATE_LOCK__VI = 0x1B73; +constexpr unsigned int mmBLND0_SM_CONTROL2__VI = 0x1B6E; +constexpr unsigned int mmBLND1_BLND_CONTROL__VI = 0x1D6D; +constexpr unsigned int mmBLND1_BLND_CONTROL2__VI = 0x1D6F; +constexpr unsigned int mmBLND1_BLND_DEBUG__VI = 0x1D74; +constexpr unsigned int mmBLND1_BLND_REG_UPDATE_STATUS__VI = 0x1D77; +constexpr unsigned int mmBLND1_BLND_TEST_DEBUG_DATA__VI = 0x1D76; +constexpr unsigned int mmBLND1_BLND_TEST_DEBUG_INDEX__VI = 0x1D75; +constexpr unsigned int mmBLND1_BLND_UNDERFLOW_INTERRUPT__VI = 0x1D71; +constexpr unsigned int mmBLND1_BLND_UPDATE__VI = 0x1D70; +constexpr unsigned int mmBLND1_BLND_V_UPDATE_LOCK__VI = 0x1D73; +constexpr unsigned int mmBLND1_SM_CONTROL2__VI = 0x1D6E; +constexpr unsigned int mmBLND2_BLND_CONTROL__VI = 0x1F6D; +constexpr unsigned int mmBLND2_BLND_CONTROL2__VI = 0x1F6F; +constexpr unsigned int mmBLND2_BLND_DEBUG__VI = 0x1F74; +constexpr unsigned int mmBLND2_BLND_REG_UPDATE_STATUS__VI = 0x1F77; +constexpr unsigned int mmBLND2_BLND_TEST_DEBUG_DATA__VI = 0x1F76; +constexpr unsigned int mmBLND2_BLND_TEST_DEBUG_INDEX__VI = 0x1F75; +constexpr unsigned int mmBLND2_BLND_UNDERFLOW_INTERRUPT__VI = 0x1F71; +constexpr unsigned int mmBLND2_BLND_UPDATE__VI = 0x1F70; +constexpr unsigned int mmBLND2_BLND_V_UPDATE_LOCK__VI = 0x1F73; +constexpr unsigned int mmBLND2_SM_CONTROL2__VI = 0x1F6E; +constexpr unsigned int mmBLND3_BLND_CONTROL__VI = 0x416D; +constexpr unsigned int mmBLND3_BLND_CONTROL2__VI = 0x416F; +constexpr unsigned int mmBLND3_BLND_DEBUG__VI = 0x4174; +constexpr unsigned int mmBLND3_BLND_REG_UPDATE_STATUS__VI = 0x4177; +constexpr unsigned int mmBLND3_BLND_TEST_DEBUG_DATA__VI = 0x4176; +constexpr unsigned int mmBLND3_BLND_TEST_DEBUG_INDEX__VI = 0x4175; +constexpr unsigned int mmBLND3_BLND_UNDERFLOW_INTERRUPT__VI = 0x4171; +constexpr unsigned int mmBLND3_BLND_UPDATE__VI = 0x4170; +constexpr unsigned int mmBLND3_BLND_V_UPDATE_LOCK__VI = 0x4173; +constexpr unsigned int mmBLND3_SM_CONTROL2__VI = 0x416E; +constexpr unsigned int mmBLND4_BLND_CONTROL__VI = 0x436D; +constexpr unsigned int mmBLND4_BLND_CONTROL2__VI = 0x436F; +constexpr unsigned int mmBLND4_BLND_DEBUG__VI = 0x4374; +constexpr unsigned int mmBLND4_BLND_REG_UPDATE_STATUS__VI = 0x4377; +constexpr unsigned int mmBLND4_BLND_TEST_DEBUG_DATA__VI = 0x4376; +constexpr unsigned int mmBLND4_BLND_TEST_DEBUG_INDEX__VI = 0x4375; +constexpr unsigned int mmBLND4_BLND_UNDERFLOW_INTERRUPT__VI = 0x4371; +constexpr unsigned int mmBLND4_BLND_UPDATE__VI = 0x4370; +constexpr unsigned int mmBLND4_BLND_V_UPDATE_LOCK__VI = 0x4373; +constexpr unsigned int mmBLND4_SM_CONTROL2__VI = 0x436E; +constexpr unsigned int mmBLND5_BLND_CONTROL__VI = 0x456D; +constexpr unsigned int mmBLND5_BLND_CONTROL2__VI = 0x456F; +constexpr unsigned int mmBLND5_BLND_DEBUG__VI = 0x4574; +constexpr unsigned int mmBLND5_BLND_REG_UPDATE_STATUS__VI = 0x4577; +constexpr unsigned int mmBLND5_BLND_TEST_DEBUG_DATA__VI = 0x4576; +constexpr unsigned int mmBLND5_BLND_TEST_DEBUG_INDEX__VI = 0x4575; +constexpr unsigned int mmBLND5_BLND_UNDERFLOW_INTERRUPT__VI = 0x4571; +constexpr unsigned int mmBLND5_BLND_UPDATE__VI = 0x4570; +constexpr unsigned int mmBLND5_BLND_V_UPDATE_LOCK__VI = 0x4573; +constexpr unsigned int mmBLND5_SM_CONTROL2__VI = 0x456E; +constexpr unsigned int mmBLND6_BLND_CONTROL__VI = 0x476D; +constexpr unsigned int mmBLND6_BLND_CONTROL2__VI = 0x476F; +constexpr unsigned int mmBLND6_BLND_DEBUG__VI = 0x4774; +constexpr unsigned int mmBLND6_BLND_REG_UPDATE_STATUS__VI = 0x4777; +constexpr unsigned int mmBLND6_BLND_TEST_DEBUG_DATA__VI = 0x4776; +constexpr unsigned int mmBLND6_BLND_TEST_DEBUG_INDEX__VI = 0x4775; +constexpr unsigned int mmBLND6_BLND_UNDERFLOW_INTERRUPT__VI = 0x4771; +constexpr unsigned int mmBLND6_BLND_UPDATE__VI = 0x4770; +constexpr unsigned int mmBLND6_BLND_V_UPDATE_LOCK__VI = 0x4773; +constexpr unsigned int mmBLND6_SM_CONTROL2__VI = 0x476E; +constexpr unsigned int mmBLND_CONTROL__VI = 0x1B6D; +constexpr unsigned int mmBLND_CONTROL2__VI = 0x1B6F; +constexpr unsigned int mmBLND_DEBUG__VI = 0x1B74; +constexpr unsigned int mmBLND_REG_UPDATE_STATUS__VI = 0x1B77; +constexpr unsigned int mmBLND_TEST_DEBUG_DATA__VI = 0x1B76; +constexpr unsigned int mmBLND_TEST_DEBUG_INDEX__VI = 0x1B75; +constexpr unsigned int mmBLND_UNDERFLOW_INTERRUPT__VI = 0x1B71; +constexpr unsigned int mmBLND_UPDATE__VI = 0x1B70; +constexpr unsigned int mmBLND_V_UPDATE_LOCK__VI = 0x1B73; +constexpr unsigned int mmBL_PWM_CNTL__VI = 0x4820; +constexpr unsigned int mmBL_PWM_CNTL2__VI = 0x4821; +constexpr unsigned int mmBL_PWM_GRP1_REG_LOCK__VI = 0x4823; +constexpr unsigned int mmBL_PWM_PERIOD_CNTL__VI = 0x4822; +constexpr unsigned int mmBPHYC_DAC_AUTO_CALIB_CONTROL__VI = 0x48BA; +constexpr unsigned int mmBPHYC_DAC_MACRO_CNTL__VI = 0x48B9; +constexpr unsigned int mmBPHYC_PLL0_DISPPLL_BG_CNTL__VI = 0x171E; +constexpr unsigned int mmBPHYC_PLL0_PLL_ANALOG__VI = 0x1708; +constexpr unsigned int mmBPHYC_PLL0_PLL_ANALOG_CNTL__VI = 0x1711; +constexpr unsigned int mmBPHYC_PLL0_PLL_CNTL__VI = 0x1707; +constexpr unsigned int mmBPHYC_PLL0_PLL_DEBUG_CNTL__VI = 0x170B; +constexpr unsigned int mmBPHYC_PLL0_PLL_DS_CNTL__VI = 0x1705; +constexpr unsigned int mmBPHYC_PLL0_PLL_FB_DIV__VI = 0x1701; +constexpr unsigned int mmBPHYC_PLL0_PLL_IDCLK_CNTL__VI = 0x1706; +constexpr unsigned int mmBPHYC_PLL0_PLL_POST_DIV__VI = 0x1702; +constexpr unsigned int mmBPHYC_PLL0_PLL_REF_DIV__VI = 0x1700; +constexpr unsigned int mmBPHYC_PLL0_PLL_SS_AMOUNT_DSFRAC__VI = 0x1703; +constexpr unsigned int mmBPHYC_PLL0_PLL_SS_CNTL__VI = 0x1704; +constexpr unsigned int mmBPHYC_PLL0_PLL_UNLOCK_DETECT_CNTL__VI = 0x170A; +constexpr unsigned int mmBPHYC_PLL0_PLL_UPDATE_CNTL__VI = 0x170D; +constexpr unsigned int mmBPHYC_PLL0_PLL_UPDATE_LOCK__VI = 0x170C; +constexpr unsigned int mmBPHYC_PLL0_PLL_VREG_CNTL__VI = 0x1709; +constexpr unsigned int mmBPHYC_PLL0_PLL_XOR_LOCK__VI = 0x1710; +constexpr unsigned int mmBPHYC_PLL0_PPLL_DEBUG_MUX_CNTL__VI = 0x1721; +constexpr unsigned int mmBPHYC_PLL0_PPLL_DIV_UPDATE_DEBUG__VI = 0x171F; +constexpr unsigned int mmBPHYC_PLL0_PPLL_SPARE0__VI = 0x1722; +constexpr unsigned int mmBPHYC_PLL0_PPLL_SPARE1__VI = 0x1723; +constexpr unsigned int mmBPHYC_PLL0_PPLL_STATUS_DEBUG__VI = 0x1720; +constexpr unsigned int mmBPHYC_PLL0_VGA25_PPLL_ANALOG__VI = 0x171B; +constexpr unsigned int mmBPHYC_PLL0_VGA25_PPLL_FB_DIV__VI = 0x1715; +constexpr unsigned int mmBPHYC_PLL0_VGA25_PPLL_POST_DIV__VI = 0x1718; +constexpr unsigned int mmBPHYC_PLL0_VGA25_PPLL_REF_DIV__VI = 0x1712; +constexpr unsigned int mmBPHYC_PLL0_VGA28_PPLL_ANALOG__VI = 0x171C; +constexpr unsigned int mmBPHYC_PLL0_VGA28_PPLL_FB_DIV__VI = 0x1716; +constexpr unsigned int mmBPHYC_PLL0_VGA28_PPLL_POST_DIV__VI = 0x1719; +constexpr unsigned int mmBPHYC_PLL0_VGA28_PPLL_REF_DIV__VI = 0x1713; +constexpr unsigned int mmBPHYC_PLL0_VGA41_PPLL_ANALOG__VI = 0x171D; +constexpr unsigned int mmBPHYC_PLL0_VGA41_PPLL_FB_DIV__VI = 0x1717; +constexpr unsigned int mmBPHYC_PLL0_VGA41_PPLL_POST_DIV__VI = 0x171A; +constexpr unsigned int mmBPHYC_PLL0_VGA41_PPLL_REF_DIV__VI = 0x1714; +constexpr unsigned int mmBPHYC_PLL1_DISPPLL_BG_CNTL__VI = 0x1748; +constexpr unsigned int mmBPHYC_PLL1_PLL_ANALOG__VI = 0x1732; +constexpr unsigned int mmBPHYC_PLL1_PLL_ANALOG_CNTL__VI = 0x173B; +constexpr unsigned int mmBPHYC_PLL1_PLL_CNTL__VI = 0x1731; +constexpr unsigned int mmBPHYC_PLL1_PLL_DEBUG_CNTL__VI = 0x1735; +constexpr unsigned int mmBPHYC_PLL1_PLL_DS_CNTL__VI = 0x172F; +constexpr unsigned int mmBPHYC_PLL1_PLL_FB_DIV__VI = 0x172B; +constexpr unsigned int mmBPHYC_PLL1_PLL_IDCLK_CNTL__VI = 0x1730; +constexpr unsigned int mmBPHYC_PLL1_PLL_POST_DIV__VI = 0x172C; +constexpr unsigned int mmBPHYC_PLL1_PLL_REF_DIV__VI = 0x172A; +constexpr unsigned int mmBPHYC_PLL1_PLL_SS_AMOUNT_DSFRAC__VI = 0x172D; +constexpr unsigned int mmBPHYC_PLL1_PLL_SS_CNTL__VI = 0x172E; +constexpr unsigned int mmBPHYC_PLL1_PLL_UNLOCK_DETECT_CNTL__VI = 0x1734; +constexpr unsigned int mmBPHYC_PLL1_PLL_UPDATE_CNTL__VI = 0x1737; +constexpr unsigned int mmBPHYC_PLL1_PLL_UPDATE_LOCK__VI = 0x1736; +constexpr unsigned int mmBPHYC_PLL1_PLL_VREG_CNTL__VI = 0x1733; +constexpr unsigned int mmBPHYC_PLL1_PLL_XOR_LOCK__VI = 0x173A; +constexpr unsigned int mmBPHYC_PLL1_PPLL_DEBUG_MUX_CNTL__VI = 0x174B; +constexpr unsigned int mmBPHYC_PLL1_PPLL_DIV_UPDATE_DEBUG__VI = 0x1749; +constexpr unsigned int mmBPHYC_PLL1_PPLL_SPARE0__VI = 0x174C; +constexpr unsigned int mmBPHYC_PLL1_PPLL_SPARE1__VI = 0x174D; +constexpr unsigned int mmBPHYC_PLL1_PPLL_STATUS_DEBUG__VI = 0x174A; +constexpr unsigned int mmBPHYC_PLL1_VGA25_PPLL_ANALOG__VI = 0x1745; +constexpr unsigned int mmBPHYC_PLL1_VGA25_PPLL_FB_DIV__VI = 0x173F; +constexpr unsigned int mmBPHYC_PLL1_VGA25_PPLL_POST_DIV__VI = 0x1742; +constexpr unsigned int mmBPHYC_PLL1_VGA25_PPLL_REF_DIV__VI = 0x173C; +constexpr unsigned int mmBPHYC_PLL1_VGA28_PPLL_ANALOG__VI = 0x1746; +constexpr unsigned int mmBPHYC_PLL1_VGA28_PPLL_FB_DIV__VI = 0x1740; +constexpr unsigned int mmBPHYC_PLL1_VGA28_PPLL_POST_DIV__VI = 0x1743; +constexpr unsigned int mmBPHYC_PLL1_VGA28_PPLL_REF_DIV__VI = 0x173D; +constexpr unsigned int mmBPHYC_PLL1_VGA41_PPLL_ANALOG__VI = 0x1747; +constexpr unsigned int mmBPHYC_PLL1_VGA41_PPLL_FB_DIV__VI = 0x1741; +constexpr unsigned int mmBPHYC_PLL1_VGA41_PPLL_POST_DIV__VI = 0x1744; +constexpr unsigned int mmBPHYC_PLL1_VGA41_PPLL_REF_DIV__VI = 0x173E; +constexpr unsigned int mmBPHYC_PLL2_DISPPLL_BG_CNTL__VI = 0x1772; +constexpr unsigned int mmBPHYC_PLL2_PLL_ANALOG__VI = 0x175C; +constexpr unsigned int mmBPHYC_PLL2_PLL_ANALOG_CNTL__VI = 0x1765; +constexpr unsigned int mmBPHYC_PLL2_PLL_CNTL__VI = 0x175B; +constexpr unsigned int mmBPHYC_PLL2_PLL_DEBUG_CNTL__VI = 0x175F; +constexpr unsigned int mmBPHYC_PLL2_PLL_DS_CNTL__VI = 0x1759; +constexpr unsigned int mmBPHYC_PLL2_PLL_FB_DIV__VI = 0x1755; +constexpr unsigned int mmBPHYC_PLL2_PLL_IDCLK_CNTL__VI = 0x175A; +constexpr unsigned int mmBPHYC_PLL2_PLL_POST_DIV__VI = 0x1756; +constexpr unsigned int mmBPHYC_PLL2_PLL_REF_DIV__VI = 0x1754; +constexpr unsigned int mmBPHYC_PLL2_PLL_SS_AMOUNT_DSFRAC__VI = 0x1757; +constexpr unsigned int mmBPHYC_PLL2_PLL_SS_CNTL__VI = 0x1758; +constexpr unsigned int mmBPHYC_PLL2_PLL_UNLOCK_DETECT_CNTL__VI = 0x175E; +constexpr unsigned int mmBPHYC_PLL2_PLL_UPDATE_CNTL__VI = 0x1761; +constexpr unsigned int mmBPHYC_PLL2_PLL_UPDATE_LOCK__VI = 0x1760; +constexpr unsigned int mmBPHYC_PLL2_PLL_VREG_CNTL__VI = 0x175D; +constexpr unsigned int mmBPHYC_PLL2_PLL_XOR_LOCK__VI = 0x1764; +constexpr unsigned int mmBPHYC_PLL2_PPLL_DEBUG_MUX_CNTL__VI = 0x1775; +constexpr unsigned int mmBPHYC_PLL2_PPLL_DIV_UPDATE_DEBUG__VI = 0x1773; +constexpr unsigned int mmBPHYC_PLL2_PPLL_SPARE0__VI = 0x1776; +constexpr unsigned int mmBPHYC_PLL2_PPLL_SPARE1__VI = 0x1777; +constexpr unsigned int mmBPHYC_PLL2_PPLL_STATUS_DEBUG__VI = 0x1774; +constexpr unsigned int mmBPHYC_PLL2_VGA25_PPLL_ANALOG__VI = 0x176F; +constexpr unsigned int mmBPHYC_PLL2_VGA25_PPLL_FB_DIV__VI = 0x1769; +constexpr unsigned int mmBPHYC_PLL2_VGA25_PPLL_POST_DIV__VI = 0x176C; +constexpr unsigned int mmBPHYC_PLL2_VGA25_PPLL_REF_DIV__VI = 0x1766; +constexpr unsigned int mmBPHYC_PLL2_VGA28_PPLL_ANALOG__VI = 0x1770; +constexpr unsigned int mmBPHYC_PLL2_VGA28_PPLL_FB_DIV__VI = 0x176A; +constexpr unsigned int mmBPHYC_PLL2_VGA28_PPLL_POST_DIV__VI = 0x176D; +constexpr unsigned int mmBPHYC_PLL2_VGA28_PPLL_REF_DIV__VI = 0x1767; +constexpr unsigned int mmBPHYC_PLL2_VGA41_PPLL_ANALOG__VI = 0x1771; +constexpr unsigned int mmBPHYC_PLL2_VGA41_PPLL_FB_DIV__VI = 0x176B; +constexpr unsigned int mmBPHYC_PLL2_VGA41_PPLL_POST_DIV__VI = 0x176E; +constexpr unsigned int mmBPHYC_PLL2_VGA41_PPLL_REF_DIV__VI = 0x1768; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_ANG_BIST_CNTL__VI = 0x48CC; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_DATA_SYNCHRONIZATION__VI = 0x48CA; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_DEBUG__VI = 0x48D6; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_PLL_CONTROL1__VI = 0x48C6; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_PLL_CONTROL2__VI = 0x48C7; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_PLL_FBDIV__VI = 0x48C5; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_PLL_SS_CNTL__VI = 0x48C9; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_PLL_SS_STEP_SIZE__VI = 0x48C8; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_POWER_CONTROL__VI = 0x48C4; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_REG_TEST_OUTPUT__VI = 0x48CB; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_REG_TEST_OUTPUT2__VI = 0x48CD; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_TPG_CONTROL__VI = 0x48D4; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_TPG_SEED__VI = 0x48D5; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_TX_CONTROL1__VI = 0x48C0; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_TX_CONTROL2__VI = 0x48C1; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_TX_CONTROL3__VI = 0x48C2; +constexpr unsigned int mmBPHYC_UNIPHY0_UNIPHY_TX_CONTROL4__VI = 0x48C3; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_ANG_BIST_CNTL__VI = 0x48EC; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_DATA_SYNCHRONIZATION__VI = 0x48EA; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_DEBUG__VI = 0x48F6; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_PLL_CONTROL1__VI = 0x48E6; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_PLL_CONTROL2__VI = 0x48E7; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_PLL_FBDIV__VI = 0x48E5; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_PLL_SS_CNTL__VI = 0x48E9; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_PLL_SS_STEP_SIZE__VI = 0x48E8; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_POWER_CONTROL__VI = 0x48E4; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_REG_TEST_OUTPUT__VI = 0x48EB; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_REG_TEST_OUTPUT2__VI = 0x48ED; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_TPG_CONTROL__VI = 0x48F4; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_TPG_SEED__VI = 0x48F5; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_TX_CONTROL1__VI = 0x48E0; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_TX_CONTROL2__VI = 0x48E1; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_TX_CONTROL3__VI = 0x48E2; +constexpr unsigned int mmBPHYC_UNIPHY1_UNIPHY_TX_CONTROL4__VI = 0x48E3; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_ANG_BIST_CNTL__VI = 0x490C; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_DATA_SYNCHRONIZATION__VI = 0x490A; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_DEBUG__VI = 0x4916; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_PLL_CONTROL1__VI = 0x4906; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_PLL_CONTROL2__VI = 0x4907; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_PLL_FBDIV__VI = 0x4905; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_PLL_SS_CNTL__VI = 0x4909; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_PLL_SS_STEP_SIZE__VI = 0x4908; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_POWER_CONTROL__VI = 0x4904; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_REG_TEST_OUTPUT__VI = 0x490B; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_REG_TEST_OUTPUT2__VI = 0x490D; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_TPG_CONTROL__VI = 0x4914; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_TPG_SEED__VI = 0x4915; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_TX_CONTROL1__VI = 0x4900; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_TX_CONTROL2__VI = 0x4901; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_TX_CONTROL3__VI = 0x4902; +constexpr unsigned int mmBPHYC_UNIPHY2_UNIPHY_TX_CONTROL4__VI = 0x4903; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_ANG_BIST_CNTL__VI = 0x492C; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_DATA_SYNCHRONIZATION__VI = 0x492A; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_DEBUG__VI = 0x4936; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_PLL_CONTROL1__VI = 0x4926; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_PLL_CONTROL2__VI = 0x4927; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_PLL_FBDIV__VI = 0x4925; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_PLL_SS_CNTL__VI = 0x4929; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_PLL_SS_STEP_SIZE__VI = 0x4928; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_POWER_CONTROL__VI = 0x4924; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_REG_TEST_OUTPUT__VI = 0x492B; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_REG_TEST_OUTPUT2__VI = 0x492D; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_TPG_CONTROL__VI = 0x4934; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_TPG_SEED__VI = 0x4935; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_TX_CONTROL1__VI = 0x4920; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_TX_CONTROL2__VI = 0x4921; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_TX_CONTROL3__VI = 0x4922; +constexpr unsigned int mmBPHYC_UNIPHY3_UNIPHY_TX_CONTROL4__VI = 0x4923; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_ANG_BIST_CNTL__VI = 0x494C; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_DATA_SYNCHRONIZATION__VI = 0x494A; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_DEBUG__VI = 0x4956; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_PLL_CONTROL1__VI = 0x4946; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_PLL_CONTROL2__VI = 0x4947; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_PLL_FBDIV__VI = 0x4945; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_PLL_SS_CNTL__VI = 0x4949; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_PLL_SS_STEP_SIZE__VI = 0x4948; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_POWER_CONTROL__VI = 0x4944; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_REG_TEST_OUTPUT__VI = 0x494B; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_REG_TEST_OUTPUT2__VI = 0x494D; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_TPG_CONTROL__VI = 0x4954; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_TPG_SEED__VI = 0x4955; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_TX_CONTROL1__VI = 0x4940; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_TX_CONTROL2__VI = 0x4941; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_TX_CONTROL3__VI = 0x4942; +constexpr unsigned int mmBPHYC_UNIPHY4_UNIPHY_TX_CONTROL4__VI = 0x4943; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_ANG_BIST_CNTL__VI = 0x496C; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_DATA_SYNCHRONIZATION__VI = 0x496A; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_DEBUG__VI = 0x4976; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_PLL_CONTROL1__VI = 0x4966; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_PLL_CONTROL2__VI = 0x4967; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_PLL_FBDIV__VI = 0x4965; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_PLL_SS_CNTL__VI = 0x4969; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_PLL_SS_STEP_SIZE__VI = 0x4968; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_POWER_CONTROL__VI = 0x4964; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_REG_TEST_OUTPUT__VI = 0x496B; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_REG_TEST_OUTPUT2__VI = 0x496D; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_TPG_CONTROL__VI = 0x4974; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_TPG_SEED__VI = 0x4975; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_TX_CONTROL1__VI = 0x4960; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_TX_CONTROL2__VI = 0x4961; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_TX_CONTROL3__VI = 0x4962; +constexpr unsigned int mmBPHYC_UNIPHY5_UNIPHY_TX_CONTROL4__VI = 0x4963; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_ANG_BIST_CNTL__VI = 0x498C; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_DATA_SYNCHRONIZATION__VI = 0x498A; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_DEBUG__VI = 0x4996; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_PLL_CONTROL1__VI = 0x4986; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_PLL_CONTROL2__VI = 0x4987; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_PLL_FBDIV__VI = 0x4985; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_PLL_SS_CNTL__VI = 0x4989; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_PLL_SS_STEP_SIZE__VI = 0x4988; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_POWER_CONTROL__VI = 0x4984; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_REG_TEST_OUTPUT__VI = 0x498B; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_REG_TEST_OUTPUT2__VI = 0x498D; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_TPG_CONTROL__VI = 0x4994; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_TPG_SEED__VI = 0x4995; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_TX_CONTROL1__VI = 0x4980; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_TX_CONTROL2__VI = 0x4981; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_TX_CONTROL3__VI = 0x4982; +constexpr unsigned int mmBPHYC_UNIPHY6_UNIPHY_TX_CONTROL4__VI = 0x4983; +constexpr unsigned int mmBX_RESET_CNTL__VI = 0x1518; +constexpr unsigned int mmCB_COLOR0_DCC_BASE__VI = 0xA325; +constexpr unsigned int mmCB_COLOR0_DCC_CONTROL__VI = 0xA31E; +constexpr unsigned int mmCB_COLOR1_DCC_BASE__VI = 0xA334; +constexpr unsigned int mmCB_COLOR1_DCC_CONTROL__VI = 0xA32D; +constexpr unsigned int mmCB_COLOR2_DCC_BASE__VI = 0xA343; +constexpr unsigned int mmCB_COLOR2_DCC_CONTROL__VI = 0xA33C; +constexpr unsigned int mmCB_COLOR3_DCC_BASE__VI = 0xA352; +constexpr unsigned int mmCB_COLOR3_DCC_CONTROL__VI = 0xA34B; +constexpr unsigned int mmCB_COLOR4_DCC_BASE__VI = 0xA361; +constexpr unsigned int mmCB_COLOR4_DCC_CONTROL__VI = 0xA35A; +constexpr unsigned int mmCB_COLOR5_DCC_BASE__VI = 0xA370; +constexpr unsigned int mmCB_COLOR5_DCC_CONTROL__VI = 0xA369; +constexpr unsigned int mmCB_COLOR6_DCC_BASE__VI = 0xA37F; +constexpr unsigned int mmCB_COLOR6_DCC_CONTROL__VI = 0xA378; +constexpr unsigned int mmCB_COLOR7_DCC_BASE__VI = 0xA38E; +constexpr unsigned int mmCB_COLOR7_DCC_CONTROL__VI = 0xA387; +constexpr unsigned int mmCB_DCC_CONFIG__VI = 0x2687; +constexpr unsigned int mmCB_DCC_CONTROL__VI = 0xA109; +constexpr unsigned int mmCB_DEBUG_BUS_19__VI = 0x26AB; +constexpr unsigned int mmCB_DEBUG_BUS_20__VI = 0x26AC; +constexpr unsigned int mmCB_DEBUG_BUS_21__VI = 0x26AD; +constexpr unsigned int mmCB_DEBUG_BUS_22__VI = 0x26AE; +constexpr unsigned int mmCC_DC_PIPE_DIS__VI = 0x0312; +constexpr unsigned int mmCC_GC_SHADER_RATE_CONFIG__VI = 0x2312; +constexpr unsigned int mmCC_RCU_DC_AUDIO_INPUT_PORT_CONNECTIVITY__VI = 0x1835; +constexpr unsigned int mmCC_RCU_DC_AUDIO_PORT_CONNECTIVITY__VI = 0x1834; +constexpr unsigned int mmCG_FPS_CNT__VI = 0x01B6; +constexpr unsigned int mmCLKREQB_PERF_COUNTER__VI = 0x1522; +constexpr unsigned int mmCNV_CSC_C11_C12__VI = 0x5E20; +constexpr unsigned int mmCNV_CSC_C13_C14__VI = 0x5E21; +constexpr unsigned int mmCNV_CSC_C21_C22__VI = 0x5E22; +constexpr unsigned int mmCNV_CSC_C23_C24__VI = 0x5E23; +constexpr unsigned int mmCNV_CSC_C31_C32__VI = 0x5E24; +constexpr unsigned int mmCNV_CSC_C33_C34__VI = 0x5E25; +constexpr unsigned int mmCNV_CSC_CLAMP_B__VI = 0x5E2B; +constexpr unsigned int mmCNV_CSC_CLAMP_G__VI = 0x5E2A; +constexpr unsigned int mmCNV_CSC_CLAMP_R__VI = 0x5E29; +constexpr unsigned int mmCNV_CSC_CONTROL__VI = 0x5E1F; +constexpr unsigned int mmCNV_CSC_ROUND_OFFSET_B__VI = 0x5E28; +constexpr unsigned int mmCNV_CSC_ROUND_OFFSET_G__VI = 0x5E27; +constexpr unsigned int mmCNV_CSC_ROUND_OFFSET_R__VI = 0x5E26; +constexpr unsigned int mmCNV_INPUT_SELECT__VI = 0x5E33; +constexpr unsigned int mmCNV_MODE__VI = 0x5E1A; +constexpr unsigned int mmCNV_SOURCE_SIZE__VI = 0x5E1E; +constexpr unsigned int mmCNV_TEST_CNTL__VI = 0x5E2C; +constexpr unsigned int mmCNV_TEST_CRC_BLUE__VI = 0x5E2F; +constexpr unsigned int mmCNV_TEST_CRC_GREEN__VI = 0x5E2E; +constexpr unsigned int mmCNV_TEST_CRC_RED__VI = 0x5E2D; +constexpr unsigned int mmCNV_TEST_DEBUG_DATA__VI = 0x5E35; +constexpr unsigned int mmCNV_TEST_DEBUG_INDEX__VI = 0x5E34; +constexpr unsigned int mmCNV_UPDATE__VI = 0x5E1D; +constexpr unsigned int mmCNV_WINDOW_SIZE__VI = 0x5E1C; +constexpr unsigned int mmCNV_WINDOW_START__VI = 0x5E1B; +constexpr unsigned int mmCOL_MAN_DEBUG_CONTROL__VI = 0x46E6; +constexpr unsigned int mmCOL_MAN_FP_CONVERTED_FIELD__VI = 0x46C7; +constexpr unsigned int mmCOL_MAN_INPUT_CSC_CONTROL__VI = 0x46A5; +constexpr unsigned int mmCOL_MAN_OUTPUT_CSC_CONTROL__VI = 0x46B6; +constexpr unsigned int mmCOL_MAN_TEST_DEBUG_DATA__VI = 0x46E5; +constexpr unsigned int mmCOL_MAN_TEST_DEBUG_INDEX__VI = 0x46E4; +constexpr unsigned int mmCOL_MAN_UPDATE__VI = 0x46A4; +constexpr unsigned int mmCOMM_MATRIXA_TRANS_C11_C12__VI = 0x1A43; +constexpr unsigned int mmCOMM_MATRIXA_TRANS_C13_C14__VI = 0x1A44; +constexpr unsigned int mmCOMM_MATRIXA_TRANS_C21_C22__VI = 0x1A45; +constexpr unsigned int mmCOMM_MATRIXA_TRANS_C23_C24__VI = 0x1A46; +constexpr unsigned int mmCOMM_MATRIXA_TRANS_C31_C32__VI = 0x1A47; +constexpr unsigned int mmCOMM_MATRIXA_TRANS_C33_C34__VI = 0x1A48; +constexpr unsigned int mmCOMM_MATRIXB_TRANS_C11_C12__VI = 0x1A49; +constexpr unsigned int mmCOMM_MATRIXB_TRANS_C13_C14__VI = 0x1A4A; +constexpr unsigned int mmCOMM_MATRIXB_TRANS_C21_C22__VI = 0x1A4B; +constexpr unsigned int mmCOMM_MATRIXB_TRANS_C23_C24__VI = 0x1A4C; +constexpr unsigned int mmCOMM_MATRIXB_TRANS_C31_C32__VI = 0x1A4D; +constexpr unsigned int mmCOMM_MATRIXB_TRANS_C33_C34__VI = 0x1A4E; +constexpr unsigned int mmCOMPUTE_DISPATCH_ID__VI = 0x2E20; +constexpr unsigned int mmCOMPUTE_NOWHERE__VI = 0x2E7F; +constexpr unsigned int mmCOMPUTE_RELAUNCH__VI = 0x2E22; +constexpr unsigned int mmCOMPUTE_THREADGROUP_ID__VI = 0x2E21; +constexpr unsigned int mmCOMPUTE_WAVE_RESTORE_ADDR_HI__VI = 0x2E24; +constexpr unsigned int mmCOMPUTE_WAVE_RESTORE_ADDR_LO__VI = 0x2E23; +constexpr unsigned int mmCOMPUTE_WAVE_RESTORE_CONTROL__VI = 0x2E25; +constexpr unsigned int mmCONFIG_RESERVED__VI = 0x1502; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED0__VI = 0x5FD0; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED1__VI = 0x5FD1; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED10__VI = 0x5FDA; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED11__VI = 0x5FDB; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED2__VI = 0x5FD2; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED3__VI = 0x5FD3; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED4__VI = 0x5FD4; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED5__VI = 0x5FD5; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED6__VI = 0x5FD6; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED7__VI = 0x5FD7; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED8__VI = 0x5FD8; +constexpr unsigned int mmCPLL_MACRO_CNTL_RESERVED9__VI = 0x5FD9; +constexpr unsigned int mmCPM_CONTROL__VI = 0x14B8; +constexpr unsigned int mmCP_CE_COMPLETION_STATUS__VI = 0xC0ED; +constexpr unsigned int mmCP_CE_METADATA_BASE_ADDR__VI = 0xC0F2; +constexpr unsigned int mmCP_CE_METADATA_BASE_ADDR_HI__VI = 0xC0F3; +constexpr unsigned int mmCP_CE_RB_OFFSET__VI = 0xC09B; +constexpr unsigned int mmCP_CE_UCODE_ADDR__SI__CI = 0x305A; +constexpr unsigned int mmCP_CE_UCODE_ADDR__VI = 0xF818; +constexpr unsigned int mmCP_CE_UCODE_DATA__SI__CI = 0x305B; +constexpr unsigned int mmCP_CE_UCODE_DATA__VI = 0xF819; +constexpr unsigned int mmCP_CONFIG__VI = 0x0F96; +constexpr unsigned int mmCP_CPC_IC_BASE_CNTL__VI = 0x30BB; +constexpr unsigned int mmCP_CPC_IC_BASE_HI__VI = 0x30BA; +constexpr unsigned int mmCP_CPC_IC_BASE_LO__VI = 0x30B9; +constexpr unsigned int mmCP_CPC_IC_OP_CNTL__VI = 0x30BC; +constexpr unsigned int mmCP_CPC_MGCG_SYNC_CNTL__VI = 0x3036; +constexpr unsigned int mmCP_DFY_CMD__VI = 0x3034; +constexpr unsigned int mmCP_DISPATCH_INDR_ADDR__VI = 0xC0F6; +constexpr unsigned int mmCP_DISPATCH_INDR_ADDR_HI__VI = 0xC0F7; +constexpr unsigned int mmCP_DRAW_INDX_INDR_ADDR__VI = 0xC0F4; +constexpr unsigned int mmCP_DRAW_INDX_INDR_ADDR_HI__VI = 0xC0F5; +constexpr unsigned int mmCP_DRAW_OBJECT__VI = 0xD810; +constexpr unsigned int mmCP_DRAW_OBJECT_COUNTER__VI = 0xD811; +constexpr unsigned int mmCP_DRAW_WINDOW_CNTL__VI = 0xD815; +constexpr unsigned int mmCP_DRAW_WINDOW_HI__VI = 0xD813; +constexpr unsigned int mmCP_DRAW_WINDOW_LO__VI = 0xD814; +constexpr unsigned int mmCP_DRAW_WINDOW_MASK_HI__VI = 0xD812; +constexpr unsigned int mmCP_EOP_DONE_CNTX_ID__VI = 0xC0D7; +constexpr unsigned int mmCP_GDS_BKUP_ADDR__VI = 0xC0FB; +constexpr unsigned int mmCP_GDS_BKUP_ADDR_HI__VI = 0xC0FC; +constexpr unsigned int mmCP_HPD_STATUS0__VI = 0x3241; +constexpr unsigned int mmCP_HQD_CNTL_STACK_OFFSET__VI = 0x3273; +constexpr unsigned int mmCP_HQD_CNTL_STACK_SIZE__VI = 0x3274; +constexpr unsigned int mmCP_HQD_CTX_SAVE_BASE_ADDR_HI__VI = 0x3271; +constexpr unsigned int mmCP_HQD_CTX_SAVE_BASE_ADDR_LO__VI = 0x3270; +constexpr unsigned int mmCP_HQD_CTX_SAVE_CONTROL__VI = 0x3272; +constexpr unsigned int mmCP_HQD_CTX_SAVE_SIZE__VI = 0x3276; +constexpr unsigned int mmCP_HQD_EOP_BASE_ADDR__VI = 0x326A; +constexpr unsigned int mmCP_HQD_EOP_BASE_ADDR_HI__VI = 0x326B; +constexpr unsigned int mmCP_HQD_EOP_CONTROL__VI = 0x326C; +constexpr unsigned int mmCP_HQD_EOP_DONES__VI = 0x327A; +constexpr unsigned int mmCP_HQD_EOP_EVENTS__VI = 0x326F; +constexpr unsigned int mmCP_HQD_EOP_RPTR__VI = 0x326D; +constexpr unsigned int mmCP_HQD_EOP_WPTR__VI = 0x326E; +constexpr unsigned int mmCP_HQD_EOP_WPTR_MEM__VI = 0x3279; +constexpr unsigned int mmCP_HQD_ERROR__VI = 0x3278; +constexpr unsigned int mmCP_HQD_GDS_RESOURCE_STATE__VI = 0x3277; +constexpr unsigned int mmCP_HQD_HQ_CONTROL0__VI = 0x3266; +constexpr unsigned int mmCP_HQD_HQ_CONTROL1__VI = 0x3269; +constexpr unsigned int mmCP_HQD_HQ_STATUS0__VI = 0x3265; +constexpr unsigned int mmCP_HQD_HQ_STATUS1__VI = 0x3268; +constexpr unsigned int mmCP_HQD_OFFLOAD__VI = 0x325E; +constexpr unsigned int mmCP_HQD_WG_STATE_OFFSET__VI = 0x3275; +constexpr unsigned int mmCP_INDEX_BASE_ADDR__VI = 0xC0F8; +constexpr unsigned int mmCP_INDEX_BASE_ADDR_HI__VI = 0xC0F9; +constexpr unsigned int mmCP_INDEX_TYPE__VI = 0xC0FA; +constexpr unsigned int mmCP_MEC1_F32_INT_DIS__VI = 0x30BD; +constexpr unsigned int mmCP_MEC2_F32_INT_DIS__VI = 0x30BE; +constexpr unsigned int mmCP_MEC_DOORBELL_RANGE_LOWER__VI = 0x305C; +constexpr unsigned int mmCP_MEC_DOORBELL_RANGE_UPPER__VI = 0x305D; +constexpr unsigned int mmCP_MEC_ME1_UCODE_ADDR__VI = 0xF81A; +constexpr unsigned int mmCP_MEC_ME1_UCODE_DATA__VI = 0xF81B; +constexpr unsigned int mmCP_MEC_ME2_UCODE_ADDR__VI = 0xF81C; +constexpr unsigned int mmCP_MEC_ME2_UCODE_DATA__VI = 0xF81D; +constexpr unsigned int mmCP_ME_RAM_DATA__SI__CI = 0x3058; +constexpr unsigned int mmCP_ME_RAM_DATA__VI = 0xF817; +constexpr unsigned int mmCP_ME_RAM_RADDR__SI__CI = 0x3056; +constexpr unsigned int mmCP_ME_RAM_RADDR__VI = 0xF816; +constexpr unsigned int mmCP_ME_RAM_WADDR__SI__CI = 0x3057; +constexpr unsigned int mmCP_ME_RAM_WADDR__VI = 0xF816; +constexpr unsigned int mmCP_PFP_COMPLETION_STATUS__VI = 0xC0EC; +constexpr unsigned int mmCP_PFP_METADATA_BASE_ADDR__VI = 0xC0F0; +constexpr unsigned int mmCP_PFP_METADATA_BASE_ADDR_HI__VI = 0xC0F1; +constexpr unsigned int mmCP_PFP_UCODE_ADDR__SI__CI = 0x3054; +constexpr unsigned int mmCP_PFP_UCODE_ADDR__VI = 0xF814; +constexpr unsigned int mmCP_PFP_UCODE_DATA__SI__CI = 0x3055; +constexpr unsigned int mmCP_PFP_UCODE_DATA__VI = 0xF815; +constexpr unsigned int mmCP_PIPE_STATS_CONTROL__VI = 0xC03D; +constexpr unsigned int mmCP_PQ_STATUS__VI = 0x30B8; +constexpr unsigned int mmCP_PRED_NOT_VISIBLE__VI = 0xC0EE; +constexpr unsigned int mmCP_RB_DOORBELL_CONTROL__VI = 0x3059; +constexpr unsigned int mmCP_RB_DOORBELL_RANGE_LOWER__VI = 0x305A; +constexpr unsigned int mmCP_RB_DOORBELL_RANGE_UPPER__VI = 0x305B; +constexpr unsigned int mmCP_SAMPLE_STATUS__VI = 0xC0FD; +constexpr unsigned int mmCP_STREAM_OUT_CONTROL__VI = 0xC03E; +constexpr unsigned int mmCP_VIRT_STATUS__VI = 0x3038; +constexpr unsigned int mmCP_VMID_STATUS__VI = 0x30BF; +constexpr unsigned int mmCRTC0_CRTC_3D_STRUCTURE_CONTROL__VI = 0x1B78; +constexpr unsigned int mmCRTC0_CRTC_AVSYNC_COUNTER__VI = 0x1B9B; +constexpr unsigned int mmCRTC0_CRTC_BLACK_COLOR__VI = 0x1BCC; +constexpr unsigned int mmCRTC0_CRTC_BLACK_COLOR_EXT__VI = 0x1BCD; +constexpr unsigned int mmCRTC0_CRTC_BLANK_DATA_COLOR__VI = 0x1BCA; +constexpr unsigned int mmCRTC0_CRTC_BLANK_DATA_COLOR_EXT__VI = 0x1BCB; +constexpr unsigned int mmCRTC0_CRTC_CRC0_DATA_B__VI = 0x1BDA; +constexpr unsigned int mmCRTC0_CRTC_CRC0_DATA_RG__VI = 0x1BD9; +constexpr unsigned int mmCRTC0_CRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x1BD5; +constexpr unsigned int mmCRTC0_CRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x1BD6; +constexpr unsigned int mmCRTC0_CRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x1BD7; +constexpr unsigned int mmCRTC0_CRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x1BD8; +constexpr unsigned int mmCRTC0_CRTC_CRC1_DATA_B__VI = 0x1BE0; +constexpr unsigned int mmCRTC0_CRTC_CRC1_DATA_RG__VI = 0x1BDF; +constexpr unsigned int mmCRTC0_CRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x1BDB; +constexpr unsigned int mmCRTC0_CRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x1BDC; +constexpr unsigned int mmCRTC0_CRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x1BDD; +constexpr unsigned int mmCRTC0_CRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x1BDE; +constexpr unsigned int mmCRTC0_CRTC_CRC_CNTL__VI = 0x1BD4; +constexpr unsigned int mmCRTC0_CRTC_DCFE_CLOCK_CONTROL__VI = 0x1B7C; +constexpr unsigned int mmCRTC0_CRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x1BE1; +constexpr unsigned int mmCRTC0_CRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x1BE5; +constexpr unsigned int mmCRTC0_CRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x1BE4; +constexpr unsigned int mmCRTC0_CRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x1BE6; +constexpr unsigned int mmCRTC0_CRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x1BE3; +constexpr unsigned int mmCRTC0_CRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x1BE2; +constexpr unsigned int mmCRTC0_CRTC_FIELD_INDICATION_CONTROL__VI = 0x1BA0; +constexpr unsigned int mmCRTC0_CRTC_GSL_CONTROL__VI = 0x1B7B; +constexpr unsigned int mmCRTC0_CRTC_GSL_VSYNC_GAP__VI = 0x1B79; +constexpr unsigned int mmCRTC0_CRTC_GSL_WINDOW__VI = 0x1B7A; +constexpr unsigned int mmCRTC0_CRTC_H_BLANK_EARLY_NUM__VI = 0x1B7D; +constexpr unsigned int mmCRTC0_CRTC_OVERSCAN_COLOR__VI = 0x1BC8; +constexpr unsigned int mmCRTC0_CRTC_OVERSCAN_COLOR_EXT__VI = 0x1BC9; +constexpr unsigned int mmCRTC0_CRTC_PIXEL_DATA_READBACK0__VI = 0x1BA1; +constexpr unsigned int mmCRTC0_CRTC_PIXEL_DATA_READBACK1__VI = 0x1BA2; +constexpr unsigned int mmCRTC0_CRTC_STATIC_SCREEN_CONTROL__VI = 0x1BE7; +constexpr unsigned int mmCRTC0_CRTC_STEREO_FORCE_NEXT_EYE__VI = 0x1B9A; +constexpr unsigned int mmCRTC0_CRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x1BCF; +constexpr unsigned int mmCRTC0_CRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x1BCE; +constexpr unsigned int mmCRTC0_CRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x1BD1; +constexpr unsigned int mmCRTC0_CRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x1BD0; +constexpr unsigned int mmCRTC0_CRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x1BD3; +constexpr unsigned int mmCRTC0_CRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x1BD2; +constexpr unsigned int mmCRTC0_DCFE_DBG_SEL__VI = 0x1B7E; +constexpr unsigned int mmCRTC0_DCFE_MEM_PWR_CTRL__VI = 0x1B7F; +constexpr unsigned int mmCRTC0_DCFE_MEM_PWR_CTRL2__VI = 0x1BB8; +constexpr unsigned int mmCRTC0_DCFE_MEM_PWR_STATUS__VI = 0x1BB9; +constexpr unsigned int mmCRTC0_PIXEL_RATE_CNTL__VI = 0x0140; +constexpr unsigned int mmCRTC1_CRTC_3D_STRUCTURE_CONTROL__VI = 0x1D78; +constexpr unsigned int mmCRTC1_CRTC_ALLOW_STOP_OFF_V_CNT__VI = 0x1DC3; +constexpr unsigned int mmCRTC1_CRTC_AVSYNC_COUNTER__VI = 0x1D9B; +constexpr unsigned int mmCRTC1_CRTC_BLACK_COLOR__VI = 0x1DCC; +constexpr unsigned int mmCRTC1_CRTC_BLACK_COLOR_EXT__VI = 0x1DCD; +constexpr unsigned int mmCRTC1_CRTC_BLANK_CONTROL__SI__CI = 0x1E9D; +constexpr unsigned int mmCRTC1_CRTC_BLANK_CONTROL__VI = 0x1D9D; +constexpr unsigned int mmCRTC1_CRTC_BLANK_DATA_COLOR__VI = 0x1DCA; +constexpr unsigned int mmCRTC1_CRTC_BLANK_DATA_COLOR_EXT__VI = 0x1DCB; +constexpr unsigned int mmCRTC1_CRTC_CONTROL__VI = 0x1D9C; +constexpr unsigned int mmCRTC1_CRTC_COUNT_CONTROL__VI = 0x1DA9; +constexpr unsigned int mmCRTC1_CRTC_COUNT_RESET__VI = 0x1DAA; +constexpr unsigned int mmCRTC1_CRTC_CRC0_DATA_B__VI = 0x1DDA; +constexpr unsigned int mmCRTC1_CRTC_CRC0_DATA_RG__VI = 0x1DD9; +constexpr unsigned int mmCRTC1_CRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x1DD5; +constexpr unsigned int mmCRTC1_CRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x1DD6; +constexpr unsigned int mmCRTC1_CRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x1DD7; +constexpr unsigned int mmCRTC1_CRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x1DD8; +constexpr unsigned int mmCRTC1_CRTC_CRC1_DATA_B__VI = 0x1DE0; +constexpr unsigned int mmCRTC1_CRTC_CRC1_DATA_RG__VI = 0x1DDF; +constexpr unsigned int mmCRTC1_CRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x1DDB; +constexpr unsigned int mmCRTC1_CRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x1DDC; +constexpr unsigned int mmCRTC1_CRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x1DDD; +constexpr unsigned int mmCRTC1_CRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x1DDE; +constexpr unsigned int mmCRTC1_CRTC_CRC_CNTL__VI = 0x1DD4; +constexpr unsigned int mmCRTC1_CRTC_DCFE_CLOCK_CONTROL__VI = 0x1D7C; +constexpr unsigned int mmCRTC1_CRTC_DOUBLE_BUFFER_CONTROL__VI = 0x1DB6; +constexpr unsigned int mmCRTC1_CRTC_DTMTEST_CNTL__VI = 0x1D92; +constexpr unsigned int mmCRTC1_CRTC_DTMTEST_STATUS_POSITION__VI = 0x1D93; +constexpr unsigned int mmCRTC1_CRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x1DE1; +constexpr unsigned int mmCRTC1_CRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x1DE5; +constexpr unsigned int mmCRTC1_CRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x1DE4; +constexpr unsigned int mmCRTC1_CRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x1DE6; +constexpr unsigned int mmCRTC1_CRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x1DE3; +constexpr unsigned int mmCRTC1_CRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x1DE2; +constexpr unsigned int mmCRTC1_CRTC_FIELD_INDICATION_CONTROL__VI = 0x1DA0; +constexpr unsigned int mmCRTC1_CRTC_FLOW_CONTROL__VI = 0x1D99; +constexpr unsigned int mmCRTC1_CRTC_FORCE_COUNT_NOW_CNTL__VI = 0x1D98; +constexpr unsigned int mmCRTC1_CRTC_GSL_CONTROL__VI = 0x1D7B; +constexpr unsigned int mmCRTC1_CRTC_GSL_VSYNC_GAP__VI = 0x1D79; +constexpr unsigned int mmCRTC1_CRTC_GSL_WINDOW__VI = 0x1D7A; +constexpr unsigned int mmCRTC1_CRTC_H_BLANK_EARLY_NUM__VI = 0x1D7D; +constexpr unsigned int mmCRTC1_CRTC_H_BLANK_START_END__VI = 0x1D81; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_A__VI = 0x1D82; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_A_CNTL__VI = 0x1D83; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_B__VI = 0x1D84; +constexpr unsigned int mmCRTC1_CRTC_H_SYNC_B_CNTL__VI = 0x1D85; +constexpr unsigned int mmCRTC1_CRTC_H_TOTAL__VI = 0x1D80; +constexpr unsigned int mmCRTC1_CRTC_INTERLACE_CONTROL__VI = 0x1D9E; +constexpr unsigned int mmCRTC1_CRTC_INTERLACE_STATUS__VI = 0x1D9F; +constexpr unsigned int mmCRTC1_CRTC_INTERRUPT_CONTROL__VI = 0x1DB4; +constexpr unsigned int mmCRTC1_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__VI = 0x1DAB; +constexpr unsigned int mmCRTC1_CRTC_MASTER_EN__VI = 0x1DC2; +constexpr unsigned int mmCRTC1_CRTC_MVP_INBAND_CNTL_INSERT__VI = 0x1DBF; +constexpr unsigned int mmCRTC1_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__VI = 0x1DC0; +constexpr unsigned int mmCRTC1_CRTC_MVP_STATUS__VI = 0x1DC1; +constexpr unsigned int mmCRTC1_CRTC_NOM_VERT_POSITION__VI = 0x1DA5; +constexpr unsigned int mmCRTC1_CRTC_OVERSCAN_COLOR__VI = 0x1DC8; +constexpr unsigned int mmCRTC1_CRTC_OVERSCAN_COLOR_EXT__VI = 0x1DC9; +constexpr unsigned int mmCRTC1_CRTC_PIXEL_DATA_READBACK0__VI = 0x1DA1; +constexpr unsigned int mmCRTC1_CRTC_PIXEL_DATA_READBACK1__VI = 0x1DA2; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_CONTROL__VI = 0x1DB0; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_FRAME__VI = 0x1DB2; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_POSITION__VI = 0x1DB1; +constexpr unsigned int mmCRTC1_CRTC_SNAPSHOT_STATUS__VI = 0x1DAF; +constexpr unsigned int mmCRTC1_CRTC_START_LINE_CONTROL__VI = 0x1DB3; +constexpr unsigned int mmCRTC1_CRTC_STATIC_SCREEN_CONTROL__VI = 0x1DE7; +constexpr unsigned int mmCRTC1_CRTC_STATUS__SI__CI = 0x1EA3; +constexpr unsigned int mmCRTC1_CRTC_STATUS__VI = 0x1DA3; +constexpr unsigned int mmCRTC1_CRTC_STATUS_FRAME_COUNT__VI = 0x1DA6; +constexpr unsigned int mmCRTC1_CRTC_STATUS_HV_COUNT__VI = 0x1DA8; +constexpr unsigned int mmCRTC1_CRTC_STATUS_POSITION__SI__CI = 0x1EA4; +constexpr unsigned int mmCRTC1_CRTC_STATUS_POSITION__VI = 0x1DA4; +constexpr unsigned int mmCRTC1_CRTC_STATUS_VF_COUNT__VI = 0x1DA7; +constexpr unsigned int mmCRTC1_CRTC_STEREO_CONTROL__VI = 0x1DAE; +constexpr unsigned int mmCRTC1_CRTC_STEREO_FORCE_NEXT_EYE__VI = 0x1D9A; +constexpr unsigned int mmCRTC1_CRTC_STEREO_STATUS__VI = 0x1DAD; +constexpr unsigned int mmCRTC1_CRTC_TEST_DEBUG_DATA__VI = 0x1DC7; +constexpr unsigned int mmCRTC1_CRTC_TEST_DEBUG_INDEX__VI = 0x1DC6; +constexpr unsigned int mmCRTC1_CRTC_TEST_PATTERN_COLOR__VI = 0x1DBC; +constexpr unsigned int mmCRTC1_CRTC_TEST_PATTERN_CONTROL__VI = 0x1DBA; +constexpr unsigned int mmCRTC1_CRTC_TEST_PATTERN_PARAMETERS__VI = 0x1DBB; +constexpr unsigned int mmCRTC1_CRTC_TRIGA_CNTL__VI = 0x1D94; +constexpr unsigned int mmCRTC1_CRTC_TRIGA_MANUAL_TRIG__VI = 0x1D95; +constexpr unsigned int mmCRTC1_CRTC_TRIGB_CNTL__VI = 0x1D96; +constexpr unsigned int mmCRTC1_CRTC_TRIGB_MANUAL_TRIG__VI = 0x1D97; +constexpr unsigned int mmCRTC1_CRTC_UPDATE_LOCK__VI = 0x1DB5; +constexpr unsigned int mmCRTC1_CRTC_VBI_END__VI = 0x1D86; +constexpr unsigned int mmCRTC1_CRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x1DCF; +constexpr unsigned int mmCRTC1_CRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x1DCE; +constexpr unsigned int mmCRTC1_CRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x1DD1; +constexpr unsigned int mmCRTC1_CRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x1DD0; +constexpr unsigned int mmCRTC1_CRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x1DD3; +constexpr unsigned int mmCRTC1_CRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x1DD2; +constexpr unsigned int mmCRTC1_CRTC_VERT_SYNC_CONTROL__VI = 0x1DAC; +constexpr unsigned int mmCRTC1_CRTC_VGA_PARAMETER_CAPTURE_MODE__VI = 0x1DB7; +constexpr unsigned int mmCRTC1_CRTC_VSYNC_NOM_INT_STATUS__VI = 0x1D8C; +constexpr unsigned int mmCRTC1_CRTC_V_BLANK_START_END__VI = 0x1D8D; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_A__VI = 0x1D8E; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_A_CNTL__VI = 0x1D8F; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_B__VI = 0x1D90; +constexpr unsigned int mmCRTC1_CRTC_V_SYNC_B_CNTL__VI = 0x1D91; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL__VI = 0x1D87; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_CONTROL__VI = 0x1D8A; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_INT_STATUS__VI = 0x1D8B; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_MAX__VI = 0x1D89; +constexpr unsigned int mmCRTC1_CRTC_V_TOTAL_MIN__VI = 0x1D88; +constexpr unsigned int mmCRTC1_CRTC_V_UPDATE_INT_STATUS__VI = 0x1DC4; +constexpr unsigned int mmCRTC1_DCFE_DBG_SEL__VI = 0x1D7E; +constexpr unsigned int mmCRTC1_DCFE_MEM_PWR_CTRL__VI = 0x1D7F; +constexpr unsigned int mmCRTC1_DCFE_MEM_PWR_CTRL2__VI = 0x1DB8; +constexpr unsigned int mmCRTC1_DCFE_MEM_PWR_STATUS__VI = 0x1DB9; +constexpr unsigned int mmCRTC1_MASTER_UPDATE_LOCK__VI = 0x1DBD; +constexpr unsigned int mmCRTC1_MASTER_UPDATE_MODE__SI__CI = 0x1EBE; +constexpr unsigned int mmCRTC1_MASTER_UPDATE_MODE__VI = 0x1DBE; +constexpr unsigned int mmCRTC1_PIXEL_RATE_CNTL__VI = 0x0144; +constexpr unsigned int mmCRTC2_CRTC_3D_STRUCTURE_CONTROL__VI = 0x1F78; +constexpr unsigned int mmCRTC2_CRTC_ALLOW_STOP_OFF_V_CNT__VI = 0x1FC3; +constexpr unsigned int mmCRTC2_CRTC_AVSYNC_COUNTER__VI = 0x1F9B; +constexpr unsigned int mmCRTC2_CRTC_BLACK_COLOR__VI = 0x1FCC; +constexpr unsigned int mmCRTC2_CRTC_BLACK_COLOR_EXT__VI = 0x1FCD; +constexpr unsigned int mmCRTC2_CRTC_BLANK_CONTROL__SI__CI = 0x419D; +constexpr unsigned int mmCRTC2_CRTC_BLANK_CONTROL__VI = 0x1F9D; +constexpr unsigned int mmCRTC2_CRTC_BLANK_DATA_COLOR__VI = 0x1FCA; +constexpr unsigned int mmCRTC2_CRTC_BLANK_DATA_COLOR_EXT__VI = 0x1FCB; +constexpr unsigned int mmCRTC2_CRTC_CONTROL__VI = 0x1F9C; +constexpr unsigned int mmCRTC2_CRTC_COUNT_CONTROL__VI = 0x1FA9; +constexpr unsigned int mmCRTC2_CRTC_COUNT_RESET__VI = 0x1FAA; +constexpr unsigned int mmCRTC2_CRTC_CRC0_DATA_B__VI = 0x1FDA; +constexpr unsigned int mmCRTC2_CRTC_CRC0_DATA_RG__VI = 0x1FD9; +constexpr unsigned int mmCRTC2_CRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x1FD5; +constexpr unsigned int mmCRTC2_CRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x1FD6; +constexpr unsigned int mmCRTC2_CRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x1FD7; +constexpr unsigned int mmCRTC2_CRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x1FD8; +constexpr unsigned int mmCRTC2_CRTC_CRC1_DATA_B__VI = 0x1FE0; +constexpr unsigned int mmCRTC2_CRTC_CRC1_DATA_RG__VI = 0x1FDF; +constexpr unsigned int mmCRTC2_CRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x1FDB; +constexpr unsigned int mmCRTC2_CRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x1FDC; +constexpr unsigned int mmCRTC2_CRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x1FDD; +constexpr unsigned int mmCRTC2_CRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x1FDE; +constexpr unsigned int mmCRTC2_CRTC_CRC_CNTL__VI = 0x1FD4; +constexpr unsigned int mmCRTC2_CRTC_DCFE_CLOCK_CONTROL__VI = 0x1F7C; +constexpr unsigned int mmCRTC2_CRTC_DOUBLE_BUFFER_CONTROL__VI = 0x1FB6; +constexpr unsigned int mmCRTC2_CRTC_DTMTEST_CNTL__VI = 0x1F92; +constexpr unsigned int mmCRTC2_CRTC_DTMTEST_STATUS_POSITION__VI = 0x1F93; +constexpr unsigned int mmCRTC2_CRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x1FE1; +constexpr unsigned int mmCRTC2_CRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x1FE5; +constexpr unsigned int mmCRTC2_CRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x1FE4; +constexpr unsigned int mmCRTC2_CRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x1FE6; +constexpr unsigned int mmCRTC2_CRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x1FE3; +constexpr unsigned int mmCRTC2_CRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x1FE2; +constexpr unsigned int mmCRTC2_CRTC_FIELD_INDICATION_CONTROL__VI = 0x1FA0; +constexpr unsigned int mmCRTC2_CRTC_FLOW_CONTROL__VI = 0x1F99; +constexpr unsigned int mmCRTC2_CRTC_FORCE_COUNT_NOW_CNTL__VI = 0x1F98; +constexpr unsigned int mmCRTC2_CRTC_GSL_CONTROL__VI = 0x1F7B; +constexpr unsigned int mmCRTC2_CRTC_GSL_VSYNC_GAP__VI = 0x1F79; +constexpr unsigned int mmCRTC2_CRTC_GSL_WINDOW__VI = 0x1F7A; +constexpr unsigned int mmCRTC2_CRTC_H_BLANK_EARLY_NUM__VI = 0x1F7D; +constexpr unsigned int mmCRTC2_CRTC_H_BLANK_START_END__VI = 0x1F81; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_A__VI = 0x1F82; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_A_CNTL__VI = 0x1F83; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_B__VI = 0x1F84; +constexpr unsigned int mmCRTC2_CRTC_H_SYNC_B_CNTL__VI = 0x1F85; +constexpr unsigned int mmCRTC2_CRTC_H_TOTAL__VI = 0x1F80; +constexpr unsigned int mmCRTC2_CRTC_INTERLACE_CONTROL__VI = 0x1F9E; +constexpr unsigned int mmCRTC2_CRTC_INTERLACE_STATUS__VI = 0x1F9F; +constexpr unsigned int mmCRTC2_CRTC_INTERRUPT_CONTROL__VI = 0x1FB4; +constexpr unsigned int mmCRTC2_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__VI = 0x1FAB; +constexpr unsigned int mmCRTC2_CRTC_MASTER_EN__VI = 0x1FC2; +constexpr unsigned int mmCRTC2_CRTC_MVP_INBAND_CNTL_INSERT__VI = 0x1FBF; +constexpr unsigned int mmCRTC2_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__VI = 0x1FC0; +constexpr unsigned int mmCRTC2_CRTC_MVP_STATUS__VI = 0x1FC1; +constexpr unsigned int mmCRTC2_CRTC_NOM_VERT_POSITION__VI = 0x1FA5; +constexpr unsigned int mmCRTC2_CRTC_OVERSCAN_COLOR__VI = 0x1FC8; +constexpr unsigned int mmCRTC2_CRTC_OVERSCAN_COLOR_EXT__VI = 0x1FC9; +constexpr unsigned int mmCRTC2_CRTC_PIXEL_DATA_READBACK0__VI = 0x1FA1; +constexpr unsigned int mmCRTC2_CRTC_PIXEL_DATA_READBACK1__VI = 0x1FA2; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_CONTROL__VI = 0x1FB0; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_FRAME__VI = 0x1FB2; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_POSITION__VI = 0x1FB1; +constexpr unsigned int mmCRTC2_CRTC_SNAPSHOT_STATUS__VI = 0x1FAF; +constexpr unsigned int mmCRTC2_CRTC_START_LINE_CONTROL__VI = 0x1FB3; +constexpr unsigned int mmCRTC2_CRTC_STATIC_SCREEN_CONTROL__VI = 0x1FE7; +constexpr unsigned int mmCRTC2_CRTC_STATUS__SI__CI = 0x41A3; +constexpr unsigned int mmCRTC2_CRTC_STATUS__VI = 0x1FA3; +constexpr unsigned int mmCRTC2_CRTC_STATUS_FRAME_COUNT__VI = 0x1FA6; +constexpr unsigned int mmCRTC2_CRTC_STATUS_HV_COUNT__VI = 0x1FA8; +constexpr unsigned int mmCRTC2_CRTC_STATUS_POSITION__SI__CI = 0x41A4; +constexpr unsigned int mmCRTC2_CRTC_STATUS_POSITION__VI = 0x1FA4; +constexpr unsigned int mmCRTC2_CRTC_STATUS_VF_COUNT__VI = 0x1FA7; +constexpr unsigned int mmCRTC2_CRTC_STEREO_CONTROL__VI = 0x1FAE; +constexpr unsigned int mmCRTC2_CRTC_STEREO_FORCE_NEXT_EYE__VI = 0x1F9A; +constexpr unsigned int mmCRTC2_CRTC_STEREO_STATUS__VI = 0x1FAD; +constexpr unsigned int mmCRTC2_CRTC_TEST_DEBUG_DATA__VI = 0x1FC7; +constexpr unsigned int mmCRTC2_CRTC_TEST_DEBUG_INDEX__VI = 0x1FC6; +constexpr unsigned int mmCRTC2_CRTC_TEST_PATTERN_COLOR__VI = 0x1FBC; +constexpr unsigned int mmCRTC2_CRTC_TEST_PATTERN_CONTROL__VI = 0x1FBA; +constexpr unsigned int mmCRTC2_CRTC_TEST_PATTERN_PARAMETERS__VI = 0x1FBB; +constexpr unsigned int mmCRTC2_CRTC_TRIGA_CNTL__VI = 0x1F94; +constexpr unsigned int mmCRTC2_CRTC_TRIGA_MANUAL_TRIG__VI = 0x1F95; +constexpr unsigned int mmCRTC2_CRTC_TRIGB_CNTL__VI = 0x1F96; +constexpr unsigned int mmCRTC2_CRTC_TRIGB_MANUAL_TRIG__VI = 0x1F97; +constexpr unsigned int mmCRTC2_CRTC_UPDATE_LOCK__VI = 0x1FB5; +constexpr unsigned int mmCRTC2_CRTC_VBI_END__VI = 0x1F86; +constexpr unsigned int mmCRTC2_CRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x1FCF; +constexpr unsigned int mmCRTC2_CRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x1FCE; +constexpr unsigned int mmCRTC2_CRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x1FD1; +constexpr unsigned int mmCRTC2_CRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x1FD0; +constexpr unsigned int mmCRTC2_CRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x1FD3; +constexpr unsigned int mmCRTC2_CRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x1FD2; +constexpr unsigned int mmCRTC2_CRTC_VERT_SYNC_CONTROL__VI = 0x1FAC; +constexpr unsigned int mmCRTC2_CRTC_VGA_PARAMETER_CAPTURE_MODE__VI = 0x1FB7; +constexpr unsigned int mmCRTC2_CRTC_VSYNC_NOM_INT_STATUS__VI = 0x1F8C; +constexpr unsigned int mmCRTC2_CRTC_V_BLANK_START_END__VI = 0x1F8D; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_A__VI = 0x1F8E; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_A_CNTL__VI = 0x1F8F; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_B__VI = 0x1F90; +constexpr unsigned int mmCRTC2_CRTC_V_SYNC_B_CNTL__VI = 0x1F91; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL__VI = 0x1F87; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_CONTROL__VI = 0x1F8A; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_INT_STATUS__VI = 0x1F8B; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_MAX__VI = 0x1F89; +constexpr unsigned int mmCRTC2_CRTC_V_TOTAL_MIN__VI = 0x1F88; +constexpr unsigned int mmCRTC2_CRTC_V_UPDATE_INT_STATUS__VI = 0x1FC4; +constexpr unsigned int mmCRTC2_DCFE_DBG_SEL__VI = 0x1F7E; +constexpr unsigned int mmCRTC2_DCFE_MEM_PWR_CTRL__VI = 0x1F7F; +constexpr unsigned int mmCRTC2_DCFE_MEM_PWR_CTRL2__VI = 0x1FB8; +constexpr unsigned int mmCRTC2_DCFE_MEM_PWR_STATUS__VI = 0x1FB9; +constexpr unsigned int mmCRTC2_MASTER_UPDATE_LOCK__VI = 0x1FBD; +constexpr unsigned int mmCRTC2_MASTER_UPDATE_MODE__SI__CI = 0x41BE; +constexpr unsigned int mmCRTC2_MASTER_UPDATE_MODE__VI = 0x1FBE; +constexpr unsigned int mmCRTC2_PIXEL_RATE_CNTL__VI = 0x0148; +constexpr unsigned int mmCRTC3_CRTC_3D_STRUCTURE_CONTROL__VI = 0x4178; +constexpr unsigned int mmCRTC3_CRTC_ALLOW_STOP_OFF_V_CNT__VI = 0x41C3; +constexpr unsigned int mmCRTC3_CRTC_AVSYNC_COUNTER__VI = 0x419B; +constexpr unsigned int mmCRTC3_CRTC_BLACK_COLOR__VI = 0x41CC; +constexpr unsigned int mmCRTC3_CRTC_BLACK_COLOR_EXT__VI = 0x41CD; +constexpr unsigned int mmCRTC3_CRTC_BLANK_CONTROL__SI__CI = 0x449D; +constexpr unsigned int mmCRTC3_CRTC_BLANK_CONTROL__VI = 0x419D; +constexpr unsigned int mmCRTC3_CRTC_BLANK_DATA_COLOR__VI = 0x41CA; +constexpr unsigned int mmCRTC3_CRTC_BLANK_DATA_COLOR_EXT__VI = 0x41CB; +constexpr unsigned int mmCRTC3_CRTC_CONTROL__VI = 0x419C; +constexpr unsigned int mmCRTC3_CRTC_COUNT_CONTROL__VI = 0x41A9; +constexpr unsigned int mmCRTC3_CRTC_COUNT_RESET__VI = 0x41AA; +constexpr unsigned int mmCRTC3_CRTC_CRC0_DATA_B__VI = 0x41DA; +constexpr unsigned int mmCRTC3_CRTC_CRC0_DATA_RG__VI = 0x41D9; +constexpr unsigned int mmCRTC3_CRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x41D5; +constexpr unsigned int mmCRTC3_CRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x41D6; +constexpr unsigned int mmCRTC3_CRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x41D7; +constexpr unsigned int mmCRTC3_CRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x41D8; +constexpr unsigned int mmCRTC3_CRTC_CRC1_DATA_B__VI = 0x41E0; +constexpr unsigned int mmCRTC3_CRTC_CRC1_DATA_RG__VI = 0x41DF; +constexpr unsigned int mmCRTC3_CRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x41DB; +constexpr unsigned int mmCRTC3_CRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x41DC; +constexpr unsigned int mmCRTC3_CRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x41DD; +constexpr unsigned int mmCRTC3_CRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x41DE; +constexpr unsigned int mmCRTC3_CRTC_CRC_CNTL__VI = 0x41D4; +constexpr unsigned int mmCRTC3_CRTC_DCFE_CLOCK_CONTROL__VI = 0x417C; +constexpr unsigned int mmCRTC3_CRTC_DOUBLE_BUFFER_CONTROL__VI = 0x41B6; +constexpr unsigned int mmCRTC3_CRTC_DTMTEST_CNTL__VI = 0x4192; +constexpr unsigned int mmCRTC3_CRTC_DTMTEST_STATUS_POSITION__VI = 0x4193; +constexpr unsigned int mmCRTC3_CRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x41E1; +constexpr unsigned int mmCRTC3_CRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x41E5; +constexpr unsigned int mmCRTC3_CRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x41E4; +constexpr unsigned int mmCRTC3_CRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x41E6; +constexpr unsigned int mmCRTC3_CRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x41E3; +constexpr unsigned int mmCRTC3_CRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x41E2; +constexpr unsigned int mmCRTC3_CRTC_FIELD_INDICATION_CONTROL__VI = 0x41A0; +constexpr unsigned int mmCRTC3_CRTC_FLOW_CONTROL__VI = 0x4199; +constexpr unsigned int mmCRTC3_CRTC_FORCE_COUNT_NOW_CNTL__VI = 0x4198; +constexpr unsigned int mmCRTC3_CRTC_GSL_CONTROL__VI = 0x417B; +constexpr unsigned int mmCRTC3_CRTC_GSL_VSYNC_GAP__VI = 0x4179; +constexpr unsigned int mmCRTC3_CRTC_GSL_WINDOW__VI = 0x417A; +constexpr unsigned int mmCRTC3_CRTC_H_BLANK_EARLY_NUM__VI = 0x417D; +constexpr unsigned int mmCRTC3_CRTC_H_BLANK_START_END__VI = 0x4181; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_A__VI = 0x4182; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_A_CNTL__VI = 0x4183; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_B__VI = 0x4184; +constexpr unsigned int mmCRTC3_CRTC_H_SYNC_B_CNTL__VI = 0x4185; +constexpr unsigned int mmCRTC3_CRTC_H_TOTAL__VI = 0x4180; +constexpr unsigned int mmCRTC3_CRTC_INTERLACE_CONTROL__VI = 0x419E; +constexpr unsigned int mmCRTC3_CRTC_INTERLACE_STATUS__VI = 0x419F; +constexpr unsigned int mmCRTC3_CRTC_INTERRUPT_CONTROL__VI = 0x41B4; +constexpr unsigned int mmCRTC3_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__VI = 0x41AB; +constexpr unsigned int mmCRTC3_CRTC_MASTER_EN__VI = 0x41C2; +constexpr unsigned int mmCRTC3_CRTC_MVP_INBAND_CNTL_INSERT__VI = 0x41BF; +constexpr unsigned int mmCRTC3_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__VI = 0x41C0; +constexpr unsigned int mmCRTC3_CRTC_MVP_STATUS__VI = 0x41C1; +constexpr unsigned int mmCRTC3_CRTC_NOM_VERT_POSITION__VI = 0x41A5; +constexpr unsigned int mmCRTC3_CRTC_OVERSCAN_COLOR__VI = 0x41C8; +constexpr unsigned int mmCRTC3_CRTC_OVERSCAN_COLOR_EXT__VI = 0x41C9; +constexpr unsigned int mmCRTC3_CRTC_PIXEL_DATA_READBACK0__VI = 0x41A1; +constexpr unsigned int mmCRTC3_CRTC_PIXEL_DATA_READBACK1__VI = 0x41A2; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_CONTROL__VI = 0x41B0; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_FRAME__VI = 0x41B2; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_POSITION__VI = 0x41B1; +constexpr unsigned int mmCRTC3_CRTC_SNAPSHOT_STATUS__VI = 0x41AF; +constexpr unsigned int mmCRTC3_CRTC_START_LINE_CONTROL__VI = 0x41B3; +constexpr unsigned int mmCRTC3_CRTC_STATIC_SCREEN_CONTROL__VI = 0x41E7; +constexpr unsigned int mmCRTC3_CRTC_STATUS__SI__CI = 0x44A3; +constexpr unsigned int mmCRTC3_CRTC_STATUS__VI = 0x41A3; +constexpr unsigned int mmCRTC3_CRTC_STATUS_FRAME_COUNT__VI = 0x41A6; +constexpr unsigned int mmCRTC3_CRTC_STATUS_HV_COUNT__VI = 0x41A8; +constexpr unsigned int mmCRTC3_CRTC_STATUS_POSITION__SI__CI = 0x44A4; +constexpr unsigned int mmCRTC3_CRTC_STATUS_POSITION__VI = 0x41A4; +constexpr unsigned int mmCRTC3_CRTC_STATUS_VF_COUNT__VI = 0x41A7; +constexpr unsigned int mmCRTC3_CRTC_STEREO_CONTROL__VI = 0x41AE; +constexpr unsigned int mmCRTC3_CRTC_STEREO_FORCE_NEXT_EYE__VI = 0x419A; +constexpr unsigned int mmCRTC3_CRTC_STEREO_STATUS__VI = 0x41AD; +constexpr unsigned int mmCRTC3_CRTC_TEST_DEBUG_DATA__VI = 0x41C7; +constexpr unsigned int mmCRTC3_CRTC_TEST_DEBUG_INDEX__VI = 0x41C6; +constexpr unsigned int mmCRTC3_CRTC_TEST_PATTERN_COLOR__VI = 0x41BC; +constexpr unsigned int mmCRTC3_CRTC_TEST_PATTERN_CONTROL__VI = 0x41BA; +constexpr unsigned int mmCRTC3_CRTC_TEST_PATTERN_PARAMETERS__VI = 0x41BB; +constexpr unsigned int mmCRTC3_CRTC_TRIGA_CNTL__VI = 0x4194; +constexpr unsigned int mmCRTC3_CRTC_TRIGA_MANUAL_TRIG__VI = 0x4195; +constexpr unsigned int mmCRTC3_CRTC_TRIGB_CNTL__VI = 0x4196; +constexpr unsigned int mmCRTC3_CRTC_TRIGB_MANUAL_TRIG__VI = 0x4197; +constexpr unsigned int mmCRTC3_CRTC_UPDATE_LOCK__VI = 0x41B5; +constexpr unsigned int mmCRTC3_CRTC_VBI_END__VI = 0x4186; +constexpr unsigned int mmCRTC3_CRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x41CF; +constexpr unsigned int mmCRTC3_CRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x41CE; +constexpr unsigned int mmCRTC3_CRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x41D1; +constexpr unsigned int mmCRTC3_CRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x41D0; +constexpr unsigned int mmCRTC3_CRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x41D3; +constexpr unsigned int mmCRTC3_CRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x41D2; +constexpr unsigned int mmCRTC3_CRTC_VERT_SYNC_CONTROL__VI = 0x41AC; +constexpr unsigned int mmCRTC3_CRTC_VGA_PARAMETER_CAPTURE_MODE__VI = 0x41B7; +constexpr unsigned int mmCRTC3_CRTC_VSYNC_NOM_INT_STATUS__VI = 0x418C; +constexpr unsigned int mmCRTC3_CRTC_V_BLANK_START_END__VI = 0x418D; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_A__VI = 0x418E; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_A_CNTL__VI = 0x418F; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_B__VI = 0x4190; +constexpr unsigned int mmCRTC3_CRTC_V_SYNC_B_CNTL__VI = 0x4191; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL__VI = 0x4187; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_CONTROL__VI = 0x418A; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_INT_STATUS__VI = 0x418B; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_MAX__VI = 0x4189; +constexpr unsigned int mmCRTC3_CRTC_V_TOTAL_MIN__VI = 0x4188; +constexpr unsigned int mmCRTC3_CRTC_V_UPDATE_INT_STATUS__VI = 0x41C4; +constexpr unsigned int mmCRTC3_DCFE_DBG_SEL__VI = 0x417E; +constexpr unsigned int mmCRTC3_DCFE_MEM_PWR_CTRL__VI = 0x417F; +constexpr unsigned int mmCRTC3_DCFE_MEM_PWR_CTRL2__VI = 0x41B8; +constexpr unsigned int mmCRTC3_DCFE_MEM_PWR_STATUS__VI = 0x41B9; +constexpr unsigned int mmCRTC3_MASTER_UPDATE_LOCK__VI = 0x41BD; +constexpr unsigned int mmCRTC3_MASTER_UPDATE_MODE__SI__CI = 0x44BE; +constexpr unsigned int mmCRTC3_MASTER_UPDATE_MODE__VI = 0x41BE; +constexpr unsigned int mmCRTC3_PIXEL_RATE_CNTL__VI = 0x014C; +constexpr unsigned int mmCRTC4_CRTC_3D_STRUCTURE_CONTROL__VI = 0x4378; +constexpr unsigned int mmCRTC4_CRTC_ALLOW_STOP_OFF_V_CNT__VI = 0x43C3; +constexpr unsigned int mmCRTC4_CRTC_AVSYNC_COUNTER__VI = 0x439B; +constexpr unsigned int mmCRTC4_CRTC_BLACK_COLOR__VI = 0x43CC; +constexpr unsigned int mmCRTC4_CRTC_BLACK_COLOR_EXT__VI = 0x43CD; +constexpr unsigned int mmCRTC4_CRTC_BLANK_CONTROL__SI__CI = 0x479D; +constexpr unsigned int mmCRTC4_CRTC_BLANK_CONTROL__VI = 0x439D; +constexpr unsigned int mmCRTC4_CRTC_BLANK_DATA_COLOR__VI = 0x43CA; +constexpr unsigned int mmCRTC4_CRTC_BLANK_DATA_COLOR_EXT__VI = 0x43CB; +constexpr unsigned int mmCRTC4_CRTC_CONTROL__VI = 0x439C; +constexpr unsigned int mmCRTC4_CRTC_COUNT_CONTROL__VI = 0x43A9; +constexpr unsigned int mmCRTC4_CRTC_COUNT_RESET__VI = 0x43AA; +constexpr unsigned int mmCRTC4_CRTC_CRC0_DATA_B__VI = 0x43DA; +constexpr unsigned int mmCRTC4_CRTC_CRC0_DATA_RG__VI = 0x43D9; +constexpr unsigned int mmCRTC4_CRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x43D5; +constexpr unsigned int mmCRTC4_CRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x43D6; +constexpr unsigned int mmCRTC4_CRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x43D7; +constexpr unsigned int mmCRTC4_CRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x43D8; +constexpr unsigned int mmCRTC4_CRTC_CRC1_DATA_B__VI = 0x43E0; +constexpr unsigned int mmCRTC4_CRTC_CRC1_DATA_RG__VI = 0x43DF; +constexpr unsigned int mmCRTC4_CRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x43DB; +constexpr unsigned int mmCRTC4_CRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x43DC; +constexpr unsigned int mmCRTC4_CRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x43DD; +constexpr unsigned int mmCRTC4_CRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x43DE; +constexpr unsigned int mmCRTC4_CRTC_CRC_CNTL__VI = 0x43D4; +constexpr unsigned int mmCRTC4_CRTC_DCFE_CLOCK_CONTROL__VI = 0x437C; +constexpr unsigned int mmCRTC4_CRTC_DOUBLE_BUFFER_CONTROL__VI = 0x43B6; +constexpr unsigned int mmCRTC4_CRTC_DTMTEST_CNTL__VI = 0x4392; +constexpr unsigned int mmCRTC4_CRTC_DTMTEST_STATUS_POSITION__VI = 0x4393; +constexpr unsigned int mmCRTC4_CRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x43E1; +constexpr unsigned int mmCRTC4_CRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x43E5; +constexpr unsigned int mmCRTC4_CRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x43E4; +constexpr unsigned int mmCRTC4_CRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x43E6; +constexpr unsigned int mmCRTC4_CRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x43E3; +constexpr unsigned int mmCRTC4_CRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x43E2; +constexpr unsigned int mmCRTC4_CRTC_FIELD_INDICATION_CONTROL__VI = 0x43A0; +constexpr unsigned int mmCRTC4_CRTC_FLOW_CONTROL__VI = 0x4399; +constexpr unsigned int mmCRTC4_CRTC_FORCE_COUNT_NOW_CNTL__VI = 0x4398; +constexpr unsigned int mmCRTC4_CRTC_GSL_CONTROL__VI = 0x437B; +constexpr unsigned int mmCRTC4_CRTC_GSL_VSYNC_GAP__VI = 0x4379; +constexpr unsigned int mmCRTC4_CRTC_GSL_WINDOW__VI = 0x437A; +constexpr unsigned int mmCRTC4_CRTC_H_BLANK_EARLY_NUM__VI = 0x437D; +constexpr unsigned int mmCRTC4_CRTC_H_BLANK_START_END__VI = 0x4381; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_A__VI = 0x4382; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_A_CNTL__VI = 0x4383; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_B__VI = 0x4384; +constexpr unsigned int mmCRTC4_CRTC_H_SYNC_B_CNTL__VI = 0x4385; +constexpr unsigned int mmCRTC4_CRTC_H_TOTAL__VI = 0x4380; +constexpr unsigned int mmCRTC4_CRTC_INTERLACE_CONTROL__VI = 0x439E; +constexpr unsigned int mmCRTC4_CRTC_INTERLACE_STATUS__VI = 0x439F; +constexpr unsigned int mmCRTC4_CRTC_INTERRUPT_CONTROL__VI = 0x43B4; +constexpr unsigned int mmCRTC4_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__VI = 0x43AB; +constexpr unsigned int mmCRTC4_CRTC_MASTER_EN__VI = 0x43C2; +constexpr unsigned int mmCRTC4_CRTC_MVP_INBAND_CNTL_INSERT__VI = 0x43BF; +constexpr unsigned int mmCRTC4_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__VI = 0x43C0; +constexpr unsigned int mmCRTC4_CRTC_MVP_STATUS__VI = 0x43C1; +constexpr unsigned int mmCRTC4_CRTC_NOM_VERT_POSITION__VI = 0x43A5; +constexpr unsigned int mmCRTC4_CRTC_OVERSCAN_COLOR__VI = 0x43C8; +constexpr unsigned int mmCRTC4_CRTC_OVERSCAN_COLOR_EXT__VI = 0x43C9; +constexpr unsigned int mmCRTC4_CRTC_PIXEL_DATA_READBACK0__VI = 0x43A1; +constexpr unsigned int mmCRTC4_CRTC_PIXEL_DATA_READBACK1__VI = 0x43A2; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_CONTROL__VI = 0x43B0; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_FRAME__VI = 0x43B2; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_POSITION__VI = 0x43B1; +constexpr unsigned int mmCRTC4_CRTC_SNAPSHOT_STATUS__VI = 0x43AF; +constexpr unsigned int mmCRTC4_CRTC_START_LINE_CONTROL__VI = 0x43B3; +constexpr unsigned int mmCRTC4_CRTC_STATIC_SCREEN_CONTROL__VI = 0x43E7; +constexpr unsigned int mmCRTC4_CRTC_STATUS__SI__CI = 0x47A3; +constexpr unsigned int mmCRTC4_CRTC_STATUS__VI = 0x43A3; +constexpr unsigned int mmCRTC4_CRTC_STATUS_FRAME_COUNT__VI = 0x43A6; +constexpr unsigned int mmCRTC4_CRTC_STATUS_HV_COUNT__VI = 0x43A8; +constexpr unsigned int mmCRTC4_CRTC_STATUS_POSITION__SI__CI = 0x47A4; +constexpr unsigned int mmCRTC4_CRTC_STATUS_POSITION__VI = 0x43A4; +constexpr unsigned int mmCRTC4_CRTC_STATUS_VF_COUNT__VI = 0x43A7; +constexpr unsigned int mmCRTC4_CRTC_STEREO_CONTROL__VI = 0x43AE; +constexpr unsigned int mmCRTC4_CRTC_STEREO_FORCE_NEXT_EYE__VI = 0x439A; +constexpr unsigned int mmCRTC4_CRTC_STEREO_STATUS__VI = 0x43AD; +constexpr unsigned int mmCRTC4_CRTC_TEST_DEBUG_DATA__VI = 0x43C7; +constexpr unsigned int mmCRTC4_CRTC_TEST_DEBUG_INDEX__VI = 0x43C6; +constexpr unsigned int mmCRTC4_CRTC_TEST_PATTERN_COLOR__VI = 0x43BC; +constexpr unsigned int mmCRTC4_CRTC_TEST_PATTERN_CONTROL__VI = 0x43BA; +constexpr unsigned int mmCRTC4_CRTC_TEST_PATTERN_PARAMETERS__VI = 0x43BB; +constexpr unsigned int mmCRTC4_CRTC_TRIGA_CNTL__VI = 0x4394; +constexpr unsigned int mmCRTC4_CRTC_TRIGA_MANUAL_TRIG__VI = 0x4395; +constexpr unsigned int mmCRTC4_CRTC_TRIGB_CNTL__VI = 0x4396; +constexpr unsigned int mmCRTC4_CRTC_TRIGB_MANUAL_TRIG__VI = 0x4397; +constexpr unsigned int mmCRTC4_CRTC_UPDATE_LOCK__VI = 0x43B5; +constexpr unsigned int mmCRTC4_CRTC_VBI_END__VI = 0x4386; +constexpr unsigned int mmCRTC4_CRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x43CF; +constexpr unsigned int mmCRTC4_CRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x43CE; +constexpr unsigned int mmCRTC4_CRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x43D1; +constexpr unsigned int mmCRTC4_CRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x43D0; +constexpr unsigned int mmCRTC4_CRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x43D3; +constexpr unsigned int mmCRTC4_CRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x43D2; +constexpr unsigned int mmCRTC4_CRTC_VERT_SYNC_CONTROL__VI = 0x43AC; +constexpr unsigned int mmCRTC4_CRTC_VGA_PARAMETER_CAPTURE_MODE__VI = 0x43B7; +constexpr unsigned int mmCRTC4_CRTC_VSYNC_NOM_INT_STATUS__VI = 0x438C; +constexpr unsigned int mmCRTC4_CRTC_V_BLANK_START_END__VI = 0x438D; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_A__VI = 0x438E; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_A_CNTL__VI = 0x438F; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_B__VI = 0x4390; +constexpr unsigned int mmCRTC4_CRTC_V_SYNC_B_CNTL__VI = 0x4391; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL__VI = 0x4387; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_CONTROL__VI = 0x438A; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_INT_STATUS__VI = 0x438B; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_MAX__VI = 0x4389; +constexpr unsigned int mmCRTC4_CRTC_V_TOTAL_MIN__VI = 0x4388; +constexpr unsigned int mmCRTC4_CRTC_V_UPDATE_INT_STATUS__VI = 0x43C4; +constexpr unsigned int mmCRTC4_DCFE_DBG_SEL__VI = 0x437E; +constexpr unsigned int mmCRTC4_DCFE_MEM_PWR_CTRL__VI = 0x437F; +constexpr unsigned int mmCRTC4_DCFE_MEM_PWR_CTRL2__VI = 0x43B8; +constexpr unsigned int mmCRTC4_DCFE_MEM_PWR_STATUS__VI = 0x43B9; +constexpr unsigned int mmCRTC4_MASTER_UPDATE_LOCK__VI = 0x43BD; +constexpr unsigned int mmCRTC4_MASTER_UPDATE_MODE__SI__CI = 0x47BE; +constexpr unsigned int mmCRTC4_MASTER_UPDATE_MODE__VI = 0x43BE; +constexpr unsigned int mmCRTC4_PIXEL_RATE_CNTL__VI = 0x0150; +constexpr unsigned int mmCRTC5_CRTC_3D_STRUCTURE_CONTROL__VI = 0x4578; +constexpr unsigned int mmCRTC5_CRTC_ALLOW_STOP_OFF_V_CNT__VI = 0x45C3; +constexpr unsigned int mmCRTC5_CRTC_AVSYNC_COUNTER__VI = 0x459B; +constexpr unsigned int mmCRTC5_CRTC_BLACK_COLOR__VI = 0x45CC; +constexpr unsigned int mmCRTC5_CRTC_BLACK_COLOR_EXT__VI = 0x45CD; +constexpr unsigned int mmCRTC5_CRTC_BLANK_CONTROL__SI__CI = 0x4A9D; +constexpr unsigned int mmCRTC5_CRTC_BLANK_CONTROL__VI = 0x459D; +constexpr unsigned int mmCRTC5_CRTC_BLANK_DATA_COLOR__VI = 0x45CA; +constexpr unsigned int mmCRTC5_CRTC_BLANK_DATA_COLOR_EXT__VI = 0x45CB; +constexpr unsigned int mmCRTC5_CRTC_CONTROL__VI = 0x459C; +constexpr unsigned int mmCRTC5_CRTC_COUNT_CONTROL__VI = 0x45A9; +constexpr unsigned int mmCRTC5_CRTC_COUNT_RESET__VI = 0x45AA; +constexpr unsigned int mmCRTC5_CRTC_CRC0_DATA_B__VI = 0x45DA; +constexpr unsigned int mmCRTC5_CRTC_CRC0_DATA_RG__VI = 0x45D9; +constexpr unsigned int mmCRTC5_CRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x45D5; +constexpr unsigned int mmCRTC5_CRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x45D6; +constexpr unsigned int mmCRTC5_CRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x45D7; +constexpr unsigned int mmCRTC5_CRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x45D8; +constexpr unsigned int mmCRTC5_CRTC_CRC1_DATA_B__VI = 0x45E0; +constexpr unsigned int mmCRTC5_CRTC_CRC1_DATA_RG__VI = 0x45DF; +constexpr unsigned int mmCRTC5_CRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x45DB; +constexpr unsigned int mmCRTC5_CRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x45DC; +constexpr unsigned int mmCRTC5_CRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x45DD; +constexpr unsigned int mmCRTC5_CRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x45DE; +constexpr unsigned int mmCRTC5_CRTC_CRC_CNTL__VI = 0x45D4; +constexpr unsigned int mmCRTC5_CRTC_DCFE_CLOCK_CONTROL__VI = 0x457C; +constexpr unsigned int mmCRTC5_CRTC_DOUBLE_BUFFER_CONTROL__VI = 0x45B6; +constexpr unsigned int mmCRTC5_CRTC_DTMTEST_CNTL__VI = 0x4592; +constexpr unsigned int mmCRTC5_CRTC_DTMTEST_STATUS_POSITION__VI = 0x4593; +constexpr unsigned int mmCRTC5_CRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x45E1; +constexpr unsigned int mmCRTC5_CRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x45E5; +constexpr unsigned int mmCRTC5_CRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x45E4; +constexpr unsigned int mmCRTC5_CRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x45E6; +constexpr unsigned int mmCRTC5_CRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x45E3; +constexpr unsigned int mmCRTC5_CRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x45E2; +constexpr unsigned int mmCRTC5_CRTC_FIELD_INDICATION_CONTROL__VI = 0x45A0; +constexpr unsigned int mmCRTC5_CRTC_FLOW_CONTROL__VI = 0x4599; +constexpr unsigned int mmCRTC5_CRTC_FORCE_COUNT_NOW_CNTL__VI = 0x4598; +constexpr unsigned int mmCRTC5_CRTC_GSL_CONTROL__VI = 0x457B; +constexpr unsigned int mmCRTC5_CRTC_GSL_VSYNC_GAP__VI = 0x4579; +constexpr unsigned int mmCRTC5_CRTC_GSL_WINDOW__VI = 0x457A; +constexpr unsigned int mmCRTC5_CRTC_H_BLANK_EARLY_NUM__VI = 0x457D; +constexpr unsigned int mmCRTC5_CRTC_H_BLANK_START_END__VI = 0x4581; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_A__VI = 0x4582; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_A_CNTL__VI = 0x4583; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_B__VI = 0x4584; +constexpr unsigned int mmCRTC5_CRTC_H_SYNC_B_CNTL__VI = 0x4585; +constexpr unsigned int mmCRTC5_CRTC_H_TOTAL__VI = 0x4580; +constexpr unsigned int mmCRTC5_CRTC_INTERLACE_CONTROL__VI = 0x459E; +constexpr unsigned int mmCRTC5_CRTC_INTERLACE_STATUS__VI = 0x459F; +constexpr unsigned int mmCRTC5_CRTC_INTERRUPT_CONTROL__VI = 0x45B4; +constexpr unsigned int mmCRTC5_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__VI = 0x45AB; +constexpr unsigned int mmCRTC5_CRTC_MASTER_EN__VI = 0x45C2; +constexpr unsigned int mmCRTC5_CRTC_MVP_INBAND_CNTL_INSERT__VI = 0x45BF; +constexpr unsigned int mmCRTC5_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__VI = 0x45C0; +constexpr unsigned int mmCRTC5_CRTC_MVP_STATUS__VI = 0x45C1; +constexpr unsigned int mmCRTC5_CRTC_NOM_VERT_POSITION__VI = 0x45A5; +constexpr unsigned int mmCRTC5_CRTC_OVERSCAN_COLOR__VI = 0x45C8; +constexpr unsigned int mmCRTC5_CRTC_OVERSCAN_COLOR_EXT__VI = 0x45C9; +constexpr unsigned int mmCRTC5_CRTC_PIXEL_DATA_READBACK0__VI = 0x45A1; +constexpr unsigned int mmCRTC5_CRTC_PIXEL_DATA_READBACK1__VI = 0x45A2; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_CONTROL__VI = 0x45B0; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_FRAME__VI = 0x45B2; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_POSITION__VI = 0x45B1; +constexpr unsigned int mmCRTC5_CRTC_SNAPSHOT_STATUS__VI = 0x45AF; +constexpr unsigned int mmCRTC5_CRTC_START_LINE_CONTROL__VI = 0x45B3; +constexpr unsigned int mmCRTC5_CRTC_STATIC_SCREEN_CONTROL__VI = 0x45E7; +constexpr unsigned int mmCRTC5_CRTC_STATUS__SI__CI = 0x4AA3; +constexpr unsigned int mmCRTC5_CRTC_STATUS__VI = 0x45A3; +constexpr unsigned int mmCRTC5_CRTC_STATUS_FRAME_COUNT__VI = 0x45A6; +constexpr unsigned int mmCRTC5_CRTC_STATUS_HV_COUNT__VI = 0x45A8; +constexpr unsigned int mmCRTC5_CRTC_STATUS_POSITION__SI__CI = 0x4AA4; +constexpr unsigned int mmCRTC5_CRTC_STATUS_POSITION__VI = 0x45A4; +constexpr unsigned int mmCRTC5_CRTC_STATUS_VF_COUNT__VI = 0x45A7; +constexpr unsigned int mmCRTC5_CRTC_STEREO_CONTROL__VI = 0x45AE; +constexpr unsigned int mmCRTC5_CRTC_STEREO_FORCE_NEXT_EYE__VI = 0x459A; +constexpr unsigned int mmCRTC5_CRTC_STEREO_STATUS__VI = 0x45AD; +constexpr unsigned int mmCRTC5_CRTC_TEST_DEBUG_DATA__VI = 0x45C7; +constexpr unsigned int mmCRTC5_CRTC_TEST_DEBUG_INDEX__VI = 0x45C6; +constexpr unsigned int mmCRTC5_CRTC_TEST_PATTERN_COLOR__VI = 0x45BC; +constexpr unsigned int mmCRTC5_CRTC_TEST_PATTERN_CONTROL__VI = 0x45BA; +constexpr unsigned int mmCRTC5_CRTC_TEST_PATTERN_PARAMETERS__VI = 0x45BB; +constexpr unsigned int mmCRTC5_CRTC_TRIGA_CNTL__VI = 0x4594; +constexpr unsigned int mmCRTC5_CRTC_TRIGA_MANUAL_TRIG__VI = 0x4595; +constexpr unsigned int mmCRTC5_CRTC_TRIGB_CNTL__VI = 0x4596; +constexpr unsigned int mmCRTC5_CRTC_TRIGB_MANUAL_TRIG__VI = 0x4597; +constexpr unsigned int mmCRTC5_CRTC_UPDATE_LOCK__VI = 0x45B5; +constexpr unsigned int mmCRTC5_CRTC_VBI_END__VI = 0x4586; +constexpr unsigned int mmCRTC5_CRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x45CF; +constexpr unsigned int mmCRTC5_CRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x45CE; +constexpr unsigned int mmCRTC5_CRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x45D1; +constexpr unsigned int mmCRTC5_CRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x45D0; +constexpr unsigned int mmCRTC5_CRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x45D3; +constexpr unsigned int mmCRTC5_CRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x45D2; +constexpr unsigned int mmCRTC5_CRTC_VERT_SYNC_CONTROL__VI = 0x45AC; +constexpr unsigned int mmCRTC5_CRTC_VGA_PARAMETER_CAPTURE_MODE__VI = 0x45B7; +constexpr unsigned int mmCRTC5_CRTC_VSYNC_NOM_INT_STATUS__VI = 0x458C; +constexpr unsigned int mmCRTC5_CRTC_V_BLANK_START_END__VI = 0x458D; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_A__VI = 0x458E; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_A_CNTL__VI = 0x458F; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_B__VI = 0x4590; +constexpr unsigned int mmCRTC5_CRTC_V_SYNC_B_CNTL__VI = 0x4591; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL__VI = 0x4587; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_CONTROL__VI = 0x458A; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_INT_STATUS__VI = 0x458B; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_MAX__VI = 0x4589; +constexpr unsigned int mmCRTC5_CRTC_V_TOTAL_MIN__VI = 0x4588; +constexpr unsigned int mmCRTC5_CRTC_V_UPDATE_INT_STATUS__VI = 0x45C4; +constexpr unsigned int mmCRTC5_DCFE_DBG_SEL__VI = 0x457E; +constexpr unsigned int mmCRTC5_DCFE_MEM_PWR_CTRL__VI = 0x457F; +constexpr unsigned int mmCRTC5_DCFE_MEM_PWR_CTRL2__VI = 0x45B8; +constexpr unsigned int mmCRTC5_DCFE_MEM_PWR_STATUS__VI = 0x45B9; +constexpr unsigned int mmCRTC5_MASTER_UPDATE_LOCK__VI = 0x45BD; +constexpr unsigned int mmCRTC5_MASTER_UPDATE_MODE__SI__CI = 0x4ABE; +constexpr unsigned int mmCRTC5_MASTER_UPDATE_MODE__VI = 0x45BE; +constexpr unsigned int mmCRTC5_PIXEL_RATE_CNTL__VI = 0x0154; +constexpr unsigned int mmCRTC6_CRTC_3D_STRUCTURE_CONTROL__VI = 0x4778; +constexpr unsigned int mmCRTC6_CRTC_ALLOW_STOP_OFF_V_CNT__VI = 0x47C3; +constexpr unsigned int mmCRTC6_CRTC_AVSYNC_COUNTER__VI = 0x479B; +constexpr unsigned int mmCRTC6_CRTC_BLACK_COLOR__VI = 0x47CC; +constexpr unsigned int mmCRTC6_CRTC_BLACK_COLOR_EXT__VI = 0x47CD; +constexpr unsigned int mmCRTC6_CRTC_BLANK_CONTROL__VI = 0x479D; +constexpr unsigned int mmCRTC6_CRTC_BLANK_DATA_COLOR__VI = 0x47CA; +constexpr unsigned int mmCRTC6_CRTC_BLANK_DATA_COLOR_EXT__VI = 0x47CB; +constexpr unsigned int mmCRTC6_CRTC_CONTROL__VI = 0x479C; +constexpr unsigned int mmCRTC6_CRTC_COUNT_CONTROL__VI = 0x47A9; +constexpr unsigned int mmCRTC6_CRTC_COUNT_RESET__VI = 0x47AA; +constexpr unsigned int mmCRTC6_CRTC_CRC0_DATA_B__VI = 0x47DA; +constexpr unsigned int mmCRTC6_CRTC_CRC0_DATA_RG__VI = 0x47D9; +constexpr unsigned int mmCRTC6_CRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x47D5; +constexpr unsigned int mmCRTC6_CRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x47D6; +constexpr unsigned int mmCRTC6_CRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x47D7; +constexpr unsigned int mmCRTC6_CRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x47D8; +constexpr unsigned int mmCRTC6_CRTC_CRC1_DATA_B__VI = 0x47E0; +constexpr unsigned int mmCRTC6_CRTC_CRC1_DATA_RG__VI = 0x47DF; +constexpr unsigned int mmCRTC6_CRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x47DB; +constexpr unsigned int mmCRTC6_CRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x47DC; +constexpr unsigned int mmCRTC6_CRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x47DD; +constexpr unsigned int mmCRTC6_CRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x47DE; +constexpr unsigned int mmCRTC6_CRTC_CRC_CNTL__VI = 0x47D4; +constexpr unsigned int mmCRTC6_CRTC_DCFE_CLOCK_CONTROL__VI = 0x477C; +constexpr unsigned int mmCRTC6_CRTC_DOUBLE_BUFFER_CONTROL__VI = 0x47B6; +constexpr unsigned int mmCRTC6_CRTC_DTMTEST_CNTL__VI = 0x4792; +constexpr unsigned int mmCRTC6_CRTC_DTMTEST_STATUS_POSITION__VI = 0x4793; +constexpr unsigned int mmCRTC6_CRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x47E1; +constexpr unsigned int mmCRTC6_CRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x47E5; +constexpr unsigned int mmCRTC6_CRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x47E4; +constexpr unsigned int mmCRTC6_CRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x47E6; +constexpr unsigned int mmCRTC6_CRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x47E3; +constexpr unsigned int mmCRTC6_CRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x47E2; +constexpr unsigned int mmCRTC6_CRTC_FIELD_INDICATION_CONTROL__VI = 0x47A0; +constexpr unsigned int mmCRTC6_CRTC_FLOW_CONTROL__VI = 0x4799; +constexpr unsigned int mmCRTC6_CRTC_FORCE_COUNT_NOW_CNTL__VI = 0x4798; +constexpr unsigned int mmCRTC6_CRTC_GSL_CONTROL__VI = 0x477B; +constexpr unsigned int mmCRTC6_CRTC_GSL_VSYNC_GAP__VI = 0x4779; +constexpr unsigned int mmCRTC6_CRTC_GSL_WINDOW__VI = 0x477A; +constexpr unsigned int mmCRTC6_CRTC_H_BLANK_EARLY_NUM__VI = 0x477D; +constexpr unsigned int mmCRTC6_CRTC_H_BLANK_START_END__VI = 0x4781; +constexpr unsigned int mmCRTC6_CRTC_H_SYNC_A__VI = 0x4782; +constexpr unsigned int mmCRTC6_CRTC_H_SYNC_A_CNTL__VI = 0x4783; +constexpr unsigned int mmCRTC6_CRTC_H_SYNC_B__VI = 0x4784; +constexpr unsigned int mmCRTC6_CRTC_H_SYNC_B_CNTL__VI = 0x4785; +constexpr unsigned int mmCRTC6_CRTC_H_TOTAL__VI = 0x4780; +constexpr unsigned int mmCRTC6_CRTC_INTERLACE_CONTROL__VI = 0x479E; +constexpr unsigned int mmCRTC6_CRTC_INTERLACE_STATUS__VI = 0x479F; +constexpr unsigned int mmCRTC6_CRTC_INTERRUPT_CONTROL__VI = 0x47B4; +constexpr unsigned int mmCRTC6_CRTC_MANUAL_FORCE_VSYNC_NEXT_LINE__VI = 0x47AB; +constexpr unsigned int mmCRTC6_CRTC_MASTER_EN__VI = 0x47C2; +constexpr unsigned int mmCRTC6_CRTC_MVP_INBAND_CNTL_INSERT__VI = 0x47BF; +constexpr unsigned int mmCRTC6_CRTC_MVP_INBAND_CNTL_INSERT_TIMER__VI = 0x47C0; +constexpr unsigned int mmCRTC6_CRTC_MVP_STATUS__VI = 0x47C1; +constexpr unsigned int mmCRTC6_CRTC_NOM_VERT_POSITION__VI = 0x47A5; +constexpr unsigned int mmCRTC6_CRTC_OVERSCAN_COLOR__VI = 0x47C8; +constexpr unsigned int mmCRTC6_CRTC_OVERSCAN_COLOR_EXT__VI = 0x47C9; +constexpr unsigned int mmCRTC6_CRTC_PIXEL_DATA_READBACK0__VI = 0x47A1; +constexpr unsigned int mmCRTC6_CRTC_PIXEL_DATA_READBACK1__VI = 0x47A2; +constexpr unsigned int mmCRTC6_CRTC_SNAPSHOT_CONTROL__VI = 0x47B0; +constexpr unsigned int mmCRTC6_CRTC_SNAPSHOT_FRAME__VI = 0x47B2; +constexpr unsigned int mmCRTC6_CRTC_SNAPSHOT_POSITION__VI = 0x47B1; +constexpr unsigned int mmCRTC6_CRTC_SNAPSHOT_STATUS__VI = 0x47AF; +constexpr unsigned int mmCRTC6_CRTC_START_LINE_CONTROL__VI = 0x47B3; +constexpr unsigned int mmCRTC6_CRTC_STATIC_SCREEN_CONTROL__VI = 0x47E7; +constexpr unsigned int mmCRTC6_CRTC_STATUS__VI = 0x47A3; +constexpr unsigned int mmCRTC6_CRTC_STATUS_FRAME_COUNT__VI = 0x47A6; +constexpr unsigned int mmCRTC6_CRTC_STATUS_HV_COUNT__VI = 0x47A8; +constexpr unsigned int mmCRTC6_CRTC_STATUS_POSITION__VI = 0x47A4; +constexpr unsigned int mmCRTC6_CRTC_STATUS_VF_COUNT__VI = 0x47A7; +constexpr unsigned int mmCRTC6_CRTC_STEREO_CONTROL__VI = 0x47AE; +constexpr unsigned int mmCRTC6_CRTC_STEREO_FORCE_NEXT_EYE__VI = 0x479A; +constexpr unsigned int mmCRTC6_CRTC_STEREO_STATUS__VI = 0x47AD; +constexpr unsigned int mmCRTC6_CRTC_TEST_DEBUG_DATA__VI = 0x47C7; +constexpr unsigned int mmCRTC6_CRTC_TEST_DEBUG_INDEX__VI = 0x47C6; +constexpr unsigned int mmCRTC6_CRTC_TEST_PATTERN_COLOR__VI = 0x47BC; +constexpr unsigned int mmCRTC6_CRTC_TEST_PATTERN_CONTROL__VI = 0x47BA; +constexpr unsigned int mmCRTC6_CRTC_TEST_PATTERN_PARAMETERS__VI = 0x47BB; +constexpr unsigned int mmCRTC6_CRTC_TRIGA_CNTL__VI = 0x4794; +constexpr unsigned int mmCRTC6_CRTC_TRIGA_MANUAL_TRIG__VI = 0x4795; +constexpr unsigned int mmCRTC6_CRTC_TRIGB_CNTL__VI = 0x4796; +constexpr unsigned int mmCRTC6_CRTC_TRIGB_MANUAL_TRIG__VI = 0x4797; +constexpr unsigned int mmCRTC6_CRTC_UPDATE_LOCK__VI = 0x47B5; +constexpr unsigned int mmCRTC6_CRTC_VBI_END__VI = 0x4786; +constexpr unsigned int mmCRTC6_CRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x47CF; +constexpr unsigned int mmCRTC6_CRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x47CE; +constexpr unsigned int mmCRTC6_CRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x47D1; +constexpr unsigned int mmCRTC6_CRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x47D0; +constexpr unsigned int mmCRTC6_CRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x47D3; +constexpr unsigned int mmCRTC6_CRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x47D2; +constexpr unsigned int mmCRTC6_CRTC_VERT_SYNC_CONTROL__VI = 0x47AC; +constexpr unsigned int mmCRTC6_CRTC_VGA_PARAMETER_CAPTURE_MODE__VI = 0x47B7; +constexpr unsigned int mmCRTC6_CRTC_VSYNC_NOM_INT_STATUS__VI = 0x478C; +constexpr unsigned int mmCRTC6_CRTC_V_BLANK_START_END__VI = 0x478D; +constexpr unsigned int mmCRTC6_CRTC_V_SYNC_A__VI = 0x478E; +constexpr unsigned int mmCRTC6_CRTC_V_SYNC_A_CNTL__VI = 0x478F; +constexpr unsigned int mmCRTC6_CRTC_V_SYNC_B__VI = 0x4790; +constexpr unsigned int mmCRTC6_CRTC_V_SYNC_B_CNTL__VI = 0x4791; +constexpr unsigned int mmCRTC6_CRTC_V_TOTAL__VI = 0x4787; +constexpr unsigned int mmCRTC6_CRTC_V_TOTAL_CONTROL__VI = 0x478A; +constexpr unsigned int mmCRTC6_CRTC_V_TOTAL_INT_STATUS__VI = 0x478B; +constexpr unsigned int mmCRTC6_CRTC_V_TOTAL_MAX__VI = 0x4789; +constexpr unsigned int mmCRTC6_CRTC_V_TOTAL_MIN__VI = 0x4788; +constexpr unsigned int mmCRTC6_CRTC_V_UPDATE_INT_STATUS__VI = 0x47C4; +constexpr unsigned int mmCRTC6_DCFE_DBG_SEL__VI = 0x477E; +constexpr unsigned int mmCRTC6_DCFE_MEM_PWR_CTRL__VI = 0x477F; +constexpr unsigned int mmCRTC6_DCFE_MEM_PWR_CTRL2__VI = 0x47B8; +constexpr unsigned int mmCRTC6_DCFE_MEM_PWR_STATUS__VI = 0x47B9; +constexpr unsigned int mmCRTC6_MASTER_UPDATE_LOCK__VI = 0x47BD; +constexpr unsigned int mmCRTC6_MASTER_UPDATE_MODE__VI = 0x47BE; +constexpr unsigned int mmCRTC_3D_STRUCTURE_CONTROL__VI = 0x1B78; +constexpr unsigned int mmCRTC_AVSYNC_COUNTER__VI = 0x1B9B; +constexpr unsigned int mmCRTC_BLACK_COLOR__VI = 0x1BCC; +constexpr unsigned int mmCRTC_BLACK_COLOR_EXT__VI = 0x1BCD; +constexpr unsigned int mmCRTC_BLANK_DATA_COLOR__VI = 0x1BCA; +constexpr unsigned int mmCRTC_BLANK_DATA_COLOR_EXT__VI = 0x1BCB; +constexpr unsigned int mmCRTC_CRC0_DATA_B__VI = 0x1BDA; +constexpr unsigned int mmCRTC_CRC0_DATA_RG__VI = 0x1BD9; +constexpr unsigned int mmCRTC_CRC0_WINDOWA_X_CONTROL__VI = 0x1BD5; +constexpr unsigned int mmCRTC_CRC0_WINDOWA_Y_CONTROL__VI = 0x1BD6; +constexpr unsigned int mmCRTC_CRC0_WINDOWB_X_CONTROL__VI = 0x1BD7; +constexpr unsigned int mmCRTC_CRC0_WINDOWB_Y_CONTROL__VI = 0x1BD8; +constexpr unsigned int mmCRTC_CRC1_DATA_B__VI = 0x1BE0; +constexpr unsigned int mmCRTC_CRC1_DATA_RG__VI = 0x1BDF; +constexpr unsigned int mmCRTC_CRC1_WINDOWA_X_CONTROL__VI = 0x1BDB; +constexpr unsigned int mmCRTC_CRC1_WINDOWA_Y_CONTROL__VI = 0x1BDC; +constexpr unsigned int mmCRTC_CRC1_WINDOWB_X_CONTROL__VI = 0x1BDD; +constexpr unsigned int mmCRTC_CRC1_WINDOWB_Y_CONTROL__VI = 0x1BDE; +constexpr unsigned int mmCRTC_CRC_CNTL__VI = 0x1BD4; +constexpr unsigned int mmCRTC_DCFE_CLOCK_CONTROL__VI = 0x1B7C; +constexpr unsigned int mmCRTC_EXT_TIMING_SYNC_CONTROL__VI = 0x1BE1; +constexpr unsigned int mmCRTC_EXT_TIMING_SYNC_INTERRUPT_CONTROL__VI = 0x1BE5; +constexpr unsigned int mmCRTC_EXT_TIMING_SYNC_LOSS_INTERRUPT_CONTROL__VI = 0x1BE4; +constexpr unsigned int mmCRTC_EXT_TIMING_SYNC_SIGNAL_INTERRUPT_CONTROL__VI = 0x1BE6; +constexpr unsigned int mmCRTC_EXT_TIMING_SYNC_WINDOW_END__VI = 0x1BE3; +constexpr unsigned int mmCRTC_EXT_TIMING_SYNC_WINDOW_START__VI = 0x1BE2; +constexpr unsigned int mmCRTC_FIELD_INDICATION_CONTROL__VI = 0x1BA0; +constexpr unsigned int mmCRTC_GSL_CONTROL__VI = 0x1B7B; +constexpr unsigned int mmCRTC_GSL_VSYNC_GAP__VI = 0x1B79; +constexpr unsigned int mmCRTC_GSL_WINDOW__VI = 0x1B7A; +constexpr unsigned int mmCRTC_H_BLANK_EARLY_NUM__VI = 0x1B7D; +constexpr unsigned int mmCRTC_OVERSCAN_COLOR__VI = 0x1BC8; +constexpr unsigned int mmCRTC_OVERSCAN_COLOR_EXT__VI = 0x1BC9; +constexpr unsigned int mmCRTC_PIXEL_DATA_READBACK0__VI = 0x1BA1; +constexpr unsigned int mmCRTC_PIXEL_DATA_READBACK1__VI = 0x1BA2; +constexpr unsigned int mmCRTC_STATIC_SCREEN_CONTROL__VI = 0x1BE7; +constexpr unsigned int mmCRTC_STEREO_FORCE_NEXT_EYE__VI = 0x1B9A; +constexpr unsigned int mmCRTC_VERTICAL_INTERRUPT0_CONTROL__VI = 0x1BCF; +constexpr unsigned int mmCRTC_VERTICAL_INTERRUPT0_POSITION__VI = 0x1BCE; +constexpr unsigned int mmCRTC_VERTICAL_INTERRUPT1_CONTROL__VI = 0x1BD1; +constexpr unsigned int mmCRTC_VERTICAL_INTERRUPT1_POSITION__VI = 0x1BD0; +constexpr unsigned int mmCRTC_VERTICAL_INTERRUPT2_CONTROL__VI = 0x1BD3; +constexpr unsigned int mmCRTC_VERTICAL_INTERRUPT2_POSITION__VI = 0x1BD2; +constexpr unsigned int mmCUR2_COLOR1__VI = 0x1A75; +constexpr unsigned int mmCUR2_COLOR2__VI = 0x1A76; +constexpr unsigned int mmCUR2_CONTROL__VI = 0x1A6F; +constexpr unsigned int mmCUR2_HOT_SPOT__VI = 0x1A74; +constexpr unsigned int mmCUR2_POSITION__VI = 0x1A73; +constexpr unsigned int mmCUR2_SIZE__VI = 0x1A71; +constexpr unsigned int mmCUR2_STEREO_CONTROL__VI = 0x1A9B; +constexpr unsigned int mmCUR2_SURFACE_ADDRESS__VI = 0x1A70; +constexpr unsigned int mmCUR2_SURFACE_ADDRESS_HIGH__VI = 0x1A72; +constexpr unsigned int mmCUR2_UPDATE__VI = 0x1A77; +constexpr unsigned int mmCUR_REQUEST_FILTER_CNTL__VI = 0x1A99; +constexpr unsigned int mmCUR_STEREO_CONTROL__VI = 0x1A9A; +constexpr unsigned int mmDAC_AUTODETECT_CONTROL__VI = 0x16B4; +constexpr unsigned int mmDAC_AUTODETECT_CONTROL2__VI = 0x16B5; +constexpr unsigned int mmDAC_AUTODETECT_CONTROL3__VI = 0x16B6; +constexpr unsigned int mmDAC_AUTODETECT_INT_CONTROL__VI = 0x16B8; +constexpr unsigned int mmDAC_AUTODETECT_STATUS__VI = 0x16B7; +constexpr unsigned int mmDAC_CLK_ENABLE__VI = 0x0128; +constexpr unsigned int mmDAC_COMPARATOR_ENABLE__VI = 0x16BD; +constexpr unsigned int mmDAC_COMPARATOR_OUTPUT__VI = 0x16BE; +constexpr unsigned int mmDAC_CONTROL__VI = 0x16BC; +constexpr unsigned int mmDAC_CRC_CONTROL__VI = 0x16AD; +constexpr unsigned int mmDAC_CRC_EN__VI = 0x16AC; +constexpr unsigned int mmDAC_CRC_SIG_CONTROL__VI = 0x16B1; +constexpr unsigned int mmDAC_CRC_SIG_CONTROL_MASK__VI = 0x16AF; +constexpr unsigned int mmDAC_CRC_SIG_RGB__VI = 0x16B0; +constexpr unsigned int mmDAC_CRC_SIG_RGB_MASK__VI = 0x16AE; +constexpr unsigned int mmDAC_DFT_CONFIG__VI = 0x16C0; +constexpr unsigned int mmDAC_ENABLE__VI = 0x16AA; +constexpr unsigned int mmDAC_FIFO_STATUS__VI = 0x16C1; +constexpr unsigned int mmDAC_FORCE_DATA__VI = 0x16BA; +constexpr unsigned int mmDAC_FORCE_OUTPUT_CNTL__VI = 0x16B9; +constexpr unsigned int mmDAC_MACRO_CNTL_RESERVED0__VI = 0x48B8; +constexpr unsigned int mmDAC_MACRO_CNTL_RESERVED1__VI = 0x48B9; +constexpr unsigned int mmDAC_MACRO_CNTL_RESERVED2__VI = 0x48BA; +constexpr unsigned int mmDAC_MACRO_CNTL_RESERVED3__VI = 0x48BB; +constexpr unsigned int mmDAC_POWERDOWN__VI = 0x16BB; +constexpr unsigned int mmDAC_PWR_CNTL__VI = 0x16BF; +constexpr unsigned int mmDAC_SOURCE_SELECT__VI = 0x16AB; +constexpr unsigned int mmDAC_STEREOSYNC_SELECT__VI = 0x16B3; +constexpr unsigned int mmDAC_SYNC_TRISTATE_CONTROL__VI = 0x16B2; +constexpr unsigned int mmDAC_TEST_DEBUG_DATA__VI = 0x16C3; +constexpr unsigned int mmDAC_TEST_DEBUG_INDEX__VI = 0x16C2; +constexpr unsigned int mmDBG_OUT_CNTL__VI = 0x4834; +constexpr unsigned int mmDBG_SMB_BYPASS_SRBM_ACCESS__VI = 0x14EB; +constexpr unsigned int mmDCCG_AUDIO_DTO0_MODULE__VI = 0x016D; +constexpr unsigned int mmDCCG_AUDIO_DTO0_PHASE__VI = 0x016C; +constexpr unsigned int mmDCCG_AUDIO_DTO1_MODULE__VI = 0x016F; +constexpr unsigned int mmDCCG_AUDIO_DTO1_PHASE__VI = 0x016E; +constexpr unsigned int mmDCCG_AUDIO_DTO_SOURCE__VI = 0x016B; +constexpr unsigned int mmDCCG_CAC_STATUS__VI = 0x0137; +constexpr unsigned int mmDCCG_CBUS_WRCMD_DELAY__VI = 0x0110; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED0__VI = 0x5FD0; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED1__VI = 0x5FD1; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED10__VI = 0x5FDA; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED11__VI = 0x5FDB; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED2__VI = 0x5FD2; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED3__VI = 0x5FD3; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED4__VI = 0x5FD4; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED5__VI = 0x5FD5; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED6__VI = 0x5FD6; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED7__VI = 0x5FD7; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED8__VI = 0x5FD8; +constexpr unsigned int mmDCCG_CPLL0_CPLL_MACRO_CNTL_RESERVED9__VI = 0x5FD9; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED0__VI = 0x5FDC; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED1__VI = 0x5FDD; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED10__VI = 0x5FE6; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED11__VI = 0x5FE7; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED2__VI = 0x5FDE; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED3__VI = 0x5FDF; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED4__VI = 0x5FE0; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED5__VI = 0x5FE1; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED6__VI = 0x5FE2; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED7__VI = 0x5FE3; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED8__VI = 0x5FE4; +constexpr unsigned int mmDCCG_CPLL1_CPLL_MACRO_CNTL_RESERVED9__VI = 0x5FE5; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED0__VI = 0x5FE8; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED1__VI = 0x5FE9; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED10__VI = 0x5FF2; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED11__VI = 0x5FF3; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED2__VI = 0x5FEA; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED3__VI = 0x5FEB; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED4__VI = 0x5FEC; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED5__VI = 0x5FED; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED6__VI = 0x5FEE; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED7__VI = 0x5FEF; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED8__VI = 0x5FF0; +constexpr unsigned int mmDCCG_CPLL2_CPLL_MACRO_CNTL_RESERVED9__VI = 0x5FF1; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED0__VI = 0x5FF4; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED1__VI = 0x5FF5; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED10__VI = 0x5FFE; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED11__VI = 0x5FFF; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED2__VI = 0x5FF6; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED3__VI = 0x5FF7; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED4__VI = 0x5FF8; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED5__VI = 0x5FF9; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED6__VI = 0x5FFA; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED7__VI = 0x5FFB; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED8__VI = 0x5FFC; +constexpr unsigned int mmDCCG_CPLL3_CPLL_MACRO_CNTL_RESERVED9__VI = 0x5FFD; +constexpr unsigned int mmDCCG_DISP_CNTL_REG__VI = 0x013F; +constexpr unsigned int mmDCCG_DS_CNTL__VI = 0x0115; +constexpr unsigned int mmDCCG_DS_DEBUG_CNTL__VI = 0x0112; +constexpr unsigned int mmDCCG_DS_DTO_INCR__VI = 0x0113; +constexpr unsigned int mmDCCG_DS_DTO_MODULO__VI = 0x0114; +constexpr unsigned int mmDCCG_DS_HW_CAL_INTERVAL__VI = 0x0116; +constexpr unsigned int mmDCCG_GATE_DISABLE_CNTL__VI = 0x0134; +constexpr unsigned int mmDCCG_GTC_CNTL__VI = 0x0120; +constexpr unsigned int mmDCCG_GTC_CURRENT__VI = 0x0123; +constexpr unsigned int mmDCCG_GTC_DTO_INCR__VI = 0x0121; +constexpr unsigned int mmDCCG_GTC_DTO_MODULO__VI = 0x0122; +constexpr unsigned int mmDCCG_PERFMON_CNTL__VI = 0x0133; +constexpr unsigned int mmDCCG_PERFMON_CNTL2__VI = 0x010E; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED0__VI = 0x1700; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED1__VI = 0x1701; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED10__VI = 0x170A; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED11__VI = 0x170B; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED12__VI = 0x170C; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED13__VI = 0x170D; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED14__VI = 0x170E; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED15__VI = 0x170F; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED16__VI = 0x1710; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED17__VI = 0x1711; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED18__VI = 0x1712; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED19__VI = 0x1713; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED2__VI = 0x1702; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED20__VI = 0x1714; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED21__VI = 0x1715; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED22__VI = 0x1716; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED23__VI = 0x1717; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED24__VI = 0x1718; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED25__VI = 0x1719; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED26__VI = 0x171A; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED27__VI = 0x171B; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED28__VI = 0x171C; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED29__VI = 0x171D; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED3__VI = 0x1703; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED30__VI = 0x171E; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED31__VI = 0x171F; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED32__VI = 0x1720; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED33__VI = 0x1721; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED34__VI = 0x1722; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED35__VI = 0x1723; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED36__VI = 0x1724; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED37__VI = 0x1725; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED38__VI = 0x1726; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED39__VI = 0x1727; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED4__VI = 0x1704; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED40__VI = 0x1728; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED41__VI = 0x1729; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED5__VI = 0x1705; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED6__VI = 0x1706; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED7__VI = 0x1707; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED8__VI = 0x1708; +constexpr unsigned int mmDCCG_PLL0_PLL_MACRO_CNTL_RESERVED9__VI = 0x1709; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED0__VI = 0x172A; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED1__VI = 0x172B; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED10__VI = 0x1734; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED11__VI = 0x1735; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED12__VI = 0x1736; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED13__VI = 0x1737; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED14__VI = 0x1738; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED15__VI = 0x1739; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED16__VI = 0x173A; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED17__VI = 0x173B; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED18__VI = 0x173C; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED19__VI = 0x173D; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED2__VI = 0x172C; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED20__VI = 0x173E; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED21__VI = 0x173F; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED22__VI = 0x1740; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED23__VI = 0x1741; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED24__VI = 0x1742; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED25__VI = 0x1743; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED26__VI = 0x1744; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED27__VI = 0x1745; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED28__VI = 0x1746; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED29__VI = 0x1747; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED3__VI = 0x172D; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED30__VI = 0x1748; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED31__VI = 0x1749; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED32__VI = 0x174A; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED33__VI = 0x174B; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED34__VI = 0x174C; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED35__VI = 0x174D; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED36__VI = 0x174E; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED37__VI = 0x174F; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED38__VI = 0x1750; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED39__VI = 0x1751; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED4__VI = 0x172E; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED40__VI = 0x1752; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED41__VI = 0x1753; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED5__VI = 0x172F; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED6__VI = 0x1730; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED7__VI = 0x1731; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED8__VI = 0x1732; +constexpr unsigned int mmDCCG_PLL1_PLL_MACRO_CNTL_RESERVED9__VI = 0x1733; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED0__VI = 0x1754; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED1__VI = 0x1755; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED10__VI = 0x175E; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED11__VI = 0x175F; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED12__VI = 0x1760; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED13__VI = 0x1761; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED14__VI = 0x1762; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED15__VI = 0x1763; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED16__VI = 0x1764; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED17__VI = 0x1765; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED18__VI = 0x1766; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED19__VI = 0x1767; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED2__VI = 0x1756; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED20__VI = 0x1768; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED21__VI = 0x1769; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED22__VI = 0x176A; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED23__VI = 0x176B; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED24__VI = 0x176C; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED25__VI = 0x176D; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED26__VI = 0x176E; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED27__VI = 0x176F; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED28__VI = 0x1770; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED29__VI = 0x1771; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED3__VI = 0x1757; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED30__VI = 0x1772; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED31__VI = 0x1773; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED32__VI = 0x1774; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED33__VI = 0x1775; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED34__VI = 0x1776; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED35__VI = 0x1777; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED36__VI = 0x1778; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED37__VI = 0x1779; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED38__VI = 0x177A; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED39__VI = 0x177B; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED4__VI = 0x1758; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED40__VI = 0x177C; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED41__VI = 0x177D; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED5__VI = 0x1759; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED6__VI = 0x175A; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED7__VI = 0x175B; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED8__VI = 0x175C; +constexpr unsigned int mmDCCG_PLL2_PLL_MACRO_CNTL_RESERVED9__VI = 0x175D; +constexpr unsigned int mmDCCG_SOFT_RESET__VI = 0x015F; +constexpr unsigned int mmDCCG_TEST_CLK_SEL__VI = 0x017E; +constexpr unsigned int mmDCCG_TEST_DEBUG_DATA__VI = 0x017D; +constexpr unsigned int mmDCCG_TEST_DEBUG_INDEX__VI = 0x017C; +constexpr unsigned int mmDCDEBUG_BUS_CLK1_SEL__VI = 0x16C4; +constexpr unsigned int mmDCDEBUG_BUS_CLK2_SEL__VI = 0x16C5; +constexpr unsigned int mmDCDEBUG_BUS_CLK3_SEL__VI = 0x16C6; +constexpr unsigned int mmDCDEBUG_BUS_CLK4_SEL__VI = 0x16C7; +constexpr unsigned int mmDCDEBUG_BUS_CLK5_SEL__VI = 0x16C8; +constexpr unsigned int mmDCDEBUG_OUT_CNTL__VI = 0x16CA; +constexpr unsigned int mmDCDEBUG_OUT_DATA__VI = 0x16CB; +constexpr unsigned int mmDCDEBUG_OUT_PIN_OVERRIDE__VI = 0x16C9; +constexpr unsigned int mmDCE_VCE_CONTROL__VI = 0x1856; +constexpr unsigned int mmDCFE0_DCFE_CLOCK_CONTROL__VI = 0x1B00; +constexpr unsigned int mmDCFE0_DCFE_DBG_CONFIG__VI = 0x1B02; +constexpr unsigned int mmDCFE0_DCFE_SOFT_RESET__VI = 0x1B01; +constexpr unsigned int mmDCFE1_DCFE_CLOCK_CONTROL__VI = 0x1D00; +constexpr unsigned int mmDCFE1_DCFE_DBG_CONFIG__VI = 0x1D02; +constexpr unsigned int mmDCFE1_DCFE_SOFT_RESET__VI = 0x1D01; +constexpr unsigned int mmDCFE2_DCFE_CLOCK_CONTROL__VI = 0x1F00; +constexpr unsigned int mmDCFE2_DCFE_DBG_CONFIG__VI = 0x1F02; +constexpr unsigned int mmDCFE2_DCFE_SOFT_RESET__VI = 0x1F01; +constexpr unsigned int mmDCFE3_DCFE_CLOCK_CONTROL__VI = 0x4100; +constexpr unsigned int mmDCFE3_DCFE_DBG_CONFIG__VI = 0x4102; +constexpr unsigned int mmDCFE3_DCFE_SOFT_RESET__VI = 0x4101; +constexpr unsigned int mmDCFE4_DCFE_CLOCK_CONTROL__VI = 0x4300; +constexpr unsigned int mmDCFE4_DCFE_DBG_CONFIG__VI = 0x4302; +constexpr unsigned int mmDCFE4_DCFE_SOFT_RESET__VI = 0x4301; +constexpr unsigned int mmDCFE5_DCFE_CLOCK_CONTROL__VI = 0x4500; +constexpr unsigned int mmDCFE5_DCFE_DBG_CONFIG__VI = 0x4502; +constexpr unsigned int mmDCFE5_DCFE_SOFT_RESET__VI = 0x4501; +constexpr unsigned int mmDCFEV0_CRTC_PIXEL_RATE_CNTL__VI = 0x0104; +constexpr unsigned int mmDCFEV0_PG_CONFIG__VI = 0x02DB; +constexpr unsigned int mmDCFEV0_PG_ENABLE__VI = 0x02DC; +constexpr unsigned int mmDCFEV0_PG_STATUS__VI = 0x02DD; +constexpr unsigned int mmDCFEV_CLOCK_CONTROL__VI = 0x46F4; +constexpr unsigned int mmDCFEV_DBG_CONFIG__VI = 0x46F7; +constexpr unsigned int mmDCFEV_DMIFV_CLOCK_CONTROL__VI = 0x46F6; +constexpr unsigned int mmDCFEV_DMIFV_MEM_PWR_CTRL__VI = 0x46F8; +constexpr unsigned int mmDCFEV_DMIFV_MEM_PWR_STATUS__VI = 0x46F9; +constexpr unsigned int mmDCFEV_SOFT_RESET__VI = 0x46F5; +constexpr unsigned int mmDCFE_CLOCK_CONTROL__VI = 0x1B00; +constexpr unsigned int mmDCFE_DBG_CONFIG__VI = 0x1B02; +constexpr unsigned int mmDCFE_DBG_SEL__VI = 0x1B7E; +constexpr unsigned int mmDCFE_MEM_PWR_CTRL__VI = 0x1B7F; +constexpr unsigned int mmDCFE_MEM_PWR_CTRL2__VI = 0x1BB8; +constexpr unsigned int mmDCFE_MEM_PWR_STATUS__VI = 0x1BB9; +constexpr unsigned int mmDCFE_SOFT_RESET__VI = 0x1B01; +constexpr unsigned int mmDCIO_CLOCK_CNTL__VI = 0x482D; +constexpr unsigned int mmDCIO_DEBUG__VI = 0x482F; +constexpr unsigned int mmDCIO_DEBUG_CONFIG__VI = 0x4835; +constexpr unsigned int mmDCIO_DPHY_SEL__VI = 0x4837; +constexpr unsigned int mmDCIO_GSL0_CNTL__VI = 0x4826; +constexpr unsigned int mmDCIO_GSL1_CNTL__VI = 0x4827; +constexpr unsigned int mmDCIO_GSL2_CNTL__VI = 0x4828; +constexpr unsigned int mmDCIO_GSL_GENLK_PAD_CNTL__VI = 0x4824; +constexpr unsigned int mmDCIO_GSL_SWAPLOCK_PAD_CNTL__VI = 0x4825; +constexpr unsigned int mmDCIO_IMPCAL_CNTL__VI = 0x483D; +constexpr unsigned int mmDCIO_IMPCAL_CNTL_CD__VI = 0x4841; +constexpr unsigned int mmDCIO_IMPCAL_CNTL_EF__VI = 0x4845; +constexpr unsigned int mmDCIO_SOFT_RESET__VI = 0x4836; +constexpr unsigned int mmDCIO_TEST_DEBUG_DATA__VI = 0x4832; +constexpr unsigned int mmDCIO_TEST_DEBUG_INDEX__VI = 0x4831; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED0__VI = 0x48C0; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED1__VI = 0x48C1; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED10__VI = 0x48CA; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED11__VI = 0x48CB; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED12__VI = 0x48CC; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED13__VI = 0x48CD; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED14__VI = 0x48CE; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED15__VI = 0x48CF; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED16__VI = 0x48D0; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED17__VI = 0x48D1; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED18__VI = 0x48D2; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED19__VI = 0x48D3; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED2__VI = 0x48C2; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED20__VI = 0x48D4; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED21__VI = 0x48D5; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED22__VI = 0x48D6; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED23__VI = 0x48D7; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED24__VI = 0x48D8; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED25__VI = 0x48D9; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED26__VI = 0x48DA; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED27__VI = 0x48DB; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED28__VI = 0x48DC; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED29__VI = 0x48DD; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED3__VI = 0x48C3; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED30__VI = 0x48DE; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED31__VI = 0x48DF; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED4__VI = 0x48C4; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED5__VI = 0x48C5; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED6__VI = 0x48C6; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED7__VI = 0x48C7; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED8__VI = 0x48C8; +constexpr unsigned int mmDCIO_UNIPHY0_UNIPHY_MACRO_CNTL_RESERVED9__VI = 0x48C9; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED0__VI = 0x48E0; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED1__VI = 0x48E1; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED10__VI = 0x48EA; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED11__VI = 0x48EB; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED12__VI = 0x48EC; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED13__VI = 0x48ED; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED14__VI = 0x48EE; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED15__VI = 0x48EF; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED16__VI = 0x48F0; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED17__VI = 0x48F1; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED18__VI = 0x48F2; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED19__VI = 0x48F3; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED2__VI = 0x48E2; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED20__VI = 0x48F4; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED21__VI = 0x48F5; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED22__VI = 0x48F6; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED23__VI = 0x48F7; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED24__VI = 0x48F8; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED25__VI = 0x48F9; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED26__VI = 0x48FA; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED27__VI = 0x48FB; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED28__VI = 0x48FC; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED29__VI = 0x48FD; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED3__VI = 0x48E3; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED30__VI = 0x48FE; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED31__VI = 0x48FF; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED4__VI = 0x48E4; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED5__VI = 0x48E5; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED6__VI = 0x48E6; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED7__VI = 0x48E7; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED8__VI = 0x48E8; +constexpr unsigned int mmDCIO_UNIPHY1_UNIPHY_MACRO_CNTL_RESERVED9__VI = 0x48E9; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED0__VI = 0x4900; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED1__VI = 0x4901; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED10__VI = 0x490A; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED11__VI = 0x490B; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED12__VI = 0x490C; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED13__VI = 0x490D; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED14__VI = 0x490E; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED15__VI = 0x490F; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED16__VI = 0x4910; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED17__VI = 0x4911; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED18__VI = 0x4912; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED19__VI = 0x4913; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED2__VI = 0x4902; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED20__VI = 0x4914; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED21__VI = 0x4915; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED22__VI = 0x4916; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED23__VI = 0x4917; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED24__VI = 0x4918; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED25__VI = 0x4919; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED26__VI = 0x491A; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED27__VI = 0x491B; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED28__VI = 0x491C; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED29__VI = 0x491D; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED3__VI = 0x4903; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED30__VI = 0x491E; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED31__VI = 0x491F; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED4__VI = 0x4904; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED5__VI = 0x4905; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED6__VI = 0x4906; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED7__VI = 0x4907; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED8__VI = 0x4908; +constexpr unsigned int mmDCIO_UNIPHY2_UNIPHY_MACRO_CNTL_RESERVED9__VI = 0x4909; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED0__VI = 0x4920; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED1__VI = 0x4921; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED10__VI = 0x492A; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED11__VI = 0x492B; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED12__VI = 0x492C; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED13__VI = 0x492D; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED14__VI = 0x492E; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED15__VI = 0x492F; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED16__VI = 0x4930; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED17__VI = 0x4931; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED18__VI = 0x4932; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED19__VI = 0x4933; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED2__VI = 0x4922; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED20__VI = 0x4934; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED21__VI = 0x4935; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED22__VI = 0x4936; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED23__VI = 0x4937; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED24__VI = 0x4938; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED25__VI = 0x4939; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED26__VI = 0x493A; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED27__VI = 0x493B; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED28__VI = 0x493C; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED29__VI = 0x493D; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED3__VI = 0x4923; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED30__VI = 0x493E; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED31__VI = 0x493F; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED4__VI = 0x4924; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED5__VI = 0x4925; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED6__VI = 0x4926; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED7__VI = 0x4927; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED8__VI = 0x4928; +constexpr unsigned int mmDCIO_UNIPHY3_UNIPHY_MACRO_CNTL_RESERVED9__VI = 0x4929; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED0__VI = 0x4940; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED1__VI = 0x4941; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED10__VI = 0x494A; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED11__VI = 0x494B; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED12__VI = 0x494C; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED13__VI = 0x494D; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED14__VI = 0x494E; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED15__VI = 0x494F; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED16__VI = 0x4950; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED17__VI = 0x4951; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED18__VI = 0x4952; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED19__VI = 0x4953; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED2__VI = 0x4942; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED20__VI = 0x4954; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED21__VI = 0x4955; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED22__VI = 0x4956; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED23__VI = 0x4957; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED24__VI = 0x4958; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED25__VI = 0x4959; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED26__VI = 0x495A; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED27__VI = 0x495B; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED28__VI = 0x495C; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED29__VI = 0x495D; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED3__VI = 0x4943; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED30__VI = 0x495E; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED31__VI = 0x495F; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED4__VI = 0x4944; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED5__VI = 0x4945; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED6__VI = 0x4946; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED7__VI = 0x4947; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED8__VI = 0x4948; +constexpr unsigned int mmDCIO_UNIPHY4_UNIPHY_MACRO_CNTL_RESERVED9__VI = 0x4949; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED0__VI = 0x4960; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED1__VI = 0x4961; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED10__VI = 0x496A; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED11__VI = 0x496B; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED12__VI = 0x496C; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED13__VI = 0x496D; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED14__VI = 0x496E; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED15__VI = 0x496F; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED16__VI = 0x4970; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED17__VI = 0x4971; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED18__VI = 0x4972; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED19__VI = 0x4973; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED2__VI = 0x4962; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED20__VI = 0x4974; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED21__VI = 0x4975; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED22__VI = 0x4976; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED23__VI = 0x4977; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED24__VI = 0x4978; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED25__VI = 0x4979; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED26__VI = 0x497A; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED27__VI = 0x497B; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED28__VI = 0x497C; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED29__VI = 0x497D; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED3__VI = 0x4963; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED30__VI = 0x497E; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED31__VI = 0x497F; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED4__VI = 0x4964; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED5__VI = 0x4965; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED6__VI = 0x4966; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED7__VI = 0x4967; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED8__VI = 0x4968; +constexpr unsigned int mmDCIO_UNIPHY5_UNIPHY_MACRO_CNTL_RESERVED9__VI = 0x4969; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED0__VI = 0x4980; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED1__VI = 0x4981; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED10__VI = 0x498A; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED11__VI = 0x498B; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED12__VI = 0x498C; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED13__VI = 0x498D; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED14__VI = 0x498E; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED15__VI = 0x498F; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED16__VI = 0x4990; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED17__VI = 0x4991; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED18__VI = 0x4992; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED19__VI = 0x4993; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED2__VI = 0x4982; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED20__VI = 0x4994; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED21__VI = 0x4995; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED22__VI = 0x4996; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED23__VI = 0x4997; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED24__VI = 0x4998; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED25__VI = 0x4999; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED26__VI = 0x499A; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED27__VI = 0x499B; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED28__VI = 0x499C; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED29__VI = 0x499D; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED3__VI = 0x4983; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED30__VI = 0x499E; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED31__VI = 0x499F; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED4__VI = 0x4984; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED5__VI = 0x4985; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED6__VI = 0x4986; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED7__VI = 0x4987; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED8__VI = 0x4988; +constexpr unsigned int mmDCIO_UNIPHY6_UNIPHY_MACRO_CNTL_RESERVED9__VI = 0x4989; +constexpr unsigned int mmDCIO_WRCMD_DELAY__VI = 0x4816; +constexpr unsigned int mmDCI_CLK_CNTL__VI = 0x0319; +constexpr unsigned int mmDCI_CLK_RAMP_CNTL__VI = 0x031A; +constexpr unsigned int mmDCI_DEBUG_CONFIG__VI = 0x0320; +constexpr unsigned int mmDCI_MEM_PWR_CNTL__VI = 0x031B; +constexpr unsigned int mmDCI_MEM_PWR_CNTL2__VI = 0x031C; +constexpr unsigned int mmDCI_MEM_PWR_CNTL3__VI = 0x031D; +constexpr unsigned int mmDCI_MEM_PWR_STATUS__VI = 0x0317; +constexpr unsigned int mmDCI_MEM_PWR_STATUS2__VI = 0x0318; +constexpr unsigned int mmDCI_PG_DEBUG_CONFIG__VI = 0x1812; +constexpr unsigned int mmDCI_SOFT_RESET__VI = 0x0328; +constexpr unsigned int mmDCI_TEST_DEBUG_DATA__VI = 0x031F; +constexpr unsigned int mmDCI_TEST_DEBUG_INDEX__VI = 0x031E; +constexpr unsigned int mmDCO_CLK_CNTL__VI = 0x1864; +constexpr unsigned int mmDCO_CLK_RAMP_CNTL__VI = 0x1865; +constexpr unsigned int mmDCO_DCFE_EXT_VSYNC_CNTL__VI = 0x4830; +constexpr unsigned int mmDCO_MEM_PWR_CTRL__VI = 0x1862; +constexpr unsigned int mmDCO_MEM_PWR_CTRL2__VI = 0x1863; +constexpr unsigned int mmDCO_MEM_PWR_STATUS__VI = 0x1861; +constexpr unsigned int mmDCO_POWER_MANAGEMENT_CNTL__VI = 0x1868; +constexpr unsigned int mmDCO_SCRATCH0__VI = 0x184E; +constexpr unsigned int mmDCO_SCRATCH1__VI = 0x184F; +constexpr unsigned int mmDCO_SCRATCH2__VI = 0x1850; +constexpr unsigned int mmDCO_SCRATCH3__VI = 0x1851; +constexpr unsigned int mmDCO_SCRATCH4__VI = 0x1852; +constexpr unsigned int mmDCO_SCRATCH5__VI = 0x1853; +constexpr unsigned int mmDCO_SCRATCH6__VI = 0x1854; +constexpr unsigned int mmDCO_SCRATCH7__VI = 0x1855; +constexpr unsigned int mmDCO_SOFT_RESET__VI = 0x1871; +constexpr unsigned int mmDCO_STEREOSYNC_SEL__VI = 0x186E; +constexpr unsigned int mmDCO_TEST_DEBUG_DATA__VI = 0x1870; +constexpr unsigned int mmDCO_TEST_DEBUG_INDEX__VI = 0x186F; +constexpr unsigned int mmDCP0_ALPHA_CONTROL__VI = 0x1ABC; +constexpr unsigned int mmDCP0_COMM_MATRIXA_TRANS_C11_C12__VI = 0x1A43; +constexpr unsigned int mmDCP0_COMM_MATRIXA_TRANS_C13_C14__VI = 0x1A44; +constexpr unsigned int mmDCP0_COMM_MATRIXA_TRANS_C21_C22__VI = 0x1A45; +constexpr unsigned int mmDCP0_COMM_MATRIXA_TRANS_C23_C24__VI = 0x1A46; +constexpr unsigned int mmDCP0_COMM_MATRIXA_TRANS_C31_C32__VI = 0x1A47; +constexpr unsigned int mmDCP0_COMM_MATRIXA_TRANS_C33_C34__VI = 0x1A48; +constexpr unsigned int mmDCP0_COMM_MATRIXB_TRANS_C11_C12__VI = 0x1A49; +constexpr unsigned int mmDCP0_COMM_MATRIXB_TRANS_C13_C14__VI = 0x1A4A; +constexpr unsigned int mmDCP0_COMM_MATRIXB_TRANS_C21_C22__VI = 0x1A4B; +constexpr unsigned int mmDCP0_COMM_MATRIXB_TRANS_C23_C24__VI = 0x1A4C; +constexpr unsigned int mmDCP0_COMM_MATRIXB_TRANS_C31_C32__VI = 0x1A4D; +constexpr unsigned int mmDCP0_COMM_MATRIXB_TRANS_C33_C34__VI = 0x1A4E; +constexpr unsigned int mmDCP0_CUR2_COLOR1__VI = 0x1A75; +constexpr unsigned int mmDCP0_CUR2_COLOR2__VI = 0x1A76; +constexpr unsigned int mmDCP0_CUR2_CONTROL__VI = 0x1A6F; +constexpr unsigned int mmDCP0_CUR2_HOT_SPOT__VI = 0x1A74; +constexpr unsigned int mmDCP0_CUR2_POSITION__VI = 0x1A73; +constexpr unsigned int mmDCP0_CUR2_SIZE__VI = 0x1A71; +constexpr unsigned int mmDCP0_CUR2_STEREO_CONTROL__VI = 0x1A9B; +constexpr unsigned int mmDCP0_CUR2_SURFACE_ADDRESS__VI = 0x1A70; +constexpr unsigned int mmDCP0_CUR2_SURFACE_ADDRESS_HIGH__VI = 0x1A72; +constexpr unsigned int mmDCP0_CUR2_UPDATE__VI = 0x1A77; +constexpr unsigned int mmDCP0_CUR_REQUEST_FILTER_CNTL__VI = 0x1A99; +constexpr unsigned int mmDCP0_CUR_STEREO_CONTROL__VI = 0x1A9A; +constexpr unsigned int mmDCP0_DCP_DEBUG2__VI = 0x1A98; +constexpr unsigned int mmDCP0_DCP_FP_CONVERTED_FIELD__VI = 0x1A65; +constexpr unsigned int mmDCP0_DCP_GSL_CONTROL__VI = 0x1A90; +constexpr unsigned int mmDCP0_DCP_RANDOM_SEEDS__VI = 0x1A61; +constexpr unsigned int mmDCP0_DCP_SPATIAL_DITHER_CNTL__VI = 0x1A60; +constexpr unsigned int mmDCP0_DC_LUT_VGA_ACCESS_ENABLE__VI = 0x1A7D; +constexpr unsigned int mmDCP0_DEGAMMA_CONTROL__VI = 0x1A58; +constexpr unsigned int mmDCP0_DENORM_CONTROL__VI = 0x1A50; +constexpr unsigned int mmDCP0_GAMUT_REMAP_C11_C12__VI = 0x1A5A; +constexpr unsigned int mmDCP0_GAMUT_REMAP_C13_C14__VI = 0x1A5B; +constexpr unsigned int mmDCP0_GAMUT_REMAP_C21_C22__VI = 0x1A5C; +constexpr unsigned int mmDCP0_GAMUT_REMAP_C23_C24__VI = 0x1A5D; +constexpr unsigned int mmDCP0_GAMUT_REMAP_C31_C32__VI = 0x1A5E; +constexpr unsigned int mmDCP0_GAMUT_REMAP_C33_C34__VI = 0x1A5F; +constexpr unsigned int mmDCP0_GAMUT_REMAP_CONTROL__VI = 0x1A59; +constexpr unsigned int mmDCP0_GRPH_FLIP_RATE_CNTL__VI = 0x1A8E; +constexpr unsigned int mmDCP0_GRPH_STEREOSYNC_FLIP__VI = 0x1A97; +constexpr unsigned int mmDCP0_GRPH_XDMA_CACHE_UNDERFLOW_DET_CNTL__VI = 0x1A9F; +constexpr unsigned int mmDCP0_GRPH_XDMA_CACHE_UNDERFLOW_DET_STATUS__VI = 0x1ABF; +constexpr unsigned int mmDCP0_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS__VI = 0x1ABD; +constexpr unsigned int mmDCP0_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS_HIGH__VI = 0x1ABE; +constexpr unsigned int mmDCP0_HW_ROTATION__VI = 0x1A9E; +constexpr unsigned int mmDCP0_INPUT_CSC_C11_C12__VI = 0x1A36; +constexpr unsigned int mmDCP0_INPUT_CSC_C13_C14__VI = 0x1A37; +constexpr unsigned int mmDCP0_INPUT_CSC_C21_C22__VI = 0x1A38; +constexpr unsigned int mmDCP0_INPUT_CSC_C23_C24__VI = 0x1A39; +constexpr unsigned int mmDCP0_INPUT_CSC_C31_C32__VI = 0x1A3A; +constexpr unsigned int mmDCP0_INPUT_CSC_C33_C34__VI = 0x1A3B; +constexpr unsigned int mmDCP0_INPUT_CSC_CONTROL__VI = 0x1A35; +constexpr unsigned int mmDCP0_INPUT_GAMMA_CONTROL__VI = 0x1A10; +constexpr unsigned int mmDCP0_KEY_CONTROL__VI = 0x1A53; +constexpr unsigned int mmDCP0_KEY_RANGE_ALPHA__VI = 0x1A54; +constexpr unsigned int mmDCP0_KEY_RANGE_BLUE__VI = 0x1A57; +constexpr unsigned int mmDCP0_KEY_RANGE_GREEN__VI = 0x1A56; +constexpr unsigned int mmDCP0_KEY_RANGE_RED__VI = 0x1A55; +constexpr unsigned int mmDCP0_OUTPUT_CSC_C11_C12__VI = 0x1A3D; +constexpr unsigned int mmDCP0_OUTPUT_CSC_C13_C14__VI = 0x1A3E; +constexpr unsigned int mmDCP0_OUTPUT_CSC_C21_C22__VI = 0x1A3F; +constexpr unsigned int mmDCP0_OUTPUT_CSC_C23_C24__VI = 0x1A40; +constexpr unsigned int mmDCP0_OUTPUT_CSC_C31_C32__VI = 0x1A41; +constexpr unsigned int mmDCP0_OUTPUT_CSC_C33_C34__VI = 0x1A42; +constexpr unsigned int mmDCP0_OUTPUT_CSC_CONTROL__VI = 0x1A3C; +constexpr unsigned int mmDCP0_OUT_CLAMP_CONTROL_B_CB__VI = 0x1A9D; +constexpr unsigned int mmDCP0_OUT_CLAMP_CONTROL_G_Y__VI = 0x1A9C; +constexpr unsigned int mmDCP0_OUT_CLAMP_CONTROL_R_CR__VI = 0x1A52; +constexpr unsigned int mmDCP0_OUT_ROUND_CONTROL__VI = 0x1A51; +constexpr unsigned int mmDCP0_OVL_SECONDARY_SURFACE_ADDRESS__VI = 0x1A92; +constexpr unsigned int mmDCP0_OVL_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x1A94; +constexpr unsigned int mmDCP0_OVL_STEREOSYNC_FLIP__VI = 0x1A93; +constexpr unsigned int mmDCP0_PRESCALE_GRPH_CONTROL__VI = 0x1A2D; +constexpr unsigned int mmDCP0_PRESCALE_OVL_CONTROL__VI = 0x1A31; +constexpr unsigned int mmDCP0_PRESCALE_VALUES_GRPH_B__VI = 0x1A30; +constexpr unsigned int mmDCP0_PRESCALE_VALUES_GRPH_G__VI = 0x1A2F; +constexpr unsigned int mmDCP0_PRESCALE_VALUES_GRPH_R__VI = 0x1A2E; +constexpr unsigned int mmDCP0_PRESCALE_VALUES_OVL_CB__VI = 0x1A32; +constexpr unsigned int mmDCP0_PRESCALE_VALUES_OVL_CR__VI = 0x1A34; +constexpr unsigned int mmDCP0_PRESCALE_VALUES_OVL_Y__VI = 0x1A33; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_END_CNTL1__VI = 0x1AA6; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_END_CNTL2__VI = 0x1AA7; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_0_1__VI = 0x1AA8; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_10_11__VI = 0x1AAD; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_12_13__VI = 0x1AAE; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_14_15__VI = 0x1AAF; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_2_3__VI = 0x1AA9; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_4_5__VI = 0x1AAA; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_6_7__VI = 0x1AAB; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_REGION_8_9__VI = 0x1AAC; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_SLOPE_CNTL__VI = 0x1AA5; +constexpr unsigned int mmDCP0_REGAMMA_CNTLA_START_CNTL__VI = 0x1AA4; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_END_CNTL1__VI = 0x1AB2; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_END_CNTL2__VI = 0x1AB3; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_0_1__VI = 0x1AB4; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_10_11__VI = 0x1AB9; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_12_13__VI = 0x1ABA; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_14_15__VI = 0x1ABB; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_2_3__VI = 0x1AB5; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_4_5__VI = 0x1AB6; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_6_7__VI = 0x1AB7; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_REGION_8_9__VI = 0x1AB8; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_SLOPE_CNTL__VI = 0x1AB1; +constexpr unsigned int mmDCP0_REGAMMA_CNTLB_START_CNTL__VI = 0x1AB0; +constexpr unsigned int mmDCP0_REGAMMA_CONTROL__VI = 0x1AA0; +constexpr unsigned int mmDCP0_REGAMMA_LUT_DATA__VI = 0x1AA2; +constexpr unsigned int mmDCP0_REGAMMA_LUT_INDEX__VI = 0x1AA1; +constexpr unsigned int mmDCP0_REGAMMA_LUT_WRITE_EN_MASK__VI = 0x1AA3; +constexpr unsigned int mmDCP1_ALPHA_CONTROL__VI = 0x1CBC; +constexpr unsigned int mmDCP1_COMM_MATRIXA_TRANS_C11_C12__VI = 0x1C43; +constexpr unsigned int mmDCP1_COMM_MATRIXA_TRANS_C13_C14__VI = 0x1C44; +constexpr unsigned int mmDCP1_COMM_MATRIXA_TRANS_C21_C22__VI = 0x1C45; +constexpr unsigned int mmDCP1_COMM_MATRIXA_TRANS_C23_C24__VI = 0x1C46; +constexpr unsigned int mmDCP1_COMM_MATRIXA_TRANS_C31_C32__VI = 0x1C47; +constexpr unsigned int mmDCP1_COMM_MATRIXA_TRANS_C33_C34__VI = 0x1C48; +constexpr unsigned int mmDCP1_COMM_MATRIXB_TRANS_C11_C12__VI = 0x1C49; +constexpr unsigned int mmDCP1_COMM_MATRIXB_TRANS_C13_C14__VI = 0x1C4A; +constexpr unsigned int mmDCP1_COMM_MATRIXB_TRANS_C21_C22__VI = 0x1C4B; +constexpr unsigned int mmDCP1_COMM_MATRIXB_TRANS_C23_C24__VI = 0x1C4C; +constexpr unsigned int mmDCP1_COMM_MATRIXB_TRANS_C31_C32__VI = 0x1C4D; +constexpr unsigned int mmDCP1_COMM_MATRIXB_TRANS_C33_C34__VI = 0x1C4E; +constexpr unsigned int mmDCP1_CUR2_COLOR1__VI = 0x1C75; +constexpr unsigned int mmDCP1_CUR2_COLOR2__VI = 0x1C76; +constexpr unsigned int mmDCP1_CUR2_CONTROL__VI = 0x1C6F; +constexpr unsigned int mmDCP1_CUR2_HOT_SPOT__VI = 0x1C74; +constexpr unsigned int mmDCP1_CUR2_POSITION__VI = 0x1C73; +constexpr unsigned int mmDCP1_CUR2_SIZE__VI = 0x1C71; +constexpr unsigned int mmDCP1_CUR2_STEREO_CONTROL__VI = 0x1C9B; +constexpr unsigned int mmDCP1_CUR2_SURFACE_ADDRESS__VI = 0x1C70; +constexpr unsigned int mmDCP1_CUR2_SURFACE_ADDRESS_HIGH__VI = 0x1C72; +constexpr unsigned int mmDCP1_CUR2_UPDATE__VI = 0x1C77; +constexpr unsigned int mmDCP1_CUR_COLOR1__VI = 0x1C6C; +constexpr unsigned int mmDCP1_CUR_COLOR2__VI = 0x1C6D; +constexpr unsigned int mmDCP1_CUR_CONTROL__VI = 0x1C66; +constexpr unsigned int mmDCP1_CUR_HOT_SPOT__VI = 0x1C6B; +constexpr unsigned int mmDCP1_CUR_POSITION__VI = 0x1C6A; +constexpr unsigned int mmDCP1_CUR_REQUEST_FILTER_CNTL__VI = 0x1C99; +constexpr unsigned int mmDCP1_CUR_SIZE__VI = 0x1C68; +constexpr unsigned int mmDCP1_CUR_STEREO_CONTROL__VI = 0x1C9A; +constexpr unsigned int mmDCP1_CUR_SURFACE_ADDRESS__VI = 0x1C67; +constexpr unsigned int mmDCP1_CUR_SURFACE_ADDRESS_HIGH__VI = 0x1C69; +constexpr unsigned int mmDCP1_CUR_UPDATE__VI = 0x1C6E; +constexpr unsigned int mmDCP1_DCP_CRC_CONTROL__VI = 0x1C87; +constexpr unsigned int mmDCP1_DCP_CRC_CURRENT__VI = 0x1C89; +constexpr unsigned int mmDCP1_DCP_CRC_LAST__VI = 0x1C8B; +constexpr unsigned int mmDCP1_DCP_CRC_MASK__VI = 0x1C88; +constexpr unsigned int mmDCP1_DCP_DEBUG__VI = 0x1C8D; +constexpr unsigned int mmDCP1_DCP_DEBUG2__VI = 0x1C98; +constexpr unsigned int mmDCP1_DCP_FP_CONVERTED_FIELD__VI = 0x1C65; +constexpr unsigned int mmDCP1_DCP_GSL_CONTROL__VI = 0x1C90; +constexpr unsigned int mmDCP1_DCP_LB_DATA_GAP_BETWEEN_CHUNK__VI = 0x1C91; +constexpr unsigned int mmDCP1_DCP_RANDOM_SEEDS__VI = 0x1C61; +constexpr unsigned int mmDCP1_DCP_SPATIAL_DITHER_CNTL__VI = 0x1C60; +constexpr unsigned int mmDCP1_DCP_TEST_DEBUG_DATA__VI = 0x1C96; +constexpr unsigned int mmDCP1_DCP_TEST_DEBUG_INDEX__VI = 0x1C95; +constexpr unsigned int mmDCP1_DC_LUT_30_COLOR__VI = 0x1C7C; +constexpr unsigned int mmDCP1_DC_LUT_AUTOFILL__VI = 0x1C7F; +constexpr unsigned int mmDCP1_DC_LUT_BLACK_OFFSET_BLUE__VI = 0x1C81; +constexpr unsigned int mmDCP1_DC_LUT_BLACK_OFFSET_GREEN__VI = 0x1C82; +constexpr unsigned int mmDCP1_DC_LUT_BLACK_OFFSET_RED__VI = 0x1C83; +constexpr unsigned int mmDCP1_DC_LUT_CONTROL__VI = 0x1C80; +constexpr unsigned int mmDCP1_DC_LUT_PWL_DATA__VI = 0x1C7B; +constexpr unsigned int mmDCP1_DC_LUT_RW_INDEX__VI = 0x1C79; +constexpr unsigned int mmDCP1_DC_LUT_RW_MODE__VI = 0x1C78; +constexpr unsigned int mmDCP1_DC_LUT_SEQ_COLOR__VI = 0x1C7A; +constexpr unsigned int mmDCP1_DC_LUT_VGA_ACCESS_ENABLE__VI = 0x1C7D; +constexpr unsigned int mmDCP1_DC_LUT_WHITE_OFFSET_BLUE__VI = 0x1C84; +constexpr unsigned int mmDCP1_DC_LUT_WHITE_OFFSET_GREEN__VI = 0x1C85; +constexpr unsigned int mmDCP1_DC_LUT_WHITE_OFFSET_RED__VI = 0x1C86; +constexpr unsigned int mmDCP1_DC_LUT_WRITE_EN_MASK__VI = 0x1C7E; +constexpr unsigned int mmDCP1_DEGAMMA_CONTROL__VI = 0x1C58; +constexpr unsigned int mmDCP1_DENORM_CONTROL__VI = 0x1C50; +constexpr unsigned int mmDCP1_GAMUT_REMAP_C11_C12__VI = 0x1C5A; +constexpr unsigned int mmDCP1_GAMUT_REMAP_C13_C14__VI = 0x1C5B; +constexpr unsigned int mmDCP1_GAMUT_REMAP_C21_C22__VI = 0x1C5C; +constexpr unsigned int mmDCP1_GAMUT_REMAP_C23_C24__VI = 0x1C5D; +constexpr unsigned int mmDCP1_GAMUT_REMAP_C31_C32__VI = 0x1C5E; +constexpr unsigned int mmDCP1_GAMUT_REMAP_C33_C34__VI = 0x1C5F; +constexpr unsigned int mmDCP1_GAMUT_REMAP_CONTROL__VI = 0x1C59; +constexpr unsigned int mmDCP1_GRPH_COMPRESS_PITCH__VI = 0x1C1A; +constexpr unsigned int mmDCP1_GRPH_COMPRESS_SURFACE_ADDRESS__VI = 0x1C19; +constexpr unsigned int mmDCP1_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__VI = 0x1C1B; +constexpr unsigned int mmDCP1_GRPH_CONTROL__SI__CI = 0x1D01; +constexpr unsigned int mmDCP1_GRPH_CONTROL__VI = 0x1C01; +constexpr unsigned int mmDCP1_GRPH_DFQ_CONTROL__VI = 0x1C14; +constexpr unsigned int mmDCP1_GRPH_DFQ_STATUS__VI = 0x1C15; +constexpr unsigned int mmDCP1_GRPH_ENABLE__VI = 0x1C00; +constexpr unsigned int mmDCP1_GRPH_FLIP_CONTROL__SI__CI = 0x1D12; +constexpr unsigned int mmDCP1_GRPH_FLIP_CONTROL__VI = 0x1C12; +constexpr unsigned int mmDCP1_GRPH_FLIP_RATE_CNTL__VI = 0x1C8E; +constexpr unsigned int mmDCP1_GRPH_INTERRUPT_CONTROL__VI = 0x1C17; +constexpr unsigned int mmDCP1_GRPH_INTERRUPT_STATUS__VI = 0x1C16; +constexpr unsigned int mmDCP1_GRPH_LUT_10BIT_BYPASS__VI = 0x1C02; +constexpr unsigned int mmDCP1_GRPH_PITCH__SI__CI = 0x1D06; +constexpr unsigned int mmDCP1_GRPH_PITCH__VI = 0x1C06; +constexpr unsigned int mmDCP1_GRPH_PRIMARY_SURFACE_ADDRESS__SI__CI = 0x1D04; +constexpr unsigned int mmDCP1_GRPH_PRIMARY_SURFACE_ADDRESS__VI = 0x1C04; +constexpr unsigned int mmDCP1_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__VI = 0x1C07; +constexpr unsigned int mmDCP1_GRPH_SECONDARY_SURFACE_ADDRESS__VI = 0x1C05; +constexpr unsigned int mmDCP1_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x1C08; +constexpr unsigned int mmDCP1_GRPH_STEREOSYNC_FLIP__VI = 0x1C97; +constexpr unsigned int mmDCP1_GRPH_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x1C18; +constexpr unsigned int mmDCP1_GRPH_SURFACE_ADDRESS_INUSE__VI = 0x1C13; +constexpr unsigned int mmDCP1_GRPH_SURFACE_OFFSET_X__VI = 0x1C09; +constexpr unsigned int mmDCP1_GRPH_SURFACE_OFFSET_Y__VI = 0x1C0A; +constexpr unsigned int mmDCP1_GRPH_SWAP_CNTL__VI = 0x1C03; +constexpr unsigned int mmDCP1_GRPH_UPDATE__SI__CI = 0x1D11; +constexpr unsigned int mmDCP1_GRPH_UPDATE__VI = 0x1C11; +constexpr unsigned int mmDCP1_GRPH_XDMA_CACHE_UNDERFLOW_DET_CNTL__VI = 0x1C9F; +constexpr unsigned int mmDCP1_GRPH_XDMA_CACHE_UNDERFLOW_DET_STATUS__VI = 0x1CBF; +constexpr unsigned int mmDCP1_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS__VI = 0x1CBD; +constexpr unsigned int mmDCP1_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS_HIGH__VI = 0x1CBE; +constexpr unsigned int mmDCP1_GRPH_X_END__VI = 0x1C0D; +constexpr unsigned int mmDCP1_GRPH_X_START__VI = 0x1C0B; +constexpr unsigned int mmDCP1_GRPH_Y_END__VI = 0x1C0E; +constexpr unsigned int mmDCP1_GRPH_Y_START__VI = 0x1C0C; +constexpr unsigned int mmDCP1_HW_ROTATION__VI = 0x1C9E; +constexpr unsigned int mmDCP1_INPUT_CSC_C11_C12__VI = 0x1C36; +constexpr unsigned int mmDCP1_INPUT_CSC_C13_C14__VI = 0x1C37; +constexpr unsigned int mmDCP1_INPUT_CSC_C21_C22__VI = 0x1C38; +constexpr unsigned int mmDCP1_INPUT_CSC_C23_C24__VI = 0x1C39; +constexpr unsigned int mmDCP1_INPUT_CSC_C31_C32__VI = 0x1C3A; +constexpr unsigned int mmDCP1_INPUT_CSC_C33_C34__VI = 0x1C3B; +constexpr unsigned int mmDCP1_INPUT_CSC_CONTROL__VI = 0x1C35; +constexpr unsigned int mmDCP1_INPUT_GAMMA_CONTROL__VI = 0x1C10; +constexpr unsigned int mmDCP1_KEY_CONTROL__VI = 0x1C53; +constexpr unsigned int mmDCP1_KEY_RANGE_ALPHA__VI = 0x1C54; +constexpr unsigned int mmDCP1_KEY_RANGE_BLUE__VI = 0x1C57; +constexpr unsigned int mmDCP1_KEY_RANGE_GREEN__VI = 0x1C56; +constexpr unsigned int mmDCP1_KEY_RANGE_RED__VI = 0x1C55; +constexpr unsigned int mmDCP1_OUTPUT_CSC_C11_C12__VI = 0x1C3D; +constexpr unsigned int mmDCP1_OUTPUT_CSC_C13_C14__VI = 0x1C3E; +constexpr unsigned int mmDCP1_OUTPUT_CSC_C21_C22__VI = 0x1C3F; +constexpr unsigned int mmDCP1_OUTPUT_CSC_C23_C24__VI = 0x1C40; +constexpr unsigned int mmDCP1_OUTPUT_CSC_C31_C32__VI = 0x1C41; +constexpr unsigned int mmDCP1_OUTPUT_CSC_C33_C34__VI = 0x1C42; +constexpr unsigned int mmDCP1_OUTPUT_CSC_CONTROL__VI = 0x1C3C; +constexpr unsigned int mmDCP1_OUT_CLAMP_CONTROL_B_CB__VI = 0x1C9D; +constexpr unsigned int mmDCP1_OUT_CLAMP_CONTROL_G_Y__VI = 0x1C9C; +constexpr unsigned int mmDCP1_OUT_CLAMP_CONTROL_R_CR__VI = 0x1C52; +constexpr unsigned int mmDCP1_OUT_ROUND_CONTROL__VI = 0x1C51; +constexpr unsigned int mmDCP1_OVLSCL_EDGE_PIXEL_CNTL__VI = 0x1C2C; +constexpr unsigned int mmDCP1_OVL_CONTROL1__VI = 0x1C1D; +constexpr unsigned int mmDCP1_OVL_CONTROL2__VI = 0x1C1E; +constexpr unsigned int mmDCP1_OVL_DFQ_CONTROL__VI = 0x1C29; +constexpr unsigned int mmDCP1_OVL_DFQ_STATUS__VI = 0x1C2A; +constexpr unsigned int mmDCP1_OVL_ENABLE__VI = 0x1C1C; +constexpr unsigned int mmDCP1_OVL_END__VI = 0x1C26; +constexpr unsigned int mmDCP1_OVL_PITCH__VI = 0x1C21; +constexpr unsigned int mmDCP1_OVL_SECONDARY_SURFACE_ADDRESS__VI = 0x1C92; +constexpr unsigned int mmDCP1_OVL_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x1C94; +constexpr unsigned int mmDCP1_OVL_START__VI = 0x1C25; +constexpr unsigned int mmDCP1_OVL_STEREOSYNC_FLIP__VI = 0x1C93; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS__SI__CI = 0x1D20; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS__VI = 0x1C20; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS_HIGH__VI = 0x1C22; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x1C2B; +constexpr unsigned int mmDCP1_OVL_SURFACE_ADDRESS_INUSE__VI = 0x1C28; +constexpr unsigned int mmDCP1_OVL_SURFACE_OFFSET_X__VI = 0x1C23; +constexpr unsigned int mmDCP1_OVL_SURFACE_OFFSET_Y__VI = 0x1C24; +constexpr unsigned int mmDCP1_OVL_SWAP_CNTL__VI = 0x1C1F; +constexpr unsigned int mmDCP1_OVL_UPDATE__VI = 0x1C27; +constexpr unsigned int mmDCP1_PRESCALE_GRPH_CONTROL__VI = 0x1C2D; +constexpr unsigned int mmDCP1_PRESCALE_OVL_CONTROL__VI = 0x1C31; +constexpr unsigned int mmDCP1_PRESCALE_VALUES_GRPH_B__VI = 0x1C30; +constexpr unsigned int mmDCP1_PRESCALE_VALUES_GRPH_G__VI = 0x1C2F; +constexpr unsigned int mmDCP1_PRESCALE_VALUES_GRPH_R__VI = 0x1C2E; +constexpr unsigned int mmDCP1_PRESCALE_VALUES_OVL_CB__VI = 0x1C32; +constexpr unsigned int mmDCP1_PRESCALE_VALUES_OVL_CR__VI = 0x1C34; +constexpr unsigned int mmDCP1_PRESCALE_VALUES_OVL_Y__VI = 0x1C33; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_END_CNTL1__VI = 0x1CA6; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_END_CNTL2__VI = 0x1CA7; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_0_1__VI = 0x1CA8; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_10_11__VI = 0x1CAD; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_12_13__VI = 0x1CAE; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_14_15__VI = 0x1CAF; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_2_3__VI = 0x1CA9; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_4_5__VI = 0x1CAA; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_6_7__VI = 0x1CAB; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_REGION_8_9__VI = 0x1CAC; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_SLOPE_CNTL__VI = 0x1CA5; +constexpr unsigned int mmDCP1_REGAMMA_CNTLA_START_CNTL__VI = 0x1CA4; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_END_CNTL1__VI = 0x1CB2; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_END_CNTL2__VI = 0x1CB3; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_0_1__VI = 0x1CB4; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_10_11__VI = 0x1CB9; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_12_13__VI = 0x1CBA; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_14_15__VI = 0x1CBB; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_2_3__VI = 0x1CB5; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_4_5__VI = 0x1CB6; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_6_7__VI = 0x1CB7; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_REGION_8_9__VI = 0x1CB8; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_SLOPE_CNTL__VI = 0x1CB1; +constexpr unsigned int mmDCP1_REGAMMA_CNTLB_START_CNTL__VI = 0x1CB0; +constexpr unsigned int mmDCP1_REGAMMA_CONTROL__VI = 0x1CA0; +constexpr unsigned int mmDCP1_REGAMMA_LUT_DATA__VI = 0x1CA2; +constexpr unsigned int mmDCP1_REGAMMA_LUT_INDEX__VI = 0x1CA1; +constexpr unsigned int mmDCP1_REGAMMA_LUT_WRITE_EN_MASK__VI = 0x1CA3; +constexpr unsigned int mmDCP2_ALPHA_CONTROL__VI = 0x1EBC; +constexpr unsigned int mmDCP2_COMM_MATRIXA_TRANS_C11_C12__VI = 0x1E43; +constexpr unsigned int mmDCP2_COMM_MATRIXA_TRANS_C13_C14__VI = 0x1E44; +constexpr unsigned int mmDCP2_COMM_MATRIXA_TRANS_C21_C22__VI = 0x1E45; +constexpr unsigned int mmDCP2_COMM_MATRIXA_TRANS_C23_C24__VI = 0x1E46; +constexpr unsigned int mmDCP2_COMM_MATRIXA_TRANS_C31_C32__VI = 0x1E47; +constexpr unsigned int mmDCP2_COMM_MATRIXA_TRANS_C33_C34__VI = 0x1E48; +constexpr unsigned int mmDCP2_COMM_MATRIXB_TRANS_C11_C12__VI = 0x1E49; +constexpr unsigned int mmDCP2_COMM_MATRIXB_TRANS_C13_C14__VI = 0x1E4A; +constexpr unsigned int mmDCP2_COMM_MATRIXB_TRANS_C21_C22__VI = 0x1E4B; +constexpr unsigned int mmDCP2_COMM_MATRIXB_TRANS_C23_C24__VI = 0x1E4C; +constexpr unsigned int mmDCP2_COMM_MATRIXB_TRANS_C31_C32__VI = 0x1E4D; +constexpr unsigned int mmDCP2_COMM_MATRIXB_TRANS_C33_C34__VI = 0x1E4E; +constexpr unsigned int mmDCP2_CUR2_COLOR1__VI = 0x1E75; +constexpr unsigned int mmDCP2_CUR2_COLOR2__VI = 0x1E76; +constexpr unsigned int mmDCP2_CUR2_CONTROL__VI = 0x1E6F; +constexpr unsigned int mmDCP2_CUR2_HOT_SPOT__VI = 0x1E74; +constexpr unsigned int mmDCP2_CUR2_POSITION__VI = 0x1E73; +constexpr unsigned int mmDCP2_CUR2_SIZE__VI = 0x1E71; +constexpr unsigned int mmDCP2_CUR2_STEREO_CONTROL__VI = 0x1E9B; +constexpr unsigned int mmDCP2_CUR2_SURFACE_ADDRESS__VI = 0x1E70; +constexpr unsigned int mmDCP2_CUR2_SURFACE_ADDRESS_HIGH__VI = 0x1E72; +constexpr unsigned int mmDCP2_CUR2_UPDATE__VI = 0x1E77; +constexpr unsigned int mmDCP2_CUR_COLOR1__VI = 0x1E6C; +constexpr unsigned int mmDCP2_CUR_COLOR2__VI = 0x1E6D; +constexpr unsigned int mmDCP2_CUR_CONTROL__VI = 0x1E66; +constexpr unsigned int mmDCP2_CUR_HOT_SPOT__VI = 0x1E6B; +constexpr unsigned int mmDCP2_CUR_POSITION__VI = 0x1E6A; +constexpr unsigned int mmDCP2_CUR_REQUEST_FILTER_CNTL__VI = 0x1E99; +constexpr unsigned int mmDCP2_CUR_SIZE__VI = 0x1E68; +constexpr unsigned int mmDCP2_CUR_STEREO_CONTROL__VI = 0x1E9A; +constexpr unsigned int mmDCP2_CUR_SURFACE_ADDRESS__VI = 0x1E67; +constexpr unsigned int mmDCP2_CUR_SURFACE_ADDRESS_HIGH__VI = 0x1E69; +constexpr unsigned int mmDCP2_CUR_UPDATE__VI = 0x1E6E; +constexpr unsigned int mmDCP2_DCP_CRC_CONTROL__VI = 0x1E87; +constexpr unsigned int mmDCP2_DCP_CRC_CURRENT__VI = 0x1E89; +constexpr unsigned int mmDCP2_DCP_CRC_LAST__VI = 0x1E8B; +constexpr unsigned int mmDCP2_DCP_CRC_MASK__VI = 0x1E88; +constexpr unsigned int mmDCP2_DCP_DEBUG__VI = 0x1E8D; +constexpr unsigned int mmDCP2_DCP_DEBUG2__VI = 0x1E98; +constexpr unsigned int mmDCP2_DCP_FP_CONVERTED_FIELD__VI = 0x1E65; +constexpr unsigned int mmDCP2_DCP_GSL_CONTROL__VI = 0x1E90; +constexpr unsigned int mmDCP2_DCP_LB_DATA_GAP_BETWEEN_CHUNK__VI = 0x1E91; +constexpr unsigned int mmDCP2_DCP_RANDOM_SEEDS__VI = 0x1E61; +constexpr unsigned int mmDCP2_DCP_SPATIAL_DITHER_CNTL__VI = 0x1E60; +constexpr unsigned int mmDCP2_DCP_TEST_DEBUG_DATA__VI = 0x1E96; +constexpr unsigned int mmDCP2_DCP_TEST_DEBUG_INDEX__VI = 0x1E95; +constexpr unsigned int mmDCP2_DC_LUT_30_COLOR__VI = 0x1E7C; +constexpr unsigned int mmDCP2_DC_LUT_AUTOFILL__VI = 0x1E7F; +constexpr unsigned int mmDCP2_DC_LUT_BLACK_OFFSET_BLUE__VI = 0x1E81; +constexpr unsigned int mmDCP2_DC_LUT_BLACK_OFFSET_GREEN__VI = 0x1E82; +constexpr unsigned int mmDCP2_DC_LUT_BLACK_OFFSET_RED__VI = 0x1E83; +constexpr unsigned int mmDCP2_DC_LUT_CONTROL__VI = 0x1E80; +constexpr unsigned int mmDCP2_DC_LUT_PWL_DATA__VI = 0x1E7B; +constexpr unsigned int mmDCP2_DC_LUT_RW_INDEX__VI = 0x1E79; +constexpr unsigned int mmDCP2_DC_LUT_RW_MODE__VI = 0x1E78; +constexpr unsigned int mmDCP2_DC_LUT_SEQ_COLOR__VI = 0x1E7A; +constexpr unsigned int mmDCP2_DC_LUT_VGA_ACCESS_ENABLE__VI = 0x1E7D; +constexpr unsigned int mmDCP2_DC_LUT_WHITE_OFFSET_BLUE__VI = 0x1E84; +constexpr unsigned int mmDCP2_DC_LUT_WHITE_OFFSET_GREEN__VI = 0x1E85; +constexpr unsigned int mmDCP2_DC_LUT_WHITE_OFFSET_RED__VI = 0x1E86; +constexpr unsigned int mmDCP2_DC_LUT_WRITE_EN_MASK__VI = 0x1E7E; +constexpr unsigned int mmDCP2_DEGAMMA_CONTROL__VI = 0x1E58; +constexpr unsigned int mmDCP2_DENORM_CONTROL__VI = 0x1E50; +constexpr unsigned int mmDCP2_GAMUT_REMAP_C11_C12__VI = 0x1E5A; +constexpr unsigned int mmDCP2_GAMUT_REMAP_C13_C14__VI = 0x1E5B; +constexpr unsigned int mmDCP2_GAMUT_REMAP_C21_C22__VI = 0x1E5C; +constexpr unsigned int mmDCP2_GAMUT_REMAP_C23_C24__VI = 0x1E5D; +constexpr unsigned int mmDCP2_GAMUT_REMAP_C31_C32__VI = 0x1E5E; +constexpr unsigned int mmDCP2_GAMUT_REMAP_C33_C34__VI = 0x1E5F; +constexpr unsigned int mmDCP2_GAMUT_REMAP_CONTROL__VI = 0x1E59; +constexpr unsigned int mmDCP2_GRPH_COMPRESS_PITCH__VI = 0x1E1A; +constexpr unsigned int mmDCP2_GRPH_COMPRESS_SURFACE_ADDRESS__VI = 0x1E19; +constexpr unsigned int mmDCP2_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__VI = 0x1E1B; +constexpr unsigned int mmDCP2_GRPH_CONTROL__SI__CI = 0x4001; +constexpr unsigned int mmDCP2_GRPH_CONTROL__VI = 0x1E01; +constexpr unsigned int mmDCP2_GRPH_DFQ_CONTROL__VI = 0x1E14; +constexpr unsigned int mmDCP2_GRPH_DFQ_STATUS__VI = 0x1E15; +constexpr unsigned int mmDCP2_GRPH_ENABLE__VI = 0x1E00; +constexpr unsigned int mmDCP2_GRPH_FLIP_CONTROL__SI__CI = 0x4012; +constexpr unsigned int mmDCP2_GRPH_FLIP_CONTROL__VI = 0x1E12; +constexpr unsigned int mmDCP2_GRPH_FLIP_RATE_CNTL__VI = 0x1E8E; +constexpr unsigned int mmDCP2_GRPH_INTERRUPT_CONTROL__VI = 0x1E17; +constexpr unsigned int mmDCP2_GRPH_INTERRUPT_STATUS__VI = 0x1E16; +constexpr unsigned int mmDCP2_GRPH_LUT_10BIT_BYPASS__VI = 0x1E02; +constexpr unsigned int mmDCP2_GRPH_PITCH__SI__CI = 0x4006; +constexpr unsigned int mmDCP2_GRPH_PITCH__VI = 0x1E06; +constexpr unsigned int mmDCP2_GRPH_PRIMARY_SURFACE_ADDRESS__SI__CI = 0x4004; +constexpr unsigned int mmDCP2_GRPH_PRIMARY_SURFACE_ADDRESS__VI = 0x1E04; +constexpr unsigned int mmDCP2_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__VI = 0x1E07; +constexpr unsigned int mmDCP2_GRPH_SECONDARY_SURFACE_ADDRESS__VI = 0x1E05; +constexpr unsigned int mmDCP2_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x1E08; +constexpr unsigned int mmDCP2_GRPH_STEREOSYNC_FLIP__VI = 0x1E97; +constexpr unsigned int mmDCP2_GRPH_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x1E18; +constexpr unsigned int mmDCP2_GRPH_SURFACE_ADDRESS_INUSE__VI = 0x1E13; +constexpr unsigned int mmDCP2_GRPH_SURFACE_OFFSET_X__VI = 0x1E09; +constexpr unsigned int mmDCP2_GRPH_SURFACE_OFFSET_Y__VI = 0x1E0A; +constexpr unsigned int mmDCP2_GRPH_SWAP_CNTL__VI = 0x1E03; +constexpr unsigned int mmDCP2_GRPH_UPDATE__SI__CI = 0x4011; +constexpr unsigned int mmDCP2_GRPH_UPDATE__VI = 0x1E11; +constexpr unsigned int mmDCP2_GRPH_XDMA_CACHE_UNDERFLOW_DET_CNTL__VI = 0x1E9F; +constexpr unsigned int mmDCP2_GRPH_XDMA_CACHE_UNDERFLOW_DET_STATUS__VI = 0x1EBF; +constexpr unsigned int mmDCP2_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS__VI = 0x1EBD; +constexpr unsigned int mmDCP2_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS_HIGH__VI = 0x1EBE; +constexpr unsigned int mmDCP2_GRPH_X_END__VI = 0x1E0D; +constexpr unsigned int mmDCP2_GRPH_X_START__VI = 0x1E0B; +constexpr unsigned int mmDCP2_GRPH_Y_END__VI = 0x1E0E; +constexpr unsigned int mmDCP2_GRPH_Y_START__VI = 0x1E0C; +constexpr unsigned int mmDCP2_HW_ROTATION__VI = 0x1E9E; +constexpr unsigned int mmDCP2_INPUT_CSC_C11_C12__VI = 0x1E36; +constexpr unsigned int mmDCP2_INPUT_CSC_C13_C14__VI = 0x1E37; +constexpr unsigned int mmDCP2_INPUT_CSC_C21_C22__VI = 0x1E38; +constexpr unsigned int mmDCP2_INPUT_CSC_C23_C24__VI = 0x1E39; +constexpr unsigned int mmDCP2_INPUT_CSC_C31_C32__VI = 0x1E3A; +constexpr unsigned int mmDCP2_INPUT_CSC_C33_C34__VI = 0x1E3B; +constexpr unsigned int mmDCP2_INPUT_CSC_CONTROL__VI = 0x1E35; +constexpr unsigned int mmDCP2_INPUT_GAMMA_CONTROL__VI = 0x1E10; +constexpr unsigned int mmDCP2_KEY_CONTROL__VI = 0x1E53; +constexpr unsigned int mmDCP2_KEY_RANGE_ALPHA__VI = 0x1E54; +constexpr unsigned int mmDCP2_KEY_RANGE_BLUE__VI = 0x1E57; +constexpr unsigned int mmDCP2_KEY_RANGE_GREEN__VI = 0x1E56; +constexpr unsigned int mmDCP2_KEY_RANGE_RED__VI = 0x1E55; +constexpr unsigned int mmDCP2_OUTPUT_CSC_C11_C12__VI = 0x1E3D; +constexpr unsigned int mmDCP2_OUTPUT_CSC_C13_C14__VI = 0x1E3E; +constexpr unsigned int mmDCP2_OUTPUT_CSC_C21_C22__VI = 0x1E3F; +constexpr unsigned int mmDCP2_OUTPUT_CSC_C23_C24__VI = 0x1E40; +constexpr unsigned int mmDCP2_OUTPUT_CSC_C31_C32__VI = 0x1E41; +constexpr unsigned int mmDCP2_OUTPUT_CSC_C33_C34__VI = 0x1E42; +constexpr unsigned int mmDCP2_OUTPUT_CSC_CONTROL__VI = 0x1E3C; +constexpr unsigned int mmDCP2_OUT_CLAMP_CONTROL_B_CB__VI = 0x1E9D; +constexpr unsigned int mmDCP2_OUT_CLAMP_CONTROL_G_Y__VI = 0x1E9C; +constexpr unsigned int mmDCP2_OUT_CLAMP_CONTROL_R_CR__VI = 0x1E52; +constexpr unsigned int mmDCP2_OUT_ROUND_CONTROL__VI = 0x1E51; +constexpr unsigned int mmDCP2_OVLSCL_EDGE_PIXEL_CNTL__VI = 0x1E2C; +constexpr unsigned int mmDCP2_OVL_CONTROL1__VI = 0x1E1D; +constexpr unsigned int mmDCP2_OVL_CONTROL2__VI = 0x1E1E; +constexpr unsigned int mmDCP2_OVL_DFQ_CONTROL__VI = 0x1E29; +constexpr unsigned int mmDCP2_OVL_DFQ_STATUS__VI = 0x1E2A; +constexpr unsigned int mmDCP2_OVL_ENABLE__VI = 0x1E1C; +constexpr unsigned int mmDCP2_OVL_END__VI = 0x1E26; +constexpr unsigned int mmDCP2_OVL_PITCH__VI = 0x1E21; +constexpr unsigned int mmDCP2_OVL_SECONDARY_SURFACE_ADDRESS__VI = 0x1E92; +constexpr unsigned int mmDCP2_OVL_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x1E94; +constexpr unsigned int mmDCP2_OVL_START__VI = 0x1E25; +constexpr unsigned int mmDCP2_OVL_STEREOSYNC_FLIP__VI = 0x1E93; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS__SI__CI = 0x4020; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS__VI = 0x1E20; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS_HIGH__VI = 0x1E22; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x1E2B; +constexpr unsigned int mmDCP2_OVL_SURFACE_ADDRESS_INUSE__VI = 0x1E28; +constexpr unsigned int mmDCP2_OVL_SURFACE_OFFSET_X__VI = 0x1E23; +constexpr unsigned int mmDCP2_OVL_SURFACE_OFFSET_Y__VI = 0x1E24; +constexpr unsigned int mmDCP2_OVL_SWAP_CNTL__VI = 0x1E1F; +constexpr unsigned int mmDCP2_OVL_UPDATE__VI = 0x1E27; +constexpr unsigned int mmDCP2_PRESCALE_GRPH_CONTROL__VI = 0x1E2D; +constexpr unsigned int mmDCP2_PRESCALE_OVL_CONTROL__VI = 0x1E31; +constexpr unsigned int mmDCP2_PRESCALE_VALUES_GRPH_B__VI = 0x1E30; +constexpr unsigned int mmDCP2_PRESCALE_VALUES_GRPH_G__VI = 0x1E2F; +constexpr unsigned int mmDCP2_PRESCALE_VALUES_GRPH_R__VI = 0x1E2E; +constexpr unsigned int mmDCP2_PRESCALE_VALUES_OVL_CB__VI = 0x1E32; +constexpr unsigned int mmDCP2_PRESCALE_VALUES_OVL_CR__VI = 0x1E34; +constexpr unsigned int mmDCP2_PRESCALE_VALUES_OVL_Y__VI = 0x1E33; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_END_CNTL1__VI = 0x1EA6; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_END_CNTL2__VI = 0x1EA7; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_0_1__VI = 0x1EA8; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_10_11__VI = 0x1EAD; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_12_13__VI = 0x1EAE; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_14_15__VI = 0x1EAF; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_2_3__VI = 0x1EA9; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_4_5__VI = 0x1EAA; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_6_7__VI = 0x1EAB; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_REGION_8_9__VI = 0x1EAC; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_SLOPE_CNTL__VI = 0x1EA5; +constexpr unsigned int mmDCP2_REGAMMA_CNTLA_START_CNTL__VI = 0x1EA4; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_END_CNTL1__VI = 0x1EB2; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_END_CNTL2__VI = 0x1EB3; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_0_1__VI = 0x1EB4; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_10_11__VI = 0x1EB9; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_12_13__VI = 0x1EBA; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_14_15__VI = 0x1EBB; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_2_3__VI = 0x1EB5; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_4_5__VI = 0x1EB6; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_6_7__VI = 0x1EB7; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_REGION_8_9__VI = 0x1EB8; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_SLOPE_CNTL__VI = 0x1EB1; +constexpr unsigned int mmDCP2_REGAMMA_CNTLB_START_CNTL__VI = 0x1EB0; +constexpr unsigned int mmDCP2_REGAMMA_CONTROL__VI = 0x1EA0; +constexpr unsigned int mmDCP2_REGAMMA_LUT_DATA__VI = 0x1EA2; +constexpr unsigned int mmDCP2_REGAMMA_LUT_INDEX__VI = 0x1EA1; +constexpr unsigned int mmDCP2_REGAMMA_LUT_WRITE_EN_MASK__VI = 0x1EA3; +constexpr unsigned int mmDCP3_ALPHA_CONTROL__VI = 0x40BC; +constexpr unsigned int mmDCP3_COMM_MATRIXA_TRANS_C11_C12__VI = 0x4043; +constexpr unsigned int mmDCP3_COMM_MATRIXA_TRANS_C13_C14__VI = 0x4044; +constexpr unsigned int mmDCP3_COMM_MATRIXA_TRANS_C21_C22__VI = 0x4045; +constexpr unsigned int mmDCP3_COMM_MATRIXA_TRANS_C23_C24__VI = 0x4046; +constexpr unsigned int mmDCP3_COMM_MATRIXA_TRANS_C31_C32__VI = 0x4047; +constexpr unsigned int mmDCP3_COMM_MATRIXA_TRANS_C33_C34__VI = 0x4048; +constexpr unsigned int mmDCP3_COMM_MATRIXB_TRANS_C11_C12__VI = 0x4049; +constexpr unsigned int mmDCP3_COMM_MATRIXB_TRANS_C13_C14__VI = 0x404A; +constexpr unsigned int mmDCP3_COMM_MATRIXB_TRANS_C21_C22__VI = 0x404B; +constexpr unsigned int mmDCP3_COMM_MATRIXB_TRANS_C23_C24__VI = 0x404C; +constexpr unsigned int mmDCP3_COMM_MATRIXB_TRANS_C31_C32__VI = 0x404D; +constexpr unsigned int mmDCP3_COMM_MATRIXB_TRANS_C33_C34__VI = 0x404E; +constexpr unsigned int mmDCP3_CUR2_COLOR1__VI = 0x4075; +constexpr unsigned int mmDCP3_CUR2_COLOR2__VI = 0x4076; +constexpr unsigned int mmDCP3_CUR2_CONTROL__VI = 0x406F; +constexpr unsigned int mmDCP3_CUR2_HOT_SPOT__VI = 0x4074; +constexpr unsigned int mmDCP3_CUR2_POSITION__VI = 0x4073; +constexpr unsigned int mmDCP3_CUR2_SIZE__VI = 0x4071; +constexpr unsigned int mmDCP3_CUR2_STEREO_CONTROL__VI = 0x409B; +constexpr unsigned int mmDCP3_CUR2_SURFACE_ADDRESS__VI = 0x4070; +constexpr unsigned int mmDCP3_CUR2_SURFACE_ADDRESS_HIGH__VI = 0x4072; +constexpr unsigned int mmDCP3_CUR2_UPDATE__VI = 0x4077; +constexpr unsigned int mmDCP3_CUR_COLOR1__VI = 0x406C; +constexpr unsigned int mmDCP3_CUR_COLOR2__VI = 0x406D; +constexpr unsigned int mmDCP3_CUR_CONTROL__VI = 0x4066; +constexpr unsigned int mmDCP3_CUR_HOT_SPOT__VI = 0x406B; +constexpr unsigned int mmDCP3_CUR_POSITION__VI = 0x406A; +constexpr unsigned int mmDCP3_CUR_REQUEST_FILTER_CNTL__VI = 0x4099; +constexpr unsigned int mmDCP3_CUR_SIZE__VI = 0x4068; +constexpr unsigned int mmDCP3_CUR_STEREO_CONTROL__VI = 0x409A; +constexpr unsigned int mmDCP3_CUR_SURFACE_ADDRESS__VI = 0x4067; +constexpr unsigned int mmDCP3_CUR_SURFACE_ADDRESS_HIGH__VI = 0x4069; +constexpr unsigned int mmDCP3_CUR_UPDATE__VI = 0x406E; +constexpr unsigned int mmDCP3_DCP_CRC_CONTROL__VI = 0x4087; +constexpr unsigned int mmDCP3_DCP_CRC_CURRENT__VI = 0x4089; +constexpr unsigned int mmDCP3_DCP_CRC_LAST__VI = 0x408B; +constexpr unsigned int mmDCP3_DCP_CRC_MASK__VI = 0x4088; +constexpr unsigned int mmDCP3_DCP_DEBUG__VI = 0x408D; +constexpr unsigned int mmDCP3_DCP_DEBUG2__VI = 0x4098; +constexpr unsigned int mmDCP3_DCP_FP_CONVERTED_FIELD__VI = 0x4065; +constexpr unsigned int mmDCP3_DCP_GSL_CONTROL__VI = 0x4090; +constexpr unsigned int mmDCP3_DCP_LB_DATA_GAP_BETWEEN_CHUNK__VI = 0x4091; +constexpr unsigned int mmDCP3_DCP_RANDOM_SEEDS__VI = 0x4061; +constexpr unsigned int mmDCP3_DCP_SPATIAL_DITHER_CNTL__VI = 0x4060; +constexpr unsigned int mmDCP3_DCP_TEST_DEBUG_DATA__VI = 0x4096; +constexpr unsigned int mmDCP3_DCP_TEST_DEBUG_INDEX__VI = 0x4095; +constexpr unsigned int mmDCP3_DC_LUT_30_COLOR__VI = 0x407C; +constexpr unsigned int mmDCP3_DC_LUT_AUTOFILL__VI = 0x407F; +constexpr unsigned int mmDCP3_DC_LUT_BLACK_OFFSET_BLUE__VI = 0x4081; +constexpr unsigned int mmDCP3_DC_LUT_BLACK_OFFSET_GREEN__VI = 0x4082; +constexpr unsigned int mmDCP3_DC_LUT_BLACK_OFFSET_RED__VI = 0x4083; +constexpr unsigned int mmDCP3_DC_LUT_CONTROL__VI = 0x4080; +constexpr unsigned int mmDCP3_DC_LUT_PWL_DATA__VI = 0x407B; +constexpr unsigned int mmDCP3_DC_LUT_RW_INDEX__VI = 0x4079; +constexpr unsigned int mmDCP3_DC_LUT_RW_MODE__VI = 0x4078; +constexpr unsigned int mmDCP3_DC_LUT_SEQ_COLOR__VI = 0x407A; +constexpr unsigned int mmDCP3_DC_LUT_VGA_ACCESS_ENABLE__VI = 0x407D; +constexpr unsigned int mmDCP3_DC_LUT_WHITE_OFFSET_BLUE__VI = 0x4084; +constexpr unsigned int mmDCP3_DC_LUT_WHITE_OFFSET_GREEN__VI = 0x4085; +constexpr unsigned int mmDCP3_DC_LUT_WHITE_OFFSET_RED__VI = 0x4086; +constexpr unsigned int mmDCP3_DC_LUT_WRITE_EN_MASK__VI = 0x407E; +constexpr unsigned int mmDCP3_DEGAMMA_CONTROL__VI = 0x4058; +constexpr unsigned int mmDCP3_DENORM_CONTROL__VI = 0x4050; +constexpr unsigned int mmDCP3_GAMUT_REMAP_C11_C12__VI = 0x405A; +constexpr unsigned int mmDCP3_GAMUT_REMAP_C13_C14__VI = 0x405B; +constexpr unsigned int mmDCP3_GAMUT_REMAP_C21_C22__VI = 0x405C; +constexpr unsigned int mmDCP3_GAMUT_REMAP_C23_C24__VI = 0x405D; +constexpr unsigned int mmDCP3_GAMUT_REMAP_C31_C32__VI = 0x405E; +constexpr unsigned int mmDCP3_GAMUT_REMAP_C33_C34__VI = 0x405F; +constexpr unsigned int mmDCP3_GAMUT_REMAP_CONTROL__VI = 0x4059; +constexpr unsigned int mmDCP3_GRPH_COMPRESS_PITCH__VI = 0x401A; +constexpr unsigned int mmDCP3_GRPH_COMPRESS_SURFACE_ADDRESS__VI = 0x4019; +constexpr unsigned int mmDCP3_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__VI = 0x401B; +constexpr unsigned int mmDCP3_GRPH_CONTROL__SI__CI = 0x4301; +constexpr unsigned int mmDCP3_GRPH_CONTROL__VI = 0x4001; +constexpr unsigned int mmDCP3_GRPH_DFQ_CONTROL__VI = 0x4014; +constexpr unsigned int mmDCP3_GRPH_DFQ_STATUS__VI = 0x4015; +constexpr unsigned int mmDCP3_GRPH_ENABLE__VI = 0x4000; +constexpr unsigned int mmDCP3_GRPH_FLIP_CONTROL__SI__CI = 0x4312; +constexpr unsigned int mmDCP3_GRPH_FLIP_CONTROL__VI = 0x4012; +constexpr unsigned int mmDCP3_GRPH_FLIP_RATE_CNTL__VI = 0x408E; +constexpr unsigned int mmDCP3_GRPH_INTERRUPT_CONTROL__VI = 0x4017; +constexpr unsigned int mmDCP3_GRPH_INTERRUPT_STATUS__VI = 0x4016; +constexpr unsigned int mmDCP3_GRPH_LUT_10BIT_BYPASS__VI = 0x4002; +constexpr unsigned int mmDCP3_GRPH_PITCH__SI__CI = 0x4306; +constexpr unsigned int mmDCP3_GRPH_PITCH__VI = 0x4006; +constexpr unsigned int mmDCP3_GRPH_PRIMARY_SURFACE_ADDRESS__SI__CI = 0x4304; +constexpr unsigned int mmDCP3_GRPH_PRIMARY_SURFACE_ADDRESS__VI = 0x4004; +constexpr unsigned int mmDCP3_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__VI = 0x4007; +constexpr unsigned int mmDCP3_GRPH_SECONDARY_SURFACE_ADDRESS__VI = 0x4005; +constexpr unsigned int mmDCP3_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x4008; +constexpr unsigned int mmDCP3_GRPH_STEREOSYNC_FLIP__VI = 0x4097; +constexpr unsigned int mmDCP3_GRPH_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x4018; +constexpr unsigned int mmDCP3_GRPH_SURFACE_ADDRESS_INUSE__VI = 0x4013; +constexpr unsigned int mmDCP3_GRPH_SURFACE_OFFSET_X__VI = 0x4009; +constexpr unsigned int mmDCP3_GRPH_SURFACE_OFFSET_Y__VI = 0x400A; +constexpr unsigned int mmDCP3_GRPH_SWAP_CNTL__VI = 0x4003; +constexpr unsigned int mmDCP3_GRPH_UPDATE__SI__CI = 0x4311; +constexpr unsigned int mmDCP3_GRPH_UPDATE__VI = 0x4011; +constexpr unsigned int mmDCP3_GRPH_XDMA_CACHE_UNDERFLOW_DET_CNTL__VI = 0x409F; +constexpr unsigned int mmDCP3_GRPH_XDMA_CACHE_UNDERFLOW_DET_STATUS__VI = 0x40BF; +constexpr unsigned int mmDCP3_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS__VI = 0x40BD; +constexpr unsigned int mmDCP3_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS_HIGH__VI = 0x40BE; +constexpr unsigned int mmDCP3_GRPH_X_END__VI = 0x400D; +constexpr unsigned int mmDCP3_GRPH_X_START__VI = 0x400B; +constexpr unsigned int mmDCP3_GRPH_Y_END__VI = 0x400E; +constexpr unsigned int mmDCP3_GRPH_Y_START__VI = 0x400C; +constexpr unsigned int mmDCP3_HW_ROTATION__VI = 0x409E; +constexpr unsigned int mmDCP3_INPUT_CSC_C11_C12__VI = 0x4036; +constexpr unsigned int mmDCP3_INPUT_CSC_C13_C14__VI = 0x4037; +constexpr unsigned int mmDCP3_INPUT_CSC_C21_C22__VI = 0x4038; +constexpr unsigned int mmDCP3_INPUT_CSC_C23_C24__VI = 0x4039; +constexpr unsigned int mmDCP3_INPUT_CSC_C31_C32__VI = 0x403A; +constexpr unsigned int mmDCP3_INPUT_CSC_C33_C34__VI = 0x403B; +constexpr unsigned int mmDCP3_INPUT_CSC_CONTROL__VI = 0x4035; +constexpr unsigned int mmDCP3_INPUT_GAMMA_CONTROL__VI = 0x4010; +constexpr unsigned int mmDCP3_KEY_CONTROL__VI = 0x4053; +constexpr unsigned int mmDCP3_KEY_RANGE_ALPHA__VI = 0x4054; +constexpr unsigned int mmDCP3_KEY_RANGE_BLUE__VI = 0x4057; +constexpr unsigned int mmDCP3_KEY_RANGE_GREEN__VI = 0x4056; +constexpr unsigned int mmDCP3_KEY_RANGE_RED__VI = 0x4055; +constexpr unsigned int mmDCP3_OUTPUT_CSC_C11_C12__VI = 0x403D; +constexpr unsigned int mmDCP3_OUTPUT_CSC_C13_C14__VI = 0x403E; +constexpr unsigned int mmDCP3_OUTPUT_CSC_C21_C22__VI = 0x403F; +constexpr unsigned int mmDCP3_OUTPUT_CSC_C23_C24__VI = 0x4040; +constexpr unsigned int mmDCP3_OUTPUT_CSC_C31_C32__VI = 0x4041; +constexpr unsigned int mmDCP3_OUTPUT_CSC_C33_C34__VI = 0x4042; +constexpr unsigned int mmDCP3_OUTPUT_CSC_CONTROL__VI = 0x403C; +constexpr unsigned int mmDCP3_OUT_CLAMP_CONTROL_B_CB__VI = 0x409D; +constexpr unsigned int mmDCP3_OUT_CLAMP_CONTROL_G_Y__VI = 0x409C; +constexpr unsigned int mmDCP3_OUT_CLAMP_CONTROL_R_CR__VI = 0x4052; +constexpr unsigned int mmDCP3_OUT_ROUND_CONTROL__VI = 0x4051; +constexpr unsigned int mmDCP3_OVLSCL_EDGE_PIXEL_CNTL__VI = 0x402C; +constexpr unsigned int mmDCP3_OVL_CONTROL1__VI = 0x401D; +constexpr unsigned int mmDCP3_OVL_CONTROL2__VI = 0x401E; +constexpr unsigned int mmDCP3_OVL_DFQ_CONTROL__VI = 0x4029; +constexpr unsigned int mmDCP3_OVL_DFQ_STATUS__VI = 0x402A; +constexpr unsigned int mmDCP3_OVL_ENABLE__VI = 0x401C; +constexpr unsigned int mmDCP3_OVL_END__VI = 0x4026; +constexpr unsigned int mmDCP3_OVL_PITCH__VI = 0x4021; +constexpr unsigned int mmDCP3_OVL_SECONDARY_SURFACE_ADDRESS__VI = 0x4092; +constexpr unsigned int mmDCP3_OVL_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x4094; +constexpr unsigned int mmDCP3_OVL_START__VI = 0x4025; +constexpr unsigned int mmDCP3_OVL_STEREOSYNC_FLIP__VI = 0x4093; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS__SI__CI = 0x4320; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS__VI = 0x4020; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS_HIGH__VI = 0x4022; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x402B; +constexpr unsigned int mmDCP3_OVL_SURFACE_ADDRESS_INUSE__VI = 0x4028; +constexpr unsigned int mmDCP3_OVL_SURFACE_OFFSET_X__VI = 0x4023; +constexpr unsigned int mmDCP3_OVL_SURFACE_OFFSET_Y__VI = 0x4024; +constexpr unsigned int mmDCP3_OVL_SWAP_CNTL__VI = 0x401F; +constexpr unsigned int mmDCP3_OVL_UPDATE__VI = 0x4027; +constexpr unsigned int mmDCP3_PRESCALE_GRPH_CONTROL__VI = 0x402D; +constexpr unsigned int mmDCP3_PRESCALE_OVL_CONTROL__VI = 0x4031; +constexpr unsigned int mmDCP3_PRESCALE_VALUES_GRPH_B__VI = 0x4030; +constexpr unsigned int mmDCP3_PRESCALE_VALUES_GRPH_G__VI = 0x402F; +constexpr unsigned int mmDCP3_PRESCALE_VALUES_GRPH_R__VI = 0x402E; +constexpr unsigned int mmDCP3_PRESCALE_VALUES_OVL_CB__VI = 0x4032; +constexpr unsigned int mmDCP3_PRESCALE_VALUES_OVL_CR__VI = 0x4034; +constexpr unsigned int mmDCP3_PRESCALE_VALUES_OVL_Y__VI = 0x4033; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_END_CNTL1__VI = 0x40A6; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_END_CNTL2__VI = 0x40A7; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_0_1__VI = 0x40A8; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_10_11__VI = 0x40AD; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_12_13__VI = 0x40AE; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_14_15__VI = 0x40AF; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_2_3__VI = 0x40A9; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_4_5__VI = 0x40AA; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_6_7__VI = 0x40AB; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_REGION_8_9__VI = 0x40AC; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_SLOPE_CNTL__VI = 0x40A5; +constexpr unsigned int mmDCP3_REGAMMA_CNTLA_START_CNTL__VI = 0x40A4; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_END_CNTL1__VI = 0x40B2; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_END_CNTL2__VI = 0x40B3; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_0_1__VI = 0x40B4; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_10_11__VI = 0x40B9; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_12_13__VI = 0x40BA; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_14_15__VI = 0x40BB; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_2_3__VI = 0x40B5; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_4_5__VI = 0x40B6; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_6_7__VI = 0x40B7; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_REGION_8_9__VI = 0x40B8; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_SLOPE_CNTL__VI = 0x40B1; +constexpr unsigned int mmDCP3_REGAMMA_CNTLB_START_CNTL__VI = 0x40B0; +constexpr unsigned int mmDCP3_REGAMMA_CONTROL__VI = 0x40A0; +constexpr unsigned int mmDCP3_REGAMMA_LUT_DATA__VI = 0x40A2; +constexpr unsigned int mmDCP3_REGAMMA_LUT_INDEX__VI = 0x40A1; +constexpr unsigned int mmDCP3_REGAMMA_LUT_WRITE_EN_MASK__VI = 0x40A3; +constexpr unsigned int mmDCP4_ALPHA_CONTROL__VI = 0x42BC; +constexpr unsigned int mmDCP4_COMM_MATRIXA_TRANS_C11_C12__VI = 0x4243; +constexpr unsigned int mmDCP4_COMM_MATRIXA_TRANS_C13_C14__VI = 0x4244; +constexpr unsigned int mmDCP4_COMM_MATRIXA_TRANS_C21_C22__VI = 0x4245; +constexpr unsigned int mmDCP4_COMM_MATRIXA_TRANS_C23_C24__VI = 0x4246; +constexpr unsigned int mmDCP4_COMM_MATRIXA_TRANS_C31_C32__VI = 0x4247; +constexpr unsigned int mmDCP4_COMM_MATRIXA_TRANS_C33_C34__VI = 0x4248; +constexpr unsigned int mmDCP4_COMM_MATRIXB_TRANS_C11_C12__VI = 0x4249; +constexpr unsigned int mmDCP4_COMM_MATRIXB_TRANS_C13_C14__VI = 0x424A; +constexpr unsigned int mmDCP4_COMM_MATRIXB_TRANS_C21_C22__VI = 0x424B; +constexpr unsigned int mmDCP4_COMM_MATRIXB_TRANS_C23_C24__VI = 0x424C; +constexpr unsigned int mmDCP4_COMM_MATRIXB_TRANS_C31_C32__VI = 0x424D; +constexpr unsigned int mmDCP4_COMM_MATRIXB_TRANS_C33_C34__VI = 0x424E; +constexpr unsigned int mmDCP4_CUR2_COLOR1__VI = 0x4275; +constexpr unsigned int mmDCP4_CUR2_COLOR2__VI = 0x4276; +constexpr unsigned int mmDCP4_CUR2_CONTROL__VI = 0x426F; +constexpr unsigned int mmDCP4_CUR2_HOT_SPOT__VI = 0x4274; +constexpr unsigned int mmDCP4_CUR2_POSITION__VI = 0x4273; +constexpr unsigned int mmDCP4_CUR2_SIZE__VI = 0x4271; +constexpr unsigned int mmDCP4_CUR2_STEREO_CONTROL__VI = 0x429B; +constexpr unsigned int mmDCP4_CUR2_SURFACE_ADDRESS__VI = 0x4270; +constexpr unsigned int mmDCP4_CUR2_SURFACE_ADDRESS_HIGH__VI = 0x4272; +constexpr unsigned int mmDCP4_CUR2_UPDATE__VI = 0x4277; +constexpr unsigned int mmDCP4_CUR_COLOR1__VI = 0x426C; +constexpr unsigned int mmDCP4_CUR_COLOR2__VI = 0x426D; +constexpr unsigned int mmDCP4_CUR_CONTROL__VI = 0x4266; +constexpr unsigned int mmDCP4_CUR_HOT_SPOT__VI = 0x426B; +constexpr unsigned int mmDCP4_CUR_POSITION__VI = 0x426A; +constexpr unsigned int mmDCP4_CUR_REQUEST_FILTER_CNTL__VI = 0x4299; +constexpr unsigned int mmDCP4_CUR_SIZE__VI = 0x4268; +constexpr unsigned int mmDCP4_CUR_STEREO_CONTROL__VI = 0x429A; +constexpr unsigned int mmDCP4_CUR_SURFACE_ADDRESS__VI = 0x4267; +constexpr unsigned int mmDCP4_CUR_SURFACE_ADDRESS_HIGH__VI = 0x4269; +constexpr unsigned int mmDCP4_CUR_UPDATE__VI = 0x426E; +constexpr unsigned int mmDCP4_DCP_CRC_CONTROL__VI = 0x4287; +constexpr unsigned int mmDCP4_DCP_CRC_CURRENT__VI = 0x4289; +constexpr unsigned int mmDCP4_DCP_CRC_LAST__VI = 0x428B; +constexpr unsigned int mmDCP4_DCP_CRC_MASK__VI = 0x4288; +constexpr unsigned int mmDCP4_DCP_DEBUG__VI = 0x428D; +constexpr unsigned int mmDCP4_DCP_DEBUG2__VI = 0x4298; +constexpr unsigned int mmDCP4_DCP_FP_CONVERTED_FIELD__VI = 0x4265; +constexpr unsigned int mmDCP4_DCP_GSL_CONTROL__VI = 0x4290; +constexpr unsigned int mmDCP4_DCP_LB_DATA_GAP_BETWEEN_CHUNK__VI = 0x4291; +constexpr unsigned int mmDCP4_DCP_RANDOM_SEEDS__VI = 0x4261; +constexpr unsigned int mmDCP4_DCP_SPATIAL_DITHER_CNTL__VI = 0x4260; +constexpr unsigned int mmDCP4_DCP_TEST_DEBUG_DATA__VI = 0x4296; +constexpr unsigned int mmDCP4_DCP_TEST_DEBUG_INDEX__VI = 0x4295; +constexpr unsigned int mmDCP4_DC_LUT_30_COLOR__VI = 0x427C; +constexpr unsigned int mmDCP4_DC_LUT_AUTOFILL__VI = 0x427F; +constexpr unsigned int mmDCP4_DC_LUT_BLACK_OFFSET_BLUE__VI = 0x4281; +constexpr unsigned int mmDCP4_DC_LUT_BLACK_OFFSET_GREEN__VI = 0x4282; +constexpr unsigned int mmDCP4_DC_LUT_BLACK_OFFSET_RED__VI = 0x4283; +constexpr unsigned int mmDCP4_DC_LUT_CONTROL__VI = 0x4280; +constexpr unsigned int mmDCP4_DC_LUT_PWL_DATA__VI = 0x427B; +constexpr unsigned int mmDCP4_DC_LUT_RW_INDEX__VI = 0x4279; +constexpr unsigned int mmDCP4_DC_LUT_RW_MODE__VI = 0x4278; +constexpr unsigned int mmDCP4_DC_LUT_SEQ_COLOR__VI = 0x427A; +constexpr unsigned int mmDCP4_DC_LUT_VGA_ACCESS_ENABLE__VI = 0x427D; +constexpr unsigned int mmDCP4_DC_LUT_WHITE_OFFSET_BLUE__VI = 0x4284; +constexpr unsigned int mmDCP4_DC_LUT_WHITE_OFFSET_GREEN__VI = 0x4285; +constexpr unsigned int mmDCP4_DC_LUT_WHITE_OFFSET_RED__VI = 0x4286; +constexpr unsigned int mmDCP4_DC_LUT_WRITE_EN_MASK__VI = 0x427E; +constexpr unsigned int mmDCP4_DEGAMMA_CONTROL__VI = 0x4258; +constexpr unsigned int mmDCP4_DENORM_CONTROL__VI = 0x4250; +constexpr unsigned int mmDCP4_GAMUT_REMAP_C11_C12__VI = 0x425A; +constexpr unsigned int mmDCP4_GAMUT_REMAP_C13_C14__VI = 0x425B; +constexpr unsigned int mmDCP4_GAMUT_REMAP_C21_C22__VI = 0x425C; +constexpr unsigned int mmDCP4_GAMUT_REMAP_C23_C24__VI = 0x425D; +constexpr unsigned int mmDCP4_GAMUT_REMAP_C31_C32__VI = 0x425E; +constexpr unsigned int mmDCP4_GAMUT_REMAP_C33_C34__VI = 0x425F; +constexpr unsigned int mmDCP4_GAMUT_REMAP_CONTROL__VI = 0x4259; +constexpr unsigned int mmDCP4_GRPH_COMPRESS_PITCH__VI = 0x421A; +constexpr unsigned int mmDCP4_GRPH_COMPRESS_SURFACE_ADDRESS__VI = 0x4219; +constexpr unsigned int mmDCP4_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__VI = 0x421B; +constexpr unsigned int mmDCP4_GRPH_CONTROL__SI__CI = 0x4601; +constexpr unsigned int mmDCP4_GRPH_CONTROL__VI = 0x4201; +constexpr unsigned int mmDCP4_GRPH_DFQ_CONTROL__VI = 0x4214; +constexpr unsigned int mmDCP4_GRPH_DFQ_STATUS__VI = 0x4215; +constexpr unsigned int mmDCP4_GRPH_ENABLE__VI = 0x4200; +constexpr unsigned int mmDCP4_GRPH_FLIP_CONTROL__SI__CI = 0x4612; +constexpr unsigned int mmDCP4_GRPH_FLIP_CONTROL__VI = 0x4212; +constexpr unsigned int mmDCP4_GRPH_FLIP_RATE_CNTL__VI = 0x428E; +constexpr unsigned int mmDCP4_GRPH_INTERRUPT_CONTROL__VI = 0x4217; +constexpr unsigned int mmDCP4_GRPH_INTERRUPT_STATUS__VI = 0x4216; +constexpr unsigned int mmDCP4_GRPH_LUT_10BIT_BYPASS__VI = 0x4202; +constexpr unsigned int mmDCP4_GRPH_PITCH__SI__CI = 0x4606; +constexpr unsigned int mmDCP4_GRPH_PITCH__VI = 0x4206; +constexpr unsigned int mmDCP4_GRPH_PRIMARY_SURFACE_ADDRESS__SI__CI = 0x4604; +constexpr unsigned int mmDCP4_GRPH_PRIMARY_SURFACE_ADDRESS__VI = 0x4204; +constexpr unsigned int mmDCP4_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__VI = 0x4207; +constexpr unsigned int mmDCP4_GRPH_SECONDARY_SURFACE_ADDRESS__VI = 0x4205; +constexpr unsigned int mmDCP4_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x4208; +constexpr unsigned int mmDCP4_GRPH_STEREOSYNC_FLIP__VI = 0x4297; +constexpr unsigned int mmDCP4_GRPH_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x4218; +constexpr unsigned int mmDCP4_GRPH_SURFACE_ADDRESS_INUSE__VI = 0x4213; +constexpr unsigned int mmDCP4_GRPH_SURFACE_OFFSET_X__VI = 0x4209; +constexpr unsigned int mmDCP4_GRPH_SURFACE_OFFSET_Y__VI = 0x420A; +constexpr unsigned int mmDCP4_GRPH_SWAP_CNTL__VI = 0x4203; +constexpr unsigned int mmDCP4_GRPH_UPDATE__SI__CI = 0x4611; +constexpr unsigned int mmDCP4_GRPH_UPDATE__VI = 0x4211; +constexpr unsigned int mmDCP4_GRPH_XDMA_CACHE_UNDERFLOW_DET_CNTL__VI = 0x429F; +constexpr unsigned int mmDCP4_GRPH_XDMA_CACHE_UNDERFLOW_DET_STATUS__VI = 0x42BF; +constexpr unsigned int mmDCP4_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS__VI = 0x42BD; +constexpr unsigned int mmDCP4_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS_HIGH__VI = 0x42BE; +constexpr unsigned int mmDCP4_GRPH_X_END__VI = 0x420D; +constexpr unsigned int mmDCP4_GRPH_X_START__VI = 0x420B; +constexpr unsigned int mmDCP4_GRPH_Y_END__VI = 0x420E; +constexpr unsigned int mmDCP4_GRPH_Y_START__VI = 0x420C; +constexpr unsigned int mmDCP4_HW_ROTATION__VI = 0x429E; +constexpr unsigned int mmDCP4_INPUT_CSC_C11_C12__VI = 0x4236; +constexpr unsigned int mmDCP4_INPUT_CSC_C13_C14__VI = 0x4237; +constexpr unsigned int mmDCP4_INPUT_CSC_C21_C22__VI = 0x4238; +constexpr unsigned int mmDCP4_INPUT_CSC_C23_C24__VI = 0x4239; +constexpr unsigned int mmDCP4_INPUT_CSC_C31_C32__VI = 0x423A; +constexpr unsigned int mmDCP4_INPUT_CSC_C33_C34__VI = 0x423B; +constexpr unsigned int mmDCP4_INPUT_CSC_CONTROL__VI = 0x4235; +constexpr unsigned int mmDCP4_INPUT_GAMMA_CONTROL__VI = 0x4210; +constexpr unsigned int mmDCP4_KEY_CONTROL__VI = 0x4253; +constexpr unsigned int mmDCP4_KEY_RANGE_ALPHA__VI = 0x4254; +constexpr unsigned int mmDCP4_KEY_RANGE_BLUE__VI = 0x4257; +constexpr unsigned int mmDCP4_KEY_RANGE_GREEN__VI = 0x4256; +constexpr unsigned int mmDCP4_KEY_RANGE_RED__VI = 0x4255; +constexpr unsigned int mmDCP4_OUTPUT_CSC_C11_C12__VI = 0x423D; +constexpr unsigned int mmDCP4_OUTPUT_CSC_C13_C14__VI = 0x423E; +constexpr unsigned int mmDCP4_OUTPUT_CSC_C21_C22__VI = 0x423F; +constexpr unsigned int mmDCP4_OUTPUT_CSC_C23_C24__VI = 0x4240; +constexpr unsigned int mmDCP4_OUTPUT_CSC_C31_C32__VI = 0x4241; +constexpr unsigned int mmDCP4_OUTPUT_CSC_C33_C34__VI = 0x4242; +constexpr unsigned int mmDCP4_OUTPUT_CSC_CONTROL__VI = 0x423C; +constexpr unsigned int mmDCP4_OUT_CLAMP_CONTROL_B_CB__VI = 0x429D; +constexpr unsigned int mmDCP4_OUT_CLAMP_CONTROL_G_Y__VI = 0x429C; +constexpr unsigned int mmDCP4_OUT_CLAMP_CONTROL_R_CR__VI = 0x4252; +constexpr unsigned int mmDCP4_OUT_ROUND_CONTROL__VI = 0x4251; +constexpr unsigned int mmDCP4_OVLSCL_EDGE_PIXEL_CNTL__VI = 0x422C; +constexpr unsigned int mmDCP4_OVL_CONTROL1__VI = 0x421D; +constexpr unsigned int mmDCP4_OVL_CONTROL2__VI = 0x421E; +constexpr unsigned int mmDCP4_OVL_DFQ_CONTROL__VI = 0x4229; +constexpr unsigned int mmDCP4_OVL_DFQ_STATUS__VI = 0x422A; +constexpr unsigned int mmDCP4_OVL_ENABLE__VI = 0x421C; +constexpr unsigned int mmDCP4_OVL_END__VI = 0x4226; +constexpr unsigned int mmDCP4_OVL_PITCH__VI = 0x4221; +constexpr unsigned int mmDCP4_OVL_SECONDARY_SURFACE_ADDRESS__VI = 0x4292; +constexpr unsigned int mmDCP4_OVL_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x4294; +constexpr unsigned int mmDCP4_OVL_START__VI = 0x4225; +constexpr unsigned int mmDCP4_OVL_STEREOSYNC_FLIP__VI = 0x4293; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS__SI__CI = 0x4620; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS__VI = 0x4220; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS_HIGH__VI = 0x4222; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x422B; +constexpr unsigned int mmDCP4_OVL_SURFACE_ADDRESS_INUSE__VI = 0x4228; +constexpr unsigned int mmDCP4_OVL_SURFACE_OFFSET_X__VI = 0x4223; +constexpr unsigned int mmDCP4_OVL_SURFACE_OFFSET_Y__VI = 0x4224; +constexpr unsigned int mmDCP4_OVL_SWAP_CNTL__VI = 0x421F; +constexpr unsigned int mmDCP4_OVL_UPDATE__VI = 0x4227; +constexpr unsigned int mmDCP4_PRESCALE_GRPH_CONTROL__VI = 0x422D; +constexpr unsigned int mmDCP4_PRESCALE_OVL_CONTROL__VI = 0x4231; +constexpr unsigned int mmDCP4_PRESCALE_VALUES_GRPH_B__VI = 0x4230; +constexpr unsigned int mmDCP4_PRESCALE_VALUES_GRPH_G__VI = 0x422F; +constexpr unsigned int mmDCP4_PRESCALE_VALUES_GRPH_R__VI = 0x422E; +constexpr unsigned int mmDCP4_PRESCALE_VALUES_OVL_CB__VI = 0x4232; +constexpr unsigned int mmDCP4_PRESCALE_VALUES_OVL_CR__VI = 0x4234; +constexpr unsigned int mmDCP4_PRESCALE_VALUES_OVL_Y__VI = 0x4233; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_END_CNTL1__VI = 0x42A6; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_END_CNTL2__VI = 0x42A7; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_0_1__VI = 0x42A8; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_10_11__VI = 0x42AD; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_12_13__VI = 0x42AE; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_14_15__VI = 0x42AF; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_2_3__VI = 0x42A9; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_4_5__VI = 0x42AA; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_6_7__VI = 0x42AB; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_REGION_8_9__VI = 0x42AC; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_SLOPE_CNTL__VI = 0x42A5; +constexpr unsigned int mmDCP4_REGAMMA_CNTLA_START_CNTL__VI = 0x42A4; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_END_CNTL1__VI = 0x42B2; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_END_CNTL2__VI = 0x42B3; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_0_1__VI = 0x42B4; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_10_11__VI = 0x42B9; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_12_13__VI = 0x42BA; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_14_15__VI = 0x42BB; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_2_3__VI = 0x42B5; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_4_5__VI = 0x42B6; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_6_7__VI = 0x42B7; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_REGION_8_9__VI = 0x42B8; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_SLOPE_CNTL__VI = 0x42B1; +constexpr unsigned int mmDCP4_REGAMMA_CNTLB_START_CNTL__VI = 0x42B0; +constexpr unsigned int mmDCP4_REGAMMA_CONTROL__VI = 0x42A0; +constexpr unsigned int mmDCP4_REGAMMA_LUT_DATA__VI = 0x42A2; +constexpr unsigned int mmDCP4_REGAMMA_LUT_INDEX__VI = 0x42A1; +constexpr unsigned int mmDCP4_REGAMMA_LUT_WRITE_EN_MASK__VI = 0x42A3; +constexpr unsigned int mmDCP5_ALPHA_CONTROL__VI = 0x44BC; +constexpr unsigned int mmDCP5_COMM_MATRIXA_TRANS_C11_C12__VI = 0x4443; +constexpr unsigned int mmDCP5_COMM_MATRIXA_TRANS_C13_C14__VI = 0x4444; +constexpr unsigned int mmDCP5_COMM_MATRIXA_TRANS_C21_C22__VI = 0x4445; +constexpr unsigned int mmDCP5_COMM_MATRIXA_TRANS_C23_C24__VI = 0x4446; +constexpr unsigned int mmDCP5_COMM_MATRIXA_TRANS_C31_C32__VI = 0x4447; +constexpr unsigned int mmDCP5_COMM_MATRIXA_TRANS_C33_C34__VI = 0x4448; +constexpr unsigned int mmDCP5_COMM_MATRIXB_TRANS_C11_C12__VI = 0x4449; +constexpr unsigned int mmDCP5_COMM_MATRIXB_TRANS_C13_C14__VI = 0x444A; +constexpr unsigned int mmDCP5_COMM_MATRIXB_TRANS_C21_C22__VI = 0x444B; +constexpr unsigned int mmDCP5_COMM_MATRIXB_TRANS_C23_C24__VI = 0x444C; +constexpr unsigned int mmDCP5_COMM_MATRIXB_TRANS_C31_C32__VI = 0x444D; +constexpr unsigned int mmDCP5_COMM_MATRIXB_TRANS_C33_C34__VI = 0x444E; +constexpr unsigned int mmDCP5_CUR2_COLOR1__VI = 0x4475; +constexpr unsigned int mmDCP5_CUR2_COLOR2__VI = 0x4476; +constexpr unsigned int mmDCP5_CUR2_CONTROL__VI = 0x446F; +constexpr unsigned int mmDCP5_CUR2_HOT_SPOT__VI = 0x4474; +constexpr unsigned int mmDCP5_CUR2_POSITION__VI = 0x4473; +constexpr unsigned int mmDCP5_CUR2_SIZE__VI = 0x4471; +constexpr unsigned int mmDCP5_CUR2_STEREO_CONTROL__VI = 0x449B; +constexpr unsigned int mmDCP5_CUR2_SURFACE_ADDRESS__VI = 0x4470; +constexpr unsigned int mmDCP5_CUR2_SURFACE_ADDRESS_HIGH__VI = 0x4472; +constexpr unsigned int mmDCP5_CUR2_UPDATE__VI = 0x4477; +constexpr unsigned int mmDCP5_CUR_COLOR1__VI = 0x446C; +constexpr unsigned int mmDCP5_CUR_COLOR2__VI = 0x446D; +constexpr unsigned int mmDCP5_CUR_CONTROL__VI = 0x4466; +constexpr unsigned int mmDCP5_CUR_HOT_SPOT__VI = 0x446B; +constexpr unsigned int mmDCP5_CUR_POSITION__VI = 0x446A; +constexpr unsigned int mmDCP5_CUR_REQUEST_FILTER_CNTL__VI = 0x4499; +constexpr unsigned int mmDCP5_CUR_SIZE__VI = 0x4468; +constexpr unsigned int mmDCP5_CUR_STEREO_CONTROL__VI = 0x449A; +constexpr unsigned int mmDCP5_CUR_SURFACE_ADDRESS__VI = 0x4467; +constexpr unsigned int mmDCP5_CUR_SURFACE_ADDRESS_HIGH__VI = 0x4469; +constexpr unsigned int mmDCP5_CUR_UPDATE__VI = 0x446E; +constexpr unsigned int mmDCP5_DCP_CRC_CONTROL__VI = 0x4487; +constexpr unsigned int mmDCP5_DCP_CRC_CURRENT__VI = 0x4489; +constexpr unsigned int mmDCP5_DCP_CRC_LAST__VI = 0x448B; +constexpr unsigned int mmDCP5_DCP_CRC_MASK__VI = 0x4488; +constexpr unsigned int mmDCP5_DCP_DEBUG__VI = 0x448D; +constexpr unsigned int mmDCP5_DCP_DEBUG2__VI = 0x4498; +constexpr unsigned int mmDCP5_DCP_FP_CONVERTED_FIELD__VI = 0x4465; +constexpr unsigned int mmDCP5_DCP_GSL_CONTROL__VI = 0x4490; +constexpr unsigned int mmDCP5_DCP_LB_DATA_GAP_BETWEEN_CHUNK__VI = 0x4491; +constexpr unsigned int mmDCP5_DCP_RANDOM_SEEDS__VI = 0x4461; +constexpr unsigned int mmDCP5_DCP_SPATIAL_DITHER_CNTL__VI = 0x4460; +constexpr unsigned int mmDCP5_DCP_TEST_DEBUG_DATA__VI = 0x4496; +constexpr unsigned int mmDCP5_DCP_TEST_DEBUG_INDEX__VI = 0x4495; +constexpr unsigned int mmDCP5_DC_LUT_30_COLOR__VI = 0x447C; +constexpr unsigned int mmDCP5_DC_LUT_AUTOFILL__VI = 0x447F; +constexpr unsigned int mmDCP5_DC_LUT_BLACK_OFFSET_BLUE__VI = 0x4481; +constexpr unsigned int mmDCP5_DC_LUT_BLACK_OFFSET_GREEN__VI = 0x4482; +constexpr unsigned int mmDCP5_DC_LUT_BLACK_OFFSET_RED__VI = 0x4483; +constexpr unsigned int mmDCP5_DC_LUT_CONTROL__VI = 0x4480; +constexpr unsigned int mmDCP5_DC_LUT_PWL_DATA__VI = 0x447B; +constexpr unsigned int mmDCP5_DC_LUT_RW_INDEX__VI = 0x4479; +constexpr unsigned int mmDCP5_DC_LUT_RW_MODE__VI = 0x4478; +constexpr unsigned int mmDCP5_DC_LUT_SEQ_COLOR__VI = 0x447A; +constexpr unsigned int mmDCP5_DC_LUT_VGA_ACCESS_ENABLE__VI = 0x447D; +constexpr unsigned int mmDCP5_DC_LUT_WHITE_OFFSET_BLUE__VI = 0x4484; +constexpr unsigned int mmDCP5_DC_LUT_WHITE_OFFSET_GREEN__VI = 0x4485; +constexpr unsigned int mmDCP5_DC_LUT_WHITE_OFFSET_RED__VI = 0x4486; +constexpr unsigned int mmDCP5_DC_LUT_WRITE_EN_MASK__VI = 0x447E; +constexpr unsigned int mmDCP5_DEGAMMA_CONTROL__VI = 0x4458; +constexpr unsigned int mmDCP5_DENORM_CONTROL__VI = 0x4450; +constexpr unsigned int mmDCP5_GAMUT_REMAP_C11_C12__VI = 0x445A; +constexpr unsigned int mmDCP5_GAMUT_REMAP_C13_C14__VI = 0x445B; +constexpr unsigned int mmDCP5_GAMUT_REMAP_C21_C22__VI = 0x445C; +constexpr unsigned int mmDCP5_GAMUT_REMAP_C23_C24__VI = 0x445D; +constexpr unsigned int mmDCP5_GAMUT_REMAP_C31_C32__VI = 0x445E; +constexpr unsigned int mmDCP5_GAMUT_REMAP_C33_C34__VI = 0x445F; +constexpr unsigned int mmDCP5_GAMUT_REMAP_CONTROL__VI = 0x4459; +constexpr unsigned int mmDCP5_GRPH_COMPRESS_PITCH__VI = 0x441A; +constexpr unsigned int mmDCP5_GRPH_COMPRESS_SURFACE_ADDRESS__VI = 0x4419; +constexpr unsigned int mmDCP5_GRPH_COMPRESS_SURFACE_ADDRESS_HIGH__VI = 0x441B; +constexpr unsigned int mmDCP5_GRPH_CONTROL__SI__CI = 0x4901; +constexpr unsigned int mmDCP5_GRPH_CONTROL__VI = 0x4401; +constexpr unsigned int mmDCP5_GRPH_DFQ_CONTROL__VI = 0x4414; +constexpr unsigned int mmDCP5_GRPH_DFQ_STATUS__VI = 0x4415; +constexpr unsigned int mmDCP5_GRPH_ENABLE__VI = 0x4400; +constexpr unsigned int mmDCP5_GRPH_FLIP_CONTROL__SI__CI = 0x4912; +constexpr unsigned int mmDCP5_GRPH_FLIP_CONTROL__VI = 0x4412; +constexpr unsigned int mmDCP5_GRPH_FLIP_RATE_CNTL__VI = 0x448E; +constexpr unsigned int mmDCP5_GRPH_INTERRUPT_CONTROL__VI = 0x4417; +constexpr unsigned int mmDCP5_GRPH_INTERRUPT_STATUS__VI = 0x4416; +constexpr unsigned int mmDCP5_GRPH_LUT_10BIT_BYPASS__VI = 0x4402; +constexpr unsigned int mmDCP5_GRPH_PITCH__SI__CI = 0x4906; +constexpr unsigned int mmDCP5_GRPH_PITCH__VI = 0x4406; +constexpr unsigned int mmDCP5_GRPH_PRIMARY_SURFACE_ADDRESS__SI__CI = 0x4904; +constexpr unsigned int mmDCP5_GRPH_PRIMARY_SURFACE_ADDRESS__VI = 0x4404; +constexpr unsigned int mmDCP5_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__VI = 0x4407; +constexpr unsigned int mmDCP5_GRPH_SECONDARY_SURFACE_ADDRESS__VI = 0x4405; +constexpr unsigned int mmDCP5_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x4408; +constexpr unsigned int mmDCP5_GRPH_STEREOSYNC_FLIP__VI = 0x4497; +constexpr unsigned int mmDCP5_GRPH_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x4418; +constexpr unsigned int mmDCP5_GRPH_SURFACE_ADDRESS_INUSE__VI = 0x4413; +constexpr unsigned int mmDCP5_GRPH_SURFACE_OFFSET_X__VI = 0x4409; +constexpr unsigned int mmDCP5_GRPH_SURFACE_OFFSET_Y__VI = 0x440A; +constexpr unsigned int mmDCP5_GRPH_SWAP_CNTL__VI = 0x4403; +constexpr unsigned int mmDCP5_GRPH_UPDATE__SI__CI = 0x4911; +constexpr unsigned int mmDCP5_GRPH_UPDATE__VI = 0x4411; +constexpr unsigned int mmDCP5_GRPH_XDMA_CACHE_UNDERFLOW_DET_CNTL__VI = 0x449F; +constexpr unsigned int mmDCP5_GRPH_XDMA_CACHE_UNDERFLOW_DET_STATUS__VI = 0x44BF; +constexpr unsigned int mmDCP5_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS__VI = 0x44BD; +constexpr unsigned int mmDCP5_GRPH_XDMA_RECOVERY_SURFACE_ADDRESS_HIGH__VI = 0x44BE; +constexpr unsigned int mmDCP5_GRPH_X_END__VI = 0x440D; +constexpr unsigned int mmDCP5_GRPH_X_START__VI = 0x440B; +constexpr unsigned int mmDCP5_GRPH_Y_END__VI = 0x440E; +constexpr unsigned int mmDCP5_GRPH_Y_START__VI = 0x440C; +constexpr unsigned int mmDCP5_HW_ROTATION__VI = 0x449E; +constexpr unsigned int mmDCP5_INPUT_CSC_C11_C12__VI = 0x4436; +constexpr unsigned int mmDCP5_INPUT_CSC_C13_C14__VI = 0x4437; +constexpr unsigned int mmDCP5_INPUT_CSC_C21_C22__VI = 0x4438; +constexpr unsigned int mmDCP5_INPUT_CSC_C23_C24__VI = 0x4439; +constexpr unsigned int mmDCP5_INPUT_CSC_C31_C32__VI = 0x443A; +constexpr unsigned int mmDCP5_INPUT_CSC_C33_C34__VI = 0x443B; +constexpr unsigned int mmDCP5_INPUT_CSC_CONTROL__VI = 0x4435; +constexpr unsigned int mmDCP5_INPUT_GAMMA_CONTROL__VI = 0x4410; +constexpr unsigned int mmDCP5_KEY_CONTROL__VI = 0x4453; +constexpr unsigned int mmDCP5_KEY_RANGE_ALPHA__VI = 0x4454; +constexpr unsigned int mmDCP5_KEY_RANGE_BLUE__VI = 0x4457; +constexpr unsigned int mmDCP5_KEY_RANGE_GREEN__VI = 0x4456; +constexpr unsigned int mmDCP5_KEY_RANGE_RED__VI = 0x4455; +constexpr unsigned int mmDCP5_OUTPUT_CSC_C11_C12__VI = 0x443D; +constexpr unsigned int mmDCP5_OUTPUT_CSC_C13_C14__VI = 0x443E; +constexpr unsigned int mmDCP5_OUTPUT_CSC_C21_C22__VI = 0x443F; +constexpr unsigned int mmDCP5_OUTPUT_CSC_C23_C24__VI = 0x4440; +constexpr unsigned int mmDCP5_OUTPUT_CSC_C31_C32__VI = 0x4441; +constexpr unsigned int mmDCP5_OUTPUT_CSC_C33_C34__VI = 0x4442; +constexpr unsigned int mmDCP5_OUTPUT_CSC_CONTROL__VI = 0x443C; +constexpr unsigned int mmDCP5_OUT_CLAMP_CONTROL_B_CB__VI = 0x449D; +constexpr unsigned int mmDCP5_OUT_CLAMP_CONTROL_G_Y__VI = 0x449C; +constexpr unsigned int mmDCP5_OUT_CLAMP_CONTROL_R_CR__VI = 0x4452; +constexpr unsigned int mmDCP5_OUT_ROUND_CONTROL__VI = 0x4451; +constexpr unsigned int mmDCP5_OVLSCL_EDGE_PIXEL_CNTL__VI = 0x442C; +constexpr unsigned int mmDCP5_OVL_CONTROL1__VI = 0x441D; +constexpr unsigned int mmDCP5_OVL_CONTROL2__VI = 0x441E; +constexpr unsigned int mmDCP5_OVL_DFQ_CONTROL__VI = 0x4429; +constexpr unsigned int mmDCP5_OVL_DFQ_STATUS__VI = 0x442A; +constexpr unsigned int mmDCP5_OVL_ENABLE__VI = 0x441C; +constexpr unsigned int mmDCP5_OVL_END__VI = 0x4426; +constexpr unsigned int mmDCP5_OVL_PITCH__VI = 0x4421; +constexpr unsigned int mmDCP5_OVL_SECONDARY_SURFACE_ADDRESS__VI = 0x4492; +constexpr unsigned int mmDCP5_OVL_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x4494; +constexpr unsigned int mmDCP5_OVL_START__VI = 0x4425; +constexpr unsigned int mmDCP5_OVL_STEREOSYNC_FLIP__VI = 0x4493; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS__SI__CI = 0x4920; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS__VI = 0x4420; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS_HIGH__VI = 0x4422; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS_HIGH_INUSE__VI = 0x442B; +constexpr unsigned int mmDCP5_OVL_SURFACE_ADDRESS_INUSE__VI = 0x4428; +constexpr unsigned int mmDCP5_OVL_SURFACE_OFFSET_X__VI = 0x4423; +constexpr unsigned int mmDCP5_OVL_SURFACE_OFFSET_Y__VI = 0x4424; +constexpr unsigned int mmDCP5_OVL_SWAP_CNTL__VI = 0x441F; +constexpr unsigned int mmDCP5_OVL_UPDATE__VI = 0x4427; +constexpr unsigned int mmDCP5_PRESCALE_GRPH_CONTROL__VI = 0x442D; +constexpr unsigned int mmDCP5_PRESCALE_OVL_CONTROL__VI = 0x4431; +constexpr unsigned int mmDCP5_PRESCALE_VALUES_GRPH_B__VI = 0x4430; +constexpr unsigned int mmDCP5_PRESCALE_VALUES_GRPH_G__VI = 0x442F; +constexpr unsigned int mmDCP5_PRESCALE_VALUES_GRPH_R__VI = 0x442E; +constexpr unsigned int mmDCP5_PRESCALE_VALUES_OVL_CB__VI = 0x4432; +constexpr unsigned int mmDCP5_PRESCALE_VALUES_OVL_CR__VI = 0x4434; +constexpr unsigned int mmDCP5_PRESCALE_VALUES_OVL_Y__VI = 0x4433; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_END_CNTL1__VI = 0x44A6; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_END_CNTL2__VI = 0x44A7; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_0_1__VI = 0x44A8; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_10_11__VI = 0x44AD; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_12_13__VI = 0x44AE; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_14_15__VI = 0x44AF; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_2_3__VI = 0x44A9; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_4_5__VI = 0x44AA; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_6_7__VI = 0x44AB; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_REGION_8_9__VI = 0x44AC; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_SLOPE_CNTL__VI = 0x44A5; +constexpr unsigned int mmDCP5_REGAMMA_CNTLA_START_CNTL__VI = 0x44A4; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_END_CNTL1__VI = 0x44B2; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_END_CNTL2__VI = 0x44B3; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_0_1__VI = 0x44B4; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_10_11__VI = 0x44B9; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_12_13__VI = 0x44BA; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_14_15__VI = 0x44BB; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_2_3__VI = 0x44B5; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_4_5__VI = 0x44B6; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_6_7__VI = 0x44B7; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_REGION_8_9__VI = 0x44B8; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_SLOPE_CNTL__VI = 0x44B1; +constexpr unsigned int mmDCP5_REGAMMA_CNTLB_START_CNTL__VI = 0x44B0; +constexpr unsigned int mmDCP5_REGAMMA_CONTROL__VI = 0x44A0; +constexpr unsigned int mmDCP5_REGAMMA_LUT_DATA__VI = 0x44A2; +constexpr unsigned int mmDCP5_REGAMMA_LUT_INDEX__VI = 0x44A1; +constexpr unsigned int mmDCP5_REGAMMA_LUT_WRITE_EN_MASK__VI = 0x44A3; +constexpr unsigned int mmDCPG_TEST_DEBUG_DATA__VI = 0x02D7; +constexpr unsigned int mmDCPG_TEST_DEBUG_INDEX__VI = 0x02D6; +constexpr unsigned int mmDCP_DEBUG2__VI = 0x1A98; +constexpr unsigned int mmDCP_FP_CONVERTED_FIELD__VI = 0x1A65; +constexpr unsigned int mmDCP_GSL_CONTROL__VI = 0x1A90; +constexpr unsigned int mmDCP_RANDOM_SEEDS__VI = 0x1A61; +constexpr unsigned int mmDCP_SPATIAL_DITHER_CNTL__VI = 0x1A60; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED0__VI = 0x5A84; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED1__VI = 0x5A85; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED10__VI = 0x5A8E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED100__VI = 0x5AE8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED101__VI = 0x5AE9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED102__VI = 0x5AEA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED103__VI = 0x5AEB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED104__VI = 0x5AEC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED105__VI = 0x5AED; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED106__VI = 0x5AEE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED107__VI = 0x5AEF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED108__VI = 0x5AF0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED109__VI = 0x5AF1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED11__VI = 0x5A8F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED110__VI = 0x5AF2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED111__VI = 0x5AF3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED112__VI = 0x5AF4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED113__VI = 0x5AF5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED114__VI = 0x5AF6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED115__VI = 0x5AF7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED116__VI = 0x5AF8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED117__VI = 0x5AF9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED118__VI = 0x5AFA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED119__VI = 0x5AFB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED12__VI = 0x5A90; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED120__VI = 0x5AFC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED121__VI = 0x5AFD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED122__VI = 0x5AFE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED123__VI = 0x5AFF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED124__VI = 0x5B00; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED125__VI = 0x5B01; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED126__VI = 0x5B02; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED127__VI = 0x5B03; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED128__VI = 0x5B04; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED129__VI = 0x5B05; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED13__VI = 0x5A91; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED130__VI = 0x5B06; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED131__VI = 0x5B07; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED132__VI = 0x5B08; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED133__VI = 0x5B09; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED134__VI = 0x5B0A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED135__VI = 0x5B0B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED136__VI = 0x5B0C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED137__VI = 0x5B0D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED138__VI = 0x5B0E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED139__VI = 0x5B0F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED14__VI = 0x5A92; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED140__VI = 0x5B10; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED141__VI = 0x5B11; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED142__VI = 0x5B12; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED143__VI = 0x5B13; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED144__VI = 0x5B14; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED145__VI = 0x5B15; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED146__VI = 0x5B16; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED147__VI = 0x5B17; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED148__VI = 0x5B18; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED149__VI = 0x5B19; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED15__VI = 0x5A93; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED150__VI = 0x5B1A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED151__VI = 0x5B1B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED152__VI = 0x5B1C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED153__VI = 0x5B1D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED154__VI = 0x5B1E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED155__VI = 0x5B1F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED156__VI = 0x5B20; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED157__VI = 0x5B21; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED158__VI = 0x5B22; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED159__VI = 0x5B23; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED16__VI = 0x5A94; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED160__VI = 0x5B24; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED161__VI = 0x5B25; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED162__VI = 0x5B26; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED163__VI = 0x5B27; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED164__VI = 0x5B28; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED165__VI = 0x5B29; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED166__VI = 0x5B2A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED167__VI = 0x5B2B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED168__VI = 0x5B2C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED169__VI = 0x5B2D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED17__VI = 0x5A95; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED170__VI = 0x5B2E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED171__VI = 0x5B2F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED172__VI = 0x5B30; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED173__VI = 0x5B31; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED174__VI = 0x5B32; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED175__VI = 0x5B33; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED176__VI = 0x5B34; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED177__VI = 0x5B35; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED178__VI = 0x5B36; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED179__VI = 0x5B37; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED18__VI = 0x5A96; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED180__VI = 0x5B38; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED181__VI = 0x5B39; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED182__VI = 0x5B3A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED183__VI = 0x5B3B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED184__VI = 0x5B3C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED185__VI = 0x5B3D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED186__VI = 0x5B3E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED187__VI = 0x5B3F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED188__VI = 0x5B40; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED189__VI = 0x5B41; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED19__VI = 0x5A97; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED190__VI = 0x5B42; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED191__VI = 0x5B43; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED192__VI = 0x5B44; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED193__VI = 0x5B45; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED194__VI = 0x5B46; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED195__VI = 0x5B47; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED196__VI = 0x5B48; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED197__VI = 0x5B49; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED198__VI = 0x5B4A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED199__VI = 0x5B4B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED2__VI = 0x5A86; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED20__VI = 0x5A98; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED200__VI = 0x5B4C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED201__VI = 0x5B4D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED202__VI = 0x5B4E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED203__VI = 0x5B4F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED204__VI = 0x5B50; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED205__VI = 0x5B51; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED206__VI = 0x5B52; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED207__VI = 0x5B53; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED208__VI = 0x5B54; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED209__VI = 0x5B55; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED21__VI = 0x5A99; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED210__VI = 0x5B56; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED211__VI = 0x5B57; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED212__VI = 0x5B58; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED213__VI = 0x5B59; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED214__VI = 0x5B5A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED215__VI = 0x5B5B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED216__VI = 0x5B5C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED217__VI = 0x5B5D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED218__VI = 0x5B5E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED219__VI = 0x5B5F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED22__VI = 0x5A9A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED220__VI = 0x5B60; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED221__VI = 0x5B61; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED222__VI = 0x5B62; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED223__VI = 0x5B63; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED224__VI = 0x5B64; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED225__VI = 0x5B65; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED226__VI = 0x5B66; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED227__VI = 0x5B67; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED228__VI = 0x5B68; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED229__VI = 0x5B69; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED23__VI = 0x5A9B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED230__VI = 0x5B6A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED231__VI = 0x5B6B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED232__VI = 0x5B6C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED233__VI = 0x5B6D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED234__VI = 0x5B6E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED235__VI = 0x5B6F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED236__VI = 0x5B70; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED237__VI = 0x5B71; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED238__VI = 0x5B72; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED239__VI = 0x5B73; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED24__VI = 0x5A9C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED240__VI = 0x5B74; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED241__VI = 0x5B75; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED242__VI = 0x5B76; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED243__VI = 0x5B77; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED244__VI = 0x5B78; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED245__VI = 0x5B79; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED246__VI = 0x5B7A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED247__VI = 0x5B7B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED248__VI = 0x5B7C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED249__VI = 0x5B7D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED25__VI = 0x5A9D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED250__VI = 0x5B7E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED251__VI = 0x5B7F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED252__VI = 0x5B80; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED253__VI = 0x5B81; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED254__VI = 0x5B82; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED255__VI = 0x5B83; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED256__VI = 0x5B84; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED257__VI = 0x5B85; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED258__VI = 0x5B86; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED259__VI = 0x5B87; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED26__VI = 0x5A9E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED260__VI = 0x5B88; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED261__VI = 0x5B89; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED262__VI = 0x5B8A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED263__VI = 0x5B8B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED264__VI = 0x5B8C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED265__VI = 0x5B8D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED266__VI = 0x5B8E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED267__VI = 0x5B8F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED268__VI = 0x5B90; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED269__VI = 0x5B91; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED27__VI = 0x5A9F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED270__VI = 0x5B92; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED271__VI = 0x5B93; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED272__VI = 0x5B94; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED273__VI = 0x5B95; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED274__VI = 0x5B96; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED275__VI = 0x5B97; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED276__VI = 0x5B98; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED277__VI = 0x5B99; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED278__VI = 0x5B9A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED279__VI = 0x5B9B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED28__VI = 0x5AA0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED280__VI = 0x5B9C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED281__VI = 0x5B9D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED282__VI = 0x5B9E; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED283__VI = 0x5B9F; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED284__VI = 0x5BA0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED285__VI = 0x5BA1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED286__VI = 0x5BA2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED287__VI = 0x5BA3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED288__VI = 0x5BA4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED289__VI = 0x5BA5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED29__VI = 0x5AA1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED290__VI = 0x5BA6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED291__VI = 0x5BA7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED292__VI = 0x5BA8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED293__VI = 0x5BA9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED294__VI = 0x5BAA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED295__VI = 0x5BAB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED296__VI = 0x5BAC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED297__VI = 0x5BAD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED298__VI = 0x5BAE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED299__VI = 0x5BAF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED3__VI = 0x5A87; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED30__VI = 0x5AA2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED300__VI = 0x5BB0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED301__VI = 0x5BB1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED302__VI = 0x5BB2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED303__VI = 0x5BB3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED304__VI = 0x5BB4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED305__VI = 0x5BB5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED306__VI = 0x5BB6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED307__VI = 0x5BB7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED308__VI = 0x5BB8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED309__VI = 0x5BB9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED31__VI = 0x5AA3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED310__VI = 0x5BBA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED311__VI = 0x5BBB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED312__VI = 0x5BBC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED313__VI = 0x5BBD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED314__VI = 0x5BBE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED315__VI = 0x5BBF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED316__VI = 0x5BC0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED317__VI = 0x5BC1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED318__VI = 0x5BC2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED319__VI = 0x5BC3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED32__VI = 0x5AA4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED320__VI = 0x5BC4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED321__VI = 0x5BC5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED322__VI = 0x5BC6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED323__VI = 0x5BC7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED324__VI = 0x5BC8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED325__VI = 0x5BC9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED326__VI = 0x5BCA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED327__VI = 0x5BCB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED328__VI = 0x5BCC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED329__VI = 0x5BCD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED33__VI = 0x5AA5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED330__VI = 0x5BCE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED331__VI = 0x5BCF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED332__VI = 0x5BD0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED333__VI = 0x5BD1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED334__VI = 0x5BD2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED335__VI = 0x5BD3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED336__VI = 0x5BD4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED337__VI = 0x5BD5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED338__VI = 0x5BD6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED339__VI = 0x5BD7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED34__VI = 0x5AA6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED340__VI = 0x5BD8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED341__VI = 0x5BD9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED342__VI = 0x5BDA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED343__VI = 0x5BDB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED344__VI = 0x5BDC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED345__VI = 0x5BDD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED346__VI = 0x5BDE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED347__VI = 0x5BDF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED348__VI = 0x5BE0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED349__VI = 0x5BE1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED35__VI = 0x5AA7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED350__VI = 0x5BE2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED351__VI = 0x5BE3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED352__VI = 0x5BE4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED353__VI = 0x5BE5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED354__VI = 0x5BE6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED355__VI = 0x5BE7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED356__VI = 0x5BE8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED357__VI = 0x5BE9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED358__VI = 0x5BEA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED359__VI = 0x5BEB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED36__VI = 0x5AA8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED360__VI = 0x5BEC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED361__VI = 0x5BED; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED362__VI = 0x5BEE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED363__VI = 0x5BEF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED364__VI = 0x5BF0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED365__VI = 0x5BF1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED366__VI = 0x5BF2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED367__VI = 0x5BF3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED368__VI = 0x5BF4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED369__VI = 0x5BF5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED37__VI = 0x5AA9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED370__VI = 0x5BF6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED371__VI = 0x5BF7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED372__VI = 0x5BF8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED373__VI = 0x5BF9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED374__VI = 0x5BFA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED375__VI = 0x5BFB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED376__VI = 0x5BFC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED377__VI = 0x5BFD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED378__VI = 0x5BFE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED379__VI = 0x5BFF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED38__VI = 0x5AAA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED39__VI = 0x5AAB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED4__VI = 0x5A88; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED40__VI = 0x5AAC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED41__VI = 0x5AAD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED42__VI = 0x5AAE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED43__VI = 0x5AAF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED44__VI = 0x5AB0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED45__VI = 0x5AB1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED46__VI = 0x5AB2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED47__VI = 0x5AB3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED48__VI = 0x5AB4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED49__VI = 0x5AB5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED5__VI = 0x5A89; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED50__VI = 0x5AB6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED51__VI = 0x5AB7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED52__VI = 0x5AB8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED53__VI = 0x5AB9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED54__VI = 0x5ABA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED55__VI = 0x5ABB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED56__VI = 0x5ABC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED57__VI = 0x5ABD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED58__VI = 0x5ABE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED59__VI = 0x5ABF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED6__VI = 0x5A8A; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED60__VI = 0x5AC0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED61__VI = 0x5AC1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED62__VI = 0x5AC2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED63__VI = 0x5AC3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED64__VI = 0x5AC4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED65__VI = 0x5AC5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED66__VI = 0x5AC6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED67__VI = 0x5AC7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED68__VI = 0x5AC8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED69__VI = 0x5AC9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED7__VI = 0x5A8B; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED70__VI = 0x5ACA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED71__VI = 0x5ACB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED72__VI = 0x5ACC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED73__VI = 0x5ACD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED74__VI = 0x5ACE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED75__VI = 0x5ACF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED76__VI = 0x5AD0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED77__VI = 0x5AD1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED78__VI = 0x5AD2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED79__VI = 0x5AD3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED8__VI = 0x5A8C; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED80__VI = 0x5AD4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED81__VI = 0x5AD5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED82__VI = 0x5AD6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED83__VI = 0x5AD7; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED84__VI = 0x5AD8; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED85__VI = 0x5AD9; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED86__VI = 0x5ADA; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED87__VI = 0x5ADB; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED88__VI = 0x5ADC; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED89__VI = 0x5ADD; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED9__VI = 0x5A8D; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED90__VI = 0x5ADE; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED91__VI = 0x5ADF; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED92__VI = 0x5AE0; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED93__VI = 0x5AE1; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED94__VI = 0x5AE2; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED95__VI = 0x5AE3; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED96__VI = 0x5AE4; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED97__VI = 0x5AE5; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED98__VI = 0x5AE6; +constexpr unsigned int mmDCRX_PHY_MACRO_CNTL_RESERVED99__VI = 0x5AE7; +constexpr unsigned int mmDC_ABM1_OVERSCAN_PIXEL_VALUE__VI = 0x169B; +constexpr unsigned int mmDC_DVODATA_CONFIG__VI = 0x481A; +constexpr unsigned int mmDC_GENERICA__VI = 0x4800; +constexpr unsigned int mmDC_GENERICB__VI = 0x4801; +constexpr unsigned int mmDC_GPIO_DDC1_A__VI = 0x4869; +constexpr unsigned int mmDC_GPIO_DDC1_EN__VI = 0x486A; +constexpr unsigned int mmDC_GPIO_DDC1_MASK__VI = 0x4868; +constexpr unsigned int mmDC_GPIO_DDC1_Y__VI = 0x486B; +constexpr unsigned int mmDC_GPIO_DDC2_A__VI = 0x486D; +constexpr unsigned int mmDC_GPIO_DDC2_EN__VI = 0x486E; +constexpr unsigned int mmDC_GPIO_DDC2_MASK__VI = 0x486C; +constexpr unsigned int mmDC_GPIO_DDC2_Y__VI = 0x486F; +constexpr unsigned int mmDC_GPIO_DDC3_A__VI = 0x4871; +constexpr unsigned int mmDC_GPIO_DDC3_EN__VI = 0x4872; +constexpr unsigned int mmDC_GPIO_DDC3_MASK__VI = 0x4870; +constexpr unsigned int mmDC_GPIO_DDC3_Y__VI = 0x4873; +constexpr unsigned int mmDC_GPIO_DDC4_A__VI = 0x4875; +constexpr unsigned int mmDC_GPIO_DDC4_EN__VI = 0x4876; +constexpr unsigned int mmDC_GPIO_DDC4_MASK__VI = 0x4874; +constexpr unsigned int mmDC_GPIO_DDC4_Y__VI = 0x4877; +constexpr unsigned int mmDC_GPIO_DDC5_A__VI = 0x4879; +constexpr unsigned int mmDC_GPIO_DDC5_EN__VI = 0x487A; +constexpr unsigned int mmDC_GPIO_DDC5_MASK__VI = 0x4878; +constexpr unsigned int mmDC_GPIO_DDC5_Y__VI = 0x487B; +constexpr unsigned int mmDC_GPIO_DDC6_A__VI = 0x487D; +constexpr unsigned int mmDC_GPIO_DDC6_EN__VI = 0x487E; +constexpr unsigned int mmDC_GPIO_DDC6_MASK__VI = 0x487C; +constexpr unsigned int mmDC_GPIO_DDC6_Y__VI = 0x487F; +constexpr unsigned int mmDC_GPIO_DDCVGA_A__VI = 0x4881; +constexpr unsigned int mmDC_GPIO_DDCVGA_EN__VI = 0x4882; +constexpr unsigned int mmDC_GPIO_DDCVGA_MASK__VI = 0x4880; +constexpr unsigned int mmDC_GPIO_DDCVGA_Y__VI = 0x4883; +constexpr unsigned int mmDC_GPIO_DEBUG__VI = 0x4804; +constexpr unsigned int mmDC_GPIO_DVODATA_A__VI = 0x4865; +constexpr unsigned int mmDC_GPIO_DVODATA_EN__VI = 0x4866; +constexpr unsigned int mmDC_GPIO_DVODATA_MASK__VI = 0x4864; +constexpr unsigned int mmDC_GPIO_DVODATA_Y__VI = 0x4867; +constexpr unsigned int mmDC_GPIO_GENERIC_A__VI = 0x4861; +constexpr unsigned int mmDC_GPIO_GENERIC_EN__VI = 0x4862; +constexpr unsigned int mmDC_GPIO_GENERIC_MASK__VI = 0x4860; +constexpr unsigned int mmDC_GPIO_GENERIC_Y__VI = 0x4863; +constexpr unsigned int mmDC_GPIO_GENLK_A__VI = 0x4889; +constexpr unsigned int mmDC_GPIO_GENLK_EN__VI = 0x488A; +constexpr unsigned int mmDC_GPIO_GENLK_MASK__VI = 0x4888; +constexpr unsigned int mmDC_GPIO_GENLK_Y__VI = 0x488B; +constexpr unsigned int mmDC_GPIO_HPD_A__VI = 0x488D; +constexpr unsigned int mmDC_GPIO_HPD_EN__VI = 0x488E; +constexpr unsigned int mmDC_GPIO_HPD_MASK__VI = 0x488C; +constexpr unsigned int mmDC_GPIO_HPD_Y__VI = 0x488F; +constexpr unsigned int mmDC_GPIO_I2CPAD_A__VI = 0x4899; +constexpr unsigned int mmDC_GPIO_I2CPAD_EN__VI = 0x489A; +constexpr unsigned int mmDC_GPIO_I2CPAD_MASK__VI = 0x4898; +constexpr unsigned int mmDC_GPIO_I2CPAD_STRENGTH__VI = 0x489C; +constexpr unsigned int mmDC_GPIO_I2CPAD_Y__VI = 0x489B; +constexpr unsigned int mmDC_GPIO_PAD_STRENGTH_1__VI = 0x4894; +constexpr unsigned int mmDC_GPIO_PAD_STRENGTH_2__VI = 0x4895; +constexpr unsigned int mmDC_GPIO_PWRSEQ_A__VI = 0x4891; +constexpr unsigned int mmDC_GPIO_PWRSEQ_EN__VI = 0x4892; +constexpr unsigned int mmDC_GPIO_PWRSEQ_MASK__VI = 0x4890; +constexpr unsigned int mmDC_GPIO_PWRSEQ_Y__VI = 0x4893; +constexpr unsigned int mmDC_GPIO_SYNCA_A__VI = 0x4885; +constexpr unsigned int mmDC_GPIO_SYNCA_EN__VI = 0x4886; +constexpr unsigned int mmDC_GPIO_SYNCA_MASK__VI = 0x4884; +constexpr unsigned int mmDC_GPIO_SYNCA_Y__VI = 0x4887; +constexpr unsigned int mmDC_GPU_TIMER_READ__VI = 0x482B; +constexpr unsigned int mmDC_GPU_TIMER_READ_CNTL__VI = 0x482C; +constexpr unsigned int mmDC_GPU_TIMER_START_POSITION_P_FLIP__VI = 0x482A; +constexpr unsigned int mmDC_GPU_TIMER_START_POSITION_V_UPDATE__VI = 0x4829; +constexpr unsigned int mmDC_HPD_CONTROL__VI = 0x189A; +constexpr unsigned int mmDC_HPD_FAST_TRAIN_CNTL__VI = 0x189B; +constexpr unsigned int mmDC_HPD_INT_CONTROL__VI = 0x1899; +constexpr unsigned int mmDC_HPD_INT_STATUS__VI = 0x1898; +constexpr unsigned int mmDC_HPD_TOGGLE_FILT_CNTL__VI = 0x189C; +constexpr unsigned int mmDC_I2C_ARBITRATION__VI = 0x16D5; +constexpr unsigned int mmDC_I2C_CONTROL__VI = 0x16D4; +constexpr unsigned int mmDC_I2C_DATA__VI = 0x16EE; +constexpr unsigned int mmDC_I2C_DDC1_HW_STATUS__VI = 0x16D8; +constexpr unsigned int mmDC_I2C_DDC1_SETUP__VI = 0x16DF; +constexpr unsigned int mmDC_I2C_DDC1_SPEED__VI = 0x16DE; +constexpr unsigned int mmDC_I2C_DDC2_HW_STATUS__VI = 0x16D9; +constexpr unsigned int mmDC_I2C_DDC2_SETUP__VI = 0x16E1; +constexpr unsigned int mmDC_I2C_DDC2_SPEED__VI = 0x16E0; +constexpr unsigned int mmDC_I2C_DDC3_HW_STATUS__VI = 0x16DA; +constexpr unsigned int mmDC_I2C_DDC3_SETUP__VI = 0x16E3; +constexpr unsigned int mmDC_I2C_DDC3_SPEED__VI = 0x16E2; +constexpr unsigned int mmDC_I2C_DDC4_HW_STATUS__VI = 0x16DB; +constexpr unsigned int mmDC_I2C_DDC4_SETUP__VI = 0x16E5; +constexpr unsigned int mmDC_I2C_DDC4_SPEED__VI = 0x16E4; +constexpr unsigned int mmDC_I2C_DDC5_HW_STATUS__VI = 0x16DC; +constexpr unsigned int mmDC_I2C_DDC5_SETUP__VI = 0x16E7; +constexpr unsigned int mmDC_I2C_DDC5_SPEED__VI = 0x16E6; +constexpr unsigned int mmDC_I2C_DDC6_HW_STATUS__VI = 0x16DD; +constexpr unsigned int mmDC_I2C_DDC6_SETUP__VI = 0x16E9; +constexpr unsigned int mmDC_I2C_DDC6_SPEED__VI = 0x16E8; +constexpr unsigned int mmDC_I2C_DDCVGA_HW_STATUS__VI = 0x16EF; +constexpr unsigned int mmDC_I2C_DDCVGA_SETUP__VI = 0x16F1; +constexpr unsigned int mmDC_I2C_DDCVGA_SPEED__VI = 0x16F0; +constexpr unsigned int mmDC_I2C_EDID_DETECT_CTRL__VI = 0x16F2; +constexpr unsigned int mmDC_I2C_INTERRUPT_CONTROL__VI = 0x16D6; +constexpr unsigned int mmDC_I2C_SW_STATUS__VI = 0x16D7; +constexpr unsigned int mmDC_I2C_TRANSACTION0__VI = 0x16EA; +constexpr unsigned int mmDC_I2C_TRANSACTION1__VI = 0x16EB; +constexpr unsigned int mmDC_I2C_TRANSACTION2__VI = 0x16EC; +constexpr unsigned int mmDC_I2C_TRANSACTION3__VI = 0x16ED; +constexpr unsigned int mmDC_IP_REQUEST_CNTL__VI = 0x02D2; +constexpr unsigned int mmDC_LUT_VGA_ACCESS_ENABLE__VI = 0x1A7D; +constexpr unsigned int mmDC_MEM_GLOBAL_PWR_REQ_CNTL__VI = 0x0132; +constexpr unsigned int mmDC_MVP_LB_CONTROL__VI = 0x1AE3; +constexpr unsigned int mmDC_PAD_EXTERN_SIG__VI = 0x4802; +constexpr unsigned int mmDC_PERFMON0_PERFCOUNTER_CNTL__VI = 0x0170; +constexpr unsigned int mmDC_PERFMON0_PERFCOUNTER_STATE__VI = 0x0171; +constexpr unsigned int mmDC_PERFMON0_PERFMON_CNTL__VI = 0x0173; +constexpr unsigned int mmDC_PERFMON0_PERFMON_CNTL2__VI = 0x017A; +constexpr unsigned int mmDC_PERFMON0_PERFMON_CVALUE_INT_MISC__VI = 0x0172; +constexpr unsigned int mmDC_PERFMON0_PERFMON_CVALUE_LOW__VI = 0x0174; +constexpr unsigned int mmDC_PERFMON0_PERFMON_HI__VI = 0x0175; +constexpr unsigned int mmDC_PERFMON0_PERFMON_LOW__VI = 0x0176; +constexpr unsigned int mmDC_PERFMON0_PERFMON_TEST_DEBUG_DATA__VI = 0x0178; +constexpr unsigned int mmDC_PERFMON0_PERFMON_TEST_DEBUG_INDEX__VI = 0x0177; +constexpr unsigned int mmDC_PERFMON10_PERFCOUNTER_CNTL__VI = 0x59A0; +constexpr unsigned int mmDC_PERFMON10_PERFCOUNTER_STATE__VI = 0x59A1; +constexpr unsigned int mmDC_PERFMON10_PERFMON_CNTL__VI = 0x59A3; +constexpr unsigned int mmDC_PERFMON10_PERFMON_CNTL2__VI = 0x59AA; +constexpr unsigned int mmDC_PERFMON10_PERFMON_CVALUE_INT_MISC__VI = 0x59A2; +constexpr unsigned int mmDC_PERFMON10_PERFMON_CVALUE_LOW__VI = 0x59A4; +constexpr unsigned int mmDC_PERFMON10_PERFMON_HI__VI = 0x59A5; +constexpr unsigned int mmDC_PERFMON10_PERFMON_LOW__VI = 0x59A6; +constexpr unsigned int mmDC_PERFMON10_PERFMON_TEST_DEBUG_DATA__VI = 0x59A8; +constexpr unsigned int mmDC_PERFMON10_PERFMON_TEST_DEBUG_INDEX__VI = 0x59A7; +constexpr unsigned int mmDC_PERFMON11_PERFCOUNTER_CNTL__VI = 0x4724; +constexpr unsigned int mmDC_PERFMON11_PERFCOUNTER_STATE__VI = 0x4725; +constexpr unsigned int mmDC_PERFMON11_PERFMON_CNTL__VI = 0x4727; +constexpr unsigned int mmDC_PERFMON11_PERFMON_CNTL2__VI = 0x472E; +constexpr unsigned int mmDC_PERFMON11_PERFMON_CVALUE_INT_MISC__VI = 0x4726; +constexpr unsigned int mmDC_PERFMON11_PERFMON_CVALUE_LOW__VI = 0x4728; +constexpr unsigned int mmDC_PERFMON11_PERFMON_HI__VI = 0x4729; +constexpr unsigned int mmDC_PERFMON11_PERFMON_LOW__VI = 0x472A; +constexpr unsigned int mmDC_PERFMON11_PERFMON_TEST_DEBUG_DATA__VI = 0x472C; +constexpr unsigned int mmDC_PERFMON11_PERFMON_TEST_DEBUG_INDEX__VI = 0x472B; +constexpr unsigned int mmDC_PERFMON1_PERFCOUNTER_CNTL__VI = 0x0364; +constexpr unsigned int mmDC_PERFMON1_PERFCOUNTER_STATE__VI = 0x0365; +constexpr unsigned int mmDC_PERFMON1_PERFMON_CNTL__VI = 0x0367; +constexpr unsigned int mmDC_PERFMON1_PERFMON_CNTL2__VI = 0x036E; +constexpr unsigned int mmDC_PERFMON1_PERFMON_CVALUE_INT_MISC__VI = 0x0366; +constexpr unsigned int mmDC_PERFMON1_PERFMON_CVALUE_LOW__VI = 0x0368; +constexpr unsigned int mmDC_PERFMON1_PERFMON_HI__VI = 0x0369; +constexpr unsigned int mmDC_PERFMON1_PERFMON_LOW__VI = 0x036A; +constexpr unsigned int mmDC_PERFMON1_PERFMON_TEST_DEBUG_DATA__VI = 0x036C; +constexpr unsigned int mmDC_PERFMON1_PERFMON_TEST_DEBUG_INDEX__VI = 0x036B; +constexpr unsigned int mmDC_PERFMON2_PERFCOUNTER_CNTL__VI = 0x18C8; +constexpr unsigned int mmDC_PERFMON2_PERFCOUNTER_STATE__VI = 0x18C9; +constexpr unsigned int mmDC_PERFMON2_PERFMON_CNTL__VI = 0x18CB; +constexpr unsigned int mmDC_PERFMON2_PERFMON_CNTL2__VI = 0x18D2; +constexpr unsigned int mmDC_PERFMON2_PERFMON_CVALUE_INT_MISC__VI = 0x18CA; +constexpr unsigned int mmDC_PERFMON2_PERFMON_CVALUE_LOW__VI = 0x18CC; +constexpr unsigned int mmDC_PERFMON2_PERFMON_HI__VI = 0x18CD; +constexpr unsigned int mmDC_PERFMON2_PERFMON_LOW__VI = 0x18CE; +constexpr unsigned int mmDC_PERFMON2_PERFMON_TEST_DEBUG_DATA__VI = 0x18D0; +constexpr unsigned int mmDC_PERFMON2_PERFMON_TEST_DEBUG_INDEX__VI = 0x18CF; +constexpr unsigned int mmDC_PERFMON3_PERFCOUNTER_CNTL__VI = 0x1B24; +constexpr unsigned int mmDC_PERFMON3_PERFCOUNTER_STATE__VI = 0x1B25; +constexpr unsigned int mmDC_PERFMON3_PERFMON_CNTL__VI = 0x1B27; +constexpr unsigned int mmDC_PERFMON3_PERFMON_CNTL2__VI = 0x1B2E; +constexpr unsigned int mmDC_PERFMON3_PERFMON_CVALUE_INT_MISC__VI = 0x1B26; +constexpr unsigned int mmDC_PERFMON3_PERFMON_CVALUE_LOW__VI = 0x1B28; +constexpr unsigned int mmDC_PERFMON3_PERFMON_HI__VI = 0x1B29; +constexpr unsigned int mmDC_PERFMON3_PERFMON_LOW__VI = 0x1B2A; +constexpr unsigned int mmDC_PERFMON3_PERFMON_TEST_DEBUG_DATA__VI = 0x1B2C; +constexpr unsigned int mmDC_PERFMON3_PERFMON_TEST_DEBUG_INDEX__VI = 0x1B2B; +constexpr unsigned int mmDC_PERFMON4_PERFCOUNTER_CNTL__VI = 0x1D24; +constexpr unsigned int mmDC_PERFMON4_PERFCOUNTER_STATE__VI = 0x1D25; +constexpr unsigned int mmDC_PERFMON4_PERFMON_CNTL__VI = 0x1D27; +constexpr unsigned int mmDC_PERFMON4_PERFMON_CNTL2__VI = 0x1D2E; +constexpr unsigned int mmDC_PERFMON4_PERFMON_CVALUE_INT_MISC__VI = 0x1D26; +constexpr unsigned int mmDC_PERFMON4_PERFMON_CVALUE_LOW__VI = 0x1D28; +constexpr unsigned int mmDC_PERFMON4_PERFMON_HI__VI = 0x1D29; +constexpr unsigned int mmDC_PERFMON4_PERFMON_LOW__VI = 0x1D2A; +constexpr unsigned int mmDC_PERFMON4_PERFMON_TEST_DEBUG_DATA__VI = 0x1D2C; +constexpr unsigned int mmDC_PERFMON4_PERFMON_TEST_DEBUG_INDEX__VI = 0x1D2B; +constexpr unsigned int mmDC_PERFMON5_PERFCOUNTER_CNTL__VI = 0x1F24; +constexpr unsigned int mmDC_PERFMON5_PERFCOUNTER_STATE__VI = 0x1F25; +constexpr unsigned int mmDC_PERFMON5_PERFMON_CNTL__VI = 0x1F27; +constexpr unsigned int mmDC_PERFMON5_PERFMON_CNTL2__VI = 0x1F2E; +constexpr unsigned int mmDC_PERFMON5_PERFMON_CVALUE_INT_MISC__VI = 0x1F26; +constexpr unsigned int mmDC_PERFMON5_PERFMON_CVALUE_LOW__VI = 0x1F28; +constexpr unsigned int mmDC_PERFMON5_PERFMON_HI__VI = 0x1F29; +constexpr unsigned int mmDC_PERFMON5_PERFMON_LOW__VI = 0x1F2A; +constexpr unsigned int mmDC_PERFMON5_PERFMON_TEST_DEBUG_DATA__VI = 0x1F2C; +constexpr unsigned int mmDC_PERFMON5_PERFMON_TEST_DEBUG_INDEX__VI = 0x1F2B; +constexpr unsigned int mmDC_PERFMON6_PERFCOUNTER_CNTL__VI = 0x4124; +constexpr unsigned int mmDC_PERFMON6_PERFCOUNTER_STATE__VI = 0x4125; +constexpr unsigned int mmDC_PERFMON6_PERFMON_CNTL__VI = 0x4127; +constexpr unsigned int mmDC_PERFMON6_PERFMON_CNTL2__VI = 0x412E; +constexpr unsigned int mmDC_PERFMON6_PERFMON_CVALUE_INT_MISC__VI = 0x4126; +constexpr unsigned int mmDC_PERFMON6_PERFMON_CVALUE_LOW__VI = 0x4128; +constexpr unsigned int mmDC_PERFMON6_PERFMON_HI__VI = 0x4129; +constexpr unsigned int mmDC_PERFMON6_PERFMON_LOW__VI = 0x412A; +constexpr unsigned int mmDC_PERFMON6_PERFMON_TEST_DEBUG_DATA__VI = 0x412C; +constexpr unsigned int mmDC_PERFMON6_PERFMON_TEST_DEBUG_INDEX__VI = 0x412B; +constexpr unsigned int mmDC_PERFMON7_PERFCOUNTER_CNTL__VI = 0x4324; +constexpr unsigned int mmDC_PERFMON7_PERFCOUNTER_STATE__VI = 0x4325; +constexpr unsigned int mmDC_PERFMON7_PERFMON_CNTL__VI = 0x4327; +constexpr unsigned int mmDC_PERFMON7_PERFMON_CNTL2__VI = 0x432E; +constexpr unsigned int mmDC_PERFMON7_PERFMON_CVALUE_INT_MISC__VI = 0x4326; +constexpr unsigned int mmDC_PERFMON7_PERFMON_CVALUE_LOW__VI = 0x4328; +constexpr unsigned int mmDC_PERFMON7_PERFMON_HI__VI = 0x4329; +constexpr unsigned int mmDC_PERFMON7_PERFMON_LOW__VI = 0x432A; +constexpr unsigned int mmDC_PERFMON7_PERFMON_TEST_DEBUG_DATA__VI = 0x432C; +constexpr unsigned int mmDC_PERFMON7_PERFMON_TEST_DEBUG_INDEX__VI = 0x432B; +constexpr unsigned int mmDC_PERFMON8_PERFCOUNTER_CNTL__VI = 0x4524; +constexpr unsigned int mmDC_PERFMON8_PERFCOUNTER_STATE__VI = 0x4525; +constexpr unsigned int mmDC_PERFMON8_PERFMON_CNTL__VI = 0x4527; +constexpr unsigned int mmDC_PERFMON8_PERFMON_CNTL2__VI = 0x452E; +constexpr unsigned int mmDC_PERFMON8_PERFMON_CVALUE_INT_MISC__VI = 0x4526; +constexpr unsigned int mmDC_PERFMON8_PERFMON_CVALUE_LOW__VI = 0x4528; +constexpr unsigned int mmDC_PERFMON8_PERFMON_HI__VI = 0x4529; +constexpr unsigned int mmDC_PERFMON8_PERFMON_LOW__VI = 0x452A; +constexpr unsigned int mmDC_PERFMON8_PERFMON_TEST_DEBUG_DATA__VI = 0x452C; +constexpr unsigned int mmDC_PERFMON8_PERFMON_TEST_DEBUG_INDEX__VI = 0x452B; +constexpr unsigned int mmDC_PERFMON9_PERFCOUNTER_CNTL__VI = 0x5F68; +constexpr unsigned int mmDC_PERFMON9_PERFCOUNTER_STATE__VI = 0x5F69; +constexpr unsigned int mmDC_PERFMON9_PERFMON_CNTL__VI = 0x5F6B; +constexpr unsigned int mmDC_PERFMON9_PERFMON_CNTL2__VI = 0x5F72; +constexpr unsigned int mmDC_PERFMON9_PERFMON_CVALUE_INT_MISC__VI = 0x5F6A; +constexpr unsigned int mmDC_PERFMON9_PERFMON_CVALUE_LOW__VI = 0x5F6C; +constexpr unsigned int mmDC_PERFMON9_PERFMON_HI__VI = 0x5F6D; +constexpr unsigned int mmDC_PERFMON9_PERFMON_LOW__VI = 0x5F6E; +constexpr unsigned int mmDC_PERFMON9_PERFMON_TEST_DEBUG_DATA__VI = 0x5F70; +constexpr unsigned int mmDC_PERFMON9_PERFMON_TEST_DEBUG_INDEX__VI = 0x5F6F; +constexpr unsigned int mmDC_PGCNTL_STATUS_REG__VI = 0x02D5; +constexpr unsigned int mmDC_PGFSM_CONFIG_REG__VI = 0x02D3; +constexpr unsigned int mmDC_PGFSM_WRITE_REG__VI = 0x02D4; +constexpr unsigned int mmDC_PINSTRAPS__VI = 0x4818; +constexpr unsigned int mmDC_REF_CLK_CNTL__VI = 0x4803; +constexpr unsigned int mmDC_TEST_DEBUG_DATA__VI = 0x157D; +constexpr unsigned int mmDC_TEST_DEBUG_INDEX__VI = 0x157C; +constexpr unsigned int mmDEGAMMA_CONTROL__VI = 0x1A58; +constexpr unsigned int mmDENORM_CLAMP_CONTROL__VI = 0x46C3; +constexpr unsigned int mmDENORM_CLAMP_RANGE_B_CB__VI = 0x46C6; +constexpr unsigned int mmDENORM_CLAMP_RANGE_G_Y__VI = 0x46C5; +constexpr unsigned int mmDENORM_CLAMP_RANGE_R_CR__VI = 0x46C4; +constexpr unsigned int mmDENORM_CONTROL__VI = 0x1A50; +constexpr unsigned int mmDENTIST_DISPCLK_CNTL__VI = 0x0124; +constexpr unsigned int mmDIG0_AFMT_60958_0__VI = 0x4A38; +constexpr unsigned int mmDIG0_AFMT_60958_1__VI = 0x4A39; +constexpr unsigned int mmDIG0_AFMT_60958_2__VI = 0x4A3F; +constexpr unsigned int mmDIG0_AFMT_AUDIO_CRC_CONTROL__VI = 0x4A3A; +constexpr unsigned int mmDIG0_AFMT_AUDIO_CRC_RESULT__VI = 0x4A40; +constexpr unsigned int mmDIG0_AFMT_AUDIO_DBG_DTO_CNTL__VI = 0x4A46; +constexpr unsigned int mmDIG0_AFMT_AUDIO_INFO0__VI = 0x4A36; +constexpr unsigned int mmDIG0_AFMT_AUDIO_INFO1__VI = 0x4A37; +constexpr unsigned int mmDIG0_AFMT_AUDIO_PACKET_CONTROL__VI = 0x4A42; +constexpr unsigned int mmDIG0_AFMT_AUDIO_PACKET_CONTROL2__VI = 0x4A14; +constexpr unsigned int mmDIG0_AFMT_AUDIO_SRC_CONTROL__VI = 0x4A45; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO0__VI = 0x4A1E; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO1__VI = 0x4A1F; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO2__VI = 0x4A20; +constexpr unsigned int mmDIG0_AFMT_AVI_INFO3__VI = 0x4A21; +constexpr unsigned int mmDIG0_AFMT_GENERIC_0__VI = 0x4A25; +constexpr unsigned int mmDIG0_AFMT_GENERIC_1__VI = 0x4A26; +constexpr unsigned int mmDIG0_AFMT_GENERIC_2__VI = 0x4A27; +constexpr unsigned int mmDIG0_AFMT_GENERIC_3__VI = 0x4A28; +constexpr unsigned int mmDIG0_AFMT_GENERIC_4__VI = 0x4A29; +constexpr unsigned int mmDIG0_AFMT_GENERIC_5__VI = 0x4A2A; +constexpr unsigned int mmDIG0_AFMT_GENERIC_6__VI = 0x4A2B; +constexpr unsigned int mmDIG0_AFMT_GENERIC_7__VI = 0x4A2C; +constexpr unsigned int mmDIG0_AFMT_GENERIC_HDR__VI = 0x4A24; +constexpr unsigned int mmDIG0_AFMT_INFOFRAME_CONTROL0__VI = 0x4A44; +constexpr unsigned int mmDIG0_AFMT_ISRC1_0__VI = 0x4A15; +constexpr unsigned int mmDIG0_AFMT_ISRC1_1__VI = 0x4A16; +constexpr unsigned int mmDIG0_AFMT_ISRC1_2__VI = 0x4A17; +constexpr unsigned int mmDIG0_AFMT_ISRC1_3__VI = 0x4A18; +constexpr unsigned int mmDIG0_AFMT_ISRC1_4__VI = 0x4A19; +constexpr unsigned int mmDIG0_AFMT_ISRC2_0__VI = 0x4A1A; +constexpr unsigned int mmDIG0_AFMT_ISRC2_1__VI = 0x4A1B; +constexpr unsigned int mmDIG0_AFMT_ISRC2_2__VI = 0x4A1C; +constexpr unsigned int mmDIG0_AFMT_ISRC2_3__VI = 0x4A1D; +constexpr unsigned int mmDIG0_AFMT_MPEG_INFO0__VI = 0x4A22; +constexpr unsigned int mmDIG0_AFMT_MPEG_INFO1__VI = 0x4A23; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL0__VI = 0x4A3B; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL1__VI = 0x4A3C; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL2__VI = 0x4A3D; +constexpr unsigned int mmDIG0_AFMT_RAMP_CONTROL3__VI = 0x4A3E; +constexpr unsigned int mmDIG0_AFMT_STATUS__VI = 0x4A41; +constexpr unsigned int mmDIG0_AFMT_VBI_PACKET_CONTROL__VI = 0x4A43; +constexpr unsigned int mmDIG0_DIG_BE_CNTL__VI = 0x4A47; +constexpr unsigned int mmDIG0_DIG_BE_EN_CNTL__VI = 0x4A48; +constexpr unsigned int mmDIG0_DIG_CLOCK_PATTERN__VI = 0x4A03; +constexpr unsigned int mmDIG0_DIG_DISPCLK_SWITCH_CNTL__VI = 0x4A07; +constexpr unsigned int mmDIG0_DIG_DISPCLK_SWITCH_STATUS__VI = 0x4A08; +constexpr unsigned int mmDIG0_DIG_FE_CNTL__VI = 0x4A00; +constexpr unsigned int mmDIG0_DIG_FE_TEST_DEBUG_DATA__VI = 0x4A7D; +constexpr unsigned int mmDIG0_DIG_FE_TEST_DEBUG_INDEX__VI = 0x4A7C; +constexpr unsigned int mmDIG0_DIG_FIFO_STATUS__VI = 0x4A06; +constexpr unsigned int mmDIG0_DIG_LANE_ENABLE__VI = 0x4A79; +constexpr unsigned int mmDIG0_DIG_OUTPUT_CRC_CNTL__VI = 0x4A01; +constexpr unsigned int mmDIG0_DIG_OUTPUT_CRC_RESULT__VI = 0x4A02; +constexpr unsigned int mmDIG0_DIG_RANDOM_PATTERN_SEED__VI = 0x4A05; +constexpr unsigned int mmDIG0_DIG_TEST_DEBUG_DATA__VI = 0x4A7B; +constexpr unsigned int mmDIG0_DIG_TEST_DEBUG_INDEX__VI = 0x4A7A; +constexpr unsigned int mmDIG0_DIG_TEST_PATTERN__VI = 0x4A04; +constexpr unsigned int mmDIG0_HDMI_ACR_32_0__VI = 0x4A2E; +constexpr unsigned int mmDIG0_HDMI_ACR_32_1__VI = 0x4A2F; +constexpr unsigned int mmDIG0_HDMI_ACR_44_0__VI = 0x4A30; +constexpr unsigned int mmDIG0_HDMI_ACR_44_1__VI = 0x4A31; +constexpr unsigned int mmDIG0_HDMI_ACR_48_0__VI = 0x4A32; +constexpr unsigned int mmDIG0_HDMI_ACR_48_1__VI = 0x4A33; +constexpr unsigned int mmDIG0_HDMI_ACR_PACKET_CONTROL__VI = 0x4A0C; +constexpr unsigned int mmDIG0_HDMI_ACR_STATUS_0__VI = 0x4A34; +constexpr unsigned int mmDIG0_HDMI_ACR_STATUS_1__VI = 0x4A35; +constexpr unsigned int mmDIG0_HDMI_AUDIO_PACKET_CONTROL__VI = 0x4A0B; +constexpr unsigned int mmDIG0_HDMI_CONTROL__VI = 0x4A09; +constexpr unsigned int mmDIG0_HDMI_GC__VI = 0x4A13; +constexpr unsigned int mmDIG0_HDMI_GENERIC_PACKET_CONTROL0__VI = 0x4A10; +constexpr unsigned int mmDIG0_HDMI_GENERIC_PACKET_CONTROL1__VI = 0x4A2D; +constexpr unsigned int mmDIG0_HDMI_INFOFRAME_CONTROL0__VI = 0x4A0E; +constexpr unsigned int mmDIG0_HDMI_INFOFRAME_CONTROL1__VI = 0x4A0F; +constexpr unsigned int mmDIG0_HDMI_STATUS__VI = 0x4A0A; +constexpr unsigned int mmDIG0_HDMI_VBI_PACKET_CONTROL__VI = 0x4A0D; +constexpr unsigned int mmDIG0_LVDS_DATA_CNTL__VI = 0x4A78; +constexpr unsigned int mmDIG0_TMDS_CNTL__VI = 0x4A6B; +constexpr unsigned int mmDIG0_TMDS_CONTROL0_FEEDBACK__VI = 0x4A6D; +constexpr unsigned int mmDIG0_TMDS_CONTROL_CHAR__VI = 0x4A6C; +constexpr unsigned int mmDIG0_TMDS_CTL0_1_GEN_CNTL__VI = 0x4A75; +constexpr unsigned int mmDIG0_TMDS_CTL2_3_GEN_CNTL__VI = 0x4A76; +constexpr unsigned int mmDIG0_TMDS_CTL_BITS__VI = 0x4A72; +constexpr unsigned int mmDIG0_TMDS_DCBALANCER_CONTROL__VI = 0x4A73; +constexpr unsigned int mmDIG0_TMDS_DEBUG__VI = 0x4A71; +constexpr unsigned int mmDIG0_TMDS_STEREOSYNC_CTL_SEL__VI = 0x4A6E; +constexpr unsigned int mmDIG0_TMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x4A6F; +constexpr unsigned int mmDIG0_TMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x4A70; +constexpr unsigned int mmDIG1_AFMT_60958_0__VI = 0x4B38; +constexpr unsigned int mmDIG1_AFMT_60958_1__VI = 0x4B39; +constexpr unsigned int mmDIG1_AFMT_60958_2__VI = 0x4B3F; +constexpr unsigned int mmDIG1_AFMT_AUDIO_CRC_CONTROL__VI = 0x4B3A; +constexpr unsigned int mmDIG1_AFMT_AUDIO_CRC_RESULT__VI = 0x4B40; +constexpr unsigned int mmDIG1_AFMT_AUDIO_DBG_DTO_CNTL__VI = 0x4B46; +constexpr unsigned int mmDIG1_AFMT_AUDIO_INFO0__VI = 0x4B36; +constexpr unsigned int mmDIG1_AFMT_AUDIO_INFO1__VI = 0x4B37; +constexpr unsigned int mmDIG1_AFMT_AUDIO_PACKET_CONTROL__VI = 0x4B42; +constexpr unsigned int mmDIG1_AFMT_AUDIO_PACKET_CONTROL2__VI = 0x4B14; +constexpr unsigned int mmDIG1_AFMT_AUDIO_SRC_CONTROL__VI = 0x4B45; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO0__VI = 0x4B1E; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO1__VI = 0x4B1F; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO2__VI = 0x4B20; +constexpr unsigned int mmDIG1_AFMT_AVI_INFO3__VI = 0x4B21; +constexpr unsigned int mmDIG1_AFMT_GENERIC_0__VI = 0x4B25; +constexpr unsigned int mmDIG1_AFMT_GENERIC_1__VI = 0x4B26; +constexpr unsigned int mmDIG1_AFMT_GENERIC_2__VI = 0x4B27; +constexpr unsigned int mmDIG1_AFMT_GENERIC_3__VI = 0x4B28; +constexpr unsigned int mmDIG1_AFMT_GENERIC_4__VI = 0x4B29; +constexpr unsigned int mmDIG1_AFMT_GENERIC_5__VI = 0x4B2A; +constexpr unsigned int mmDIG1_AFMT_GENERIC_6__VI = 0x4B2B; +constexpr unsigned int mmDIG1_AFMT_GENERIC_7__VI = 0x4B2C; +constexpr unsigned int mmDIG1_AFMT_GENERIC_HDR__VI = 0x4B24; +constexpr unsigned int mmDIG1_AFMT_INFOFRAME_CONTROL0__VI = 0x4B44; +constexpr unsigned int mmDIG1_AFMT_ISRC1_0__VI = 0x4B15; +constexpr unsigned int mmDIG1_AFMT_ISRC1_1__VI = 0x4B16; +constexpr unsigned int mmDIG1_AFMT_ISRC1_2__VI = 0x4B17; +constexpr unsigned int mmDIG1_AFMT_ISRC1_3__VI = 0x4B18; +constexpr unsigned int mmDIG1_AFMT_ISRC1_4__VI = 0x4B19; +constexpr unsigned int mmDIG1_AFMT_ISRC2_0__VI = 0x4B1A; +constexpr unsigned int mmDIG1_AFMT_ISRC2_1__VI = 0x4B1B; +constexpr unsigned int mmDIG1_AFMT_ISRC2_2__VI = 0x4B1C; +constexpr unsigned int mmDIG1_AFMT_ISRC2_3__VI = 0x4B1D; +constexpr unsigned int mmDIG1_AFMT_MPEG_INFO0__VI = 0x4B22; +constexpr unsigned int mmDIG1_AFMT_MPEG_INFO1__VI = 0x4B23; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL0__VI = 0x4B3B; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL1__VI = 0x4B3C; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL2__VI = 0x4B3D; +constexpr unsigned int mmDIG1_AFMT_RAMP_CONTROL3__VI = 0x4B3E; +constexpr unsigned int mmDIG1_AFMT_STATUS__VI = 0x4B41; +constexpr unsigned int mmDIG1_AFMT_VBI_PACKET_CONTROL__VI = 0x4B43; +constexpr unsigned int mmDIG1_DIG_BE_CNTL__VI = 0x4B47; +constexpr unsigned int mmDIG1_DIG_BE_EN_CNTL__VI = 0x4B48; +constexpr unsigned int mmDIG1_DIG_CLOCK_PATTERN__VI = 0x4B03; +constexpr unsigned int mmDIG1_DIG_DISPCLK_SWITCH_CNTL__VI = 0x4B07; +constexpr unsigned int mmDIG1_DIG_DISPCLK_SWITCH_STATUS__VI = 0x4B08; +constexpr unsigned int mmDIG1_DIG_FE_CNTL__VI = 0x4B00; +constexpr unsigned int mmDIG1_DIG_FE_TEST_DEBUG_DATA__VI = 0x4B7D; +constexpr unsigned int mmDIG1_DIG_FE_TEST_DEBUG_INDEX__VI = 0x4B7C; +constexpr unsigned int mmDIG1_DIG_FIFO_STATUS__VI = 0x4B06; +constexpr unsigned int mmDIG1_DIG_LANE_ENABLE__VI = 0x4B79; +constexpr unsigned int mmDIG1_DIG_OUTPUT_CRC_CNTL__VI = 0x4B01; +constexpr unsigned int mmDIG1_DIG_OUTPUT_CRC_RESULT__VI = 0x4B02; +constexpr unsigned int mmDIG1_DIG_RANDOM_PATTERN_SEED__VI = 0x4B05; +constexpr unsigned int mmDIG1_DIG_TEST_DEBUG_DATA__VI = 0x4B7B; +constexpr unsigned int mmDIG1_DIG_TEST_DEBUG_INDEX__VI = 0x4B7A; +constexpr unsigned int mmDIG1_DIG_TEST_PATTERN__VI = 0x4B04; +constexpr unsigned int mmDIG1_HDMI_ACR_32_0__VI = 0x4B2E; +constexpr unsigned int mmDIG1_HDMI_ACR_32_1__VI = 0x4B2F; +constexpr unsigned int mmDIG1_HDMI_ACR_44_0__VI = 0x4B30; +constexpr unsigned int mmDIG1_HDMI_ACR_44_1__VI = 0x4B31; +constexpr unsigned int mmDIG1_HDMI_ACR_48_0__VI = 0x4B32; +constexpr unsigned int mmDIG1_HDMI_ACR_48_1__VI = 0x4B33; +constexpr unsigned int mmDIG1_HDMI_ACR_PACKET_CONTROL__VI = 0x4B0C; +constexpr unsigned int mmDIG1_HDMI_ACR_STATUS_0__VI = 0x4B34; +constexpr unsigned int mmDIG1_HDMI_ACR_STATUS_1__VI = 0x4B35; +constexpr unsigned int mmDIG1_HDMI_AUDIO_PACKET_CONTROL__VI = 0x4B0B; +constexpr unsigned int mmDIG1_HDMI_CONTROL__VI = 0x4B09; +constexpr unsigned int mmDIG1_HDMI_GC__VI = 0x4B13; +constexpr unsigned int mmDIG1_HDMI_GENERIC_PACKET_CONTROL0__VI = 0x4B10; +constexpr unsigned int mmDIG1_HDMI_GENERIC_PACKET_CONTROL1__VI = 0x4B2D; +constexpr unsigned int mmDIG1_HDMI_INFOFRAME_CONTROL0__VI = 0x4B0E; +constexpr unsigned int mmDIG1_HDMI_INFOFRAME_CONTROL1__VI = 0x4B0F; +constexpr unsigned int mmDIG1_HDMI_STATUS__VI = 0x4B0A; +constexpr unsigned int mmDIG1_HDMI_VBI_PACKET_CONTROL__VI = 0x4B0D; +constexpr unsigned int mmDIG1_LVDS_DATA_CNTL__VI = 0x4B78; +constexpr unsigned int mmDIG1_TMDS_CNTL__VI = 0x4B6B; +constexpr unsigned int mmDIG1_TMDS_CONTROL0_FEEDBACK__VI = 0x4B6D; +constexpr unsigned int mmDIG1_TMDS_CONTROL_CHAR__VI = 0x4B6C; +constexpr unsigned int mmDIG1_TMDS_CTL0_1_GEN_CNTL__VI = 0x4B75; +constexpr unsigned int mmDIG1_TMDS_CTL2_3_GEN_CNTL__VI = 0x4B76; +constexpr unsigned int mmDIG1_TMDS_CTL_BITS__VI = 0x4B72; +constexpr unsigned int mmDIG1_TMDS_DCBALANCER_CONTROL__VI = 0x4B73; +constexpr unsigned int mmDIG1_TMDS_DEBUG__VI = 0x4B71; +constexpr unsigned int mmDIG1_TMDS_STEREOSYNC_CTL_SEL__VI = 0x4B6E; +constexpr unsigned int mmDIG1_TMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x4B6F; +constexpr unsigned int mmDIG1_TMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x4B70; +constexpr unsigned int mmDIG2_AFMT_60958_0__VI = 0x4C38; +constexpr unsigned int mmDIG2_AFMT_60958_1__VI = 0x4C39; +constexpr unsigned int mmDIG2_AFMT_60958_2__VI = 0x4C3F; +constexpr unsigned int mmDIG2_AFMT_AUDIO_CRC_CONTROL__VI = 0x4C3A; +constexpr unsigned int mmDIG2_AFMT_AUDIO_CRC_RESULT__VI = 0x4C40; +constexpr unsigned int mmDIG2_AFMT_AUDIO_DBG_DTO_CNTL__VI = 0x4C46; +constexpr unsigned int mmDIG2_AFMT_AUDIO_INFO0__VI = 0x4C36; +constexpr unsigned int mmDIG2_AFMT_AUDIO_INFO1__VI = 0x4C37; +constexpr unsigned int mmDIG2_AFMT_AUDIO_PACKET_CONTROL__VI = 0x4C42; +constexpr unsigned int mmDIG2_AFMT_AUDIO_PACKET_CONTROL2__VI = 0x4C14; +constexpr unsigned int mmDIG2_AFMT_AUDIO_SRC_CONTROL__VI = 0x4C45; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO0__VI = 0x4C1E; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO1__VI = 0x4C1F; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO2__VI = 0x4C20; +constexpr unsigned int mmDIG2_AFMT_AVI_INFO3__VI = 0x4C21; +constexpr unsigned int mmDIG2_AFMT_GENERIC_0__VI = 0x4C25; +constexpr unsigned int mmDIG2_AFMT_GENERIC_1__VI = 0x4C26; +constexpr unsigned int mmDIG2_AFMT_GENERIC_2__VI = 0x4C27; +constexpr unsigned int mmDIG2_AFMT_GENERIC_3__VI = 0x4C28; +constexpr unsigned int mmDIG2_AFMT_GENERIC_4__VI = 0x4C29; +constexpr unsigned int mmDIG2_AFMT_GENERIC_5__VI = 0x4C2A; +constexpr unsigned int mmDIG2_AFMT_GENERIC_6__VI = 0x4C2B; +constexpr unsigned int mmDIG2_AFMT_GENERIC_7__VI = 0x4C2C; +constexpr unsigned int mmDIG2_AFMT_GENERIC_HDR__VI = 0x4C24; +constexpr unsigned int mmDIG2_AFMT_INFOFRAME_CONTROL0__VI = 0x4C44; +constexpr unsigned int mmDIG2_AFMT_ISRC1_0__VI = 0x4C15; +constexpr unsigned int mmDIG2_AFMT_ISRC1_1__VI = 0x4C16; +constexpr unsigned int mmDIG2_AFMT_ISRC1_2__VI = 0x4C17; +constexpr unsigned int mmDIG2_AFMT_ISRC1_3__VI = 0x4C18; +constexpr unsigned int mmDIG2_AFMT_ISRC1_4__VI = 0x4C19; +constexpr unsigned int mmDIG2_AFMT_ISRC2_0__VI = 0x4C1A; +constexpr unsigned int mmDIG2_AFMT_ISRC2_1__VI = 0x4C1B; +constexpr unsigned int mmDIG2_AFMT_ISRC2_2__VI = 0x4C1C; +constexpr unsigned int mmDIG2_AFMT_ISRC2_3__VI = 0x4C1D; +constexpr unsigned int mmDIG2_AFMT_MPEG_INFO0__VI = 0x4C22; +constexpr unsigned int mmDIG2_AFMT_MPEG_INFO1__VI = 0x4C23; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL0__VI = 0x4C3B; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL1__VI = 0x4C3C; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL2__VI = 0x4C3D; +constexpr unsigned int mmDIG2_AFMT_RAMP_CONTROL3__VI = 0x4C3E; +constexpr unsigned int mmDIG2_AFMT_STATUS__VI = 0x4C41; +constexpr unsigned int mmDIG2_AFMT_VBI_PACKET_CONTROL__VI = 0x4C43; +constexpr unsigned int mmDIG2_DIG_BE_CNTL__VI = 0x4C47; +constexpr unsigned int mmDIG2_DIG_BE_EN_CNTL__VI = 0x4C48; +constexpr unsigned int mmDIG2_DIG_CLOCK_PATTERN__VI = 0x4C03; +constexpr unsigned int mmDIG2_DIG_DISPCLK_SWITCH_CNTL__VI = 0x4C07; +constexpr unsigned int mmDIG2_DIG_DISPCLK_SWITCH_STATUS__VI = 0x4C08; +constexpr unsigned int mmDIG2_DIG_FE_CNTL__VI = 0x4C00; +constexpr unsigned int mmDIG2_DIG_FE_TEST_DEBUG_DATA__VI = 0x4C7D; +constexpr unsigned int mmDIG2_DIG_FE_TEST_DEBUG_INDEX__VI = 0x4C7C; +constexpr unsigned int mmDIG2_DIG_FIFO_STATUS__VI = 0x4C06; +constexpr unsigned int mmDIG2_DIG_LANE_ENABLE__VI = 0x4C79; +constexpr unsigned int mmDIG2_DIG_OUTPUT_CRC_CNTL__VI = 0x4C01; +constexpr unsigned int mmDIG2_DIG_OUTPUT_CRC_RESULT__VI = 0x4C02; +constexpr unsigned int mmDIG2_DIG_RANDOM_PATTERN_SEED__VI = 0x4C05; +constexpr unsigned int mmDIG2_DIG_TEST_DEBUG_DATA__VI = 0x4C7B; +constexpr unsigned int mmDIG2_DIG_TEST_DEBUG_INDEX__VI = 0x4C7A; +constexpr unsigned int mmDIG2_DIG_TEST_PATTERN__VI = 0x4C04; +constexpr unsigned int mmDIG2_HDMI_ACR_32_0__VI = 0x4C2E; +constexpr unsigned int mmDIG2_HDMI_ACR_32_1__VI = 0x4C2F; +constexpr unsigned int mmDIG2_HDMI_ACR_44_0__VI = 0x4C30; +constexpr unsigned int mmDIG2_HDMI_ACR_44_1__VI = 0x4C31; +constexpr unsigned int mmDIG2_HDMI_ACR_48_0__VI = 0x4C32; +constexpr unsigned int mmDIG2_HDMI_ACR_48_1__VI = 0x4C33; +constexpr unsigned int mmDIG2_HDMI_ACR_PACKET_CONTROL__VI = 0x4C0C; +constexpr unsigned int mmDIG2_HDMI_ACR_STATUS_0__VI = 0x4C34; +constexpr unsigned int mmDIG2_HDMI_ACR_STATUS_1__VI = 0x4C35; +constexpr unsigned int mmDIG2_HDMI_AUDIO_PACKET_CONTROL__VI = 0x4C0B; +constexpr unsigned int mmDIG2_HDMI_CONTROL__VI = 0x4C09; +constexpr unsigned int mmDIG2_HDMI_GC__VI = 0x4C13; +constexpr unsigned int mmDIG2_HDMI_GENERIC_PACKET_CONTROL0__VI = 0x4C10; +constexpr unsigned int mmDIG2_HDMI_GENERIC_PACKET_CONTROL1__VI = 0x4C2D; +constexpr unsigned int mmDIG2_HDMI_INFOFRAME_CONTROL0__VI = 0x4C0E; +constexpr unsigned int mmDIG2_HDMI_INFOFRAME_CONTROL1__VI = 0x4C0F; +constexpr unsigned int mmDIG2_HDMI_STATUS__VI = 0x4C0A; +constexpr unsigned int mmDIG2_HDMI_VBI_PACKET_CONTROL__VI = 0x4C0D; +constexpr unsigned int mmDIG2_LVDS_DATA_CNTL__VI = 0x4C78; +constexpr unsigned int mmDIG2_TMDS_CNTL__VI = 0x4C6B; +constexpr unsigned int mmDIG2_TMDS_CONTROL0_FEEDBACK__VI = 0x4C6D; +constexpr unsigned int mmDIG2_TMDS_CONTROL_CHAR__VI = 0x4C6C; +constexpr unsigned int mmDIG2_TMDS_CTL0_1_GEN_CNTL__VI = 0x4C75; +constexpr unsigned int mmDIG2_TMDS_CTL2_3_GEN_CNTL__VI = 0x4C76; +constexpr unsigned int mmDIG2_TMDS_CTL_BITS__VI = 0x4C72; +constexpr unsigned int mmDIG2_TMDS_DCBALANCER_CONTROL__VI = 0x4C73; +constexpr unsigned int mmDIG2_TMDS_DEBUG__VI = 0x4C71; +constexpr unsigned int mmDIG2_TMDS_STEREOSYNC_CTL_SEL__VI = 0x4C6E; +constexpr unsigned int mmDIG2_TMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x4C6F; +constexpr unsigned int mmDIG2_TMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x4C70; +constexpr unsigned int mmDIG3_AFMT_60958_0__VI = 0x4D38; +constexpr unsigned int mmDIG3_AFMT_60958_1__VI = 0x4D39; +constexpr unsigned int mmDIG3_AFMT_60958_2__VI = 0x4D3F; +constexpr unsigned int mmDIG3_AFMT_AUDIO_CRC_CONTROL__VI = 0x4D3A; +constexpr unsigned int mmDIG3_AFMT_AUDIO_CRC_RESULT__VI = 0x4D40; +constexpr unsigned int mmDIG3_AFMT_AUDIO_DBG_DTO_CNTL__VI = 0x4D46; +constexpr unsigned int mmDIG3_AFMT_AUDIO_INFO0__VI = 0x4D36; +constexpr unsigned int mmDIG3_AFMT_AUDIO_INFO1__VI = 0x4D37; +constexpr unsigned int mmDIG3_AFMT_AUDIO_PACKET_CONTROL__VI = 0x4D42; +constexpr unsigned int mmDIG3_AFMT_AUDIO_PACKET_CONTROL2__VI = 0x4D14; +constexpr unsigned int mmDIG3_AFMT_AUDIO_SRC_CONTROL__VI = 0x4D45; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO0__VI = 0x4D1E; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO1__VI = 0x4D1F; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO2__VI = 0x4D20; +constexpr unsigned int mmDIG3_AFMT_AVI_INFO3__VI = 0x4D21; +constexpr unsigned int mmDIG3_AFMT_GENERIC_0__VI = 0x4D25; +constexpr unsigned int mmDIG3_AFMT_GENERIC_1__VI = 0x4D26; +constexpr unsigned int mmDIG3_AFMT_GENERIC_2__VI = 0x4D27; +constexpr unsigned int mmDIG3_AFMT_GENERIC_3__VI = 0x4D28; +constexpr unsigned int mmDIG3_AFMT_GENERIC_4__VI = 0x4D29; +constexpr unsigned int mmDIG3_AFMT_GENERIC_5__VI = 0x4D2A; +constexpr unsigned int mmDIG3_AFMT_GENERIC_6__VI = 0x4D2B; +constexpr unsigned int mmDIG3_AFMT_GENERIC_7__VI = 0x4D2C; +constexpr unsigned int mmDIG3_AFMT_GENERIC_HDR__VI = 0x4D24; +constexpr unsigned int mmDIG3_AFMT_INFOFRAME_CONTROL0__VI = 0x4D44; +constexpr unsigned int mmDIG3_AFMT_ISRC1_0__VI = 0x4D15; +constexpr unsigned int mmDIG3_AFMT_ISRC1_1__VI = 0x4D16; +constexpr unsigned int mmDIG3_AFMT_ISRC1_2__VI = 0x4D17; +constexpr unsigned int mmDIG3_AFMT_ISRC1_3__VI = 0x4D18; +constexpr unsigned int mmDIG3_AFMT_ISRC1_4__VI = 0x4D19; +constexpr unsigned int mmDIG3_AFMT_ISRC2_0__VI = 0x4D1A; +constexpr unsigned int mmDIG3_AFMT_ISRC2_1__VI = 0x4D1B; +constexpr unsigned int mmDIG3_AFMT_ISRC2_2__VI = 0x4D1C; +constexpr unsigned int mmDIG3_AFMT_ISRC2_3__VI = 0x4D1D; +constexpr unsigned int mmDIG3_AFMT_MPEG_INFO0__VI = 0x4D22; +constexpr unsigned int mmDIG3_AFMT_MPEG_INFO1__VI = 0x4D23; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL0__VI = 0x4D3B; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL1__VI = 0x4D3C; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL2__VI = 0x4D3D; +constexpr unsigned int mmDIG3_AFMT_RAMP_CONTROL3__VI = 0x4D3E; +constexpr unsigned int mmDIG3_AFMT_STATUS__VI = 0x4D41; +constexpr unsigned int mmDIG3_AFMT_VBI_PACKET_CONTROL__VI = 0x4D43; +constexpr unsigned int mmDIG3_DIG_BE_CNTL__VI = 0x4D47; +constexpr unsigned int mmDIG3_DIG_BE_EN_CNTL__VI = 0x4D48; +constexpr unsigned int mmDIG3_DIG_CLOCK_PATTERN__VI = 0x4D03; +constexpr unsigned int mmDIG3_DIG_DISPCLK_SWITCH_CNTL__VI = 0x4D07; +constexpr unsigned int mmDIG3_DIG_DISPCLK_SWITCH_STATUS__VI = 0x4D08; +constexpr unsigned int mmDIG3_DIG_FE_CNTL__VI = 0x4D00; +constexpr unsigned int mmDIG3_DIG_FE_TEST_DEBUG_DATA__VI = 0x4D7D; +constexpr unsigned int mmDIG3_DIG_FE_TEST_DEBUG_INDEX__VI = 0x4D7C; +constexpr unsigned int mmDIG3_DIG_FIFO_STATUS__VI = 0x4D06; +constexpr unsigned int mmDIG3_DIG_LANE_ENABLE__VI = 0x4D79; +constexpr unsigned int mmDIG3_DIG_OUTPUT_CRC_CNTL__VI = 0x4D01; +constexpr unsigned int mmDIG3_DIG_OUTPUT_CRC_RESULT__VI = 0x4D02; +constexpr unsigned int mmDIG3_DIG_RANDOM_PATTERN_SEED__VI = 0x4D05; +constexpr unsigned int mmDIG3_DIG_TEST_DEBUG_DATA__VI = 0x4D7B; +constexpr unsigned int mmDIG3_DIG_TEST_DEBUG_INDEX__VI = 0x4D7A; +constexpr unsigned int mmDIG3_DIG_TEST_PATTERN__VI = 0x4D04; +constexpr unsigned int mmDIG3_HDMI_ACR_32_0__VI = 0x4D2E; +constexpr unsigned int mmDIG3_HDMI_ACR_32_1__VI = 0x4D2F; +constexpr unsigned int mmDIG3_HDMI_ACR_44_0__VI = 0x4D30; +constexpr unsigned int mmDIG3_HDMI_ACR_44_1__VI = 0x4D31; +constexpr unsigned int mmDIG3_HDMI_ACR_48_0__VI = 0x4D32; +constexpr unsigned int mmDIG3_HDMI_ACR_48_1__VI = 0x4D33; +constexpr unsigned int mmDIG3_HDMI_ACR_PACKET_CONTROL__VI = 0x4D0C; +constexpr unsigned int mmDIG3_HDMI_ACR_STATUS_0__VI = 0x4D34; +constexpr unsigned int mmDIG3_HDMI_ACR_STATUS_1__VI = 0x4D35; +constexpr unsigned int mmDIG3_HDMI_AUDIO_PACKET_CONTROL__VI = 0x4D0B; +constexpr unsigned int mmDIG3_HDMI_CONTROL__VI = 0x4D09; +constexpr unsigned int mmDIG3_HDMI_GC__VI = 0x4D13; +constexpr unsigned int mmDIG3_HDMI_GENERIC_PACKET_CONTROL0__VI = 0x4D10; +constexpr unsigned int mmDIG3_HDMI_GENERIC_PACKET_CONTROL1__VI = 0x4D2D; +constexpr unsigned int mmDIG3_HDMI_INFOFRAME_CONTROL0__VI = 0x4D0E; +constexpr unsigned int mmDIG3_HDMI_INFOFRAME_CONTROL1__VI = 0x4D0F; +constexpr unsigned int mmDIG3_HDMI_STATUS__VI = 0x4D0A; +constexpr unsigned int mmDIG3_HDMI_VBI_PACKET_CONTROL__VI = 0x4D0D; +constexpr unsigned int mmDIG3_LVDS_DATA_CNTL__VI = 0x4D78; +constexpr unsigned int mmDIG3_TMDS_CNTL__VI = 0x4D6B; +constexpr unsigned int mmDIG3_TMDS_CONTROL0_FEEDBACK__VI = 0x4D6D; +constexpr unsigned int mmDIG3_TMDS_CONTROL_CHAR__VI = 0x4D6C; +constexpr unsigned int mmDIG3_TMDS_CTL0_1_GEN_CNTL__VI = 0x4D75; +constexpr unsigned int mmDIG3_TMDS_CTL2_3_GEN_CNTL__VI = 0x4D76; +constexpr unsigned int mmDIG3_TMDS_CTL_BITS__VI = 0x4D72; +constexpr unsigned int mmDIG3_TMDS_DCBALANCER_CONTROL__VI = 0x4D73; +constexpr unsigned int mmDIG3_TMDS_DEBUG__VI = 0x4D71; +constexpr unsigned int mmDIG3_TMDS_STEREOSYNC_CTL_SEL__VI = 0x4D6E; +constexpr unsigned int mmDIG3_TMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x4D6F; +constexpr unsigned int mmDIG3_TMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x4D70; +constexpr unsigned int mmDIG4_AFMT_60958_0__VI = 0x4E38; +constexpr unsigned int mmDIG4_AFMT_60958_1__VI = 0x4E39; +constexpr unsigned int mmDIG4_AFMT_60958_2__VI = 0x4E3F; +constexpr unsigned int mmDIG4_AFMT_AUDIO_CRC_CONTROL__VI = 0x4E3A; +constexpr unsigned int mmDIG4_AFMT_AUDIO_CRC_RESULT__VI = 0x4E40; +constexpr unsigned int mmDIG4_AFMT_AUDIO_DBG_DTO_CNTL__VI = 0x4E46; +constexpr unsigned int mmDIG4_AFMT_AUDIO_INFO0__VI = 0x4E36; +constexpr unsigned int mmDIG4_AFMT_AUDIO_INFO1__VI = 0x4E37; +constexpr unsigned int mmDIG4_AFMT_AUDIO_PACKET_CONTROL__VI = 0x4E42; +constexpr unsigned int mmDIG4_AFMT_AUDIO_PACKET_CONTROL2__VI = 0x4E14; +constexpr unsigned int mmDIG4_AFMT_AUDIO_SRC_CONTROL__VI = 0x4E45; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO0__VI = 0x4E1E; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO1__VI = 0x4E1F; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO2__VI = 0x4E20; +constexpr unsigned int mmDIG4_AFMT_AVI_INFO3__VI = 0x4E21; +constexpr unsigned int mmDIG4_AFMT_GENERIC_0__VI = 0x4E25; +constexpr unsigned int mmDIG4_AFMT_GENERIC_1__VI = 0x4E26; +constexpr unsigned int mmDIG4_AFMT_GENERIC_2__VI = 0x4E27; +constexpr unsigned int mmDIG4_AFMT_GENERIC_3__VI = 0x4E28; +constexpr unsigned int mmDIG4_AFMT_GENERIC_4__VI = 0x4E29; +constexpr unsigned int mmDIG4_AFMT_GENERIC_5__VI = 0x4E2A; +constexpr unsigned int mmDIG4_AFMT_GENERIC_6__VI = 0x4E2B; +constexpr unsigned int mmDIG4_AFMT_GENERIC_7__VI = 0x4E2C; +constexpr unsigned int mmDIG4_AFMT_GENERIC_HDR__VI = 0x4E24; +constexpr unsigned int mmDIG4_AFMT_INFOFRAME_CONTROL0__VI = 0x4E44; +constexpr unsigned int mmDIG4_AFMT_ISRC1_0__VI = 0x4E15; +constexpr unsigned int mmDIG4_AFMT_ISRC1_1__VI = 0x4E16; +constexpr unsigned int mmDIG4_AFMT_ISRC1_2__VI = 0x4E17; +constexpr unsigned int mmDIG4_AFMT_ISRC1_3__VI = 0x4E18; +constexpr unsigned int mmDIG4_AFMT_ISRC1_4__VI = 0x4E19; +constexpr unsigned int mmDIG4_AFMT_ISRC2_0__VI = 0x4E1A; +constexpr unsigned int mmDIG4_AFMT_ISRC2_1__VI = 0x4E1B; +constexpr unsigned int mmDIG4_AFMT_ISRC2_2__VI = 0x4E1C; +constexpr unsigned int mmDIG4_AFMT_ISRC2_3__VI = 0x4E1D; +constexpr unsigned int mmDIG4_AFMT_MPEG_INFO0__VI = 0x4E22; +constexpr unsigned int mmDIG4_AFMT_MPEG_INFO1__VI = 0x4E23; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL0__VI = 0x4E3B; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL1__VI = 0x4E3C; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL2__VI = 0x4E3D; +constexpr unsigned int mmDIG4_AFMT_RAMP_CONTROL3__VI = 0x4E3E; +constexpr unsigned int mmDIG4_AFMT_STATUS__VI = 0x4E41; +constexpr unsigned int mmDIG4_AFMT_VBI_PACKET_CONTROL__VI = 0x4E43; +constexpr unsigned int mmDIG4_DIG_BE_CNTL__VI = 0x4E47; +constexpr unsigned int mmDIG4_DIG_BE_EN_CNTL__VI = 0x4E48; +constexpr unsigned int mmDIG4_DIG_CLOCK_PATTERN__VI = 0x4E03; +constexpr unsigned int mmDIG4_DIG_DISPCLK_SWITCH_CNTL__VI = 0x4E07; +constexpr unsigned int mmDIG4_DIG_DISPCLK_SWITCH_STATUS__VI = 0x4E08; +constexpr unsigned int mmDIG4_DIG_FE_CNTL__VI = 0x4E00; +constexpr unsigned int mmDIG4_DIG_FE_TEST_DEBUG_DATA__VI = 0x4E7D; +constexpr unsigned int mmDIG4_DIG_FE_TEST_DEBUG_INDEX__VI = 0x4E7C; +constexpr unsigned int mmDIG4_DIG_FIFO_STATUS__VI = 0x4E06; +constexpr unsigned int mmDIG4_DIG_LANE_ENABLE__VI = 0x4E79; +constexpr unsigned int mmDIG4_DIG_OUTPUT_CRC_CNTL__VI = 0x4E01; +constexpr unsigned int mmDIG4_DIG_OUTPUT_CRC_RESULT__VI = 0x4E02; +constexpr unsigned int mmDIG4_DIG_RANDOM_PATTERN_SEED__VI = 0x4E05; +constexpr unsigned int mmDIG4_DIG_TEST_DEBUG_DATA__VI = 0x4E7B; +constexpr unsigned int mmDIG4_DIG_TEST_DEBUG_INDEX__VI = 0x4E7A; +constexpr unsigned int mmDIG4_DIG_TEST_PATTERN__VI = 0x4E04; +constexpr unsigned int mmDIG4_HDMI_ACR_32_0__VI = 0x4E2E; +constexpr unsigned int mmDIG4_HDMI_ACR_32_1__VI = 0x4E2F; +constexpr unsigned int mmDIG4_HDMI_ACR_44_0__VI = 0x4E30; +constexpr unsigned int mmDIG4_HDMI_ACR_44_1__VI = 0x4E31; +constexpr unsigned int mmDIG4_HDMI_ACR_48_0__VI = 0x4E32; +constexpr unsigned int mmDIG4_HDMI_ACR_48_1__VI = 0x4E33; +constexpr unsigned int mmDIG4_HDMI_ACR_PACKET_CONTROL__VI = 0x4E0C; +constexpr unsigned int mmDIG4_HDMI_ACR_STATUS_0__VI = 0x4E34; +constexpr unsigned int mmDIG4_HDMI_ACR_STATUS_1__VI = 0x4E35; +constexpr unsigned int mmDIG4_HDMI_AUDIO_PACKET_CONTROL__VI = 0x4E0B; +constexpr unsigned int mmDIG4_HDMI_CONTROL__VI = 0x4E09; +constexpr unsigned int mmDIG4_HDMI_GC__VI = 0x4E13; +constexpr unsigned int mmDIG4_HDMI_GENERIC_PACKET_CONTROL0__VI = 0x4E10; +constexpr unsigned int mmDIG4_HDMI_GENERIC_PACKET_CONTROL1__VI = 0x4E2D; +constexpr unsigned int mmDIG4_HDMI_INFOFRAME_CONTROL0__VI = 0x4E0E; +constexpr unsigned int mmDIG4_HDMI_INFOFRAME_CONTROL1__VI = 0x4E0F; +constexpr unsigned int mmDIG4_HDMI_STATUS__VI = 0x4E0A; +constexpr unsigned int mmDIG4_HDMI_VBI_PACKET_CONTROL__VI = 0x4E0D; +constexpr unsigned int mmDIG4_LVDS_DATA_CNTL__VI = 0x4E78; +constexpr unsigned int mmDIG4_TMDS_CNTL__VI = 0x4E6B; +constexpr unsigned int mmDIG4_TMDS_CONTROL0_FEEDBACK__VI = 0x4E6D; +constexpr unsigned int mmDIG4_TMDS_CONTROL_CHAR__VI = 0x4E6C; +constexpr unsigned int mmDIG4_TMDS_CTL0_1_GEN_CNTL__VI = 0x4E75; +constexpr unsigned int mmDIG4_TMDS_CTL2_3_GEN_CNTL__VI = 0x4E76; +constexpr unsigned int mmDIG4_TMDS_CTL_BITS__VI = 0x4E72; +constexpr unsigned int mmDIG4_TMDS_DCBALANCER_CONTROL__VI = 0x4E73; +constexpr unsigned int mmDIG4_TMDS_DEBUG__VI = 0x4E71; +constexpr unsigned int mmDIG4_TMDS_STEREOSYNC_CTL_SEL__VI = 0x4E6E; +constexpr unsigned int mmDIG4_TMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x4E6F; +constexpr unsigned int mmDIG4_TMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x4E70; +constexpr unsigned int mmDIG5_AFMT_60958_0__VI = 0x4F38; +constexpr unsigned int mmDIG5_AFMT_60958_1__VI = 0x4F39; +constexpr unsigned int mmDIG5_AFMT_60958_2__VI = 0x4F3F; +constexpr unsigned int mmDIG5_AFMT_AUDIO_CRC_CONTROL__VI = 0x4F3A; +constexpr unsigned int mmDIG5_AFMT_AUDIO_CRC_RESULT__VI = 0x4F40; +constexpr unsigned int mmDIG5_AFMT_AUDIO_DBG_DTO_CNTL__VI = 0x4F46; +constexpr unsigned int mmDIG5_AFMT_AUDIO_INFO0__VI = 0x4F36; +constexpr unsigned int mmDIG5_AFMT_AUDIO_INFO1__VI = 0x4F37; +constexpr unsigned int mmDIG5_AFMT_AUDIO_PACKET_CONTROL__VI = 0x4F42; +constexpr unsigned int mmDIG5_AFMT_AUDIO_PACKET_CONTROL2__VI = 0x4F14; +constexpr unsigned int mmDIG5_AFMT_AUDIO_SRC_CONTROL__VI = 0x4F45; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO0__VI = 0x4F1E; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO1__VI = 0x4F1F; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO2__VI = 0x4F20; +constexpr unsigned int mmDIG5_AFMT_AVI_INFO3__VI = 0x4F21; +constexpr unsigned int mmDIG5_AFMT_GENERIC_0__VI = 0x4F25; +constexpr unsigned int mmDIG5_AFMT_GENERIC_1__VI = 0x4F26; +constexpr unsigned int mmDIG5_AFMT_GENERIC_2__VI = 0x4F27; +constexpr unsigned int mmDIG5_AFMT_GENERIC_3__VI = 0x4F28; +constexpr unsigned int mmDIG5_AFMT_GENERIC_4__VI = 0x4F29; +constexpr unsigned int mmDIG5_AFMT_GENERIC_5__VI = 0x4F2A; +constexpr unsigned int mmDIG5_AFMT_GENERIC_6__VI = 0x4F2B; +constexpr unsigned int mmDIG5_AFMT_GENERIC_7__VI = 0x4F2C; +constexpr unsigned int mmDIG5_AFMT_GENERIC_HDR__VI = 0x4F24; +constexpr unsigned int mmDIG5_AFMT_INFOFRAME_CONTROL0__VI = 0x4F44; +constexpr unsigned int mmDIG5_AFMT_ISRC1_0__VI = 0x4F15; +constexpr unsigned int mmDIG5_AFMT_ISRC1_1__VI = 0x4F16; +constexpr unsigned int mmDIG5_AFMT_ISRC1_2__VI = 0x4F17; +constexpr unsigned int mmDIG5_AFMT_ISRC1_3__VI = 0x4F18; +constexpr unsigned int mmDIG5_AFMT_ISRC1_4__VI = 0x4F19; +constexpr unsigned int mmDIG5_AFMT_ISRC2_0__VI = 0x4F1A; +constexpr unsigned int mmDIG5_AFMT_ISRC2_1__VI = 0x4F1B; +constexpr unsigned int mmDIG5_AFMT_ISRC2_2__VI = 0x4F1C; +constexpr unsigned int mmDIG5_AFMT_ISRC2_3__VI = 0x4F1D; +constexpr unsigned int mmDIG5_AFMT_MPEG_INFO0__VI = 0x4F22; +constexpr unsigned int mmDIG5_AFMT_MPEG_INFO1__VI = 0x4F23; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL0__VI = 0x4F3B; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL1__VI = 0x4F3C; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL2__VI = 0x4F3D; +constexpr unsigned int mmDIG5_AFMT_RAMP_CONTROL3__VI = 0x4F3E; +constexpr unsigned int mmDIG5_AFMT_STATUS__VI = 0x4F41; +constexpr unsigned int mmDIG5_AFMT_VBI_PACKET_CONTROL__VI = 0x4F43; +constexpr unsigned int mmDIG5_DIG_BE_CNTL__VI = 0x4F47; +constexpr unsigned int mmDIG5_DIG_BE_EN_CNTL__VI = 0x4F48; +constexpr unsigned int mmDIG5_DIG_CLOCK_PATTERN__VI = 0x4F03; +constexpr unsigned int mmDIG5_DIG_DISPCLK_SWITCH_CNTL__VI = 0x4F07; +constexpr unsigned int mmDIG5_DIG_DISPCLK_SWITCH_STATUS__VI = 0x4F08; +constexpr unsigned int mmDIG5_DIG_FE_CNTL__VI = 0x4F00; +constexpr unsigned int mmDIG5_DIG_FE_TEST_DEBUG_DATA__VI = 0x4F7D; +constexpr unsigned int mmDIG5_DIG_FE_TEST_DEBUG_INDEX__VI = 0x4F7C; +constexpr unsigned int mmDIG5_DIG_FIFO_STATUS__VI = 0x4F06; +constexpr unsigned int mmDIG5_DIG_LANE_ENABLE__VI = 0x4F79; +constexpr unsigned int mmDIG5_DIG_OUTPUT_CRC_CNTL__VI = 0x4F01; +constexpr unsigned int mmDIG5_DIG_OUTPUT_CRC_RESULT__VI = 0x4F02; +constexpr unsigned int mmDIG5_DIG_RANDOM_PATTERN_SEED__VI = 0x4F05; +constexpr unsigned int mmDIG5_DIG_TEST_DEBUG_DATA__VI = 0x4F7B; +constexpr unsigned int mmDIG5_DIG_TEST_DEBUG_INDEX__VI = 0x4F7A; +constexpr unsigned int mmDIG5_DIG_TEST_PATTERN__VI = 0x4F04; +constexpr unsigned int mmDIG5_HDMI_ACR_32_0__VI = 0x4F2E; +constexpr unsigned int mmDIG5_HDMI_ACR_32_1__VI = 0x4F2F; +constexpr unsigned int mmDIG5_HDMI_ACR_44_0__VI = 0x4F30; +constexpr unsigned int mmDIG5_HDMI_ACR_44_1__VI = 0x4F31; +constexpr unsigned int mmDIG5_HDMI_ACR_48_0__VI = 0x4F32; +constexpr unsigned int mmDIG5_HDMI_ACR_48_1__VI = 0x4F33; +constexpr unsigned int mmDIG5_HDMI_ACR_PACKET_CONTROL__VI = 0x4F0C; +constexpr unsigned int mmDIG5_HDMI_ACR_STATUS_0__VI = 0x4F34; +constexpr unsigned int mmDIG5_HDMI_ACR_STATUS_1__VI = 0x4F35; +constexpr unsigned int mmDIG5_HDMI_AUDIO_PACKET_CONTROL__VI = 0x4F0B; +constexpr unsigned int mmDIG5_HDMI_CONTROL__VI = 0x4F09; +constexpr unsigned int mmDIG5_HDMI_GC__VI = 0x4F13; +constexpr unsigned int mmDIG5_HDMI_GENERIC_PACKET_CONTROL0__VI = 0x4F10; +constexpr unsigned int mmDIG5_HDMI_GENERIC_PACKET_CONTROL1__VI = 0x4F2D; +constexpr unsigned int mmDIG5_HDMI_INFOFRAME_CONTROL0__VI = 0x4F0E; +constexpr unsigned int mmDIG5_HDMI_INFOFRAME_CONTROL1__VI = 0x4F0F; +constexpr unsigned int mmDIG5_HDMI_STATUS__VI = 0x4F0A; +constexpr unsigned int mmDIG5_HDMI_VBI_PACKET_CONTROL__VI = 0x4F0D; +constexpr unsigned int mmDIG5_LVDS_DATA_CNTL__VI = 0x4F78; +constexpr unsigned int mmDIG5_TMDS_CNTL__VI = 0x4F6B; +constexpr unsigned int mmDIG5_TMDS_CONTROL0_FEEDBACK__VI = 0x4F6D; +constexpr unsigned int mmDIG5_TMDS_CONTROL_CHAR__VI = 0x4F6C; +constexpr unsigned int mmDIG5_TMDS_CTL0_1_GEN_CNTL__VI = 0x4F75; +constexpr unsigned int mmDIG5_TMDS_CTL2_3_GEN_CNTL__VI = 0x4F76; +constexpr unsigned int mmDIG5_TMDS_CTL_BITS__VI = 0x4F72; +constexpr unsigned int mmDIG5_TMDS_DCBALANCER_CONTROL__VI = 0x4F73; +constexpr unsigned int mmDIG5_TMDS_DEBUG__VI = 0x4F71; +constexpr unsigned int mmDIG5_TMDS_STEREOSYNC_CTL_SEL__VI = 0x4F6E; +constexpr unsigned int mmDIG5_TMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x4F6F; +constexpr unsigned int mmDIG5_TMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x4F70; +constexpr unsigned int mmDIG6_AFMT_60958_0__VI = 0x5438; +constexpr unsigned int mmDIG6_AFMT_60958_1__VI = 0x5439; +constexpr unsigned int mmDIG6_AFMT_60958_2__VI = 0x543F; +constexpr unsigned int mmDIG6_AFMT_AUDIO_CRC_CONTROL__VI = 0x543A; +constexpr unsigned int mmDIG6_AFMT_AUDIO_CRC_RESULT__VI = 0x5440; +constexpr unsigned int mmDIG6_AFMT_AUDIO_DBG_DTO_CNTL__VI = 0x5446; +constexpr unsigned int mmDIG6_AFMT_AUDIO_INFO0__VI = 0x5436; +constexpr unsigned int mmDIG6_AFMT_AUDIO_INFO1__VI = 0x5437; +constexpr unsigned int mmDIG6_AFMT_AUDIO_PACKET_CONTROL__VI = 0x5442; +constexpr unsigned int mmDIG6_AFMT_AUDIO_PACKET_CONTROL2__VI = 0x5414; +constexpr unsigned int mmDIG6_AFMT_AUDIO_SRC_CONTROL__VI = 0x5445; +constexpr unsigned int mmDIG6_AFMT_AVI_INFO0__VI = 0x541E; +constexpr unsigned int mmDIG6_AFMT_AVI_INFO1__VI = 0x541F; +constexpr unsigned int mmDIG6_AFMT_AVI_INFO2__VI = 0x5420; +constexpr unsigned int mmDIG6_AFMT_AVI_INFO3__VI = 0x5421; +constexpr unsigned int mmDIG6_AFMT_GENERIC_0__VI = 0x5425; +constexpr unsigned int mmDIG6_AFMT_GENERIC_1__VI = 0x5426; +constexpr unsigned int mmDIG6_AFMT_GENERIC_2__VI = 0x5427; +constexpr unsigned int mmDIG6_AFMT_GENERIC_3__VI = 0x5428; +constexpr unsigned int mmDIG6_AFMT_GENERIC_4__VI = 0x5429; +constexpr unsigned int mmDIG6_AFMT_GENERIC_5__VI = 0x542A; +constexpr unsigned int mmDIG6_AFMT_GENERIC_6__VI = 0x542B; +constexpr unsigned int mmDIG6_AFMT_GENERIC_7__VI = 0x542C; +constexpr unsigned int mmDIG6_AFMT_GENERIC_HDR__VI = 0x5424; +constexpr unsigned int mmDIG6_AFMT_INFOFRAME_CONTROL0__VI = 0x5444; +constexpr unsigned int mmDIG6_AFMT_ISRC1_0__VI = 0x5415; +constexpr unsigned int mmDIG6_AFMT_ISRC1_1__VI = 0x5416; +constexpr unsigned int mmDIG6_AFMT_ISRC1_2__VI = 0x5417; +constexpr unsigned int mmDIG6_AFMT_ISRC1_3__VI = 0x5418; +constexpr unsigned int mmDIG6_AFMT_ISRC1_4__VI = 0x5419; +constexpr unsigned int mmDIG6_AFMT_ISRC2_0__VI = 0x541A; +constexpr unsigned int mmDIG6_AFMT_ISRC2_1__VI = 0x541B; +constexpr unsigned int mmDIG6_AFMT_ISRC2_2__VI = 0x541C; +constexpr unsigned int mmDIG6_AFMT_ISRC2_3__VI = 0x541D; +constexpr unsigned int mmDIG6_AFMT_MPEG_INFO0__VI = 0x5422; +constexpr unsigned int mmDIG6_AFMT_MPEG_INFO1__VI = 0x5423; +constexpr unsigned int mmDIG6_AFMT_RAMP_CONTROL0__VI = 0x543B; +constexpr unsigned int mmDIG6_AFMT_RAMP_CONTROL1__VI = 0x543C; +constexpr unsigned int mmDIG6_AFMT_RAMP_CONTROL2__VI = 0x543D; +constexpr unsigned int mmDIG6_AFMT_RAMP_CONTROL3__VI = 0x543E; +constexpr unsigned int mmDIG6_AFMT_STATUS__VI = 0x5441; +constexpr unsigned int mmDIG6_AFMT_VBI_PACKET_CONTROL__VI = 0x5443; +constexpr unsigned int mmDIG6_DIG_BE_CNTL__VI = 0x5447; +constexpr unsigned int mmDIG6_DIG_BE_EN_CNTL__VI = 0x5448; +constexpr unsigned int mmDIG6_DIG_CLOCK_PATTERN__VI = 0x5403; +constexpr unsigned int mmDIG6_DIG_DISPCLK_SWITCH_CNTL__VI = 0x5407; +constexpr unsigned int mmDIG6_DIG_DISPCLK_SWITCH_STATUS__VI = 0x5408; +constexpr unsigned int mmDIG6_DIG_FE_CNTL__VI = 0x5400; +constexpr unsigned int mmDIG6_DIG_FE_TEST_DEBUG_DATA__VI = 0x547D; +constexpr unsigned int mmDIG6_DIG_FE_TEST_DEBUG_INDEX__VI = 0x547C; +constexpr unsigned int mmDIG6_DIG_FIFO_STATUS__VI = 0x5406; +constexpr unsigned int mmDIG6_DIG_LANE_ENABLE__VI = 0x5479; +constexpr unsigned int mmDIG6_DIG_OUTPUT_CRC_CNTL__VI = 0x5401; +constexpr unsigned int mmDIG6_DIG_OUTPUT_CRC_RESULT__VI = 0x5402; +constexpr unsigned int mmDIG6_DIG_RANDOM_PATTERN_SEED__VI = 0x5405; +constexpr unsigned int mmDIG6_DIG_TEST_DEBUG_DATA__VI = 0x547B; +constexpr unsigned int mmDIG6_DIG_TEST_DEBUG_INDEX__VI = 0x547A; +constexpr unsigned int mmDIG6_DIG_TEST_PATTERN__VI = 0x5404; +constexpr unsigned int mmDIG6_HDMI_ACR_32_0__VI = 0x542E; +constexpr unsigned int mmDIG6_HDMI_ACR_32_1__VI = 0x542F; +constexpr unsigned int mmDIG6_HDMI_ACR_44_0__VI = 0x5430; +constexpr unsigned int mmDIG6_HDMI_ACR_44_1__VI = 0x5431; +constexpr unsigned int mmDIG6_HDMI_ACR_48_0__VI = 0x5432; +constexpr unsigned int mmDIG6_HDMI_ACR_48_1__VI = 0x5433; +constexpr unsigned int mmDIG6_HDMI_ACR_PACKET_CONTROL__VI = 0x540C; +constexpr unsigned int mmDIG6_HDMI_ACR_STATUS_0__VI = 0x5434; +constexpr unsigned int mmDIG6_HDMI_ACR_STATUS_1__VI = 0x5435; +constexpr unsigned int mmDIG6_HDMI_AUDIO_PACKET_CONTROL__VI = 0x540B; +constexpr unsigned int mmDIG6_HDMI_CONTROL__VI = 0x5409; +constexpr unsigned int mmDIG6_HDMI_GC__VI = 0x5413; +constexpr unsigned int mmDIG6_HDMI_GENERIC_PACKET_CONTROL0__VI = 0x5410; +constexpr unsigned int mmDIG6_HDMI_GENERIC_PACKET_CONTROL1__VI = 0x542D; +constexpr unsigned int mmDIG6_HDMI_INFOFRAME_CONTROL0__VI = 0x540E; +constexpr unsigned int mmDIG6_HDMI_INFOFRAME_CONTROL1__VI = 0x540F; +constexpr unsigned int mmDIG6_HDMI_STATUS__VI = 0x540A; +constexpr unsigned int mmDIG6_HDMI_VBI_PACKET_CONTROL__VI = 0x540D; +constexpr unsigned int mmDIG6_LVDS_DATA_CNTL__VI = 0x5478; +constexpr unsigned int mmDIG6_TMDS_CNTL__VI = 0x546B; +constexpr unsigned int mmDIG6_TMDS_CONTROL0_FEEDBACK__VI = 0x546D; +constexpr unsigned int mmDIG6_TMDS_CONTROL_CHAR__VI = 0x546C; +constexpr unsigned int mmDIG6_TMDS_CTL0_1_GEN_CNTL__VI = 0x5475; +constexpr unsigned int mmDIG6_TMDS_CTL2_3_GEN_CNTL__VI = 0x5476; +constexpr unsigned int mmDIG6_TMDS_CTL_BITS__VI = 0x5472; +constexpr unsigned int mmDIG6_TMDS_DCBALANCER_CONTROL__VI = 0x5473; +constexpr unsigned int mmDIG6_TMDS_DEBUG__VI = 0x5471; +constexpr unsigned int mmDIG6_TMDS_STEREOSYNC_CTL_SEL__VI = 0x546E; +constexpr unsigned int mmDIG6_TMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x546F; +constexpr unsigned int mmDIG6_TMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x5470; +constexpr unsigned int mmDIG_BE_CNTL__VI = 0x4A47; +constexpr unsigned int mmDIG_BE_EN_CNTL__VI = 0x4A48; +constexpr unsigned int mmDIG_CLOCK_PATTERN__VI = 0x4A03; +constexpr unsigned int mmDIG_DISPCLK_SWITCH_CNTL__VI = 0x4A07; +constexpr unsigned int mmDIG_DISPCLK_SWITCH_STATUS__VI = 0x4A08; +constexpr unsigned int mmDIG_FE_CNTL__VI = 0x4A00; +constexpr unsigned int mmDIG_FE_TEST_DEBUG_DATA__VI = 0x4A7D; +constexpr unsigned int mmDIG_FE_TEST_DEBUG_INDEX__VI = 0x4A7C; +constexpr unsigned int mmDIG_FIFO_STATUS__VI = 0x4A06; +constexpr unsigned int mmDIG_LANE_ENABLE__VI = 0x4A79; +constexpr unsigned int mmDIG_OUTPUT_CRC_CNTL__VI = 0x4A01; +constexpr unsigned int mmDIG_OUTPUT_CRC_RESULT__VI = 0x4A02; +constexpr unsigned int mmDIG_RANDOM_PATTERN_SEED__VI = 0x4A05; +constexpr unsigned int mmDIG_SOFT_RESET__VI = 0x1872; +constexpr unsigned int mmDIG_TEST_DEBUG_DATA__VI = 0x4A7B; +constexpr unsigned int mmDIG_TEST_DEBUG_INDEX__VI = 0x4A7A; +constexpr unsigned int mmDIG_TEST_PATTERN__VI = 0x4A04; +constexpr unsigned int mmDISPCLK_CGTT_BLK_CTRL_REG__VI = 0x0135; +constexpr unsigned int mmDISPCLK_FREQ_CHANGE_CNTL__VI = 0x0131; +constexpr unsigned int mmDISPPLL_BG_CNTL__VI = 0x171E; +constexpr unsigned int mmDISP_INTERRUPT_STATUS__VI = 0x1857; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE__VI = 0x1858; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE2__VI = 0x1859; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE3__VI = 0x185A; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE4__VI = 0x185B; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE5__VI = 0x185C; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE6__VI = 0x185D; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE7__VI = 0x185E; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE8__VI = 0x185F; +constexpr unsigned int mmDISP_INTERRUPT_STATUS_CONTINUE9__VI = 0x1860; +constexpr unsigned int mmDMCU_DPRX_INTERRUPT_STATUS1__VI = 0x1634; +constexpr unsigned int mmDMCU_DPRX_INTERRUPT_TO_UC_EN_MASK1__VI = 0x1635; +constexpr unsigned int mmDMCU_DPRX_INTERRUPT_TO_UC_XIRQ_IRQ_SEL1__VI = 0x1636; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_STATUS1__VI = 0x1644; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_STATUS2__VI = 0x1645; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_STATUS3__VI = 0x1646; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_STATUS4__VI = 0x1647; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_STATUS5__VI = 0x1642; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_HOST_EN_MASK1__VI = 0x167C; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_HOST_EN_MASK2__VI = 0x167D; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_HOST_EN_MASK3__VI = 0x167E; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_HOST_EN_MASK4__VI = 0x167F; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_HOST_EN_MASK5__VI = 0x1633; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK1__VI = 0x1674; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK2__VI = 0x1675; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK3__VI = 0x1676; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK4__VI = 0x1677; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_EN_MASK5__VI = 0x1643; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL1__VI = 0x1678; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL2__VI = 0x1679; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL3__VI = 0x167A; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL4__VI = 0x167B; +constexpr unsigned int mmDMCU_PERFMON_INTERRUPT_TO_UC_XIRQ_IRQ_SEL5__VI = 0x1673; +constexpr unsigned int mmDMCU_SMU_INTERRUPT_CNTL__VI = 0x012C; +constexpr unsigned int mmDMCU_SS_INTERRUPT_CNTL_STATUS__VI = 0x1613; +constexpr unsigned int mmDMCU_UC_CLK_GATING_CNTL__VI = 0x161B; +constexpr unsigned int mmDMIF_ADDR_CALC__VI = 0x0303; +constexpr unsigned int mmDMIF_ADDR_CONFIG__VI = 0x02F5; +constexpr unsigned int mmDMIF_PG0_DPG_HW_DEBUG_11__VI = 0x1B3D; +constexpr unsigned int mmDMIF_PG0_DPG_HW_DEBUG_A__VI = 0x1B3B; +constexpr unsigned int mmDMIF_PG0_DPG_HW_DEBUG_B__VI = 0x1B3C; +constexpr unsigned int mmDMIF_PG0_DPG_PIPE_ARBITRATION_CONTROL1__VI = 0x1B30; +constexpr unsigned int mmDMIF_PG0_DPG_PIPE_ARBITRATION_CONTROL2__VI = 0x1B31; +constexpr unsigned int mmDMIF_PG0_DPG_PIPE_DPM_CONTROL__VI = 0x1B34; +constexpr unsigned int mmDMIF_PG0_DPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x1B36; +constexpr unsigned int mmDMIF_PG0_DPG_PIPE_STUTTER_CONTROL__VI = 0x1B35; +constexpr unsigned int mmDMIF_PG0_DPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x1B37; +constexpr unsigned int mmDMIF_PG0_DPG_PIPE_URGENCY_CONTROL__VI = 0x1B33; +constexpr unsigned int mmDMIF_PG0_DPG_REPEATER_PROGRAM__VI = 0x1B3A; +constexpr unsigned int mmDMIF_PG0_DPG_TEST_DEBUG_DATA__VI = 0x1B39; +constexpr unsigned int mmDMIF_PG0_DPG_TEST_DEBUG_INDEX__VI = 0x1B38; +constexpr unsigned int mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL__VI = 0x1B32; +constexpr unsigned int mmDMIF_PG1_DPG_HW_DEBUG_11__VI = 0x1D3D; +constexpr unsigned int mmDMIF_PG1_DPG_HW_DEBUG_A__VI = 0x1D3B; +constexpr unsigned int mmDMIF_PG1_DPG_HW_DEBUG_B__VI = 0x1D3C; +constexpr unsigned int mmDMIF_PG1_DPG_PIPE_ARBITRATION_CONTROL1__VI = 0x1D30; +constexpr unsigned int mmDMIF_PG1_DPG_PIPE_ARBITRATION_CONTROL2__VI = 0x1D31; +constexpr unsigned int mmDMIF_PG1_DPG_PIPE_DPM_CONTROL__VI = 0x1D34; +constexpr unsigned int mmDMIF_PG1_DPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x1D36; +constexpr unsigned int mmDMIF_PG1_DPG_PIPE_STUTTER_CONTROL__VI = 0x1D35; +constexpr unsigned int mmDMIF_PG1_DPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x1D37; +constexpr unsigned int mmDMIF_PG1_DPG_PIPE_URGENCY_CONTROL__VI = 0x1D33; +constexpr unsigned int mmDMIF_PG1_DPG_REPEATER_PROGRAM__VI = 0x1D3A; +constexpr unsigned int mmDMIF_PG1_DPG_TEST_DEBUG_DATA__VI = 0x1D39; +constexpr unsigned int mmDMIF_PG1_DPG_TEST_DEBUG_INDEX__VI = 0x1D38; +constexpr unsigned int mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL__VI = 0x1D32; +constexpr unsigned int mmDMIF_PG2_DPG_HW_DEBUG_11__VI = 0x1F3D; +constexpr unsigned int mmDMIF_PG2_DPG_HW_DEBUG_A__VI = 0x1F3B; +constexpr unsigned int mmDMIF_PG2_DPG_HW_DEBUG_B__VI = 0x1F3C; +constexpr unsigned int mmDMIF_PG2_DPG_PIPE_ARBITRATION_CONTROL1__VI = 0x1F30; +constexpr unsigned int mmDMIF_PG2_DPG_PIPE_ARBITRATION_CONTROL2__VI = 0x1F31; +constexpr unsigned int mmDMIF_PG2_DPG_PIPE_DPM_CONTROL__VI = 0x1F34; +constexpr unsigned int mmDMIF_PG2_DPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x1F36; +constexpr unsigned int mmDMIF_PG2_DPG_PIPE_STUTTER_CONTROL__VI = 0x1F35; +constexpr unsigned int mmDMIF_PG2_DPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x1F37; +constexpr unsigned int mmDMIF_PG2_DPG_PIPE_URGENCY_CONTROL__VI = 0x1F33; +constexpr unsigned int mmDMIF_PG2_DPG_REPEATER_PROGRAM__VI = 0x1F3A; +constexpr unsigned int mmDMIF_PG2_DPG_TEST_DEBUG_DATA__VI = 0x1F39; +constexpr unsigned int mmDMIF_PG2_DPG_TEST_DEBUG_INDEX__VI = 0x1F38; +constexpr unsigned int mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL__VI = 0x1F32; +constexpr unsigned int mmDMIF_PG3_DPG_HW_DEBUG_11__VI = 0x413D; +constexpr unsigned int mmDMIF_PG3_DPG_HW_DEBUG_A__VI = 0x413B; +constexpr unsigned int mmDMIF_PG3_DPG_HW_DEBUG_B__VI = 0x413C; +constexpr unsigned int mmDMIF_PG3_DPG_PIPE_ARBITRATION_CONTROL1__VI = 0x4130; +constexpr unsigned int mmDMIF_PG3_DPG_PIPE_ARBITRATION_CONTROL2__VI = 0x4131; +constexpr unsigned int mmDMIF_PG3_DPG_PIPE_DPM_CONTROL__VI = 0x4134; +constexpr unsigned int mmDMIF_PG3_DPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x4136; +constexpr unsigned int mmDMIF_PG3_DPG_PIPE_STUTTER_CONTROL__VI = 0x4135; +constexpr unsigned int mmDMIF_PG3_DPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x4137; +constexpr unsigned int mmDMIF_PG3_DPG_PIPE_URGENCY_CONTROL__VI = 0x4133; +constexpr unsigned int mmDMIF_PG3_DPG_REPEATER_PROGRAM__VI = 0x413A; +constexpr unsigned int mmDMIF_PG3_DPG_TEST_DEBUG_DATA__VI = 0x4139; +constexpr unsigned int mmDMIF_PG3_DPG_TEST_DEBUG_INDEX__VI = 0x4138; +constexpr unsigned int mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL__VI = 0x4132; +constexpr unsigned int mmDMIF_PG4_DPG_HW_DEBUG_11__VI = 0x433D; +constexpr unsigned int mmDMIF_PG4_DPG_HW_DEBUG_A__VI = 0x433B; +constexpr unsigned int mmDMIF_PG4_DPG_HW_DEBUG_B__VI = 0x433C; +constexpr unsigned int mmDMIF_PG4_DPG_PIPE_ARBITRATION_CONTROL1__VI = 0x4330; +constexpr unsigned int mmDMIF_PG4_DPG_PIPE_ARBITRATION_CONTROL2__VI = 0x4331; +constexpr unsigned int mmDMIF_PG4_DPG_PIPE_DPM_CONTROL__VI = 0x4334; +constexpr unsigned int mmDMIF_PG4_DPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x4336; +constexpr unsigned int mmDMIF_PG4_DPG_PIPE_STUTTER_CONTROL__VI = 0x4335; +constexpr unsigned int mmDMIF_PG4_DPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x4337; +constexpr unsigned int mmDMIF_PG4_DPG_PIPE_URGENCY_CONTROL__VI = 0x4333; +constexpr unsigned int mmDMIF_PG4_DPG_REPEATER_PROGRAM__VI = 0x433A; +constexpr unsigned int mmDMIF_PG4_DPG_TEST_DEBUG_DATA__VI = 0x4339; +constexpr unsigned int mmDMIF_PG4_DPG_TEST_DEBUG_INDEX__VI = 0x4338; +constexpr unsigned int mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL__VI = 0x4332; +constexpr unsigned int mmDMIF_PG5_DPG_HW_DEBUG_11__VI = 0x453D; +constexpr unsigned int mmDMIF_PG5_DPG_HW_DEBUG_A__VI = 0x453B; +constexpr unsigned int mmDMIF_PG5_DPG_HW_DEBUG_B__VI = 0x453C; +constexpr unsigned int mmDMIF_PG5_DPG_PIPE_ARBITRATION_CONTROL1__VI = 0x4530; +constexpr unsigned int mmDMIF_PG5_DPG_PIPE_ARBITRATION_CONTROL2__VI = 0x4531; +constexpr unsigned int mmDMIF_PG5_DPG_PIPE_DPM_CONTROL__VI = 0x4534; +constexpr unsigned int mmDMIF_PG5_DPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x4536; +constexpr unsigned int mmDMIF_PG5_DPG_PIPE_STUTTER_CONTROL__VI = 0x4535; +constexpr unsigned int mmDMIF_PG5_DPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x4537; +constexpr unsigned int mmDMIF_PG5_DPG_PIPE_URGENCY_CONTROL__VI = 0x4533; +constexpr unsigned int mmDMIF_PG5_DPG_REPEATER_PROGRAM__VI = 0x453A; +constexpr unsigned int mmDMIF_PG5_DPG_TEST_DEBUG_DATA__VI = 0x4539; +constexpr unsigned int mmDMIF_PG5_DPG_TEST_DEBUG_INDEX__VI = 0x4538; +constexpr unsigned int mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL__VI = 0x4532; +constexpr unsigned int mmDMIF_PG6_DPG_HW_DEBUG_11__VI = 0x473D; +constexpr unsigned int mmDMIF_PG6_DPG_HW_DEBUG_A__VI = 0x473B; +constexpr unsigned int mmDMIF_PG6_DPG_HW_DEBUG_B__VI = 0x473C; +constexpr unsigned int mmDMIF_PG6_DPG_PIPE_ARBITRATION_CONTROL1__VI = 0x4730; +constexpr unsigned int mmDMIF_PG6_DPG_PIPE_ARBITRATION_CONTROL2__VI = 0x4731; +constexpr unsigned int mmDMIF_PG6_DPG_PIPE_DPM_CONTROL__VI = 0x4734; +constexpr unsigned int mmDMIF_PG6_DPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x4736; +constexpr unsigned int mmDMIF_PG6_DPG_PIPE_STUTTER_CONTROL__VI = 0x4735; +constexpr unsigned int mmDMIF_PG6_DPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x4737; +constexpr unsigned int mmDMIF_PG6_DPG_PIPE_URGENCY_CONTROL__VI = 0x4733; +constexpr unsigned int mmDMIF_PG6_DPG_REPEATER_PROGRAM__VI = 0x473A; +constexpr unsigned int mmDMIF_PG6_DPG_TEST_DEBUG_DATA__VI = 0x4739; +constexpr unsigned int mmDMIF_PG6_DPG_TEST_DEBUG_INDEX__VI = 0x4738; +constexpr unsigned int mmDMIF_PG6_DPG_WATERMARK_MASK_CONTROL__VI = 0x4732; +constexpr unsigned int mmDMIF_P_VMID__VI = 0x0300; +constexpr unsigned int mmDMIF_STATUS2__VI = 0x0304; +constexpr unsigned int mmDMIF_TEST_DEBUG_DATA__VI = 0x0302; +constexpr unsigned int mmDMIF_TEST_DEBUG_INDEX__VI = 0x0301; +constexpr unsigned int mmDMIF_URG_OVERRIDE__VI = 0x0329; +constexpr unsigned int mmDP0_DP_CONFIG__VI = 0x4AA3; +constexpr unsigned int mmDP0_DP_DPHY_8B10B_CNTL__VI = 0x4AB4; +constexpr unsigned int mmDP0_DP_DPHY_CNTL__VI = 0x4AAF; +constexpr unsigned int mmDP0_DP_DPHY_CRC_CNTL__VI = 0x4AB8; +constexpr unsigned int mmDP0_DP_DPHY_CRC_EN__VI = 0x4AB7; +constexpr unsigned int mmDP0_DP_DPHY_CRC_MST_CNTL__VI = 0x4ABA; +constexpr unsigned int mmDP0_DP_DPHY_CRC_MST_STATUS__VI = 0x4ABB; +constexpr unsigned int mmDP0_DP_DPHY_CRC_RESULT__VI = 0x4AB9; +constexpr unsigned int mmDP0_DP_DPHY_FAST_TRAINING__VI = 0x4ABC; +constexpr unsigned int mmDP0_DP_DPHY_FAST_TRAINING_STATUS__VI = 0x4ABD; +constexpr unsigned int mmDP0_DP_DPHY_PRBS_CNTL__VI = 0x4AB5; +constexpr unsigned int mmDP0_DP_DPHY_SYM0__VI = 0x4AB1; +constexpr unsigned int mmDP0_DP_DPHY_SYM1__VI = 0x4AB2; +constexpr unsigned int mmDP0_DP_DPHY_SYM2__VI = 0x4AB3; +constexpr unsigned int mmDP0_DP_DPHY_TRAINING_PATTERN_SEL__VI = 0x4AB0; +constexpr unsigned int mmDP0_DP_FE_TEST_DEBUG_DATA__VI = 0x4ADB; +constexpr unsigned int mmDP0_DP_FE_TEST_DEBUG_INDEX__VI = 0x4ADA; +constexpr unsigned int mmDP0_DP_HBR2_EYE_PATTERN__VI = 0x4AAC; +constexpr unsigned int mmDP0_DP_LINK_CNTL__VI = 0x4AA0; +constexpr unsigned int mmDP0_DP_LINK_FRAMING_CNTL__VI = 0x4AAB; +constexpr unsigned int mmDP0_DP_MSA_COLORIMETRY__VI = 0x4AA2; +constexpr unsigned int mmDP0_DP_MSA_MISC__VI = 0x4AA6; +constexpr unsigned int mmDP0_DP_MSA_V_TIMING_OVERRIDE1__VI = 0x4ABE; +constexpr unsigned int mmDP0_DP_MSA_V_TIMING_OVERRIDE2__VI = 0x4ABF; +constexpr unsigned int mmDP0_DP_MSE_LINK_TIMING__VI = 0x4AD6; +constexpr unsigned int mmDP0_DP_MSE_MISC_CNTL__VI = 0x4AD7; +constexpr unsigned int mmDP0_DP_MSE_RATE_CNTL__VI = 0x4ACF; +constexpr unsigned int mmDP0_DP_MSE_RATE_UPDATE__VI = 0x4AD1; +constexpr unsigned int mmDP0_DP_MSE_SAT0__VI = 0x4AD2; +constexpr unsigned int mmDP0_DP_MSE_SAT1__VI = 0x4AD3; +constexpr unsigned int mmDP0_DP_MSE_SAT2__VI = 0x4AD4; +constexpr unsigned int mmDP0_DP_MSE_SAT_UPDATE__VI = 0x4AD5; +constexpr unsigned int mmDP0_DP_PIXEL_FORMAT__VI = 0x4AA1; +constexpr unsigned int mmDP0_DP_SEC_AUD_M__VI = 0x4ACB; +constexpr unsigned int mmDP0_DP_SEC_AUD_M_READBACK__VI = 0x4ACC; +constexpr unsigned int mmDP0_DP_SEC_AUD_N__VI = 0x4AC9; +constexpr unsigned int mmDP0_DP_SEC_AUD_N_READBACK__VI = 0x4ACA; +constexpr unsigned int mmDP0_DP_SEC_CNTL__VI = 0x4AC3; +constexpr unsigned int mmDP0_DP_SEC_CNTL1__VI = 0x4AC4; +constexpr unsigned int mmDP0_DP_SEC_FRAMING1__VI = 0x4AC5; +constexpr unsigned int mmDP0_DP_SEC_FRAMING2__VI = 0x4AC6; +constexpr unsigned int mmDP0_DP_SEC_FRAMING3__VI = 0x4AC7; +constexpr unsigned int mmDP0_DP_SEC_FRAMING4__VI = 0x4AC8; +constexpr unsigned int mmDP0_DP_SEC_PACKET_CNTL__VI = 0x4ACE; +constexpr unsigned int mmDP0_DP_SEC_TIMESTAMP__VI = 0x4ACD; +constexpr unsigned int mmDP0_DP_STEER_FIFO__VI = 0x4AA5; +constexpr unsigned int mmDP0_DP_TEST_DEBUG_DATA__VI = 0x4AD9; +constexpr unsigned int mmDP0_DP_TEST_DEBUG_INDEX__VI = 0x4AD8; +constexpr unsigned int mmDP0_DP_VID_INTERRUPT_CNTL__VI = 0x4AAE; +constexpr unsigned int mmDP0_DP_VID_M__VI = 0x4AAA; +constexpr unsigned int mmDP0_DP_VID_MSA_VBID__VI = 0x4AAD; +constexpr unsigned int mmDP0_DP_VID_N__VI = 0x4AA9; +constexpr unsigned int mmDP0_DP_VID_STREAM_CNTL__VI = 0x4AA4; +constexpr unsigned int mmDP0_DP_VID_TIMING__VI = 0x4AA8; +constexpr unsigned int mmDP1_DP_CONFIG__VI = 0x4BA3; +constexpr unsigned int mmDP1_DP_DPHY_8B10B_CNTL__VI = 0x4BB4; +constexpr unsigned int mmDP1_DP_DPHY_CNTL__VI = 0x4BAF; +constexpr unsigned int mmDP1_DP_DPHY_CRC_CNTL__VI = 0x4BB8; +constexpr unsigned int mmDP1_DP_DPHY_CRC_EN__VI = 0x4BB7; +constexpr unsigned int mmDP1_DP_DPHY_CRC_MST_CNTL__VI = 0x4BBA; +constexpr unsigned int mmDP1_DP_DPHY_CRC_MST_STATUS__VI = 0x4BBB; +constexpr unsigned int mmDP1_DP_DPHY_CRC_RESULT__VI = 0x4BB9; +constexpr unsigned int mmDP1_DP_DPHY_FAST_TRAINING__VI = 0x4BBC; +constexpr unsigned int mmDP1_DP_DPHY_FAST_TRAINING_STATUS__VI = 0x4BBD; +constexpr unsigned int mmDP1_DP_DPHY_PRBS_CNTL__VI = 0x4BB5; +constexpr unsigned int mmDP1_DP_DPHY_SYM0__VI = 0x4BB1; +constexpr unsigned int mmDP1_DP_DPHY_SYM1__VI = 0x4BB2; +constexpr unsigned int mmDP1_DP_DPHY_SYM2__VI = 0x4BB3; +constexpr unsigned int mmDP1_DP_DPHY_TRAINING_PATTERN_SEL__VI = 0x4BB0; +constexpr unsigned int mmDP1_DP_FE_TEST_DEBUG_DATA__VI = 0x4BDB; +constexpr unsigned int mmDP1_DP_FE_TEST_DEBUG_INDEX__VI = 0x4BDA; +constexpr unsigned int mmDP1_DP_HBR2_EYE_PATTERN__VI = 0x4BAC; +constexpr unsigned int mmDP1_DP_LINK_CNTL__VI = 0x4BA0; +constexpr unsigned int mmDP1_DP_LINK_FRAMING_CNTL__VI = 0x4BAB; +constexpr unsigned int mmDP1_DP_MSA_COLORIMETRY__VI = 0x4BA2; +constexpr unsigned int mmDP1_DP_MSA_MISC__VI = 0x4BA6; +constexpr unsigned int mmDP1_DP_MSA_V_TIMING_OVERRIDE1__VI = 0x4BBE; +constexpr unsigned int mmDP1_DP_MSA_V_TIMING_OVERRIDE2__VI = 0x4BBF; +constexpr unsigned int mmDP1_DP_MSE_LINK_TIMING__VI = 0x4BD6; +constexpr unsigned int mmDP1_DP_MSE_MISC_CNTL__VI = 0x4BD7; +constexpr unsigned int mmDP1_DP_MSE_RATE_CNTL__VI = 0x4BCF; +constexpr unsigned int mmDP1_DP_MSE_RATE_UPDATE__VI = 0x4BD1; +constexpr unsigned int mmDP1_DP_MSE_SAT0__VI = 0x4BD2; +constexpr unsigned int mmDP1_DP_MSE_SAT1__VI = 0x4BD3; +constexpr unsigned int mmDP1_DP_MSE_SAT2__VI = 0x4BD4; +constexpr unsigned int mmDP1_DP_MSE_SAT_UPDATE__VI = 0x4BD5; +constexpr unsigned int mmDP1_DP_PIXEL_FORMAT__VI = 0x4BA1; +constexpr unsigned int mmDP1_DP_SEC_AUD_M__VI = 0x4BCB; +constexpr unsigned int mmDP1_DP_SEC_AUD_M_READBACK__VI = 0x4BCC; +constexpr unsigned int mmDP1_DP_SEC_AUD_N__VI = 0x4BC9; +constexpr unsigned int mmDP1_DP_SEC_AUD_N_READBACK__VI = 0x4BCA; +constexpr unsigned int mmDP1_DP_SEC_CNTL__VI = 0x4BC3; +constexpr unsigned int mmDP1_DP_SEC_CNTL1__VI = 0x4BC4; +constexpr unsigned int mmDP1_DP_SEC_FRAMING1__VI = 0x4BC5; +constexpr unsigned int mmDP1_DP_SEC_FRAMING2__VI = 0x4BC6; +constexpr unsigned int mmDP1_DP_SEC_FRAMING3__VI = 0x4BC7; +constexpr unsigned int mmDP1_DP_SEC_FRAMING4__VI = 0x4BC8; +constexpr unsigned int mmDP1_DP_SEC_PACKET_CNTL__VI = 0x4BCE; +constexpr unsigned int mmDP1_DP_SEC_TIMESTAMP__VI = 0x4BCD; +constexpr unsigned int mmDP1_DP_STEER_FIFO__VI = 0x4BA5; +constexpr unsigned int mmDP1_DP_TEST_DEBUG_DATA__VI = 0x4BD9; +constexpr unsigned int mmDP1_DP_TEST_DEBUG_INDEX__VI = 0x4BD8; +constexpr unsigned int mmDP1_DP_VID_INTERRUPT_CNTL__VI = 0x4BAE; +constexpr unsigned int mmDP1_DP_VID_M__VI = 0x4BAA; +constexpr unsigned int mmDP1_DP_VID_MSA_VBID__VI = 0x4BAD; +constexpr unsigned int mmDP1_DP_VID_N__VI = 0x4BA9; +constexpr unsigned int mmDP1_DP_VID_STREAM_CNTL__VI = 0x4BA4; +constexpr unsigned int mmDP1_DP_VID_TIMING__VI = 0x4BA8; +constexpr unsigned int mmDP2_DP_CONFIG__VI = 0x4CA3; +constexpr unsigned int mmDP2_DP_DPHY_8B10B_CNTL__VI = 0x4CB4; +constexpr unsigned int mmDP2_DP_DPHY_CNTL__VI = 0x4CAF; +constexpr unsigned int mmDP2_DP_DPHY_CRC_CNTL__VI = 0x4CB8; +constexpr unsigned int mmDP2_DP_DPHY_CRC_EN__VI = 0x4CB7; +constexpr unsigned int mmDP2_DP_DPHY_CRC_MST_CNTL__VI = 0x4CBA; +constexpr unsigned int mmDP2_DP_DPHY_CRC_MST_STATUS__VI = 0x4CBB; +constexpr unsigned int mmDP2_DP_DPHY_CRC_RESULT__VI = 0x4CB9; +constexpr unsigned int mmDP2_DP_DPHY_FAST_TRAINING__VI = 0x4CBC; +constexpr unsigned int mmDP2_DP_DPHY_FAST_TRAINING_STATUS__VI = 0x4CBD; +constexpr unsigned int mmDP2_DP_DPHY_PRBS_CNTL__VI = 0x4CB5; +constexpr unsigned int mmDP2_DP_DPHY_SYM0__VI = 0x4CB1; +constexpr unsigned int mmDP2_DP_DPHY_SYM1__VI = 0x4CB2; +constexpr unsigned int mmDP2_DP_DPHY_SYM2__VI = 0x4CB3; +constexpr unsigned int mmDP2_DP_DPHY_TRAINING_PATTERN_SEL__VI = 0x4CB0; +constexpr unsigned int mmDP2_DP_FE_TEST_DEBUG_DATA__VI = 0x4CDB; +constexpr unsigned int mmDP2_DP_FE_TEST_DEBUG_INDEX__VI = 0x4CDA; +constexpr unsigned int mmDP2_DP_HBR2_EYE_PATTERN__VI = 0x4CAC; +constexpr unsigned int mmDP2_DP_LINK_CNTL__VI = 0x4CA0; +constexpr unsigned int mmDP2_DP_LINK_FRAMING_CNTL__VI = 0x4CAB; +constexpr unsigned int mmDP2_DP_MSA_COLORIMETRY__VI = 0x4CA2; +constexpr unsigned int mmDP2_DP_MSA_MISC__VI = 0x4CA6; +constexpr unsigned int mmDP2_DP_MSA_V_TIMING_OVERRIDE1__VI = 0x4CBE; +constexpr unsigned int mmDP2_DP_MSA_V_TIMING_OVERRIDE2__VI = 0x4CBF; +constexpr unsigned int mmDP2_DP_MSE_LINK_TIMING__VI = 0x4CD6; +constexpr unsigned int mmDP2_DP_MSE_MISC_CNTL__VI = 0x4CD7; +constexpr unsigned int mmDP2_DP_MSE_RATE_CNTL__VI = 0x4CCF; +constexpr unsigned int mmDP2_DP_MSE_RATE_UPDATE__VI = 0x4CD1; +constexpr unsigned int mmDP2_DP_MSE_SAT0__VI = 0x4CD2; +constexpr unsigned int mmDP2_DP_MSE_SAT1__VI = 0x4CD3; +constexpr unsigned int mmDP2_DP_MSE_SAT2__VI = 0x4CD4; +constexpr unsigned int mmDP2_DP_MSE_SAT_UPDATE__VI = 0x4CD5; +constexpr unsigned int mmDP2_DP_PIXEL_FORMAT__VI = 0x4CA1; +constexpr unsigned int mmDP2_DP_SEC_AUD_M__VI = 0x4CCB; +constexpr unsigned int mmDP2_DP_SEC_AUD_M_READBACK__VI = 0x4CCC; +constexpr unsigned int mmDP2_DP_SEC_AUD_N__VI = 0x4CC9; +constexpr unsigned int mmDP2_DP_SEC_AUD_N_READBACK__VI = 0x4CCA; +constexpr unsigned int mmDP2_DP_SEC_CNTL__VI = 0x4CC3; +constexpr unsigned int mmDP2_DP_SEC_CNTL1__VI = 0x4CC4; +constexpr unsigned int mmDP2_DP_SEC_FRAMING1__VI = 0x4CC5; +constexpr unsigned int mmDP2_DP_SEC_FRAMING2__VI = 0x4CC6; +constexpr unsigned int mmDP2_DP_SEC_FRAMING3__VI = 0x4CC7; +constexpr unsigned int mmDP2_DP_SEC_FRAMING4__VI = 0x4CC8; +constexpr unsigned int mmDP2_DP_SEC_PACKET_CNTL__VI = 0x4CCE; +constexpr unsigned int mmDP2_DP_SEC_TIMESTAMP__VI = 0x4CCD; +constexpr unsigned int mmDP2_DP_STEER_FIFO__VI = 0x4CA5; +constexpr unsigned int mmDP2_DP_TEST_DEBUG_DATA__VI = 0x4CD9; +constexpr unsigned int mmDP2_DP_TEST_DEBUG_INDEX__VI = 0x4CD8; +constexpr unsigned int mmDP2_DP_VID_INTERRUPT_CNTL__VI = 0x4CAE; +constexpr unsigned int mmDP2_DP_VID_M__VI = 0x4CAA; +constexpr unsigned int mmDP2_DP_VID_MSA_VBID__VI = 0x4CAD; +constexpr unsigned int mmDP2_DP_VID_N__VI = 0x4CA9; +constexpr unsigned int mmDP2_DP_VID_STREAM_CNTL__VI = 0x4CA4; +constexpr unsigned int mmDP2_DP_VID_TIMING__VI = 0x4CA8; +constexpr unsigned int mmDP3_DP_CONFIG__VI = 0x4DA3; +constexpr unsigned int mmDP3_DP_DPHY_8B10B_CNTL__VI = 0x4DB4; +constexpr unsigned int mmDP3_DP_DPHY_CNTL__VI = 0x4DAF; +constexpr unsigned int mmDP3_DP_DPHY_CRC_CNTL__VI = 0x4DB8; +constexpr unsigned int mmDP3_DP_DPHY_CRC_EN__VI = 0x4DB7; +constexpr unsigned int mmDP3_DP_DPHY_CRC_MST_CNTL__VI = 0x4DBA; +constexpr unsigned int mmDP3_DP_DPHY_CRC_MST_STATUS__VI = 0x4DBB; +constexpr unsigned int mmDP3_DP_DPHY_CRC_RESULT__VI = 0x4DB9; +constexpr unsigned int mmDP3_DP_DPHY_FAST_TRAINING__VI = 0x4DBC; +constexpr unsigned int mmDP3_DP_DPHY_FAST_TRAINING_STATUS__VI = 0x4DBD; +constexpr unsigned int mmDP3_DP_DPHY_PRBS_CNTL__VI = 0x4DB5; +constexpr unsigned int mmDP3_DP_DPHY_SYM0__VI = 0x4DB1; +constexpr unsigned int mmDP3_DP_DPHY_SYM1__VI = 0x4DB2; +constexpr unsigned int mmDP3_DP_DPHY_SYM2__VI = 0x4DB3; +constexpr unsigned int mmDP3_DP_DPHY_TRAINING_PATTERN_SEL__VI = 0x4DB0; +constexpr unsigned int mmDP3_DP_FE_TEST_DEBUG_DATA__VI = 0x4DDB; +constexpr unsigned int mmDP3_DP_FE_TEST_DEBUG_INDEX__VI = 0x4DDA; +constexpr unsigned int mmDP3_DP_HBR2_EYE_PATTERN__VI = 0x4DAC; +constexpr unsigned int mmDP3_DP_LINK_CNTL__VI = 0x4DA0; +constexpr unsigned int mmDP3_DP_LINK_FRAMING_CNTL__VI = 0x4DAB; +constexpr unsigned int mmDP3_DP_MSA_COLORIMETRY__VI = 0x4DA2; +constexpr unsigned int mmDP3_DP_MSA_MISC__VI = 0x4DA6; +constexpr unsigned int mmDP3_DP_MSA_V_TIMING_OVERRIDE1__VI = 0x4DBE; +constexpr unsigned int mmDP3_DP_MSA_V_TIMING_OVERRIDE2__VI = 0x4DBF; +constexpr unsigned int mmDP3_DP_MSE_LINK_TIMING__VI = 0x4DD6; +constexpr unsigned int mmDP3_DP_MSE_MISC_CNTL__VI = 0x4DD7; +constexpr unsigned int mmDP3_DP_MSE_RATE_CNTL__VI = 0x4DCF; +constexpr unsigned int mmDP3_DP_MSE_RATE_UPDATE__VI = 0x4DD1; +constexpr unsigned int mmDP3_DP_MSE_SAT0__VI = 0x4DD2; +constexpr unsigned int mmDP3_DP_MSE_SAT1__VI = 0x4DD3; +constexpr unsigned int mmDP3_DP_MSE_SAT2__VI = 0x4DD4; +constexpr unsigned int mmDP3_DP_MSE_SAT_UPDATE__VI = 0x4DD5; +constexpr unsigned int mmDP3_DP_PIXEL_FORMAT__VI = 0x4DA1; +constexpr unsigned int mmDP3_DP_SEC_AUD_M__VI = 0x4DCB; +constexpr unsigned int mmDP3_DP_SEC_AUD_M_READBACK__VI = 0x4DCC; +constexpr unsigned int mmDP3_DP_SEC_AUD_N__VI = 0x4DC9; +constexpr unsigned int mmDP3_DP_SEC_AUD_N_READBACK__VI = 0x4DCA; +constexpr unsigned int mmDP3_DP_SEC_CNTL__VI = 0x4DC3; +constexpr unsigned int mmDP3_DP_SEC_CNTL1__VI = 0x4DC4; +constexpr unsigned int mmDP3_DP_SEC_FRAMING1__VI = 0x4DC5; +constexpr unsigned int mmDP3_DP_SEC_FRAMING2__VI = 0x4DC6; +constexpr unsigned int mmDP3_DP_SEC_FRAMING3__VI = 0x4DC7; +constexpr unsigned int mmDP3_DP_SEC_FRAMING4__VI = 0x4DC8; +constexpr unsigned int mmDP3_DP_SEC_PACKET_CNTL__VI = 0x4DCE; +constexpr unsigned int mmDP3_DP_SEC_TIMESTAMP__VI = 0x4DCD; +constexpr unsigned int mmDP3_DP_STEER_FIFO__VI = 0x4DA5; +constexpr unsigned int mmDP3_DP_TEST_DEBUG_DATA__VI = 0x4DD9; +constexpr unsigned int mmDP3_DP_TEST_DEBUG_INDEX__VI = 0x4DD8; +constexpr unsigned int mmDP3_DP_VID_INTERRUPT_CNTL__VI = 0x4DAE; +constexpr unsigned int mmDP3_DP_VID_M__VI = 0x4DAA; +constexpr unsigned int mmDP3_DP_VID_MSA_VBID__VI = 0x4DAD; +constexpr unsigned int mmDP3_DP_VID_N__VI = 0x4DA9; +constexpr unsigned int mmDP3_DP_VID_STREAM_CNTL__VI = 0x4DA4; +constexpr unsigned int mmDP3_DP_VID_TIMING__VI = 0x4DA8; +constexpr unsigned int mmDP4_DP_CONFIG__VI = 0x4EA3; +constexpr unsigned int mmDP4_DP_DPHY_8B10B_CNTL__VI = 0x4EB4; +constexpr unsigned int mmDP4_DP_DPHY_CNTL__VI = 0x4EAF; +constexpr unsigned int mmDP4_DP_DPHY_CRC_CNTL__VI = 0x4EB8; +constexpr unsigned int mmDP4_DP_DPHY_CRC_EN__VI = 0x4EB7; +constexpr unsigned int mmDP4_DP_DPHY_CRC_MST_CNTL__VI = 0x4EBA; +constexpr unsigned int mmDP4_DP_DPHY_CRC_MST_STATUS__VI = 0x4EBB; +constexpr unsigned int mmDP4_DP_DPHY_CRC_RESULT__VI = 0x4EB9; +constexpr unsigned int mmDP4_DP_DPHY_FAST_TRAINING__VI = 0x4EBC; +constexpr unsigned int mmDP4_DP_DPHY_FAST_TRAINING_STATUS__VI = 0x4EBD; +constexpr unsigned int mmDP4_DP_DPHY_PRBS_CNTL__VI = 0x4EB5; +constexpr unsigned int mmDP4_DP_DPHY_SYM0__VI = 0x4EB1; +constexpr unsigned int mmDP4_DP_DPHY_SYM1__VI = 0x4EB2; +constexpr unsigned int mmDP4_DP_DPHY_SYM2__VI = 0x4EB3; +constexpr unsigned int mmDP4_DP_DPHY_TRAINING_PATTERN_SEL__VI = 0x4EB0; +constexpr unsigned int mmDP4_DP_FE_TEST_DEBUG_DATA__VI = 0x4EDB; +constexpr unsigned int mmDP4_DP_FE_TEST_DEBUG_INDEX__VI = 0x4EDA; +constexpr unsigned int mmDP4_DP_HBR2_EYE_PATTERN__VI = 0x4EAC; +constexpr unsigned int mmDP4_DP_LINK_CNTL__VI = 0x4EA0; +constexpr unsigned int mmDP4_DP_LINK_FRAMING_CNTL__VI = 0x4EAB; +constexpr unsigned int mmDP4_DP_MSA_COLORIMETRY__VI = 0x4EA2; +constexpr unsigned int mmDP4_DP_MSA_MISC__VI = 0x4EA6; +constexpr unsigned int mmDP4_DP_MSA_V_TIMING_OVERRIDE1__VI = 0x4EBE; +constexpr unsigned int mmDP4_DP_MSA_V_TIMING_OVERRIDE2__VI = 0x4EBF; +constexpr unsigned int mmDP4_DP_MSE_LINK_TIMING__VI = 0x4ED6; +constexpr unsigned int mmDP4_DP_MSE_MISC_CNTL__VI = 0x4ED7; +constexpr unsigned int mmDP4_DP_MSE_RATE_CNTL__VI = 0x4ECF; +constexpr unsigned int mmDP4_DP_MSE_RATE_UPDATE__VI = 0x4ED1; +constexpr unsigned int mmDP4_DP_MSE_SAT0__VI = 0x4ED2; +constexpr unsigned int mmDP4_DP_MSE_SAT1__VI = 0x4ED3; +constexpr unsigned int mmDP4_DP_MSE_SAT2__VI = 0x4ED4; +constexpr unsigned int mmDP4_DP_MSE_SAT_UPDATE__VI = 0x4ED5; +constexpr unsigned int mmDP4_DP_PIXEL_FORMAT__VI = 0x4EA1; +constexpr unsigned int mmDP4_DP_SEC_AUD_M__VI = 0x4ECB; +constexpr unsigned int mmDP4_DP_SEC_AUD_M_READBACK__VI = 0x4ECC; +constexpr unsigned int mmDP4_DP_SEC_AUD_N__VI = 0x4EC9; +constexpr unsigned int mmDP4_DP_SEC_AUD_N_READBACK__VI = 0x4ECA; +constexpr unsigned int mmDP4_DP_SEC_CNTL__VI = 0x4EC3; +constexpr unsigned int mmDP4_DP_SEC_CNTL1__VI = 0x4EC4; +constexpr unsigned int mmDP4_DP_SEC_FRAMING1__VI = 0x4EC5; +constexpr unsigned int mmDP4_DP_SEC_FRAMING2__VI = 0x4EC6; +constexpr unsigned int mmDP4_DP_SEC_FRAMING3__VI = 0x4EC7; +constexpr unsigned int mmDP4_DP_SEC_FRAMING4__VI = 0x4EC8; +constexpr unsigned int mmDP4_DP_SEC_PACKET_CNTL__VI = 0x4ECE; +constexpr unsigned int mmDP4_DP_SEC_TIMESTAMP__VI = 0x4ECD; +constexpr unsigned int mmDP4_DP_STEER_FIFO__VI = 0x4EA5; +constexpr unsigned int mmDP4_DP_TEST_DEBUG_DATA__VI = 0x4ED9; +constexpr unsigned int mmDP4_DP_TEST_DEBUG_INDEX__VI = 0x4ED8; +constexpr unsigned int mmDP4_DP_VID_INTERRUPT_CNTL__VI = 0x4EAE; +constexpr unsigned int mmDP4_DP_VID_M__VI = 0x4EAA; +constexpr unsigned int mmDP4_DP_VID_MSA_VBID__VI = 0x4EAD; +constexpr unsigned int mmDP4_DP_VID_N__VI = 0x4EA9; +constexpr unsigned int mmDP4_DP_VID_STREAM_CNTL__VI = 0x4EA4; +constexpr unsigned int mmDP4_DP_VID_TIMING__VI = 0x4EA8; +constexpr unsigned int mmDP5_DP_CONFIG__VI = 0x4FA3; +constexpr unsigned int mmDP5_DP_DPHY_8B10B_CNTL__VI = 0x4FB4; +constexpr unsigned int mmDP5_DP_DPHY_CNTL__VI = 0x4FAF; +constexpr unsigned int mmDP5_DP_DPHY_CRC_CNTL__VI = 0x4FB8; +constexpr unsigned int mmDP5_DP_DPHY_CRC_EN__VI = 0x4FB7; +constexpr unsigned int mmDP5_DP_DPHY_CRC_MST_CNTL__VI = 0x4FBA; +constexpr unsigned int mmDP5_DP_DPHY_CRC_MST_STATUS__VI = 0x4FBB; +constexpr unsigned int mmDP5_DP_DPHY_CRC_RESULT__VI = 0x4FB9; +constexpr unsigned int mmDP5_DP_DPHY_FAST_TRAINING__VI = 0x4FBC; +constexpr unsigned int mmDP5_DP_DPHY_FAST_TRAINING_STATUS__VI = 0x4FBD; +constexpr unsigned int mmDP5_DP_DPHY_PRBS_CNTL__VI = 0x4FB5; +constexpr unsigned int mmDP5_DP_DPHY_SYM0__VI = 0x4FB1; +constexpr unsigned int mmDP5_DP_DPHY_SYM1__VI = 0x4FB2; +constexpr unsigned int mmDP5_DP_DPHY_SYM2__VI = 0x4FB3; +constexpr unsigned int mmDP5_DP_DPHY_TRAINING_PATTERN_SEL__VI = 0x4FB0; +constexpr unsigned int mmDP5_DP_FE_TEST_DEBUG_DATA__VI = 0x4FDB; +constexpr unsigned int mmDP5_DP_FE_TEST_DEBUG_INDEX__VI = 0x4FDA; +constexpr unsigned int mmDP5_DP_HBR2_EYE_PATTERN__VI = 0x4FAC; +constexpr unsigned int mmDP5_DP_LINK_CNTL__VI = 0x4FA0; +constexpr unsigned int mmDP5_DP_LINK_FRAMING_CNTL__VI = 0x4FAB; +constexpr unsigned int mmDP5_DP_MSA_COLORIMETRY__VI = 0x4FA2; +constexpr unsigned int mmDP5_DP_MSA_MISC__VI = 0x4FA6; +constexpr unsigned int mmDP5_DP_MSA_V_TIMING_OVERRIDE1__VI = 0x4FBE; +constexpr unsigned int mmDP5_DP_MSA_V_TIMING_OVERRIDE2__VI = 0x4FBF; +constexpr unsigned int mmDP5_DP_MSE_LINK_TIMING__VI = 0x4FD6; +constexpr unsigned int mmDP5_DP_MSE_MISC_CNTL__VI = 0x4FD7; +constexpr unsigned int mmDP5_DP_MSE_RATE_CNTL__VI = 0x4FCF; +constexpr unsigned int mmDP5_DP_MSE_RATE_UPDATE__VI = 0x4FD1; +constexpr unsigned int mmDP5_DP_MSE_SAT0__VI = 0x4FD2; +constexpr unsigned int mmDP5_DP_MSE_SAT1__VI = 0x4FD3; +constexpr unsigned int mmDP5_DP_MSE_SAT2__VI = 0x4FD4; +constexpr unsigned int mmDP5_DP_MSE_SAT_UPDATE__VI = 0x4FD5; +constexpr unsigned int mmDP5_DP_PIXEL_FORMAT__VI = 0x4FA1; +constexpr unsigned int mmDP5_DP_SEC_AUD_M__VI = 0x4FCB; +constexpr unsigned int mmDP5_DP_SEC_AUD_M_READBACK__VI = 0x4FCC; +constexpr unsigned int mmDP5_DP_SEC_AUD_N__VI = 0x4FC9; +constexpr unsigned int mmDP5_DP_SEC_AUD_N_READBACK__VI = 0x4FCA; +constexpr unsigned int mmDP5_DP_SEC_CNTL__VI = 0x4FC3; +constexpr unsigned int mmDP5_DP_SEC_CNTL1__VI = 0x4FC4; +constexpr unsigned int mmDP5_DP_SEC_FRAMING1__VI = 0x4FC5; +constexpr unsigned int mmDP5_DP_SEC_FRAMING2__VI = 0x4FC6; +constexpr unsigned int mmDP5_DP_SEC_FRAMING3__VI = 0x4FC7; +constexpr unsigned int mmDP5_DP_SEC_FRAMING4__VI = 0x4FC8; +constexpr unsigned int mmDP5_DP_SEC_PACKET_CNTL__VI = 0x4FCE; +constexpr unsigned int mmDP5_DP_SEC_TIMESTAMP__VI = 0x4FCD; +constexpr unsigned int mmDP5_DP_STEER_FIFO__VI = 0x4FA5; +constexpr unsigned int mmDP5_DP_TEST_DEBUG_DATA__VI = 0x4FD9; +constexpr unsigned int mmDP5_DP_TEST_DEBUG_INDEX__VI = 0x4FD8; +constexpr unsigned int mmDP5_DP_VID_INTERRUPT_CNTL__VI = 0x4FAE; +constexpr unsigned int mmDP5_DP_VID_M__VI = 0x4FAA; +constexpr unsigned int mmDP5_DP_VID_MSA_VBID__VI = 0x4FAD; +constexpr unsigned int mmDP5_DP_VID_N__VI = 0x4FA9; +constexpr unsigned int mmDP5_DP_VID_STREAM_CNTL__VI = 0x4FA4; +constexpr unsigned int mmDP5_DP_VID_TIMING__VI = 0x4FA8; +constexpr unsigned int mmDP6_DP_CONFIG__VI = 0x54A3; +constexpr unsigned int mmDP6_DP_DPHY_8B10B_CNTL__VI = 0x54B4; +constexpr unsigned int mmDP6_DP_DPHY_CNTL__VI = 0x54AF; +constexpr unsigned int mmDP6_DP_DPHY_CRC_CNTL__VI = 0x54B8; +constexpr unsigned int mmDP6_DP_DPHY_CRC_EN__VI = 0x54B7; +constexpr unsigned int mmDP6_DP_DPHY_CRC_MST_CNTL__VI = 0x54BA; +constexpr unsigned int mmDP6_DP_DPHY_CRC_MST_STATUS__VI = 0x54BB; +constexpr unsigned int mmDP6_DP_DPHY_CRC_RESULT__VI = 0x54B9; +constexpr unsigned int mmDP6_DP_DPHY_FAST_TRAINING__VI = 0x54BC; +constexpr unsigned int mmDP6_DP_DPHY_FAST_TRAINING_STATUS__VI = 0x54BD; +constexpr unsigned int mmDP6_DP_DPHY_PRBS_CNTL__VI = 0x54B5; +constexpr unsigned int mmDP6_DP_DPHY_SYM0__VI = 0x54B1; +constexpr unsigned int mmDP6_DP_DPHY_SYM1__VI = 0x54B2; +constexpr unsigned int mmDP6_DP_DPHY_SYM2__VI = 0x54B3; +constexpr unsigned int mmDP6_DP_DPHY_TRAINING_PATTERN_SEL__VI = 0x54B0; +constexpr unsigned int mmDP6_DP_FE_TEST_DEBUG_DATA__VI = 0x54DB; +constexpr unsigned int mmDP6_DP_FE_TEST_DEBUG_INDEX__VI = 0x54DA; +constexpr unsigned int mmDP6_DP_HBR2_EYE_PATTERN__VI = 0x54AC; +constexpr unsigned int mmDP6_DP_LINK_CNTL__VI = 0x54A0; +constexpr unsigned int mmDP6_DP_LINK_FRAMING_CNTL__VI = 0x54AB; +constexpr unsigned int mmDP6_DP_MSA_COLORIMETRY__VI = 0x54A2; +constexpr unsigned int mmDP6_DP_MSA_MISC__VI = 0x54A6; +constexpr unsigned int mmDP6_DP_MSA_V_TIMING_OVERRIDE1__VI = 0x54BE; +constexpr unsigned int mmDP6_DP_MSA_V_TIMING_OVERRIDE2__VI = 0x54BF; +constexpr unsigned int mmDP6_DP_MSE_LINK_TIMING__VI = 0x54D6; +constexpr unsigned int mmDP6_DP_MSE_MISC_CNTL__VI = 0x54D7; +constexpr unsigned int mmDP6_DP_MSE_RATE_CNTL__VI = 0x54CF; +constexpr unsigned int mmDP6_DP_MSE_RATE_UPDATE__VI = 0x54D1; +constexpr unsigned int mmDP6_DP_MSE_SAT0__VI = 0x54D2; +constexpr unsigned int mmDP6_DP_MSE_SAT1__VI = 0x54D3; +constexpr unsigned int mmDP6_DP_MSE_SAT2__VI = 0x54D4; +constexpr unsigned int mmDP6_DP_MSE_SAT_UPDATE__VI = 0x54D5; +constexpr unsigned int mmDP6_DP_PIXEL_FORMAT__VI = 0x54A1; +constexpr unsigned int mmDP6_DP_SEC_AUD_M__VI = 0x54CB; +constexpr unsigned int mmDP6_DP_SEC_AUD_M_READBACK__VI = 0x54CC; +constexpr unsigned int mmDP6_DP_SEC_AUD_N__VI = 0x54C9; +constexpr unsigned int mmDP6_DP_SEC_AUD_N_READBACK__VI = 0x54CA; +constexpr unsigned int mmDP6_DP_SEC_CNTL__VI = 0x54C3; +constexpr unsigned int mmDP6_DP_SEC_CNTL1__VI = 0x54C4; +constexpr unsigned int mmDP6_DP_SEC_FRAMING1__VI = 0x54C5; +constexpr unsigned int mmDP6_DP_SEC_FRAMING2__VI = 0x54C6; +constexpr unsigned int mmDP6_DP_SEC_FRAMING3__VI = 0x54C7; +constexpr unsigned int mmDP6_DP_SEC_FRAMING4__VI = 0x54C8; +constexpr unsigned int mmDP6_DP_SEC_PACKET_CNTL__VI = 0x54CE; +constexpr unsigned int mmDP6_DP_SEC_TIMESTAMP__VI = 0x54CD; +constexpr unsigned int mmDP6_DP_STEER_FIFO__VI = 0x54A5; +constexpr unsigned int mmDP6_DP_TEST_DEBUG_DATA__VI = 0x54D9; +constexpr unsigned int mmDP6_DP_TEST_DEBUG_INDEX__VI = 0x54D8; +constexpr unsigned int mmDP6_DP_VID_INTERRUPT_CNTL__VI = 0x54AE; +constexpr unsigned int mmDP6_DP_VID_M__VI = 0x54AA; +constexpr unsigned int mmDP6_DP_VID_MSA_VBID__VI = 0x54AD; +constexpr unsigned int mmDP6_DP_VID_N__VI = 0x54A9; +constexpr unsigned int mmDP6_DP_VID_STREAM_CNTL__VI = 0x54A4; +constexpr unsigned int mmDP6_DP_VID_TIMING__VI = 0x54A8; +constexpr unsigned int mmDPDBG_CLK_FORCE_CONTROL__VI = 0x010D; +constexpr unsigned int mmDPDBG_CNTL__VI = 0x1866; +constexpr unsigned int mmDPDBG_INTERRUPT__VI = 0x1867; +constexpr unsigned int mmDPG_HW_DEBUG_11__VI = 0x1B3D; +constexpr unsigned int mmDPG_HW_DEBUG_A__VI = 0x1B3B; +constexpr unsigned int mmDPG_HW_DEBUG_B__VI = 0x1B3C; +constexpr unsigned int mmDPG_PIPE_ARBITRATION_CONTROL1__VI = 0x1B30; +constexpr unsigned int mmDPG_PIPE_ARBITRATION_CONTROL2__VI = 0x1B31; +constexpr unsigned int mmDPG_PIPE_DPM_CONTROL__VI = 0x1B34; +constexpr unsigned int mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL__VI = 0x1B36; +constexpr unsigned int mmDPG_PIPE_STUTTER_CONTROL__VI = 0x1B35; +constexpr unsigned int mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH__VI = 0x1B37; +constexpr unsigned int mmDPG_PIPE_URGENCY_CONTROL__VI = 0x1B33; +constexpr unsigned int mmDPG_REPEATER_PROGRAM__VI = 0x1B3A; +constexpr unsigned int mmDPG_TEST_DEBUG_DATA__VI = 0x1B39; +constexpr unsigned int mmDPG_TEST_DEBUG_INDEX__VI = 0x1B38; +constexpr unsigned int mmDPG_WATERMARK_MASK_CONTROL__VI = 0x1B32; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED0__VI = 0x5D98; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED1__VI = 0x5D99; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED10__VI = 0x5DA2; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED11__VI = 0x5DA3; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED12__VI = 0x5DA4; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED13__VI = 0x5DA5; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED14__VI = 0x5DA6; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED15__VI = 0x5DA7; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED16__VI = 0x5DA8; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED17__VI = 0x5DA9; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED18__VI = 0x5DAA; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED19__VI = 0x5DAB; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED2__VI = 0x5D9A; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED20__VI = 0x5DAC; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED21__VI = 0x5DAD; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED22__VI = 0x5DAE; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED23__VI = 0x5DAF; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED24__VI = 0x5DB0; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED25__VI = 0x5DB1; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED26__VI = 0x5DB2; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED27__VI = 0x5DB3; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED28__VI = 0x5DB4; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED29__VI = 0x5DB5; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED3__VI = 0x5D9B; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED30__VI = 0x5DB6; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED31__VI = 0x5DB7; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED32__VI = 0x5DB8; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED33__VI = 0x5DB9; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED34__VI = 0x5DBA; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED35__VI = 0x5DBB; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED36__VI = 0x5DBC; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED37__VI = 0x5DBD; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED38__VI = 0x5DBE; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED39__VI = 0x5DBF; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED4__VI = 0x5D9C; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED40__VI = 0x5DC0; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED41__VI = 0x5DC1; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED42__VI = 0x5DC2; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED43__VI = 0x5DC3; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED44__VI = 0x5DC4; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED45__VI = 0x5DC5; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED46__VI = 0x5DC6; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED47__VI = 0x5DC7; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED48__VI = 0x5DC8; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED49__VI = 0x5DC9; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED5__VI = 0x5D9D; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED50__VI = 0x5DCA; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED51__VI = 0x5DCB; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED52__VI = 0x5DCC; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED53__VI = 0x5DCD; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED54__VI = 0x5DCE; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED55__VI = 0x5DCF; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED56__VI = 0x5DD0; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED57__VI = 0x5DD1; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED58__VI = 0x5DD2; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED59__VI = 0x5DD3; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED6__VI = 0x5D9E; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED60__VI = 0x5DD4; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED61__VI = 0x5DD5; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED62__VI = 0x5DD6; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED63__VI = 0x5DD7; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED7__VI = 0x5D9F; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED8__VI = 0x5DA0; +constexpr unsigned int mmDPHY_MACRO_CNTL_RESERVED9__VI = 0x5DA1; +constexpr unsigned int mmDPREFCLK_CGTT_BLK_CTRL_REG__VI = 0x0108; +constexpr unsigned int mmDPREFCLK_CNTL__VI = 0x0118; +constexpr unsigned int mmDP_AUX0_AUX_ARB_CONTROL__VI = 0x5C02; +constexpr unsigned int mmDP_AUX0_AUX_CONTROL__VI = 0x5C00; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_RX_CONTROL0__VI = 0x5C0A; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_RX_CONTROL1__VI = 0x5C0B; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_RX_STATUS__VI = 0x5C0D; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_TX_CONTROL__VI = 0x5C09; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_TX_REF_CONTROL__VI = 0x5C08; +constexpr unsigned int mmDP_AUX0_AUX_DPHY_TX_STATUS__VI = 0x5C0C; +constexpr unsigned int mmDP_AUX0_AUX_GTC_SYNC_CONTROL__VI = 0x5C0E; +constexpr unsigned int mmDP_AUX0_AUX_GTC_SYNC_CONTROLLER_STATUS__VI = 0x5C10; +constexpr unsigned int mmDP_AUX0_AUX_GTC_SYNC_DATA__VI = 0x5C12; +constexpr unsigned int mmDP_AUX0_AUX_GTC_SYNC_ERROR_CONTROL__VI = 0x5C0F; +constexpr unsigned int mmDP_AUX0_AUX_GTC_SYNC_PHASE_OFFSET_OVERRIDE__VI = 0x5C13; +constexpr unsigned int mmDP_AUX0_AUX_GTC_SYNC_STATUS__VI = 0x5C11; +constexpr unsigned int mmDP_AUX0_AUX_INTERRUPT_CONTROL__VI = 0x5C03; +constexpr unsigned int mmDP_AUX0_AUX_LS_DATA__VI = 0x5C07; +constexpr unsigned int mmDP_AUX0_AUX_LS_STATUS__VI = 0x5C05; +constexpr unsigned int mmDP_AUX0_AUX_SW_CONTROL__VI = 0x5C01; +constexpr unsigned int mmDP_AUX0_AUX_SW_DATA__VI = 0x5C06; +constexpr unsigned int mmDP_AUX0_AUX_SW_STATUS__VI = 0x5C04; +constexpr unsigned int mmDP_AUX0_AUX_TEST_DEBUG_DATA__VI = 0x5C15; +constexpr unsigned int mmDP_AUX0_AUX_TEST_DEBUG_INDEX__VI = 0x5C14; +constexpr unsigned int mmDP_AUX1_AUX_ARB_CONTROL__VI = 0x5C1E; +constexpr unsigned int mmDP_AUX1_AUX_CONTROL__VI = 0x5C1C; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_RX_CONTROL0__VI = 0x5C26; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_RX_CONTROL1__VI = 0x5C27; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_RX_STATUS__VI = 0x5C29; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_TX_CONTROL__VI = 0x5C25; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_TX_REF_CONTROL__VI = 0x5C24; +constexpr unsigned int mmDP_AUX1_AUX_DPHY_TX_STATUS__VI = 0x5C28; +constexpr unsigned int mmDP_AUX1_AUX_GTC_SYNC_CONTROL__VI = 0x5C2A; +constexpr unsigned int mmDP_AUX1_AUX_GTC_SYNC_CONTROLLER_STATUS__VI = 0x5C2C; +constexpr unsigned int mmDP_AUX1_AUX_GTC_SYNC_DATA__VI = 0x5C2E; +constexpr unsigned int mmDP_AUX1_AUX_GTC_SYNC_ERROR_CONTROL__VI = 0x5C2B; +constexpr unsigned int mmDP_AUX1_AUX_GTC_SYNC_PHASE_OFFSET_OVERRIDE__VI = 0x5C2F; +constexpr unsigned int mmDP_AUX1_AUX_GTC_SYNC_STATUS__VI = 0x5C2D; +constexpr unsigned int mmDP_AUX1_AUX_INTERRUPT_CONTROL__VI = 0x5C1F; +constexpr unsigned int mmDP_AUX1_AUX_LS_DATA__VI = 0x5C23; +constexpr unsigned int mmDP_AUX1_AUX_LS_STATUS__VI = 0x5C21; +constexpr unsigned int mmDP_AUX1_AUX_SW_CONTROL__VI = 0x5C1D; +constexpr unsigned int mmDP_AUX1_AUX_SW_DATA__VI = 0x5C22; +constexpr unsigned int mmDP_AUX1_AUX_SW_STATUS__VI = 0x5C20; +constexpr unsigned int mmDP_AUX1_AUX_TEST_DEBUG_DATA__VI = 0x5C31; +constexpr unsigned int mmDP_AUX1_AUX_TEST_DEBUG_INDEX__VI = 0x5C30; +constexpr unsigned int mmDP_AUX2_AUX_ARB_CONTROL__VI = 0x5C3A; +constexpr unsigned int mmDP_AUX2_AUX_CONTROL__VI = 0x5C38; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_RX_CONTROL0__VI = 0x5C42; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_RX_CONTROL1__VI = 0x5C43; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_RX_STATUS__VI = 0x5C45; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_TX_CONTROL__VI = 0x5C41; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_TX_REF_CONTROL__VI = 0x5C40; +constexpr unsigned int mmDP_AUX2_AUX_DPHY_TX_STATUS__VI = 0x5C44; +constexpr unsigned int mmDP_AUX2_AUX_GTC_SYNC_CONTROL__VI = 0x5C46; +constexpr unsigned int mmDP_AUX2_AUX_GTC_SYNC_CONTROLLER_STATUS__VI = 0x5C48; +constexpr unsigned int mmDP_AUX2_AUX_GTC_SYNC_DATA__VI = 0x5C4A; +constexpr unsigned int mmDP_AUX2_AUX_GTC_SYNC_ERROR_CONTROL__VI = 0x5C47; +constexpr unsigned int mmDP_AUX2_AUX_GTC_SYNC_PHASE_OFFSET_OVERRIDE__VI = 0x5C4B; +constexpr unsigned int mmDP_AUX2_AUX_GTC_SYNC_STATUS__VI = 0x5C49; +constexpr unsigned int mmDP_AUX2_AUX_INTERRUPT_CONTROL__VI = 0x5C3B; +constexpr unsigned int mmDP_AUX2_AUX_LS_DATA__VI = 0x5C3F; +constexpr unsigned int mmDP_AUX2_AUX_LS_STATUS__VI = 0x5C3D; +constexpr unsigned int mmDP_AUX2_AUX_SW_CONTROL__VI = 0x5C39; +constexpr unsigned int mmDP_AUX2_AUX_SW_DATA__VI = 0x5C3E; +constexpr unsigned int mmDP_AUX2_AUX_SW_STATUS__VI = 0x5C3C; +constexpr unsigned int mmDP_AUX2_AUX_TEST_DEBUG_DATA__VI = 0x5C4D; +constexpr unsigned int mmDP_AUX2_AUX_TEST_DEBUG_INDEX__VI = 0x5C4C; +constexpr unsigned int mmDP_AUX3_AUX_ARB_CONTROL__VI = 0x5C56; +constexpr unsigned int mmDP_AUX3_AUX_CONTROL__VI = 0x5C54; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_RX_CONTROL0__VI = 0x5C5E; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_RX_CONTROL1__VI = 0x5C5F; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_RX_STATUS__VI = 0x5C61; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_TX_CONTROL__VI = 0x5C5D; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_TX_REF_CONTROL__VI = 0x5C5C; +constexpr unsigned int mmDP_AUX3_AUX_DPHY_TX_STATUS__VI = 0x5C60; +constexpr unsigned int mmDP_AUX3_AUX_GTC_SYNC_CONTROL__VI = 0x5C62; +constexpr unsigned int mmDP_AUX3_AUX_GTC_SYNC_CONTROLLER_STATUS__VI = 0x5C64; +constexpr unsigned int mmDP_AUX3_AUX_GTC_SYNC_DATA__VI = 0x5C66; +constexpr unsigned int mmDP_AUX3_AUX_GTC_SYNC_ERROR_CONTROL__VI = 0x5C63; +constexpr unsigned int mmDP_AUX3_AUX_GTC_SYNC_PHASE_OFFSET_OVERRIDE__VI = 0x5C67; +constexpr unsigned int mmDP_AUX3_AUX_GTC_SYNC_STATUS__VI = 0x5C65; +constexpr unsigned int mmDP_AUX3_AUX_INTERRUPT_CONTROL__VI = 0x5C57; +constexpr unsigned int mmDP_AUX3_AUX_LS_DATA__VI = 0x5C5B; +constexpr unsigned int mmDP_AUX3_AUX_LS_STATUS__VI = 0x5C59; +constexpr unsigned int mmDP_AUX3_AUX_SW_CONTROL__VI = 0x5C55; +constexpr unsigned int mmDP_AUX3_AUX_SW_DATA__VI = 0x5C5A; +constexpr unsigned int mmDP_AUX3_AUX_SW_STATUS__VI = 0x5C58; +constexpr unsigned int mmDP_AUX3_AUX_TEST_DEBUG_DATA__VI = 0x5C69; +constexpr unsigned int mmDP_AUX3_AUX_TEST_DEBUG_INDEX__VI = 0x5C68; +constexpr unsigned int mmDP_AUX4_AUX_ARB_CONTROL__VI = 0x5C72; +constexpr unsigned int mmDP_AUX4_AUX_CONTROL__VI = 0x5C70; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_RX_CONTROL0__VI = 0x5C7A; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_RX_CONTROL1__VI = 0x5C7B; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_RX_STATUS__VI = 0x5C7D; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_TX_CONTROL__VI = 0x5C79; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_TX_REF_CONTROL__VI = 0x5C78; +constexpr unsigned int mmDP_AUX4_AUX_DPHY_TX_STATUS__VI = 0x5C7C; +constexpr unsigned int mmDP_AUX4_AUX_GTC_SYNC_CONTROL__VI = 0x5C7E; +constexpr unsigned int mmDP_AUX4_AUX_GTC_SYNC_CONTROLLER_STATUS__VI = 0x5C80; +constexpr unsigned int mmDP_AUX4_AUX_GTC_SYNC_DATA__VI = 0x5C82; +constexpr unsigned int mmDP_AUX4_AUX_GTC_SYNC_ERROR_CONTROL__VI = 0x5C7F; +constexpr unsigned int mmDP_AUX4_AUX_GTC_SYNC_PHASE_OFFSET_OVERRIDE__VI = 0x5C83; +constexpr unsigned int mmDP_AUX4_AUX_GTC_SYNC_STATUS__VI = 0x5C81; +constexpr unsigned int mmDP_AUX4_AUX_INTERRUPT_CONTROL__VI = 0x5C73; +constexpr unsigned int mmDP_AUX4_AUX_LS_DATA__VI = 0x5C77; +constexpr unsigned int mmDP_AUX4_AUX_LS_STATUS__VI = 0x5C75; +constexpr unsigned int mmDP_AUX4_AUX_SW_CONTROL__VI = 0x5C71; +constexpr unsigned int mmDP_AUX4_AUX_SW_DATA__VI = 0x5C76; +constexpr unsigned int mmDP_AUX4_AUX_SW_STATUS__VI = 0x5C74; +constexpr unsigned int mmDP_AUX4_AUX_TEST_DEBUG_DATA__VI = 0x5C85; +constexpr unsigned int mmDP_AUX4_AUX_TEST_DEBUG_INDEX__VI = 0x5C84; +constexpr unsigned int mmDP_AUX5_AUX_ARB_CONTROL__VI = 0x5C8E; +constexpr unsigned int mmDP_AUX5_AUX_CONTROL__VI = 0x5C8C; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_RX_CONTROL0__VI = 0x5C96; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_RX_CONTROL1__VI = 0x5C97; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_RX_STATUS__VI = 0x5C99; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_TX_CONTROL__VI = 0x5C95; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_TX_REF_CONTROL__VI = 0x5C94; +constexpr unsigned int mmDP_AUX5_AUX_DPHY_TX_STATUS__VI = 0x5C98; +constexpr unsigned int mmDP_AUX5_AUX_GTC_SYNC_CONTROL__VI = 0x5C9A; +constexpr unsigned int mmDP_AUX5_AUX_GTC_SYNC_CONTROLLER_STATUS__VI = 0x5C9C; +constexpr unsigned int mmDP_AUX5_AUX_GTC_SYNC_DATA__VI = 0x5C9E; +constexpr unsigned int mmDP_AUX5_AUX_GTC_SYNC_ERROR_CONTROL__VI = 0x5C9B; +constexpr unsigned int mmDP_AUX5_AUX_GTC_SYNC_PHASE_OFFSET_OVERRIDE__VI = 0x5C9F; +constexpr unsigned int mmDP_AUX5_AUX_GTC_SYNC_STATUS__VI = 0x5C9D; +constexpr unsigned int mmDP_AUX5_AUX_INTERRUPT_CONTROL__VI = 0x5C8F; +constexpr unsigned int mmDP_AUX5_AUX_LS_DATA__VI = 0x5C93; +constexpr unsigned int mmDP_AUX5_AUX_LS_STATUS__VI = 0x5C91; +constexpr unsigned int mmDP_AUX5_AUX_SW_CONTROL__VI = 0x5C8D; +constexpr unsigned int mmDP_AUX5_AUX_SW_DATA__VI = 0x5C92; +constexpr unsigned int mmDP_AUX5_AUX_SW_STATUS__VI = 0x5C90; +constexpr unsigned int mmDP_AUX5_AUX_TEST_DEBUG_DATA__VI = 0x5CA1; +constexpr unsigned int mmDP_AUX5_AUX_TEST_DEBUG_INDEX__VI = 0x5CA0; +constexpr unsigned int mmDP_CONFIG__VI = 0x4AA3; +constexpr unsigned int mmDP_DPHY_8B10B_CNTL__VI = 0x4AB4; +constexpr unsigned int mmDP_DPHY_CNTL__VI = 0x4AAF; +constexpr unsigned int mmDP_DPHY_CRC_CNTL__VI = 0x4AB8; +constexpr unsigned int mmDP_DPHY_CRC_EN__VI = 0x4AB7; +constexpr unsigned int mmDP_DPHY_CRC_MST_CNTL__VI = 0x4ABA; +constexpr unsigned int mmDP_DPHY_CRC_MST_STATUS__VI = 0x4ABB; +constexpr unsigned int mmDP_DPHY_CRC_RESULT__VI = 0x4AB9; +constexpr unsigned int mmDP_DPHY_FAST_TRAINING__VI = 0x4ABC; +constexpr unsigned int mmDP_DPHY_FAST_TRAINING_STATUS__VI = 0x4ABD; +constexpr unsigned int mmDP_DPHY_PRBS_CNTL__VI = 0x4AB5; +constexpr unsigned int mmDP_DPHY_SYM0__VI = 0x4AB1; +constexpr unsigned int mmDP_DPHY_SYM1__VI = 0x4AB2; +constexpr unsigned int mmDP_DPHY_SYM2__VI = 0x4AB3; +constexpr unsigned int mmDP_DPHY_TRAINING_PATTERN_SEL__VI = 0x4AB0; +constexpr unsigned int mmDP_DTO0_MODULO__VI = 0x0142; +constexpr unsigned int mmDP_DTO0_PHASE__VI = 0x0141; +constexpr unsigned int mmDP_DTO1_MODULO__VI = 0x0146; +constexpr unsigned int mmDP_DTO1_PHASE__VI = 0x0145; +constexpr unsigned int mmDP_DTO2_MODULO__VI = 0x014A; +constexpr unsigned int mmDP_DTO2_PHASE__VI = 0x0149; +constexpr unsigned int mmDP_DTO3_MODULO__VI = 0x014E; +constexpr unsigned int mmDP_DTO3_PHASE__VI = 0x014D; +constexpr unsigned int mmDP_DTO4_MODULO__VI = 0x0152; +constexpr unsigned int mmDP_DTO4_PHASE__VI = 0x0151; +constexpr unsigned int mmDP_DTO5_MODULO__VI = 0x0156; +constexpr unsigned int mmDP_DTO5_PHASE__VI = 0x0155; +constexpr unsigned int mmDP_FE_TEST_DEBUG_DATA__VI = 0x4ADB; +constexpr unsigned int mmDP_FE_TEST_DEBUG_INDEX__VI = 0x4ADA; +constexpr unsigned int mmDP_HBR2_EYE_PATTERN__VI = 0x4AAC; +constexpr unsigned int mmDP_LINK_CNTL__VI = 0x4AA0; +constexpr unsigned int mmDP_LINK_FRAMING_CNTL__VI = 0x4AAB; +constexpr unsigned int mmDP_MSA_COLORIMETRY__VI = 0x4AA2; +constexpr unsigned int mmDP_MSA_MISC__VI = 0x4AA6; +constexpr unsigned int mmDP_MSA_V_TIMING_OVERRIDE1__VI = 0x4ABE; +constexpr unsigned int mmDP_MSA_V_TIMING_OVERRIDE2__VI = 0x4ABF; +constexpr unsigned int mmDP_MSE_LINK_TIMING__VI = 0x4AD6; +constexpr unsigned int mmDP_MSE_MISC_CNTL__VI = 0x4AD7; +constexpr unsigned int mmDP_MSE_RATE_CNTL__VI = 0x4ACF; +constexpr unsigned int mmDP_MSE_RATE_UPDATE__VI = 0x4AD1; +constexpr unsigned int mmDP_MSE_SAT0__VI = 0x4AD2; +constexpr unsigned int mmDP_MSE_SAT1__VI = 0x4AD3; +constexpr unsigned int mmDP_MSE_SAT2__VI = 0x4AD4; +constexpr unsigned int mmDP_MSE_SAT_UPDATE__VI = 0x4AD5; +constexpr unsigned int mmDP_PIXEL_FORMAT__VI = 0x4AA1; +constexpr unsigned int mmDP_SEC_AUD_M__VI = 0x4ACB; +constexpr unsigned int mmDP_SEC_AUD_M_READBACK__VI = 0x4ACC; +constexpr unsigned int mmDP_SEC_AUD_N__VI = 0x4AC9; +constexpr unsigned int mmDP_SEC_AUD_N_READBACK__VI = 0x4ACA; +constexpr unsigned int mmDP_SEC_CNTL__VI = 0x4AC3; +constexpr unsigned int mmDP_SEC_CNTL1__VI = 0x4AC4; +constexpr unsigned int mmDP_SEC_FRAMING1__VI = 0x4AC5; +constexpr unsigned int mmDP_SEC_FRAMING2__VI = 0x4AC6; +constexpr unsigned int mmDP_SEC_FRAMING3__VI = 0x4AC7; +constexpr unsigned int mmDP_SEC_FRAMING4__VI = 0x4AC8; +constexpr unsigned int mmDP_SEC_PACKET_CNTL__VI = 0x4ACE; +constexpr unsigned int mmDP_SEC_TIMESTAMP__VI = 0x4ACD; +constexpr unsigned int mmDP_STEER_FIFO__VI = 0x4AA5; +constexpr unsigned int mmDP_TEST_DEBUG_DATA__VI = 0x4AD9; +constexpr unsigned int mmDP_TEST_DEBUG_INDEX__VI = 0x4AD8; +constexpr unsigned int mmDP_VID_INTERRUPT_CNTL__VI = 0x4AAE; +constexpr unsigned int mmDP_VID_M__VI = 0x4AAA; +constexpr unsigned int mmDP_VID_MSA_VBID__VI = 0x4AAD; +constexpr unsigned int mmDP_VID_N__VI = 0x4AA9; +constexpr unsigned int mmDP_VID_STREAM_CNTL__VI = 0x4AA4; +constexpr unsigned int mmDP_VID_TIMING__VI = 0x4AA8; +constexpr unsigned int mmDVOACLKC_CNTL__VI = 0x016A; +constexpr unsigned int mmDVOACLKC_MVP_CNTL__VI = 0x0169; +constexpr unsigned int mmDVOACLKD_CNTL__VI = 0x0168; +constexpr unsigned int mmDVO_CLK_ENABLE__VI = 0x0129; +constexpr unsigned int mmDVO_CONTROL__VI = 0x16A3; +constexpr unsigned int mmDVO_CRC2_SIG_MASK__VI = 0x16A5; +constexpr unsigned int mmDVO_CRC2_SIG_RESULT__VI = 0x16A6; +constexpr unsigned int mmDVO_CRC_EN__VI = 0x16A4; +constexpr unsigned int mmDVO_ENABLE__VI = 0x16A0; +constexpr unsigned int mmDVO_FIFO_ERROR_STATUS__VI = 0x16A7; +constexpr unsigned int mmDVO_OUTPUT__VI = 0x16A2; +constexpr unsigned int mmDVO_SKEW_ADJUST__VI = 0x489F; +constexpr unsigned int mmDVO_SOURCE_SELECT__VI = 0x16A1; +constexpr unsigned int mmDVO_STRENGTH_CONTROL__VI = 0x489D; +constexpr unsigned int mmDVO_TEST_DEBUG_DATA__VI = 0x16A9; +constexpr unsigned int mmDVO_TEST_DEBUG_INDEX__VI = 0x16A8; +constexpr unsigned int mmDVO_VREF_CONTROL__VI = 0x489E; +constexpr unsigned int mmFBC_CLIENT_REGION_MASK__VI = 0x029B; +constexpr unsigned int mmFBC_CNTL__VI = 0x0280; +constexpr unsigned int mmFBC_COMP_CNTL__VI = 0x0284; +constexpr unsigned int mmFBC_COMP_MODE__VI = 0x0285; +constexpr unsigned int mmFBC_CSM_REGION_OFFSET_01__VI = 0x0299; +constexpr unsigned int mmFBC_CSM_REGION_OFFSET_23__VI = 0x029A; +constexpr unsigned int mmFBC_DEBUG0__VI = 0x0286; +constexpr unsigned int mmFBC_DEBUG1__VI = 0x0287; +constexpr unsigned int mmFBC_DEBUG2__VI = 0x0288; +constexpr unsigned int mmFBC_DEBUG_COMP__VI = 0x029C; +constexpr unsigned int mmFBC_DEBUG_CSR__VI = 0x029D; +constexpr unsigned int mmFBC_DEBUG_CSR_RDATA__VI = 0x029E; +constexpr unsigned int mmFBC_DEBUG_CSR_RDATA_HI__VI = 0x02A0; +constexpr unsigned int mmFBC_DEBUG_CSR_WDATA__VI = 0x029F; +constexpr unsigned int mmFBC_DEBUG_CSR_WDATA_HI__VI = 0x02A1; +constexpr unsigned int mmFBC_IDLE_FORCE_CLEAR_MASK__VI = 0x0282; +constexpr unsigned int mmFBC_IDLE_MASK__VI = 0x0281; +constexpr unsigned int mmFBC_IND_LUT0__VI = 0x0289; +constexpr unsigned int mmFBC_IND_LUT1__VI = 0x028A; +constexpr unsigned int mmFBC_IND_LUT10__VI = 0x0293; +constexpr unsigned int mmFBC_IND_LUT11__VI = 0x0294; +constexpr unsigned int mmFBC_IND_LUT12__VI = 0x0295; +constexpr unsigned int mmFBC_IND_LUT13__VI = 0x0296; +constexpr unsigned int mmFBC_IND_LUT14__VI = 0x0297; +constexpr unsigned int mmFBC_IND_LUT15__VI = 0x0298; +constexpr unsigned int mmFBC_IND_LUT2__VI = 0x028B; +constexpr unsigned int mmFBC_IND_LUT3__VI = 0x028C; +constexpr unsigned int mmFBC_IND_LUT4__VI = 0x028D; +constexpr unsigned int mmFBC_IND_LUT5__VI = 0x028E; +constexpr unsigned int mmFBC_IND_LUT6__VI = 0x028F; +constexpr unsigned int mmFBC_IND_LUT7__VI = 0x0290; +constexpr unsigned int mmFBC_IND_LUT8__VI = 0x0291; +constexpr unsigned int mmFBC_IND_LUT9__VI = 0x0292; +constexpr unsigned int mmFBC_MISC__VI = 0x02A2; +constexpr unsigned int mmFBC_START_STOP_DELAY__VI = 0x0283; +constexpr unsigned int mmFBC_STATUS__VI = 0x02A3; +constexpr unsigned int mmFBC_TEST_DEBUG_DATA__VI = 0x02A5; +constexpr unsigned int mmFBC_TEST_DEBUG_INDEX__VI = 0x02A4; +constexpr unsigned int mmFMT0_FMT_CLAMP_COMPONENT_B__VI = 0x1BEA; +constexpr unsigned int mmFMT0_FMT_CLAMP_COMPONENT_G__VI = 0x1BE9; +constexpr unsigned int mmFMT0_FMT_CLAMP_COMPONENT_R__VI = 0x1BE8; +constexpr unsigned int mmFMT0_FMT_TEST_DEBUG_DATA__VI = 0x1BEC; +constexpr unsigned int mmFMT0_FMT_TEST_DEBUG_INDEX__VI = 0x1BEB; +constexpr unsigned int mmFMT1_FMT_BIT_DEPTH_CONTROL__VI = 0x1DF2; +constexpr unsigned int mmFMT1_FMT_CLAMP_CNTL__VI = 0x1DF9; +constexpr unsigned int mmFMT1_FMT_CLAMP_COMPONENT_B__VI = 0x1DEA; +constexpr unsigned int mmFMT1_FMT_CLAMP_COMPONENT_G__VI = 0x1DE9; +constexpr unsigned int mmFMT1_FMT_CLAMP_COMPONENT_R__VI = 0x1DE8; +constexpr unsigned int mmFMT1_FMT_CONTROL__VI = 0x1DEE; +constexpr unsigned int mmFMT1_FMT_CRC_CNTL__VI = 0x1DFA; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_BLUE_CONTROL__VI = 0x1DFE; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_BLUE_CONTROL_MASK__VI = 0x1DFC; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_RED_GREEN__VI = 0x1DFD; +constexpr unsigned int mmFMT1_FMT_CRC_SIG_RED_GREEN_MASK__VI = 0x1DFB; +constexpr unsigned int mmFMT1_FMT_DEBUG_CNTL__VI = 0x1DFF; +constexpr unsigned int mmFMT1_FMT_DITHER_RAND_B_SEED__VI = 0x1DF5; +constexpr unsigned int mmFMT1_FMT_DITHER_RAND_G_SEED__VI = 0x1DF4; +constexpr unsigned int mmFMT1_FMT_DITHER_RAND_R_SEED__VI = 0x1DF3; +constexpr unsigned int mmFMT1_FMT_DYNAMIC_EXP_CNTL__VI = 0x1DED; +constexpr unsigned int mmFMT1_FMT_FORCE_DATA_0_1__VI = 0x1DF0; +constexpr unsigned int mmFMT1_FMT_FORCE_DATA_2_3__VI = 0x1DF1; +constexpr unsigned int mmFMT1_FMT_FORCE_OUTPUT_CNTL__VI = 0x1DEF; +constexpr unsigned int mmFMT1_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__VI = 0x1DF6; +constexpr unsigned int mmFMT1_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__VI = 0x1DF7; +constexpr unsigned int mmFMT1_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__VI = 0x1DF8; +constexpr unsigned int mmFMT1_FMT_TEST_DEBUG_DATA__VI = 0x1DEC; +constexpr unsigned int mmFMT1_FMT_TEST_DEBUG_INDEX__VI = 0x1DEB; +constexpr unsigned int mmFMT2_FMT_BIT_DEPTH_CONTROL__VI = 0x1FF2; +constexpr unsigned int mmFMT2_FMT_CLAMP_CNTL__VI = 0x1FF9; +constexpr unsigned int mmFMT2_FMT_CLAMP_COMPONENT_B__VI = 0x1FEA; +constexpr unsigned int mmFMT2_FMT_CLAMP_COMPONENT_G__VI = 0x1FE9; +constexpr unsigned int mmFMT2_FMT_CLAMP_COMPONENT_R__VI = 0x1FE8; +constexpr unsigned int mmFMT2_FMT_CONTROL__VI = 0x1FEE; +constexpr unsigned int mmFMT2_FMT_CRC_CNTL__VI = 0x1FFA; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_BLUE_CONTROL__VI = 0x1FFE; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_BLUE_CONTROL_MASK__VI = 0x1FFC; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_RED_GREEN__VI = 0x1FFD; +constexpr unsigned int mmFMT2_FMT_CRC_SIG_RED_GREEN_MASK__VI = 0x1FFB; +constexpr unsigned int mmFMT2_FMT_DEBUG_CNTL__VI = 0x1FFF; +constexpr unsigned int mmFMT2_FMT_DITHER_RAND_B_SEED__VI = 0x1FF5; +constexpr unsigned int mmFMT2_FMT_DITHER_RAND_G_SEED__VI = 0x1FF4; +constexpr unsigned int mmFMT2_FMT_DITHER_RAND_R_SEED__VI = 0x1FF3; +constexpr unsigned int mmFMT2_FMT_DYNAMIC_EXP_CNTL__VI = 0x1FED; +constexpr unsigned int mmFMT2_FMT_FORCE_DATA_0_1__VI = 0x1FF0; +constexpr unsigned int mmFMT2_FMT_FORCE_DATA_2_3__VI = 0x1FF1; +constexpr unsigned int mmFMT2_FMT_FORCE_OUTPUT_CNTL__VI = 0x1FEF; +constexpr unsigned int mmFMT2_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__VI = 0x1FF6; +constexpr unsigned int mmFMT2_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__VI = 0x1FF7; +constexpr unsigned int mmFMT2_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__VI = 0x1FF8; +constexpr unsigned int mmFMT2_FMT_TEST_DEBUG_DATA__VI = 0x1FEC; +constexpr unsigned int mmFMT2_FMT_TEST_DEBUG_INDEX__VI = 0x1FEB; +constexpr unsigned int mmFMT3_FMT_BIT_DEPTH_CONTROL__VI = 0x41F2; +constexpr unsigned int mmFMT3_FMT_CLAMP_CNTL__VI = 0x41F9; +constexpr unsigned int mmFMT3_FMT_CLAMP_COMPONENT_B__VI = 0x41EA; +constexpr unsigned int mmFMT3_FMT_CLAMP_COMPONENT_G__VI = 0x41E9; +constexpr unsigned int mmFMT3_FMT_CLAMP_COMPONENT_R__VI = 0x41E8; +constexpr unsigned int mmFMT3_FMT_CONTROL__VI = 0x41EE; +constexpr unsigned int mmFMT3_FMT_CRC_CNTL__VI = 0x41FA; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_BLUE_CONTROL__VI = 0x41FE; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_BLUE_CONTROL_MASK__VI = 0x41FC; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_RED_GREEN__VI = 0x41FD; +constexpr unsigned int mmFMT3_FMT_CRC_SIG_RED_GREEN_MASK__VI = 0x41FB; +constexpr unsigned int mmFMT3_FMT_DEBUG_CNTL__VI = 0x41FF; +constexpr unsigned int mmFMT3_FMT_DITHER_RAND_B_SEED__VI = 0x41F5; +constexpr unsigned int mmFMT3_FMT_DITHER_RAND_G_SEED__VI = 0x41F4; +constexpr unsigned int mmFMT3_FMT_DITHER_RAND_R_SEED__VI = 0x41F3; +constexpr unsigned int mmFMT3_FMT_DYNAMIC_EXP_CNTL__VI = 0x41ED; +constexpr unsigned int mmFMT3_FMT_FORCE_DATA_0_1__VI = 0x41F0; +constexpr unsigned int mmFMT3_FMT_FORCE_DATA_2_3__VI = 0x41F1; +constexpr unsigned int mmFMT3_FMT_FORCE_OUTPUT_CNTL__VI = 0x41EF; +constexpr unsigned int mmFMT3_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__VI = 0x41F6; +constexpr unsigned int mmFMT3_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__VI = 0x41F7; +constexpr unsigned int mmFMT3_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__VI = 0x41F8; +constexpr unsigned int mmFMT3_FMT_TEST_DEBUG_DATA__VI = 0x41EC; +constexpr unsigned int mmFMT3_FMT_TEST_DEBUG_INDEX__VI = 0x41EB; +constexpr unsigned int mmFMT4_FMT_BIT_DEPTH_CONTROL__VI = 0x43F2; +constexpr unsigned int mmFMT4_FMT_CLAMP_CNTL__VI = 0x43F9; +constexpr unsigned int mmFMT4_FMT_CLAMP_COMPONENT_B__VI = 0x43EA; +constexpr unsigned int mmFMT4_FMT_CLAMP_COMPONENT_G__VI = 0x43E9; +constexpr unsigned int mmFMT4_FMT_CLAMP_COMPONENT_R__VI = 0x43E8; +constexpr unsigned int mmFMT4_FMT_CONTROL__VI = 0x43EE; +constexpr unsigned int mmFMT4_FMT_CRC_CNTL__VI = 0x43FA; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_BLUE_CONTROL__VI = 0x43FE; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_BLUE_CONTROL_MASK__VI = 0x43FC; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_RED_GREEN__VI = 0x43FD; +constexpr unsigned int mmFMT4_FMT_CRC_SIG_RED_GREEN_MASK__VI = 0x43FB; +constexpr unsigned int mmFMT4_FMT_DEBUG_CNTL__VI = 0x43FF; +constexpr unsigned int mmFMT4_FMT_DITHER_RAND_B_SEED__VI = 0x43F5; +constexpr unsigned int mmFMT4_FMT_DITHER_RAND_G_SEED__VI = 0x43F4; +constexpr unsigned int mmFMT4_FMT_DITHER_RAND_R_SEED__VI = 0x43F3; +constexpr unsigned int mmFMT4_FMT_DYNAMIC_EXP_CNTL__VI = 0x43ED; +constexpr unsigned int mmFMT4_FMT_FORCE_DATA_0_1__VI = 0x43F0; +constexpr unsigned int mmFMT4_FMT_FORCE_DATA_2_3__VI = 0x43F1; +constexpr unsigned int mmFMT4_FMT_FORCE_OUTPUT_CNTL__VI = 0x43EF; +constexpr unsigned int mmFMT4_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__VI = 0x43F6; +constexpr unsigned int mmFMT4_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__VI = 0x43F7; +constexpr unsigned int mmFMT4_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__VI = 0x43F8; +constexpr unsigned int mmFMT4_FMT_TEST_DEBUG_DATA__VI = 0x43EC; +constexpr unsigned int mmFMT4_FMT_TEST_DEBUG_INDEX__VI = 0x43EB; +constexpr unsigned int mmFMT5_FMT_BIT_DEPTH_CONTROL__VI = 0x45F2; +constexpr unsigned int mmFMT5_FMT_CLAMP_CNTL__VI = 0x45F9; +constexpr unsigned int mmFMT5_FMT_CLAMP_COMPONENT_B__VI = 0x45EA; +constexpr unsigned int mmFMT5_FMT_CLAMP_COMPONENT_G__VI = 0x45E9; +constexpr unsigned int mmFMT5_FMT_CLAMP_COMPONENT_R__VI = 0x45E8; +constexpr unsigned int mmFMT5_FMT_CONTROL__VI = 0x45EE; +constexpr unsigned int mmFMT5_FMT_CRC_CNTL__VI = 0x45FA; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_BLUE_CONTROL__VI = 0x45FE; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_BLUE_CONTROL_MASK__VI = 0x45FC; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_RED_GREEN__VI = 0x45FD; +constexpr unsigned int mmFMT5_FMT_CRC_SIG_RED_GREEN_MASK__VI = 0x45FB; +constexpr unsigned int mmFMT5_FMT_DEBUG_CNTL__VI = 0x45FF; +constexpr unsigned int mmFMT5_FMT_DITHER_RAND_B_SEED__VI = 0x45F5; +constexpr unsigned int mmFMT5_FMT_DITHER_RAND_G_SEED__VI = 0x45F4; +constexpr unsigned int mmFMT5_FMT_DITHER_RAND_R_SEED__VI = 0x45F3; +constexpr unsigned int mmFMT5_FMT_DYNAMIC_EXP_CNTL__VI = 0x45ED; +constexpr unsigned int mmFMT5_FMT_FORCE_DATA_0_1__VI = 0x45F0; +constexpr unsigned int mmFMT5_FMT_FORCE_DATA_2_3__VI = 0x45F1; +constexpr unsigned int mmFMT5_FMT_FORCE_OUTPUT_CNTL__VI = 0x45EF; +constexpr unsigned int mmFMT5_FMT_TEMPORAL_DITHER_PATTERN_CONTROL__VI = 0x45F6; +constexpr unsigned int mmFMT5_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX__VI = 0x45F7; +constexpr unsigned int mmFMT5_FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX__VI = 0x45F8; +constexpr unsigned int mmFMT5_FMT_TEST_DEBUG_DATA__VI = 0x45EC; +constexpr unsigned int mmFMT5_FMT_TEST_DEBUG_INDEX__VI = 0x45EB; +constexpr unsigned int mmFMT_CLAMP_COMPONENT_B__VI = 0x1BEA; +constexpr unsigned int mmFMT_CLAMP_COMPONENT_G__VI = 0x1BE9; +constexpr unsigned int mmFMT_CLAMP_COMPONENT_R__VI = 0x1BE8; +constexpr unsigned int mmFMT_TEST_DEBUG_DATA__VI = 0x1BEC; +constexpr unsigned int mmFMT_TEST_DEBUG_INDEX__VI = 0x1BEB; +constexpr unsigned int mmGAMMA_CORR_CNTLA_END_CNTL1__VI = 0x46CE; +constexpr unsigned int mmGAMMA_CORR_CNTLA_END_CNTL2__VI = 0x46CF; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_0_1__VI = 0x46D0; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_10_11__VI = 0x46D5; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_12_13__VI = 0x46D6; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_14_15__VI = 0x46D7; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_2_3__VI = 0x46D1; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_4_5__VI = 0x46D2; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_6_7__VI = 0x46D3; +constexpr unsigned int mmGAMMA_CORR_CNTLA_REGION_8_9__VI = 0x46D4; +constexpr unsigned int mmGAMMA_CORR_CNTLA_SLOPE_CNTL__VI = 0x46CD; +constexpr unsigned int mmGAMMA_CORR_CNTLA_START_CNTL__VI = 0x46CC; +constexpr unsigned int mmGAMMA_CORR_CNTLB_END_CNTL1__VI = 0x46DA; +constexpr unsigned int mmGAMMA_CORR_CNTLB_END_CNTL2__VI = 0x46DB; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_0_1__VI = 0x46DC; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_10_11__VI = 0x46E1; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_12_13__VI = 0x46E2; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_14_15__VI = 0x46E3; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_2_3__VI = 0x46DD; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_4_5__VI = 0x46DE; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_6_7__VI = 0x46DF; +constexpr unsigned int mmGAMMA_CORR_CNTLB_REGION_8_9__VI = 0x46E0; +constexpr unsigned int mmGAMMA_CORR_CNTLB_SLOPE_CNTL__VI = 0x46D9; +constexpr unsigned int mmGAMMA_CORR_CNTLB_START_CNTL__VI = 0x46D8; +constexpr unsigned int mmGAMMA_CORR_CONTROL__VI = 0x46C8; +constexpr unsigned int mmGAMMA_CORR_LUT_DATA__VI = 0x46CA; +constexpr unsigned int mmGAMMA_CORR_LUT_INDEX__VI = 0x46C9; +constexpr unsigned int mmGAMMA_CORR_LUT_WRITE_EN_MASK__VI = 0x46CB; +constexpr unsigned int mmGAMUT_REMAP_C11_C12__VI = 0x1A5A; +constexpr unsigned int mmGAMUT_REMAP_C13_C14__VI = 0x1A5B; +constexpr unsigned int mmGAMUT_REMAP_C21_C22__VI = 0x1A5C; +constexpr unsigned int mmGAMUT_REMAP_C23_C24__VI = 0x1A5D; +constexpr unsigned int mmGAMUT_REMAP_C31_C32__VI = 0x1A5E; +constexpr unsigned int mmGAMUT_REMAP_C33_C34__VI = 0x1A5F; +constexpr unsigned int mmGAMUT_REMAP_CONTROL__VI = 0x1A59; +constexpr unsigned int mmGARLIC_COHE_CP_DMA_ME_COMMAND__VI = 0x141B; +constexpr unsigned int mmGARLIC_COHE_CP_DMA_PFP_COMMAND__VI = 0x141C; +constexpr unsigned int mmGARLIC_COHE_CP_DMA_PIO_COMMAND__VI = 0x1424; +constexpr unsigned int mmGARLIC_COHE_CP_RB0_WPTR__VI = 0x1415; +constexpr unsigned int mmGARLIC_COHE_CP_RB1_WPTR__VI = 0x1416; +constexpr unsigned int mmGARLIC_COHE_CP_RB2_WPTR__VI = 0x1417; +constexpr unsigned int mmGARLIC_COHE_GARLIC_FLUSH_REQ__VI = 0x1425; +constexpr unsigned int mmGARLIC_COHE_SAM_SAB_RBI_WPTR__VI = 0x141D; +constexpr unsigned int mmGARLIC_COHE_SAM_SAB_RBO_WPTR__VI = 0x141E; +constexpr unsigned int mmGARLIC_COHE_SDMA0_GFX_RB_WPTR__VI = 0x1419; +constexpr unsigned int mmGARLIC_COHE_SDMA1_GFX_RB_WPTR__VI = 0x141A; +constexpr unsigned int mmGARLIC_COHE_SDMA2_GFX_RB_WPTR__VI = 0x1422; +constexpr unsigned int mmGARLIC_COHE_SDMA3_GFX_RB_WPTR__VI = 0x1423; +constexpr unsigned int mmGARLIC_COHE_UVD_RBC_RB_WPTR__VI = 0x1418; +constexpr unsigned int mmGARLIC_COHE_VCE_OUT_RB_WPTR__VI = 0x141F; +constexpr unsigned int mmGARLIC_COHE_VCE_RB_WPTR__VI = 0x1421; +constexpr unsigned int mmGARLIC_COHE_VCE_RB_WPTR2__VI = 0x1420; +constexpr unsigned int mmGC_CAC_CGTT_CLK_CTRL__VI = 0x3292; +constexpr unsigned int mmGC_CAC_LKG_AGGR_LOWER__VI = 0x3296; +constexpr unsigned int mmGC_CAC_LKG_AGGR_UPPER__VI = 0x3297; +constexpr unsigned int mmGC_USER_SHADER_RATE_CONFIG__VI = 0x2313; +constexpr unsigned int mmGDS_CS_CTXSW_CNT0__VI = 0x334E; +constexpr unsigned int mmGDS_CS_CTXSW_CNT1__VI = 0x334F; +constexpr unsigned int mmGDS_CS_CTXSW_CNT2__VI = 0x3350; +constexpr unsigned int mmGDS_CS_CTXSW_CNT3__VI = 0x3351; +constexpr unsigned int mmGDS_CS_CTXSW_STATUS__VI = 0x334D; +constexpr unsigned int mmGDS_DSM_CNTL__VI = 0x25CA; +constexpr unsigned int mmGDS_EDC_CNT__VI = 0x25C5; +constexpr unsigned int mmGDS_EDC_GRBM_CNT__VI = 0x25C6; +constexpr unsigned int mmGDS_EDC_OA_DED__VI = 0x25C7; +constexpr unsigned int mmGDS_GFX_CTXSW_STATUS__VI = 0x3352; +constexpr unsigned int mmGDS_PS0_CTXSW_CNT0__VI = 0x3357; +constexpr unsigned int mmGDS_PS0_CTXSW_CNT1__VI = 0x3358; +constexpr unsigned int mmGDS_PS0_CTXSW_CNT2__VI = 0x3359; +constexpr unsigned int mmGDS_PS0_CTXSW_CNT3__VI = 0x335A; +constexpr unsigned int mmGDS_PS1_CTXSW_CNT0__VI = 0x335B; +constexpr unsigned int mmGDS_PS1_CTXSW_CNT1__VI = 0x335C; +constexpr unsigned int mmGDS_PS1_CTXSW_CNT2__VI = 0x335D; +constexpr unsigned int mmGDS_PS1_CTXSW_CNT3__VI = 0x335E; +constexpr unsigned int mmGDS_PS2_CTXSW_CNT0__VI = 0x335F; +constexpr unsigned int mmGDS_PS2_CTXSW_CNT1__VI = 0x3360; +constexpr unsigned int mmGDS_PS2_CTXSW_CNT2__VI = 0x3361; +constexpr unsigned int mmGDS_PS2_CTXSW_CNT3__VI = 0x3362; +constexpr unsigned int mmGDS_PS3_CTXSW_CNT0__VI = 0x3363; +constexpr unsigned int mmGDS_PS3_CTXSW_CNT1__VI = 0x3364; +constexpr unsigned int mmGDS_PS3_CTXSW_CNT2__VI = 0x3365; +constexpr unsigned int mmGDS_PS3_CTXSW_CNT3__VI = 0x3366; +constexpr unsigned int mmGDS_PS4_CTXSW_CNT0__VI = 0x3367; +constexpr unsigned int mmGDS_PS4_CTXSW_CNT1__VI = 0x3368; +constexpr unsigned int mmGDS_PS4_CTXSW_CNT2__VI = 0x3369; +constexpr unsigned int mmGDS_PS4_CTXSW_CNT3__VI = 0x336A; +constexpr unsigned int mmGDS_PS5_CTXSW_CNT0__VI = 0x336B; +constexpr unsigned int mmGDS_PS5_CTXSW_CNT1__VI = 0x336C; +constexpr unsigned int mmGDS_PS5_CTXSW_CNT2__VI = 0x336D; +constexpr unsigned int mmGDS_PS5_CTXSW_CNT3__VI = 0x336E; +constexpr unsigned int mmGDS_PS6_CTXSW_CNT0__VI = 0x336F; +constexpr unsigned int mmGDS_PS6_CTXSW_CNT1__VI = 0x3370; +constexpr unsigned int mmGDS_PS6_CTXSW_CNT2__VI = 0x3371; +constexpr unsigned int mmGDS_PS6_CTXSW_CNT3__VI = 0x3372; +constexpr unsigned int mmGDS_PS7_CTXSW_CNT0__VI = 0x3373; +constexpr unsigned int mmGDS_PS7_CTXSW_CNT1__VI = 0x3374; +constexpr unsigned int mmGDS_PS7_CTXSW_CNT2__VI = 0x3375; +constexpr unsigned int mmGDS_PS7_CTXSW_CNT3__VI = 0x3376; +constexpr unsigned int mmGDS_VS_CTXSW_CNT0__VI = 0x3353; +constexpr unsigned int mmGDS_VS_CTXSW_CNT1__VI = 0x3354; +constexpr unsigned int mmGDS_VS_CTXSW_CNT2__VI = 0x3355; +constexpr unsigned int mmGDS_VS_CTXSW_CNT3__VI = 0x3356; +constexpr unsigned int mmGENERIC_I2C_CONTROL__VI = 0x16F4; +constexpr unsigned int mmGENERIC_I2C_DATA__VI = 0x16FA; +constexpr unsigned int mmGENERIC_I2C_INTERRUPT_CONTROL__VI = 0x16F5; +constexpr unsigned int mmGENERIC_I2C_PIN_DEBUG__VI = 0x16FC; +constexpr unsigned int mmGENERIC_I2C_PIN_SELECTION__VI = 0x16FB; +constexpr unsigned int mmGENERIC_I2C_SETUP__VI = 0x16F8; +constexpr unsigned int mmGENERIC_I2C_SPEED__VI = 0x16F7; +constexpr unsigned int mmGENERIC_I2C_STATUS__VI = 0x16F6; +constexpr unsigned int mmGENERIC_I2C_TRANSACTION__VI = 0x16F9; +constexpr unsigned int mmGMCON_LPT_TARGET__VI = 0x0D53; +constexpr unsigned int mmGPU_BIST_CONTROL__VI = 0xF835; +constexpr unsigned int mmGRBM_CAM_DATA__SI__CI = 0x3001; +constexpr unsigned int mmGRBM_CAM_DATA__VI = 0xF83F; +constexpr unsigned int mmGRBM_CAM_INDEX__SI__CI = 0x3000; +constexpr unsigned int mmGRBM_CAM_INDEX__VI = 0xF83E; +constexpr unsigned int mmGRBM_DSM_BYPASS__VI = 0x201E; +constexpr unsigned int mmGRBM_HYP_CAM_DATA__VI = 0xF83F; +constexpr unsigned int mmGRBM_HYP_CAM_INDEX__VI = 0xF83E; +constexpr unsigned int mmGRBM_TRAP_ADDR__VI = 0x201A; +constexpr unsigned int mmGRBM_TRAP_ADDR_MSK__VI = 0x201B; +constexpr unsigned int mmGRBM_TRAP_OP__VI = 0x2019; +constexpr unsigned int mmGRBM_TRAP_WD__VI = 0x201C; +constexpr unsigned int mmGRBM_TRAP_WD_MSK__VI = 0x201D; +constexpr unsigned int mmGRBM_WRITE_ERROR__VI = 0x201F; +constexpr unsigned int mmGRPH_FLIP_RATE_CNTL__VI = 0x1A8E; +constexpr unsigned int mmGRPH_STEREOSYNC_FLIP__VI = 0x1A97; +constexpr unsigned int mmGRPH_XDMA_CACHE_UNDERFLOW_DET_CNTL__VI = 0x1A9F; +constexpr unsigned int mmGRPH_XDMA_CACHE_UNDERFLOW_DET_STATUS__VI = 0x1ABF; +constexpr unsigned int mmGRPH_XDMA_RECOVERY_SURFACE_ADDRESS__VI = 0x1ABD; +constexpr unsigned int mmGRPH_XDMA_RECOVERY_SURFACE_ADDRESS_HIGH__VI = 0x1ABE; +constexpr unsigned int mmGSKT_CONTROL__VI = 0x14BF; +constexpr unsigned int mmHDMI_ACR_32_0__VI = 0x4A2E; +constexpr unsigned int mmHDMI_ACR_32_1__VI = 0x4A2F; +constexpr unsigned int mmHDMI_ACR_44_0__VI = 0x4A30; +constexpr unsigned int mmHDMI_ACR_44_1__VI = 0x4A31; +constexpr unsigned int mmHDMI_ACR_48_0__VI = 0x4A32; +constexpr unsigned int mmHDMI_ACR_48_1__VI = 0x4A33; +constexpr unsigned int mmHDMI_ACR_PACKET_CONTROL__VI = 0x4A0C; +constexpr unsigned int mmHDMI_ACR_STATUS_0__VI = 0x4A34; +constexpr unsigned int mmHDMI_ACR_STATUS_1__VI = 0x4A35; +constexpr unsigned int mmHDMI_AUDIO_PACKET_CONTROL__VI = 0x4A0B; +constexpr unsigned int mmHDMI_CONTROL__VI = 0x4A09; +constexpr unsigned int mmHDMI_GC__VI = 0x4A13; +constexpr unsigned int mmHDMI_GENERIC_PACKET_CONTROL0__VI = 0x4A10; +constexpr unsigned int mmHDMI_GENERIC_PACKET_CONTROL1__VI = 0x4A2D; +constexpr unsigned int mmHDMI_INFOFRAME_CONTROL0__VI = 0x4A0E; +constexpr unsigned int mmHDMI_INFOFRAME_CONTROL1__VI = 0x4A0F; +constexpr unsigned int mmHDMI_STATUS__VI = 0x4A0A; +constexpr unsigned int mmHDMI_VBI_PACKET_CONTROL__VI = 0x4A0D; +constexpr unsigned int mmHDP_ADDR_CONFIG__VI = 0x0BD2; +constexpr unsigned int mmHDP_MEMIO_ADDR__VI = 0x0BF7; +constexpr unsigned int mmHDP_MEMIO_CNTL__VI = 0x0BF6; +constexpr unsigned int mmHDP_MEMIO_RD_DATA__VI = 0x0BFA; +constexpr unsigned int mmHDP_MEMIO_STATUS__VI = 0x0BF8; +constexpr unsigned int mmHDP_MEMIO_WR_DATA__VI = 0x0BF9; +constexpr unsigned int mmHDP_MEM_POWER_LS__VI = 0x0BD4; +constexpr unsigned int mmHDP_MISC_CNTL__VI = 0x0BD3; +constexpr unsigned int mmHDP_NONSURFACE_PREFETCH__VI = 0x0BD5; +constexpr unsigned int mmHDP_VF_ENABLE__VI = 0x0BFB; +constexpr unsigned int mmHDP_XDP_BARS_ADDR_39_36__VI = 0x0C44; +constexpr unsigned int mmHPD0_DC_HPD_CONTROL__VI = 0x189A; +constexpr unsigned int mmHPD0_DC_HPD_FAST_TRAIN_CNTL__VI = 0x189B; +constexpr unsigned int mmHPD0_DC_HPD_INT_CONTROL__VI = 0x1899; +constexpr unsigned int mmHPD0_DC_HPD_INT_STATUS__VI = 0x1898; +constexpr unsigned int mmHPD0_DC_HPD_TOGGLE_FILT_CNTL__VI = 0x189C; +constexpr unsigned int mmHPD1_DC_HPD_CONTROL__VI = 0x18A2; +constexpr unsigned int mmHPD1_DC_HPD_FAST_TRAIN_CNTL__VI = 0x18A3; +constexpr unsigned int mmHPD1_DC_HPD_INT_CONTROL__VI = 0x18A1; +constexpr unsigned int mmHPD1_DC_HPD_INT_STATUS__VI = 0x18A0; +constexpr unsigned int mmHPD1_DC_HPD_TOGGLE_FILT_CNTL__VI = 0x18A4; +constexpr unsigned int mmHPD2_DC_HPD_CONTROL__VI = 0x18AA; +constexpr unsigned int mmHPD2_DC_HPD_FAST_TRAIN_CNTL__VI = 0x18AB; +constexpr unsigned int mmHPD2_DC_HPD_INT_CONTROL__VI = 0x18A9; +constexpr unsigned int mmHPD2_DC_HPD_INT_STATUS__VI = 0x18A8; +constexpr unsigned int mmHPD2_DC_HPD_TOGGLE_FILT_CNTL__VI = 0x18AC; +constexpr unsigned int mmHPD3_DC_HPD_CONTROL__VI = 0x18B2; +constexpr unsigned int mmHPD3_DC_HPD_FAST_TRAIN_CNTL__VI = 0x18B3; +constexpr unsigned int mmHPD3_DC_HPD_INT_CONTROL__VI = 0x18B1; +constexpr unsigned int mmHPD3_DC_HPD_INT_STATUS__VI = 0x18B0; +constexpr unsigned int mmHPD3_DC_HPD_TOGGLE_FILT_CNTL__VI = 0x18B4; +constexpr unsigned int mmHPD4_DC_HPD_CONTROL__VI = 0x18BA; +constexpr unsigned int mmHPD4_DC_HPD_FAST_TRAIN_CNTL__VI = 0x18BB; +constexpr unsigned int mmHPD4_DC_HPD_INT_CONTROL__VI = 0x18B9; +constexpr unsigned int mmHPD4_DC_HPD_INT_STATUS__VI = 0x18B8; +constexpr unsigned int mmHPD4_DC_HPD_TOGGLE_FILT_CNTL__VI = 0x18BC; +constexpr unsigned int mmHPD5_DC_HPD_CONTROL__VI = 0x18C2; +constexpr unsigned int mmHPD5_DC_HPD_FAST_TRAIN_CNTL__VI = 0x18C3; +constexpr unsigned int mmHPD5_DC_HPD_INT_CONTROL__VI = 0x18C1; +constexpr unsigned int mmHPD5_DC_HPD_INT_STATUS__VI = 0x18C0; +constexpr unsigned int mmHPD5_DC_HPD_TOGGLE_FILT_CNTL__VI = 0x18C4; +constexpr unsigned int mmHW_ROTATION__VI = 0x1A9E; +constexpr unsigned int mmIH_ACTIVE_FCN_ID__VI = 0x0E43; +constexpr unsigned int mmIH_CLIENT_MAY_SEND_INCOMPLETE_INT__VI = 0x0E4B; +constexpr unsigned int mmIH_CNTL__SI__CI = 0x0F86; +constexpr unsigned int mmIH_CNTL__VI = 0x0E36; +constexpr unsigned int mmIH_DEBUG__VI = 0x0E3C; +constexpr unsigned int mmIH_DOORBELL_RPTR__VI = 0x0E42; +constexpr unsigned int mmIH_DSM_MATCH_DATA_CONTROL__VI = 0x0E41; +constexpr unsigned int mmIH_DSM_MATCH_FIELD_CONTROL__VI = 0x0E40; +constexpr unsigned int mmIH_DSM_MATCH_VALUE_BIT_31_0__VI = 0x0E3D; +constexpr unsigned int mmIH_DSM_MATCH_VALUE_BIT_63_32__VI = 0x0E3E; +constexpr unsigned int mmIH_DSM_MATCH_VALUE_BIT_95_64__VI = 0x0E3F; +constexpr unsigned int mmIH_LEVEL_INTR_MASK__VI = 0x0E49; +constexpr unsigned int mmIH_LEVEL_STATUS__SI__CI = 0x0F87; +constexpr unsigned int mmIH_LEVEL_STATUS__VI = 0x0E37; +constexpr unsigned int mmIH_PERFCOUNTER0_RESULT__VI = 0x0E3A; +constexpr unsigned int mmIH_PERFCOUNTER1_RESULT__VI = 0x0E3B; +constexpr unsigned int mmIH_PERFMON_CNTL__VI = 0x0E39; +constexpr unsigned int mmIH_RB_BASE__SI__CI = 0x0F81; +constexpr unsigned int mmIH_RB_BASE__VI = 0x0E31; +constexpr unsigned int mmIH_RB_CNTL__SI__CI = 0x0F80; +constexpr unsigned int mmIH_RB_CNTL__VI = 0x0E30; +constexpr unsigned int mmIH_RB_RPTR__SI__CI = 0x0F82; +constexpr unsigned int mmIH_RB_RPTR__VI = 0x0E32; +constexpr unsigned int mmIH_RB_WPTR__SI__CI = 0x0F83; +constexpr unsigned int mmIH_RB_WPTR__VI = 0x0E33; +constexpr unsigned int mmIH_RB_WPTR_ADDR_HI__SI__CI = 0x0F84; +constexpr unsigned int mmIH_RB_WPTR_ADDR_HI__VI = 0x0E34; +constexpr unsigned int mmIH_RB_WPTR_ADDR_LO__SI__CI = 0x0F85; +constexpr unsigned int mmIH_RB_WPTR_ADDR_LO__VI = 0x0E35; +constexpr unsigned int mmIH_RESET_INCOMPLETE_INT_CNTL__VI = 0x0E4A; +constexpr unsigned int mmIH_STATUS__SI__CI = 0x0F88; +constexpr unsigned int mmIH_STATUS__VI = 0x0E38; +constexpr unsigned int mmIH_VERSION__VI = 0x0E48; +constexpr unsigned int mmIH_VF_ENABLE__VI = 0x0E45; +constexpr unsigned int mmIH_VF_RB_BIF_STATUS__VI = 0x0E47; +constexpr unsigned int mmIH_VF_RB_STATUS__VI = 0x0E44; +constexpr unsigned int mmIH_VIRT_RESET_REQ__VI = 0x0E46; +constexpr unsigned int mmIH_VMID_0_LUT__VI = 0x0E00; +constexpr unsigned int mmIH_VMID_10_LUT__VI = 0x0E0A; +constexpr unsigned int mmIH_VMID_11_LUT__VI = 0x0E0B; +constexpr unsigned int mmIH_VMID_12_LUT__VI = 0x0E0C; +constexpr unsigned int mmIH_VMID_13_LUT__VI = 0x0E0D; +constexpr unsigned int mmIH_VMID_14_LUT__VI = 0x0E0E; +constexpr unsigned int mmIH_VMID_15_LUT__VI = 0x0E0F; +constexpr unsigned int mmIH_VMID_1_LUT__VI = 0x0E01; +constexpr unsigned int mmIH_VMID_2_LUT__VI = 0x0E02; +constexpr unsigned int mmIH_VMID_3_LUT__VI = 0x0E03; +constexpr unsigned int mmIH_VMID_4_LUT__VI = 0x0E04; +constexpr unsigned int mmIH_VMID_5_LUT__VI = 0x0E05; +constexpr unsigned int mmIH_VMID_6_LUT__VI = 0x0E06; +constexpr unsigned int mmIH_VMID_7_LUT__VI = 0x0E07; +constexpr unsigned int mmIH_VMID_8_LUT__VI = 0x0E08; +constexpr unsigned int mmIH_VMID_9_LUT__VI = 0x0E09; +constexpr unsigned int mmINPUT_CSC_C11_C12__VI = 0x1A36; +constexpr unsigned int mmINPUT_CSC_C11_C12_A__VI = 0x46A6; +constexpr unsigned int mmINPUT_CSC_C11_C12_B__VI = 0x46AC; +constexpr unsigned int mmINPUT_CSC_C13_C14__VI = 0x1A37; +constexpr unsigned int mmINPUT_CSC_C13_C14_A__VI = 0x46A7; +constexpr unsigned int mmINPUT_CSC_C13_C14_B__VI = 0x46AD; +constexpr unsigned int mmINPUT_CSC_C21_C22__VI = 0x1A38; +constexpr unsigned int mmINPUT_CSC_C21_C22_A__VI = 0x46A8; +constexpr unsigned int mmINPUT_CSC_C21_C22_B__VI = 0x46AE; +constexpr unsigned int mmINPUT_CSC_C23_C24__VI = 0x1A39; +constexpr unsigned int mmINPUT_CSC_C23_C24_A__VI = 0x46A9; +constexpr unsigned int mmINPUT_CSC_C23_C24_B__VI = 0x46AF; +constexpr unsigned int mmINPUT_CSC_C31_C32__VI = 0x1A3A; +constexpr unsigned int mmINPUT_CSC_C31_C32_A__VI = 0x46AA; +constexpr unsigned int mmINPUT_CSC_C31_C32_B__VI = 0x46B0; +constexpr unsigned int mmINPUT_CSC_C33_C34__VI = 0x1A3B; +constexpr unsigned int mmINPUT_CSC_C33_C34_A__VI = 0x46AB; +constexpr unsigned int mmINPUT_CSC_C33_C34_B__VI = 0x46B1; +constexpr unsigned int mmINPUT_CSC_CONTROL__VI = 0x1A35; +constexpr unsigned int mmINPUT_GAMMA_CONTROL__VI = 0x1A10; +constexpr unsigned int mmKEY_CONTROL__VI = 0x1A53; +constexpr unsigned int mmKEY_RANGE_ALPHA__VI = 0x1A54; +constexpr unsigned int mmKEY_RANGE_BLUE__VI = 0x1A57; +constexpr unsigned int mmKEY_RANGE_GREEN__VI = 0x1A56; +constexpr unsigned int mmKEY_RANGE_RED__VI = 0x1A55; +constexpr unsigned int mmLB0_DC_MVP_LB_CONTROL__VI = 0x1AE3; +constexpr unsigned int mmLB0_LB_BLACK_KEYER_B_CB__VI = 0x1ACF; +constexpr unsigned int mmLB0_LB_BLACK_KEYER_G_Y__VI = 0x1ACE; +constexpr unsigned int mmLB0_LB_BLACK_KEYER_R_CR__VI = 0x1ACD; +constexpr unsigned int mmLB0_LB_BUFFER_LEVEL_STATUS__VI = 0x1AD7; +constexpr unsigned int mmLB0_LB_BUFFER_STATUS__VI = 0x1ADA; +constexpr unsigned int mmLB0_LB_BUFFER_URGENCY_CTRL__VI = 0x1AD8; +constexpr unsigned int mmLB0_LB_BUFFER_URGENCY_STATUS__VI = 0x1AD9; +constexpr unsigned int mmLB0_LB_DATA_FORMAT__VI = 0x1AC0; +constexpr unsigned int mmLB0_LB_DEBUG__VI = 0x1AE4; +constexpr unsigned int mmLB0_LB_DEBUG2__VI = 0x1AE5; +constexpr unsigned int mmLB0_LB_DEBUG3__VI = 0x1AE6; +constexpr unsigned int mmLB0_LB_DESKTOP_HEIGHT__VI = 0x1AC3; +constexpr unsigned int mmLB0_LB_INTERRUPT_MASK__VI = 0x1AC8; +constexpr unsigned int mmLB0_LB_KEYER_COLOR_B_CB__VI = 0x1AD3; +constexpr unsigned int mmLB0_LB_KEYER_COLOR_CTRL__VI = 0x1AD0; +constexpr unsigned int mmLB0_LB_KEYER_COLOR_G_Y__VI = 0x1AD2; +constexpr unsigned int mmLB0_LB_KEYER_COLOR_REP_B_CB__VI = 0x1AD6; +constexpr unsigned int mmLB0_LB_KEYER_COLOR_REP_G_Y__VI = 0x1AD5; +constexpr unsigned int mmLB0_LB_KEYER_COLOR_REP_R_CR__VI = 0x1AD4; +constexpr unsigned int mmLB0_LB_KEYER_COLOR_R_CR__VI = 0x1AD1; +constexpr unsigned int mmLB0_LB_MEMORY_CTRL__VI = 0x1AC1; +constexpr unsigned int mmLB0_LB_MEMORY_SIZE_STATUS__VI = 0x1AC2; +constexpr unsigned int mmLB0_LB_NO_OUTSTANDING_REQ_STATUS__VI = 0x1ADC; +constexpr unsigned int mmLB0_LB_SNAPSHOT_V_COUNTER__VI = 0x1AC7; +constexpr unsigned int mmLB0_LB_SYNC_RESET_SEL__VI = 0x1ACC; +constexpr unsigned int mmLB0_LB_VBLANK_STATUS__VI = 0x1ACB; +constexpr unsigned int mmLB0_LB_VLINE2_START_END__VI = 0x1AC5; +constexpr unsigned int mmLB0_LB_VLINE2_STATUS__VI = 0x1ACA; +constexpr unsigned int mmLB0_LB_VLINE_START_END__VI = 0x1AC4; +constexpr unsigned int mmLB0_LB_VLINE_STATUS__VI = 0x1AC9; +constexpr unsigned int mmLB0_LB_V_COUNTER__VI = 0x1AC6; +constexpr unsigned int mmLB0_MVP_AFR_FLIP_FIFO_CNTL__VI = 0x1AE1; +constexpr unsigned int mmLB0_MVP_AFR_FLIP_MODE__VI = 0x1AE0; +constexpr unsigned int mmLB0_MVP_FLIP_LINE_NUM_INSERT__VI = 0x1AE2; +constexpr unsigned int mmLB1_DC_MVP_LB_CONTROL__VI = 0x1CE3; +constexpr unsigned int mmLB1_LB_BLACK_KEYER_B_CB__VI = 0x1CCF; +constexpr unsigned int mmLB1_LB_BLACK_KEYER_G_Y__VI = 0x1CCE; +constexpr unsigned int mmLB1_LB_BLACK_KEYER_R_CR__VI = 0x1CCD; +constexpr unsigned int mmLB1_LB_BUFFER_LEVEL_STATUS__VI = 0x1CD7; +constexpr unsigned int mmLB1_LB_BUFFER_STATUS__VI = 0x1CDA; +constexpr unsigned int mmLB1_LB_BUFFER_URGENCY_CTRL__VI = 0x1CD8; +constexpr unsigned int mmLB1_LB_BUFFER_URGENCY_STATUS__VI = 0x1CD9; +constexpr unsigned int mmLB1_LB_DATA_FORMAT__VI = 0x1CC0; +constexpr unsigned int mmLB1_LB_DEBUG__VI = 0x1CE4; +constexpr unsigned int mmLB1_LB_DEBUG2__VI = 0x1CE5; +constexpr unsigned int mmLB1_LB_DEBUG3__VI = 0x1CE6; +constexpr unsigned int mmLB1_LB_DESKTOP_HEIGHT__VI = 0x1CC3; +constexpr unsigned int mmLB1_LB_INTERRUPT_MASK__VI = 0x1CC8; +constexpr unsigned int mmLB1_LB_KEYER_COLOR_B_CB__VI = 0x1CD3; +constexpr unsigned int mmLB1_LB_KEYER_COLOR_CTRL__VI = 0x1CD0; +constexpr unsigned int mmLB1_LB_KEYER_COLOR_G_Y__VI = 0x1CD2; +constexpr unsigned int mmLB1_LB_KEYER_COLOR_REP_B_CB__VI = 0x1CD6; +constexpr unsigned int mmLB1_LB_KEYER_COLOR_REP_G_Y__VI = 0x1CD5; +constexpr unsigned int mmLB1_LB_KEYER_COLOR_REP_R_CR__VI = 0x1CD4; +constexpr unsigned int mmLB1_LB_KEYER_COLOR_R_CR__VI = 0x1CD1; +constexpr unsigned int mmLB1_LB_MEMORY_CTRL__VI = 0x1CC1; +constexpr unsigned int mmLB1_LB_MEMORY_SIZE_STATUS__VI = 0x1CC2; +constexpr unsigned int mmLB1_LB_NO_OUTSTANDING_REQ_STATUS__VI = 0x1CDC; +constexpr unsigned int mmLB1_LB_SNAPSHOT_V_COUNTER__VI = 0x1CC7; +constexpr unsigned int mmLB1_LB_SYNC_RESET_SEL__VI = 0x1CCC; +constexpr unsigned int mmLB1_LB_TEST_DEBUG_DATA__VI = 0x1CFF; +constexpr unsigned int mmLB1_LB_TEST_DEBUG_INDEX__VI = 0x1CFE; +constexpr unsigned int mmLB1_LB_VBLANK_STATUS__VI = 0x1CCB; +constexpr unsigned int mmLB1_LB_VLINE2_START_END__VI = 0x1CC5; +constexpr unsigned int mmLB1_LB_VLINE2_STATUS__VI = 0x1CCA; +constexpr unsigned int mmLB1_LB_VLINE_START_END__VI = 0x1CC4; +constexpr unsigned int mmLB1_LB_VLINE_STATUS__VI = 0x1CC9; +constexpr unsigned int mmLB1_LB_V_COUNTER__VI = 0x1CC6; +constexpr unsigned int mmLB1_MVP_AFR_FLIP_FIFO_CNTL__VI = 0x1CE1; +constexpr unsigned int mmLB1_MVP_AFR_FLIP_MODE__VI = 0x1CE0; +constexpr unsigned int mmLB1_MVP_FLIP_LINE_NUM_INSERT__VI = 0x1CE2; +constexpr unsigned int mmLB2_DC_MVP_LB_CONTROL__VI = 0x1EE3; +constexpr unsigned int mmLB2_LB_BLACK_KEYER_B_CB__VI = 0x1ECF; +constexpr unsigned int mmLB2_LB_BLACK_KEYER_G_Y__VI = 0x1ECE; +constexpr unsigned int mmLB2_LB_BLACK_KEYER_R_CR__VI = 0x1ECD; +constexpr unsigned int mmLB2_LB_BUFFER_LEVEL_STATUS__VI = 0x1ED7; +constexpr unsigned int mmLB2_LB_BUFFER_STATUS__VI = 0x1EDA; +constexpr unsigned int mmLB2_LB_BUFFER_URGENCY_CTRL__VI = 0x1ED8; +constexpr unsigned int mmLB2_LB_BUFFER_URGENCY_STATUS__VI = 0x1ED9; +constexpr unsigned int mmLB2_LB_DATA_FORMAT__VI = 0x1EC0; +constexpr unsigned int mmLB2_LB_DEBUG__VI = 0x1EE4; +constexpr unsigned int mmLB2_LB_DEBUG2__VI = 0x1EE5; +constexpr unsigned int mmLB2_LB_DEBUG3__VI = 0x1EE6; +constexpr unsigned int mmLB2_LB_DESKTOP_HEIGHT__VI = 0x1EC3; +constexpr unsigned int mmLB2_LB_INTERRUPT_MASK__VI = 0x1EC8; +constexpr unsigned int mmLB2_LB_KEYER_COLOR_B_CB__VI = 0x1ED3; +constexpr unsigned int mmLB2_LB_KEYER_COLOR_CTRL__VI = 0x1ED0; +constexpr unsigned int mmLB2_LB_KEYER_COLOR_G_Y__VI = 0x1ED2; +constexpr unsigned int mmLB2_LB_KEYER_COLOR_REP_B_CB__VI = 0x1ED6; +constexpr unsigned int mmLB2_LB_KEYER_COLOR_REP_G_Y__VI = 0x1ED5; +constexpr unsigned int mmLB2_LB_KEYER_COLOR_REP_R_CR__VI = 0x1ED4; +constexpr unsigned int mmLB2_LB_KEYER_COLOR_R_CR__VI = 0x1ED1; +constexpr unsigned int mmLB2_LB_MEMORY_CTRL__VI = 0x1EC1; +constexpr unsigned int mmLB2_LB_MEMORY_SIZE_STATUS__VI = 0x1EC2; +constexpr unsigned int mmLB2_LB_NO_OUTSTANDING_REQ_STATUS__VI = 0x1EDC; +constexpr unsigned int mmLB2_LB_SNAPSHOT_V_COUNTER__VI = 0x1EC7; +constexpr unsigned int mmLB2_LB_SYNC_RESET_SEL__VI = 0x1ECC; +constexpr unsigned int mmLB2_LB_TEST_DEBUG_DATA__VI = 0x1EFF; +constexpr unsigned int mmLB2_LB_TEST_DEBUG_INDEX__VI = 0x1EFE; +constexpr unsigned int mmLB2_LB_VBLANK_STATUS__VI = 0x1ECB; +constexpr unsigned int mmLB2_LB_VLINE2_START_END__VI = 0x1EC5; +constexpr unsigned int mmLB2_LB_VLINE2_STATUS__VI = 0x1ECA; +constexpr unsigned int mmLB2_LB_VLINE_START_END__VI = 0x1EC4; +constexpr unsigned int mmLB2_LB_VLINE_STATUS__VI = 0x1EC9; +constexpr unsigned int mmLB2_LB_V_COUNTER__VI = 0x1EC6; +constexpr unsigned int mmLB2_MVP_AFR_FLIP_FIFO_CNTL__VI = 0x1EE1; +constexpr unsigned int mmLB2_MVP_AFR_FLIP_MODE__VI = 0x1EE0; +constexpr unsigned int mmLB2_MVP_FLIP_LINE_NUM_INSERT__VI = 0x1EE2; +constexpr unsigned int mmLB3_DC_MVP_LB_CONTROL__VI = 0x40E3; +constexpr unsigned int mmLB3_LB_BLACK_KEYER_B_CB__VI = 0x40CF; +constexpr unsigned int mmLB3_LB_BLACK_KEYER_G_Y__VI = 0x40CE; +constexpr unsigned int mmLB3_LB_BLACK_KEYER_R_CR__VI = 0x40CD; +constexpr unsigned int mmLB3_LB_BUFFER_LEVEL_STATUS__VI = 0x40D7; +constexpr unsigned int mmLB3_LB_BUFFER_STATUS__VI = 0x40DA; +constexpr unsigned int mmLB3_LB_BUFFER_URGENCY_CTRL__VI = 0x40D8; +constexpr unsigned int mmLB3_LB_BUFFER_URGENCY_STATUS__VI = 0x40D9; +constexpr unsigned int mmLB3_LB_DATA_FORMAT__VI = 0x40C0; +constexpr unsigned int mmLB3_LB_DEBUG__VI = 0x40E4; +constexpr unsigned int mmLB3_LB_DEBUG2__VI = 0x40E5; +constexpr unsigned int mmLB3_LB_DEBUG3__VI = 0x40E6; +constexpr unsigned int mmLB3_LB_DESKTOP_HEIGHT__VI = 0x40C3; +constexpr unsigned int mmLB3_LB_INTERRUPT_MASK__VI = 0x40C8; +constexpr unsigned int mmLB3_LB_KEYER_COLOR_B_CB__VI = 0x40D3; +constexpr unsigned int mmLB3_LB_KEYER_COLOR_CTRL__VI = 0x40D0; +constexpr unsigned int mmLB3_LB_KEYER_COLOR_G_Y__VI = 0x40D2; +constexpr unsigned int mmLB3_LB_KEYER_COLOR_REP_B_CB__VI = 0x40D6; +constexpr unsigned int mmLB3_LB_KEYER_COLOR_REP_G_Y__VI = 0x40D5; +constexpr unsigned int mmLB3_LB_KEYER_COLOR_REP_R_CR__VI = 0x40D4; +constexpr unsigned int mmLB3_LB_KEYER_COLOR_R_CR__VI = 0x40D1; +constexpr unsigned int mmLB3_LB_MEMORY_CTRL__VI = 0x40C1; +constexpr unsigned int mmLB3_LB_MEMORY_SIZE_STATUS__VI = 0x40C2; +constexpr unsigned int mmLB3_LB_NO_OUTSTANDING_REQ_STATUS__VI = 0x40DC; +constexpr unsigned int mmLB3_LB_SNAPSHOT_V_COUNTER__VI = 0x40C7; +constexpr unsigned int mmLB3_LB_SYNC_RESET_SEL__VI = 0x40CC; +constexpr unsigned int mmLB3_LB_TEST_DEBUG_DATA__VI = 0x40FF; +constexpr unsigned int mmLB3_LB_TEST_DEBUG_INDEX__VI = 0x40FE; +constexpr unsigned int mmLB3_LB_VBLANK_STATUS__VI = 0x40CB; +constexpr unsigned int mmLB3_LB_VLINE2_START_END__VI = 0x40C5; +constexpr unsigned int mmLB3_LB_VLINE2_STATUS__VI = 0x40CA; +constexpr unsigned int mmLB3_LB_VLINE_START_END__VI = 0x40C4; +constexpr unsigned int mmLB3_LB_VLINE_STATUS__VI = 0x40C9; +constexpr unsigned int mmLB3_LB_V_COUNTER__VI = 0x40C6; +constexpr unsigned int mmLB3_MVP_AFR_FLIP_FIFO_CNTL__VI = 0x40E1; +constexpr unsigned int mmLB3_MVP_AFR_FLIP_MODE__VI = 0x40E0; +constexpr unsigned int mmLB3_MVP_FLIP_LINE_NUM_INSERT__VI = 0x40E2; +constexpr unsigned int mmLB4_DC_MVP_LB_CONTROL__VI = 0x42E3; +constexpr unsigned int mmLB4_LB_BLACK_KEYER_B_CB__VI = 0x42CF; +constexpr unsigned int mmLB4_LB_BLACK_KEYER_G_Y__VI = 0x42CE; +constexpr unsigned int mmLB4_LB_BLACK_KEYER_R_CR__VI = 0x42CD; +constexpr unsigned int mmLB4_LB_BUFFER_LEVEL_STATUS__VI = 0x42D7; +constexpr unsigned int mmLB4_LB_BUFFER_STATUS__VI = 0x42DA; +constexpr unsigned int mmLB4_LB_BUFFER_URGENCY_CTRL__VI = 0x42D8; +constexpr unsigned int mmLB4_LB_BUFFER_URGENCY_STATUS__VI = 0x42D9; +constexpr unsigned int mmLB4_LB_DATA_FORMAT__VI = 0x42C0; +constexpr unsigned int mmLB4_LB_DEBUG__VI = 0x42E4; +constexpr unsigned int mmLB4_LB_DEBUG2__VI = 0x42E5; +constexpr unsigned int mmLB4_LB_DEBUG3__VI = 0x42E6; +constexpr unsigned int mmLB4_LB_DESKTOP_HEIGHT__VI = 0x42C3; +constexpr unsigned int mmLB4_LB_INTERRUPT_MASK__VI = 0x42C8; +constexpr unsigned int mmLB4_LB_KEYER_COLOR_B_CB__VI = 0x42D3; +constexpr unsigned int mmLB4_LB_KEYER_COLOR_CTRL__VI = 0x42D0; +constexpr unsigned int mmLB4_LB_KEYER_COLOR_G_Y__VI = 0x42D2; +constexpr unsigned int mmLB4_LB_KEYER_COLOR_REP_B_CB__VI = 0x42D6; +constexpr unsigned int mmLB4_LB_KEYER_COLOR_REP_G_Y__VI = 0x42D5; +constexpr unsigned int mmLB4_LB_KEYER_COLOR_REP_R_CR__VI = 0x42D4; +constexpr unsigned int mmLB4_LB_KEYER_COLOR_R_CR__VI = 0x42D1; +constexpr unsigned int mmLB4_LB_MEMORY_CTRL__VI = 0x42C1; +constexpr unsigned int mmLB4_LB_MEMORY_SIZE_STATUS__VI = 0x42C2; +constexpr unsigned int mmLB4_LB_NO_OUTSTANDING_REQ_STATUS__VI = 0x42DC; +constexpr unsigned int mmLB4_LB_SNAPSHOT_V_COUNTER__VI = 0x42C7; +constexpr unsigned int mmLB4_LB_SYNC_RESET_SEL__VI = 0x42CC; +constexpr unsigned int mmLB4_LB_TEST_DEBUG_DATA__VI = 0x42FF; +constexpr unsigned int mmLB4_LB_TEST_DEBUG_INDEX__VI = 0x42FE; +constexpr unsigned int mmLB4_LB_VBLANK_STATUS__VI = 0x42CB; +constexpr unsigned int mmLB4_LB_VLINE2_START_END__VI = 0x42C5; +constexpr unsigned int mmLB4_LB_VLINE2_STATUS__VI = 0x42CA; +constexpr unsigned int mmLB4_LB_VLINE_START_END__VI = 0x42C4; +constexpr unsigned int mmLB4_LB_VLINE_STATUS__VI = 0x42C9; +constexpr unsigned int mmLB4_LB_V_COUNTER__VI = 0x42C6; +constexpr unsigned int mmLB4_MVP_AFR_FLIP_FIFO_CNTL__VI = 0x42E1; +constexpr unsigned int mmLB4_MVP_AFR_FLIP_MODE__VI = 0x42E0; +constexpr unsigned int mmLB4_MVP_FLIP_LINE_NUM_INSERT__VI = 0x42E2; +constexpr unsigned int mmLB5_DC_MVP_LB_CONTROL__VI = 0x44E3; +constexpr unsigned int mmLB5_LB_BLACK_KEYER_B_CB__VI = 0x44CF; +constexpr unsigned int mmLB5_LB_BLACK_KEYER_G_Y__VI = 0x44CE; +constexpr unsigned int mmLB5_LB_BLACK_KEYER_R_CR__VI = 0x44CD; +constexpr unsigned int mmLB5_LB_BUFFER_LEVEL_STATUS__VI = 0x44D7; +constexpr unsigned int mmLB5_LB_BUFFER_STATUS__VI = 0x44DA; +constexpr unsigned int mmLB5_LB_BUFFER_URGENCY_CTRL__VI = 0x44D8; +constexpr unsigned int mmLB5_LB_BUFFER_URGENCY_STATUS__VI = 0x44D9; +constexpr unsigned int mmLB5_LB_DATA_FORMAT__VI = 0x44C0; +constexpr unsigned int mmLB5_LB_DEBUG__VI = 0x44E4; +constexpr unsigned int mmLB5_LB_DEBUG2__VI = 0x44E5; +constexpr unsigned int mmLB5_LB_DEBUG3__VI = 0x44E6; +constexpr unsigned int mmLB5_LB_DESKTOP_HEIGHT__VI = 0x44C3; +constexpr unsigned int mmLB5_LB_INTERRUPT_MASK__VI = 0x44C8; +constexpr unsigned int mmLB5_LB_KEYER_COLOR_B_CB__VI = 0x44D3; +constexpr unsigned int mmLB5_LB_KEYER_COLOR_CTRL__VI = 0x44D0; +constexpr unsigned int mmLB5_LB_KEYER_COLOR_G_Y__VI = 0x44D2; +constexpr unsigned int mmLB5_LB_KEYER_COLOR_REP_B_CB__VI = 0x44D6; +constexpr unsigned int mmLB5_LB_KEYER_COLOR_REP_G_Y__VI = 0x44D5; +constexpr unsigned int mmLB5_LB_KEYER_COLOR_REP_R_CR__VI = 0x44D4; +constexpr unsigned int mmLB5_LB_KEYER_COLOR_R_CR__VI = 0x44D1; +constexpr unsigned int mmLB5_LB_MEMORY_CTRL__VI = 0x44C1; +constexpr unsigned int mmLB5_LB_MEMORY_SIZE_STATUS__VI = 0x44C2; +constexpr unsigned int mmLB5_LB_NO_OUTSTANDING_REQ_STATUS__VI = 0x44DC; +constexpr unsigned int mmLB5_LB_SNAPSHOT_V_COUNTER__VI = 0x44C7; +constexpr unsigned int mmLB5_LB_SYNC_RESET_SEL__VI = 0x44CC; +constexpr unsigned int mmLB5_LB_TEST_DEBUG_DATA__VI = 0x44FF; +constexpr unsigned int mmLB5_LB_TEST_DEBUG_INDEX__VI = 0x44FE; +constexpr unsigned int mmLB5_LB_VBLANK_STATUS__VI = 0x44CB; +constexpr unsigned int mmLB5_LB_VLINE2_START_END__VI = 0x44C5; +constexpr unsigned int mmLB5_LB_VLINE2_STATUS__VI = 0x44CA; +constexpr unsigned int mmLB5_LB_VLINE_START_END__VI = 0x44C4; +constexpr unsigned int mmLB5_LB_VLINE_STATUS__VI = 0x44C9; +constexpr unsigned int mmLB5_LB_V_COUNTER__VI = 0x44C6; +constexpr unsigned int mmLB5_MVP_AFR_FLIP_FIFO_CNTL__VI = 0x44E1; +constexpr unsigned int mmLB5_MVP_AFR_FLIP_MODE__VI = 0x44E0; +constexpr unsigned int mmLB5_MVP_FLIP_LINE_NUM_INSERT__VI = 0x44E2; +constexpr unsigned int mmLBV_BLACK_KEYER_B_CB__VI = 0x464D; +constexpr unsigned int mmLBV_BLACK_KEYER_G_Y__VI = 0x464C; +constexpr unsigned int mmLBV_BLACK_KEYER_R_CR__VI = 0x464B; +constexpr unsigned int mmLBV_BUFFER_LEVEL_STATUS__VI = 0x4655; +constexpr unsigned int mmLBV_BUFFER_STATUS__VI = 0x4658; +constexpr unsigned int mmLBV_BUFFER_URGENCY_CTRL__VI = 0x4656; +constexpr unsigned int mmLBV_BUFFER_URGENCY_STATUS__VI = 0x4657; +constexpr unsigned int mmLBV_DATA_FORMAT__VI = 0x463C; +constexpr unsigned int mmLBV_DEBUG__VI = 0x465A; +constexpr unsigned int mmLBV_DEBUG2__VI = 0x465B; +constexpr unsigned int mmLBV_DEBUG3__VI = 0x465C; +constexpr unsigned int mmLBV_DESKTOP_HEIGHT__VI = 0x463F; +constexpr unsigned int mmLBV_INTERRUPT_MASK__VI = 0x4646; +constexpr unsigned int mmLBV_KEYER_COLOR_B_CB__VI = 0x4651; +constexpr unsigned int mmLBV_KEYER_COLOR_CTRL__VI = 0x464E; +constexpr unsigned int mmLBV_KEYER_COLOR_G_Y__VI = 0x4650; +constexpr unsigned int mmLBV_KEYER_COLOR_REP_B_CB__VI = 0x4654; +constexpr unsigned int mmLBV_KEYER_COLOR_REP_G_Y__VI = 0x4653; +constexpr unsigned int mmLBV_KEYER_COLOR_REP_R_CR__VI = 0x4652; +constexpr unsigned int mmLBV_KEYER_COLOR_R_CR__VI = 0x464F; +constexpr unsigned int mmLBV_MEMORY_CTRL__VI = 0x463D; +constexpr unsigned int mmLBV_MEMORY_SIZE_STATUS__VI = 0x463E; +constexpr unsigned int mmLBV_NO_OUTSTANDING_REQ_STATUS__VI = 0x4659; +constexpr unsigned int mmLBV_SNAPSHOT_V_COUNTER__VI = 0x4643; +constexpr unsigned int mmLBV_SNAPSHOT_V_COUNTER_CHROMA__VI = 0x4645; +constexpr unsigned int mmLBV_SYNC_RESET_SEL__VI = 0x464A; +constexpr unsigned int mmLBV_TEST_DEBUG_DATA__VI = 0x4667; +constexpr unsigned int mmLBV_TEST_DEBUG_INDEX__VI = 0x4666; +constexpr unsigned int mmLBV_VBLANK_STATUS__VI = 0x4649; +constexpr unsigned int mmLBV_VLINE2_START_END__VI = 0x4641; +constexpr unsigned int mmLBV_VLINE2_STATUS__VI = 0x4648; +constexpr unsigned int mmLBV_VLINE_START_END__VI = 0x4640; +constexpr unsigned int mmLBV_VLINE_STATUS__VI = 0x4647; +constexpr unsigned int mmLBV_V_COUNTER__VI = 0x4642; +constexpr unsigned int mmLBV_V_COUNTER_CHROMA__VI = 0x4644; +constexpr unsigned int mmLB_BLACK_KEYER_B_CB__VI = 0x1ACF; +constexpr unsigned int mmLB_BLACK_KEYER_G_Y__VI = 0x1ACE; +constexpr unsigned int mmLB_BLACK_KEYER_R_CR__VI = 0x1ACD; +constexpr unsigned int mmLB_BUFFER_LEVEL_STATUS__VI = 0x1AD7; +constexpr unsigned int mmLB_BUFFER_STATUS__VI = 0x1ADA; +constexpr unsigned int mmLB_BUFFER_URGENCY_CTRL__VI = 0x1AD8; +constexpr unsigned int mmLB_BUFFER_URGENCY_STATUS__VI = 0x1AD9; +constexpr unsigned int mmLB_DATA_FORMAT__VI = 0x1AC0; +constexpr unsigned int mmLB_DEBUG__VI = 0x1AE4; +constexpr unsigned int mmLB_DEBUG2__VI = 0x1AE5; +constexpr unsigned int mmLB_DEBUG3__VI = 0x1AE6; +constexpr unsigned int mmLB_DESKTOP_HEIGHT__VI = 0x1AC3; +constexpr unsigned int mmLB_INTERRUPT_MASK__VI = 0x1AC8; +constexpr unsigned int mmLB_KEYER_COLOR_B_CB__VI = 0x1AD3; +constexpr unsigned int mmLB_KEYER_COLOR_CTRL__VI = 0x1AD0; +constexpr unsigned int mmLB_KEYER_COLOR_G_Y__VI = 0x1AD2; +constexpr unsigned int mmLB_KEYER_COLOR_REP_B_CB__VI = 0x1AD6; +constexpr unsigned int mmLB_KEYER_COLOR_REP_G_Y__VI = 0x1AD5; +constexpr unsigned int mmLB_KEYER_COLOR_REP_R_CR__VI = 0x1AD4; +constexpr unsigned int mmLB_KEYER_COLOR_R_CR__VI = 0x1AD1; +constexpr unsigned int mmLB_MEMORY_CTRL__VI = 0x1AC1; +constexpr unsigned int mmLB_MEMORY_SIZE_STATUS__VI = 0x1AC2; +constexpr unsigned int mmLB_NO_OUTSTANDING_REQ_STATUS__VI = 0x1ADC; +constexpr unsigned int mmLB_SNAPSHOT_V_COUNTER__VI = 0x1AC7; +constexpr unsigned int mmLB_SYNC_RESET_SEL__VI = 0x1ACC; +constexpr unsigned int mmLB_VBLANK_STATUS__VI = 0x1ACB; +constexpr unsigned int mmLB_VLINE2_START_END__VI = 0x1AC5; +constexpr unsigned int mmLB_VLINE2_STATUS__VI = 0x1ACA; +constexpr unsigned int mmLB_VLINE_START_END__VI = 0x1AC4; +constexpr unsigned int mmLB_VLINE_STATUS__VI = 0x1AC9; +constexpr unsigned int mmLB_V_COUNTER__VI = 0x1AC6; +constexpr unsigned int mmLOW_POWER_TILING_CONTROL__VI = 0x030B; +constexpr unsigned int mmLVDS_DATA_CNTL__VI = 0x4A78; +constexpr unsigned int mmLVTMA_PWRSEQ_CNTL__VI = 0x481B; +constexpr unsigned int mmLVTMA_PWRSEQ_DELAY1__VI = 0x481E; +constexpr unsigned int mmLVTMA_PWRSEQ_DELAY2__VI = 0x481F; +constexpr unsigned int mmLVTMA_PWRSEQ_REF_DIV__VI = 0x481D; +constexpr unsigned int mmLVTMA_PWRSEQ_STATE__VI = 0x481C; +constexpr unsigned int mmMAILBOX_CONTROL__VI = 0x14D0; +constexpr unsigned int mmMAILBOX_INDEX__VI = 0x14C6; +constexpr unsigned int mmMAILBOX_INT_CNTL__VI = 0x14D1; +constexpr unsigned int mmMAILBOX_MSGBUF_RCV_DW0__VI = 0x14CC; +constexpr unsigned int mmMAILBOX_MSGBUF_RCV_DW1__VI = 0x14CD; +constexpr unsigned int mmMAILBOX_MSGBUF_RCV_DW2__VI = 0x14CE; +constexpr unsigned int mmMAILBOX_MSGBUF_RCV_DW3__VI = 0x14CF; +constexpr unsigned int mmMAILBOX_MSGBUF_TRN_DW0__VI = 0x14C8; +constexpr unsigned int mmMAILBOX_MSGBUF_TRN_DW1__VI = 0x14C9; +constexpr unsigned int mmMAILBOX_MSGBUF_TRN_DW2__VI = 0x14CA; +constexpr unsigned int mmMAILBOX_MSGBUF_TRN_DW3__VI = 0x14CB; +constexpr unsigned int mmMCIF_CONTROL__VI = 0x030C; +constexpr unsigned int mmMCIF_MEM_CONTROL__VI = 0x0311; +constexpr unsigned int mmMCIF_TEST_DEBUG_DATA__VI = 0x030F; +constexpr unsigned int mmMCIF_TEST_DEBUG_INDEX__VI = 0x030E; +constexpr unsigned int mmMCIF_VMID__VI = 0x0310; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_ARBITRATION_CONTROL__VI = 0x5E84; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUFMGR_CUR_LINE_R__VI = 0x5E79; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUFMGR_STATUS__VI = 0x5E7A; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUFMGR_SW_CONTROL__VI = 0x5E78; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUFMGR_VCE_CONTROL__VI = 0x5E98; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_1_ADDR_C__VI = 0x5E8A; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_1_ADDR_C_OFFSET__VI = 0x5E8B; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_1_ADDR_Y__VI = 0x5E88; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_1_ADDR_Y_OFFSET__VI = 0x5E89; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_1_STATUS__VI = 0x5E7C; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_1_STATUS2__VI = 0x5E7D; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_2_ADDR_C__VI = 0x5E8E; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_2_ADDR_C_OFFSET__VI = 0x5E8F; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_2_ADDR_Y__VI = 0x5E8C; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_2_ADDR_Y_OFFSET__VI = 0x5E8D; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_2_STATUS__VI = 0x5E7E; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_2_STATUS2__VI = 0x5E7F; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_3_ADDR_C__VI = 0x5E92; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_3_ADDR_C_OFFSET__VI = 0x5E93; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_3_ADDR_Y__VI = 0x5E90; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_3_ADDR_Y_OFFSET__VI = 0x5E91; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_3_STATUS__VI = 0x5E80; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_3_STATUS2__VI = 0x5E81; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_4_ADDR_C__VI = 0x5E96; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_4_ADDR_C_OFFSET__VI = 0x5E97; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_4_ADDR_Y__VI = 0x5E94; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_4_ADDR_Y_OFFSET__VI = 0x5E95; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_4_STATUS__VI = 0x5E82; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_4_STATUS2__VI = 0x5E83; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_BUF_PITCH__VI = 0x5E7B; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_HVVMID_CONTROL__VI = 0x5E99; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_TEST_DEBUG_DATA__VI = 0x5E87; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_TEST_DEBUG_INDEX__VI = 0x5E86; +constexpr unsigned int mmMCIF_WB0_MCIF_WB_URGENCY_WATERMARK__VI = 0x5E85; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_ARBITRATION_CONTROL__VI = 0x5EC4; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUFMGR_CUR_LINE_R__VI = 0x5EB9; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUFMGR_STATUS__VI = 0x5EBA; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUFMGR_SW_CONTROL__VI = 0x5EB8; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUFMGR_VCE_CONTROL__VI = 0x5ED8; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_1_ADDR_C__VI = 0x5ECA; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_1_ADDR_C_OFFSET__VI = 0x5ECB; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_1_ADDR_Y__VI = 0x5EC8; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_1_ADDR_Y_OFFSET__VI = 0x5EC9; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_1_STATUS__VI = 0x5EBC; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_1_STATUS2__VI = 0x5EBD; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_2_ADDR_C__VI = 0x5ECE; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_2_ADDR_C_OFFSET__VI = 0x5ECF; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_2_ADDR_Y__VI = 0x5ECC; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_2_ADDR_Y_OFFSET__VI = 0x5ECD; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_2_STATUS__VI = 0x5EBE; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_2_STATUS2__VI = 0x5EBF; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_3_ADDR_C__VI = 0x5ED2; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_3_ADDR_C_OFFSET__VI = 0x5ED3; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_3_ADDR_Y__VI = 0x5ED0; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_3_ADDR_Y_OFFSET__VI = 0x5ED1; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_3_STATUS__VI = 0x5EC0; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_3_STATUS2__VI = 0x5EC1; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_4_ADDR_C__VI = 0x5ED6; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_4_ADDR_C_OFFSET__VI = 0x5ED7; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_4_ADDR_Y__VI = 0x5ED4; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_4_ADDR_Y_OFFSET__VI = 0x5ED5; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_4_STATUS__VI = 0x5EC2; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_4_STATUS2__VI = 0x5EC3; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_BUF_PITCH__VI = 0x5EBB; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_HVVMID_CONTROL__VI = 0x5ED9; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_TEST_DEBUG_DATA__VI = 0x5EC7; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_TEST_DEBUG_INDEX__VI = 0x5EC6; +constexpr unsigned int mmMCIF_WB1_MCIF_WB_URGENCY_WATERMARK__VI = 0x5EC5; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_ARBITRATION_CONTROL__VI = 0x5F04; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUFMGR_CUR_LINE_R__VI = 0x5EF9; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUFMGR_STATUS__VI = 0x5EFA; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUFMGR_SW_CONTROL__VI = 0x5EF8; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUFMGR_VCE_CONTROL__VI = 0x5F18; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_1_ADDR_C__VI = 0x5F0A; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_1_ADDR_C_OFFSET__VI = 0x5F0B; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_1_ADDR_Y__VI = 0x5F08; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_1_ADDR_Y_OFFSET__VI = 0x5F09; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_1_STATUS__VI = 0x5EFC; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_1_STATUS2__VI = 0x5EFD; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_2_ADDR_C__VI = 0x5F0E; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_2_ADDR_C_OFFSET__VI = 0x5F0F; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_2_ADDR_Y__VI = 0x5F0C; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_2_ADDR_Y_OFFSET__VI = 0x5F0D; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_2_STATUS__VI = 0x5EFE; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_2_STATUS2__VI = 0x5EFF; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_3_ADDR_C__VI = 0x5F12; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_3_ADDR_C_OFFSET__VI = 0x5F13; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_3_ADDR_Y__VI = 0x5F10; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_3_ADDR_Y_OFFSET__VI = 0x5F11; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_3_STATUS__VI = 0x5F00; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_3_STATUS2__VI = 0x5F01; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_4_ADDR_C__VI = 0x5F16; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_4_ADDR_C_OFFSET__VI = 0x5F17; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_4_ADDR_Y__VI = 0x5F14; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_4_ADDR_Y_OFFSET__VI = 0x5F15; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_4_STATUS__VI = 0x5F02; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_4_STATUS2__VI = 0x5F03; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_BUF_PITCH__VI = 0x5EFB; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_HVVMID_CONTROL__VI = 0x5F19; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_TEST_DEBUG_DATA__VI = 0x5F07; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_TEST_DEBUG_INDEX__VI = 0x5F06; +constexpr unsigned int mmMCIF_WB2_MCIF_WB_URGENCY_WATERMARK__VI = 0x5F05; +constexpr unsigned int mmMCIF_WB_ARBITRATION_CONTROL__VI = 0x5E84; +constexpr unsigned int mmMCIF_WB_BUFMGR_CUR_LINE_R__VI = 0x5E79; +constexpr unsigned int mmMCIF_WB_BUFMGR_STATUS__VI = 0x5E7A; +constexpr unsigned int mmMCIF_WB_BUFMGR_SW_CONTROL__VI = 0x5E78; +constexpr unsigned int mmMCIF_WB_BUFMGR_VCE_CONTROL__VI = 0x5E98; +constexpr unsigned int mmMCIF_WB_BUF_1_ADDR_C__VI = 0x5E8A; +constexpr unsigned int mmMCIF_WB_BUF_1_ADDR_C_OFFSET__VI = 0x5E8B; +constexpr unsigned int mmMCIF_WB_BUF_1_ADDR_Y__VI = 0x5E88; +constexpr unsigned int mmMCIF_WB_BUF_1_ADDR_Y_OFFSET__VI = 0x5E89; +constexpr unsigned int mmMCIF_WB_BUF_1_STATUS__VI = 0x5E7C; +constexpr unsigned int mmMCIF_WB_BUF_1_STATUS2__VI = 0x5E7D; +constexpr unsigned int mmMCIF_WB_BUF_2_ADDR_C__VI = 0x5E8E; +constexpr unsigned int mmMCIF_WB_BUF_2_ADDR_C_OFFSET__VI = 0x5E8F; +constexpr unsigned int mmMCIF_WB_BUF_2_ADDR_Y__VI = 0x5E8C; +constexpr unsigned int mmMCIF_WB_BUF_2_ADDR_Y_OFFSET__VI = 0x5E8D; +constexpr unsigned int mmMCIF_WB_BUF_2_STATUS__VI = 0x5E7E; +constexpr unsigned int mmMCIF_WB_BUF_2_STATUS2__VI = 0x5E7F; +constexpr unsigned int mmMCIF_WB_BUF_3_ADDR_C__VI = 0x5E92; +constexpr unsigned int mmMCIF_WB_BUF_3_ADDR_C_OFFSET__VI = 0x5E93; +constexpr unsigned int mmMCIF_WB_BUF_3_ADDR_Y__VI = 0x5E90; +constexpr unsigned int mmMCIF_WB_BUF_3_ADDR_Y_OFFSET__VI = 0x5E91; +constexpr unsigned int mmMCIF_WB_BUF_3_STATUS__VI = 0x5E80; +constexpr unsigned int mmMCIF_WB_BUF_3_STATUS2__VI = 0x5E81; +constexpr unsigned int mmMCIF_WB_BUF_4_ADDR_C__VI = 0x5E96; +constexpr unsigned int mmMCIF_WB_BUF_4_ADDR_C_OFFSET__VI = 0x5E97; +constexpr unsigned int mmMCIF_WB_BUF_4_ADDR_Y__VI = 0x5E94; +constexpr unsigned int mmMCIF_WB_BUF_4_ADDR_Y_OFFSET__VI = 0x5E95; +constexpr unsigned int mmMCIF_WB_BUF_4_STATUS__VI = 0x5E82; +constexpr unsigned int mmMCIF_WB_BUF_4_STATUS2__VI = 0x5E83; +constexpr unsigned int mmMCIF_WB_BUF_PITCH__VI = 0x5E7B; +constexpr unsigned int mmMCIF_WB_HVVMID_CONTROL__VI = 0x5E99; +constexpr unsigned int mmMCIF_WB_TEST_DEBUG_DATA__VI = 0x5E87; +constexpr unsigned int mmMCIF_WB_TEST_DEBUG_INDEX__VI = 0x5E86; +constexpr unsigned int mmMCIF_WB_URGENCY_WATERMARK__VI = 0x5E85; +constexpr unsigned int mmMCIF_WRITE_COMBINE_CONTROL__VI = 0x030D; +constexpr unsigned int mmMC_ARB_ATOMIC__VI = 0x09BE; +constexpr unsigned int mmMC_ARB_GRUB__VI = 0x09C8; +constexpr unsigned int mmMC_ARB_GRUB2__VI = 0x0A01; +constexpr unsigned int mmMC_ARB_GRUB_PRIORITY1_RD__VI = 0x0DD8; +constexpr unsigned int mmMC_ARB_GRUB_PRIORITY1_WR__VI = 0x0DD9; +constexpr unsigned int mmMC_ARB_GRUB_PRIORITY2_RD__VI = 0x0DDA; +constexpr unsigned int mmMC_ARB_GRUB_PRIORITY2_WR__VI = 0x0DDB; +constexpr unsigned int mmMC_ARB_GRUB_PROMOTE__VI = 0x09CE; +constexpr unsigned int mmMC_ARB_GRUB_REALTIME_RD__VI = 0x09F9; +constexpr unsigned int mmMC_ARB_GRUB_REALTIME_WR__VI = 0x09FB; +constexpr unsigned int mmMC_ARB_PERF_CID__VI = 0x09C6; +constexpr unsigned int mmMC_ARB_SNOOP__VI = 0x09C7; +constexpr unsigned int mmMC_BIST_CMD__VI = 0x0A85; +constexpr unsigned int mmMC_BIST_CNTL__SI__CI = 0x0A05; +constexpr unsigned int mmMC_BIST_CNTL__VI = 0x0A84; +constexpr unsigned int mmMC_BIST_DAT__VI = 0x0A86; +constexpr unsigned int mmMC_BIST_DATA_WORD0__SI__CI = 0x0A0A; +constexpr unsigned int mmMC_BIST_DATA_WORD0__VI = 0x0A8A; +constexpr unsigned int mmMC_BIST_DATA_WORD1__SI__CI = 0x0A0B; +constexpr unsigned int mmMC_BIST_DATA_WORD1__VI = 0x0A8B; +constexpr unsigned int mmMC_BIST_DATA_WORD2__SI__CI = 0x0A0C; +constexpr unsigned int mmMC_BIST_DATA_WORD2__VI = 0x0A8C; +constexpr unsigned int mmMC_BIST_DATA_WORD3__SI__CI = 0x0A0D; +constexpr unsigned int mmMC_BIST_DATA_WORD3__VI = 0x0A8D; +constexpr unsigned int mmMC_BIST_DATA_WORD4__SI__CI = 0x0A0E; +constexpr unsigned int mmMC_BIST_DATA_WORD4__VI = 0x0A8E; +constexpr unsigned int mmMC_BIST_DATA_WORD5__SI__CI = 0x0A0F; +constexpr unsigned int mmMC_BIST_DATA_WORD5__VI = 0x0A8F; +constexpr unsigned int mmMC_BIST_DATA_WORD6__SI__CI = 0x0A10; +constexpr unsigned int mmMC_BIST_DATA_WORD6__VI = 0x0A90; +constexpr unsigned int mmMC_BIST_DATA_WORD7__SI__CI = 0x0A11; +constexpr unsigned int mmMC_BIST_DATA_WORD7__VI = 0x0A91; +constexpr unsigned int mmMC_BIST_MISMATCH_ADDR__SI__CI = 0x0A13; +constexpr unsigned int mmMC_BIST_MISMATCH_ADDR__VI = 0x0A93; +constexpr unsigned int mmMC_BIST_RDATA_WORD0__SI__CI = 0x0A14; +constexpr unsigned int mmMC_BIST_RDATA_WORD0__VI = 0x0A94; +constexpr unsigned int mmMC_BIST_RDATA_WORD1__SI__CI = 0x0A15; +constexpr unsigned int mmMC_BIST_RDATA_WORD1__VI = 0x0A95; +constexpr unsigned int mmMC_BIST_RDATA_WORD2__SI__CI = 0x0A16; +constexpr unsigned int mmMC_BIST_RDATA_WORD2__VI = 0x0A96; +constexpr unsigned int mmMC_BIST_RDATA_WORD3__SI__CI = 0x0A17; +constexpr unsigned int mmMC_BIST_RDATA_WORD3__VI = 0x0A97; +constexpr unsigned int mmMC_BIST_RDATA_WORD4__SI__CI = 0x0A18; +constexpr unsigned int mmMC_BIST_RDATA_WORD4__VI = 0x0A98; +constexpr unsigned int mmMC_BIST_RDATA_WORD5__SI__CI = 0x0A19; +constexpr unsigned int mmMC_BIST_RDATA_WORD5__VI = 0x0A99; +constexpr unsigned int mmMC_BIST_RDATA_WORD6__SI__CI = 0x0A1A; +constexpr unsigned int mmMC_BIST_RDATA_WORD6__VI = 0x0A9A; +constexpr unsigned int mmMC_BIST_RDATA_WORD7__SI__CI = 0x0A1B; +constexpr unsigned int mmMC_BIST_RDATA_WORD7__VI = 0x0A9B; +constexpr unsigned int mmMC_CG_DATAPORT__SI__CI = 0x0A21; +constexpr unsigned int mmMC_CG_DATAPORT__VI = 0x0A32; +constexpr unsigned int mmMC_CITF_CREDITS_ARB_RD2__VI = 0x097E; +constexpr unsigned int mmMC_DC_INTERFACE_NACK_STATUS__VI = 0x0313; +constexpr unsigned int mmMC_FUS_ARB_GARLIC_CNTL__VI = 0x0A20; +constexpr unsigned int mmMC_FUS_ARB_GARLIC_ISOC_PRI__VI = 0x0A1F; +constexpr unsigned int mmMC_FUS_ARB_GARLIC_WR_PRI__VI = 0x0A21; +constexpr unsigned int mmMC_FUS_ARB_GARLIC_WR_PRI2__VI = 0x0A22; +constexpr unsigned int mmMC_FUS_DRAM0_BANK_ADDR_MAPPING__VI = 0x0A11; +constexpr unsigned int mmMC_FUS_DRAM0_CS0_BASE__VI = 0x0A05; +constexpr unsigned int mmMC_FUS_DRAM0_CS1_BASE__VI = 0x0A07; +constexpr unsigned int mmMC_FUS_DRAM0_CS2_BASE__VI = 0x0A09; +constexpr unsigned int mmMC_FUS_DRAM0_CS3_BASE__VI = 0x0A0B; +constexpr unsigned int mmMC_FUS_DRAM0_CTL_BASE__VI = 0x0A13; +constexpr unsigned int mmMC_FUS_DRAM0_CTL_LIMIT__VI = 0x0A15; +constexpr unsigned int mmMC_FUS_DRAM1_BANK_ADDR_MAPPING__VI = 0x0A12; +constexpr unsigned int mmMC_FUS_DRAM1_CS0_BASE__VI = 0x0A06; +constexpr unsigned int mmMC_FUS_DRAM1_CS1_BASE__VI = 0x0A08; +constexpr unsigned int mmMC_FUS_DRAM1_CS2_BASE__VI = 0x0A0A; +constexpr unsigned int mmMC_FUS_DRAM1_CS3_BASE__VI = 0x0A0C; +constexpr unsigned int mmMC_FUS_DRAM1_CTL_BASE__VI = 0x0A14; +constexpr unsigned int mmMC_FUS_DRAM1_CTL_LIMIT__VI = 0x0A16; +constexpr unsigned int mmMC_FUS_DRAM_APER_BASE__VI = 0x0A1A; +constexpr unsigned int mmMC_FUS_DRAM_APER_DEF__VI = 0x0A1E; +constexpr unsigned int mmMC_FUS_DRAM_APER_TOP__VI = 0x0A1B; +constexpr unsigned int mmMC_FUS_DRAM_CTL_HIGH_01__VI = 0x0A17; +constexpr unsigned int mmMC_FUS_DRAM_CTL_HIGH_23__VI = 0x0A18; +constexpr unsigned int mmMC_FUS_DRAM_MODE__VI = 0x0A19; +constexpr unsigned int mmMC_GRUB_FEATURES__VI = 0x0A36; +constexpr unsigned int mmMC_GRUB_PERFCOUNTER0_CFG__VI = 0x07E6; +constexpr unsigned int mmMC_GRUB_PERFCOUNTER1_CFG__VI = 0x07E7; +constexpr unsigned int mmMC_GRUB_PERFCOUNTER_HI__VI = 0x07E5; +constexpr unsigned int mmMC_GRUB_PERFCOUNTER_LO__VI = 0x07E4; +constexpr unsigned int mmMC_GRUB_PERFCOUNTER_RSLT_CNTL__VI = 0x07E8; +constexpr unsigned int mmMC_GRUB_POST_PROBE_DELAY__VI = 0x0A34; +constexpr unsigned int mmMC_GRUB_PROBE_CREDITS__VI = 0x0A35; +constexpr unsigned int mmMC_GRUB_PROBE_MAP__VI = 0x0A33; +constexpr unsigned int mmMC_GRUB_TCB_DATA_HI__VI = 0x0A3A; +constexpr unsigned int mmMC_GRUB_TCB_DATA_LO__VI = 0x0A39; +constexpr unsigned int mmMC_GRUB_TCB_INDEX__VI = 0x0A38; +constexpr unsigned int mmMC_GRUB_TX_CREDITS__VI = 0x0A37; +constexpr unsigned int mmMC_HUB_MISC_ATOMIC_IDLE_STATUS__VI = 0x084F; +constexpr unsigned int mmMC_HUB_RDREQ_ACPG__VI = 0x0881; +constexpr unsigned int mmMC_HUB_RDREQ_ACPO__VI = 0x0882; +constexpr unsigned int mmMC_HUB_RDREQ_BYPASS_GBL0__VI = 0x084C; +constexpr unsigned int mmMC_HUB_RDREQ_DMIF__VI = 0x0862; +constexpr unsigned int mmMC_HUB_RDREQ_HDP__VI = 0x085A; +constexpr unsigned int mmMC_HUB_RDREQ_ISP_CCPU__VI = 0x0DE2; +constexpr unsigned int mmMC_HUB_RDREQ_ISP_MPM__VI = 0x0DE1; +constexpr unsigned int mmMC_HUB_RDREQ_ISP_SPM__VI = 0x0DE0; +constexpr unsigned int mmMC_HUB_RDREQ_MCDS__VI = 0x0DE7; +constexpr unsigned int mmMC_HUB_RDREQ_MCDT__VI = 0x0DE8; +constexpr unsigned int mmMC_HUB_RDREQ_MCDU__VI = 0x0DE9; +constexpr unsigned int mmMC_HUB_RDREQ_MCDV__VI = 0x0DEA; +constexpr unsigned int mmMC_HUB_RDREQ_MCIF__VI = 0x0863; +constexpr unsigned int mmMC_HUB_RDREQ_RLC__VI = 0x085C; +constexpr unsigned int mmMC_HUB_RDREQ_SAMMSP__VI = 0x0883; +constexpr unsigned int mmMC_HUB_RDREQ_SDMA0__VI = 0x0859; +constexpr unsigned int mmMC_HUB_RDREQ_SDMA1__VI = 0x085B; +constexpr unsigned int mmMC_HUB_RDREQ_SEM__VI = 0x085D; +constexpr unsigned int mmMC_HUB_RDREQ_TLS__VI = 0x0861; +constexpr unsigned int mmMC_HUB_RDREQ_UMC__VI = 0x085F; +constexpr unsigned int mmMC_HUB_RDREQ_UVD__VI = 0x0860; +constexpr unsigned int mmMC_HUB_RDREQ_VCE0__VI = 0x085E; +constexpr unsigned int mmMC_HUB_RDREQ_VCE1__VI = 0x0DFC; +constexpr unsigned int mmMC_HUB_RDREQ_VCEU0__VI = 0x0865; +constexpr unsigned int mmMC_HUB_RDREQ_VCEU1__VI = 0x0DFD; +constexpr unsigned int mmMC_HUB_RDREQ_VMC__VI = 0x0864; +constexpr unsigned int mmMC_HUB_RDREQ_VP8__VI = 0x0884; +constexpr unsigned int mmMC_HUB_RDREQ_VP8U__VI = 0x0885; +constexpr unsigned int mmMC_HUB_RDREQ_XDMAM__VI = 0x0880; +constexpr unsigned int mmMC_HUB_WDP_ACPG__VI = 0x0885; +constexpr unsigned int mmMC_HUB_WDP_ACPO__VI = 0x0886; +constexpr unsigned int mmMC_HUB_WDP_BP2__VI = 0x0DFB; +constexpr unsigned int mmMC_HUB_WDP_BYPASS_GBL0__VI = 0x084A; +constexpr unsigned int mmMC_HUB_WDP_BYPASS_GBL1__VI = 0x084B; +constexpr unsigned int mmMC_HUB_WDP_CREDITS2__VI = 0x0840; +constexpr unsigned int mmMC_HUB_WDP_CREDITS3__VI = 0x0843; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDS__VI = 0x0DF7; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDT__VI = 0x0DF8; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDU__VI = 0x0DF9; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDV__VI = 0x0DFA; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDW__VI = 0x0DF3; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDX__VI = 0x0DF4; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDY__VI = 0x0DF5; +constexpr unsigned int mmMC_HUB_WDP_CREDITS_MCDZ__VI = 0x0DF6; +constexpr unsigned int mmMC_HUB_WDP_HDP__VI = 0x0877; +constexpr unsigned int mmMC_HUB_WDP_IH__VI = 0x0870; +constexpr unsigned int mmMC_HUB_WDP_ISP_CCPU__VI = 0x0DE6; +constexpr unsigned int mmMC_HUB_WDP_ISP_MPM__VI = 0x0DE5; +constexpr unsigned int mmMC_HUB_WDP_ISP_MPS__VI = 0x0DE4; +constexpr unsigned int mmMC_HUB_WDP_ISP_SPM__VI = 0x0DE3; +constexpr unsigned int mmMC_HUB_WDP_MCDS__VI = 0x0DEB; +constexpr unsigned int mmMC_HUB_WDP_MCDT__VI = 0x0DEC; +constexpr unsigned int mmMC_HUB_WDP_MCDU__VI = 0x0DED; +constexpr unsigned int mmMC_HUB_WDP_MCDV__VI = 0x0DEE; +constexpr unsigned int mmMC_HUB_WDP_MCDW__VI = 0x0866; +constexpr unsigned int mmMC_HUB_WDP_MCDX__VI = 0x0867; +constexpr unsigned int mmMC_HUB_WDP_MCDY__VI = 0x0868; +constexpr unsigned int mmMC_HUB_WDP_MCDZ__VI = 0x0869; +constexpr unsigned int mmMC_HUB_WDP_MCIF__VI = 0x086D; +constexpr unsigned int mmMC_HUB_WDP_RLC__VI = 0x0871; +constexpr unsigned int mmMC_HUB_WDP_SAMMSP__VI = 0x0887; +constexpr unsigned int mmMC_HUB_WDP_SDMA0__VI = 0x0878; +constexpr unsigned int mmMC_HUB_WDP_SDMA1__VI = 0x086B; +constexpr unsigned int mmMC_HUB_WDP_SEM__VI = 0x0872; +constexpr unsigned int mmMC_HUB_WDP_SH0__VI = 0x086C; +constexpr unsigned int mmMC_HUB_WDP_SH1__VI = 0x0874; +constexpr unsigned int mmMC_HUB_WDP_SIP__VI = 0x086A; +constexpr unsigned int mmMC_HUB_WDP_SMU__VI = 0x0873; +constexpr unsigned int mmMC_HUB_WDP_UMC__VI = 0x0875; +constexpr unsigned int mmMC_HUB_WDP_UVD__VI = 0x0876; +constexpr unsigned int mmMC_HUB_WDP_VCE0__VI = 0x086E; +constexpr unsigned int mmMC_HUB_WDP_VCE1__VI = 0x0DFE; +constexpr unsigned int mmMC_HUB_WDP_VCEU0__VI = 0x087D; +constexpr unsigned int mmMC_HUB_WDP_VCEU1__VI = 0x0DFF; +constexpr unsigned int mmMC_HUB_WDP_VIN0__VI = 0x0850; +constexpr unsigned int mmMC_HUB_WDP_VP8__VI = 0x0888; +constexpr unsigned int mmMC_HUB_WDP_VP8U__VI = 0x088A; +constexpr unsigned int mmMC_HUB_WDP_XDMA__VI = 0x087F; +constexpr unsigned int mmMC_HUB_WDP_XDMAM__VI = 0x087E; +constexpr unsigned int mmMC_HUB_WDP_XDP__VI = 0x086F; +constexpr unsigned int mmMC_HUB_WRRET_MCDS__VI = 0x0DEF; +constexpr unsigned int mmMC_HUB_WRRET_MCDT__VI = 0x0DF0; +constexpr unsigned int mmMC_HUB_WRRET_MCDU__VI = 0x0DF1; +constexpr unsigned int mmMC_HUB_WRRET_MCDV__VI = 0x0DF2; +constexpr unsigned int mmMC_HUB_WRRET_MCDW__VI = 0x0879; +constexpr unsigned int mmMC_HUB_WRRET_MCDX__VI = 0x087A; +constexpr unsigned int mmMC_HUB_WRRET_MCDY__VI = 0x087B; +constexpr unsigned int mmMC_HUB_WRRET_MCDZ__VI = 0x087C; +constexpr unsigned int mmMC_PMG_CFG__SI__CI = 0x0A84; +constexpr unsigned int mmMC_PMG_CFG__VI = 0x0A54; +constexpr unsigned int mmMC_PMG_CMD_EMRS__SI__CI = 0x0A83; +constexpr unsigned int mmMC_PMG_CMD_EMRS__VI = 0x0A4A; +constexpr unsigned int mmMC_PMG_CMD_MRS__SI__CI = 0x0AAB; +constexpr unsigned int mmMC_PMG_CMD_MRS__VI = 0x0A4C; +constexpr unsigned int mmMC_PMG_CMD_MRS1__SI__CI = 0x0AD1; +constexpr unsigned int mmMC_PMG_CMD_MRS1__VI = 0x0A4E; +constexpr unsigned int mmMC_PMG_CMD_MRS2__SI__CI = 0x0AD7; +constexpr unsigned int mmMC_PMG_CMD_MRS2__VI = 0x0A50; +constexpr unsigned int mmMC_RPB_TCI_CNTL__VI = 0x095C; +constexpr unsigned int mmMC_RPB_TCI_CNTL2__VI = 0x095D; +constexpr unsigned int mmMC_SEQ_CAS_TIMING__SI__CI = 0x0A29; +constexpr unsigned int mmMC_SEQ_CAS_TIMING__VI = 0x0A2B; +constexpr unsigned int mmMC_SEQ_CAS_TIMING_LP__SI__CI = 0x0A9C; +constexpr unsigned int mmMC_SEQ_CAS_TIMING_LP__VI = 0x0A2C; +constexpr unsigned int mmMC_SEQ_CG__SI__CI = 0x0A9A; +constexpr unsigned int mmMC_SEQ_CG__VI = 0x0A7B; +constexpr unsigned int mmMC_SEQ_CMD__SI__CI = 0x0A31; +constexpr unsigned int mmMC_SEQ_CMD__VI = 0x0A47; +constexpr unsigned int mmMC_SEQ_CNTL__SI__CI = 0x0A25; +constexpr unsigned int mmMC_SEQ_CNTL__VI = 0x0A24; +constexpr unsigned int mmMC_SEQ_CNTL_2__SI__CI = 0x0AD4; +constexpr unsigned int mmMC_SEQ_CNTL_2__VI = 0x0A25; +constexpr unsigned int mmMC_SEQ_CNTL_3__VI = 0x0A26; +constexpr unsigned int mmMC_SEQ_DRAM__SI__CI = 0x0A26; +constexpr unsigned int mmMC_SEQ_DRAM__VI = 0x0A27; +constexpr unsigned int mmMC_SEQ_DRAM_2__SI__CI = 0x0A27; +constexpr unsigned int mmMC_SEQ_DRAM_2__VI = 0x0A28; +constexpr unsigned int mmMC_SEQ_FIFO_CTL__SI__CI = 0x0A57; +constexpr unsigned int mmMC_SEQ_FIFO_CTL__VI = 0x0A5D; +constexpr unsigned int mmMC_SEQ_IO_DEBUG_DATA__SI__CI = 0x0A92; +constexpr unsigned int mmMC_SEQ_IO_DEBUG_DATA__VI = 0x0ABD; +constexpr unsigned int mmMC_SEQ_IO_DEBUG_INDEX__SI__CI = 0x0A91; +constexpr unsigned int mmMC_SEQ_IO_DEBUG_INDEX__VI = 0x0ABC; +constexpr unsigned int mmMC_SEQ_IO_RESERVE__VI = 0x0A61; +constexpr unsigned int mmMC_SEQ_MISC0__SI__CI = 0x0A80; +constexpr unsigned int mmMC_SEQ_MISC0__VI = 0x0A71; +constexpr unsigned int mmMC_SEQ_MISC1__SI__CI = 0x0A81; +constexpr unsigned int mmMC_SEQ_MISC1__VI = 0x0A72; +constexpr unsigned int mmMC_SEQ_MISC3__SI__CI = 0x0A8B; +constexpr unsigned int mmMC_SEQ_MISC3__VI = 0x0A74; +constexpr unsigned int mmMC_SEQ_MISC4__SI__CI = 0x0A8C; +constexpr unsigned int mmMC_SEQ_MISC4__VI = 0x0A75; +constexpr unsigned int mmMC_SEQ_MISC5__SI__CI = 0x0A95; +constexpr unsigned int mmMC_SEQ_MISC5__VI = 0x0A76; +constexpr unsigned int mmMC_SEQ_MISC6__SI__CI = 0x0A96; +constexpr unsigned int mmMC_SEQ_MISC6__VI = 0x0A77; +constexpr unsigned int mmMC_SEQ_MISC7__SI__CI = 0x0A99; +constexpr unsigned int mmMC_SEQ_MISC7__VI = 0x0A78; +constexpr unsigned int mmMC_SEQ_MISC8__SI__CI = 0x0A5F; +constexpr unsigned int mmMC_SEQ_MISC8__VI = 0x0A79; +constexpr unsigned int mmMC_SEQ_MISC9__SI__CI = 0x0AE7; +constexpr unsigned int mmMC_SEQ_MISC9__VI = 0x0A7A; +constexpr unsigned int mmMC_SEQ_MISC_TIMING__SI__CI = 0x0A2A; +constexpr unsigned int mmMC_SEQ_MISC_TIMING__VI = 0x0A2D; +constexpr unsigned int mmMC_SEQ_MISC_TIMING2__SI__CI = 0x0A2B; +constexpr unsigned int mmMC_SEQ_MISC_TIMING2__VI = 0x0A2F; +constexpr unsigned int mmMC_SEQ_MISC_TIMING2_LP__SI__CI = 0x0A9E; +constexpr unsigned int mmMC_SEQ_MISC_TIMING2_LP__VI = 0x0A30; +constexpr unsigned int mmMC_SEQ_MISC_TIMING_LP__SI__CI = 0x0A9D; +constexpr unsigned int mmMC_SEQ_MISC_TIMING_LP__VI = 0x0A2E; +constexpr unsigned int mmMC_SEQ_PMG_TIMING__SI__CI = 0x0A2C; +constexpr unsigned int mmMC_SEQ_PMG_TIMING__VI = 0x0A31; +constexpr unsigned int mmMC_SEQ_PMG_TIMING_LP__SI__CI = 0x0AD3; +constexpr unsigned int mmMC_SEQ_PMG_TIMING_LP__VI = 0x0A32; +constexpr unsigned int mmMC_SEQ_RAS_TIMING__SI__CI = 0x0A28; +constexpr unsigned int mmMC_SEQ_RAS_TIMING__VI = 0x0A29; +constexpr unsigned int mmMC_SEQ_RAS_TIMING_LP__SI__CI = 0x0A9B; +constexpr unsigned int mmMC_SEQ_RAS_TIMING_LP__VI = 0x0A2A; +constexpr unsigned int mmMC_SEQ_RD_CTL_D0__SI__CI = 0x0A2D; +constexpr unsigned int mmMC_SEQ_RD_CTL_D0__VI = 0x0A33; +constexpr unsigned int mmMC_SEQ_RD_CTL_D0_LP__SI__CI = 0x0AC7; +constexpr unsigned int mmMC_SEQ_RD_CTL_D0_LP__VI = 0x0A34; +constexpr unsigned int mmMC_SEQ_RD_CTL_D1__SI__CI = 0x0A2E; +constexpr unsigned int mmMC_SEQ_RD_CTL_D1__VI = 0x0A35; +constexpr unsigned int mmMC_SEQ_RD_CTL_D1_LP__SI__CI = 0x0AC8; +constexpr unsigned int mmMC_SEQ_RD_CTL_D1_LP__VI = 0x0A36; +constexpr unsigned int mmMC_SEQ_RESERVE_0_S__SI__CI = 0x0A1E; +constexpr unsigned int mmMC_SEQ_RESERVE_0_S__VI = 0x0A07; +constexpr unsigned int mmMC_SEQ_RESERVE_1_S__SI__CI = 0x0A1F; +constexpr unsigned int mmMC_SEQ_RESERVE_1_S__VI = 0x0A08; +constexpr unsigned int mmMC_SEQ_RESERVE_M__SI__CI = 0x0A82; +constexpr unsigned int mmMC_SEQ_RESERVE_M__VI = 0x0A60; +constexpr unsigned int mmMC_SEQ_SREG_READ__VI = 0x0A7F; +constexpr unsigned int mmMC_SEQ_SREG_STATUS__VI = 0x0A80; +constexpr unsigned int mmMC_SEQ_STATUS_M__SI__CI = 0x0A7D; +constexpr unsigned int mmMC_SEQ_STATUS_M__VI = 0x0A5E; +constexpr unsigned int mmMC_SEQ_STATUS_S__SI__CI = 0x0A20; +constexpr unsigned int mmMC_SEQ_STATUS_S__VI = 0x0A05; +constexpr unsigned int mmMC_SEQ_SUP_CNTL__SI__CI = 0x0A32; +constexpr unsigned int mmMC_SEQ_SUP_CNTL__VI = 0x0A63; +constexpr unsigned int mmMC_SEQ_SUP_DEC_STAT__SI__CI = 0x0A88; +constexpr unsigned int mmMC_SEQ_SUP_DEC_STAT__VI = 0x0A6A; +constexpr unsigned int mmMC_SEQ_SUP_GP0_STAT__SI__CI = 0x0A8F; +constexpr unsigned int mmMC_SEQ_SUP_GP0_STAT__VI = 0x0A65; +constexpr unsigned int mmMC_SEQ_SUP_GP1_STAT__SI__CI = 0x0A90; +constexpr unsigned int mmMC_SEQ_SUP_GP1_STAT__VI = 0x0A66; +constexpr unsigned int mmMC_SEQ_SUP_GP2_STAT__SI__CI = 0x0A85; +constexpr unsigned int mmMC_SEQ_SUP_GP2_STAT__VI = 0x0A67; +constexpr unsigned int mmMC_SEQ_SUP_GP3_STAT__SI__CI = 0x0A86; +constexpr unsigned int mmMC_SEQ_SUP_GP3_STAT__VI = 0x0A68; +constexpr unsigned int mmMC_SEQ_SUP_IR_STAT__SI__CI = 0x0A87; +constexpr unsigned int mmMC_SEQ_SUP_IR_STAT__VI = 0x0A69; +constexpr unsigned int mmMC_SEQ_SUP_PGM__SI__CI = 0x0A33; +constexpr unsigned int mmMC_SEQ_SUP_PGM__VI = 0x0A64; +constexpr unsigned int mmMC_SEQ_SUP_PGM_STAT__SI__CI = 0x0A89; +constexpr unsigned int mmMC_SEQ_SUP_PGM_STAT__VI = 0x0A6B; +constexpr unsigned int mmMC_SEQ_SUP_R_PGM__SI__CI = 0x0A8A; +constexpr unsigned int mmMC_SEQ_SUP_R_PGM__VI = 0x0A6C; +constexpr unsigned int mmMC_SEQ_TIMER_RD__SI__CI = 0x0ACA; +constexpr unsigned int mmMC_SEQ_TIMER_RD__VI = 0x0A7D; +constexpr unsigned int mmMC_SEQ_TIMER_WR__SI__CI = 0x0AC9; +constexpr unsigned int mmMC_SEQ_TIMER_WR__VI = 0x0A7C; +constexpr unsigned int mmMC_SEQ_TRAIN_CAPTURE__SI__CI = 0x0A3E; +constexpr unsigned int mmMC_SEQ_TRAIN_CAPTURE__VI = 0x0A5B; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_CLEAR__SI__CI = 0x0A3F; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_CLEAR__VI = 0x0A5C; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_CNTL__SI__CI = 0x0A3A; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_CNTL__VI = 0x0A57; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_EDGE__SI__CI = 0x0A3C; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_EDGE__VI = 0x0A58; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_MASK__SI__CI = 0x0A3D; +constexpr unsigned int mmMC_SEQ_TRAIN_WAKEUP_MASK__VI = 0x0A59; +constexpr unsigned int mmMC_SEQ_WR_CTL_D0__SI__CI = 0x0A2F; +constexpr unsigned int mmMC_SEQ_WR_CTL_D0__VI = 0x0A3B; +constexpr unsigned int mmMC_SEQ_WR_CTL_D0_LP__SI__CI = 0x0A9F; +constexpr unsigned int mmMC_SEQ_WR_CTL_D0_LP__VI = 0x0A3C; +constexpr unsigned int mmMC_SEQ_WR_CTL_D1__SI__CI = 0x0A30; +constexpr unsigned int mmMC_SEQ_WR_CTL_D1__VI = 0x0A3D; +constexpr unsigned int mmMC_SEQ_WR_CTL_D1_LP__SI__CI = 0x0AA0; +constexpr unsigned int mmMC_SEQ_WR_CTL_D1_LP__VI = 0x0A3E; +constexpr unsigned int mmMC_SHARED_ACTIVE_FCN_ID__VI = 0x081F; +constexpr unsigned int mmMC_SHARED_CHREMAP2__VI = 0x081C; +constexpr unsigned int mmMC_SHARED_VF_ENABLE__VI = 0x081D; +constexpr unsigned int mmMC_SHARED_VIRT_RESET_REQ__VI = 0x081E; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF0__VI = 0xF980; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF1__VI = 0xF981; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF10__VI = 0xF98A; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF11__VI = 0xF98B; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF12__VI = 0xF98C; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF13__VI = 0xF98D; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF14__VI = 0xF98E; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF15__VI = 0xF98F; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF2__VI = 0xF982; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF3__VI = 0xF983; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF4__VI = 0xF984; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF5__VI = 0xF985; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF6__VI = 0xF986; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF7__VI = 0xF987; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF8__VI = 0xF988; +constexpr unsigned int mmMC_VM_FB_SIZE_OFFSET_VF9__VI = 0xF989; +constexpr unsigned int mmMC_VM_MARC_BASE_HI_0__VI = 0xF999; +constexpr unsigned int mmMC_VM_MARC_BASE_HI_1__VI = 0xF99F; +constexpr unsigned int mmMC_VM_MARC_BASE_HI_2__VI = 0xF9A5; +constexpr unsigned int mmMC_VM_MARC_BASE_HI_3__VI = 0xF9AB; +constexpr unsigned int mmMC_VM_MARC_BASE_LO_0__VI = 0xF998; +constexpr unsigned int mmMC_VM_MARC_BASE_LO_1__VI = 0xF99E; +constexpr unsigned int mmMC_VM_MARC_BASE_LO_2__VI = 0xF9A4; +constexpr unsigned int mmMC_VM_MARC_BASE_LO_3__VI = 0xF9AA; +constexpr unsigned int mmMC_VM_MARC_CNTL__VI = 0xF9B0; +constexpr unsigned int mmMC_VM_MARC_LEN_HI_0__VI = 0xF99D; +constexpr unsigned int mmMC_VM_MARC_LEN_HI_1__VI = 0xF9A3; +constexpr unsigned int mmMC_VM_MARC_LEN_HI_2__VI = 0xF9A9; +constexpr unsigned int mmMC_VM_MARC_LEN_HI_3__VI = 0xF9AF; +constexpr unsigned int mmMC_VM_MARC_LEN_LO_0__VI = 0xF99C; +constexpr unsigned int mmMC_VM_MARC_LEN_LO_1__VI = 0xF9A2; +constexpr unsigned int mmMC_VM_MARC_LEN_LO_2__VI = 0xF9A8; +constexpr unsigned int mmMC_VM_MARC_LEN_LO_3__VI = 0xF9AE; +constexpr unsigned int mmMC_VM_MARC_RELOC_HI_0__VI = 0xF99B; +constexpr unsigned int mmMC_VM_MARC_RELOC_HI_1__VI = 0xF9A1; +constexpr unsigned int mmMC_VM_MARC_RELOC_HI_2__VI = 0xF9A7; +constexpr unsigned int mmMC_VM_MARC_RELOC_HI_3__VI = 0xF9AD; +constexpr unsigned int mmMC_VM_MARC_RELOC_LO_0__VI = 0xF99A; +constexpr unsigned int mmMC_VM_MARC_RELOC_LO_1__VI = 0xF9A0; +constexpr unsigned int mmMC_VM_MARC_RELOC_LO_2__VI = 0xF9A6; +constexpr unsigned int mmMC_VM_MARC_RELOC_LO_3__VI = 0xF9AC; +constexpr unsigned int mmMC_VM_MB_L1_TLB1_DEBUG__VI = 0x0892; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL0__VI = 0xF9B1; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL1__VI = 0xF9B4; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL2__VI = 0xF9B7; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL3__VI = 0xF9BA; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL4__VI = 0xF9BD; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL5__VI = 0xF9C0; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL6__VI = 0xF9C3; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL7__VI = 0xF9C6; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_CNTL8__VI = 0xF9C9; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR0__VI = 0xF9B3; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR1__VI = 0xF9B6; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR2__VI = 0xF9B9; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR3__VI = 0xF9BC; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR4__VI = 0xF9BF; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR5__VI = 0xF9C2; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR6__VI = 0xF9C5; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR7__VI = 0xF9C8; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_END_ADDR8__VI = 0xF9CB; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_PROTECTION_FAULT_ADDR__VI = 0xF9CD; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_PROTECTION_FAULT_STATUS__VI = 0xF9CC; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR0__VI = 0xF9B2; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR1__VI = 0xF9B5; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR2__VI = 0xF9B8; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR3__VI = 0xF9BB; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR4__VI = 0xF9BE; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR5__VI = 0xF9C1; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR6__VI = 0xF9C4; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR7__VI = 0xF9C7; +constexpr unsigned int mmMC_VM_MB_L1_TLS0_START_ADDR8__VI = 0xF9CA; +constexpr unsigned int mmMC_VM_NB_LOWER_TOP_OF_DRAM2__VI = 0xF995; +constexpr unsigned int mmMC_VM_NB_MMIOBASE__VI = 0xF990; +constexpr unsigned int mmMC_VM_NB_MMIOLIMIT__VI = 0xF991; +constexpr unsigned int mmMC_VM_NB_PCI_ARB__VI = 0xF993; +constexpr unsigned int mmMC_VM_NB_PCI_CTRL__VI = 0xF992; +constexpr unsigned int mmMC_VM_NB_TOP_OF_DRAM3__VI = 0xF997; +constexpr unsigned int mmMC_VM_NB_TOP_OF_DRAM_SLOT1__VI = 0xF994; +constexpr unsigned int mmMC_VM_NB_UPPER_TOP_OF_DRAM2__VI = 0xF996; +constexpr unsigned int mmMC_XBAR_FIFO_MON_CNTL0__VI = 0x0C8F; +constexpr unsigned int mmMC_XBAR_FIFO_MON_CNTL1__VI = 0x0C90; +constexpr unsigned int mmMC_XBAR_FIFO_MON_CNTL2__VI = 0x0C91; +constexpr unsigned int mmMC_XBAR_FIFO_MON_MAX_THSH__VI = 0x0C96; +constexpr unsigned int mmMC_XBAR_FIFO_MON_RSLT0__VI = 0x0C92; +constexpr unsigned int mmMC_XBAR_FIFO_MON_RSLT1__VI = 0x0C93; +constexpr unsigned int mmMC_XBAR_FIFO_MON_RSLT2__VI = 0x0C94; +constexpr unsigned int mmMC_XBAR_FIFO_MON_RSLT3__VI = 0x0C95; +constexpr unsigned int mmMICROSECOND_TIME_BASE_DIV__VI = 0x013B; +constexpr unsigned int mmMILLISECOND_TIME_BASE_DIV__VI = 0x0130; +constexpr unsigned int mmMP_FPS_CNT__VI = 0x0235; +constexpr unsigned int mmMVP_AFR_FLIP_FIFO_CNTL__VI = 0x1AE1; +constexpr unsigned int mmMVP_AFR_FLIP_MODE__VI = 0x1AE0; +constexpr unsigned int mmMVP_BLACK_KEYER__VI = 0x02B2; +constexpr unsigned int mmMVP_CONTROL1__VI = 0x02AC; +constexpr unsigned int mmMVP_CONTROL2__VI = 0x02AD; +constexpr unsigned int mmMVP_CONTROL3__VI = 0x02B6; +constexpr unsigned int mmMVP_CRC_CNTL__VI = 0x02B3; +constexpr unsigned int mmMVP_CRC_RESULT_BLUE_GREEN__VI = 0x02B4; +constexpr unsigned int mmMVP_CRC_RESULT_RED__VI = 0x02B5; +constexpr unsigned int mmMVP_DEBUG__VI = 0x02BB; +constexpr unsigned int mmMVP_FIFO_CONTROL__VI = 0x02AE; +constexpr unsigned int mmMVP_FIFO_STATUS__VI = 0x02AF; +constexpr unsigned int mmMVP_FLIP_LINE_NUM_INSERT__VI = 0x1AE2; +constexpr unsigned int mmMVP_INBAND_CNTL_CAP__VI = 0x02B1; +constexpr unsigned int mmMVP_RECEIVE_CNT_CNTL1__VI = 0x02B7; +constexpr unsigned int mmMVP_RECEIVE_CNT_CNTL2__VI = 0x02B8; +constexpr unsigned int mmMVP_SLAVE_STATUS__VI = 0x02B0; +constexpr unsigned int mmMVP_TEST_DEBUG_DATA__VI = 0x02BA; +constexpr unsigned int mmMVP_TEST_DEBUG_INDEX__VI = 0x02B9; +constexpr unsigned int mmOUTPUT_CSC_C11_C12__VI = 0x1A3D; +constexpr unsigned int mmOUTPUT_CSC_C11_C12_A__VI = 0x46B7; +constexpr unsigned int mmOUTPUT_CSC_C11_C12_B__VI = 0x46BD; +constexpr unsigned int mmOUTPUT_CSC_C13_C14__VI = 0x1A3E; +constexpr unsigned int mmOUTPUT_CSC_C13_C14_A__VI = 0x46B8; +constexpr unsigned int mmOUTPUT_CSC_C13_C14_B__VI = 0x46BE; +constexpr unsigned int mmOUTPUT_CSC_C21_C22__VI = 0x1A3F; +constexpr unsigned int mmOUTPUT_CSC_C21_C22_A__VI = 0x46B9; +constexpr unsigned int mmOUTPUT_CSC_C21_C22_B__VI = 0x46BF; +constexpr unsigned int mmOUTPUT_CSC_C23_C24__VI = 0x1A40; +constexpr unsigned int mmOUTPUT_CSC_C23_C24_A__VI = 0x46BA; +constexpr unsigned int mmOUTPUT_CSC_C23_C24_B__VI = 0x46C0; +constexpr unsigned int mmOUTPUT_CSC_C31_C32__VI = 0x1A41; +constexpr unsigned int mmOUTPUT_CSC_C31_C32_A__VI = 0x46BB; +constexpr unsigned int mmOUTPUT_CSC_C31_C32_B__VI = 0x46C1; +constexpr unsigned int mmOUTPUT_CSC_C33_C34__VI = 0x1A42; +constexpr unsigned int mmOUTPUT_CSC_C33_C34_A__VI = 0x46BC; +constexpr unsigned int mmOUTPUT_CSC_C33_C34_B__VI = 0x46C2; +constexpr unsigned int mmOUTPUT_CSC_CONTROL__VI = 0x1A3C; +constexpr unsigned int mmOUT_CLAMP_CONTROL_B_CB__VI = 0x1A9D; +constexpr unsigned int mmOUT_CLAMP_CONTROL_G_Y__VI = 0x1A9C; +constexpr unsigned int mmOUT_CLAMP_CONTROL_R_CR__VI = 0x1A52; +constexpr unsigned int mmOUT_ROUND_CONTROL__VI = 0x1A51; +constexpr unsigned int mmOVL_SECONDARY_SURFACE_ADDRESS__VI = 0x1A92; +constexpr unsigned int mmOVL_SECONDARY_SURFACE_ADDRESS_HIGH__VI = 0x1A94; +constexpr unsigned int mmOVL_STEREOSYNC_FLIP__VI = 0x1A93; +constexpr unsigned int mmPCIE_EFUSE__VI = 0x0FC0; +constexpr unsigned int mmPCIE_EFUSE2__VI = 0x0FC1; +constexpr unsigned int mmPCIE_EFUSE3__VI = 0x0FC2; +constexpr unsigned int mmPCIE_EFUSE4__VI = 0x0FC3; +constexpr unsigned int mmPCIE_EFUSE5__VI = 0x0FC4; +constexpr unsigned int mmPCIE_EFUSE6__VI = 0x0FC5; +constexpr unsigned int mmPCIE_EFUSE7__VI = 0x0FC6; +constexpr unsigned int mmPERFCOUNTER_CNTL__VI = 0x0170; +constexpr unsigned int mmPERFCOUNTER_STATE__VI = 0x0171; +constexpr unsigned int mmPERFMON_CNTL__VI = 0x0173; +constexpr unsigned int mmPERFMON_CNTL2__VI = 0x017A; +constexpr unsigned int mmPERFMON_CVALUE_INT_MISC__VI = 0x0172; +constexpr unsigned int mmPERFMON_CVALUE_LOW__VI = 0x0174; +constexpr unsigned int mmPERFMON_HI__VI = 0x0175; +constexpr unsigned int mmPERFMON_LOW__VI = 0x0176; +constexpr unsigned int mmPERFMON_TEST_DEBUG_DATA__VI = 0x0178; +constexpr unsigned int mmPERFMON_TEST_DEBUG_INDEX__VI = 0x0177; +constexpr unsigned int mmPHY_AUX_CNTL__VI = 0x4897; +constexpr unsigned int mmPIPE0_ARBITRATION_CONTROL3__VI = 0x02FA; +constexpr unsigned int mmPIPE0_DMIF_BUFFER_CONTROL__VI = 0x0321; +constexpr unsigned int mmPIPE0_MAX_REQUESTS__VI = 0x0305; +constexpr unsigned int mmPIPE0_PG_CONFIG__VI = 0x02C0; +constexpr unsigned int mmPIPE0_PG_ENABLE__VI = 0x02C1; +constexpr unsigned int mmPIPE0_PG_STATUS__VI = 0x02C2; +constexpr unsigned int mmPIPE1_ARBITRATION_CONTROL3__VI = 0x02FB; +constexpr unsigned int mmPIPE1_DMIF_BUFFER_CONTROL__VI = 0x0322; +constexpr unsigned int mmPIPE1_MAX_REQUESTS__VI = 0x0306; +constexpr unsigned int mmPIPE1_PG_CONFIG__VI = 0x02C3; +constexpr unsigned int mmPIPE1_PG_ENABLE__VI = 0x02C4; +constexpr unsigned int mmPIPE1_PG_STATUS__VI = 0x02C5; +constexpr unsigned int mmPIPE2_ARBITRATION_CONTROL3__VI = 0x02FC; +constexpr unsigned int mmPIPE2_DMIF_BUFFER_CONTROL__VI = 0x0323; +constexpr unsigned int mmPIPE2_MAX_REQUESTS__VI = 0x0307; +constexpr unsigned int mmPIPE2_PG_CONFIG__VI = 0x02C6; +constexpr unsigned int mmPIPE2_PG_ENABLE__VI = 0x02C7; +constexpr unsigned int mmPIPE2_PG_STATUS__VI = 0x02C8; +constexpr unsigned int mmPIPE3_ARBITRATION_CONTROL3__VI = 0x02FD; +constexpr unsigned int mmPIPE3_DMIF_BUFFER_CONTROL__VI = 0x0324; +constexpr unsigned int mmPIPE3_MAX_REQUESTS__VI = 0x0308; +constexpr unsigned int mmPIPE3_PG_CONFIG__VI = 0x02C9; +constexpr unsigned int mmPIPE3_PG_ENABLE__VI = 0x02CA; +constexpr unsigned int mmPIPE3_PG_STATUS__VI = 0x02CB; +constexpr unsigned int mmPIPE4_ARBITRATION_CONTROL3__VI = 0x02FE; +constexpr unsigned int mmPIPE4_DMIF_BUFFER_CONTROL__VI = 0x0325; +constexpr unsigned int mmPIPE4_MAX_REQUESTS__VI = 0x0309; +constexpr unsigned int mmPIPE4_PG_CONFIG__VI = 0x02CC; +constexpr unsigned int mmPIPE4_PG_ENABLE__VI = 0x02CD; +constexpr unsigned int mmPIPE4_PG_STATUS__VI = 0x02CE; +constexpr unsigned int mmPIPE5_ARBITRATION_CONTROL3__VI = 0x02FF; +constexpr unsigned int mmPIPE5_DMIF_BUFFER_CONTROL__VI = 0x0326; +constexpr unsigned int mmPIPE5_MAX_REQUESTS__VI = 0x030A; +constexpr unsigned int mmPIPE5_PG_CONFIG__VI = 0x02CF; +constexpr unsigned int mmPIPE5_PG_ENABLE__VI = 0x02D0; +constexpr unsigned int mmPIPE5_PG_STATUS__VI = 0x02D1; +constexpr unsigned int mmPIPE6_ARBITRATION_CONTROL3__VI = 0x032A; +constexpr unsigned int mmPIPE6_MAX_REQUESTS__VI = 0x032C; +constexpr unsigned int mmPIPE7_ARBITRATION_CONTROL3__VI = 0x032B; +constexpr unsigned int mmPIPE7_MAX_REQUESTS__VI = 0x032D; +constexpr unsigned int mmPIXCLK0_RESYNC_CNTL__VI = 0x013A; +constexpr unsigned int mmPIXCLK1_RESYNC_CNTL__VI = 0x0138; +constexpr unsigned int mmPIXCLK2_RESYNC_CNTL__VI = 0x0139; +constexpr unsigned int mmPLL_ANALOG__VI = 0x1708; +constexpr unsigned int mmPLL_ANALOG_CNTL__VI = 0x1711; +constexpr unsigned int mmPLL_CNTL__VI = 0x1707; +constexpr unsigned int mmPLL_DEBUG_CNTL__VI = 0x170B; +constexpr unsigned int mmPLL_DS_CNTL__VI = 0x1705; +constexpr unsigned int mmPLL_FB_DIV__VI = 0x1701; +constexpr unsigned int mmPLL_IDCLK_CNTL__VI = 0x1706; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED0__VI = 0x1700; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED1__VI = 0x1701; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED10__VI = 0x170A; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED11__VI = 0x170B; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED12__VI = 0x170C; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED13__VI = 0x170D; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED14__VI = 0x170E; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED15__VI = 0x170F; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED16__VI = 0x1710; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED17__VI = 0x1711; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED18__VI = 0x1712; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED19__VI = 0x1713; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED2__VI = 0x1702; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED20__VI = 0x1714; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED21__VI = 0x1715; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED22__VI = 0x1716; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED23__VI = 0x1717; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED24__VI = 0x1718; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED25__VI = 0x1719; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED26__VI = 0x171A; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED27__VI = 0x171B; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED28__VI = 0x171C; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED29__VI = 0x171D; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED3__VI = 0x1703; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED30__VI = 0x171E; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED31__VI = 0x171F; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED32__VI = 0x1720; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED33__VI = 0x1721; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED34__VI = 0x1722; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED35__VI = 0x1723; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED36__VI = 0x1724; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED37__VI = 0x1725; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED38__VI = 0x1726; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED39__VI = 0x1727; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED4__VI = 0x1704; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED40__VI = 0x1728; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED41__VI = 0x1729; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED5__VI = 0x1705; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED6__VI = 0x1706; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED7__VI = 0x1707; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED8__VI = 0x1708; +constexpr unsigned int mmPLL_MACRO_CNTL_RESERVED9__VI = 0x1709; +constexpr unsigned int mmPLL_POST_DIV__VI = 0x1702; +constexpr unsigned int mmPLL_REF_DIV__VI = 0x1700; +constexpr unsigned int mmPLL_SS_AMOUNT_DSFRAC__VI = 0x1703; +constexpr unsigned int mmPLL_SS_CNTL__VI = 0x1704; +constexpr unsigned int mmPLL_UNLOCK_DETECT_CNTL__VI = 0x170A; +constexpr unsigned int mmPLL_UPDATE_CNTL__VI = 0x170D; +constexpr unsigned int mmPLL_UPDATE_LOCK__VI = 0x170C; +constexpr unsigned int mmPLL_VREG_CNTL__VI = 0x1709; +constexpr unsigned int mmPLL_XOR_LOCK__VI = 0x1710; +constexpr unsigned int mmPPLL_DEBUG_MUX_CNTL__VI = 0x1721; +constexpr unsigned int mmPPLL_DIV_UPDATE_DEBUG__VI = 0x171F; +constexpr unsigned int mmPPLL_SPARE0__VI = 0x1722; +constexpr unsigned int mmPPLL_SPARE1__VI = 0x1723; +constexpr unsigned int mmPPLL_STATUS_DEBUG__VI = 0x1720; +constexpr unsigned int mmPRESCALE_CONTROL__VI = 0x46B2; +constexpr unsigned int mmPRESCALE_GRPH_CONTROL__VI = 0x1A2D; +constexpr unsigned int mmPRESCALE_OVL_CONTROL__VI = 0x1A31; +constexpr unsigned int mmPRESCALE_VALUES_B__VI = 0x46B5; +constexpr unsigned int mmPRESCALE_VALUES_G__VI = 0x46B4; +constexpr unsigned int mmPRESCALE_VALUES_GRPH_B__VI = 0x1A30; +constexpr unsigned int mmPRESCALE_VALUES_GRPH_G__VI = 0x1A2F; +constexpr unsigned int mmPRESCALE_VALUES_GRPH_R__VI = 0x1A2E; +constexpr unsigned int mmPRESCALE_VALUES_OVL_CB__VI = 0x1A32; +constexpr unsigned int mmPRESCALE_VALUES_OVL_CR__VI = 0x1A34; +constexpr unsigned int mmPRESCALE_VALUES_OVL_Y__VI = 0x1A33; +constexpr unsigned int mmPRESCALE_VALUES_R__VI = 0x46B3; +constexpr unsigned int mmRAS_TA_SIGNATURE1__VI = 0x33A0; +constexpr unsigned int mmRBBMIF_STATUS__VI = 0x0315; +constexpr unsigned int mmRBBMIF_STATUS_FLAG__VI = 0x0327; +constexpr unsigned int mmRBBMIF_TIMEOUT__VI = 0x0314; +constexpr unsigned int mmRBBMIF_TIMEOUT_DIS__VI = 0x0316; +constexpr unsigned int mmREFCLK_CGTT_BLK_CTRL_REG__VI = 0x010B; +constexpr unsigned int mmREFCLK_CNTL__VI = 0x0109; +constexpr unsigned int mmREGAMMA_CNTLA_END_CNTL1__VI = 0x1AA6; +constexpr unsigned int mmREGAMMA_CNTLA_END_CNTL2__VI = 0x1AA7; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_0_1__VI = 0x1AA8; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_10_11__VI = 0x1AAD; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_12_13__VI = 0x1AAE; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_14_15__VI = 0x1AAF; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_2_3__VI = 0x1AA9; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_4_5__VI = 0x1AAA; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_6_7__VI = 0x1AAB; +constexpr unsigned int mmREGAMMA_CNTLA_REGION_8_9__VI = 0x1AAC; +constexpr unsigned int mmREGAMMA_CNTLA_SLOPE_CNTL__VI = 0x1AA5; +constexpr unsigned int mmREGAMMA_CNTLA_START_CNTL__VI = 0x1AA4; +constexpr unsigned int mmREGAMMA_CNTLB_END_CNTL1__VI = 0x1AB2; +constexpr unsigned int mmREGAMMA_CNTLB_END_CNTL2__VI = 0x1AB3; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_0_1__VI = 0x1AB4; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_10_11__VI = 0x1AB9; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_12_13__VI = 0x1ABA; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_14_15__VI = 0x1ABB; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_2_3__VI = 0x1AB5; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_4_5__VI = 0x1AB6; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_6_7__VI = 0x1AB7; +constexpr unsigned int mmREGAMMA_CNTLB_REGION_8_9__VI = 0x1AB8; +constexpr unsigned int mmREGAMMA_CNTLB_SLOPE_CNTL__VI = 0x1AB1; +constexpr unsigned int mmREGAMMA_CNTLB_START_CNTL__VI = 0x1AB0; +constexpr unsigned int mmREGAMMA_CONTROL__VI = 0x1AA0; +constexpr unsigned int mmREGAMMA_LUT_DATA__VI = 0x1AA2; +constexpr unsigned int mmREGAMMA_LUT_INDEX__VI = 0x1AA1; +constexpr unsigned int mmREGAMMA_LUT_WRITE_EN_MASK__VI = 0x1AA3; +constexpr unsigned int mmREMAP_HDP_MEM_FLUSH_CNTL__VI = 0x1426; +constexpr unsigned int mmREMAP_HDP_REG_FLUSH_CNTL__VI = 0x1427; +constexpr unsigned int mmRLC_AUTO_PG_CTRL__VI = 0xEC55; +constexpr unsigned int mmRLC_CAPTURE_GPU_CLOCK_COUNT__VI = 0xEC26; +constexpr unsigned int mmRLC_CGCG_CGLS_CTRL__VI = 0xEC49; +constexpr unsigned int mmRLC_CGCG_RAMP_CTRL__VI = 0xEC4A; +constexpr unsigned int mmRLC_CGTT_MGCG_OVERRIDE__VI = 0xEC48; +constexpr unsigned int mmRLC_CNTL__SI__CI = 0x30C0; +constexpr unsigned int mmRLC_CNTL__VI = 0xEC00; +constexpr unsigned int mmRLC_CP_RESPONSE0__VI = 0xECA5; +constexpr unsigned int mmRLC_CP_RESPONSE1__VI = 0xECA6; +constexpr unsigned int mmRLC_CP_RESPONSE2__VI = 0xECA7; +constexpr unsigned int mmRLC_CP_RESPONSE3__VI = 0xECA8; +constexpr unsigned int mmRLC_CP_SCHEDULERS__VI = 0xECAA; +constexpr unsigned int mmRLC_CSIB_ADDR_HI__VI = 0xECA3; +constexpr unsigned int mmRLC_CSIB_ADDR_LO__VI = 0xECA2; +constexpr unsigned int mmRLC_CSIB_LENGTH__VI = 0xECA4; +constexpr unsigned int mmRLC_CU_STATUS__VI = 0xEC4E; +constexpr unsigned int mmRLC_DEBUG__VI = 0xEC02; +constexpr unsigned int mmRLC_DEBUG_SELECT__VI = 0xEC01; +constexpr unsigned int mmRLC_DRIVER_CPDMA_STATUS__VI = 0xEC1E; +constexpr unsigned int mmRLC_DYN_PG_REQUEST__VI = 0xEC4C; +constexpr unsigned int mmRLC_DYN_PG_STATUS__VI = 0xEC4B; +constexpr unsigned int mmRLC_GPM_CU_PD_TIMEOUT__VI = 0xEC6B; +constexpr unsigned int mmRLC_GPM_DEBUG__VI = 0xEC21; +constexpr unsigned int mmRLC_GPM_DEBUG_SELECT__VI = 0xEC20; +constexpr unsigned int mmRLC_GPM_GENERAL_0__VI = 0xEC63; +constexpr unsigned int mmRLC_GPM_GENERAL_1__VI = 0xEC64; +constexpr unsigned int mmRLC_GPM_GENERAL_2__VI = 0xEC65; +constexpr unsigned int mmRLC_GPM_GENERAL_3__VI = 0xEC66; +constexpr unsigned int mmRLC_GPM_GENERAL_4__VI = 0xEC67; +constexpr unsigned int mmRLC_GPM_GENERAL_5__VI = 0xEC68; +constexpr unsigned int mmRLC_GPM_GENERAL_6__VI = 0xEC69; +constexpr unsigned int mmRLC_GPM_GENERAL_7__VI = 0xEC6A; +constexpr unsigned int mmRLC_GPM_INT_DISABLE_TH0__VI = 0xEC7C; +constexpr unsigned int mmRLC_GPM_INT_DISABLE_TH1__VI = 0xEC7D; +constexpr unsigned int mmRLC_GPM_INT_FORCE_TH0__VI = 0xEC7E; +constexpr unsigned int mmRLC_GPM_INT_FORCE_TH1__VI = 0xEC7F; +constexpr unsigned int mmRLC_GPM_LOG_ADDR__VI = 0xEC76; +constexpr unsigned int mmRLC_GPM_LOG_CONT__VI = 0xEC7B; +constexpr unsigned int mmRLC_GPM_LOG_SIZE__VI = 0xEC77; +constexpr unsigned int mmRLC_GPM_PERF_COUNT_0__VI = 0xEC6F; +constexpr unsigned int mmRLC_GPM_PERF_COUNT_1__VI = 0xEC70; +constexpr unsigned int mmRLC_GPM_SCRATCH_ADDR__VI = 0xEC6C; +constexpr unsigned int mmRLC_GPM_SCRATCH_DATA__VI = 0xEC6D; +constexpr unsigned int mmRLC_GPM_STAT__VI = 0xEC40; +constexpr unsigned int mmRLC_GPM_THREAD_ENABLE__VI = 0xEC45; +constexpr unsigned int mmRLC_GPM_THREAD_PRIORITY__VI = 0xEC44; +constexpr unsigned int mmRLC_GPM_THREAD_RESET__VI = 0xEC28; +constexpr unsigned int mmRLC_GPM_UCODE_ADDR__VI = 0xF83C; +constexpr unsigned int mmRLC_GPM_UCODE_DATA__VI = 0xF83D; +constexpr unsigned int mmRLC_GPM_VMID_THREAD0__VI = 0xEC46; +constexpr unsigned int mmRLC_GPM_VMID_THREAD1__VI = 0xEC47; +constexpr unsigned int mmRLC_GPM_VMID_THREAD2__VI = 0xFB41; +constexpr unsigned int mmRLC_GPR_REG1__VI = 0xEC79; +constexpr unsigned int mmRLC_GPR_REG2__VI = 0xEC7A; +constexpr unsigned int mmRLC_GPU_CLOCK_32__VI = 0xEC42; +constexpr unsigned int mmRLC_GPU_CLOCK_32_RES_SEL__VI = 0xEC41; +constexpr unsigned int mmRLC_GPU_CLOCK_COUNT_LSB__VI = 0xEC24; +constexpr unsigned int mmRLC_GPU_CLOCK_COUNT_MSB__VI = 0xEC25; +constexpr unsigned int mmRLC_GPU_IOV_ACTIVE_FCN_ID__VI = 0xFB40; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG1__VI = 0xFB01; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG10__VI = 0xFB22; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG11__VI = 0xFB23; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG12__VI = 0xFB24; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG13__VI = 0xFB25; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG14__VI = 0xFB26; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG15__VI = 0xFB27; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG2__VI = 0xFB02; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG6__VI = 0xFB06; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG8__VI = 0xFB08; +constexpr unsigned int mmRLC_GPU_IOV_CFG_REG9__VI = 0xFB21; +constexpr unsigned int mmRLC_GPU_IOV_F32_CNTL__VI = 0xFB46; +constexpr unsigned int mmRLC_GPU_IOV_F32_RESET__VI = 0xFB47; +constexpr unsigned int mmRLC_GPU_IOV_INT_DISABLE__VI = 0xFB4E; +constexpr unsigned int mmRLC_GPU_IOV_INT_FORCE__VI = 0xFB4F; +constexpr unsigned int mmRLC_GPU_IOV_RLC_RESPONSE__VI = 0xFB4D; +constexpr unsigned int mmRLC_GPU_IOV_SCH_0__VI = 0xFB52; +constexpr unsigned int mmRLC_GPU_IOV_SCH_1__VI = 0xFB53; +constexpr unsigned int mmRLC_GPU_IOV_SCH_2__VI = 0xFB54; +constexpr unsigned int mmRLC_GPU_IOV_SCH_3__VI = 0xFB55; +constexpr unsigned int mmRLC_GPU_IOV_SCH_INT__VI = 0xFB56; +constexpr unsigned int mmRLC_GPU_IOV_SCRATCH_ADDR__VI = 0xFB44; +constexpr unsigned int mmRLC_GPU_IOV_SCRATCH_DATA__VI = 0xFB45; +constexpr unsigned int mmRLC_GPU_IOV_SDMA0_BUSY_STATUS__VI = 0xFB50; +constexpr unsigned int mmRLC_GPU_IOV_SDMA0_STATUS__VI = 0xFB48; +constexpr unsigned int mmRLC_GPU_IOV_SDMA1_BUSY_STATUS__VI = 0xFB51; +constexpr unsigned int mmRLC_GPU_IOV_SDMA1_STATUS__VI = 0xFB49; +constexpr unsigned int mmRLC_GPU_IOV_SMU_RESPONSE__VI = 0xFB4A; +constexpr unsigned int mmRLC_GPU_IOV_UCODE_ADDR__VI = 0xFB42; +constexpr unsigned int mmRLC_GPU_IOV_UCODE_DATA__VI = 0xFB43; +constexpr unsigned int mmRLC_GPU_IOV_VF_ENABLE__VI = 0xFB00; +constexpr unsigned int mmRLC_GPU_IOV_VIRT_RESET_REQ__VI = 0xFB4C; +constexpr unsigned int mmRLC_HYP_GPM_UCODE_ADDR__VI = 0xF83C; +constexpr unsigned int mmRLC_HYP_GPM_UCODE_DATA__VI = 0xF83D; +constexpr unsigned int mmRLC_JUMP_TABLE_RESTORE__VI = 0xEC1E; +constexpr unsigned int mmRLC_LB_ALWAYS_ACTIVE_CU_MASK__VI = 0xEC50; +constexpr unsigned int mmRLC_LB_CNTL__VI = 0xEC19; +constexpr unsigned int mmRLC_LB_CNTR_INIT__VI = 0xEC1B; +constexpr unsigned int mmRLC_LB_CNTR_MAX__VI = 0xEC12; +constexpr unsigned int mmRLC_LB_INIT_CU_MASK__VI = 0xEC4F; +constexpr unsigned int mmRLC_LB_PARAMS__VI = 0xEC51; +constexpr unsigned int mmRLC_LOAD_BALANCE_CNTR__VI = 0xEC1C; +constexpr unsigned int mmRLC_MAX_PG_CU__VI = 0xEC54; +constexpr unsigned int mmRLC_MC_CNTL__VI = 0xEC03; +constexpr unsigned int mmRLC_MEM_SLP_CNTL__VI = 0xEC06; +constexpr unsigned int mmRLC_MGCG_CTRL__VI = 0xEC1A; +constexpr unsigned int mmRLC_PERFMON_CLK_CNTL__VI = 0xDCBF; +constexpr unsigned int mmRLC_PG_ALWAYS_ON_CU_MASK__VI = 0xEC53; +constexpr unsigned int mmRLC_PG_CNTL__VI = 0xEC43; +constexpr unsigned int mmRLC_PG_DELAY__VI = 0xEC4D; +constexpr unsigned int mmRLC_PG_DELAY_2__VI = 0xEC1F; +constexpr unsigned int mmRLC_PG_DELAY_3__VI = 0xEC78; +constexpr unsigned int mmRLC_RLCV_COMMAND__VI = 0xEC0A; +constexpr unsigned int mmRLC_RLCV_SAFE_MODE__VI = 0xEC08; +constexpr unsigned int mmRLC_ROM_CNTL__VI = 0xF836; +constexpr unsigned int mmRLC_SAFE_MODE__VI = 0xEC05; +constexpr unsigned int mmRLC_SAVE_AND_RESTORE_BASE__VI = 0xEC1D; +constexpr unsigned int mmRLC_SERDES_CU_MASTER_BUSY__VI = 0xEC61; +constexpr unsigned int mmRLC_SERDES_NONCU_MASTER_BUSY__VI = 0xEC62; +constexpr unsigned int mmRLC_SERDES_RD_DATA_0__VI = 0xEC5A; +constexpr unsigned int mmRLC_SERDES_RD_DATA_1__VI = 0xEC5B; +constexpr unsigned int mmRLC_SERDES_RD_DATA_2__VI = 0xEC5C; +constexpr unsigned int mmRLC_SERDES_RD_MASTER_INDEX__VI = 0xEC59; +constexpr unsigned int mmRLC_SERDES_WR_CTRL__VI = 0xEC5F; +constexpr unsigned int mmRLC_SERDES_WR_CU_MASTER_MASK__VI = 0xEC5D; +constexpr unsigned int mmRLC_SERDES_WR_DATA__VI = 0xEC60; +constexpr unsigned int mmRLC_SERDES_WR_NONCU_MASTER_MASK__VI = 0xEC5E; +constexpr unsigned int mmRLC_SMU_COMMAND__VI = 0xECA9; +constexpr unsigned int mmRLC_SMU_GRBM_REG_SAVE_CTRL__VI = 0xEC56; +constexpr unsigned int mmRLC_SMU_MESSAGE__VI = 0xEC76; +constexpr unsigned int mmRLC_SMU_PG_CTRL__VI = 0xEC57; +constexpr unsigned int mmRLC_SMU_PG_WAKE_UP_CTRL__VI = 0xEC58; +constexpr unsigned int mmRLC_SMU_SAFE_MODE__VI = 0xEC09; +constexpr unsigned int mmRLC_SOFT_RESET_GPU__VI = 0xEC05; +constexpr unsigned int mmRLC_SPM_CBR0_PERFMON_SAMPLE_DELAY__VI = 0xDCA1; +constexpr unsigned int mmRLC_SPM_CBR1_PERFMON_SAMPLE_DELAY__VI = 0xDCA2; +constexpr unsigned int mmRLC_SPM_DBR0_PERFMON_SAMPLE_DELAY__VI = 0xDC9F; +constexpr unsigned int mmRLC_SPM_DBR1_PERFMON_SAMPLE_DELAY__VI = 0xDCA0; +constexpr unsigned int mmRLC_SPM_DEBUG__VI = 0xEC75; +constexpr unsigned int mmRLC_SPM_DEBUG_SELECT__VI = 0xEC74; +constexpr unsigned int mmRLC_SPM_INT_CNTL__VI = 0xEC72; +constexpr unsigned int mmRLC_SPM_INT_STATUS__VI = 0xEC73; +constexpr unsigned int mmRLC_SPM_VMID__VI = 0xEC71; +constexpr unsigned int mmRLC_SRM_ARAM_ADDR__VI = 0xEC83; +constexpr unsigned int mmRLC_SRM_ARAM_DATA__VI = 0xEC84; +constexpr unsigned int mmRLC_SRM_CNTL__VI = 0xEC80; +constexpr unsigned int mmRLC_SRM_DEBUG__VI = 0xEC82; +constexpr unsigned int mmRLC_SRM_DEBUG_SELECT__VI = 0xEC81; +constexpr unsigned int mmRLC_SRM_DRAM_ADDR__VI = 0xEC85; +constexpr unsigned int mmRLC_SRM_DRAM_DATA__VI = 0xEC86; +constexpr unsigned int mmRLC_SRM_GPM_ABORT__VI = 0xEC9C; +constexpr unsigned int mmRLC_SRM_GPM_COMMAND__VI = 0xEC87; +constexpr unsigned int mmRLC_SRM_GPM_COMMAND_STATUS__VI = 0xEC88; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_0__VI = 0xEC8B; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_1__VI = 0xEC8C; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_2__VI = 0xEC8D; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_3__VI = 0xEC8E; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_4__VI = 0xEC8F; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_5__VI = 0xEC90; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_6__VI = 0xEC91; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_ADDR_7__VI = 0xEC92; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_0__VI = 0xEC93; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_1__VI = 0xEC94; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_2__VI = 0xEC95; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_3__VI = 0xEC96; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_4__VI = 0xEC97; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_5__VI = 0xEC98; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_6__VI = 0xEC99; +constexpr unsigned int mmRLC_SRM_INDEX_CNTL_DATA_7__VI = 0xEC9A; +constexpr unsigned int mmRLC_SRM_RLCV_COMMAND__VI = 0xEC89; +constexpr unsigned int mmRLC_SRM_RLCV_COMMAND_STATUS__VI = 0xEC8A; +constexpr unsigned int mmRLC_SRM_STAT__VI = 0xEC9B; +constexpr unsigned int mmRLC_STAT__VI = 0xEC04; +constexpr unsigned int mmRLC_STATIC_PG_STATUS__VI = 0xEC6E; +constexpr unsigned int mmRLC_THREAD1_DELAY__VI = 0xEC52; +constexpr unsigned int mmRLC_UCODE_CNTL__VI = 0xEC27; +constexpr unsigned int mmSAM_IH_EXT_ERR_INTR__VI = 0x8810; +constexpr unsigned int mmSAM_IH_EXT_ERR_INTR_STATUS__VI = 0x8812; +constexpr unsigned int mmSCL0_SCL_DEBUG2__VI = 0x1B69; +constexpr unsigned int mmSCL0_SCL_HORZ_FILTER_CONTROL__VI = 0x1B48; +constexpr unsigned int mmSCL0_SCL_HORZ_FILTER_INIT__VI = 0x1B4A; +constexpr unsigned int mmSCL0_SCL_HORZ_FILTER_SCALE_RATIO__VI = 0x1B49; +constexpr unsigned int mmSCL0_SCL_MODE__VI = 0x1B42; +constexpr unsigned int mmSCL0_SCL_ROUND_OFFSET__VI = 0x1B4F; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_CONTROL__VI = 0x1B4B; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_INIT__VI = 0x1B4D; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_INIT_BOT__VI = 0x1B4E; +constexpr unsigned int mmSCL0_SCL_VERT_FILTER_SCALE_RATIO__VI = 0x1B4C; +constexpr unsigned int mmSCL0_VIEWPORT_START_SECONDARY__VI = 0x1B5B; +constexpr unsigned int mmSCL1_EXT_OVERSCAN_LEFT_RIGHT__VI = 0x1D5E; +constexpr unsigned int mmSCL1_EXT_OVERSCAN_TOP_BOTTOM__VI = 0x1D5F; +constexpr unsigned int mmSCL1_SCL_ALU_CONTROL__VI = 0x1D54; +constexpr unsigned int mmSCL1_SCL_AUTOMATIC_MODE_CONTROL__VI = 0x1D47; +constexpr unsigned int mmSCL1_SCL_BYPASS_CONTROL__VI = 0x1D45; +constexpr unsigned int mmSCL1_SCL_COEF_RAM_CONFLICT_STATUS__VI = 0x1D55; +constexpr unsigned int mmSCL1_SCL_COEF_RAM_SELECT__VI = 0x1D40; +constexpr unsigned int mmSCL1_SCL_COEF_RAM_TAP_DATA__VI = 0x1D41; +constexpr unsigned int mmSCL1_SCL_CONTROL__VI = 0x1D44; +constexpr unsigned int mmSCL1_SCL_DEBUG__VI = 0x1D6A; +constexpr unsigned int mmSCL1_SCL_DEBUG2__VI = 0x1D69; +constexpr unsigned int mmSCL1_SCL_F_SHARP_CONTROL__VI = 0x1D53; +constexpr unsigned int mmSCL1_SCL_HORZ_FILTER_CONTROL__VI = 0x1D48; +constexpr unsigned int mmSCL1_SCL_HORZ_FILTER_INIT__VI = 0x1D4A; +constexpr unsigned int mmSCL1_SCL_HORZ_FILTER_SCALE_RATIO__VI = 0x1D49; +constexpr unsigned int mmSCL1_SCL_MANUAL_REPLICATE_CONTROL__VI = 0x1D46; +constexpr unsigned int mmSCL1_SCL_MODE__VI = 0x1D42; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_DET1__VI = 0x1D60; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_DET2__VI = 0x1D61; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_DET3__VI = 0x1D62; +constexpr unsigned int mmSCL1_SCL_MODE_CHANGE_MASK__VI = 0x1D63; +constexpr unsigned int mmSCL1_SCL_ROUND_OFFSET__VI = 0x1D4F; +constexpr unsigned int mmSCL1_SCL_TAP_CONTROL__VI = 0x1D43; +constexpr unsigned int mmSCL1_SCL_TEST_DEBUG_DATA__VI = 0x1D6C; +constexpr unsigned int mmSCL1_SCL_TEST_DEBUG_INDEX__VI = 0x1D6B; +constexpr unsigned int mmSCL1_SCL_UPDATE__VI = 0x1D51; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_CONTROL__VI = 0x1D4B; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_INIT__VI = 0x1D4D; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_INIT_BOT__VI = 0x1D4E; +constexpr unsigned int mmSCL1_SCL_VERT_FILTER_SCALE_RATIO__VI = 0x1D4C; +constexpr unsigned int mmSCL1_VIEWPORT_SIZE__VI = 0x1D5D; +constexpr unsigned int mmSCL1_VIEWPORT_START__VI = 0x1D5C; +constexpr unsigned int mmSCL1_VIEWPORT_START_SECONDARY__VI = 0x1D5B; +constexpr unsigned int mmSCL2_EXT_OVERSCAN_LEFT_RIGHT__VI = 0x1F5E; +constexpr unsigned int mmSCL2_EXT_OVERSCAN_TOP_BOTTOM__VI = 0x1F5F; +constexpr unsigned int mmSCL2_SCL_ALU_CONTROL__VI = 0x1F54; +constexpr unsigned int mmSCL2_SCL_AUTOMATIC_MODE_CONTROL__VI = 0x1F47; +constexpr unsigned int mmSCL2_SCL_BYPASS_CONTROL__VI = 0x1F45; +constexpr unsigned int mmSCL2_SCL_COEF_RAM_CONFLICT_STATUS__VI = 0x1F55; +constexpr unsigned int mmSCL2_SCL_COEF_RAM_SELECT__VI = 0x1F40; +constexpr unsigned int mmSCL2_SCL_COEF_RAM_TAP_DATA__VI = 0x1F41; +constexpr unsigned int mmSCL2_SCL_CONTROL__VI = 0x1F44; +constexpr unsigned int mmSCL2_SCL_DEBUG__VI = 0x1F6A; +constexpr unsigned int mmSCL2_SCL_DEBUG2__VI = 0x1F69; +constexpr unsigned int mmSCL2_SCL_F_SHARP_CONTROL__VI = 0x1F53; +constexpr unsigned int mmSCL2_SCL_HORZ_FILTER_CONTROL__VI = 0x1F48; +constexpr unsigned int mmSCL2_SCL_HORZ_FILTER_INIT__VI = 0x1F4A; +constexpr unsigned int mmSCL2_SCL_HORZ_FILTER_SCALE_RATIO__VI = 0x1F49; +constexpr unsigned int mmSCL2_SCL_MANUAL_REPLICATE_CONTROL__VI = 0x1F46; +constexpr unsigned int mmSCL2_SCL_MODE__VI = 0x1F42; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_DET1__VI = 0x1F60; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_DET2__VI = 0x1F61; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_DET3__VI = 0x1F62; +constexpr unsigned int mmSCL2_SCL_MODE_CHANGE_MASK__VI = 0x1F63; +constexpr unsigned int mmSCL2_SCL_ROUND_OFFSET__VI = 0x1F4F; +constexpr unsigned int mmSCL2_SCL_TAP_CONTROL__VI = 0x1F43; +constexpr unsigned int mmSCL2_SCL_TEST_DEBUG_DATA__VI = 0x1F6C; +constexpr unsigned int mmSCL2_SCL_TEST_DEBUG_INDEX__VI = 0x1F6B; +constexpr unsigned int mmSCL2_SCL_UPDATE__VI = 0x1F51; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_CONTROL__VI = 0x1F4B; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_INIT__VI = 0x1F4D; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_INIT_BOT__VI = 0x1F4E; +constexpr unsigned int mmSCL2_SCL_VERT_FILTER_SCALE_RATIO__VI = 0x1F4C; +constexpr unsigned int mmSCL2_VIEWPORT_SIZE__VI = 0x1F5D; +constexpr unsigned int mmSCL2_VIEWPORT_START__VI = 0x1F5C; +constexpr unsigned int mmSCL2_VIEWPORT_START_SECONDARY__VI = 0x1F5B; +constexpr unsigned int mmSCL3_EXT_OVERSCAN_LEFT_RIGHT__VI = 0x415E; +constexpr unsigned int mmSCL3_EXT_OVERSCAN_TOP_BOTTOM__VI = 0x415F; +constexpr unsigned int mmSCL3_SCL_ALU_CONTROL__VI = 0x4154; +constexpr unsigned int mmSCL3_SCL_AUTOMATIC_MODE_CONTROL__VI = 0x4147; +constexpr unsigned int mmSCL3_SCL_BYPASS_CONTROL__VI = 0x4145; +constexpr unsigned int mmSCL3_SCL_COEF_RAM_CONFLICT_STATUS__VI = 0x4155; +constexpr unsigned int mmSCL3_SCL_COEF_RAM_SELECT__VI = 0x4140; +constexpr unsigned int mmSCL3_SCL_COEF_RAM_TAP_DATA__VI = 0x4141; +constexpr unsigned int mmSCL3_SCL_CONTROL__VI = 0x4144; +constexpr unsigned int mmSCL3_SCL_DEBUG__VI = 0x416A; +constexpr unsigned int mmSCL3_SCL_DEBUG2__VI = 0x4169; +constexpr unsigned int mmSCL3_SCL_F_SHARP_CONTROL__VI = 0x4153; +constexpr unsigned int mmSCL3_SCL_HORZ_FILTER_CONTROL__VI = 0x4148; +constexpr unsigned int mmSCL3_SCL_HORZ_FILTER_INIT__VI = 0x414A; +constexpr unsigned int mmSCL3_SCL_HORZ_FILTER_SCALE_RATIO__VI = 0x4149; +constexpr unsigned int mmSCL3_SCL_MANUAL_REPLICATE_CONTROL__VI = 0x4146; +constexpr unsigned int mmSCL3_SCL_MODE__VI = 0x4142; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_DET1__VI = 0x4160; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_DET2__VI = 0x4161; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_DET3__VI = 0x4162; +constexpr unsigned int mmSCL3_SCL_MODE_CHANGE_MASK__VI = 0x4163; +constexpr unsigned int mmSCL3_SCL_ROUND_OFFSET__VI = 0x414F; +constexpr unsigned int mmSCL3_SCL_TAP_CONTROL__VI = 0x4143; +constexpr unsigned int mmSCL3_SCL_TEST_DEBUG_DATA__VI = 0x416C; +constexpr unsigned int mmSCL3_SCL_TEST_DEBUG_INDEX__VI = 0x416B; +constexpr unsigned int mmSCL3_SCL_UPDATE__VI = 0x4151; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_CONTROL__VI = 0x414B; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_INIT__VI = 0x414D; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_INIT_BOT__VI = 0x414E; +constexpr unsigned int mmSCL3_SCL_VERT_FILTER_SCALE_RATIO__VI = 0x414C; +constexpr unsigned int mmSCL3_VIEWPORT_SIZE__VI = 0x415D; +constexpr unsigned int mmSCL3_VIEWPORT_START__VI = 0x415C; +constexpr unsigned int mmSCL3_VIEWPORT_START_SECONDARY__VI = 0x415B; +constexpr unsigned int mmSCL4_EXT_OVERSCAN_LEFT_RIGHT__VI = 0x435E; +constexpr unsigned int mmSCL4_EXT_OVERSCAN_TOP_BOTTOM__VI = 0x435F; +constexpr unsigned int mmSCL4_SCL_ALU_CONTROL__VI = 0x4354; +constexpr unsigned int mmSCL4_SCL_AUTOMATIC_MODE_CONTROL__VI = 0x4347; +constexpr unsigned int mmSCL4_SCL_BYPASS_CONTROL__VI = 0x4345; +constexpr unsigned int mmSCL4_SCL_COEF_RAM_CONFLICT_STATUS__VI = 0x4355; +constexpr unsigned int mmSCL4_SCL_COEF_RAM_SELECT__VI = 0x4340; +constexpr unsigned int mmSCL4_SCL_COEF_RAM_TAP_DATA__VI = 0x4341; +constexpr unsigned int mmSCL4_SCL_CONTROL__VI = 0x4344; +constexpr unsigned int mmSCL4_SCL_DEBUG__VI = 0x436A; +constexpr unsigned int mmSCL4_SCL_DEBUG2__VI = 0x4369; +constexpr unsigned int mmSCL4_SCL_F_SHARP_CONTROL__VI = 0x4353; +constexpr unsigned int mmSCL4_SCL_HORZ_FILTER_CONTROL__VI = 0x4348; +constexpr unsigned int mmSCL4_SCL_HORZ_FILTER_INIT__VI = 0x434A; +constexpr unsigned int mmSCL4_SCL_HORZ_FILTER_SCALE_RATIO__VI = 0x4349; +constexpr unsigned int mmSCL4_SCL_MANUAL_REPLICATE_CONTROL__VI = 0x4346; +constexpr unsigned int mmSCL4_SCL_MODE__VI = 0x4342; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_DET1__VI = 0x4360; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_DET2__VI = 0x4361; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_DET3__VI = 0x4362; +constexpr unsigned int mmSCL4_SCL_MODE_CHANGE_MASK__VI = 0x4363; +constexpr unsigned int mmSCL4_SCL_ROUND_OFFSET__VI = 0x434F; +constexpr unsigned int mmSCL4_SCL_TAP_CONTROL__VI = 0x4343; +constexpr unsigned int mmSCL4_SCL_TEST_DEBUG_DATA__VI = 0x436C; +constexpr unsigned int mmSCL4_SCL_TEST_DEBUG_INDEX__VI = 0x436B; +constexpr unsigned int mmSCL4_SCL_UPDATE__VI = 0x4351; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_CONTROL__VI = 0x434B; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_INIT__VI = 0x434D; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_INIT_BOT__VI = 0x434E; +constexpr unsigned int mmSCL4_SCL_VERT_FILTER_SCALE_RATIO__VI = 0x434C; +constexpr unsigned int mmSCL4_VIEWPORT_SIZE__VI = 0x435D; +constexpr unsigned int mmSCL4_VIEWPORT_START__VI = 0x435C; +constexpr unsigned int mmSCL4_VIEWPORT_START_SECONDARY__VI = 0x435B; +constexpr unsigned int mmSCL5_EXT_OVERSCAN_LEFT_RIGHT__VI = 0x455E; +constexpr unsigned int mmSCL5_EXT_OVERSCAN_TOP_BOTTOM__VI = 0x455F; +constexpr unsigned int mmSCL5_SCL_ALU_CONTROL__VI = 0x4554; +constexpr unsigned int mmSCL5_SCL_AUTOMATIC_MODE_CONTROL__VI = 0x4547; +constexpr unsigned int mmSCL5_SCL_BYPASS_CONTROL__VI = 0x4545; +constexpr unsigned int mmSCL5_SCL_COEF_RAM_CONFLICT_STATUS__VI = 0x4555; +constexpr unsigned int mmSCL5_SCL_COEF_RAM_SELECT__VI = 0x4540; +constexpr unsigned int mmSCL5_SCL_COEF_RAM_TAP_DATA__VI = 0x4541; +constexpr unsigned int mmSCL5_SCL_CONTROL__VI = 0x4544; +constexpr unsigned int mmSCL5_SCL_DEBUG__VI = 0x456A; +constexpr unsigned int mmSCL5_SCL_DEBUG2__VI = 0x4569; +constexpr unsigned int mmSCL5_SCL_F_SHARP_CONTROL__VI = 0x4553; +constexpr unsigned int mmSCL5_SCL_HORZ_FILTER_CONTROL__VI = 0x4548; +constexpr unsigned int mmSCL5_SCL_HORZ_FILTER_INIT__VI = 0x454A; +constexpr unsigned int mmSCL5_SCL_HORZ_FILTER_SCALE_RATIO__VI = 0x4549; +constexpr unsigned int mmSCL5_SCL_MANUAL_REPLICATE_CONTROL__VI = 0x4546; +constexpr unsigned int mmSCL5_SCL_MODE__VI = 0x4542; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_DET1__VI = 0x4560; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_DET2__VI = 0x4561; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_DET3__VI = 0x4562; +constexpr unsigned int mmSCL5_SCL_MODE_CHANGE_MASK__VI = 0x4563; +constexpr unsigned int mmSCL5_SCL_ROUND_OFFSET__VI = 0x454F; +constexpr unsigned int mmSCL5_SCL_TAP_CONTROL__VI = 0x4543; +constexpr unsigned int mmSCL5_SCL_TEST_DEBUG_DATA__VI = 0x456C; +constexpr unsigned int mmSCL5_SCL_TEST_DEBUG_INDEX__VI = 0x456B; +constexpr unsigned int mmSCL5_SCL_UPDATE__VI = 0x4551; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_CONTROL__VI = 0x454B; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_INIT__VI = 0x454D; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_INIT_BOT__VI = 0x454E; +constexpr unsigned int mmSCL5_SCL_VERT_FILTER_SCALE_RATIO__VI = 0x454C; +constexpr unsigned int mmSCL5_VIEWPORT_SIZE__VI = 0x455D; +constexpr unsigned int mmSCL5_VIEWPORT_START__VI = 0x455C; +constexpr unsigned int mmSCL5_VIEWPORT_START_SECONDARY__VI = 0x455B; +constexpr unsigned int mmSCLK_CGTT_BLK_CTRL_REG__VI = 0x0136; +constexpr unsigned int mmSCLV_ALU_CONTROL__VI = 0x4685; +constexpr unsigned int mmSCLV_AUTOMATIC_MODE_CONTROL__VI = 0x4676; +constexpr unsigned int mmSCLV_COEF_RAM_SELECT__VI = 0x4670; +constexpr unsigned int mmSCLV_COEF_RAM_TAP_DATA__VI = 0x4671; +constexpr unsigned int mmSCLV_CONTROL__VI = 0x4674; +constexpr unsigned int mmSCLV_DEBUG__VI = 0x4693; +constexpr unsigned int mmSCLV_DEBUG2__VI = 0x4692; +constexpr unsigned int mmSCLV_EXT_OVERSCAN_LEFT_RIGHT__VI = 0x468C; +constexpr unsigned int mmSCLV_EXT_OVERSCAN_TOP_BOTTOM__VI = 0x468D; +constexpr unsigned int mmSCLV_HORZ_FILTER_CONTROL__VI = 0x4677; +constexpr unsigned int mmSCLV_HORZ_FILTER_INIT__VI = 0x4679; +constexpr unsigned int mmSCLV_HORZ_FILTER_INIT_C__VI = 0x467B; +constexpr unsigned int mmSCLV_HORZ_FILTER_SCALE_RATIO__VI = 0x4678; +constexpr unsigned int mmSCLV_HORZ_FILTER_SCALE_RATIO_C__VI = 0x467A; +constexpr unsigned int mmSCLV_MANUAL_REPLICATE_CONTROL__VI = 0x4675; +constexpr unsigned int mmSCLV_MODE__VI = 0x4672; +constexpr unsigned int mmSCLV_MODE_CHANGE_DET1__VI = 0x468E; +constexpr unsigned int mmSCLV_MODE_CHANGE_DET2__VI = 0x468F; +constexpr unsigned int mmSCLV_MODE_CHANGE_DET3__VI = 0x4690; +constexpr unsigned int mmSCLV_MODE_CHANGE_MASK__VI = 0x4691; +constexpr unsigned int mmSCLV_ROUND_OFFSET__VI = 0x4683; +constexpr unsigned int mmSCLV_TAP_CONTROL__VI = 0x4673; +constexpr unsigned int mmSCLV_TEST_DEBUG_DATA__VI = 0x4695; +constexpr unsigned int mmSCLV_TEST_DEBUG_INDEX__VI = 0x4694; +constexpr unsigned int mmSCLV_UPDATE__VI = 0x4684; +constexpr unsigned int mmSCLV_VERT_FILTER_CONTROL__VI = 0x467C; +constexpr unsigned int mmSCLV_VERT_FILTER_INIT__VI = 0x467E; +constexpr unsigned int mmSCLV_VERT_FILTER_INIT_BOT__VI = 0x467F; +constexpr unsigned int mmSCLV_VERT_FILTER_INIT_BOT_C__VI = 0x4682; +constexpr unsigned int mmSCLV_VERT_FILTER_INIT_C__VI = 0x4681; +constexpr unsigned int mmSCLV_VERT_FILTER_SCALE_RATIO__VI = 0x467D; +constexpr unsigned int mmSCLV_VERT_FILTER_SCALE_RATIO_C__VI = 0x4680; +constexpr unsigned int mmSCLV_VIEWPORT_SIZE__VI = 0x4688; +constexpr unsigned int mmSCLV_VIEWPORT_SIZE_C__VI = 0x468B; +constexpr unsigned int mmSCLV_VIEWPORT_START__VI = 0x4686; +constexpr unsigned int mmSCLV_VIEWPORT_START_C__VI = 0x4689; +constexpr unsigned int mmSCLV_VIEWPORT_START_SECONDARY__VI = 0x4687; +constexpr unsigned int mmSCLV_VIEWPORT_START_SECONDARY_C__VI = 0x468A; +constexpr unsigned int mmSCL_DEBUG2__VI = 0x1B69; +constexpr unsigned int mmSCL_HORZ_FILTER_CONTROL__VI = 0x1B48; +constexpr unsigned int mmSCL_HORZ_FILTER_INIT__VI = 0x1B4A; +constexpr unsigned int mmSCL_HORZ_FILTER_SCALE_RATIO__VI = 0x1B49; +constexpr unsigned int mmSCL_MODE__VI = 0x1B42; +constexpr unsigned int mmSCL_ROUND_OFFSET__VI = 0x1B4F; +constexpr unsigned int mmSCL_VERT_FILTER_CONTROL__VI = 0x1B4B; +constexpr unsigned int mmSCL_VERT_FILTER_INIT__VI = 0x1B4D; +constexpr unsigned int mmSCL_VERT_FILTER_INIT_BOT__VI = 0x1B4E; +constexpr unsigned int mmSCL_VERT_FILTER_SCALE_RATIO__VI = 0x1B4C; +constexpr unsigned int mmSDMA0_ACTIVE_FCN_ID__VI = 0x341F; +constexpr unsigned int mmSDMA0_ATOMIC_CNTL__VI = 0x342E; +constexpr unsigned int mmSDMA0_ATOMIC_PREOP_HI__VI = 0x3430; +constexpr unsigned int mmSDMA0_ATOMIC_PREOP_LO__VI = 0x342F; +constexpr unsigned int mmSDMA0_BA_THRESHOLD__VI = 0x342B; +constexpr unsigned int mmSDMA0_CONTEXT_REG_TYPE0__VI = 0x3478; +constexpr unsigned int mmSDMA0_CONTEXT_REG_TYPE1__VI = 0x3479; +constexpr unsigned int mmSDMA0_CONTEXT_REG_TYPE2__VI = 0x347A; +constexpr unsigned int mmSDMA0_EDC_CONFIG__VI = 0x341A; +constexpr unsigned int mmSDMA0_GFX_CSA_ADDR_HI__VI = 0x34AD; +constexpr unsigned int mmSDMA0_GFX_CSA_ADDR_LO__VI = 0x34AC; +constexpr unsigned int mmSDMA0_GFX_DOORBELL__VI = 0x3492; +constexpr unsigned int mmSDMA0_GFX_DOORBELL_LOG__VI = 0x34A9; +constexpr unsigned int mmSDMA0_GFX_DUMMY_REG__VI = 0x34B1; +constexpr unsigned int mmSDMA0_GFX_IB_SUB_REMAIN__VI = 0x34AF; +constexpr unsigned int mmSDMA0_GFX_MIDCMD_CNTL__VI = 0x34C7; +constexpr unsigned int mmSDMA0_GFX_MIDCMD_DATA0__VI = 0x34C1; +constexpr unsigned int mmSDMA0_GFX_MIDCMD_DATA1__VI = 0x34C2; +constexpr unsigned int mmSDMA0_GFX_MIDCMD_DATA2__VI = 0x34C3; +constexpr unsigned int mmSDMA0_GFX_MIDCMD_DATA3__VI = 0x34C4; +constexpr unsigned int mmSDMA0_GFX_MIDCMD_DATA4__VI = 0x34C5; +constexpr unsigned int mmSDMA0_GFX_MIDCMD_DATA5__VI = 0x34C6; +constexpr unsigned int mmSDMA0_GFX_PREEMPT__VI = 0x34B0; +constexpr unsigned int mmSDMA0_GFX_WATERMARK__VI = 0x34AA; +constexpr unsigned int mmSDMA0_ID__VI = 0x342C; +constexpr unsigned int mmSDMA0_PERFCOUNTER0_RESULT__VI = 0x9001; +constexpr unsigned int mmSDMA0_PERFCOUNTER1_RESULT__VI = 0x9002; +constexpr unsigned int mmSDMA0_PERFMON_CNTL__VI = 0x9000; +constexpr unsigned int mmSDMA0_PERF_REG_TYPE0__VI = 0x3477; +constexpr unsigned int mmSDMA0_POWER_CNTL_IDLE__VI = 0x342C; +constexpr unsigned int mmSDMA0_PUB_REG_TYPE0__VI = 0x347C; +constexpr unsigned int mmSDMA0_PUB_REG_TYPE1__VI = 0x347D; +constexpr unsigned int mmSDMA0_RD_BURST_CNTL__VI = 0x340F; +constexpr unsigned int mmSDMA0_RLC0_CSA_ADDR_HI__VI = 0x352D; +constexpr unsigned int mmSDMA0_RLC0_CSA_ADDR_LO__VI = 0x352C; +constexpr unsigned int mmSDMA0_RLC0_DUMMY_REG__VI = 0x3531; +constexpr unsigned int mmSDMA0_RLC0_IB_SUB_REMAIN__VI = 0x352F; +constexpr unsigned int mmSDMA0_RLC0_MIDCMD_CNTL__VI = 0x3547; +constexpr unsigned int mmSDMA0_RLC0_MIDCMD_DATA0__VI = 0x3541; +constexpr unsigned int mmSDMA0_RLC0_MIDCMD_DATA1__VI = 0x3542; +constexpr unsigned int mmSDMA0_RLC0_MIDCMD_DATA2__VI = 0x3543; +constexpr unsigned int mmSDMA0_RLC0_MIDCMD_DATA3__VI = 0x3544; +constexpr unsigned int mmSDMA0_RLC0_MIDCMD_DATA4__VI = 0x3545; +constexpr unsigned int mmSDMA0_RLC0_MIDCMD_DATA5__VI = 0x3546; +constexpr unsigned int mmSDMA0_RLC0_PREEMPT__VI = 0x3530; +constexpr unsigned int mmSDMA0_RLC0_WATERMARK__VI = 0x352A; +constexpr unsigned int mmSDMA0_RLC1_CSA_ADDR_HI__VI = 0x35AD; +constexpr unsigned int mmSDMA0_RLC1_CSA_ADDR_LO__VI = 0x35AC; +constexpr unsigned int mmSDMA0_RLC1_DUMMY_REG__VI = 0x35B1; +constexpr unsigned int mmSDMA0_RLC1_IB_SUB_REMAIN__VI = 0x35AF; +constexpr unsigned int mmSDMA0_RLC1_MIDCMD_CNTL__VI = 0x35C7; +constexpr unsigned int mmSDMA0_RLC1_MIDCMD_DATA0__VI = 0x35C1; +constexpr unsigned int mmSDMA0_RLC1_MIDCMD_DATA1__VI = 0x35C2; +constexpr unsigned int mmSDMA0_RLC1_MIDCMD_DATA2__VI = 0x35C3; +constexpr unsigned int mmSDMA0_RLC1_MIDCMD_DATA3__VI = 0x35C4; +constexpr unsigned int mmSDMA0_RLC1_MIDCMD_DATA4__VI = 0x35C5; +constexpr unsigned int mmSDMA0_RLC1_MIDCMD_DATA5__VI = 0x35C6; +constexpr unsigned int mmSDMA0_RLC1_PREEMPT__VI = 0x35B0; +constexpr unsigned int mmSDMA0_RLC1_WATERMARK__VI = 0x35AA; +constexpr unsigned int mmSDMA0_STATUS2_REG__VI = 0x341E; +constexpr unsigned int mmSDMA0_VERSION__VI = 0x342D; +constexpr unsigned int mmSDMA0_VF_ENABLE__VI = 0x342A; +constexpr unsigned int mmSDMA0_VIRT_RESET_REQ__VI = 0x3421; +constexpr unsigned int mmSDMA0_VM_CNTL__VI = 0x341B; +constexpr unsigned int mmSDMA0_VM_CTX_CNTL__VI = 0x3420; +constexpr unsigned int mmSDMA0_VM_CTX_HI__VI = 0x341D; +constexpr unsigned int mmSDMA0_VM_CTX_LO__VI = 0x341C; +constexpr unsigned int mmSDMA1_ACTIVE_FCN_ID__VI = 0x361F; +constexpr unsigned int mmSDMA1_ATOMIC_CNTL__VI = 0x362E; +constexpr unsigned int mmSDMA1_ATOMIC_PREOP_HI__VI = 0x3630; +constexpr unsigned int mmSDMA1_ATOMIC_PREOP_LO__VI = 0x362F; +constexpr unsigned int mmSDMA1_BA_THRESHOLD__VI = 0x362B; +constexpr unsigned int mmSDMA1_CONTEXT_REG_TYPE0__VI = 0x3678; +constexpr unsigned int mmSDMA1_CONTEXT_REG_TYPE1__VI = 0x3679; +constexpr unsigned int mmSDMA1_CONTEXT_REG_TYPE2__VI = 0x367A; +constexpr unsigned int mmSDMA1_EDC_CONFIG__VI = 0x361A; +constexpr unsigned int mmSDMA1_GFX_CSA_ADDR_HI__VI = 0x36AD; +constexpr unsigned int mmSDMA1_GFX_CSA_ADDR_LO__VI = 0x36AC; +constexpr unsigned int mmSDMA1_GFX_DOORBELL__VI = 0x3692; +constexpr unsigned int mmSDMA1_GFX_DOORBELL_LOG__VI = 0x36A9; +constexpr unsigned int mmSDMA1_GFX_DUMMY_REG__VI = 0x36B1; +constexpr unsigned int mmSDMA1_GFX_IB_SUB_REMAIN__VI = 0x36AF; +constexpr unsigned int mmSDMA1_GFX_MIDCMD_CNTL__VI = 0x36C7; +constexpr unsigned int mmSDMA1_GFX_MIDCMD_DATA0__VI = 0x36C1; +constexpr unsigned int mmSDMA1_GFX_MIDCMD_DATA1__VI = 0x36C2; +constexpr unsigned int mmSDMA1_GFX_MIDCMD_DATA2__VI = 0x36C3; +constexpr unsigned int mmSDMA1_GFX_MIDCMD_DATA3__VI = 0x36C4; +constexpr unsigned int mmSDMA1_GFX_MIDCMD_DATA4__VI = 0x36C5; +constexpr unsigned int mmSDMA1_GFX_MIDCMD_DATA5__VI = 0x36C6; +constexpr unsigned int mmSDMA1_GFX_PREEMPT__VI = 0x36B0; +constexpr unsigned int mmSDMA1_GFX_WATERMARK__VI = 0x36AA; +constexpr unsigned int mmSDMA1_ID__VI = 0x362C; +constexpr unsigned int mmSDMA1_PERFCOUNTER0_RESULT__VI = 0x9011; +constexpr unsigned int mmSDMA1_PERFCOUNTER1_RESULT__VI = 0x9012; +constexpr unsigned int mmSDMA1_PERFMON_CNTL__VI = 0x9010; +constexpr unsigned int mmSDMA1_PERF_REG_TYPE0__VI = 0x3677; +constexpr unsigned int mmSDMA1_POWER_CNTL_IDLE__VI = 0x362C; +constexpr unsigned int mmSDMA1_PUB_REG_TYPE0__VI = 0x367C; +constexpr unsigned int mmSDMA1_PUB_REG_TYPE1__VI = 0x367D; +constexpr unsigned int mmSDMA1_RD_BURST_CNTL__VI = 0x360F; +constexpr unsigned int mmSDMA1_RLC0_CSA_ADDR_HI__VI = 0x372D; +constexpr unsigned int mmSDMA1_RLC0_CSA_ADDR_LO__VI = 0x372C; +constexpr unsigned int mmSDMA1_RLC0_DUMMY_REG__VI = 0x3731; +constexpr unsigned int mmSDMA1_RLC0_IB_SUB_REMAIN__VI = 0x372F; +constexpr unsigned int mmSDMA1_RLC0_MIDCMD_CNTL__VI = 0x3747; +constexpr unsigned int mmSDMA1_RLC0_MIDCMD_DATA0__VI = 0x3741; +constexpr unsigned int mmSDMA1_RLC0_MIDCMD_DATA1__VI = 0x3742; +constexpr unsigned int mmSDMA1_RLC0_MIDCMD_DATA2__VI = 0x3743; +constexpr unsigned int mmSDMA1_RLC0_MIDCMD_DATA3__VI = 0x3744; +constexpr unsigned int mmSDMA1_RLC0_MIDCMD_DATA4__VI = 0x3745; +constexpr unsigned int mmSDMA1_RLC0_MIDCMD_DATA5__VI = 0x3746; +constexpr unsigned int mmSDMA1_RLC0_PREEMPT__VI = 0x3730; +constexpr unsigned int mmSDMA1_RLC0_WATERMARK__VI = 0x372A; +constexpr unsigned int mmSDMA1_RLC1_CSA_ADDR_HI__VI = 0x37AD; +constexpr unsigned int mmSDMA1_RLC1_CSA_ADDR_LO__VI = 0x37AC; +constexpr unsigned int mmSDMA1_RLC1_DUMMY_REG__VI = 0x37B1; +constexpr unsigned int mmSDMA1_RLC1_IB_SUB_REMAIN__VI = 0x37AF; +constexpr unsigned int mmSDMA1_RLC1_MIDCMD_CNTL__VI = 0x37C7; +constexpr unsigned int mmSDMA1_RLC1_MIDCMD_DATA0__VI = 0x37C1; +constexpr unsigned int mmSDMA1_RLC1_MIDCMD_DATA1__VI = 0x37C2; +constexpr unsigned int mmSDMA1_RLC1_MIDCMD_DATA2__VI = 0x37C3; +constexpr unsigned int mmSDMA1_RLC1_MIDCMD_DATA3__VI = 0x37C4; +constexpr unsigned int mmSDMA1_RLC1_MIDCMD_DATA4__VI = 0x37C5; +constexpr unsigned int mmSDMA1_RLC1_MIDCMD_DATA5__VI = 0x37C6; +constexpr unsigned int mmSDMA1_RLC1_PREEMPT__VI = 0x37B0; +constexpr unsigned int mmSDMA1_RLC1_WATERMARK__VI = 0x37AA; +constexpr unsigned int mmSDMA1_STATUS2_REG__VI = 0x361E; +constexpr unsigned int mmSDMA1_VERSION__VI = 0x362D; +constexpr unsigned int mmSDMA1_VF_ENABLE__VI = 0x362A; +constexpr unsigned int mmSDMA1_VIRT_RESET_REQ__VI = 0x3621; +constexpr unsigned int mmSDMA1_VM_CNTL__VI = 0x361B; +constexpr unsigned int mmSDMA1_VM_CTX_CNTL__VI = 0x3620; +constexpr unsigned int mmSDMA1_VM_CTX_HI__VI = 0x361D; +constexpr unsigned int mmSDMA1_VM_CTX_LO__VI = 0x361C; +constexpr unsigned int mmSEM_ACTIVE_FCN_ID__VI = 0x0F97; +constexpr unsigned int mmSEM_MAILBOX_CLIENTCONFIG_EXTRA__VI = 0x0F9F; +constexpr unsigned int mmSEM_PERFCOUNTER0_RESULT__VI = 0x0F92; +constexpr unsigned int mmSEM_PERFCOUNTER1_RESULT__VI = 0x0F93; +constexpr unsigned int mmSEM_PERFMON_CNTL__VI = 0x0F91; +constexpr unsigned int mmSEM_VF_ENABLE__VI = 0x0F95; +constexpr unsigned int mmSEM_VIRT_RESET_REQ__VI = 0x0F98; +constexpr unsigned int mmSE_CAC_CGTT_CLK_CTRL__VI = 0x3293; +constexpr unsigned int mmSMBCLK_PAD_CNTL__VI = 0x15ED; +constexpr unsigned int mmSMBDAT_PAD_CNTL__VI = 0x15EC; +constexpr unsigned int mmSMBUS_BACO_DUMMY__VI = 0x15EB; +constexpr unsigned int mmSMC_MSG_ARG_11__VI = 0x0093; +constexpr unsigned int mmSMU_BIF_VDDGFX_PWR_STATUS__VI = 0x14F8; +constexpr unsigned int mmSMU_CONTROL__VI = 0x012D; +constexpr unsigned int mmSMU_IND_DATA_0__VI = 0x01A7; +constexpr unsigned int mmSMU_IND_DATA_1__VI = 0x01A9; +constexpr unsigned int mmSMU_IND_DATA_2__VI = 0x01AB; +constexpr unsigned int mmSMU_IND_DATA_3__VI = 0x01AD; +constexpr unsigned int mmSMU_IND_DATA_4__VI = 0x01AF; +constexpr unsigned int mmSMU_IND_DATA_5__VI = 0x01B1; +constexpr unsigned int mmSMU_IND_DATA_6__VI = 0x01B3; +constexpr unsigned int mmSMU_IND_DATA_7__VI = 0x01B5; +constexpr unsigned int mmSMU_IND_INDEX_0__VI = 0x01A6; +constexpr unsigned int mmSMU_IND_INDEX_1__VI = 0x01A8; +constexpr unsigned int mmSMU_IND_INDEX_2__VI = 0x01AA; +constexpr unsigned int mmSMU_IND_INDEX_3__VI = 0x01AC; +constexpr unsigned int mmSMU_IND_INDEX_4__VI = 0x01AE; +constexpr unsigned int mmSMU_IND_INDEX_5__VI = 0x01B0; +constexpr unsigned int mmSMU_IND_INDEX_6__VI = 0x01B2; +constexpr unsigned int mmSMU_IND_INDEX_7__VI = 0x01B4; +constexpr unsigned int mmSMU_INTERRUPT_CONTROL__VI = 0x012E; +constexpr unsigned int mmSMU_MP1_RLC2MP_RESP__VI = 0x01F4; +constexpr unsigned int mmSMU_MP1_SRBM2P_MSG_5__VI = 0x01C5; +constexpr unsigned int mmSMU_RLC_RESPONSE__VI = 0xEC07; +constexpr unsigned int mmSM_CONTROL2__VI = 0x1B6E; +constexpr unsigned int mmSPI_COMPUTE_WF_CTX_SAVE__VI = 0x31FC; +constexpr unsigned int mmSPI_CONFIG_CNTL_2__VI = 0x2451; +constexpr unsigned int mmSPI_DSM_CNTL__VI = 0x2443; +constexpr unsigned int mmSPI_EDC_CNT__VI = 0x2444; +constexpr unsigned int mmSPI_GFX_CNTL__VI = 0x243C; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_12__VI = 0x31F4; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_13__VI = 0x31F5; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_14__VI = 0x31F6; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_CU_15__VI = 0x31F7; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_12__VI = 0x31F8; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_13__VI = 0x31F9; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_14__VI = 0x31FA; +constexpr unsigned int mmSPI_RESOURCE_RESERVE_EN_CU_15__VI = 0x31FB; +constexpr unsigned int mmSPI_START_PHASE__VI = 0x243B; +constexpr unsigned int mmSQC_ATC_EDC_GATCL1_CNT__VI = 0x23B3; +constexpr unsigned int mmSQC_DSM_CNTL__VI = 0x230F; +constexpr unsigned int mmSQC_EDC_CNT__VI = 0x23A0; +constexpr unsigned int mmSQC_GATCL1_CNTL__VI = 0x23B2; +constexpr unsigned int mmSQC_WRITEBACK__VI = 0xC349; +constexpr unsigned int mmSQ_DSM_CNTL__VI = 0x2306; +constexpr unsigned int mmSQ_EDC_DED_CNT__VI = 0x23A2; +constexpr unsigned int mmSQ_EDC_INFO__VI = 0x23A3; +constexpr unsigned int mmSQ_EDC_SEC_CNT__VI = 0x23A1; +constexpr unsigned int mmSQ_M0_GPR_IDX_WORD__VI = 0x23D2; +constexpr unsigned int mmSQ_SMEM_0__VI = 0x237F; +constexpr unsigned int mmSQ_SMEM_1__VI = 0x237F; +constexpr unsigned int mmSQ_THREAD_TRACE_BASE__SI__CI = 0x2380; +constexpr unsigned int mmSQ_THREAD_TRACE_BASE__VI = 0xC330; +constexpr unsigned int mmSQ_THREAD_TRACE_BASE2__VI = 0xC337; +constexpr unsigned int mmSQ_THREAD_TRACE_CTRL__SI__CI = 0x238F; +constexpr unsigned int mmSQ_THREAD_TRACE_CTRL__VI = 0xC335; +constexpr unsigned int mmSQ_THREAD_TRACE_HIWATER__SI__CI = 0x2392; +constexpr unsigned int mmSQ_THREAD_TRACE_HIWATER__VI = 0xC33B; +constexpr unsigned int mmSQ_THREAD_TRACE_MASK__SI__CI = 0x2382; +constexpr unsigned int mmSQ_THREAD_TRACE_MASK__VI = 0xC332; +constexpr unsigned int mmSQ_THREAD_TRACE_MODE__SI__CI = 0x238E; +constexpr unsigned int mmSQ_THREAD_TRACE_MODE__VI = 0xC336; +constexpr unsigned int mmSQ_THREAD_TRACE_PERF_MASK__SI__CI = 0x2384; +constexpr unsigned int mmSQ_THREAD_TRACE_PERF_MASK__VI = 0xC334; +constexpr unsigned int mmSQ_THREAD_TRACE_SIZE__SI__CI = 0x2381; +constexpr unsigned int mmSQ_THREAD_TRACE_SIZE__VI = 0xC331; +constexpr unsigned int mmSQ_THREAD_TRACE_STATUS__SI__CI = 0x238D; +constexpr unsigned int mmSQ_THREAD_TRACE_STATUS__VI = 0xC33A; +constexpr unsigned int mmSQ_THREAD_TRACE_TOKEN_MASK__SI__CI = 0x2383; +constexpr unsigned int mmSQ_THREAD_TRACE_TOKEN_MASK__VI = 0xC333; +constexpr unsigned int mmSQ_THREAD_TRACE_TOKEN_MASK2__VI = 0xC338; +constexpr unsigned int mmSQ_THREAD_TRACE_WPTR__SI__CI = 0x238C; +constexpr unsigned int mmSQ_THREAD_TRACE_WPTR__VI = 0xC339; +constexpr unsigned int mmSQ_VOP_DPP__VI = 0x237F; +constexpr unsigned int mmSQ_VOP_SDWA__VI = 0x237F; +constexpr unsigned int mmSQ_WREXEC_EXEC_HI__VI = 0x23B1; +constexpr unsigned int mmSQ_WREXEC_EXEC_LO__VI = 0x23B1; +constexpr unsigned int mmSRBM_CAM_DATA__SI__CI = 0x0397; +constexpr unsigned int mmSRBM_CAM_DATA__VI = 0xFE35; +constexpr unsigned int mmSRBM_CAM_INDEX__SI__CI = 0x0396; +constexpr unsigned int mmSRBM_CAM_INDEX__VI = 0xFE34; +constexpr unsigned int mmSRBM_CREDIT_RECOVER__VI = 0x039D; +constexpr unsigned int mmSRBM_CREDIT_RECOVER_CNTL__VI = 0x039C; +constexpr unsigned int mmSRBM_CREDIT_RESET__VI = 0x039E; +constexpr unsigned int mmSRBM_DEBUG_SNAPSHOT2__VI = 0x03AD; +constexpr unsigned int mmSRBM_DSM_TRIG_CNTL0__VI = 0x03AF; +constexpr unsigned int mmSRBM_DSM_TRIG_CNTL1__VI = 0x03B0; +constexpr unsigned int mmSRBM_DSM_TRIG_MASK0__VI = 0x03B1; +constexpr unsigned int mmSRBM_DSM_TRIG_MASK1__VI = 0x03B2; +constexpr unsigned int mmSRBM_FIREWALL_ERROR_ADDR__VI = 0x03AC; +constexpr unsigned int mmSRBM_FIREWALL_ERROR_SRC__VI = 0x03AB; +constexpr unsigned int mmSRBM_GFX_CNTL_DATA__VI = 0xFA2F; +constexpr unsigned int mmSRBM_GFX_CNTL_SELECT__VI = 0xFA2E; +constexpr unsigned int mmSRBM_ISP_CLKEN_CNTL__VI = 0x03B9; +constexpr unsigned int mmSRBM_ISP_DOMAIN_ADDR0__VI = 0xFA20; +constexpr unsigned int mmSRBM_ISP_DOMAIN_ADDR1__VI = 0xFA21; +constexpr unsigned int mmSRBM_ISP_DOMAIN_ADDR2__VI = 0xFA22; +constexpr unsigned int mmSRBM_MC_DOMAIN_ADDR0__VI = 0xFA00; +constexpr unsigned int mmSRBM_MC_DOMAIN_ADDR1__VI = 0xFA01; +constexpr unsigned int mmSRBM_MC_DOMAIN_ADDR2__VI = 0xFA02; +constexpr unsigned int mmSRBM_MC_DOMAIN_ADDR3__VI = 0xFA03; +constexpr unsigned int mmSRBM_MC_DOMAIN_ADDR4__VI = 0xFA04; +constexpr unsigned int mmSRBM_MC_DOMAIN_ADDR5__VI = 0xFA05; +constexpr unsigned int mmSRBM_MC_DOMAIN_ADDR6__VI = 0xFA06; +constexpr unsigned int mmSRBM_PERFCOUNTER0_HI__SI__CI = 0x0704; +constexpr unsigned int mmSRBM_PERFCOUNTER0_HI__VI = 0x7C04; +constexpr unsigned int mmSRBM_PERFCOUNTER0_LO__SI__CI = 0x0703; +constexpr unsigned int mmSRBM_PERFCOUNTER0_LO__VI = 0x7C03; +constexpr unsigned int mmSRBM_PERFCOUNTER0_SELECT__SI__CI = 0x0701; +constexpr unsigned int mmSRBM_PERFCOUNTER0_SELECT__VI = 0x7C01; +constexpr unsigned int mmSRBM_PERFCOUNTER1_HI__SI__CI = 0x0706; +constexpr unsigned int mmSRBM_PERFCOUNTER1_HI__VI = 0x7C06; +constexpr unsigned int mmSRBM_PERFCOUNTER1_LO__SI__CI = 0x0705; +constexpr unsigned int mmSRBM_PERFCOUNTER1_LO__VI = 0x7C05; +constexpr unsigned int mmSRBM_PERFCOUNTER1_SELECT__SI__CI = 0x0702; +constexpr unsigned int mmSRBM_PERFCOUNTER1_SELECT__VI = 0x7C02; +constexpr unsigned int mmSRBM_PERFMON_CNTL__SI__CI = 0x0700; +constexpr unsigned int mmSRBM_PERFMON_CNTL__VI = 0x7C00; +constexpr unsigned int mmSRBM_READ_CNTL__VI = 0x0392; +constexpr unsigned int mmSRBM_READ_ERROR2__VI = 0x03AE; +constexpr unsigned int mmSRBM_SAM_DOMAIN_ADDR0__VI = 0xFA1C; +constexpr unsigned int mmSRBM_SAM_DOMAIN_ADDR1__VI = 0xFA1D; +constexpr unsigned int mmSRBM_SAM_DOMAIN_ADDR2__VI = 0xFA1E; +constexpr unsigned int mmSRBM_SDMA_DOMAIN_ADDR0__VI = 0xFA10; +constexpr unsigned int mmSRBM_SDMA_DOMAIN_ADDR1__VI = 0xFA11; +constexpr unsigned int mmSRBM_SDMA_DOMAIN_ADDR2__VI = 0xFA12; +constexpr unsigned int mmSRBM_SDMA_DOMAIN_ADDR3__VI = 0xFA13; +constexpr unsigned int mmSRBM_STATUS3__VI = 0x0395; +constexpr unsigned int mmSRBM_SYS_DOMAIN_ADDR0__VI = 0xFA08; +constexpr unsigned int mmSRBM_SYS_DOMAIN_ADDR1__VI = 0xFA09; +constexpr unsigned int mmSRBM_SYS_DOMAIN_ADDR2__VI = 0xFA0A; +constexpr unsigned int mmSRBM_SYS_DOMAIN_ADDR3__VI = 0xFA0B; +constexpr unsigned int mmSRBM_SYS_DOMAIN_ADDR4__VI = 0xFA0C; +constexpr unsigned int mmSRBM_SYS_DOMAIN_ADDR5__VI = 0xFA0D; +constexpr unsigned int mmSRBM_SYS_DOMAIN_ADDR6__VI = 0xFA0E; +constexpr unsigned int mmSRBM_UVD_DOMAIN_ADDR0__VI = 0xFA14; +constexpr unsigned int mmSRBM_UVD_DOMAIN_ADDR1__VI = 0xFA15; +constexpr unsigned int mmSRBM_UVD_DOMAIN_ADDR2__VI = 0xFA16; +constexpr unsigned int mmSRBM_VCE_DOMAIN_ADDR0__VI = 0xFA18; +constexpr unsigned int mmSRBM_VCE_DOMAIN_ADDR1__VI = 0xFA19; +constexpr unsigned int mmSRBM_VCE_DOMAIN_ADDR2__VI = 0xFA1A; +constexpr unsigned int mmSRBM_VF_ENABLE__VI = 0xFA30; +constexpr unsigned int mmSRBM_VIRT_CNTL__VI = 0xFA31; +constexpr unsigned int mmSRBM_VIRT_RESET_REQ__VI = 0xFA32; +constexpr unsigned int mmSRBM_VP8_CLKEN_CNTL__VI = 0x03BA; +constexpr unsigned int mmSRBM_VP8_DOMAIN_ADDR0__VI = 0xFA24; +constexpr unsigned int mmSWRST_COMMAND_0__VI = 0x14A2; +constexpr unsigned int mmSWRST_COMMAND_1__VI = 0x14A3; +constexpr unsigned int mmSWRST_COMMAND_STATUS__VI = 0x14A0; +constexpr unsigned int mmSWRST_CONTROL_0__VI = 0x14A4; +constexpr unsigned int mmSWRST_CONTROL_1__VI = 0x14A5; +constexpr unsigned int mmSWRST_CONTROL_2__VI = 0x14A6; +constexpr unsigned int mmSWRST_CONTROL_3__VI = 0x14A7; +constexpr unsigned int mmSWRST_CONTROL_4__VI = 0x14A8; +constexpr unsigned int mmSWRST_CONTROL_5__VI = 0x14A9; +constexpr unsigned int mmSWRST_CONTROL_6__VI = 0x14AA; +constexpr unsigned int mmSWRST_EP_COMMAND_0__VI = 0x14AB; +constexpr unsigned int mmSWRST_EP_CONTROL_0__VI = 0x14AC; +constexpr unsigned int mmSWRST_GENERAL_CONTROL__VI = 0x14A1; +constexpr unsigned int mmSX_BLEND_OPT_CONTROL__VI = 0xA1D7; +constexpr unsigned int mmSX_BLEND_OPT_EPSILON__VI = 0xA1D6; +constexpr unsigned int mmSX_MRT0_BLEND_OPT__VI = 0xA1D8; +constexpr unsigned int mmSX_MRT1_BLEND_OPT__VI = 0xA1D9; +constexpr unsigned int mmSX_MRT2_BLEND_OPT__VI = 0xA1DA; +constexpr unsigned int mmSX_MRT3_BLEND_OPT__VI = 0xA1DB; +constexpr unsigned int mmSX_MRT4_BLEND_OPT__VI = 0xA1DC; +constexpr unsigned int mmSX_MRT5_BLEND_OPT__VI = 0xA1DD; +constexpr unsigned int mmSX_MRT6_BLEND_OPT__VI = 0xA1DE; +constexpr unsigned int mmSX_MRT7_BLEND_OPT__VI = 0xA1DF; +constexpr unsigned int mmSX_PS_DOWNCONVERT__VI = 0xA1D5; +constexpr unsigned int mmSYMCLKA_CLOCK_ENABLE__VI = 0x0160; +constexpr unsigned int mmSYMCLKB_CLOCK_ENABLE__VI = 0x0161; +constexpr unsigned int mmSYMCLKC_CLOCK_ENABLE__VI = 0x0162; +constexpr unsigned int mmSYMCLKD_CLOCK_ENABLE__VI = 0x0163; +constexpr unsigned int mmSYMCLKE_CLOCK_ENABLE__VI = 0x0164; +constexpr unsigned int mmSYMCLKF_CLOCK_ENABLE__VI = 0x0165; +constexpr unsigned int mmSYMCLKG_CLOCK_ENABLE__VI = 0x0117; +constexpr unsigned int mmSYS_GRBM_GFX_INDEX_DATA__VI = 0xFA2D; +constexpr unsigned int mmSYS_GRBM_GFX_INDEX_SELECT__VI = 0xFA2C; +constexpr unsigned int mmTCC_DSM_CNTL__VI = 0x2B85; +constexpr unsigned int mmTCC_EDC_CNT__VI = 0x2B82; +constexpr unsigned int mmTCC_EXE_DISABLE__VI = 0x2B84; +constexpr unsigned int mmTCP_ATC_EDC_GATCL1_CNT__VI = 0x32B1; +constexpr unsigned int mmTCP_CNTL2__VI = 0x32B4; +constexpr unsigned int mmTCP_DSM_CNTL__VI = 0x32B3; +constexpr unsigned int mmTCP_EDC_CNT__VI = 0x2B17; +constexpr unsigned int mmTCP_GATCL1_CNTL__VI = 0x32B0; +constexpr unsigned int mmTCP_GATCL1_DSM_CNTL__VI = 0x32B2; +constexpr unsigned int mmTD_DSM_CNTL__VI = 0x252F; +constexpr unsigned int mmTMDS_CNTL__VI = 0x4A6B; +constexpr unsigned int mmTMDS_CONTROL0_FEEDBACK__VI = 0x4A6D; +constexpr unsigned int mmTMDS_CONTROL_CHAR__VI = 0x4A6C; +constexpr unsigned int mmTMDS_CTL0_1_GEN_CNTL__VI = 0x4A75; +constexpr unsigned int mmTMDS_CTL2_3_GEN_CNTL__VI = 0x4A76; +constexpr unsigned int mmTMDS_CTL_BITS__VI = 0x4A72; +constexpr unsigned int mmTMDS_DCBALANCER_CONTROL__VI = 0x4A73; +constexpr unsigned int mmTMDS_DEBUG__VI = 0x4A71; +constexpr unsigned int mmTMDS_STEREOSYNC_CTL_SEL__VI = 0x4A6E; +constexpr unsigned int mmTMDS_SYNC_CHAR_PATTERN_0_1__VI = 0x4A6F; +constexpr unsigned int mmTMDS_SYNC_CHAR_PATTERN_2_3__VI = 0x4A70; +constexpr unsigned int mmUNIPHYA_CHANNEL_XBAR_CNTL__VI = 0x4806; +constexpr unsigned int mmUNIPHYA_LINK_CNTL__VI = 0x4805; +constexpr unsigned int mmUNIPHYB_CHANNEL_XBAR_CNTL__VI = 0x4808; +constexpr unsigned int mmUNIPHYB_LINK_CNTL__VI = 0x4807; +constexpr unsigned int mmUNIPHYC_CHANNEL_XBAR_CNTL__VI = 0x480A; +constexpr unsigned int mmUNIPHYC_LINK_CNTL__VI = 0x4809; +constexpr unsigned int mmUNIPHYD_CHANNEL_XBAR_CNTL__VI = 0x480C; +constexpr unsigned int mmUNIPHYD_LINK_CNTL__VI = 0x480B; +constexpr unsigned int mmUNIPHYE_CHANNEL_XBAR_CNTL__VI = 0x480E; +constexpr unsigned int mmUNIPHYE_LINK_CNTL__VI = 0x480D; +constexpr unsigned int mmUNIPHYF_CHANNEL_XBAR_CNTL__VI = 0x4810; +constexpr unsigned int mmUNIPHYF_LINK_CNTL__VI = 0x480F; +constexpr unsigned int mmUNIPHYG_CHANNEL_XBAR_CNTL__VI = 0x4812; +constexpr unsigned int mmUNIPHYG_LINK_CNTL__VI = 0x4811; +constexpr unsigned int mmUNIPHY_ANG_BIST_CNTL__VI = 0x48CC; +constexpr unsigned int mmUNIPHY_DATA_SYNCHRONIZATION__VI = 0x48CA; +constexpr unsigned int mmUNIPHY_DEBUG__VI = 0x48D6; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKA__VI = 0x4838; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKB__VI = 0x4839; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKC__VI = 0x483F; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKD__VI = 0x4840; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKE__VI = 0x4843; +constexpr unsigned int mmUNIPHY_IMPCAL_LINKF__VI = 0x4844; +constexpr unsigned int mmUNIPHY_IMPCAL_PERIOD__VI = 0x483A; +constexpr unsigned int mmUNIPHY_IMPCAL_PSW_AB__VI = 0x483E; +constexpr unsigned int mmUNIPHY_IMPCAL_PSW_CD__VI = 0x4842; +constexpr unsigned int mmUNIPHY_IMPCAL_PSW_EF__VI = 0x4846; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED0__VI = 0x48C0; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED1__VI = 0x48C1; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED10__VI = 0x48CA; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED11__VI = 0x48CB; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED12__VI = 0x48CC; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED13__VI = 0x48CD; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED14__VI = 0x48CE; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED15__VI = 0x48CF; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED16__VI = 0x48D0; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED17__VI = 0x48D1; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED18__VI = 0x48D2; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED19__VI = 0x48D3; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED2__VI = 0x48C2; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED20__VI = 0x48D4; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED21__VI = 0x48D5; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED22__VI = 0x48D6; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED23__VI = 0x48D7; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED24__VI = 0x48D8; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED25__VI = 0x48D9; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED26__VI = 0x48DA; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED27__VI = 0x48DB; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED28__VI = 0x48DC; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED29__VI = 0x48DD; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED3__VI = 0x48C3; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED30__VI = 0x48DE; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED31__VI = 0x48DF; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED4__VI = 0x48C4; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED5__VI = 0x48C5; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED6__VI = 0x48C6; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED7__VI = 0x48C7; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED8__VI = 0x48C8; +constexpr unsigned int mmUNIPHY_MACRO_CNTL_RESERVED9__VI = 0x48C9; +constexpr unsigned int mmUNIPHY_PLL_CONTROL1__VI = 0x48C6; +constexpr unsigned int mmUNIPHY_PLL_CONTROL2__VI = 0x48C7; +constexpr unsigned int mmUNIPHY_PLL_FBDIV__VI = 0x48C5; +constexpr unsigned int mmUNIPHY_PLL_SS_CNTL__VI = 0x48C9; +constexpr unsigned int mmUNIPHY_PLL_SS_STEP_SIZE__VI = 0x48C8; +constexpr unsigned int mmUNIPHY_POWER_CONTROL__VI = 0x48C4; +constexpr unsigned int mmUNIPHY_REG_TEST_OUTPUT__VI = 0x48CB; +constexpr unsigned int mmUNIPHY_REG_TEST_OUTPUT2__VI = 0x48CD; +constexpr unsigned int mmUNIPHY_TPG_CONTROL__VI = 0x48D4; +constexpr unsigned int mmUNIPHY_TPG_SEED__VI = 0x48D5; +constexpr unsigned int mmUNIPHY_TX_CONTROL1__VI = 0x48C0; +constexpr unsigned int mmUNIPHY_TX_CONTROL2__VI = 0x48C1; +constexpr unsigned int mmUNIPHY_TX_CONTROL3__VI = 0x48C2; +constexpr unsigned int mmUNIPHY_TX_CONTROL4__VI = 0x48C3; +constexpr unsigned int mmUNP_CRC_CONTROL__VI = 0x4630; +constexpr unsigned int mmUNP_CRC_CURRENT__VI = 0x4632; +constexpr unsigned int mmUNP_CRC_LAST__VI = 0x4633; +constexpr unsigned int mmUNP_CRC_MASK__VI = 0x4631; +constexpr unsigned int mmUNP_DEBUG__VI = 0x4636; +constexpr unsigned int mmUNP_DEBUG2__VI = 0x4637; +constexpr unsigned int mmUNP_GRPH_CONTROL__VI = 0x4601; +constexpr unsigned int mmUNP_GRPH_CONTROL_EXP__VI = 0x4603; +constexpr unsigned int mmUNP_GRPH_DFQ_CONTROL__VI = 0x4629; +constexpr unsigned int mmUNP_GRPH_DFQ_STATUS__VI = 0x462A; +constexpr unsigned int mmUNP_GRPH_ENABLE__VI = 0x4600; +constexpr unsigned int mmUNP_GRPH_FLIP_RATE_CNTL__VI = 0x462F; +constexpr unsigned int mmUNP_GRPH_INTERRUPT_CONTROL__VI = 0x462C; +constexpr unsigned int mmUNP_GRPH_INTERRUPT_STATUS__VI = 0x462B; +constexpr unsigned int mmUNP_GRPH_PITCH_C__VI = 0x4617; +constexpr unsigned int mmUNP_GRPH_PITCH_L__VI = 0x4616; +constexpr unsigned int mmUNP_GRPH_PRIMARY_BOTTOM_SURFACE_ADDRESS_C__VI = 0x460B; +constexpr unsigned int mmUNP_GRPH_PRIMARY_BOTTOM_SURFACE_ADDRESS_HIGH_C__VI = 0x460D; +constexpr unsigned int mmUNP_GRPH_PRIMARY_BOTTOM_SURFACE_ADDRESS_HIGH_L__VI = 0x460C; +constexpr unsigned int mmUNP_GRPH_PRIMARY_BOTTOM_SURFACE_ADDRESS_L__VI = 0x460A; +constexpr unsigned int mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__VI = 0x4607; +constexpr unsigned int mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__VI = 0x4609; +constexpr unsigned int mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__VI = 0x4608; +constexpr unsigned int mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__VI = 0x4606; +constexpr unsigned int mmUNP_GRPH_SECONDARY_BOTTOM_SURFACE_ADDRESS_C__VI = 0x4613; +constexpr unsigned int mmUNP_GRPH_SECONDARY_BOTTOM_SURFACE_ADDRESS_HIGH_C__VI = 0x4615; +constexpr unsigned int mmUNP_GRPH_SECONDARY_BOTTOM_SURFACE_ADDRESS_HIGH_L__VI = 0x4614; +constexpr unsigned int mmUNP_GRPH_SECONDARY_BOTTOM_SURFACE_ADDRESS_L__VI = 0x4612; +constexpr unsigned int mmUNP_GRPH_SECONDARY_SURFACE_ADDRESS_C__VI = 0x460F; +constexpr unsigned int mmUNP_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH_C__VI = 0x4611; +constexpr unsigned int mmUNP_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH_L__VI = 0x4610; +constexpr unsigned int mmUNP_GRPH_SECONDARY_SURFACE_ADDRESS_L__VI = 0x460E; +constexpr unsigned int mmUNP_GRPH_STEREOSYNC_FLIP__VI = 0x462E; +constexpr unsigned int mmUNP_GRPH_SURFACE_ADDRESS_HIGH_INUSE_C__VI = 0x4628; +constexpr unsigned int mmUNP_GRPH_SURFACE_ADDRESS_HIGH_INUSE_L__VI = 0x4627; +constexpr unsigned int mmUNP_GRPH_SURFACE_ADDRESS_INUSE_C__VI = 0x4626; +constexpr unsigned int mmUNP_GRPH_SURFACE_ADDRESS_INUSE_L__VI = 0x4625; +constexpr unsigned int mmUNP_GRPH_SURFACE_OFFSET_X_C__VI = 0x4619; +constexpr unsigned int mmUNP_GRPH_SURFACE_OFFSET_X_L__VI = 0x4618; +constexpr unsigned int mmUNP_GRPH_SURFACE_OFFSET_Y_C__VI = 0x461B; +constexpr unsigned int mmUNP_GRPH_SURFACE_OFFSET_Y_L__VI = 0x461A; +constexpr unsigned int mmUNP_GRPH_SWAP_CNTL__VI = 0x4605; +constexpr unsigned int mmUNP_GRPH_UPDATE__VI = 0x4624; +constexpr unsigned int mmUNP_GRPH_X_END_C__VI = 0x4621; +constexpr unsigned int mmUNP_GRPH_X_END_L__VI = 0x4620; +constexpr unsigned int mmUNP_GRPH_X_START_C__VI = 0x461D; +constexpr unsigned int mmUNP_GRPH_X_START_L__VI = 0x461C; +constexpr unsigned int mmUNP_GRPH_Y_END_C__VI = 0x4623; +constexpr unsigned int mmUNP_GRPH_Y_END_L__VI = 0x4622; +constexpr unsigned int mmUNP_GRPH_Y_START_C__VI = 0x461F; +constexpr unsigned int mmUNP_GRPH_Y_START_L__VI = 0x461E; +constexpr unsigned int mmUNP_HW_ROTATION__VI = 0x4635; +constexpr unsigned int mmUNP_LB_DATA_GAP_BETWEEN_CHUNK__VI = 0x4634; +constexpr unsigned int mmUNP_TEST_DEBUG_DATA__VI = 0x4639; +constexpr unsigned int mmUNP_TEST_DEBUG_INDEX__VI = 0x4638; +constexpr unsigned int mmUVD_CGC_UDEC_STATUS__VI = 0x3D2D; +constexpr unsigned int mmUVD_JPEG_ADDR_CONFIG__VI = 0x3A1F; +constexpr unsigned int mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH__VI = 0x3C66; +constexpr unsigned int mmUVD_LMI_RBC_IB_64BIT_BAR_LOW__VI = 0x3C67; +constexpr unsigned int mmUVD_LMI_RBC_IB_VMID__VI = 0x3DA1; +constexpr unsigned int mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH__VI = 0x3C68; +constexpr unsigned int mmUVD_LMI_RBC_RB_64BIT_BAR_LOW__VI = 0x3C69; +constexpr unsigned int mmUVD_LMI_RBC_RB_VMID__VI = 0x3DA3; +constexpr unsigned int mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH__VI = 0x3C5E; +constexpr unsigned int mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW__VI = 0x3C5F; +constexpr unsigned int mmUVD_MIF_CURR_ADDR_CONFIG__VI = 0x3992; +constexpr unsigned int mmUVD_MIF_RECON1_ADDR_CONFIG__VI = 0x39C5; +constexpr unsigned int mmUVD_MIF_REF_ADDR_CONFIG__VI = 0x3993; +constexpr unsigned int mmUVD_PGFSM_CONFIG__VI = 0x38C0; +constexpr unsigned int mmUVD_PGFSM_READ_TILE1__VI = 0x38C2; +constexpr unsigned int mmUVD_PGFSM_READ_TILE2__VI = 0x38C3; +constexpr unsigned int mmUVD_PGFSM_READ_TILE3__VI = 0x38C5; +constexpr unsigned int mmUVD_PGFSM_READ_TILE4__VI = 0x38C6; +constexpr unsigned int mmUVD_PGFSM_READ_TILE5__VI = 0x38C8; +constexpr unsigned int mmUVD_PGFSM_READ_TILE6__VI = 0x38EE; +constexpr unsigned int mmUVD_PGFSM_READ_TILE7__VI = 0x38EF; +constexpr unsigned int mmUVD_POWER_STATUS__VI = 0x38C4; +constexpr unsigned int mmUVD_SUVD_CGC_CTRL__VI = 0x3BE6; +constexpr unsigned int mmUVD_SUVD_CGC_GATE__VI = 0x3BE4; +constexpr unsigned int mmUVD_SUVD_CGC_STATUS__VI = 0x3BE5; +constexpr unsigned int mmUVD_UDEC_ADDR_CONFIG__VI = 0x3BD3; +constexpr unsigned int mmUVD_UDEC_DBW_ADDR_CONFIG__VI = 0x3BD5; +constexpr unsigned int mmUVD_UDEC_DB_ADDR_CONFIG__VI = 0x3BD4; +constexpr unsigned int mmVCE_LMI_CACHE_CTRL__VI = 0x85BD; +constexpr unsigned int mmVCE_LMI_CTRL__VI = 0x85A6; +constexpr unsigned int mmVCE_LMI_CTRL2__VI = 0x859D; +constexpr unsigned int mmVCE_LMI_SWAP_CNTL__VI = 0x85AD; +constexpr unsigned int mmVCE_LMI_SWAP_CNTL1__VI = 0x85AE; +constexpr unsigned int mmVCE_LMI_SWAP_CNTL2__VI = 0x85B3; +constexpr unsigned int mmVCE_LMI_SWAP_CNTL3__VI = 0x859E; +constexpr unsigned int mmVCE_LMI_VCPU_CACHE_40BIT_BAR__VI = 0x8597; +constexpr unsigned int mmVCE_RB_ARB_CTRL__VI = 0x809F; +constexpr unsigned int mmVCE_RB_BASE_HI__VI = 0x8061; +constexpr unsigned int mmVCE_RB_BASE_HI2__VI = 0x805C; +constexpr unsigned int mmVCE_RB_BASE_HI3__VI = 0x80D5; +constexpr unsigned int mmVCE_RB_BASE_LO__VI = 0x8060; +constexpr unsigned int mmVCE_RB_BASE_LO2__VI = 0x805B; +constexpr unsigned int mmVCE_RB_BASE_LO3__VI = 0x80D4; +constexpr unsigned int mmVCE_RB_RPTR__VI = 0x8063; +constexpr unsigned int mmVCE_RB_RPTR2__VI = 0x805E; +constexpr unsigned int mmVCE_RB_RPTR3__VI = 0x80D7; +constexpr unsigned int mmVCE_RB_SIZE__VI = 0x8062; +constexpr unsigned int mmVCE_RB_SIZE2__VI = 0x805D; +constexpr unsigned int mmVCE_RB_SIZE3__VI = 0x80D6; +constexpr unsigned int mmVCE_RB_WPTR__VI = 0x8064; +constexpr unsigned int mmVCE_RB_WPTR2__VI = 0x805F; +constexpr unsigned int mmVCE_RB_WPTR3__VI = 0x80D8; +constexpr unsigned int mmVCE_SOFT_RESET__VI = 0x8048; +constexpr unsigned int mmVCE_STATUS__VI = 0x8001; +constexpr unsigned int mmVCE_SYS_INT_ACK__VI = 0x8541; +constexpr unsigned int mmVCE_SYS_INT_EN__VI = 0x8540; +constexpr unsigned int mmVCE_SYS_INT_STATUS__VI = 0x8541; +constexpr unsigned int mmVCE_UENC_DMA_DCLK_CTRL__VI = 0x8390; +constexpr unsigned int mmVCE_VCPU_CACHE_OFFSET0__VI = 0x8009; +constexpr unsigned int mmVCE_VCPU_CACHE_OFFSET1__VI = 0x800B; +constexpr unsigned int mmVCE_VCPU_CACHE_OFFSET2__VI = 0x800D; +constexpr unsigned int mmVCE_VCPU_CACHE_SIZE0__VI = 0x800A; +constexpr unsigned int mmVCE_VCPU_CACHE_SIZE1__VI = 0x800C; +constexpr unsigned int mmVCE_VCPU_CACHE_SIZE2__VI = 0x800E; +constexpr unsigned int mmVCE_VCPU_CNTL__VI = 0x8005; +constexpr unsigned int mmVGA25_PPLL_ANALOG__VI = 0x171B; +constexpr unsigned int mmVGA25_PPLL_FB_DIV__VI = 0x1715; +constexpr unsigned int mmVGA25_PPLL_POST_DIV__VI = 0x1718; +constexpr unsigned int mmVGA25_PPLL_REF_DIV__VI = 0x1712; +constexpr unsigned int mmVGA28_PPLL_ANALOG__VI = 0x171C; +constexpr unsigned int mmVGA28_PPLL_FB_DIV__VI = 0x1716; +constexpr unsigned int mmVGA28_PPLL_POST_DIV__VI = 0x1719; +constexpr unsigned int mmVGA28_PPLL_REF_DIV__VI = 0x1713; +constexpr unsigned int mmVGA41_PPLL_ANALOG__VI = 0x171D; +constexpr unsigned int mmVGA41_PPLL_FB_DIV__VI = 0x1717; +constexpr unsigned int mmVGA41_PPLL_POST_DIV__VI = 0x171A; +constexpr unsigned int mmVGA41_PPLL_REF_DIV__VI = 0x1714; +constexpr unsigned int mmVGT_DISPATCH_DRAW_INDEX__VI = 0xA2DD; +constexpr unsigned int mmVGT_TESS_DISTRIBUTION__VI = 0xA2D4; +constexpr unsigned int mmVIEWPORT_START_SECONDARY__VI = 0x1B5B; +constexpr unsigned int mmVM_INIT_STATUS__VI = 0x14D3; +constexpr unsigned int mmVM_L2_BANK_SELECT_RESERVED_CID__VI = 0x0579; +constexpr unsigned int mmVM_L2_BANK_SELECT_RESERVED_CID2__VI = 0x057A; +constexpr unsigned int mmVM_L2_CNTL4__VI = 0x0578; +constexpr unsigned int mmWB_DBG_MODE__VI = 0x5E31; +constexpr unsigned int mmWB_DEBUG_CTRL__VI = 0x5E30; +constexpr unsigned int mmWB_EC_CONFIG__VI = 0x5E19; +constexpr unsigned int mmWB_ENABLE__VI = 0x5E18; +constexpr unsigned int mmWB_HW_DEBUG__VI = 0x5E32; +constexpr unsigned int mmWB_SOFT_RESET__VI = 0x5E36; +constexpr unsigned int mmWD_QOS__VI = 0x2242; +constexpr unsigned int mmXDMA_AON_TEST_DEBUG_DATA__VI = 0x03FD; +constexpr unsigned int mmXDMA_AON_TEST_DEBUG_INDEX__VI = 0x03FC; +constexpr unsigned int mmXDMA_CLOCK_GATING_CNTL__VI = 0x03E4; +constexpr unsigned int mmXDMA_IF_BIF_STATUS__VI = 0x03E7; +constexpr unsigned int mmXDMA_IF_STATUS__VI = 0x03E9; +constexpr unsigned int mmXDMA_INTERRUPT__VI = 0x03E3; +constexpr unsigned int mmXDMA_LOCAL_SURFACE_TILING1__VI = 0x03E1; +constexpr unsigned int mmXDMA_LOCAL_SURFACE_TILING2__VI = 0x03E2; +constexpr unsigned int mmXDMA_MC_PCIE_CLIENT_CONFIG__VI = 0x03E0; +constexpr unsigned int mmXDMA_MEM_POWER_CNTL__VI = 0x03E6; +constexpr unsigned int mmXDMA_MSTR_CACHE__VI = 0x040A; +constexpr unsigned int mmXDMA_MSTR_CACHE_BASE_ADDR__VI = 0x0408; +constexpr unsigned int mmXDMA_MSTR_CACHE_BASE_ADDR_HIGH__VI = 0x0409; +constexpr unsigned int mmXDMA_MSTR_CHANNEL_DIM__VI = 0x0402; +constexpr unsigned int mmXDMA_MSTR_CHANNEL_START__VI = 0x040B; +constexpr unsigned int mmXDMA_MSTR_CMD_URGENT_CNTL__VI = 0x03F2; +constexpr unsigned int mmXDMA_MSTR_CNTL__VI = 0x03EC; +constexpr unsigned int mmXDMA_MSTR_HEIGHT__VI = 0x0403; +constexpr unsigned int mmXDMA_MSTR_LOCAL_SURFACE_BASE_ADDR__VI = 0x03EF; +constexpr unsigned int mmXDMA_MSTR_LOCAL_SURFACE_BASE_ADDR_HIGH__VI = 0x03F0; +constexpr unsigned int mmXDMA_MSTR_LOCAL_SURFACE_PITCH__VI = 0x03F1; +constexpr unsigned int mmXDMA_MSTR_MEM_CLIENT_CONFIG__VI = 0x03EE; +constexpr unsigned int mmXDMA_MSTR_MEM_NACK_STATUS__VI = 0x03F6; +constexpr unsigned int mmXDMA_MSTR_MEM_URGENT_CNTL__VI = 0x03F3; +constexpr unsigned int mmXDMA_MSTR_PCIE_NACK_STATUS__VI = 0x03F5; +constexpr unsigned int mmXDMA_MSTR_PERFMEAS_CNTL__VI = 0x040F; +constexpr unsigned int mmXDMA_MSTR_PERFMEAS_STATUS__VI = 0x040E; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_CACHE__VI = 0x040A; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_CACHE_BASE_ADDR__VI = 0x0408; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_CACHE_BASE_ADDR_HIGH__VI = 0x0409; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_CHANNEL_DIM__VI = 0x0402; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_CHANNEL_START__VI = 0x040B; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_HEIGHT__VI = 0x0403; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_PERFMEAS_CNTL__VI = 0x040F; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_PERFMEAS_STATUS__VI = 0x040E; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_PIPE_CNTL__VI = 0x0400; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_READ_COMMAND__VI = 0x0401; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_REMOTE_GPU_ADDRESS__VI = 0x0406; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0407; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_REMOTE_SURFACE_BASE__VI = 0x0404; +constexpr unsigned int mmXDMA_MSTR_PIPE0_XDMA_MSTR_REMOTE_SURFACE_BASE_HIGH__VI = 0x0405; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_CACHE__VI = 0x041A; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_CACHE_BASE_ADDR__VI = 0x0418; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_CACHE_BASE_ADDR_HIGH__VI = 0x0419; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_CHANNEL_DIM__VI = 0x0412; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_CHANNEL_START__VI = 0x041B; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_HEIGHT__VI = 0x0413; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_PERFMEAS_CNTL__VI = 0x041F; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_PERFMEAS_STATUS__VI = 0x041E; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_PIPE_CNTL__VI = 0x0410; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_READ_COMMAND__VI = 0x0411; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_REMOTE_GPU_ADDRESS__VI = 0x0416; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0417; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_REMOTE_SURFACE_BASE__VI = 0x0414; +constexpr unsigned int mmXDMA_MSTR_PIPE1_XDMA_MSTR_REMOTE_SURFACE_BASE_HIGH__VI = 0x0415; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_CACHE__VI = 0x042A; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_CACHE_BASE_ADDR__VI = 0x0428; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_CACHE_BASE_ADDR_HIGH__VI = 0x0429; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_CHANNEL_DIM__VI = 0x0422; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_CHANNEL_START__VI = 0x042B; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_HEIGHT__VI = 0x0423; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_PERFMEAS_CNTL__VI = 0x042F; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_PERFMEAS_STATUS__VI = 0x042E; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_PIPE_CNTL__VI = 0x0420; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_READ_COMMAND__VI = 0x0421; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_REMOTE_GPU_ADDRESS__VI = 0x0426; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0427; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_REMOTE_SURFACE_BASE__VI = 0x0424; +constexpr unsigned int mmXDMA_MSTR_PIPE2_XDMA_MSTR_REMOTE_SURFACE_BASE_HIGH__VI = 0x0425; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_CACHE__VI = 0x043A; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_CACHE_BASE_ADDR__VI = 0x0438; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_CACHE_BASE_ADDR_HIGH__VI = 0x0439; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_CHANNEL_DIM__VI = 0x0432; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_CHANNEL_START__VI = 0x043B; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_HEIGHT__VI = 0x0433; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_PERFMEAS_CNTL__VI = 0x043F; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_PERFMEAS_STATUS__VI = 0x043E; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_PIPE_CNTL__VI = 0x0430; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_READ_COMMAND__VI = 0x0431; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_REMOTE_GPU_ADDRESS__VI = 0x0436; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0437; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_REMOTE_SURFACE_BASE__VI = 0x0434; +constexpr unsigned int mmXDMA_MSTR_PIPE3_XDMA_MSTR_REMOTE_SURFACE_BASE_HIGH__VI = 0x0435; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_CACHE__VI = 0x044A; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_CACHE_BASE_ADDR__VI = 0x0448; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_CACHE_BASE_ADDR_HIGH__VI = 0x0449; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_CHANNEL_DIM__VI = 0x0442; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_CHANNEL_START__VI = 0x044B; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_HEIGHT__VI = 0x0443; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_PERFMEAS_CNTL__VI = 0x044F; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_PERFMEAS_STATUS__VI = 0x044E; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_PIPE_CNTL__VI = 0x0440; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_READ_COMMAND__VI = 0x0441; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_REMOTE_GPU_ADDRESS__VI = 0x0446; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0447; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_REMOTE_SURFACE_BASE__VI = 0x0444; +constexpr unsigned int mmXDMA_MSTR_PIPE4_XDMA_MSTR_REMOTE_SURFACE_BASE_HIGH__VI = 0x0445; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_CACHE__VI = 0x045A; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_CACHE_BASE_ADDR__VI = 0x0458; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_CACHE_BASE_ADDR_HIGH__VI = 0x0459; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_CHANNEL_DIM__VI = 0x0452; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_CHANNEL_START__VI = 0x045B; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_HEIGHT__VI = 0x0453; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_PERFMEAS_CNTL__VI = 0x045F; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_PERFMEAS_STATUS__VI = 0x045E; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_PIPE_CNTL__VI = 0x0450; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_READ_COMMAND__VI = 0x0451; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_REMOTE_GPU_ADDRESS__VI = 0x0456; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0457; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_REMOTE_SURFACE_BASE__VI = 0x0454; +constexpr unsigned int mmXDMA_MSTR_PIPE5_XDMA_MSTR_REMOTE_SURFACE_BASE_HIGH__VI = 0x0455; +constexpr unsigned int mmXDMA_MSTR_PIPE_CNTL__VI = 0x0400; +constexpr unsigned int mmXDMA_MSTR_READ_COMMAND__VI = 0x0401; +constexpr unsigned int mmXDMA_MSTR_REMOTE_GPU_ADDRESS__VI = 0x0406; +constexpr unsigned int mmXDMA_MSTR_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0407; +constexpr unsigned int mmXDMA_MSTR_REMOTE_SURFACE_BASE__VI = 0x0404; +constexpr unsigned int mmXDMA_MSTR_REMOTE_SURFACE_BASE_HIGH__VI = 0x0405; +constexpr unsigned int mmXDMA_MSTR_STATUS__VI = 0x03ED; +constexpr unsigned int mmXDMA_MSTR_VSYNC_GSL_CHECK__VI = 0x03F7; +constexpr unsigned int mmXDMA_PERF_MEAS_STATUS__VI = 0x03E8; +constexpr unsigned int mmXDMA_PG_CONTROL__VI = 0x03F9; +constexpr unsigned int mmXDMA_PG_STATUS__VI = 0x03FB; +constexpr unsigned int mmXDMA_PG_WDATA__VI = 0x03FA; +constexpr unsigned int mmXDMA_RBBMIF_RDWR_CNTL__VI = 0x03F8; +constexpr unsigned int mmXDMA_SLV_CHANNEL0_XDMA_SLV_CHANNEL_CNTL__VI = 0x0470; +constexpr unsigned int mmXDMA_SLV_CHANNEL0_XDMA_SLV_REMOTE_GPU_ADDRESS__VI = 0x0471; +constexpr unsigned int mmXDMA_SLV_CHANNEL0_XDMA_SLV_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0472; +constexpr unsigned int mmXDMA_SLV_CHANNEL1_XDMA_SLV_CHANNEL_CNTL__VI = 0x0478; +constexpr unsigned int mmXDMA_SLV_CHANNEL1_XDMA_SLV_REMOTE_GPU_ADDRESS__VI = 0x0479; +constexpr unsigned int mmXDMA_SLV_CHANNEL1_XDMA_SLV_REMOTE_GPU_ADDRESS_HIGH__VI = 0x047A; +constexpr unsigned int mmXDMA_SLV_CHANNEL2_XDMA_SLV_CHANNEL_CNTL__VI = 0x0480; +constexpr unsigned int mmXDMA_SLV_CHANNEL2_XDMA_SLV_REMOTE_GPU_ADDRESS__VI = 0x0481; +constexpr unsigned int mmXDMA_SLV_CHANNEL2_XDMA_SLV_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0482; +constexpr unsigned int mmXDMA_SLV_CHANNEL3_XDMA_SLV_CHANNEL_CNTL__VI = 0x0488; +constexpr unsigned int mmXDMA_SLV_CHANNEL3_XDMA_SLV_REMOTE_GPU_ADDRESS__VI = 0x0489; +constexpr unsigned int mmXDMA_SLV_CHANNEL3_XDMA_SLV_REMOTE_GPU_ADDRESS_HIGH__VI = 0x048A; +constexpr unsigned int mmXDMA_SLV_CHANNEL4_XDMA_SLV_CHANNEL_CNTL__VI = 0x0490; +constexpr unsigned int mmXDMA_SLV_CHANNEL4_XDMA_SLV_REMOTE_GPU_ADDRESS__VI = 0x0491; +constexpr unsigned int mmXDMA_SLV_CHANNEL4_XDMA_SLV_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0492; +constexpr unsigned int mmXDMA_SLV_CHANNEL5_XDMA_SLV_CHANNEL_CNTL__VI = 0x0498; +constexpr unsigned int mmXDMA_SLV_CHANNEL5_XDMA_SLV_REMOTE_GPU_ADDRESS__VI = 0x0499; +constexpr unsigned int mmXDMA_SLV_CHANNEL5_XDMA_SLV_REMOTE_GPU_ADDRESS_HIGH__VI = 0x049A; +constexpr unsigned int mmXDMA_SLV_CHANNEL_CNTL__VI = 0x0470; +constexpr unsigned int mmXDMA_SLV_CNTL__VI = 0x0460; +constexpr unsigned int mmXDMA_SLV_MEM_CLIENT_CONFIG__VI = 0x0461; +constexpr unsigned int mmXDMA_SLV_MEM_NACK_STATUS__VI = 0x0469; +constexpr unsigned int mmXDMA_SLV_PCIE_NACK_STATUS__VI = 0x0468; +constexpr unsigned int mmXDMA_SLV_RDRET_BUF_STATUS__VI = 0x046A; +constexpr unsigned int mmXDMA_SLV_READ_LATENCY_AVE__VI = 0x0467; +constexpr unsigned int mmXDMA_SLV_READ_LATENCY_MINMAX__VI = 0x0466; +constexpr unsigned int mmXDMA_SLV_READ_LATENCY_TIMER__VI = 0x046B; +constexpr unsigned int mmXDMA_SLV_READ_URGENT_CNTL__VI = 0x0463; +constexpr unsigned int mmXDMA_SLV_REMOTE_GPU_ADDRESS__VI = 0x0471; +constexpr unsigned int mmXDMA_SLV_REMOTE_GPU_ADDRESS_HIGH__VI = 0x0472; +constexpr unsigned int mmXDMA_SLV_SLS_PITCH__VI = 0x0462; +constexpr unsigned int mmXDMA_SLV_WB_RATE_CNTL__VI = 0x0465; +constexpr unsigned int mmXDMA_SLV_WRITE_URGENT_CNTL__VI = 0x0464; +constexpr unsigned int mmXDMA_TEST_DEBUG_DATA__VI = 0x03EB; +constexpr unsigned int mmXDMA_TEST_DEBUG_INDEX__VI = 0x03EA; +#define offset_HEADER__VI +constexpr unsigned int pciMSI_MASK__VI = 0x002B; +constexpr unsigned int pciMSI_MASK_64__VI = 0x002C; +constexpr unsigned int pciMSI_PENDING__VI = 0x002C; +constexpr unsigned int pciMSI_PENDING_64__VI = 0x002D; +constexpr unsigned int pciPCIE_ARI_CAP__VI = 0x00CB; +constexpr unsigned int pciPCIE_ARI_CNTL__VI = 0x00CB; +constexpr unsigned int pciPCIE_ARI_ENH_CAP_LIST__VI = 0x00CA; +constexpr unsigned int pciPCIE_LTR_CAP__VI = 0x00C9; +constexpr unsigned int pciPCIE_LTR_ENH_CAP_LIST__VI = 0x00C8; +constexpr unsigned int pciPCIE_MC_ADDR0__VI = 0x00BE; +constexpr unsigned int pciPCIE_MC_ADDR1__VI = 0x00BF; +constexpr unsigned int pciPCIE_MC_BLOCK_ALL0__VI = 0x00C2; +constexpr unsigned int pciPCIE_MC_BLOCK_ALL1__VI = 0x00C3; +constexpr unsigned int pciPCIE_MC_BLOCK_UNTRANSLATED_0__VI = 0x00C4; +constexpr unsigned int pciPCIE_MC_BLOCK_UNTRANSLATED_1__VI = 0x00C5; +constexpr unsigned int pciPCIE_MC_CAP__VI = 0x00BD; +constexpr unsigned int pciPCIE_MC_CNTL__VI = 0x00BD; +constexpr unsigned int pciPCIE_MC_ENH_CAP_LIST__VI = 0x00BC; +constexpr unsigned int pciPCIE_MC_RCV0__VI = 0x00C0; +constexpr unsigned int pciPCIE_MC_RCV1__VI = 0x00C1; +constexpr unsigned int pciPCIE_SRIOV_CAP__VI = 0x00CD; +constexpr unsigned int pciPCIE_SRIOV_CONTROL__VI = 0x00CE; +constexpr unsigned int pciPCIE_SRIOV_ENH_CAP_LIST__VI = 0x00CC; +constexpr unsigned int pciPCIE_SRIOV_FIRST_VF_OFFSET__VI = 0x00D1; +constexpr unsigned int pciPCIE_SRIOV_FUNC_DEP_LINK__VI = 0x00D0; +constexpr unsigned int pciPCIE_SRIOV_INITIAL_VFS__VI = 0x00CF; +constexpr unsigned int pciPCIE_SRIOV_NUM_VFS__VI = 0x00D0; +constexpr unsigned int pciPCIE_SRIOV_STATUS__VI = 0x00CE; +constexpr unsigned int pciPCIE_SRIOV_SUPPORTED_PAGE_SIZE__VI = 0x00D3; +constexpr unsigned int pciPCIE_SRIOV_SYSTEM_PAGE_SIZE__VI = 0x00D4; +constexpr unsigned int pciPCIE_SRIOV_TOTAL_VFS__VI = 0x00CF; +constexpr unsigned int pciPCIE_SRIOV_VF_BASE_ADDR_0__VI = 0x00D5; +constexpr unsigned int pciPCIE_SRIOV_VF_BASE_ADDR_1__VI = 0x00D6; +constexpr unsigned int pciPCIE_SRIOV_VF_BASE_ADDR_2__VI = 0x00D7; +constexpr unsigned int pciPCIE_SRIOV_VF_BASE_ADDR_3__VI = 0x00D8; +constexpr unsigned int pciPCIE_SRIOV_VF_BASE_ADDR_4__VI = 0x00D9; +constexpr unsigned int pciPCIE_SRIOV_VF_BASE_ADDR_5__VI = 0x00DA; +constexpr unsigned int pciPCIE_SRIOV_VF_DEVICE_ID__VI = 0x00D2; +constexpr unsigned int pciPCIE_SRIOV_VF_MIGRATION_STATE_ARRAY_OFFSET__VI = 0x00DB; +constexpr unsigned int pciPCIE_SRIOV_VF_STRIDE__VI = 0x00D1; +constexpr unsigned int pciPCIE_TPH_REQR_CAP__VI = 0x00B9; +constexpr unsigned int pciPCIE_TPH_REQR_CNTL__VI = 0x00BA; +constexpr unsigned int pciPCIE_TPH_REQR_ENH_CAP_LIST__VI = 0x00B8; +constexpr unsigned int pciPCIE_VENDOR_SPECIFIC_ENH_CAP_LIST_GPUIOV__VI = 0x0100; +constexpr unsigned int pciPCIE_VENDOR_SPECIFIC_HDR_GPUIOV__VI = 0x0101; +constexpr unsigned int pciPCIE_VENDOR_SPECIFIC_HDR_GPUIOV_RESET_CONTROL__VI = 0x0105; +} // inline namespace Chip +} // namespace Gfx6 +} // namespace Pal + +#endif diff --git a/gpu/third_party/gcn/include/gcn/si_ci_vi_merged_pm4_it_opcodes.h b/gpu/third_party/gcn/include/gcn/si_ci_vi_merged_pm4_it_opcodes.h new file mode 100644 index 0000000..0c2ac3a --- /dev/null +++ b/gpu/third_party/gcn/include/gcn/si_ci_vi_merged_pm4_it_opcodes.h @@ -0,0 +1,117 @@ +/* + *********************************************************************************************************************** + * + * Copyright (c) 2015-2021 Advanced Micro Devices, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * 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 Software. + * + * THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + **********************************************************************************************************************/ + +#ifndef PM4_IT_OPCODES_H +#define PM4_IT_OPCODES_H + +enum IT_OpCodeType { + IT_NOP = 0x10, + IT_SET_BASE = 0x11, + IT_CLEAR_STATE = 0x12, + IT_INDEX_BUFFER_SIZE = 0x13, + IT_DISPATCH_DIRECT = 0x15, + IT_DISPATCH_INDIRECT = 0x16, + IT_ATOMIC_GDS = 0x1D, + IT_ATOMIC = 0x1E, + IT_OCCLUSION_QUERY = 0x1F, + IT_SET_PREDICATION = 0x20, + IT_REG_RMW = 0x21, + IT_COND_EXEC = 0x22, + IT_PRED_EXEC = 0x23, + IT_DRAW_INDIRECT = 0x24, + IT_DRAW_INDEX_INDIRECT = 0x25, + IT_INDEX_BASE = 0x26, + IT_DRAW_INDEX_2 = 0x27, + IT_CONTEXT_CONTROL = 0x28, + IT_INDEX_TYPE = 0x2A, + IT_DRAW_INDIRECT_MULTI = 0x2C, + IT_DRAW_INDEX_AUTO = 0x2D, + IT_NUM_INSTANCES = 0x2F, + IT_DRAW_INDEX_MULTI_AUTO = 0x30, + IT_INDIRECT_BUFFER_CNST = 0x33, + IT_STRMOUT_BUFFER_UPDATE = 0x34, + IT_DRAW_INDEX_OFFSET_2 = 0x35, + IT_WRITE_DATA = 0x37, + IT_DRAW_INDEX_INDIRECT_MULTI = 0x38, + IT_MEM_SEMAPHORE = 0x39, + IT_COPY_DW__SI__CI = 0x3B, + IT_WAIT_REG_MEM = 0x3C, + IT_INDIRECT_BUFFER = 0x3F, + IT_COND_INDIRECT_BUFFER = 0x3F, + IT_COPY_DATA = 0x40, + IT_CP_DMA = 0x41, + IT_PFP_SYNC_ME = 0x42, + IT_SURFACE_SYNC = 0x43, + IT_COND_WRITE = 0x45, + IT_EVENT_WRITE = 0x46, + IT_EVENT_WRITE_EOP = 0x47, + IT_EVENT_WRITE_EOS = 0x48, + IT_PREAMBLE_CNTL = 0x4A, + IT_CONTEXT_REG_RMW = 0x51, + IT_LOAD_SH_REG = 0x5F, + IT_LOAD_CONFIG_REG = 0x60, + IT_LOAD_CONTEXT_REG = 0x61, + IT_SET_CONFIG_REG = 0x68, + IT_SET_CONTEXT_REG = 0x69, + IT_SET_CONTEXT_REG_INDIRECT = 0x73, + IT_SET_SH_REG = 0x76, + IT_SET_SH_REG_OFFSET = 0x77, + IT_SCRATCH_RAM_WRITE = 0x7D, + IT_SCRATCH_RAM_READ = 0x7E, + IT_LOAD_CONST_RAM = 0x80, + IT_WRITE_CONST_RAM = 0x81, + IT_DUMP_CONST_RAM = 0x83, + IT_INCREMENT_CE_COUNTER = 0x84, + IT_INCREMENT_DE_COUNTER = 0x85, + IT_WAIT_ON_CE_COUNTER = 0x86, + IT_WAIT_ON_DE_COUNTER__SI = 0x87, + IT_WAIT_ON_DE_COUNTER_DIFF = 0x88, + IT_SWITCH_BUFFER = 0x8B, + IT_DRAW_PREAMBLE__CI__VI = 0x36, + IT_RELEASE_MEM__CI__VI = 0x49, + IT_DMA_DATA__CI__VI = 0x50, + IT_ACQUIRE_MEM__CI__VI = 0x58, + IT_REWIND__CI__VI = 0x59, + IT_LOAD_UCONFIG_REG__CI__VI = 0x5E, + IT_SET_QUEUE_REG__CI__VI = 0x78, + IT_SET_UCONFIG_REG__CI__VI = 0x79, + IT_INDEX_ATTRIBUTES_INDIRECT__CI__VI = 0x91, + IT_SET_SH_REG_INDEX__CI__VI = 0x9B, + IT_SET_RESOURCES__CI__VI = 0xA0, + IT_MAP_PROCESS__CI__VI = 0xA1, + IT_MAP_QUEUES__CI__VI = 0xA2, + IT_UNMAP_QUEUES__CI__VI = 0xA3, + IT_QUERY_STATUS__CI__VI = 0xA4, + IT_RUN_LIST__CI__VI = 0xA5, + IT_LOAD_SH_REG_INDEX__VI = 0x63, + IT_LOAD_CONTEXT_REG_INDEX__VI = 0x9F, + IT_DUMP_CONST_RAM_OFFSET__VI = 0x9E, +}; + +#define PM4_TYPE_0 0 +#define PM4_TYPE_2 2 +#define PM4_TYPE_3 3 + +#endif diff --git a/gpu/third_party/half/.azuredevops/rocm-ci.yml b/gpu/third_party/half/.azuredevops/rocm-ci.yml new file mode 100644 index 0000000..b82aa20 --- /dev/null +++ b/gpu/third_party/half/.azuredevops/rocm-ci.yml @@ -0,0 +1,40 @@ +resources: + repositories: + - repository: pipelines_repo + type: github + endpoint: ROCm + name: ROCm/ROCm + +variables: +- group: common +- template: /.azuredevops/variables-global.yml@pipelines_repo + +trigger: + batch: true + branches: + include: + - rocm + paths: + exclude: + - .github + - docs + - '.*.y*ml' + - LICENSE.txt + - README.txt + +pr: + autoCancel: true + branches: + include: + - rocm + paths: + exclude: + - .github + - docs + - '.*.y*ml' + - LICENSE.txt + - README.txt + drafts: false + +jobs: + - template: ${{ variables.CI_COMPONENT_PATH }}/half.yml@pipelines_repo diff --git a/gpu/third_party/half/.github/CODEOWNERS b/gpu/third_party/half/.github/CODEOWNERS new file mode 100644 index 0000000..deb4b86 --- /dev/null +++ b/gpu/third_party/half/.github/CODEOWNERS @@ -0,0 +1 @@ +**/CMakeLists.txt @pfultz2 diff --git a/gpu/third_party/half/.github/dependabot.yml b/gpu/third_party/half/.github/dependabot.yml new file mode 100644 index 0000000..e7ac584 --- /dev/null +++ b/gpu/third_party/half/.github/dependabot.yml @@ -0,0 +1,18 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "pip" # See documentation for possible values + directory: "/docs/sphinx" # Location of package manifests + open-pull-requests-limit: 10 + schedule: + interval: "daily" + target-branch: "develop" + labels: + - "documentation" + - "dependencies" + reviewers: + - "samjwu" diff --git a/gpu/third_party/half/.readthedocs.yaml b/gpu/third_party/half/.readthedocs.yaml new file mode 100644 index 0000000..b3299fa --- /dev/null +++ b/gpu/third_party/half/.readthedocs.yaml @@ -0,0 +1,18 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +sphinx: + configuration: docs/conf.py + +formats: [htmlzip, pdf, epub] + +python: + install: + - requirements: docs/sphinx/requirements.txt + +build: + os: ubuntu-22.04 + tools: + python: "3.10" diff --git a/gpu/third_party/half/CMakeLists.txt b/gpu/third_party/half/CMakeLists.txt new file mode 100644 index 0000000..9e9e361 --- /dev/null +++ b/gpu/third_party/half/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) + +# This has to be initialized before the project() command appears +# Set the default of CMAKE_BUILD_TYPE to be release, unless user specifies with -D. MSVC_IDE does not use CMAKE_BUILD_TYPE +if( NOT MSVC_IDE AND NOT CMAKE_BUILD_TYPE ) + set( CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." ) +endif() + +# Default installation path +if(WIN32) + set(CMAKE_INSTALL_PREFIX "/opt/rocm/x86_64-w64-mingw32" CACHE PATH "") +else() + set(CMAKE_INSTALL_PREFIX "/opt/rocm" CACHE PATH "") +endif() + +project(half) +find_package(ROCM REQUIRED) + +include(ROCMSetupVersion) +include(ROCMCreatePackage) + +# FOR HANDLING ENABLE/DISABLE OPTIONAL BACKWARD COMPATIBILITY for FILE/FOLDER REORG +option(BUILD_FILE_REORG_BACKWARD_COMPATIBILITY "Build with file/folder reorg with backward compatibility enabled" OFF) + +rocm_setup_version(VERSION 1.12.0 NO_GIT_TAG_VERSION) + +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/half.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/half) + +if(BUILD_FILE_REORG_BACKWARD_COMPATIBILITY) + include(ROCMHeaderWrapper) + rocm_wrap_header_file( + half.hpp + GUARDS WRAPPER + WRAPPER_LOCATIONS ${CMAKE_INSTALL_INCLUDEDIR} + ) + + #Install Wrapper for backward compatibility + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/half.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +endif() + +rocm_create_package( + NAME half + DESCRIPTION "HALF-PRECISION FLOATING POINT LIBRARY" + MAINTAINER "Paul Fultz II " +) diff --git a/gpu/third_party/half/ChangeLog.txt b/gpu/third_party/half/ChangeLog.txt new file mode 100644 index 0000000..9100b6a --- /dev/null +++ b/gpu/third_party/half/ChangeLog.txt @@ -0,0 +1,184 @@ +Release Notes {#changelog} +============= + +1.12.0 release (2017-03-06): +---------------------------- + +- Changed behaviour of `half_cast` to perform conversions to/from `double` + and `long double` directly according to specified rounding mode, without an + intermediate `float` conversion. +- Added `noexcept` specifiers to constructors. +- Fixed minor portability problem with `logb` and `ilogb`. +- Tested for *VC++ 2015*. + + +1.11.0 release (2013-11-16): +---------------------------- + +- Made tie-breaking behaviour in round to nearest configurable by + `HALF_ROUND_TIES_TO_EVEN` macro. +- Completed support for all C++11 mathematical functions even if single- + precision versions from `` are unsupported. +- Fixed inability to disable support for C++11 mathematical functions on + *VC++ 2013*. + + +1.10.0 release (2013-11-09): +---------------------------- + +- Made default rounding mode configurable by `HALF_ROUND_STYLE` macro. +- Added support for non-IEEE single-precision implementations. +- Added `HALF_ENABLE_CPP11_TYPE_TRAITS` preprocessor flag for checking + support for C++11 type traits and TMP features. +- Restricted `half_cast` to support built-in arithmetic types only. +- Changed behaviour of `half_cast` to respect rounding mode when casting + to/from integer types. + + +1.9.2 release (2013-11-01): +--------------------------- + +- Tested for *gcc 4.8*. +- Tested and fixed for *VC++ 2013*. +- Removed unnecessary warnings in *MSVC*. + + +1.9.1 release (2013-08-08): +--------------------------- + +- Fixed problems with older gcc and MSVC versions. +- Small fix to non-C++11 implementations of `remainder` and `remquo`. + + +1.9.0 release (2013-08-07): +--------------------------- + +- Changed behaviour of `nearbyint`, `rint`, `lrint` and `llrint` to use + rounding mode of half-precision implementation (which is + truncating/indeterminate) instead of single-precision rounding mode. +- Added support for more C++11 mathematical functions even if single- + precision versions from `` are unsupported, in particular + `remainder`, `remquo` and `cbrt`. +- Minor implementation changes. + + +1.8.1 release (2013-01-22): +--------------------------- + +- Fixed bug resulting in multiple definitions of the `nanh` function due to + a missing `inline` specification. + + +1.8.0 release (2013-01-19): +--------------------------- + +- Added support for more C++11 mathematical functions even if single- + precision versions from `` are unsupported, in particular + exponential and logarithm functions, hyperbolic area functions and the + hypotenuse function. +- Made `fma` function use default implementation if single-precision version + from `` is not faster and thus `FP_FAST_FMAH` to be defined always. +- Fixed overload resolution issues when invoking certain mathematical + functions by unqualified calls. + + +1.7.0 release (2012-10-26): +--------------------------- + +- Added support for C++11 `noexcept` specifiers. +- Changed C++11 `long long` to be supported on *VC++ 2003* and up. + + +1.6.1 release (2012-09-13): +--------------------------- + +- Made `fma` and `fdim` functions available even if corresponding + single-precision functions are not. + + +1.6.0 release (2012-09-12): +--------------------------- + +- Added `HALF_ENABLE_CPP11_LONG_LONG` to control support for `long long` + integers and corresponding mathematical functions. +- Fixed C++98 compatibility on non-VC compilers. + + +1.5.1 release (2012-08-17): +--------------------------- + +- Recorrected `std::numeric_limits::round_style` to always return + `std::round_indeterminate`, due to overflow-handling deviating from + correct round-toward-zero behaviour. + + +1.5.0 release (2012-08-16): +--------------------------- + +- Added `half_cast` for explicitly casting between half and any type + convertible to/from `float` and allowing the explicit specification of + the rounding mode to use. + + +1.4.0 release (2012-08-12): +--------------------------- + +- Added support for C++11 generalized constant expressions (`constexpr`). + + +1.3.1 release (2012-08-11): +--------------------------- + +- Fixed requirement for `std::signbit` and `std::isnan` (even if C++11 + `` functions disabled) on non-VC compilers. + + +1.3.0 release (2012-08-10): +--------------------------- + +- Made requirement for `` and `static_assert` optional and thus + made the library C++98-compatible. +- Made support for C++11 features user-overridable through explicit + definition of corresponding preprocessor symbols to either 0 or 1. +- Renamed `HALF_ENABLE_HASH` to `HALF_ENABLE_CPP11_HASH` in correspondence + with other C++11 preprocessor symbols. + + +1.2.0 release (2012-08-07): +--------------------------- + +- Added proper preprocessor definitions for `HUGE_VALH` and `FP_FAST_FMAH` + in correspondence with their single-precision counterparts from ``. +- Fixed internal preprocessor macros to be properly undefined after use. + + +1.1.2 release (2012-08-07): +--------------------------- + +- Revised `std::numeric_limits::round_style` to return + `std::round_toward_zero` if the `float` version also does and + `std::round_indeterminate` otherwise. +- Fixed `std::numeric_limits::round_error` to reflect worst-case round + toward zero behaviour. + + +1.1.1 release (2012-08-06): +--------------------------- + +- Fixed `std::numeric_limits::min` to return smallest positive normal + number, instead of subnormal number. +- Fixed `std::numeric_limits::round_style` to return + `std::round_indeterminate` due to mixture of separately rounded + single-precision arithmetics with truncating single-to-half conversions. + + +1.1.0 release (2012-08-06): +--------------------------- + +- Added half-precision literals. + + +1.0.0 release (2012-08-05): +--------------------------- + +- First release. diff --git a/gpu/third_party/half/LICENSE.txt b/gpu/third_party/half/LICENSE.txt new file mode 100644 index 0000000..9e4618b --- /dev/null +++ b/gpu/third_party/half/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2012-2017 Christian Rau + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +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 Software. + +THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/gpu/third_party/half/README.txt b/gpu/third_party/half/README.txt new file mode 100644 index 0000000..3a0960c --- /dev/null +++ b/gpu/third_party/half/README.txt @@ -0,0 +1,288 @@ +HALF-PRECISION FLOATING POINT LIBRARY (Version 1.12.0) +------------------------------------------------------ + +This is a C++ header-only library to provide an IEEE 754 conformant 16-bit +half-precision floating point type along with corresponding arithmetic +operators, type conversions and common mathematical functions. It aims for both +efficiency and ease of use, trying to accurately mimic the behaviour of the +builtin floating point types at the best performance possible. + + +INSTALLATION AND REQUIREMENTS +----------------------------- + +Comfortably enough, the library consists of just a single header file +containing all the functionality, which can be directly included by your +projects, without the neccessity to build anything or link to anything. + +Whereas this library is fully C++98-compatible, it can profit from certain +C++11 features. Support for those features is checked automatically at compile +(or rather preprocessing) time, but can be explicitly enabled or disabled by +defining the corresponding preprocessor symbols to either 1 or 0 yourself. This +is useful when the automatic detection fails (for more exotic implementations) +or when a feature should be explicitly disabled: + + - 'long long' integer type for mathematical functions returning 'long long' + results (enabled for VC++ 2003 and newer, gcc and clang, overridable with + 'HALF_ENABLE_CPP11_LONG_LONG'). + + - Static assertions for extended compile-time checks (enabled for VC++ 2010, + gcc 4.3, clang 2.9 and newer, overridable with 'HALF_ENABLE_CPP11_STATIC_ASSERT'). + + - Generalized constant expressions (enabled for VC++ 2015, gcc 4.6, clang 3.1 + and newer, overridable with 'HALF_ENABLE_CPP11_CONSTEXPR'). + + - noexcept exception specifications (enabled for VC++ 2015, gcc 4.6, clang 3.0 + and newer, overridable with 'HALF_ENABLE_CPP11_NOEXCEPT'). + + - User-defined literals for half-precision literals to work (enabled for + VC++ 2015, gcc 4.7, clang 3.1 and newer, overridable with + 'HALF_ENABLE_CPP11_USER_LITERALS'). + + - Type traits and template meta-programming features from + (enabled for VC++ 2010, libstdc++ 4.3, libc++ and newer, overridable with + 'HALF_ENABLE_CPP11_TYPE_TRAITS'). + + - Special integer types from (enabled for VC++ 2010, libstdc++ 4.3, + libc++ and newer, overridable with 'HALF_ENABLE_CPP11_CSTDINT'). + + - Certain C++11 single-precision mathematical functions from for + an improved implementation of their half-precision counterparts to work + (enabled for VC++ 2013, libstdc++ 4.3, libc++ and newer, overridable with + 'HALF_ENABLE_CPP11_CMATH'). + + - Hash functor 'std::hash' from (enabled for VC++ 2010, + libstdc++ 4.3, libc++ and newer, overridable with 'HALF_ENABLE_CPP11_HASH'). + +The library has been tested successfully with Visual C++ 2005-2015, gcc 4.4-4.8 +and clang 3.1. Please contact me if you have any problems, suggestions or even +just success testing it on other platforms. + + +DOCUMENTATION +------------- + +Here follow some general words about the usage of the library and its +implementation. For a complete documentation of its iterface look at the +corresponding website http://half.sourceforge.net. You may also generate the +complete developer documentation from the library's only include file's doxygen +comments, but this is more relevant to developers rather than mere users (for +reasons described below). + +BASIC USAGE + +To make use of the library just include its only header file half.hpp, which +defines all half-precision functionality inside the 'half_float' namespace. The +actual 16-bit half-precision data type is represented by the 'half' type. This +type behaves like the builtin floating point types as much as possible, +supporting the usual arithmetic, comparison and streaming operators, which +makes its use pretty straight-forward: + + using half_float::half; + half a(3.4), b(5); + half c = a * b; + c += 3; + if(c > a) + std::cout << c << std::endl; + +Additionally the 'half_float' namespace also defines half-precision versions +for all mathematical functions of the C++ standard library, which can be used +directly through ADL: + + half a(-3.14159); + half s = sin(abs(a)); + long l = lround(s); + +You may also specify explicit half-precision literals, since the library +provides a user-defined literal inside the 'half_float::literal' namespace, +which you just need to import (assuming support for C++11 user-defined literals): + + using namespace half_float::literal; + half x = 1.0_h; + +Furthermore the library provides proper specializations for +'std::numeric_limits', defining various implementation properties, and +'std::hash' for hashing half-precision numbers (assuming support for C++11 +'std::hash'). Similar to the corresponding preprocessor symbols from +the library also defines the 'HUGE_VALH' constant and maybe the 'FP_FAST_FMAH' +symbol. + +CONVERSIONS AND ROUNDING + +The half is explicitly constructible/convertible from a single-precision float +argument. Thus it is also explicitly constructible/convertible from any type +implicitly convertible to float, but constructing it from types like double or +int will involve the usual warnings arising when implicitly converting those to +float because of the lost precision. On the one hand those warnings are +intentional, because converting those types to half neccessarily also reduces +precision. But on the other hand they are raised for explicit conversions from +those types, when the user knows what he is doing. So if those warnings keep +bugging you, then you won't get around first explicitly converting to float +before converting to half, or use the 'half_cast' described below. In addition +you can also directly assign float values to halfs. + +In contrast to the float-to-half conversion, which reduces precision, the +conversion from half to float (and thus to any other type implicitly +convertible from float) is implicit, because all values represetable with +half-precision are also representable with single-precision. This way the +half-to-float conversion behaves similar to the builtin float-to-double +conversion and all arithmetic expressions involving both half-precision and +single-precision arguments will be of single-precision type. This way you can +also directly use the mathematical functions of the C++ standard library, +though in this case you will invoke the single-precision versions which will +also return single-precision values, which is (even if maybe performing the +exact same computation, see below) not as conceptually clean when working in a +half-precision environment. + +The default rounding mode for conversions from float to half uses truncation +(round toward zero, but mapping overflows to infinity) for rounding values not +representable exactly in half-precision. This is the fastest rounding possible +and is usually sufficient. But by redefining the 'HALF_ROUND_STYLE' +preprocessor symbol (before including half.hpp) this default can be overridden +with one of the other standard rounding modes using their respective constants +or the equivalent values of 'std::float_round_style' (it can even be +synchronized with the underlying single-precision implementation by defining it +to 'std::numeric_limits::round_style'): + + - 'std::round_indeterminate' or -1 for the fastest rounding (default). + + - 'std::round_toward_zero' or 0 for rounding toward zero. + + - std::round_to_nearest' or 1 for rounding to the nearest value. + + - std::round_toward_infinity' or 2 for rounding toward positive infinity. + + - std::round_toward_neg_infinity' or 3 for rounding toward negative infinity. + +In addition to changing the overall default rounding mode one can also use the +'half_cast'. This converts between half and any built-in arithmetic type using +a configurable rounding mode (or the default rounding mode if none is +specified). In addition to a configurable rounding mode, 'half_cast' has +another big difference to a mere 'static_cast': Any conversions are performed +directly using the given rounding mode, without any intermediate conversion +to/from 'float'. This is especially relevant for conversions to integer types, +which don't necessarily truncate anymore. But also for conversions from +'double' or 'long double' this may produce more precise results than a +pre-conversion to 'float' using the single-precision implementation's current +rounding mode would. + + half a = half_cast(4.2); + half b = half_cast::round_style>(4.2f); + assert( half_cast( 0.7_h ) == 1 ); + assert( half_cast( 4097 ) == 4096.0_h ); + assert( half_cast( 4097 ) == 4100.0_h ); + assert( half_cast( std::numeric_limits::min() ) > 0.0_h ); + +When using round to nearest (either as default or through 'half_cast') ties are +by default resolved by rounding them away from zero (and thus equal to the +behaviour of the 'round' function). But by redefining the +'HALF_ROUND_TIES_TO_EVEN' preprocessor symbol to 1 (before including half.hpp) +this default can be changed to the slightly slower but less biased and more +IEEE-conformant behaviour of rounding half-way cases to the nearest even value. + + #define HALF_ROUND_TIES_TO_EVEN 1 + #include + ... + assert( half_cast(3.5_h) + == half_cast(4.5_h) ); + +IMPLEMENTATION + +For performance reasons (and ease of implementation) many of the mathematical +functions provided by the library as well as all arithmetic operations are +actually carried out in single-precision under the hood, calling to the C++ +standard library implementations of those functions whenever appropriate, +meaning the arguments are converted to floats and the result back to half. But +to reduce the conversion overhead as much as possible any temporary values +inside of lengthy expressions are kept in single-precision as long as possible, +while still maintaining a strong half-precision type to the outside world. Only +when finally assigning the value to a half or calling a function that works +directly on halfs is the actual conversion done (or never, when further +converting the result to float. + +This approach has two implications. First of all you have to treat the +library's documentation at http://half.sourceforge.net as a simplified version, +describing the behaviour of the library as if implemented this way. The actual +argument and return types of functions and operators may involve other internal +types (feel free to generate the exact developer documentation from the Doxygen +comments in the library's header file if you really need to). But nevertheless +the behaviour is exactly like specified in the documentation. The other +implication is, that in the presence of rounding errors or over-/underflows +arithmetic expressions may produce different results when compared to +converting to half-precision after each individual operation: + + half a = std::numeric_limits::max() * 2.0_h / 2.0_h; // a = MAX + half b = half(std::numeric_limits::max() * 2.0_h) / 2.0_h; // b = INF + assert( a != b ); + +But this should only be a problem in very few cases. One last word has to be +said when talking about performance. Even with its efforts in reducing +conversion overhead as much as possible, the software half-precision +implementation can most probably not beat the direct use of single-precision +computations. Usually using actual float values for all computations and +temproraries and using halfs only for storage is the recommended way. On the +one hand this somehow makes the provided mathematical functions obsolete +(especially in light of the implicit conversion from half to float), but +nevertheless the goal of this library was to provide a complete and +conceptually clean half-precision implementation, to which the standard +mathematical functions belong, even if usually not needed. + +IEEE CONFORMANCE + +The half type uses the standard IEEE representation with 1 sign bit, 5 exponent +bits and 10 mantissa bits (11 when counting the hidden bit). It supports all +types of special values, like subnormal values, infinity and NaNs. But there +are some limitations to the complete conformance to the IEEE 754 standard: + + - The implementation does not differentiate between signalling and quiet + NaNs, this means operations on halfs are not specified to trap on + signalling NaNs (though they may, see last point). + + - Though arithmetic operations are internally rounded to single-precision + using the underlying single-precision implementation's current rounding + mode, those values are then converted to half-precision using the default + half-precision rounding mode (changed by defining 'HALF_ROUND_STYLE' + accordingly). This mixture of rounding modes is also the reason why + 'std::numeric_limits::round_style' may actually return + 'std::round_indeterminate' when half- and single-precision rounding modes + don't match. + + - Because of internal truncation it may also be that certain single-precision + NaNs will be wrongly converted to half-precision infinity, though this is + very unlikely to happen, since most single-precision implementations don't + tend to only set the lowest bits of a NaN mantissa. + + - The implementation does not provide any floating point exceptions, thus + arithmetic operations or mathematical functions are not specified to invoke + proper floating point exceptions. But due to many functions implemented in + single-precision, those may still invoke floating point exceptions of the + underlying single-precision implementation. + +Some of those points could have been circumvented by controlling the floating +point environment using or implementing a similar exception mechanism. +But this would have required excessive runtime checks giving two high an impact +on performance for something that is rarely ever needed. If you really need to +rely on proper floating point exceptions, it is recommended to explicitly +perform computations using the built-in floating point types to be on the safe +side. In the same way, if you really need to rely on a particular rounding +behaviour, it is recommended to either use single-precision computations and +explicitly convert the result to half-precision using 'half_cast' and +specifying the desired rounding mode, or synchronize the default half-precision +rounding mode to the rounding mode of the single-precision implementation (most +likely 'HALF_ROUND_STYLE=1', 'HALF_ROUND_TIES_TO_EVEN=1'). But this is really +considered an expert-scenario that should be used only when necessary, since +actually working with half-precision usually comes with a certain +tolerance/ignorance of exactness considerations and proper rounding comes with +a certain performance cost. + + +CREDITS AND CONTACT +------------------- + +This library is developed by CHRISTIAN RAU and released under the MIT License +(see LICENSE.txt). If you have any questions or problems with it, feel free to +contact me at rauy@users.sourceforge.net. + +Additional credit goes to JEROEN VAN DER ZIJP for his paper on "Fast Half Float +Conversions", whose algorithms have been used in the library for converting +between half-precision and single-precision values. diff --git a/gpu/third_party/half/docs/.gitignore b/gpu/third_party/half/docs/.gitignore new file mode 100644 index 0000000..734b917 --- /dev/null +++ b/gpu/third_party/half/docs/.gitignore @@ -0,0 +1,5 @@ +_build/ +_doxygen/ +sphinx/_toc.yml +doxygen/html/ +doxygen/xml/ diff --git a/gpu/third_party/half/docs/conf.py b/gpu/third_party/half/docs/conf.py new file mode 100644 index 0000000..f027e34 --- /dev/null +++ b/gpu/third_party/half/docs/conf.py @@ -0,0 +1,35 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +import re + + +html_theme = "rocm_docs_theme" +html_theme_options = {"flavor": "rocm"} + +extensions = ["rocm_docs", "rocm_docs.doxygen"] +external_toc_path = "./sphinx/_toc.yml" +doxygen_root = "doxygen" +doxysphinx_enabled = True +doxygen_project = { + "name": "half", + "path": "doxygen/xml", +} + +with open('../CMakeLists.txt', encoding='utf-8') as f: + match = re.search(r'rocm_setup_version\(VERSION\s+([0-9.]+)', f.read()) + if not match: + raise ValueError("VERSION not found!") + version_number = match[1] + +version = version_number +release = version_number +html_title = f"half {version}" +project = "half" +author = "Advanced Micro Devices, Inc." +copyright = ( + "Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved." +) diff --git a/gpu/third_party/half/docs/doxygen/Doxyfile b/gpu/third_party/half/docs/doxygen/Doxyfile new file mode 100644 index 0000000..28ffa01 --- /dev/null +++ b/gpu/third_party/half/docs/doxygen/Doxyfile @@ -0,0 +1,1890 @@ +# Doxyfile 1.8.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = half + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.12 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "IEEE 754-based half-precision floating point library" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented classes, +# or namespaces to their corresponding documentation. Such a link can be +# prevented in individual cases by by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../../include/half.hpp + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page (index.html). +# This can be useful if you have a project on for instance GitHub and want reuse +# the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = ../_doxygen/header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = ../_doxygen/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = ../_doxygen/stylesheet.css + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = ../_doxygen/extra_stylesheet.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search engine +# library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other +# doxygen projects that are not otherwise connected via tags files, but are +# all added to the same search index. Each project needs to have a tag file set +# via GENERATE_TAGFILE. The search mapping then maps the name of the tag file +# to a relative location where the documentation can be found, similar to the +# TAGFILES option but without actually processing the tag file. +# The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = YES + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = FP_ILOGB0 \ + FP_ILOGBNAN \ + FP_SUBNORMAL \ + FP_ZERO \ + FP_NAN \ + FP_INFINITE \ + FP_NORMAL \ + HALF_ENABLE_CPP11_HASH \ + HALF_ENABLE_CPP11_USER_LITERALS \ + FP_FAST_FMAH \ + HALF_ENABLE_CPP11_CSTDINT \ + HALF_ENABLE_CPP11_CMATH \ + HALF_ENABLE_CPP11_CONSTEXPR \ + HALF_ENABLE_CPP11_LONG_LONG \ + HALF_ENABLE_CPP11_NOEXCEPT \ + HALF_ENABLE_CPP11_TYPE_TRAITS + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = html/tagfile.xml + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = svg + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/gpu/third_party/half/docs/index.rst b/gpu/third_party/half/docs/index.rst new file mode 100644 index 0000000..a1fd9b8 --- /dev/null +++ b/gpu/third_party/half/docs/index.rst @@ -0,0 +1,6 @@ +======= +Home +======= + +.. include:: ../README.txt + :literal: diff --git a/gpu/third_party/half/docs/license.rst b/gpu/third_party/half/docs/license.rst new file mode 100644 index 0000000..af0ca25 --- /dev/null +++ b/gpu/third_party/half/docs/license.rst @@ -0,0 +1,6 @@ +======= +License +======= + +.. include:: ../LICENSE.txt + :literal: diff --git a/gpu/third_party/half/docs/sphinx/_toc.yml.in b/gpu/third_party/half/docs/sphinx/_toc.yml.in new file mode 100644 index 0000000..81b95ad --- /dev/null +++ b/gpu/third_party/half/docs/sphinx/_toc.yml.in @@ -0,0 +1,13 @@ +# Anywhere {branch} is used, the branch name will be substituted. +# These comments will also be removed. +defaults: + numbered: False + maxdepth: 6 +root: index +subtrees: + - caption: API Reference + entries: + - file: doxygen/html/index + - caption: About + entries: + - file: license diff --git a/gpu/third_party/half/docs/sphinx/requirements.in b/gpu/third_party/half/docs/sphinx/requirements.in new file mode 100644 index 0000000..c48f551 --- /dev/null +++ b/gpu/third_party/half/docs/sphinx/requirements.in @@ -0,0 +1 @@ +rocm-docs-core[api_reference]==1.1.1 diff --git a/gpu/third_party/half/docs/sphinx/requirements.txt b/gpu/third_party/half/docs/sphinx/requirements.txt new file mode 100644 index 0000000..65df9c9 --- /dev/null +++ b/gpu/third_party/half/docs/sphinx/requirements.txt @@ -0,0 +1,169 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile requirements.in +# +accessible-pygments==0.0.4 + # via pydata-sphinx-theme +alabaster==0.7.16 + # via sphinx +babel==2.14.0 + # via + # pydata-sphinx-theme + # sphinx +beautifulsoup4==4.12.3 + # via pydata-sphinx-theme +breathe==4.35.0 + # via rocm-docs-core +certifi==2024.2.2 + # via requests +cffi==1.16.0 + # via + # cryptography + # pynacl +charset-normalizer==3.3.2 + # via requests +click==8.1.7 + # via + # click-log + # doxysphinx + # sphinx-external-toc +click-log==0.4.0 + # via doxysphinx +cryptography==42.0.5 + # via pyjwt +deprecated==1.2.14 + # via pygithub +docutils==0.21.2 + # via + # breathe + # myst-parser + # pydata-sphinx-theme + # sphinx +doxysphinx==3.3.8 + # via rocm-docs-core +fastjsonschema==2.19.1 + # via rocm-docs-core +gitdb==4.0.11 + # via gitpython +gitpython==3.1.43 + # via rocm-docs-core +idna==3.7 + # via requests +imagesize==1.4.1 + # via sphinx +jinja2==3.1.3 + # via + # myst-parser + # sphinx +libsass==0.22.0 + # via doxysphinx +lxml==4.9.4 + # via doxysphinx +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.5 + # via jinja2 +mdit-py-plugins==0.4.0 + # via myst-parser +mdurl==0.1.2 + # via markdown-it-py +mpire==2.10.1 + # via doxysphinx +myst-parser==3.0.1 + # via rocm-docs-core +numpy==1.26.4 + # via doxysphinx +packaging==24.0 + # via + # pydata-sphinx-theme + # sphinx +pycparser==2.22 + # via cffi +pydata-sphinx-theme==0.15.2 + # via + # rocm-docs-core + # sphinx-book-theme +pygithub==2.3.0 + # via rocm-docs-core +pygments==2.17.2 + # via + # accessible-pygments + # mpire + # pydata-sphinx-theme + # sphinx +pyjson5==1.6.6 + # via doxysphinx +pyjwt[crypto]==2.8.0 + # via pygithub +pynacl==1.5.0 + # via pygithub +pyparsing==3.1.2 + # via doxysphinx +pyyaml==6.0.1 + # via + # myst-parser + # rocm-docs-core + # sphinx-external-toc +requests==2.31.0 + # via + # pygithub + # sphinx +rocm-docs-core[api_reference]==1.1.1 + # via -r requirements.in +smmap==5.0.1 + # via gitdb +snowballstemmer==2.2.0 + # via sphinx +soupsieve==2.5 + # via beautifulsoup4 +sphinx==7.3.7 + # via + # breathe + # myst-parser + # pydata-sphinx-theme + # rocm-docs-core + # sphinx-book-theme + # sphinx-copybutton + # sphinx-design + # sphinx-external-toc + # sphinx-notfound-page +sphinx-book-theme==1.1.2 + # via rocm-docs-core +sphinx-copybutton==0.5.2 + # via rocm-docs-core +sphinx-design==0.5.0 + # via rocm-docs-core +sphinx-external-toc==1.0.1 + # via rocm-docs-core +sphinx-notfound-page==1.0.0 + # via rocm-docs-core +sphinxcontrib-applehelp==1.0.8 + # via sphinx +sphinxcontrib-devhelp==1.0.6 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.7 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 + # via sphinx +tomli==2.0.1 + # via sphinx +tqdm==4.66.2 + # via mpire +typing-extensions==4.11.0 + # via + # pydata-sphinx-theme + # pygithub +urllib3==2.2.1 + # via + # pygithub + # requests +wrapt==1.16.0 + # via deprecated diff --git a/gpu/third_party/half/half.sln b/gpu/third_party/half/half.sln new file mode 100644 index 0000000..e5059c0 --- /dev/null +++ b/gpu/third_party/half/half.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "half", "half.vcxproj", "{56F458B6-C7BA-49EE-981C-9766A2FAEB7C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web", "web\web.vcxproj", "{B36DE2E9-6E9C-4629-AEDA-8EFAE78E29D0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\projects\vs2015\test.vcxproj", "{3949106C-CB15-4DD5-A1E6-13D5F067EC8C}" + ProjectSection(ProjectDependencies) = postProject + {56F458B6-C7BA-49EE-981C-9766A2FAEB7C} = {56F458B6-C7BA-49EE-981C-9766A2FAEB7C} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {56F458B6-C7BA-49EE-981C-9766A2FAEB7C}.Debug|Win32.ActiveCfg = Debug|Win32 + {56F458B6-C7BA-49EE-981C-9766A2FAEB7C}.Debug|Win32.Build.0 = Debug|Win32 + {56F458B6-C7BA-49EE-981C-9766A2FAEB7C}.Release|Win32.ActiveCfg = Release|Win32 + {56F458B6-C7BA-49EE-981C-9766A2FAEB7C}.Release|Win32.Build.0 = Release|Win32 + {B36DE2E9-6E9C-4629-AEDA-8EFAE78E29D0}.Debug|Win32.ActiveCfg = Debug|Win32 + {B36DE2E9-6E9C-4629-AEDA-8EFAE78E29D0}.Debug|Win32.Build.0 = Debug|Win32 + {B36DE2E9-6E9C-4629-AEDA-8EFAE78E29D0}.Release|Win32.ActiveCfg = Release|Win32 + {B36DE2E9-6E9C-4629-AEDA-8EFAE78E29D0}.Release|Win32.Build.0 = Release|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.ActiveCfg = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.Build.0 = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.ActiveCfg = Release|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/gpu/third_party/half/half.vcxproj b/gpu/third_party/half/half.vcxproj new file mode 100644 index 0000000..4020838 --- /dev/null +++ b/gpu/third_party/half/half.vcxproj @@ -0,0 +1,98 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {56F458B6-C7BA-49EE-981C-9766A2FAEB7C} + Win32Proj + half + + + + Utility + true + Unicode + v140 + + + Utility + false + true + Unicode + v140 + + + + + + + + + + + + + true + $(ProjectName)d + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + Document + "C:\Program Files\doxygen\bin\doxygen.exe" $(InputPath) + "C:\Program Files\doxygen\bin\doxygen.exe" $(InputPath) + Generating Documentation + Generating Documentation + doc + doc + $(ProjectDir)include/half.hpp + $(ProjectDir)include/half.hpp + + + + + + \ No newline at end of file diff --git a/gpu/third_party/half/half.vcxproj.filters b/gpu/third_party/half/half.vcxproj.filters new file mode 100644 index 0000000..530ec03 --- /dev/null +++ b/gpu/third_party/half/half.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Headerdateien + + + + + + \ No newline at end of file diff --git a/gpu/third_party/half/include/half.hpp b/gpu/third_party/half/include/half.hpp new file mode 100644 index 0000000..0d7459b --- /dev/null +++ b/gpu/third_party/half/include/half.hpp @@ -0,0 +1,3068 @@ +// half - IEEE 754-based half-precision floating point library. +// +// Copyright (c) 2012-2017 Christian Rau +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is 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 Software. +// +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Version 1.12.0 + +/// \file +/// Main header file for half precision functionality. + +#ifndef HALF_HALF_HPP +#define HALF_HALF_HPP + +/// Combined gcc version number. +#define HALF_GNUC_VERSION (__GNUC__*100+__GNUC_MINOR__) + +//check C++11 language features +#if defined(__clang__) //clang + #if __has_feature(cxx_static_assert) && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT) + #define HALF_ENABLE_CPP11_STATIC_ASSERT 1 + #endif + #if __has_feature(cxx_constexpr) && !defined(HALF_ENABLE_CPP11_CONSTEXPR) + #define HALF_ENABLE_CPP11_CONSTEXPR 1 + #endif + #if __has_feature(cxx_noexcept) && !defined(HALF_ENABLE_CPP11_NOEXCEPT) + #define HALF_ENABLE_CPP11_NOEXCEPT 1 + #endif + #if __has_feature(cxx_user_literals) && !defined(HALF_ENABLE_CPP11_USER_LITERALS) + #define HALF_ENABLE_CPP11_USER_LITERALS 1 + #endif + #if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) && !defined(HALF_ENABLE_CPP11_LONG_LONG) + #define HALF_ENABLE_CPP11_LONG_LONG 1 + #endif +/*#elif defined(__INTEL_COMPILER) //Intel C++ + #if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT) ???????? + #define HALF_ENABLE_CPP11_STATIC_ASSERT 1 + #endif + #if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_CONSTEXPR) ???????? + #define HALF_ENABLE_CPP11_CONSTEXPR 1 + #endif + #if __INTEL_COMPILER >= 1300 && !defined(HALF_ENABLE_CPP11_NOEXCEPT) ???????? + #define HALF_ENABLE_CPP11_NOEXCEPT 1 + #endif + #if __INTEL_COMPILER >= 1100 && !defined(HALF_ENABLE_CPP11_LONG_LONG) ???????? + #define HALF_ENABLE_CPP11_LONG_LONG 1 + #endif*/ +#elif defined(__GNUC__) //gcc + #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L + #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT) + #define HALF_ENABLE_CPP11_STATIC_ASSERT 1 + #endif + #if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_CONSTEXPR) + #define HALF_ENABLE_CPP11_CONSTEXPR 1 + #endif + #if HALF_GNUC_VERSION >= 406 && !defined(HALF_ENABLE_CPP11_NOEXCEPT) + #define HALF_ENABLE_CPP11_NOEXCEPT 1 + #endif + #if HALF_GNUC_VERSION >= 407 && !defined(HALF_ENABLE_CPP11_USER_LITERALS) + #define HALF_ENABLE_CPP11_USER_LITERALS 1 + #endif + #if !defined(HALF_ENABLE_CPP11_LONG_LONG) + #define HALF_ENABLE_CPP11_LONG_LONG 1 + #endif + #endif +#elif defined(_MSC_VER) //Visual C++ + #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_CONSTEXPR) + #define HALF_ENABLE_CPP11_CONSTEXPR 1 + #endif + #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_NOEXCEPT) + #define HALF_ENABLE_CPP11_NOEXCEPT 1 + #endif + #if _MSC_VER >= 1900 && !defined(HALF_ENABLE_CPP11_USER_LITERALS) + #define HALF_ENABLE_CPP11_USER_LITERALS 1 + #endif + #if _MSC_VER >= 1600 && !defined(HALF_ENABLE_CPP11_STATIC_ASSERT) + #define HALF_ENABLE_CPP11_STATIC_ASSERT 1 + #endif + #if _MSC_VER >= 1310 && !defined(HALF_ENABLE_CPP11_LONG_LONG) + #define HALF_ENABLE_CPP11_LONG_LONG 1 + #endif + #define HALF_POP_WARNINGS 1 + #pragma warning(push) + #pragma warning(disable : 4099 4127 4146) //struct vs class, constant in if, negative unsigned +#endif + +//check C++11 library features +#include +#if defined(_LIBCPP_VERSION) //libc++ + #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103 + #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS + #define HALF_ENABLE_CPP11_TYPE_TRAITS 1 + #endif + #ifndef HALF_ENABLE_CPP11_CSTDINT + #define HALF_ENABLE_CPP11_CSTDINT 1 + #endif + #ifndef HALF_ENABLE_CPP11_CMATH + #define HALF_ENABLE_CPP11_CMATH 1 + #endif + #ifndef HALF_ENABLE_CPP11_HASH + #define HALF_ENABLE_CPP11_HASH 1 + #endif + #endif +#elif defined(__GLIBCXX__) //libstdc++ + #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103 + #ifdef __clang__ + #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_TYPE_TRAITS) + #define HALF_ENABLE_CPP11_TYPE_TRAITS 1 + #endif + #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CSTDINT) + #define HALF_ENABLE_CPP11_CSTDINT 1 + #endif + #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_CMATH) + #define HALF_ENABLE_CPP11_CMATH 1 + #endif + #if __GLIBCXX__ >= 20080606 && !defined(HALF_ENABLE_CPP11_HASH) + #define HALF_ENABLE_CPP11_HASH 1 + #endif + #else + #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CSTDINT) + #define HALF_ENABLE_CPP11_CSTDINT 1 + #endif + #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_CMATH) + #define HALF_ENABLE_CPP11_CMATH 1 + #endif + #if HALF_GNUC_VERSION >= 403 && !defined(HALF_ENABLE_CPP11_HASH) + #define HALF_ENABLE_CPP11_HASH 1 + #endif + #endif + #endif +#elif defined(_CPPLIB_VER) //Dinkumware/Visual C++ + #if _CPPLIB_VER >= 520 + #ifndef HALF_ENABLE_CPP11_TYPE_TRAITS + #define HALF_ENABLE_CPP11_TYPE_TRAITS 1 + #endif + #ifndef HALF_ENABLE_CPP11_CSTDINT + #define HALF_ENABLE_CPP11_CSTDINT 1 + #endif + #ifndef HALF_ENABLE_CPP11_HASH + #define HALF_ENABLE_CPP11_HASH 1 + #endif + #endif + #if _CPPLIB_VER >= 610 + #ifndef HALF_ENABLE_CPP11_CMATH + #define HALF_ENABLE_CPP11_CMATH 1 + #endif + #endif +#endif +#undef HALF_GNUC_VERSION + +//support constexpr +#if HALF_ENABLE_CPP11_CONSTEXPR + #define HALF_CONSTEXPR constexpr + #define HALF_CONSTEXPR_CONST constexpr +#else + #define HALF_CONSTEXPR + #define HALF_CONSTEXPR_CONST const +#endif + +//support noexcept +#if HALF_ENABLE_CPP11_NOEXCEPT + #define HALF_NOEXCEPT noexcept + #define HALF_NOTHROW noexcept +#else + #define HALF_NOEXCEPT + #define HALF_NOTHROW throw() +#endif + +#include +#include +#include +#include +#include +#include +#include +#if HALF_ENABLE_CPP11_TYPE_TRAITS + #include +#endif +#if HALF_ENABLE_CPP11_CSTDINT + #include +#endif +#if HALF_ENABLE_CPP11_HASH + #include +#endif + + +/// Default rounding mode. +/// This specifies the rounding mode used for all conversions between [half](\ref half_float::half)s and `float`s as well as +/// for the half_cast() if not specifying a rounding mode explicitly. It can be redefined (before including half.hpp) to one +/// of the standard rounding modes using their respective constants or the equivalent values of `std::float_round_style`: +/// +/// `std::float_round_style` | value | rounding +/// ---------------------------------|-------|------------------------- +/// `std::round_indeterminate` | -1 | fastest (default) +/// `std::round_toward_zero` | 0 | toward zero +/// `std::round_to_nearest` | 1 | to nearest +/// `std::round_toward_infinity` | 2 | toward positive infinity +/// `std::round_toward_neg_infinity` | 3 | toward negative infinity +/// +/// By default this is set to `-1` (`std::round_indeterminate`), which uses truncation (round toward zero, but with overflows +/// set to infinity) and is the fastest rounding mode possible. It can even be set to `std::numeric_limits::round_style` +/// to synchronize the rounding mode with that of the underlying single-precision implementation. +#ifndef HALF_ROUND_STYLE + #define HALF_ROUND_STYLE -1 // = std::round_indeterminate +#endif + +/// Tie-breaking behaviour for round to nearest. +/// This specifies if ties in round to nearest should be resolved by rounding to the nearest even value. By default this is +/// defined to `0` resulting in the faster but slightly more biased behaviour of rounding away from zero in half-way cases (and +/// thus equal to the round() function), but can be redefined to `1` (before including half.hpp) if more IEEE-conformant +/// behaviour is needed. +#ifndef HALF_ROUND_TIES_TO_EVEN + #define HALF_ROUND_TIES_TO_EVEN 0 // ties away from zero +#endif + +/// Value signaling overflow. +/// In correspondence with `HUGE_VAL[F|L]` from `` this symbol expands to a positive value signaling the overflow of an +/// operation, in particular it just evaluates to positive infinity. +#define HUGE_VALH std::numeric_limits::infinity() + +/// Fast half-precision fma function. +/// This symbol is only defined if the fma() function generally executes as fast as, or faster than, a separate +/// half-precision multiplication followed by an addition. Due to the internal single-precision implementation of all +/// arithmetic operations, this is in fact always the case. +#define FP_FAST_FMAH 1 + +#ifndef FP_ILOGB0 + #define FP_ILOGB0 INT_MIN +#endif +#ifndef FP_ILOGBNAN + #define FP_ILOGBNAN INT_MAX +#endif +#ifndef FP_SUBNORMAL + #define FP_SUBNORMAL 0 +#endif +#ifndef FP_ZERO + #define FP_ZERO 1 +#endif +#ifndef FP_NAN + #define FP_NAN 2 +#endif +#ifndef FP_INFINITE + #define FP_INFINITE 3 +#endif +#ifndef FP_NORMAL + #define FP_NORMAL 4 +#endif + + +/// Main namespace for half precision functionality. +/// This namespace contains all the functionality provided by the library. +namespace half_float +{ + class half; + +#if HALF_ENABLE_CPP11_USER_LITERALS + /// Library-defined half-precision literals. + /// Import this namespace to enable half-precision floating point literals: + /// ~~~~{.cpp} + /// using namespace half_float::literal; + /// half_float::half = 4.2_h; + /// ~~~~ + namespace literal + { + half operator""_h(long double); + } +#endif + + /// \internal + /// \brief Implementation details. + namespace detail + { + #if HALF_ENABLE_CPP11_TYPE_TRAITS + /// Conditional type. + template struct conditional : std::conditional {}; + + /// Helper for tag dispatching. + template struct bool_type : std::integral_constant {}; + using std::true_type; + using std::false_type; + + /// Type traits for floating point types. + template struct is_float : std::is_floating_point {}; + #else + /// Conditional type. + template struct conditional { typedef T type; }; + template struct conditional { typedef F type; }; + + /// Helper for tag dispatching. + template struct bool_type {}; + typedef bool_type true_type; + typedef bool_type false_type; + + /// Type traits for floating point types. + template struct is_float : false_type {}; + template struct is_float : is_float {}; + template struct is_float : is_float {}; + template struct is_float : is_float {}; + template<> struct is_float : true_type {}; + template<> struct is_float : true_type {}; + template<> struct is_float : true_type {}; + #endif + + /// Type traits for floating point bits. + template struct bits { typedef unsigned char type; }; + template struct bits : bits {}; + template struct bits : bits {}; + template struct bits : bits {}; + + #if HALF_ENABLE_CPP11_CSTDINT + /// Unsigned integer of (at least) 16 bits width. + typedef std::uint_least16_t uint16; + + /// Unsigned integer of (at least) 32 bits width. + template<> struct bits { typedef std::uint_least32_t type; }; + + /// Unsigned integer of (at least) 64 bits width. + template<> struct bits { typedef std::uint_least64_t type; }; + #else + /// Unsigned integer of (at least) 16 bits width. + typedef unsigned short uint16; + + /// Unsigned integer of (at least) 32 bits width. + template<> struct bits : conditional::digits>=32,unsigned int,unsigned long> {}; + + #if HALF_ENABLE_CPP11_LONG_LONG + /// Unsigned integer of (at least) 64 bits width. + template<> struct bits : conditional::digits>=64,unsigned long,unsigned long long> {}; + #else + /// Unsigned integer of (at least) 64 bits width. + template<> struct bits { typedef unsigned long type; }; + #endif + #endif + + /// Tag type for binary construction. + struct binary_t {}; + + /// Tag for binary construction. + HALF_CONSTEXPR_CONST binary_t binary = binary_t(); + + /// Temporary half-precision expression. + /// This class represents a half-precision expression which just stores a single-precision value internally. + struct expr + { + /// Conversion constructor. + /// \param f single-precision value to convert + explicit HALF_CONSTEXPR expr(float f) HALF_NOEXCEPT : value_(f) {} + + /// Conversion to single-precision. + /// \return single precision value representing expression value + HALF_CONSTEXPR operator float() const HALF_NOEXCEPT { return value_; } + + private: + /// Internal expression value stored in single-precision. + float value_; + }; + + /// SFINAE helper for generic half-precision functions. + /// This class template has to be specialized for each valid combination of argument types to provide a corresponding + /// `type` member equivalent to \a T. + /// \tparam T type to return + template struct enable {}; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + template struct enable { typedef T type; }; + + /// Return type for specialized generic 2-argument half-precision functions. + /// This class template has to be specialized for each valid combination of argument types to provide a corresponding + /// `type` member denoting the appropriate return type. + /// \tparam T first argument type + /// \tparam U first argument type + template struct result : enable {}; + template<> struct result { typedef half type; }; + + /// \name Classification helpers + /// \{ + + /// Check for infinity. + /// \tparam T argument type (builtin floating point type) + /// \param arg value to query + /// \retval true if infinity + /// \retval false else + template bool builtin_isinf(T arg) + { + #if HALF_ENABLE_CPP11_CMATH + return std::isinf(arg); + #elif defined(_MSC_VER) + return !::_finite(static_cast(arg)) && !::_isnan(static_cast(arg)); + #else + return arg == std::numeric_limits::infinity() || arg == -std::numeric_limits::infinity(); + #endif + } + + /// Check for NaN. + /// \tparam T argument type (builtin floating point type) + /// \param arg value to query + /// \retval true if not a number + /// \retval false else + template bool builtin_isnan(T arg) + { + #if HALF_ENABLE_CPP11_CMATH + return std::isnan(arg); + #elif defined(_MSC_VER) + return ::_isnan(static_cast(arg)) != 0; + #else + return arg != arg; + #endif + } + + /// Check sign. + /// \tparam T argument type (builtin floating point type) + /// \param arg value to query + /// \retval true if signbit set + /// \retval false else + template bool builtin_signbit(T arg) + { + #if HALF_ENABLE_CPP11_CMATH + return std::signbit(arg); + #else + return arg < T() || (arg == T() && T(1)/arg < T()); + #endif + } + + /// \} + /// \name Conversion + /// \{ + + /// Convert IEEE single-precision to half-precision. + /// Credit for this goes to [Jeroen van der Zijp](ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf). + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \param value single-precision value + /// \return binary representation of half-precision value + template uint16 float2half_impl(float value, true_type) + { + typedef bits::type uint32; + uint32 bits;// = *reinterpret_cast(&value); //violating strict aliasing! + std::memcpy(&bits, &value, sizeof(float)); +/* uint16 hbits = (bits>>16) & 0x8000; + bits &= 0x7FFFFFFF; + int exp = bits >> 23; + if(exp == 255) + return hbits | 0x7C00 | (0x3FF&-static_cast((bits&0x7FFFFF)!=0)); + if(exp > 142) + { + if(R == std::round_toward_infinity) + return hbits | 0x7C00 - (hbits>>15); + if(R == std::round_toward_neg_infinity) + return hbits | 0x7BFF + (hbits>>15); + return hbits | 0x7BFF + (R!=std::round_toward_zero); + } + int g, s; + if(exp > 112) + { + g = (bits>>12) & 1; + s = (bits&0xFFF) != 0; + hbits |= ((exp-112)<<10) | ((bits>>13)&0x3FF); + } + else if(exp > 101) + { + int i = 125 - exp; + bits = (bits&0x7FFFFF) | 0x800000; + g = (bits>>i) & 1; + s = (bits&((1L<> (i+1); + } + else + { + g = 0; + s = bits != 0; + } + if(R == std::round_to_nearest) + #if HALF_ROUND_TIES_TO_EVEN + hbits += g & (s|hbits); + #else + hbits += g; + #endif + else if(R == std::round_toward_infinity) + hbits += ~(hbits>>15) & (s|g); + else if(R == std::round_toward_neg_infinity) + hbits += (hbits>>15) & (g|s); +*/ static const uint16 base_table[512] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, + 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7C00, + 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, + 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, + 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, + 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, + 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, + 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, + 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, 0x7C00, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, + 0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00, + 0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFC00, + 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, + 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, + 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, + 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, + 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, + 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, + 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00, 0xFC00 }; + static const unsigned char shift_table[512] = { + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13 }; + uint16 hbits = base_table[bits>>23] + static_cast((bits&0x7FFFFF)>>shift_table[bits>>23]); + if(R == std::round_to_nearest) + hbits += (((bits&0x7FFFFF)>>(shift_table[bits>>23]-1))|(((bits>>23)&0xFF)==102)) & ((hbits&0x7C00)!=0x7C00) + #if HALF_ROUND_TIES_TO_EVEN + & (((((static_cast(1)<<(shift_table[bits>>23]-1))-1)&bits)!=0)|hbits) + #endif + ; + else if(R == std::round_toward_zero) + hbits -= ((hbits&0x7FFF)==0x7C00) & ~shift_table[bits>>23]; + else if(R == std::round_toward_infinity) + hbits += ((((bits&0x7FFFFF&((static_cast(1)<<(shift_table[bits>>23]))-1))!=0)|(((bits>>23)<=102)& + ((bits>>23)!=0)))&(hbits<0x7C00)) - ((hbits==0xFC00)&((bits>>23)!=511)); + else if(R == std::round_toward_neg_infinity) + hbits += ((((bits&0x7FFFFF&((static_cast(1)<<(shift_table[bits>>23]))-1))!=0)|(((bits>>23)<=358)& + ((bits>>23)!=256)))&(hbits<0xFC00)&(hbits>>15)) - ((hbits==0x7C00)&((bits>>23)!=255)); + return hbits; + } + + /// Convert IEEE double-precision to half-precision. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \param value double-precision value + /// \return binary representation of half-precision value + template uint16 float2half_impl(double value, true_type) + { + typedef bits::type uint32; + typedef bits::type uint64; + uint64 bits;// = *reinterpret_cast(&value); //violating strict aliasing! + std::memcpy(&bits, &value, sizeof(double)); + uint32 hi = bits >> 32, lo = bits & 0xFFFFFFFF; + uint16 hbits = (hi>>16) & 0x8000; + hi &= 0x7FFFFFFF; + int exp = hi >> 20; + if(exp == 2047) + return hbits | 0x7C00 | (0x3FF&-static_cast((bits&0xFFFFFFFFFFFFF)!=0)); + if(exp > 1038) + { + if(R == std::round_toward_infinity) + return hbits | 0x7C00 - (hbits>>15); + if(R == std::round_toward_neg_infinity) + return hbits | 0x7BFF + (hbits>>15); + return hbits | 0x7BFF + (R!=std::round_toward_zero); + } + int g, s = lo != 0; + if(exp > 1008) + { + g = (hi>>9) & 1; + s |= (hi&0x1FF) != 0; + hbits |= ((exp-1008)<<10) | ((hi>>10)&0x3FF); + } + else if(exp > 997) + { + int i = 1018 - exp; + hi = (hi&0xFFFFF) | 0x100000; + g = (hi>>i) & 1; + s |= (hi&((1L<> (i+1); + } + else + { + g = 0; + s |= hi != 0; + } + if(R == std::round_to_nearest) + #if HALF_ROUND_TIES_TO_EVEN + hbits += g & (s|hbits); + #else + hbits += g; + #endif + else if(R == std::round_toward_infinity) + hbits += ~(hbits>>15) & (s|g); + else if(R == std::round_toward_neg_infinity) + hbits += (hbits>>15) & (g|s); + return hbits; + } + + /// Convert non-IEEE floating point to half-precision. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \tparam T source type (builtin floating point type) + /// \param value floating point value + /// \return binary representation of half-precision value + template uint16 float2half_impl(T value, ...) + { + uint16 hbits = static_cast(builtin_signbit(value)) << 15; + if(value == T()) + return hbits; + if(builtin_isnan(value)) + return hbits | 0x7FFF; + if(builtin_isinf(value)) + return hbits | 0x7C00; + int exp; + std::frexp(value, &exp); + if(exp > 16) + { + if(R == std::round_toward_infinity) + return hbits | (0x7C00-(hbits>>15)); + else if(R == std::round_toward_neg_infinity) + return hbits | (0x7BFF+(hbits>>15)); + return hbits | (0x7BFF+(R!=std::round_toward_zero)); + } + if(exp < -13) + value = std::ldexp(value, 24); + else + { + value = std::ldexp(value, 11-exp); + hbits |= ((exp+13)<<10); + } + T ival, frac = std::modf(value, &ival); + hbits += static_cast(std::abs(static_cast(ival))); + if(R == std::round_to_nearest) + { + frac = std::abs(frac); + #if HALF_ROUND_TIES_TO_EVEN + hbits += (frac>T(0.5)) | ((frac==T(0.5))&hbits); + #else + hbits += frac >= T(0.5); + #endif + } + else if(R == std::round_toward_infinity) + hbits += frac > T(); + else if(R == std::round_toward_neg_infinity) + hbits += frac < T(); + return hbits; + } + + /// Convert floating point to half-precision. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \tparam T source type (builtin floating point type) + /// \param value floating point value + /// \return binary representation of half-precision value + template uint16 float2half(T value) + { + return float2half_impl(value, bool_type::is_iec559&&sizeof(typename bits::type)==sizeof(T)>()); + } + + /// Convert integer to half-precision floating point. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \tparam S `true` if value negative, `false` else + /// \tparam T type to convert (builtin integer type) + /// \param value non-negative integral value + /// \return binary representation of half-precision value + template uint16 int2half_impl(T value) + { + #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS + static_assert(std::is_integral::value, "int to half conversion only supports builtin integer types"); + #endif + if(S) + value = -value; + uint16 bits = S << 15; + if(value > 0xFFFF) + { + if(R == std::round_toward_infinity) + bits |= 0x7C00 - S; + else if(R == std::round_toward_neg_infinity) + bits |= 0x7BFF + S; + else + bits |= 0x7BFF + (R!=std::round_toward_zero); + } + else if(value) + { + unsigned int m = value, exp = 24; + for(; m<0x400; m<<=1,--exp) ; + for(; m>0x7FF; m>>=1,++exp) ; + bits |= (exp<<10) + m; + if(exp > 24) + { + if(R == std::round_to_nearest) + bits += (value>>(exp-25)) & 1 + #if HALF_ROUND_TIES_TO_EVEN + & (((((1<<(exp-25))-1)&value)!=0)|bits) + #endif + ; + else if(R == std::round_toward_infinity) + bits += ((value&((1<<(exp-24))-1))!=0) & !S; + else if(R == std::round_toward_neg_infinity) + bits += ((value&((1<<(exp-24))-1))!=0) & S; + } + } + return bits; + } + + /// Convert integer to half-precision floating point. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \tparam T type to convert (builtin integer type) + /// \param value integral value + /// \return binary representation of half-precision value + template uint16 int2half(T value) + { + return (value<0) ? int2half_impl(value) : int2half_impl(value); + } + + /// Convert half-precision to IEEE single-precision. + /// Credit for this goes to [Jeroen van der Zijp](ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf). + /// \param value binary representation of half-precision value + /// \return single-precision value + inline float half2float_impl(uint16 value, float, true_type) + { + typedef bits::type uint32; +/* uint32 bits = static_cast(value&0x8000) << 16; + int abs = value & 0x7FFF; + if(abs) + { + bits |= 0x38000000 << static_cast(abs>=0x7C00); + for(; abs<0x400; abs<<=1,bits-=0x800000) ; + bits += static_cast(abs) << 13; + } +*/ static const uint32 mantissa_table[2048] = { + 0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000, + 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000, + 0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000, + 0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000, + 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000, + 0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000, + 0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000, + 0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000, + 0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000, + 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000, + 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000, + 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000, + 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000, + 0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000, + 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000, + 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000, + 0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000, + 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000, + 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000, + 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000, + 0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000, + 0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000, + 0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000, + 0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000, + 0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000, + 0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000, + 0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000, + 0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000, + 0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000, + 0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000, + 0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000, + 0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000, + 0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000, + 0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000, + 0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000, + 0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000, + 0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000, + 0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000, + 0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000, + 0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000, + 0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000, + 0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000, + 0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000, + 0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000, + 0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000, + 0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000, + 0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000, + 0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000, + 0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000, + 0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000, + 0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000, + 0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000, + 0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000, + 0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000, + 0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000, + 0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000, + 0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000, + 0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000, + 0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000, + 0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000, + 0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000, + 0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000, + 0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000, + 0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000, + 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000, + 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000, + 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000, + 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000, + 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000, + 0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000, + 0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000, + 0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000, + 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000, + 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000, + 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000, + 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000, + 0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000, + 0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000, + 0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000, + 0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000, + 0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000, + 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000, + 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000, + 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000, + 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000, + 0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000, + 0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000, + 0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000, + 0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000, + 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000, + 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000, + 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000, + 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000, + 0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000, + 0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000, + 0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000, + 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000, + 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000, + 0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000, + 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000, + 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000, + 0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000, + 0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000, + 0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000, + 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000, + 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000, + 0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000, + 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000, + 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000, + 0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000, + 0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000, + 0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000, + 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000, + 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000, + 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000, + 0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000, + 0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000, + 0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000, + 0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000, + 0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000, + 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000, + 0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000, + 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000, + 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000, + 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000, + 0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000, + 0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000, + 0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 }; + static const uint32 exponent_table[64] = { + 0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000, + 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000, + 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000, + 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 }; + static const unsigned short offset_table[64] = { + 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 }; + uint32 bits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10]; +// return *reinterpret_cast(&bits); //violating strict aliasing! + float out; + std::memcpy(&out, &bits, sizeof(float)); + return out; + } + + /// Convert half-precision to IEEE double-precision. + /// \param value binary representation of half-precision value + /// \return double-precision value + inline double half2float_impl(uint16 value, double, true_type) + { + typedef bits::type uint32; + typedef bits::type uint64; + uint32 hi = static_cast(value&0x8000) << 16; + int abs = value & 0x7FFF; + if(abs) + { + hi |= 0x3F000000 << static_cast(abs>=0x7C00); + for(; abs<0x400; abs<<=1,hi-=0x100000) ; + hi += static_cast(abs) << 10; + } + uint64 bits = static_cast(hi) << 32; +// return *reinterpret_cast(&bits); //violating strict aliasing! + double out; + std::memcpy(&out, &bits, sizeof(double)); + return out; + } + + /// Convert half-precision to non-IEEE floating point. + /// \tparam T type to convert to (builtin integer type) + /// \param value binary representation of half-precision value + /// \return floating point value + template T half2float_impl(uint16 value, T, ...) + { + T out; + int abs = value & 0x7FFF; + if(abs > 0x7C00) + out = std::numeric_limits::has_quiet_NaN ? std::numeric_limits::quiet_NaN() : T(); + else if(abs == 0x7C00) + out = std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max(); + else if(abs > 0x3FF) + out = std::ldexp(static_cast((abs&0x3FF)|0x400), (abs>>10)-25); + else + out = std::ldexp(static_cast(abs), -24); + return (value&0x8000) ? -out : out; + } + + /// Convert half-precision to floating point. + /// \tparam T type to convert to (builtin integer type) + /// \param value binary representation of half-precision value + /// \return floating point value + template T half2float(uint16 value) + { + return half2float_impl(value, T(), bool_type::is_iec559&&sizeof(typename bits::type)==sizeof(T)>()); + } + + /// Convert half-precision floating point to integer. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \tparam E `true` for round to even, `false` for round away from zero + /// \tparam T type to convert to (buitlin integer type with at least 16 bits precision, excluding any implicit sign bits) + /// \param value binary representation of half-precision value + /// \return integral value + template T half2int_impl(uint16 value) + { + #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS + static_assert(std::is_integral::value, "half to int conversion only supports builtin integer types"); + #endif + unsigned int e = value & 0x7FFF; + if(e >= 0x7C00) + return (value&0x8000) ? std::numeric_limits::min() : std::numeric_limits::max(); + if(e < 0x3800) + { + if(R == std::round_toward_infinity) + return T(~(value>>15)&(e!=0)); + else if(R == std::round_toward_neg_infinity) + return -T(value>0x8000); + return T(); + } + unsigned int m = (value&0x3FF) | 0x400; + e >>= 10; + if(e < 25) + { + if(R == std::round_to_nearest) + m += (1<<(24-e)) - (~(m>>(25-e))&E); + else if(R == std::round_toward_infinity) + m += ((value>>15)-1) & ((1<<(25-e))-1U); + else if(R == std::round_toward_neg_infinity) + m += -(value>>15) & ((1<<(25-e))-1U); + m >>= 25 - e; + } + else + m <<= e - 25; + return (value&0x8000) ? -static_cast(m) : static_cast(m); + } + + /// Convert half-precision floating point to integer. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \tparam T type to convert to (buitlin integer type with at least 16 bits precision, excluding any implicit sign bits) + /// \param value binary representation of half-precision value + /// \return integral value + template T half2int(uint16 value) { return half2int_impl(value); } + + /// Convert half-precision floating point to integer using round-to-nearest-away-from-zero. + /// \tparam T type to convert to (buitlin integer type with at least 16 bits precision, excluding any implicit sign bits) + /// \param value binary representation of half-precision value + /// \return integral value + template T half2int_up(uint16 value) { return half2int_impl(value); } + + /// Round half-precision number to nearest integer value. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \tparam E `true` for round to even, `false` for round away from zero + /// \param value binary representation of half-precision value + /// \return half-precision bits for nearest integral value + template uint16 round_half_impl(uint16 value) + { + unsigned int e = value & 0x7FFF; + uint16 result = value; + if(e < 0x3C00) + { + result &= 0x8000; + if(R == std::round_to_nearest) + result |= 0x3C00U & -(e>=(0x3800+E)); + else if(R == std::round_toward_infinity) + result |= 0x3C00U & -(~(value>>15)&(e!=0)); + else if(R == std::round_toward_neg_infinity) + result |= 0x3C00U & -(value>0x8000); + } + else if(e < 0x6400) + { + e = 25 - (e>>10); + unsigned int mask = (1<>e)&E); + else if(R == std::round_toward_infinity) + result += mask & ((value>>15)-1); + else if(R == std::round_toward_neg_infinity) + result += mask & -(value>>15); + result &= ~mask; + } + return result; + } + + /// Round half-precision number to nearest integer value. + /// \tparam R rounding mode to use, `std::round_indeterminate` for fastest rounding + /// \param value binary representation of half-precision value + /// \return half-precision bits for nearest integral value + template uint16 round_half(uint16 value) { return round_half_impl(value); } + + /// Round half-precision number to nearest integer value using round-to-nearest-away-from-zero. + /// \param value binary representation of half-precision value + /// \return half-precision bits for nearest integral value + inline uint16 round_half_up(uint16 value) { return round_half_impl(value); } + /// \} + + struct functions; + template struct unary_specialized; + template struct binary_specialized; + template struct half_caster; + } + + /// Half-precision floating point type. + /// This class implements an IEEE-conformant half-precision floating point type with the usual arithmetic operators and + /// conversions. It is implicitly convertible to single-precision floating point, which makes artihmetic expressions and + /// functions with mixed-type operands to be of the most precise operand type. Additionally all arithmetic operations + /// (and many mathematical functions) are carried out in single-precision internally. All conversions from single- to + /// half-precision are done using the library's default rounding mode, but temporary results inside chained arithmetic + /// expressions are kept in single-precision as long as possible (while of course still maintaining a strong half-precision type). + /// + /// According to the C++98/03 definition, the half type is not a POD type. But according to C++11's less strict and + /// extended definitions it is both a standard layout type and a trivially copyable type (even if not a POD type), which + /// means it can be standard-conformantly copied using raw binary copies. But in this context some more words about the + /// actual size of the type. Although the half is representing an IEEE 16-bit type, it does not neccessarily have to be of + /// exactly 16-bits size. But on any reasonable implementation the actual binary representation of this type will most + /// probably not ivolve any additional "magic" or padding beyond the simple binary representation of the underlying 16-bit + /// IEEE number, even if not strictly guaranteed by the standard. But even then it only has an actual size of 16 bits if + /// your C++ implementation supports an unsigned integer type of exactly 16 bits width. But this should be the case on + /// nearly any reasonable platform. + /// + /// So if your C++ implementation is not totally exotic or imposes special alignment requirements, it is a reasonable + /// assumption that the data of a half is just comprised of the 2 bytes of the underlying IEEE representation. + class half + { + friend struct detail::functions; + friend struct detail::unary_specialized; + friend struct detail::binary_specialized; + template friend struct detail::half_caster; + friend class std::numeric_limits; + #if HALF_ENABLE_CPP11_HASH + friend struct std::hash; + #endif + #if HALF_ENABLE_CPP11_USER_LITERALS + friend half literal::operator""_h(long double); + #endif + + public: + /// Default constructor. + /// This initializes the half to 0. Although this does not match the builtin types' default-initialization semantics + /// and may be less efficient than no initialization, it is needed to provide proper value-initialization semantics. + HALF_CONSTEXPR half() HALF_NOEXCEPT : data_() {} + + /// Copy constructor. + /// \tparam T type of concrete half expression + /// \param rhs half expression to copy from + half(detail::expr rhs) : data_(detail::float2half(static_cast(rhs))) {} + + /// Conversion constructor. + /// \param rhs float to convert + explicit half(float rhs) : data_(detail::float2half(rhs)) {} + + /// Conversion to single-precision. + /// \return single precision value representing expression value + operator float() const { return detail::half2float(data_); } + + /// Assignment operator. + /// \tparam T type of concrete half expression + /// \param rhs half expression to copy from + /// \return reference to this half + half& operator=(detail::expr rhs) { return *this = static_cast(rhs); } + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to add + /// \return reference to this half + template typename detail::enable::type operator+=(T rhs) { return *this += static_cast(rhs); } + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to subtract + /// \return reference to this half + template typename detail::enable::type operator-=(T rhs) { return *this -= static_cast(rhs); } + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to multiply with + /// \return reference to this half + template typename detail::enable::type operator*=(T rhs) { return *this *= static_cast(rhs); } + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to divide by + /// \return reference to this half + template typename detail::enable::type operator/=(T rhs) { return *this /= static_cast(rhs); } + + /// Assignment operator. + /// \param rhs single-precision value to copy from + /// \return reference to this half + half& operator=(float rhs) { data_ = detail::float2half(rhs); return *this; } + + /// Arithmetic assignment. + /// \param rhs single-precision value to add + /// \return reference to this half + half& operator+=(float rhs) { data_ = detail::float2half(detail::half2float(data_)+rhs); return *this; } + + /// Arithmetic assignment. + /// \param rhs single-precision value to subtract + /// \return reference to this half + half& operator-=(float rhs) { data_ = detail::float2half(detail::half2float(data_)-rhs); return *this; } + + /// Arithmetic assignment. + /// \param rhs single-precision value to multiply with + /// \return reference to this half + half& operator*=(float rhs) { data_ = detail::float2half(detail::half2float(data_)*rhs); return *this; } + + /// Arithmetic assignment. + /// \param rhs single-precision value to divide by + /// \return reference to this half + half& operator/=(float rhs) { data_ = detail::float2half(detail::half2float(data_)/rhs); return *this; } + + /// Prefix increment. + /// \return incremented half value + half& operator++() { return *this += 1.0f; } + + /// Prefix decrement. + /// \return decremented half value + half& operator--() { return *this -= 1.0f; } + + /// Postfix increment. + /// \return non-incremented half value + half operator++(int) { half out(*this); ++*this; return out; } + + /// Postfix decrement. + /// \return non-decremented half value + half operator--(int) { half out(*this); --*this; return out; } + + private: + /// Rounding mode to use + static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE); + + /// Constructor. + /// \param bits binary representation to set half to + HALF_CONSTEXPR half(detail::binary_t, detail::uint16 bits) HALF_NOEXCEPT : data_(bits) {} + + /// Internal binary representation + detail::uint16 data_; + }; + +#if HALF_ENABLE_CPP11_USER_LITERALS + namespace literal + { + /// Half literal. + /// While this returns an actual half-precision value, half literals can unfortunately not be constant expressions due + /// to rather involved conversions. + /// \param value literal value + /// \return half with given value (if representable) + inline half operator""_h(long double value) { return half(detail::binary, detail::float2half(value)); } + } +#endif + + namespace detail + { + /// Wrapper implementing unspecialized half-precision functions. + struct functions + { + /// Addition implementation. + /// \param x first operand + /// \param y second operand + /// \return Half-precision sum stored in single-precision + static expr plus(float x, float y) { return expr(x+y); } + + /// Subtraction implementation. + /// \param x first operand + /// \param y second operand + /// \return Half-precision difference stored in single-precision + static expr minus(float x, float y) { return expr(x-y); } + + /// Multiplication implementation. + /// \param x first operand + /// \param y second operand + /// \return Half-precision product stored in single-precision + static expr multiplies(float x, float y) { return expr(x*y); } + + /// Division implementation. + /// \param x first operand + /// \param y second operand + /// \return Half-precision quotient stored in single-precision + static expr divides(float x, float y) { return expr(x/y); } + + /// Output implementation. + /// \param out stream to write to + /// \param arg value to write + /// \return reference to stream + template static std::basic_ostream& write(std::basic_ostream &out, float arg) { return out << arg; } + + /// Input implementation. + /// \param in stream to read from + /// \param arg half to read into + /// \return reference to stream + template static std::basic_istream& read(std::basic_istream &in, half &arg) + { + float f; + if(in >> f) + arg = f; + return in; + } + + /// Modulo implementation. + /// \param x first operand + /// \param y second operand + /// \return Half-precision division remainder stored in single-precision + static expr fmod(float x, float y) { return expr(std::fmod(x, y)); } + + /// Remainder implementation. + /// \param x first operand + /// \param y second operand + /// \return Half-precision division remainder stored in single-precision + static expr remainder(float x, float y) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::remainder(x, y)); + #else + if(builtin_isnan(x) || builtin_isnan(y)) + return expr(std::numeric_limits::quiet_NaN()); + float ax = std::fabs(x), ay = std::fabs(y); + if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24)) + return expr(std::numeric_limits::quiet_NaN()); + if(ay >= 65536.0f) + return expr(x); + if(ax == ay) + return expr(builtin_signbit(x) ? -0.0f : 0.0f); + ax = std::fmod(ax, ay+ay); + float y2 = 0.5f * ay; + if(ax > y2) + { + ax -= ay; + if(ax >= y2) + ax -= ay; + } + return expr(builtin_signbit(x) ? -ax : ax); + #endif + } + + /// Remainder implementation. + /// \param x first operand + /// \param y second operand + /// \param quo address to store quotient bits at + /// \return Half-precision division remainder stored in single-precision + static expr remquo(float x, float y, int *quo) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::remquo(x, y, quo)); + #else + if(builtin_isnan(x) || builtin_isnan(y)) + return expr(std::numeric_limits::quiet_NaN()); + bool sign = builtin_signbit(x), qsign = static_cast(sign^builtin_signbit(y)); + float ax = std::fabs(x), ay = std::fabs(y); + if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24)) + return expr(std::numeric_limits::quiet_NaN()); + if(ay >= 65536.0f) + return expr(x); + if(ax == ay) + return *quo = qsign ? -1 : 1, expr(sign ? -0.0f : 0.0f); + ax = std::fmod(ax, 8.0f*ay); + int cquo = 0; + if(ax >= 4.0f * ay) + { + ax -= 4.0f * ay; + cquo += 4; + } + if(ax >= 2.0f * ay) + { + ax -= 2.0f * ay; + cquo += 2; + } + float y2 = 0.5f * ay; + if(ax > y2) + { + ax -= ay; + ++cquo; + if(ax >= y2) + { + ax -= ay; + ++cquo; + } + } + return *quo = qsign ? -cquo : cquo, expr(sign ? -ax : ax); + #endif + } + + /// Positive difference implementation. + /// \param x first operand + /// \param y second operand + /// \return Positive difference stored in single-precision + static expr fdim(float x, float y) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::fdim(x, y)); + #else + return expr((x<=y) ? 0.0f : (x-y)); + #endif + } + + /// Fused multiply-add implementation. + /// \param x first operand + /// \param y second operand + /// \param z third operand + /// \return \a x * \a y + \a z stored in single-precision + static expr fma(float x, float y, float z) + { + #if HALF_ENABLE_CPP11_CMATH && defined(FP_FAST_FMAF) + return expr(std::fma(x, y, z)); + #else + return expr(x*y+z); + #endif + } + + /// Get NaN. + /// \return Half-precision quiet NaN + static half nanh() { return half(binary, 0x7FFF); } + + /// Exponential implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr exp(float arg) { return expr(std::exp(arg)); } + + /// Exponential implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr expm1(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::expm1(arg)); + #else + return expr(static_cast(std::exp(static_cast(arg))-1.0)); + #endif + } + + /// Binary exponential implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr exp2(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::exp2(arg)); + #else + return expr(static_cast(std::exp(arg*0.69314718055994530941723212145818))); + #endif + } + + /// Logarithm implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr log(float arg) { return expr(std::log(arg)); } + + /// Common logarithm implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr log10(float arg) { return expr(std::log10(arg)); } + + /// Logarithm implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr log1p(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::log1p(arg)); + #else + return expr(static_cast(std::log(1.0+arg))); + #endif + } + + /// Binary logarithm implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr log2(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::log2(arg)); + #else + return expr(static_cast(std::log(static_cast(arg))*1.4426950408889634073599246810019)); + #endif + } + + /// Square root implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr sqrt(float arg) { return expr(std::sqrt(arg)); } + + /// Cubic root implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr cbrt(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::cbrt(arg)); + #else + if(builtin_isnan(arg) || builtin_isinf(arg)) + return expr(arg); + return expr(builtin_signbit(arg) ? -static_cast(std::pow(-static_cast(arg), 1.0/3.0)) : + static_cast(std::pow(static_cast(arg), 1.0/3.0))); + #endif + } + + /// Hypotenuse implementation. + /// \param x first argument + /// \param y second argument + /// \return function value stored in single-preicision + static expr hypot(float x, float y) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::hypot(x, y)); + #else + return expr((builtin_isinf(x) || builtin_isinf(y)) ? std::numeric_limits::infinity() : + static_cast(std::sqrt(static_cast(x)*x+static_cast(y)*y))); + #endif + } + + /// Power implementation. + /// \param base value to exponentiate + /// \param exp power to expontiate to + /// \return function value stored in single-preicision + static expr pow(float base, float exp) { return expr(std::pow(base, exp)); } + + /// Sine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr sin(float arg) { return expr(std::sin(arg)); } + + /// Cosine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr cos(float arg) { return expr(std::cos(arg)); } + + /// Tan implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr tan(float arg) { return expr(std::tan(arg)); } + + /// Arc sine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr asin(float arg) { return expr(std::asin(arg)); } + + /// Arc cosine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr acos(float arg) { return expr(std::acos(arg)); } + + /// Arc tangent implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr atan(float arg) { return expr(std::atan(arg)); } + + /// Arc tangent implementation. + /// \param x first argument + /// \param y second argument + /// \return function value stored in single-preicision + static expr atan2(float x, float y) { return expr(std::atan2(x, y)); } + + /// Hyperbolic sine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr sinh(float arg) { return expr(std::sinh(arg)); } + + /// Hyperbolic cosine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr cosh(float arg) { return expr(std::cosh(arg)); } + + /// Hyperbolic tangent implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr tanh(float arg) { return expr(std::tanh(arg)); } + + /// Hyperbolic area sine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr asinh(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::asinh(arg)); + #else + return expr((arg==-std::numeric_limits::infinity()) ? arg : static_cast(std::log(arg+std::sqrt(arg*arg+1.0)))); + #endif + } + + /// Hyperbolic area cosine implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr acosh(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::acosh(arg)); + #else + return expr((arg<-1.0f) ? std::numeric_limits::quiet_NaN() : static_cast(std::log(arg+std::sqrt(arg*arg-1.0)))); + #endif + } + + /// Hyperbolic area tangent implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr atanh(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::atanh(arg)); + #else + return expr(static_cast(0.5*std::log((1.0+arg)/(1.0-arg)))); + #endif + } + + /// Error function implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr erf(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::erf(arg)); + #else + return expr(static_cast(erf(static_cast(arg)))); + #endif + } + + /// Complementary implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr erfc(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::erfc(arg)); + #else + return expr(static_cast(1.0-erf(static_cast(arg)))); + #endif + } + + /// Gamma logarithm implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr lgamma(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::lgamma(arg)); + #else + if(builtin_isinf(arg)) + return expr(std::numeric_limits::infinity()); + if(arg < 0.0f) + { + float i, f = std::modf(-arg, &i); + if(f == 0.0f) + return expr(std::numeric_limits::infinity()); + return expr(static_cast(1.1447298858494001741434273513531- + std::log(std::abs(std::sin(3.1415926535897932384626433832795*f)))-lgamma(1.0-arg))); + } + return expr(static_cast(lgamma(static_cast(arg)))); + #endif + } + + /// Gamma implementation. + /// \param arg function argument + /// \return function value stored in single-preicision + static expr tgamma(float arg) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::tgamma(arg)); + #else + if(arg == 0.0f) + return builtin_signbit(arg) ? expr(-std::numeric_limits::infinity()) : expr(std::numeric_limits::infinity()); + if(arg < 0.0f) + { + float i, f = std::modf(-arg, &i); + if(f == 0.0f) + return expr(std::numeric_limits::quiet_NaN()); + double value = 3.1415926535897932384626433832795 / (std::sin(3.1415926535897932384626433832795*f)*std::exp(lgamma(1.0-arg))); + return expr(static_cast((std::fmod(i, 2.0f)==0.0f) ? -value : value)); + } + if(builtin_isinf(arg)) + return expr(arg); + return expr(static_cast(std::exp(lgamma(static_cast(arg))))); + #endif + } + + /// Floor implementation. + /// \param arg value to round + /// \return rounded value + static half floor(half arg) { return half(binary, round_half(arg.data_)); } + + /// Ceiling implementation. + /// \param arg value to round + /// \return rounded value + static half ceil(half arg) { return half(binary, round_half(arg.data_)); } + + /// Truncation implementation. + /// \param arg value to round + /// \return rounded value + static half trunc(half arg) { return half(binary, round_half(arg.data_)); } + + /// Nearest integer implementation. + /// \param arg value to round + /// \return rounded value + static half round(half arg) { return half(binary, round_half_up(arg.data_)); } + + /// Nearest integer implementation. + /// \param arg value to round + /// \return rounded value + static long lround(half arg) { return detail::half2int_up(arg.data_); } + + /// Nearest integer implementation. + /// \param arg value to round + /// \return rounded value + static half rint(half arg) { return half(binary, round_half(arg.data_)); } + + /// Nearest integer implementation. + /// \param arg value to round + /// \return rounded value + static long lrint(half arg) { return detail::half2int(arg.data_); } + + #if HALF_ENABLE_CPP11_LONG_LONG + /// Nearest integer implementation. + /// \param arg value to round + /// \return rounded value + static long long llround(half arg) { return detail::half2int_up(arg.data_); } + + /// Nearest integer implementation. + /// \param arg value to round + /// \return rounded value + static long long llrint(half arg) { return detail::half2int(arg.data_); } + #endif + + /// Decompression implementation. + /// \param arg number to decompress + /// \param exp address to store exponent at + /// \return normalized significant + static half frexp(half arg, int *exp) + { + int m = arg.data_ & 0x7FFF, e = -14; + if(m >= 0x7C00 || !m) + return *exp = 0, arg; + for(; m<0x400; m<<=1,--e) ; + return *exp = e+(m>>10), half(binary, (arg.data_&0x8000)|0x3800|(m&0x3FF)); + } + + /// Decompression implementation. + /// \param arg number to decompress + /// \param iptr address to store integer part at + /// \return fractional part + static half modf(half arg, half *iptr) + { + unsigned int e = arg.data_ & 0x7FFF; + if(e >= 0x6400) + return *iptr = arg, half(binary, arg.data_&(0x8000U|-(e>0x7C00))); + if(e < 0x3C00) + return iptr->data_ = arg.data_ & 0x8000, arg; + e >>= 10; + unsigned int mask = (1<<(25-e)) - 1, m = arg.data_ & mask; + iptr->data_ = arg.data_ & ~mask; + if(!m) + return half(binary, arg.data_&0x8000); + for(; m<0x400; m<<=1,--e) ; + return half(binary, static_cast((arg.data_&0x8000)|(e<<10)|(m&0x3FF))); + } + + /// Scaling implementation. + /// \param arg number to scale + /// \param exp power of two to scale by + /// \return scaled number + static half scalbln(half arg, long exp) + { + unsigned int m = arg.data_ & 0x7FFF; + if(m >= 0x7C00 || !m) + return arg; + for(; m<0x400; m<<=1,--exp) ; + exp += m >> 10; + uint16 value = arg.data_ & 0x8000; + if(exp > 30) + { + if(half::round_style == std::round_toward_zero) + value |= 0x7BFF; + else if(half::round_style == std::round_toward_infinity) + value |= 0x7C00 - (value>>15); + else if(half::round_style == std::round_toward_neg_infinity) + value |= 0x7BFF + (value>>15); + else + value |= 0x7C00; + } + else if(exp > 0) + value |= (exp<<10) | (m&0x3FF); + else if(exp > -11) + { + m = (m&0x3FF) | 0x400; + if(half::round_style == std::round_to_nearest) + { + m += 1 << -exp; + #if HALF_ROUND_TIES_TO_EVEN + m -= (m>>(1-exp)) & 1; + #endif + } + else if(half::round_style == std::round_toward_infinity) + m += ((value>>15)-1) & ((1<<(1-exp))-1U); + else if(half::round_style == std::round_toward_neg_infinity) + m += -(value>>15) & ((1<<(1-exp))-1U); + value |= m >> (1-exp); + } + else if(half::round_style == std::round_toward_infinity) + value -= (value>>15) - 1; + else if(half::round_style == std::round_toward_neg_infinity) + value += value >> 15; + return half(binary, value); + } + + /// Exponent implementation. + /// \param arg number to query + /// \return floating point exponent + static int ilogb(half arg) + { + int abs = arg.data_ & 0x7FFF; + if(!abs) + return FP_ILOGB0; + if(abs < 0x7C00) + { + int exp = (abs>>10) - 15; + if(abs < 0x400) + for(; abs<0x200; abs<<=1,--exp) ; + return exp; + } + if(abs > 0x7C00) + return FP_ILOGBNAN; + return INT_MAX; + } + + /// Exponent implementation. + /// \param arg number to query + /// \return floating point exponent + static half logb(half arg) + { + int abs = arg.data_ & 0x7FFF; + if(!abs) + return half(binary, 0xFC00); + if(abs < 0x7C00) + { + int exp = (abs>>10) - 15; + if(abs < 0x400) + for(; abs<0x200; abs<<=1,--exp) ; + uint16 bits = (exp<0) << 15; + if(exp) + { + unsigned int m = std::abs(exp) << 6, e = 18; + for(; m<0x400; m<<=1,--e) ; + bits |= (e<<10) + m; + } + return half(binary, bits); + } + if(abs > 0x7C00) + return arg; + return half(binary, 0x7C00); + } + + /// Enumeration implementation. + /// \param from number to increase/decrease + /// \param to direction to enumerate into + /// \return next representable number + static half nextafter(half from, half to) + { + uint16 fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF; + if(fabs > 0x7C00) + return from; + if(tabs > 0x7C00 || from.data_ == to.data_ || !(fabs|tabs)) + return to; + if(!fabs) + return half(binary, (to.data_&0x8000)+1); + bool lt = ((fabs==from.data_) ? static_cast(fabs) : -static_cast(fabs)) < + ((tabs==to.data_) ? static_cast(tabs) : -static_cast(tabs)); + return half(binary, from.data_+(((from.data_>>15)^static_cast(lt))<<1)-1); + } + + /// Enumeration implementation. + /// \param from number to increase/decrease + /// \param to direction to enumerate into + /// \return next representable number + static half nexttoward(half from, long double to) + { + if(isnan(from)) + return from; + long double lfrom = static_cast(from); + if(builtin_isnan(to) || lfrom == to) + return half(static_cast(to)); + if(!(from.data_&0x7FFF)) + return half(binary, (static_cast(builtin_signbit(to))<<15)+1); + return half(binary, from.data_+(((from.data_>>15)^static_cast(lfrom0x3FF) ? ((abs>=0x7C00) ? ((abs>0x7C00) ? FP_NAN : FP_INFINITE) : FP_NORMAL) :FP_SUBNORMAL) : FP_ZERO; + } + + /// Classification implementation. + /// \param arg value to classify + /// \retval true if finite number + /// \retval false else + static bool isfinite(half arg) { return (arg.data_&0x7C00) != 0x7C00; } + + /// Classification implementation. + /// \param arg value to classify + /// \retval true if infinite number + /// \retval false else + static bool isinf(half arg) { return (arg.data_&0x7FFF) == 0x7C00; } + + /// Classification implementation. + /// \param arg value to classify + /// \retval true if not a number + /// \retval false else + static bool isnan(half arg) { return (arg.data_&0x7FFF) > 0x7C00; } + + /// Classification implementation. + /// \param arg value to classify + /// \retval true if normal number + /// \retval false else + static bool isnormal(half arg) { return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); } + + /// Sign bit implementation. + /// \param arg value to check + /// \retval true if signed + /// \retval false if unsigned + static bool signbit(half arg) { return (arg.data_&0x8000) != 0; } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if operands equal + /// \retval false else + static bool isequal(half x, half y) { return (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF)) && !isnan(x); } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if operands not equal + /// \retval false else + static bool isnotequal(half x, half y) { return (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF)) || isnan(x); } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x > \a y + /// \retval false else + static bool isgreater(half x, half y) + { + int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF; + return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) > ((yabs==y.data_) ? yabs : -yabs)); + } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x >= \a y + /// \retval false else + static bool isgreaterequal(half x, half y) + { + int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF; + return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) >= ((yabs==y.data_) ? yabs : -yabs)); + } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x < \a y + /// \retval false else + static bool isless(half x, half y) + { + int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF; + return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) < ((yabs==y.data_) ? yabs : -yabs)); + } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x <= \a y + /// \retval false else + static bool islessequal(half x, half y) + { + int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF; + return xabs<=0x7C00 && yabs<=0x7C00 && (((xabs==x.data_) ? xabs : -xabs) <= ((yabs==y.data_) ? yabs : -yabs)); + } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if either \a x > \a y nor \a x < \a y + /// \retval false else + static bool islessgreater(half x, half y) + { + int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF; + if(xabs > 0x7C00 || yabs > 0x7C00) + return false; + int a = (xabs==x.data_) ? xabs : -xabs, b = (yabs==y.data_) ? yabs : -yabs; + return a < b || a > b; + } + + /// Comparison implementation. + /// \param x first operand + /// \param y second operand + /// \retval true if operand unordered + /// \retval false else + static bool isunordered(half x, half y) { return isnan(x) || isnan(y); } + + private: + static double erf(double arg) + { + if(builtin_isinf(arg)) + return (arg<0.0) ? -1.0 : 1.0; + double x2 = arg * arg, ax2 = 0.147 * x2, value = std::sqrt(1.0-std::exp(-x2*(1.2732395447351626861510701069801+ax2)/(1.0+ax2))); + return builtin_signbit(arg) ? -value : value; + } + + static double lgamma(double arg) + { + double v = 1.0; + for(; arg<8.0; ++arg) v *= arg; + double w = 1.0 / (arg*arg); + return (((((((-0.02955065359477124183006535947712*w+0.00641025641025641025641025641026)*w+ + -0.00191752691752691752691752691753)*w+8.4175084175084175084175084175084e-4)*w+ + -5.952380952380952380952380952381e-4)*w+7.9365079365079365079365079365079e-4)*w+ + -0.00277777777777777777777777777778)*w+0.08333333333333333333333333333333)/arg + + 0.91893853320467274178032973640562 - std::log(v) - arg + (arg-0.5) * std::log(arg); + } + }; + + /// Wrapper for unary half-precision functions needing specialization for individual argument types. + /// \tparam T argument type + template struct unary_specialized + { + /// Negation implementation. + /// \param arg value to negate + /// \return negated value + static HALF_CONSTEXPR half negate(half arg) { return half(binary, arg.data_^0x8000); } + + /// Absolute value implementation. + /// \param arg function argument + /// \return absolute value + static half fabs(half arg) { return half(binary, arg.data_&0x7FFF); } + }; + template<> struct unary_specialized + { + static HALF_CONSTEXPR expr negate(float arg) { return expr(-arg); } + static expr fabs(float arg) { return expr(std::fabs(arg)); } + }; + + /// Wrapper for binary half-precision functions needing specialization for individual argument types. + /// \tparam T first argument type + /// \tparam U first argument type + template struct binary_specialized + { + /// Minimum implementation. + /// \param x first operand + /// \param y second operand + /// \return minimum value + static expr fmin(float x, float y) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::fmin(x, y)); + #else + if(builtin_isnan(x)) + return expr(y); + if(builtin_isnan(y)) + return expr(x); + return expr(std::min(x, y)); + #endif + } + + /// Maximum implementation. + /// \param x first operand + /// \param y second operand + /// \return maximum value + static expr fmax(float x, float y) + { + #if HALF_ENABLE_CPP11_CMATH + return expr(std::fmax(x, y)); + #else + if(builtin_isnan(x)) + return expr(y); + if(builtin_isnan(y)) + return expr(x); + return expr(std::max(x, y)); + #endif + } + }; + template<> struct binary_specialized + { + static half fmin(half x, half y) + { + int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF; + if(xabs > 0x7C00) + return y; + if(yabs > 0x7C00) + return x; + return (((xabs==x.data_) ? xabs : -xabs) > ((yabs==y.data_) ? yabs : -yabs)) ? y : x; + } + static half fmax(half x, half y) + { + int xabs = x.data_ & 0x7FFF, yabs = y.data_ & 0x7FFF; + if(xabs > 0x7C00) + return y; + if(yabs > 0x7C00) + return x; + return (((xabs==x.data_) ? xabs : -xabs) < ((yabs==y.data_) ? yabs : -yabs)) ? y : x; + } + }; + + /// Helper class for half casts. + /// This class template has to be specialized for all valid cast argument to define an appropriate static `cast` member + /// function and a corresponding `type` member denoting its return type. + /// \tparam T destination type + /// \tparam U source type + /// \tparam R rounding mode to use + template struct half_caster {}; + template struct half_caster + { + #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS + static_assert(std::is_arithmetic::value, "half_cast from non-arithmetic type unsupported"); + #endif + + static half cast(U arg) { return cast_impl(arg, is_float()); }; + + private: + static half cast_impl(U arg, true_type) { return half(binary, float2half(arg)); } + static half cast_impl(U arg, false_type) { return half(binary, int2half(arg)); } + }; + template struct half_caster + { + #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS + static_assert(std::is_arithmetic::value, "half_cast to non-arithmetic type unsupported"); + #endif + + static T cast(half arg) { return cast_impl(arg, is_float()); } + + private: + static T cast_impl(half arg, true_type) { return half2float(arg.data_); } + static T cast_impl(half arg, false_type) { return half2int(arg.data_); } + }; + template struct half_caster + { + #if HALF_ENABLE_CPP11_STATIC_ASSERT && HALF_ENABLE_CPP11_TYPE_TRAITS + static_assert(std::is_arithmetic::value, "half_cast to non-arithmetic type unsupported"); + #endif + + static T cast(expr arg) { return cast_impl(arg, is_float()); } + + private: + static T cast_impl(float arg, true_type) { return static_cast(arg); } + static T cast_impl(half arg, false_type) { return half2int(arg.data_); } + }; + template struct half_caster + { + static half cast(half arg) { return arg; } + }; + template struct half_caster : half_caster {}; + + /// \name Comparison operators + /// \{ + + /// Comparison for equality. + /// \param x first operand + /// \param y second operand + /// \retval true if operands equal + /// \retval false else + template typename enable::type operator==(T x, U y) { return functions::isequal(x, y); } + + /// Comparison for inequality. + /// \param x first operand + /// \param y second operand + /// \retval true if operands not equal + /// \retval false else + template typename enable::type operator!=(T x, U y) { return functions::isnotequal(x, y); } + + /// Comparison for less than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less than \a y + /// \retval false else + template typename enable::type operator<(T x, U y) { return functions::isless(x, y); } + + /// Comparison for greater than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater than \a y + /// \retval false else + template typename enable::type operator>(T x, U y) { return functions::isgreater(x, y); } + + /// Comparison for less equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less equal \a y + /// \retval false else + template typename enable::type operator<=(T x, U y) { return functions::islessequal(x, y); } + + /// Comparison for greater equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater equal \a y + /// \retval false else + template typename enable::type operator>=(T x, U y) { return functions::isgreaterequal(x, y); } + + /// \} + /// \name Arithmetic operators + /// \{ + + /// Add halfs. + /// \param x left operand + /// \param y right operand + /// \return sum of half expressions + template typename enable::type operator+(T x, U y) { return functions::plus(x, y); } + + /// Subtract halfs. + /// \param x left operand + /// \param y right operand + /// \return difference of half expressions + template typename enable::type operator-(T x, U y) { return functions::minus(x, y); } + + /// Multiply halfs. + /// \param x left operand + /// \param y right operand + /// \return product of half expressions + template typename enable::type operator*(T x, U y) { return functions::multiplies(x, y); } + + /// Divide halfs. + /// \param x left operand + /// \param y right operand + /// \return quotient of half expressions + template typename enable::type operator/(T x, U y) { return functions::divides(x, y); } + + /// Identity. + /// \param arg operand + /// \return uncahnged operand + template HALF_CONSTEXPR typename enable::type operator+(T arg) { return arg; } + + /// Negation. + /// \param arg operand + /// \return negated operand + template HALF_CONSTEXPR typename enable::type operator-(T arg) { return unary_specialized::negate(arg); } + + /// \} + /// \name Input and output + /// \{ + + /// Output operator. + /// \param out output stream to write into + /// \param arg half expression to write + /// \return reference to output stream + template typename enable&,T>::type + operator<<(std::basic_ostream &out, T arg) { return functions::write(out, arg); } + + /// Input operator. + /// \param in input stream to read from + /// \param arg half to read into + /// \return reference to input stream + template std::basic_istream& + operator>>(std::basic_istream &in, half &arg) { return functions::read(in, arg); } + + /// \} + /// \name Basic mathematical operations + /// \{ + + /// Absolute value. + /// \param arg operand + /// \return absolute value of \a arg +// template typename enable::type abs(T arg) { return unary_specialized::fabs(arg); } + inline half abs(half arg) { return unary_specialized::fabs(arg); } + inline expr abs(expr arg) { return unary_specialized::fabs(arg); } + + /// Absolute value. + /// \param arg operand + /// \return absolute value of \a arg +// template typename enable::type fabs(T arg) { return unary_specialized::fabs(arg); } + inline half fabs(half arg) { return unary_specialized::fabs(arg); } + inline expr fabs(expr arg) { return unary_specialized::fabs(arg); } + + /// Remainder of division. + /// \param x first operand + /// \param y second operand + /// \return remainder of floating point division. +// template typename enable::type fmod(T x, U y) { return functions::fmod(x, y); } + inline expr fmod(half x, half y) { return functions::fmod(x, y); } + inline expr fmod(half x, expr y) { return functions::fmod(x, y); } + inline expr fmod(expr x, half y) { return functions::fmod(x, y); } + inline expr fmod(expr x, expr y) { return functions::fmod(x, y); } + + /// Remainder of division. + /// \param x first operand + /// \param y second operand + /// \return remainder of floating point division. +// template typename enable::type remainder(T x, U y) { return functions::remainder(x, y); } + inline expr remainder(half x, half y) { return functions::remainder(x, y); } + inline expr remainder(half x, expr y) { return functions::remainder(x, y); } + inline expr remainder(expr x, half y) { return functions::remainder(x, y); } + inline expr remainder(expr x, expr y) { return functions::remainder(x, y); } + + /// Remainder of division. + /// \param x first operand + /// \param y second operand + /// \param quo address to store some bits of quotient at + /// \return remainder of floating point division. +// template typename enable::type remquo(T x, U y, int *quo) { return functions::remquo(x, y, quo); } + inline expr remquo(half x, half y, int *quo) { return functions::remquo(x, y, quo); } + inline expr remquo(half x, expr y, int *quo) { return functions::remquo(x, y, quo); } + inline expr remquo(expr x, half y, int *quo) { return functions::remquo(x, y, quo); } + inline expr remquo(expr x, expr y, int *quo) { return functions::remquo(x, y, quo); } + + /// Fused multiply add. + /// \param x first operand + /// \param y second operand + /// \param z third operand + /// \return ( \a x * \a y ) + \a z rounded as one operation. +// template typename enable::type fma(T x, U y, V z) { return functions::fma(x, y, z); } + inline expr fma(half x, half y, half z) { return functions::fma(x, y, z); } + inline expr fma(half x, half y, expr z) { return functions::fma(x, y, z); } + inline expr fma(half x, expr y, half z) { return functions::fma(x, y, z); } + inline expr fma(half x, expr y, expr z) { return functions::fma(x, y, z); } + inline expr fma(expr x, half y, half z) { return functions::fma(x, y, z); } + inline expr fma(expr x, half y, expr z) { return functions::fma(x, y, z); } + inline expr fma(expr x, expr y, half z) { return functions::fma(x, y, z); } + inline expr fma(expr x, expr y, expr z) { return functions::fma(x, y, z); } + + /// Maximum of half expressions. + /// \param x first operand + /// \param y second operand + /// \return maximum of operands +// template typename result::type fmax(T x, U y) { return binary_specialized::fmax(x, y); } + inline half fmax(half x, half y) { return binary_specialized::fmax(x, y); } + inline expr fmax(half x, expr y) { return binary_specialized::fmax(x, y); } + inline expr fmax(expr x, half y) { return binary_specialized::fmax(x, y); } + inline expr fmax(expr x, expr y) { return binary_specialized::fmax(x, y); } + + /// Minimum of half expressions. + /// \param x first operand + /// \param y second operand + /// \return minimum of operands +// template typename result::type fmin(T x, U y) { return binary_specialized::fmin(x, y); } + inline half fmin(half x, half y) { return binary_specialized::fmin(x, y); } + inline expr fmin(half x, expr y) { return binary_specialized::fmin(x, y); } + inline expr fmin(expr x, half y) { return binary_specialized::fmin(x, y); } + inline expr fmin(expr x, expr y) { return binary_specialized::fmin(x, y); } + + /// Positive difference. + /// \param x first operand + /// \param y second operand + /// \return \a x - \a y or 0 if difference negative +// template typename enable::type fdim(T x, U y) { return functions::fdim(x, y); } + inline expr fdim(half x, half y) { return functions::fdim(x, y); } + inline expr fdim(half x, expr y) { return functions::fdim(x, y); } + inline expr fdim(expr x, half y) { return functions::fdim(x, y); } + inline expr fdim(expr x, expr y) { return functions::fdim(x, y); } + + /// Get NaN value. + /// \return quiet NaN + inline half nanh(const char*) { return functions::nanh(); } + + /// \} + /// \name Exponential functions + /// \{ + + /// Exponential function. + /// \param arg function argument + /// \return e raised to \a arg +// template typename enable::type exp(T arg) { return functions::exp(arg); } + inline expr exp(half arg) { return functions::exp(arg); } + inline expr exp(expr arg) { return functions::exp(arg); } + + /// Exponential minus one. + /// \param arg function argument + /// \return e raised to \a arg subtracted by 1 +// template typename enable::type expm1(T arg) { return functions::expm1(arg); } + inline expr expm1(half arg) { return functions::expm1(arg); } + inline expr expm1(expr arg) { return functions::expm1(arg); } + + /// Binary exponential. + /// \param arg function argument + /// \return 2 raised to \a arg +// template typename enable::type exp2(T arg) { return functions::exp2(arg); } + inline expr exp2(half arg) { return functions::exp2(arg); } + inline expr exp2(expr arg) { return functions::exp2(arg); } + + /// Natural logorithm. + /// \param arg function argument + /// \return logarithm of \a arg to base e +// template typename enable::type log(T arg) { return functions::log(arg); } + inline expr log(half arg) { return functions::log(arg); } + inline expr log(expr arg) { return functions::log(arg); } + + /// Common logorithm. + /// \param arg function argument + /// \return logarithm of \a arg to base 10 +// template typename enable::type log10(T arg) { return functions::log10(arg); } + inline expr log10(half arg) { return functions::log10(arg); } + inline expr log10(expr arg) { return functions::log10(arg); } + + /// Natural logorithm. + /// \param arg function argument + /// \return logarithm of \a arg plus 1 to base e +// template typename enable::type log1p(T arg) { return functions::log1p(arg); } + inline expr log1p(half arg) { return functions::log1p(arg); } + inline expr log1p(expr arg) { return functions::log1p(arg); } + + /// Binary logorithm. + /// \param arg function argument + /// \return logarithm of \a arg to base 2 +// template typename enable::type log2(T arg) { return functions::log2(arg); } + inline expr log2(half arg) { return functions::log2(arg); } + inline expr log2(expr arg) { return functions::log2(arg); } + + /// \} + /// \name Power functions + /// \{ + + /// Square root. + /// \param arg function argument + /// \return square root of \a arg +// template typename enable::type sqrt(T arg) { return functions::sqrt(arg); } + inline expr sqrt(half arg) { return functions::sqrt(arg); } + inline expr sqrt(expr arg) { return functions::sqrt(arg); } + + /// Cubic root. + /// \param arg function argument + /// \return cubic root of \a arg +// template typename enable::type cbrt(T arg) { return functions::cbrt(arg); } + inline expr cbrt(half arg) { return functions::cbrt(arg); } + inline expr cbrt(expr arg) { return functions::cbrt(arg); } + + /// Hypotenuse function. + /// \param x first argument + /// \param y second argument + /// \return square root of sum of squares without internal over- or underflows +// template typename enable::type hypot(T x, U y) { return functions::hypot(x, y); } + inline expr hypot(half x, half y) { return functions::hypot(x, y); } + inline expr hypot(half x, expr y) { return functions::hypot(x, y); } + inline expr hypot(expr x, half y) { return functions::hypot(x, y); } + inline expr hypot(expr x, expr y) { return functions::hypot(x, y); } + + /// Power function. + /// \param base first argument + /// \param exp second argument + /// \return \a base raised to \a exp +// template typename enable::type pow(T base, U exp) { return functions::pow(base, exp); } + inline expr pow(half base, half exp) { return functions::pow(base, exp); } + inline expr pow(half base, expr exp) { return functions::pow(base, exp); } + inline expr pow(expr base, half exp) { return functions::pow(base, exp); } + inline expr pow(expr base, expr exp) { return functions::pow(base, exp); } + + /// \} + /// \name Trigonometric functions + /// \{ + + /// Sine function. + /// \param arg function argument + /// \return sine value of \a arg +// template typename enable::type sin(T arg) { return functions::sin(arg); } + inline expr sin(half arg) { return functions::sin(arg); } + inline expr sin(expr arg) { return functions::sin(arg); } + + /// Cosine function. + /// \param arg function argument + /// \return cosine value of \a arg +// template typename enable::type cos(T arg) { return functions::cos(arg); } + inline expr cos(half arg) { return functions::cos(arg); } + inline expr cos(expr arg) { return functions::cos(arg); } + + /// Tangent function. + /// \param arg function argument + /// \return tangent value of \a arg +// template typename enable::type tan(T arg) { return functions::tan(arg); } + inline expr tan(half arg) { return functions::tan(arg); } + inline expr tan(expr arg) { return functions::tan(arg); } + + /// Arc sine. + /// \param arg function argument + /// \return arc sine value of \a arg +// template typename enable::type asin(T arg) { return functions::asin(arg); } + inline expr asin(half arg) { return functions::asin(arg); } + inline expr asin(expr arg) { return functions::asin(arg); } + + /// Arc cosine function. + /// \param arg function argument + /// \return arc cosine value of \a arg +// template typename enable::type acos(T arg) { return functions::acos(arg); } + inline expr acos(half arg) { return functions::acos(arg); } + inline expr acos(expr arg) { return functions::acos(arg); } + + /// Arc tangent function. + /// \param arg function argument + /// \return arc tangent value of \a arg +// template typename enable::type atan(T arg) { return functions::atan(arg); } + inline expr atan(half arg) { return functions::atan(arg); } + inline expr atan(expr arg) { return functions::atan(arg); } + + /// Arc tangent function. + /// \param x first argument + /// \param y second argument + /// \return arc tangent value +// template typename enable::type atan2(T x, U y) { return functions::atan2(x, y); } + inline expr atan2(half x, half y) { return functions::atan2(x, y); } + inline expr atan2(half x, expr y) { return functions::atan2(x, y); } + inline expr atan2(expr x, half y) { return functions::atan2(x, y); } + inline expr atan2(expr x, expr y) { return functions::atan2(x, y); } + + /// \} + /// \name Hyperbolic functions + /// \{ + + /// Hyperbolic sine. + /// \param arg function argument + /// \return hyperbolic sine value of \a arg +// template typename enable::type sinh(T arg) { return functions::sinh(arg); } + inline expr sinh(half arg) { return functions::sinh(arg); } + inline expr sinh(expr arg) { return functions::sinh(arg); } + + /// Hyperbolic cosine. + /// \param arg function argument + /// \return hyperbolic cosine value of \a arg +// template typename enable::type cosh(T arg) { return functions::cosh(arg); } + inline expr cosh(half arg) { return functions::cosh(arg); } + inline expr cosh(expr arg) { return functions::cosh(arg); } + + /// Hyperbolic tangent. + /// \param arg function argument + /// \return hyperbolic tangent value of \a arg +// template typename enable::type tanh(T arg) { return functions::tanh(arg); } + inline expr tanh(half arg) { return functions::tanh(arg); } + inline expr tanh(expr arg) { return functions::tanh(arg); } + + /// Hyperbolic area sine. + /// \param arg function argument + /// \return area sine value of \a arg +// template typename enable::type asinh(T arg) { return functions::asinh(arg); } + inline expr asinh(half arg) { return functions::asinh(arg); } + inline expr asinh(expr arg) { return functions::asinh(arg); } + + /// Hyperbolic area cosine. + /// \param arg function argument + /// \return area cosine value of \a arg +// template typename enable::type acosh(T arg) { return functions::acosh(arg); } + inline expr acosh(half arg) { return functions::acosh(arg); } + inline expr acosh(expr arg) { return functions::acosh(arg); } + + /// Hyperbolic area tangent. + /// \param arg function argument + /// \return area tangent value of \a arg +// template typename enable::type atanh(T arg) { return functions::atanh(arg); } + inline expr atanh(half arg) { return functions::atanh(arg); } + inline expr atanh(expr arg) { return functions::atanh(arg); } + + /// \} + /// \name Error and gamma functions + /// \{ + + /// Error function. + /// \param arg function argument + /// \return error function value of \a arg +// template typename enable::type erf(T arg) { return functions::erf(arg); } + inline expr erf(half arg) { return functions::erf(arg); } + inline expr erf(expr arg) { return functions::erf(arg); } + + /// Complementary error function. + /// \param arg function argument + /// \return 1 minus error function value of \a arg +// template typename enable::type erfc(T arg) { return functions::erfc(arg); } + inline expr erfc(half arg) { return functions::erfc(arg); } + inline expr erfc(expr arg) { return functions::erfc(arg); } + + /// Natural logarithm of gamma function. + /// \param arg function argument + /// \return natural logarith of gamma function for \a arg +// template typename enable::type lgamma(T arg) { return functions::lgamma(arg); } + inline expr lgamma(half arg) { return functions::lgamma(arg); } + inline expr lgamma(expr arg) { return functions::lgamma(arg); } + + /// Gamma function. + /// \param arg function argument + /// \return gamma function value of \a arg +// template typename enable::type tgamma(T arg) { return functions::tgamma(arg); } + inline expr tgamma(half arg) { return functions::tgamma(arg); } + inline expr tgamma(expr arg) { return functions::tgamma(arg); } + + /// \} + /// \name Rounding + /// \{ + + /// Nearest integer not less than half value. + /// \param arg half to round + /// \return nearest integer not less than \a arg +// template typename enable::type ceil(T arg) { return functions::ceil(arg); } + inline half ceil(half arg) { return functions::ceil(arg); } + inline half ceil(expr arg) { return functions::ceil(arg); } + + /// Nearest integer not greater than half value. + /// \param arg half to round + /// \return nearest integer not greater than \a arg +// template typename enable::type floor(T arg) { return functions::floor(arg); } + inline half floor(half arg) { return functions::floor(arg); } + inline half floor(expr arg) { return functions::floor(arg); } + + /// Nearest integer not greater in magnitude than half value. + /// \param arg half to round + /// \return nearest integer not greater in magnitude than \a arg +// template typename enable::type trunc(T arg) { return functions::trunc(arg); } + inline half trunc(half arg) { return functions::trunc(arg); } + inline half trunc(expr arg) { return functions::trunc(arg); } + + /// Nearest integer. + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases +// template typename enable::type round(T arg) { return functions::round(arg); } + inline half round(half arg) { return functions::round(arg); } + inline half round(expr arg) { return functions::round(arg); } + + /// Nearest integer. + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases +// template typename enable::type lround(T arg) { return functions::lround(arg); } + inline long lround(half arg) { return functions::lround(arg); } + inline long lround(expr arg) { return functions::lround(arg); } + + /// Nearest integer using half's internal rounding mode. + /// \param arg half expression to round + /// \return nearest integer using default rounding mode +// template typename enable::type nearbyint(T arg) { return functions::nearbyint(arg); } + inline half nearbyint(half arg) { return functions::rint(arg); } + inline half nearbyint(expr arg) { return functions::rint(arg); } + + /// Nearest integer using half's internal rounding mode. + /// \param arg half expression to round + /// \return nearest integer using default rounding mode +// template typename enable::type rint(T arg) { return functions::rint(arg); } + inline half rint(half arg) { return functions::rint(arg); } + inline half rint(expr arg) { return functions::rint(arg); } + + /// Nearest integer using half's internal rounding mode. + /// \param arg half expression to round + /// \return nearest integer using default rounding mode +// template typename enable::type lrint(T arg) { return functions::lrint(arg); } + inline long lrint(half arg) { return functions::lrint(arg); } + inline long lrint(expr arg) { return functions::lrint(arg); } + #if HALF_ENABLE_CPP11_LONG_LONG + /// Nearest integer. + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases +// template typename enable::type llround(T arg) { return functions::llround(arg); } + inline long long llround(half arg) { return functions::llround(arg); } + inline long long llround(expr arg) { return functions::llround(arg); } + + /// Nearest integer using half's internal rounding mode. + /// \param arg half expression to round + /// \return nearest integer using default rounding mode +// template typename enable::type llrint(T arg) { return functions::llrint(arg); } + inline long long llrint(half arg) { return functions::llrint(arg); } + inline long long llrint(expr arg) { return functions::llrint(arg); } + #endif + + /// \} + /// \name Floating point manipulation + /// \{ + + /// Decompress floating point number. + /// \param arg number to decompress + /// \param exp address to store exponent at + /// \return significant in range [0.5, 1) +// template typename enable::type frexp(T arg, int *exp) { return functions::frexp(arg, exp); } + inline half frexp(half arg, int *exp) { return functions::frexp(arg, exp); } + inline half frexp(expr arg, int *exp) { return functions::frexp(arg, exp); } + + /// Multiply by power of two. + /// \param arg number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp +// template typename enable::type ldexp(T arg, int exp) { return functions::scalbln(arg, exp); } + inline half ldexp(half arg, int exp) { return functions::scalbln(arg, exp); } + inline half ldexp(expr arg, int exp) { return functions::scalbln(arg, exp); } + + /// Extract integer and fractional parts. + /// \param arg number to decompress + /// \param iptr address to store integer part at + /// \return fractional part +// template typename enable::type modf(T arg, half *iptr) { return functions::modf(arg, iptr); } + inline half modf(half arg, half *iptr) { return functions::modf(arg, iptr); } + inline half modf(expr arg, half *iptr) { return functions::modf(arg, iptr); } + + /// Multiply by power of two. + /// \param arg number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp +// template typename enable::type scalbn(T arg, int exp) { return functions::scalbln(arg, exp); } + inline half scalbn(half arg, int exp) { return functions::scalbln(arg, exp); } + inline half scalbn(expr arg, int exp) { return functions::scalbln(arg, exp); } + + /// Multiply by power of two. + /// \param arg number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp +// template typename enable::type scalbln(T arg, long exp) { return functions::scalbln(arg, exp); } + inline half scalbln(half arg, long exp) { return functions::scalbln(arg, exp); } + inline half scalbln(expr arg, long exp) { return functions::scalbln(arg, exp); } + + /// Extract exponent. + /// \param arg number to query + /// \return floating point exponent + /// \retval FP_ILOGB0 for zero + /// \retval FP_ILOGBNAN for NaN + /// \retval MAX_INT for infinity +// template typename enable::type ilogb(T arg) { return functions::ilogb(arg); } + inline int ilogb(half arg) { return functions::ilogb(arg); } + inline int ilogb(expr arg) { return functions::ilogb(arg); } + + /// Extract exponent. + /// \param arg number to query + /// \return floating point exponent +// template typename enable::type logb(T arg) { return functions::logb(arg); } + inline half logb(half arg) { return functions::logb(arg); } + inline half logb(expr arg) { return functions::logb(arg); } + + /// Next representable value. + /// \param from value to compute next representable value for + /// \param to direction towards which to compute next value + /// \return next representable value after \a from in direction towards \a to +// template typename enable::type nextafter(T from, U to) { return functions::nextafter(from, to); } + inline half nextafter(half from, half to) { return functions::nextafter(from, to); } + inline half nextafter(half from, expr to) { return functions::nextafter(from, to); } + inline half nextafter(expr from, half to) { return functions::nextafter(from, to); } + inline half nextafter(expr from, expr to) { return functions::nextafter(from, to); } + + /// Next representable value. + /// \param from value to compute next representable value for + /// \param to direction towards which to compute next value + /// \return next representable value after \a from in direction towards \a to +// template typename enable::type nexttoward(T from, long double to) { return functions::nexttoward(from, to); } + inline half nexttoward(half from, long double to) { return functions::nexttoward(from, to); } + inline half nexttoward(expr from, long double to) { return functions::nexttoward(from, to); } + + /// Take sign. + /// \param x value to change sign for + /// \param y value to take sign from + /// \return value equal to \a x in magnitude and to \a y in sign +// template typename enable::type copysign(T x, U y) { return functions::copysign(x, y); } + inline half copysign(half x, half y) { return functions::copysign(x, y); } + inline half copysign(half x, expr y) { return functions::copysign(x, y); } + inline half copysign(expr x, half y) { return functions::copysign(x, y); } + inline half copysign(expr x, expr y) { return functions::copysign(x, y); } + + /// \} + /// \name Floating point classification + /// \{ + + + /// Classify floating point value. + /// \param arg number to classify + /// \retval FP_ZERO for positive and negative zero + /// \retval FP_SUBNORMAL for subnormal numbers + /// \retval FP_INFINITY for positive and negative infinity + /// \retval FP_NAN for NaNs + /// \retval FP_NORMAL for all other (normal) values +// template typename enable::type fpclassify(T arg) { return functions::fpclassify(arg); } + inline int fpclassify(half arg) { return functions::fpclassify(arg); } + inline int fpclassify(expr arg) { return functions::fpclassify(arg); } + + /// Check if finite number. + /// \param arg number to check + /// \retval true if neither infinity nor NaN + /// \retval false else +// template typename enable::type isfinite(T arg) { return functions::isfinite(arg); } + inline bool isfinite(half arg) { return functions::isfinite(arg); } + inline bool isfinite(expr arg) { return functions::isfinite(arg); } + + /// Check for infinity. + /// \param arg number to check + /// \retval true for positive or negative infinity + /// \retval false else +// template typename enable::type isinf(T arg) { return functions::isinf(arg); } + inline bool isinf(half arg) { return functions::isinf(arg); } + inline bool isinf(expr arg) { return functions::isinf(arg); } + + /// Check for NaN. + /// \param arg number to check + /// \retval true for NaNs + /// \retval false else +// template typename enable::type isnan(T arg) { return functions::isnan(arg); } + inline bool isnan(half arg) { return functions::isnan(arg); } + inline bool isnan(expr arg) { return functions::isnan(arg); } + + /// Check if normal number. + /// \param arg number to check + /// \retval true if normal number + /// \retval false if either subnormal, zero, infinity or NaN +// template typename enable::type isnormal(T arg) { return functions::isnormal(arg); } + inline bool isnormal(half arg) { return functions::isnormal(arg); } + inline bool isnormal(expr arg) { return functions::isnormal(arg); } + + /// Check sign. + /// \param arg number to check + /// \retval true for negative number + /// \retval false for positive number +// template typename enable::type signbit(T arg) { return functions::signbit(arg); } + inline bool signbit(half arg) { return functions::signbit(arg); } + inline bool signbit(expr arg) { return functions::signbit(arg); } + + /// \} + /// \name Comparison + /// \{ + + /// Comparison for greater than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater than \a y + /// \retval false else +// template typename enable::type isgreater(T x, U y) { return functions::isgreater(x, y); } + inline bool isgreater(half x, half y) { return functions::isgreater(x, y); } + inline bool isgreater(half x, expr y) { return functions::isgreater(x, y); } + inline bool isgreater(expr x, half y) { return functions::isgreater(x, y); } + inline bool isgreater(expr x, expr y) { return functions::isgreater(x, y); } + + /// Comparison for greater equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater equal \a y + /// \retval false else +// template typename enable::type isgreaterequal(T x, U y) { return functions::isgreaterequal(x, y); } + inline bool isgreaterequal(half x, half y) { return functions::isgreaterequal(x, y); } + inline bool isgreaterequal(half x, expr y) { return functions::isgreaterequal(x, y); } + inline bool isgreaterequal(expr x, half y) { return functions::isgreaterequal(x, y); } + inline bool isgreaterequal(expr x, expr y) { return functions::isgreaterequal(x, y); } + + /// Comparison for less than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less than \a y + /// \retval false else +// template typename enable::type isless(T x, U y) { return functions::isless(x, y); } + inline bool isless(half x, half y) { return functions::isless(x, y); } + inline bool isless(half x, expr y) { return functions::isless(x, y); } + inline bool isless(expr x, half y) { return functions::isless(x, y); } + inline bool isless(expr x, expr y) { return functions::isless(x, y); } + + /// Comparison for less equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less equal \a y + /// \retval false else +// template typename enable::type islessequal(T x, U y) { return functions::islessequal(x, y); } + inline bool islessequal(half x, half y) { return functions::islessequal(x, y); } + inline bool islessequal(half x, expr y) { return functions::islessequal(x, y); } + inline bool islessequal(expr x, half y) { return functions::islessequal(x, y); } + inline bool islessequal(expr x, expr y) { return functions::islessequal(x, y); } + + /// Comarison for less or greater. + /// \param x first operand + /// \param y second operand + /// \retval true if either less or greater + /// \retval false else +// template typename enable::type islessgreater(T x, U y) { return functions::islessgreater(x, y); } + inline bool islessgreater(half x, half y) { return functions::islessgreater(x, y); } + inline bool islessgreater(half x, expr y) { return functions::islessgreater(x, y); } + inline bool islessgreater(expr x, half y) { return functions::islessgreater(x, y); } + inline bool islessgreater(expr x, expr y) { return functions::islessgreater(x, y); } + + /// Check if unordered. + /// \param x first operand + /// \param y second operand + /// \retval true if unordered (one or two NaN operands) + /// \retval false else +// template typename enable::type isunordered(T x, U y) { return functions::isunordered(x, y); } + inline bool isunordered(half x, half y) { return functions::isunordered(x, y); } + inline bool isunordered(half x, expr y) { return functions::isunordered(x, y); } + inline bool isunordered(expr x, half y) { return functions::isunordered(x, y); } + inline bool isunordered(expr x, expr y) { return functions::isunordered(x, y); } + + /// \name Casting + /// \{ + + /// Cast to or from half-precision floating point number. + /// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted + /// directly using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do. + /// It uses the default rounding mode. + /// + /// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types + /// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler + /// error and casting between [half](\ref half_float::half)s is just a no-op. + /// \tparam T destination type (half or built-in arithmetic type) + /// \tparam U source type (half or built-in arithmetic type) + /// \param arg value to cast + /// \return \a arg converted to destination type + template T half_cast(U arg) { return half_caster::cast(arg); } + + /// Cast to or from half-precision floating point number. + /// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted + /// directly using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do. + /// + /// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types + /// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler + /// error and casting between [half](\ref half_float::half)s is just a no-op. + /// \tparam T destination type (half or built-in arithmetic type) + /// \tparam R rounding mode to use. + /// \tparam U source type (half or built-in arithmetic type) + /// \param arg value to cast + /// \return \a arg converted to destination type + template T half_cast(U arg) { return half_caster::cast(arg); } + /// \} + } + + using detail::operator==; + using detail::operator!=; + using detail::operator<; + using detail::operator>; + using detail::operator<=; + using detail::operator>=; + using detail::operator+; + using detail::operator-; + using detail::operator*; + using detail::operator/; + using detail::operator<<; + using detail::operator>>; + + using detail::abs; + using detail::fabs; + using detail::fmod; + using detail::remainder; + using detail::remquo; + using detail::fma; + using detail::fmax; + using detail::fmin; + using detail::fdim; + using detail::nanh; + using detail::exp; + using detail::expm1; + using detail::exp2; + using detail::log; + using detail::log10; + using detail::log1p; + using detail::log2; + using detail::sqrt; + using detail::cbrt; + using detail::hypot; + using detail::pow; + using detail::sin; + using detail::cos; + using detail::tan; + using detail::asin; + using detail::acos; + using detail::atan; + using detail::atan2; + using detail::sinh; + using detail::cosh; + using detail::tanh; + using detail::asinh; + using detail::acosh; + using detail::atanh; + using detail::erf; + using detail::erfc; + using detail::lgamma; + using detail::tgamma; + using detail::ceil; + using detail::floor; + using detail::trunc; + using detail::round; + using detail::lround; + using detail::nearbyint; + using detail::rint; + using detail::lrint; +#if HALF_ENABLE_CPP11_LONG_LONG + using detail::llround; + using detail::llrint; +#endif + using detail::frexp; + using detail::ldexp; + using detail::modf; + using detail::scalbn; + using detail::scalbln; + using detail::ilogb; + using detail::logb; + using detail::nextafter; + using detail::nexttoward; + using detail::copysign; + using detail::fpclassify; + using detail::isfinite; + using detail::isinf; + using detail::isnan; + using detail::isnormal; + using detail::signbit; + using detail::isgreater; + using detail::isgreaterequal; + using detail::isless; + using detail::islessequal; + using detail::islessgreater; + using detail::isunordered; + + using detail::half_cast; +} + + +/// Extensions to the C++ standard library. +namespace std +{ + /// Numeric limits for half-precision floats. + /// Because of the underlying single-precision implementation of many operations, it inherits some properties from + /// `std::numeric_limits`. + template<> class numeric_limits : public numeric_limits + { + public: + /// Supports signed values. + static HALF_CONSTEXPR_CONST bool is_signed = true; + + /// Is not exact. + static HALF_CONSTEXPR_CONST bool is_exact = false; + + /// Doesn't provide modulo arithmetic. + static HALF_CONSTEXPR_CONST bool is_modulo = false; + + /// IEEE conformant. + static HALF_CONSTEXPR_CONST bool is_iec559 = true; + + /// Supports infinity. + static HALF_CONSTEXPR_CONST bool has_infinity = true; + + /// Supports quiet NaNs. + static HALF_CONSTEXPR_CONST bool has_quiet_NaN = true; + + /// Supports subnormal values. + static HALF_CONSTEXPR_CONST float_denorm_style has_denorm = denorm_present; + + /// Rounding mode. + /// Due to the mix of internal single-precision computations (using the rounding mode of the underlying + /// single-precision implementation) with the rounding mode of the single-to-half conversions, the actual rounding + /// mode might be `std::round_indeterminate` if the default half-precision rounding mode doesn't match the + /// single-precision rounding mode. + static HALF_CONSTEXPR_CONST float_round_style round_style = (std::numeric_limits::round_style== + half_float::half::round_style) ? half_float::half::round_style : round_indeterminate; + + /// Significant digits. + static HALF_CONSTEXPR_CONST int digits = 11; + + /// Significant decimal digits. + static HALF_CONSTEXPR_CONST int digits10 = 3; + + /// Required decimal digits to represent all possible values. + static HALF_CONSTEXPR_CONST int max_digits10 = 5; + + /// Number base. + static HALF_CONSTEXPR_CONST int radix = 2; + + /// One more than smallest exponent. + static HALF_CONSTEXPR_CONST int min_exponent = -13; + + /// Smallest normalized representable power of 10. + static HALF_CONSTEXPR_CONST int min_exponent10 = -4; + + /// One more than largest exponent + static HALF_CONSTEXPR_CONST int max_exponent = 16; + + /// Largest finitely representable power of 10. + static HALF_CONSTEXPR_CONST int max_exponent10 = 4; + + /// Smallest positive normal value. + static HALF_CONSTEXPR half_float::half min() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x0400); } + + /// Smallest finite value. + static HALF_CONSTEXPR half_float::half lowest() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0xFBFF); } + + /// Largest finite value. + static HALF_CONSTEXPR half_float::half max() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7BFF); } + + /// Difference between one and next representable value. + static HALF_CONSTEXPR half_float::half epsilon() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x1400); } + + /// Maximum rounding error. + static HALF_CONSTEXPR half_float::half round_error() HALF_NOTHROW + { return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); } + + /// Positive infinity. + static HALF_CONSTEXPR half_float::half infinity() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7C00); } + + /// Quiet NaN. + static HALF_CONSTEXPR half_float::half quiet_NaN() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7FFF); } + + /// Signalling NaN. + static HALF_CONSTEXPR half_float::half signaling_NaN() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x7DFF); } + + /// Smallest positive subnormal value. + static HALF_CONSTEXPR half_float::half denorm_min() HALF_NOTHROW { return half_float::half(half_float::detail::binary, 0x0001); } + }; + +#if HALF_ENABLE_CPP11_HASH + /// Hash function for half-precision floats. + /// This is only defined if C++11 `std::hash` is supported and enabled. + template<> struct hash //: unary_function + { + /// Type of function argument. + typedef half_float::half argument_type; + + /// Function return type. + typedef size_t result_type; + + /// Compute hash function. + /// \param arg half to hash + /// \return hash value + result_type operator()(argument_type arg) const + { return hash()(static_cast(arg.data_)&-(arg.data_!=0x8000)); } + }; +#endif +} + + +#undef HALF_CONSTEXPR +#undef HALF_CONSTEXPR_CONST +#undef HALF_NOEXCEPT +#undef HALF_NOTHROW +#ifdef HALF_POP_WARNINGS + #pragma warning(pop) + #undef HALF_POP_WARNINGS +#endif + +#endif diff --git a/gpu/third_party/half/test/Makefile b/gpu/third_party/half/test/Makefile new file mode 100644 index 0000000..882d14c --- /dev/null +++ b/gpu/third_party/half/test/Makefile @@ -0,0 +1,24 @@ +CC = /usr/bin/g++ +CFLAGS = -Wall -pedantic -g -O2 +C11FLAGS = -std=c++0x $(CFLAGS) +CPPFLAGS = -I../include +LDFLAGS = + +test11: src/test11.cpp ../include/half.hpp + mkdir -p bin + $(CC) $(C11FLAGS) $(CPPFLAGS) $(LDFLAGS) -o bin/test src/test11.cpp + +test03: src/test03.cpp ../include/half.hpp + mkdir -p bin + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o bin/test src/test03.cpp + +asm11: src/test11.cpp ../include/half.hpp + mkdir -p asm + $(CC) $(C11FLAGS) $(CPPFLAGS) $(LDFLAGS) -S -o asm/test11.asm src/test11.cpp + +asm03: src/test11.cpp ../include/half.hpp + mkdir -p asm + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -S -o asm/test03.asm src/test03.cpp + +clean: + rm -rvf *~ src/*~ asm bin diff --git a/gpu/third_party/half/test/projects/vs2005/test.sln b/gpu/third_party/half/test/projects/vs2005/test.sln new file mode 100644 index 0000000..f08a40c --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2005/test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{DDAD59C9-019D-497B-9F64-8E8685DCB5AE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Debug|Win32.ActiveCfg = Debug|Win32 + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Debug|Win32.Build.0 = Debug|Win32 + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Release|Win32.ActiveCfg = Release|Win32 + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/gpu/third_party/half/test/projects/vs2005/test.vcproj b/gpu/third_party/half/test/projects/vs2005/test.vcproj new file mode 100644 index 0000000..fa08658 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2005/test.vcproj @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpu/third_party/half/test/projects/vs2008/test.sln b/gpu/third_party/half/test/projects/vs2008/test.sln new file mode 100644 index 0000000..5d75f55 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2008/test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{DDAD59C9-019D-497B-9F64-8E8685DCB5AE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Debug|Win32.ActiveCfg = Debug|Win32 + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Debug|Win32.Build.0 = Debug|Win32 + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Release|Win32.ActiveCfg = Release|Win32 + {DDAD59C9-019D-497B-9F64-8E8685DCB5AE}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/gpu/third_party/half/test/projects/vs2008/test.vcproj b/gpu/third_party/half/test/projects/vs2008/test.vcproj new file mode 100644 index 0000000..ef7175d --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2008/test.vcproj @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpu/third_party/half/test/projects/vs2010/test.sln b/gpu/third_party/half/test/projects/vs2010/test.sln new file mode 100644 index 0000000..fa1c88f --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2010/test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{3949106C-CB15-4DD5-A1E6-13D5F067EC8C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.ActiveCfg = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.Build.0 = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.ActiveCfg = Release|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/gpu/third_party/half/test/projects/vs2010/test.vcxproj b/gpu/third_party/half/test/projects/vs2010/test.vcxproj new file mode 100644 index 0000000..1aac817 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2010/test.vcxproj @@ -0,0 +1,91 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + AssemblyAndSourceCode + + + + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C} + Win32Proj + test + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + $(ProjectName)d + + + false + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + + + Console + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/projects/vs2010/test.vcxproj.filters b/gpu/third_party/half/test/projects/vs2010/test.vcxproj.filters new file mode 100644 index 0000000..ad40889 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2010/test.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Quelldateien + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/projects/vs2012/test.sln b/gpu/third_party/half/test/projects/vs2012/test.sln new file mode 100644 index 0000000..1dbd286 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2012/test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{3949106C-CB15-4DD5-A1E6-13D5F067EC8C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.ActiveCfg = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.Build.0 = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.ActiveCfg = Release|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/gpu/third_party/half/test/projects/vs2012/test.vcxproj b/gpu/third_party/half/test/projects/vs2012/test.vcxproj new file mode 100644 index 0000000..21a0dd0 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2012/test.vcxproj @@ -0,0 +1,94 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + AssemblyCode + + + + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C} + Win32Proj + test + + + + Application + true + Unicode + v110 + + + Application + false + true + Unicode + v110 + + + + + + + + + + + + + true + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + $(ProjectName)d + + + false + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + 4127;4514;4668;4710;4711 + + + Console + true + + + + + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + Level4 + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/projects/vs2012/test.vcxproj.filters b/gpu/third_party/half/test/projects/vs2012/test.vcxproj.filters new file mode 100644 index 0000000..ad40889 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2012/test.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Quelldateien + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/projects/vs2013/test.sln b/gpu/third_party/half/test/projects/vs2013/test.sln new file mode 100644 index 0000000..566b9ad --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2013/test.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{3949106C-CB15-4DD5-A1E6-13D5F067EC8C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.ActiveCfg = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.Build.0 = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.ActiveCfg = Release|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/gpu/third_party/half/test/projects/vs2013/test.vcxproj b/gpu/third_party/half/test/projects/vs2013/test.vcxproj new file mode 100644 index 0000000..c717105 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2013/test.vcxproj @@ -0,0 +1,94 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + AssemblyCode + + + + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C} + Win32Proj + test + + + + Application + true + Unicode + v120 + + + Application + false + true + Unicode + v120 + + + + + + + + + + + + + true + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + $(ProjectName)d + + + false + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + 4127;4514;4668;4710;4711 + + + Console + true + + + + + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + Level4 + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/projects/vs2013/test.vcxproj.filters b/gpu/third_party/half/test/projects/vs2013/test.vcxproj.filters new file mode 100644 index 0000000..ad40889 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2013/test.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Quelldateien + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/projects/vs2015/test.sln b/gpu/third_party/half/test/projects/vs2015/test.sln new file mode 100644 index 0000000..89f78d1 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2015/test.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{3949106C-CB15-4DD5-A1E6-13D5F067EC8C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.ActiveCfg = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Debug|Win32.Build.0 = Debug|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.ActiveCfg = Release|Win32 + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/gpu/third_party/half/test/projects/vs2015/test.vcxproj b/gpu/third_party/half/test/projects/vs2015/test.vcxproj new file mode 100644 index 0000000..e9f9ad8 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2015/test.vcxproj @@ -0,0 +1,94 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + AssemblyCode + + + + {3949106C-CB15-4DD5-A1E6-13D5F067EC8C} + Win32Proj + test + + + + Application + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + + + + + + + + + + + true + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + $(ProjectName)d + + + false + $(ProjectDir)..\..\bin\ + $(ProjectDir)$(Configuration)\ + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + 4127;4514;4668;4710;4711 + + + Console + true + + + + + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\..\include\ + Level4 + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/projects/vs2015/test.vcxproj.filters b/gpu/third_party/half/test/projects/vs2015/test.vcxproj.filters new file mode 100644 index 0000000..ad40889 --- /dev/null +++ b/gpu/third_party/half/test/projects/vs2015/test.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Quelldateien + + + \ No newline at end of file diff --git a/gpu/third_party/half/test/src/test03.cpp b/gpu/third_party/half/test/src/test03.cpp new file mode 100644 index 0000000..0332e90 --- /dev/null +++ b/gpu/third_party/half/test/src/test03.cpp @@ -0,0 +1,26 @@ +// test - Test application for half-precision floating point functionality. +// +// Copyright (c) 2012-2013 Christian Rau +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is 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 Software. +// +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include + +using half_float::half; + + +int main(int argc, char *argv[]) +{ + half a(3.14159), b(-7), c = sin(a+b); + std::cout << c << ", " << ilogb(c) << '\n'; +} diff --git a/gpu/third_party/half/test/src/test11.cpp b/gpu/third_party/half/test/src/test11.cpp new file mode 100644 index 0000000..8e7ef49 --- /dev/null +++ b/gpu/third_party/half/test/src/test11.cpp @@ -0,0 +1,667 @@ +// test - Test application for half-precision floating point functionality. +// +// Copyright (c) 2012-2017 Christian Rau +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is 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 Software. +// +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#define HALF_ROUND_STYLE 1 +#define HALF_ROUND_TIES_TO_EVEN 1 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if HALF_ENABLE_CPP11_HASH + #include +#endif + + +#define UNARY_MATH_TEST(func) { \ + double err = 0.0, rel = 0.0; \ + bool success = unary_test(#func, [&](half arg) -> bool { \ + half a = func(arg), b(std::func(static_cast(arg))); bool equal = comp(a, b); \ + if(!equal) { double error = std::abs(static_cast(a)-static_cast(b)); \ + err = std::max(err, error); rel = std::max(rel, error/std::abs(static_cast(arg))); } return equal; }); \ + if(err != 0.0 || rel != 0.0) std::cout << #func << " max error: " << err << " - max relative error: " << rel << '\n'; } + +#define BINARY_MATH_TEST(func) { \ + double err = 0.0, rel = 0.0; \ + bool success = binary_test(#func, [&](half x, half y) -> bool { \ + half a = func(x, y), b(std::func(static_cast(x), static_cast(y))); bool equal = comp(a, b); \ + if(!equal) { double error = std::abs(static_cast(a)-static_cast(b)); \ + err = std::max(err, error); rel = std::max(rel, error/std::min(std::abs(static_cast(x)), std::abs(static_cast(y)))); } return equal; }); \ + if(err != 0.0 || rel != 0.0) std::cout << #func << " max error: " << err << " - max relative error: " << rel << '\n'; } + + +using half_float::half; +using half_float::half_cast; + +half b2h(std::uint16_t bits) +{ + return *reinterpret_cast(&bits); +} + +std::uint16_t h2b(half h) +{ + return *reinterpret_cast(&h); +} + +bool comp(half a, half b) +{ + return (isnan(a) && isnan(b)) || a == b; +} + + +class half_test +{ +public: + half_test(std::ostream &log, bool fast) + : tests_(0), log_(log), fast_(fast) + { + //prepare halfs + half_vector batch; + std::uint16_t u = 0; + halfs_.insert(std::make_pair("positive zero", half_vector(1, b2h(u++)))); + for(; u<0x400; ++u) + batch.push_back(b2h(u)); + halfs_.insert(std::make_pair("positive subn", std::move(batch))); + batch.clear(); + for(; u<0x7C00; ++u) + batch.push_back(b2h(u)); + halfs_.insert(std::make_pair("positive norm", std::move(batch))); + batch.clear(); + halfs_.insert(std::make_pair("positive inft", half_vector(1, b2h(u++)))); + for(; u<0x8000; ++u) + batch.push_back(b2h(u)); + halfs_.insert(std::make_pair("positive NaN", std::move(batch))); + batch.clear(); + halfs_.insert(std::make_pair("negative zero", half_vector(1, b2h(u++)))); + for(; u<0x8400; ++u) + batch.push_back(b2h(u)); + halfs_.insert(std::make_pair("negative subn", std::move(batch))); + batch.clear(); + for(; u<0xFC00; ++u) + batch.push_back(b2h(u)); + halfs_.insert(std::make_pair("negative norm", std::move(batch))); + batch.clear(); + halfs_.insert(std::make_pair("negative inft", half_vector(1, b2h(u++)))); + for(; u!=0; ++u) + batch.push_back(b2h(u)); + halfs_.insert(std::make_pair("negative NaN", std::move(batch))); + + //set classes + classes_["positive zero"] = FP_ZERO; + classes_["positive subn"] = FP_SUBNORMAL; + classes_["positive norm"] = FP_NORMAL; + classes_["positive inft"] = FP_INFINITE; + classes_["positive NaN"] = FP_NAN; + classes_["negative zero"] = FP_ZERO; + classes_["negative subn"] = FP_SUBNORMAL; + classes_["negative norm"] = FP_NORMAL; + classes_["negative inft"] = FP_INFINITE; + classes_["negative NaN"] = FP_NAN; + } + + unsigned int test() + { + //test size + simple_test("size", []() { return sizeof(half)*CHAR_BIT >= 16; }); + + //test conversion + unary_test("float conversion", [](half arg) { return comp(half_cast(half_cast(arg)), arg); }); + unary_test("double conversion", [](half arg) { return comp(half_cast(half_cast(arg)), arg); }); + unary_test("long double conversion", [](half arg) { return comp(half_cast(half_cast(arg)), arg); }); + + //test classification + class_test("fpclassify", [](half arg, int cls) { return fpclassify(arg) == cls; }); + class_test("isfinite", [](half arg, int cls) { return isfinite(arg) == (cls!=FP_INFINITE&&cls!=FP_NAN); }); + class_test("isinf", [](half arg, int cls) { return isinf(arg) == (cls==FP_INFINITE); }); + class_test("isnan", [](half arg, int cls) { return isnan(arg) == (cls==FP_NAN); }); + class_test("isnormal", [](half arg, int cls) { return isnormal(arg) == (cls==FP_NORMAL); }); + unary_test("signbit", [](half arg) -> bool { double f = arg; return isnan(arg) || f==0.0 || (signbit(arg)==(f<0.0)); }); + + //test operators + unary_test("prefix increment", [](half arg) -> bool { double f = static_cast(arg); + return comp(static_cast(++f), ++arg) && comp(static_cast(f), arg); }); + unary_test("prefix decrement", [](half arg) -> bool { double f = static_cast(arg); + return comp(static_cast(--f), --arg) && comp(static_cast(f), arg); }); + unary_test("postfix increment", [](half arg) -> bool { double f = static_cast(arg); + return comp(static_cast(f++), arg++) && comp(static_cast(f), arg); }); + unary_test("postfix decrement", [](half arg) -> bool { double f = static_cast(arg); + return comp(static_cast(f--), arg--) && comp(static_cast(f), arg); }); + unary_test("unary plus", [](half arg) { return comp(+arg, arg); }); + unary_test("unary minus", [](half arg) { return comp(-arg, static_cast(-static_cast(arg))); }); + binary_test("addition", [](half a, half b) { return comp(a+b, static_cast(static_cast(a)+static_cast(b))); }); + binary_test("subtraction", [](half a, half b) { return comp(a-b, static_cast(static_cast(a)-static_cast(b))); }); + binary_test("multiplication", [](half a, half b) { return comp(a*b, static_cast(static_cast(a)*static_cast(b))); }); + binary_test("division", [](half a, half b) { return comp(a/b, static_cast(static_cast(a)/static_cast(b))); }); + binary_test("equal", [](half a, half b) { return (a==b) == (static_cast(a)==static_cast(b)); }); + binary_test("not equal", [](half a, half b) { return (a!=b) == (static_cast(a)!=static_cast(b)); }); + binary_test("less", [](half a, half b) { return (a(a)(b)); }); + binary_test("greater", [](half a, half b) { return (a>b) == (static_cast(a)>static_cast(b)); }); + binary_test("less equal", [](half a, half b) { return (a<=b) == (static_cast(a)<=static_cast(b)); }); + binary_test("greater equal", [](half a, half b) { return (a>=b) == (static_cast(a)>=static_cast(b)); }); + + //test basic functions + UNARY_MATH_TEST(abs); + UNARY_MATH_TEST(fabs); + BINARY_MATH_TEST(fmod); + binary_test("fdim", [](half a, half b) -> bool { half c = fdim(a, b); return isnan(a) || isnan(b) || + (isinf(a) && isinf(b) && signbit(a)==signbit(b)) || ((a>b) && comp(c, a-b)) || ((a<=b) && comp(c, static_cast(0.0f))); }); + + //test exponential functions + UNARY_MATH_TEST(exp); + UNARY_MATH_TEST(log); + UNARY_MATH_TEST(log10); + + //test power functions + UNARY_MATH_TEST(sqrt); + BINARY_MATH_TEST(pow); + + //test trig functions + UNARY_MATH_TEST(sin); + UNARY_MATH_TEST(cos); + UNARY_MATH_TEST(tan); + UNARY_MATH_TEST(asin); + UNARY_MATH_TEST(acos); + UNARY_MATH_TEST(atan); + BINARY_MATH_TEST(atan2); + + //test hyp functions + UNARY_MATH_TEST(sinh); + UNARY_MATH_TEST(cosh); + UNARY_MATH_TEST(tanh); + + //test round functions + UNARY_MATH_TEST(ceil); + UNARY_MATH_TEST(floor); + unary_test("trunc", [](half arg) { return !isfinite(arg) || comp(trunc(arg), static_cast(static_cast(arg))); }); + unary_test("round", [](half arg) { return !isfinite(arg) || comp(round(arg), + static_cast(static_cast(static_cast(arg)+(signbit(arg) ? -0.5 : 0.5)))); }); + unary_test("lround", [](half arg) { return !isfinite(arg) || lround(arg) == + static_cast(static_cast(arg)+(signbit(arg) ? -0.5 : 0.5)); }); + unary_test("nearbyint", [](half arg) { return !isfinite(arg) || comp(nearbyint(arg), static_cast(half_cast(arg))); }); + unary_test("rint", [](half arg) { return !isfinite(arg) || comp(rint(arg), static_cast(half_cast(arg))); }); + unary_test("lrint", [](half arg) { return !isfinite(arg) || lrint(arg) == half_cast(arg); }); + #if HALF_ENABLE_CPP11_LONG_LONG + unary_test("llround", [](half arg) { return !isfinite(arg) || llround(arg) == + static_cast(static_cast(arg)+(signbit(arg) ? -0.5 : 0.5)); }); + unary_test("llrint", [](half arg) { return !isfinite(arg) || llrint(arg) == half_cast(arg); }); + #endif + + //test float functions + unary_test("frexp", [](half arg) -> bool { int eh, ef; bool eq = comp(frexp(arg, &eh), + static_cast(std::frexp(static_cast(arg), &ef))); return eq && (!isfinite(arg) || eh==ef); }); + unary_test("ldexp", [](half arg) -> bool { unsigned int passed = 0; for(int i=-50; i<50; ++i) passed += + comp(ldexp(arg, i), static_cast(std::ldexp(static_cast(arg), i))); return passed==100; }); + unary_test("modf", [](half arg) -> bool { half h; double f; return comp(modf(arg, &h), static_cast( + std::modf(static_cast(arg), &f))) && comp(h, static_cast(f)); }); + binary_test("nextafter", [](half a, half b) -> bool { half c = nextafter(a, b); std::int16_t d = std::abs( + static_cast(h2b(a)-h2b(c))); return ((isnan(a) || isnan(b)) && isnan(c)) || + (comp(a, b) && comp(b, c)) || ((d==1||d==0x7FFF) && (a bool { half c = nexttoward(a, static_cast(b)); std::int16_t d = std::abs( + static_cast(h2b(a)-h2b(c))); return ((isnan(a) || isnan(b)) && isnan(c)) || + (comp(a, b) && comp(b, c)) || ((d==1||d==0x7FFF) && (a bool { half h = copysign(a, b); + return comp(abs(h), abs(a)) && signbit(h)==signbit(b); }); + + #if HALF_ENABLE_CPP11_CMATH + //test basic functions + BINARY_MATH_TEST(remainder); + binary_test("remquo", [](half a, half b) -> bool { int qh = 0, qf = 0; bool eq = comp(remquo(a, b, &qh), + static_cast(std::remquo(static_cast(a), static_cast(b), &qf))); return eq && (qh&7)==(qf&7); }); + BINARY_MATH_TEST(fmin); + BINARY_MATH_TEST(fmax); + BINARY_MATH_TEST(fdim); + + //test exponential functions + UNARY_MATH_TEST(exp2); + UNARY_MATH_TEST(expm1); + UNARY_MATH_TEST(log1p); + UNARY_MATH_TEST(log2); + + //test power functions + UNARY_MATH_TEST(cbrt); + BINARY_MATH_TEST(hypot); + + //test hyp functions + UNARY_MATH_TEST(asinh); + UNARY_MATH_TEST(acosh); + UNARY_MATH_TEST(atanh); + + //test err functions + UNARY_MATH_TEST(erf); + UNARY_MATH_TEST(erfc); + UNARY_MATH_TEST(lgamma); + UNARY_MATH_TEST(tgamma); + + //test round functions + UNARY_MATH_TEST(trunc); + UNARY_MATH_TEST(round); + unary_test("lround", [](half arg) { return !isfinite(arg) || lround(arg) == std::lround(static_cast(arg)); }); + unary_test("llround", [](half arg) { return !isfinite(arg) || llround(arg) == std::llround(static_cast(arg)); }); + #if HALF_ROUND_STYLE == 1 && HALF_ROUND_TIES_TO_EVEN == 1 + UNARY_MATH_TEST(nearbyint); + UNARY_MATH_TEST(rint); + unary_test("lrint", [](half arg) { return !isfinite(arg) || half_float::lrint(arg) == std::lrint(static_cast(arg)); }); + unary_test("llrint", [](half arg) { return !isfinite(arg) || llrint(arg) == std::llrint(static_cast(arg)); }); + #endif + + //test float functions + unary_test("scalbn", [](half arg) -> bool { unsigned int passed = 0; for(int i=-50; i<50; ++i) passed += + comp(scalbn(arg, i), static_cast(std::scalbn(static_cast(arg), i))); return passed==100; }); + unary_test("scalbln", [](half arg) -> bool { unsigned int passed = 0; for(long i=-50; i<50; ++i) passed += + comp(scalbln(arg, i), static_cast(std::scalbln(static_cast(arg), i))); return passed==100; }); + unary_test("ilogb", [](half arg) { return ilogb(arg) == std::ilogb(static_cast(arg)); }); + unary_test("logb", [](half arg) { return comp(logb(arg), static_cast(std::logb(static_cast(arg)))); }); + binary_test("copysign", [](half a, half b) { return comp(copysign(a, b), + static_cast(std::copysign(static_cast(a), static_cast(b)))); }); + + //test classification functions + unary_test("fpclassify", [](half arg) -> bool { int ch=fpclassify(arg), cf=std::fpclassify( + static_cast(arg)); return ch==cf || (ch==FP_SUBNORMAL && cf==FP_NORMAL); }); + unary_test("isfinite", [](half arg) { return isfinite(arg) == std::isfinite(static_cast(arg)); }); + unary_test("isinf", [](half arg) { return isinf(arg) == std::isinf(static_cast(arg)); }); + unary_test("isnan", [](half arg) { return isnan(arg) == std::isnan(static_cast(arg)); }); + unary_test("isnormal", [](half arg) { return isnormal(arg) == std::isnormal(static_cast(arg)) || + (!isnormal(arg) && fpclassify(arg)==FP_SUBNORMAL); }); + unary_test("signbit", [](half arg) { return signbit(arg) == std::signbit(static_cast(arg)); }); + + //test comparison functions + binary_test("isgreater", [](half a, half b) { return isgreater(a, b) == + std::isgreater(static_cast(a), static_cast(b)); }); + binary_test("isgreaterequal", [](half a, half b) { return isgreaterequal(a, b) == + std::isgreaterequal(static_cast(a), static_cast(b)); }); + binary_test("isless", [](half a, half b) { return isless(a, b) == + std::isless(static_cast(a), static_cast(b)); }); + binary_test("islessequal", [](half a, half b) { return islessequal(a, b) == + std::islessequal(static_cast(a), static_cast(b)); }); + binary_test("islessgreater", [](half a, half b) { return islessgreater(a, b) == + std::islessgreater(static_cast(a), static_cast(b)); }); + binary_test("isunordered", [](half a, half b) { return isunordered(a, b) == + std::isunordered(static_cast(a), static_cast(b)); }); + #endif + + //test rounding + float_test("round_to_nearest", [](float f) -> bool { half a = half_cast(f), + b(nextafter(a, copysign(std::numeric_limits::infinity(), a))), h = half_cast(f); + float af(a), bf(b), hf(h); return half_float::detail::builtin_isnan(f) || + (std::abs(hf)>std::abs(f)&&comp(h, b)&&(( + #if HALF_ROUND_TIES_TO_EVEN + std::abs(f-af)>std::abs(bf-f) || (std::abs(f-af)==std::abs(bf-f)&&!(h2b(h)&1)) + #else + std::abs(f-af)>=std::abs(bf-f) + #endif + )||isinf(h))) || (std::abs(hf)<=std::abs(f)&&comp(h, a)&&(( + #if HALF_ROUND_TIES_TO_EVEN + std::abs(f-af) bool { half a = half_cast(f), + h = half_cast(f); float af(a), hf(h); return half_float::detail::builtin_isnan(f) || isinf(a) || af == hf; }); + float_test("round_toward_infinity", [](float f) -> bool { half a = half_cast(f), + b(nextafter(a, copysign(std::numeric_limits::infinity(), a))), h = half_cast(f); + float hf(h); return half_float::detail::builtin_isnan(f) || (comp(h, a)&&(signbit(h)||hf==f)) || (comp(h, b)&&!signbit(h)&&hf>f); }); + float_test("round_toward_neg_infinity", [](float f) -> bool { half a = half_cast(f), + b(nextafter(a, copysign(std::numeric_limits::infinity(), a))), h = half_cast(f); + float hf(h); return half_float::detail::builtin_isnan(f) || (comp(h, a)&&(!signbit(h)||hf==f)) || (comp(h, b)&&signbit(h)&&hf(0, (1<<23)-1), std::default_random_engine()); + unary_test("half_cast", [](half arg) -> bool { float a = half_cast(arg), b = static_cast(arg); + return *reinterpret_cast(&a) == *reinterpret_cast(&b); }); + unary_test("half_cast(float)", [&rand23](half arg) -> bool { float f = half_cast(arg); + std::uint32_t n=rand23(), m=1<<13; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return fpclassify(arg)==FP_ZERO || + comp(half_cast(f), + #if HALF_ROUND_TIES_TO_EVEN + ((n&(m>>1)) && ((n&((m>>1)-1)) || (h2b(arg)&1))) + #else + (n&(m>>1)) + #endif + ? nextafter(arg, copysign(std::numeric_limits::infinity(), arg)) : arg); }); + unary_test("half_cast(float)", [&rand23](half arg) -> bool { float f = half_cast(arg); + std::uint32_t n=rand23(), m=1<<13; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return comp(half_cast(f), arg); }); + unary_test("half_cast(float)", [&rand23](half arg) -> bool { float f = half_cast(arg); + std::uint32_t n=rand23(), m=1<<13; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return comp(half_cast(f), + (!signbit(arg)&&(n&(m-1))) ? nextafter(arg, copysign(std::numeric_limits::infinity(), arg)) : arg); }); + unary_test("half_cast(float)", [&rand23](half arg) -> bool { float f = half_cast(arg); + std::uint32_t n=rand23(), m=1<<13; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return comp(half_cast(f), + (signbit(arg)&&(n&(m-1))) ? nextafter(arg, copysign(std::numeric_limits::infinity(), arg)) : arg); }); + + //test double casting + auto rand52 = std::bind(std::uniform_int_distribution(0, (1ULL<<52)-1), std::default_random_engine()); + unary_test("half_cast", [](half arg) -> bool { double a = half_cast(arg), b = static_cast(arg); + return isnan(arg) || *reinterpret_cast(&a) == *reinterpret_cast(&b); }); + unary_test("half_cast(double)", [&rand52](half arg) -> bool { double f = half_cast(arg); + std::uint64_t n=rand52(), m=1ULL<<42; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return fpclassify(arg)==FP_ZERO || + comp(half_cast(f), + #if HALF_ROUND_TIES_TO_EVEN + ((n&(m>>1)) && ((n&((m>>1)-1)) || (h2b(arg)&1))) + #else + (n&(m>>1)) + #endif + ? nextafter(arg, copysign(std::numeric_limits::infinity(), arg)) : arg); }); + unary_test("half_cast(double)", [&rand52](half arg) -> bool { double f = half_cast(arg); + std::uint64_t n=rand52(), m=1ULL<<42; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return comp(half_cast(f), arg); }); + unary_test("half_cast(double)", [&rand52](half arg) -> bool { double f = half_cast(arg); + std::uint64_t n=rand52(), m=1ULL<<42; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return comp(half_cast(f), + (!signbit(arg)&&(n&(m-1))) ? nextafter(arg, copysign(std::numeric_limits::infinity(), arg)) : arg); }); + unary_test("half_cast(double)", [&rand52](half arg) -> bool { double f = half_cast(arg); + std::uint64_t n=rand52(), m=1ULL<<42; if(fpclassify(arg)==FP_SUBNORMAL) m <<= std::min(std::max(-ilogb(arg)-14, 0), 10); + *reinterpret_cast(&f) |= n&(m-1)&-isfinite(arg); return comp(half_cast(f), + (signbit(arg)&&(n&(m-1))) ? nextafter(arg, copysign(std::numeric_limits::infinity(), arg)) : arg); }); + + //test casting to int + #if HALF_ENABLE_CPP11_CMATH + unary_test("half_cast", [](half arg) -> bool { return !isfinite(arg) || half_cast(arg) == static_cast(nearbyint(arg)); }); + #endif + unary_test("half_cast", [](half arg) -> bool { float fi, ff = std::abs(std::modf(static_cast(arg), &fi)); + int i = static_cast(fi); i += (-2*signbit(arg)+1) * + #if HALF_ROUND_TIES_TO_EVEN + (ff>0.5f || (ff==0.5f && i&1)); + #else + (ff>=0.5f); + #endif + return !isfinite(arg) || half_cast(arg) == i; + }); + unary_test("half_cast", [](half arg) -> bool { return !isfinite(arg) || half_cast(arg) == static_cast(arg); }); + unary_test("half_cast", [](half arg) -> bool { float fi, ff = std::modf(static_cast(arg), &fi); + return !isfinite(arg) || half_cast(arg) == (static_cast(fi)+(ff>0.0f)); }); + unary_test("half_cast", [](half arg) -> bool { float fi, ff = std::modf(static_cast(arg), &fi); + return !isfinite(arg) || half_cast(arg) == (static_cast(fi)-(ff<0.0f)); }); + + //test casting from int + int_test("half_cast<>(int)", [](int i) -> bool { return comp(half_cast(i), half_cast(static_cast(i))); }); + int_test("half_cast(int)", [](int i) -> bool { + return comp(half_cast(i), half_cast(static_cast(i))); }); + int_test("half_cast(int)", [](int i) -> bool { + return comp(half_cast(i), half_cast(static_cast(i))); }); + int_test("half_cast(int)", [](int i) -> bool { + return comp(half_cast(i), half_cast(static_cast(i))); }); + int_test("half_cast(int)", [](int i) -> bool { + return comp(half_cast(i), half_cast(static_cast(i))); }); + + //test numeric limits + unary_test("numeric_limits::min", [](half arg) { return !isnormal(arg) || signbit(arg) || arg>=std::numeric_limits::min(); }); + unary_test("numeric_limits::lowest", [](half arg) { return !isfinite(arg) || arg>=std::numeric_limits::lowest(); }); + unary_test("numeric_limits::max", [](half arg) { return !isfinite(arg) || arg<=std::numeric_limits::max(); }); + unary_test("numeric_limits::denorm_min", [](half arg) { return !isfinite(arg) || + signbit(arg) || arg==static_cast(0.0f) || arg>=std::numeric_limits::denorm_min(); }); + simple_test("numeric_limits::infinity", []() { return isinf(std::numeric_limits::infinity()) && + !signbit(std::numeric_limits::infinity()); }); + simple_test("numeric_limits::quiet_NaN", []() { return isnan(std::numeric_limits::quiet_NaN()); }); + simple_test("numeric_limits::signaling_NaN", []() { return isnan(std::numeric_limits::signaling_NaN()); }); + simple_test("numeric_limits::epsilon", []() { return nextafter(static_cast(1.0f), + std::numeric_limits::infinity())-static_cast(1.0f) == std::numeric_limits::epsilon(); }); + binary_test("numeric_limits::round_error", [](half a, half b) -> bool { double c = static_cast(a) + + static_cast(b); return !isfinite(a) || !isfinite(b) || c>static_cast(std::numeric_limits::max()) || + c(std::numeric_limits::lowest()) || std::abs(c-static_cast( + static_cast(c)))<=std::ldexp(static_cast(std::numeric_limits::round_error()), + ilogb(static_cast(c))-std::numeric_limits::digits+1); }); + + #if HALF_ENABLE_CPP11_HASH + //test hash + binary_test("hash function", [](half a, half b) { return a != b || std::hash()(a) == std::hash()(b); }); + struct { bool operator()(half a, half b) const { return h2b(a) == h2b(b); } } bincomp; + std::unordered_map,decltype(bincomp)> map(65536, std::hash(), bincomp); + unary_test("hash insert", [&map](const half &arg) { return map.insert(std::make_pair(arg, &arg)).second; }); + unary_test("hash retrieve", [&map](const half &arg) { return map[arg] == &arg; }); + #endif + + #if HALF_ENABLE_CPP11_USER_LITERALS + //test literals + simple_test("literals", []() -> bool { using namespace half_float::literal; return comp(0.0_h, half(0.0f)) && comp(-1.0_h, half(-1.0f)) && + comp(+3.14159265359_h, half(3.14159265359f)) && comp(1e-2_h, half(1e-2f)) && comp(-4.2e3_h, half(-4.2e3f)); }); + #endif + + if(failed_.empty()) + log_ << "all tests passed\n"; + else + { + log_ << (failed_.size()) << " OF " << tests_ << " FAILED:\n "; + std::copy(failed_.begin(), failed_.end(), std::ostream_iterator(log_, "\n ")); + log_ << '\n'; + } + return failed_.size(); + } + +private: + typedef std::vector half_vector; + typedef std::map test_map; + typedef std::map class_map; + + template bool class_test(const std::string &name, F test) + { + unsigned int count = 0; + log_ << "testing " << name << ":\n"; + for(auto iterB=halfs_.begin(); iterB!=halfs_.end(); ++iterB) + { + unsigned int passed = 0; + int fpclass = classes_[iterB->first]; + for(auto iterH=iterB->second.begin(); iterH!=iterB->second.end(); ++iterH) + passed += test(*iterH, fpclass); + log_ << " " << iterB->first << ": "; + if(passed == iterB->second.size()) + { + log_ << "all passed\n"; + ++count; + } + else + log_ << (iterB->second.size()-passed) << " of " << iterB->second.size() << " FAILED\n"; + } + log_ << '\n'; + ++tests_; + if(count == halfs_.size()) + return true; + failed_.push_back(name); + return false; + } + + template bool simple_test(const std::string &name, F test) + { + log_ << "testing " << name << ": "; + bool passed = test(); + log_ << (passed ? "passed" : "FAILED") << "\n\n"; + ++tests_; + if(!passed) + failed_.push_back(name); + return passed; + } + + template bool unary_test(const std::string &name, F test) + { + unsigned int count = 0; + log_ << "testing " << name << ":\n"; + for(auto iterB=halfs_.begin(); iterB!=halfs_.end(); ++iterB) + { + unsigned int passed = 0; + for(auto iterH=iterB->second.begin(); iterH!=iterB->second.end(); ++iterH) + passed += test(*iterH); + log_ << " " << iterB->first << ": "; + if(passed == iterB->second.size()) + { + log_ << "all passed\n"; + ++count; + } + else + log_ << (iterB->second.size()-passed) << " of " << iterB->second.size() << " FAILED\n"; + } + log_ << '\n'; + ++tests_; + if(count == halfs_.size()) + return true; + failed_.push_back(name); + return false; + } + + template bool binary_test(const std::string &name, F test) + { + unsigned long tests = 0, count = 0, step = fast_ ? 64 : 1; + auto rand = std::bind(std::uniform_int_distribution(0, step-1), std::default_random_engine()); + log_ << "testing " << name << ": "; + for(auto iterB1=halfs_.begin(); iterB1!=halfs_.end(); ++iterB1) + { + for(auto iterB2=halfs_.begin(); iterB2!=halfs_.end(); ++iterB2) + { + unsigned int end1 = (iterB1->first.find("NaN")==std::string::npos) ? iterB1->second.size() : 1; + unsigned int end2 = (iterB2->first.find("NaN")==std::string::npos) ? iterB2->second.size() : 1; + for(unsigned int i=fast_ ? std::min(rand(), iterB1->second.size()-1) : 0; isecond.size()-1) : 0; jsecond[i], iterB2->second[j]); + } + } + } + } + bool passed = count == tests; + if(passed) + log_ << "all passed\n\n"; + else + { + log_ << (tests-count) << " of " << tests << " FAILED\n\n"; + failed_.push_back(name); + } + ++tests_; + return passed; + } + + template bool float_test(const std::string &name, F test) + { + auto rand32 = std::bind(std::uniform_int_distribution(0, std::numeric_limits::max()), std::default_random_engine()); + unsigned long long count = 0, tests = fast_ ? 1e6 : (1ULL<<32); + log_ << "testing " << name << ": "; + if(fast_) + { + for(unsigned long long i=0; i(&u)); + } + } + else + for(std::uint32_t i=0; i++>0; ) + count += test(*reinterpret_cast(&i)); + bool passed = count == tests; + if(passed) + log_ << "all passed\n\n"; + else + { + log_ << (tests-count) << " of " << tests << " FAILED\n\n"; + failed_.push_back(name); + } + ++tests_; + return passed; + } + + template bool int_test(const std::string &name, F test) + { + unsigned int count = 0, tests = (1<<17) + 1; + log_ << "testing " << name << ": "; + for(int i=-(1<<16); i<=(1<<16); ++i) + count += test(i); + bool passed = count == tests; + if(passed) + log_ << "all passed\n\n"; + else + { + log_ << (tests-count) << " of " << tests << " FAILED\n\n"; + failed_.push_back(name); + } + ++tests_; + return passed; + } + + test_map halfs_; + class_map classes_; + unsigned int tests_; + std::vector failed_; + std::ostream &log_; + bool fast_; +}; + +#include +struct timer +{ + timer() : start_(std::chrono::high_resolution_clock::now()) {} + ~timer() { std::cout << "time: " << std::chrono::duration_cast(std::chrono::high_resolution_clock::now()-start_).count() << " ms\n"; } + +private: + std::chrono::time_point start_; +}; + +int main(int argc, char *argv[]) +{ +/* auto rand_abs = std::bind(std::uniform_int_distribution(0x00000000, 0x7F100000), std::default_random_engine()); + auto rand_sign = std::bind(std::uniform_int_distribution(0, 1), std::default_random_engine()); + std::vector floats; + for(unsigned int i=0; i<1e8; ++i) + { + auto bits = rand_abs() | (rand_sign()<<31); + floats.push_back(*reinterpret_cast(&bits)); + } + std::shuffle(floats.begin(), floats.end(), std::default_random_engine()); + std::vector halfs(floats.size()); + { + timer time; + for(std::size_t i=0; i(floats[i]); + } + return 0; +*/ + half pi = half_cast(3.1415926535897932384626433832795L); + std::cout << "Pi: " << pi << " - 0x" << std::hex << std::setfill('0') << std::setw(4) << h2b(pi) << std::dec + << " - " << std::bitset<16>(static_cast(h2b(pi))).to_string() << std::endl; + half e = half_cast(std::exp(1.0L)); + std::cout << "e: " << e << " - 0x" << std::hex << std::setfill('0') << std::setw(4) << h2b(e) << std::dec + << " - " << std::bitset<16>(static_cast(h2b(e))).to_string() << std::endl; + + std::vector args(argv, argv+argc); + std::unique_ptr file; + bool fast = false; + for(auto iter=std::next(args.begin()); iter!=args.end(); ++iter) + { + if(*iter == "-fast") + fast = true; + else + file.reset(new std::ofstream(*iter)); + } + half_test test(file ? *file : std::cout, fast); + + timer time; + return test.test(); +} diff --git a/gpu/third_party/half/web/Doxyfile b/gpu/third_party/half/web/Doxyfile new file mode 100644 index 0000000..b5f1b35 --- /dev/null +++ b/gpu/third_party/half/web/Doxyfile @@ -0,0 +1,1806 @@ +# Doxyfile 1.8.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = half + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.12 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "IEEE 754-based half-precision floating point library" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = txt=md + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented classes, +# or namespaces to their corresponding documentation. Such a link can be +# prevented in individual cases by by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = layout.xml + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = half.hpp \ + Mainpage.md \ + News.md \ + ../ChangeLog.txt + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = ../LICENSE.txt + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 27 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 240 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = YES + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/gpu/third_party/half/web/Mainpage.md b/gpu/third_party/half/web/Mainpage.md new file mode 100644 index 0000000..2ff4e2b --- /dev/null +++ b/gpu/third_party/half/web/Mainpage.md @@ -0,0 +1,164 @@ +Half-precision floating point library {#mainpage} +===================================== + +This is a C++ header-only library to provide an [IEEE 754](http://en.wikipedia.org/wiki/IEEE_754-2008) conformant 16-bit [half-precision](http://en.wikipedia.org/wiki/Half_precision_floating-point_format) floating point type along with corresponding arithmetic operators, type conversions and common mathematical functions. It aims for both efficiency and ease of use, trying to accurately mimic the behaviour of the builtin floating point types at the best performance possible. It is hosted on [SourceForge.net](http://sourceforge.net/projects/half/). + +[TOC] + + +News {#new} +==== + +March 6, 2017 - Release 1.12.0 +------------------------------ + +[Version 1.12.0](http://sourceforge.net/projects/half/files/half/1.12.0) of the library has been released. It changes the behaviour of half_cast() when casting to/from builtin floating point types. Previously those were performed by an explicit intermediary cast to/from `float`. But this could lead to imprecise results, since the rounding from `double`/`long double` to `float` was not controlled by the rounding mode of the half_cast(). Now each half_cast() always rounds directly to/from the specified type using the given rounding mode and thus guarantees exact compliance to this rounding mode. Furthermore, a minor portability issue with logb() and ilogb() has been fixed, that could cause trouble on non-twos-complement implementations (if there are any at all). It was also tested for *MS Visual C++ 2015*. + +November 16, 2013 - Release 1.11.0 +--------------------------------- + +[Version 1.11.0](http://sourceforge.net/projects/half/files/half/1.11.0) of the library has been released. It further increases the flexibility of the rounding, by allowing the round to nearest behaviour to be configured more precisely. By default half-way cases during round to nearest are rounded away from zero (and thus analogous to the round() function), but by redefining [HALF_ROUND_TIES_TO_EVEN](\ref HALF_ROUND_TIES_TO_EVEN) to `1` this can be changed to the slower but less biased round to even. In addition to that the support for C++11 mathematical functions in light of unsupported single-precision versions has been completed by providing erf(), erfc(), lgamma() and tgamma() even if their `` counterparts are unavailable. Furthermore, it fixes a bug that made it impossible to disable support for C++11 mathematical functions in *VC++ 2013*. + +[more](news.html) + + +------------------------- +Download and Installation {#downloads} +========================= + +The library in its most recent version can be obtained from here, see the [Release Notes](changelog.html) for further information: + +
  • [Download half 1.12.0 (.zip)](http://sourceforge.net/projects/half/files/latest/download)
+ +If you are interested in previous versions of the library, see the [SourceForge download page](http://sourceforge.net/projects/half/files/half). + +Comfortably enough, the library consists of just a single header file containing all the functionality, which can be directly included by your projects, without the neccessity to build anything or link to anything. + +Whereas this library is fully C++98-compatible, it can profit from certain C++11 features. Support for those features is checked and enabled automatically at compile (or rather preprocessing) time, but can be explicitly enabled or disabled by defining the corresponding preprocessor symbols to either 1 or 0 yourself. This is useful when the automatic detection fails (for more exotic implementations) or when a feature should be explicitly disabled: + +C++11 feature | Used for | Enabled for (and newer) | Override with +-------------------------------------|------------------------------------|---------------------------------------------|---------------------------------- +`long long` integer type | functions returning `long long` | *VC++ 2003*, *gcc*, *clang* | `HALF_ENABLE_CPP11_LONG_LONG` +static assertions | extended compile-time checks | *VC++ 2010*, *gcc 4.3*, *clang 2.9* | `HALF_ENABLE_CPP11_STATIC_ASSERT` +generalized constant expressions | constant operations | *VC++ 2015*, *gcc 4.6*, *clang 3.1* | `HALF_ENABLE_CPP11_CONSTEXPR` +`noexcept` specifications | proper `noexcept` functions | *VC++ 2015*, *gcc 4.6*, *clang 3.0* | `HALF_ENABLE_CPP11_NOEXCEPT` +user-defined literals | half-precision literals | *VC++ 2015*, *gcc 4.7*, *clang 3.1* | `HALF_ENABLE_CPP11_USER_LITERALS` +type traits from `` | TMP and extended checks | *VC++ 2010*, *libstdc++ 4.3*, libc++ | `HALF_ENABLE_CPP11_TYPE_TRAITS` +sized integer types from `` | more flexible type sizes | *VC++ 2010*, *libstdc++ 4.3*, libc++ | `HALF_ENABLE_CPP11_CSTDINT` +certain new `` functions | corresponding half implementations | *VC++ 2013*, *libstdc++ 4.3*, libc++ | `HALF_ENABLE_CPP11_CMATH` +`std::hash` from `` | hash function for halfs | *VC++ 2010*, *libstdc++ 4.3*, libc++ | `HALF_ENABLE_CPP11_HASH` + +The library has been tested successfully with *Visual C++ 2005* - *2015*, *gcc 4.4* - *4.8* and *clang 3.1*. Please [contact me](#contact) if you have any problems, suggestions or even just success testing it on other platforms. + + +------------- +Documentation {#doc} +============= + +What follows are some general words about the usage of the library and its implementation. For a complete reference documentation of its iterface you should consult the [API Documentation](usergroup0.html). + + +Basic usage {#usage} +----------- + +To make use of the library just include its only header file half.hpp, which defines all half-precision functionality inside the half_float namespace. The actual 16-bit half-precision data type is represented by the [half](\ref half_float::half) type. This type behaves like the builtin floating point types as much as possible, supporting the usual arithmetic, comparison and streaming operators, which makes its use pretty straight-forward: + +~~~~{.cpp} +using half_float::half; +half a(3.4), b(5); +half c = a * b; +c += 3; +if(c > a) + std::cout << c << std::endl; +~~~~ + +Additionally the half_float namespace also defines half-precision versions for all mathematical functions of the [C++ standard library](http://en.cppreference.com/w/cpp/numeric/math), which can be used directly through ADL: + +~~~~{.cpp} +half a(-3.14159); +half s = sin(abs(a)); +long l = lround(s); +~~~~ + +You may also specify explicit half-precision literals, since the library provides a user-defined literal inside the half_float::literal namespace, which you just need to import (assuming support for C++11 user-defined literals): + +~~~~{.cpp} +using namespace half_float::literal; +half x = 1.0_h; +~~~~ + +Furthermore the library provides proper specializations for `std::numeric_limits`, defining various implementation properties, and `std::hash` for hashing half-precision numbers (assuming support for C++11 `std::hash`). Similar to the corresponding preprocessor symbols from `` the library also defines the [HUGE_VALH](\ref HUGE_VALH) constant and maybe the [FP_FAST_FMAH](\ref FP_FAST_FMAH) symbol. + +Conversions and rounding {#conversions} +------------------------ + +The [half](\ref half_float::half) is explicitly constructible/convertible from a single-precision `float` argument. Thus it is also explicitly constructible/convertible from any type implicitly convertible to `float`, but constructing it from types like `double` or `int` will involve the usual warnings arising when implicitly converting those to `float` because of the lost precision. On the one hand those warnings are intentional, because converting those types to [half](\ref half_float::half) neccessarily also reduces precision. But on the other hand they are raised for explicit conversions from those types, when the user knows what he is doing. So if those warnings keep bugging you, then you won't get around first explicitly converting to `float` before converting to [half](\ref half_float::half), or use the half_cast() described below. In addition you can also directly assign `float` values to [half](\ref half_float::half)s. + +In contrast to the float-to-half conversion, which reduces precision, the conversion from [half](\ref half_float::half) to `float` (and thus to any other type implicitly convertible from `float`) is implicit, because all values represetable with half-precision are also representable with single-precision. This way the half-to-float conversion behaves similar to the builtin float-to-double conversion and all arithmetic expressions involving both half-precision and single-precision arguments will be of single-precision type. This way you can also directly use the mathematical functions of the C++ standard library, though in this case you will invoke the single-precision versions which will also return single-precision values, which is (even if maybe performing the exact same computation, see below) not as conceptually clean when working in a half-precision environment. + +The default rounding mode for conversions from `float` to [half](\ref half_float::half) uses truncation (round toward zero, but mapping overflows to infinity) for rounding values not representable exactly in half-precision. This is the fastest rounding possible and is usually sufficient. But by redefining the [HALF_ROUND_STYLE](\ref HALF_ROUND_STYLE) preprocessor symbol (before including half.hpp) this default can be overridden with one of the other standard rounding modes using their respective constants or the equivalent values of `std::float_round_style` (it can even be synchronized with the underlying single-precision implementation by defining it to `std::numeric_limits::round_style`): + +`std::float_round_style` | value | rounding +---------------------------------|-------|------------------------- +`std::round_indeterminate` | -1 | fastest (default) +`std::round_toward_zero` | 0 | toward zero +`std::round_to_nearest` | 1 | to nearest +`std::round_toward_infinity` | 2 | toward positive infinity +`std::round_toward_neg_infinity` | 3 | toward negative infinity + +In addition to changing the overall default rounding mode one can also use the half_cast(). This converts between [half](\ref half_float::half) and any built-in arithmetic type using a configurable rounding mode (or the default rounding mode if none is specified). In addition to a configurable rounding mode, half_cast() has another big difference to a mere `static_cast`: Any conversions are performed directly using the given rounding mode, without any intermediate conversion to/from `float`. This is especially relevant for conversions to integer types, which don't necessarily truncate anymore. But also for conversions from `double` or `long double` this may produce more precise results than a pre-conversion to `float` using the single-precision implementation's current rounding mode would. + +~~~~{.cpp} +half a = half_cast(4.2); +half b = half_cast::round_style>(4.2f); +assert( half_cast( 0.7_h ) == 1 ); +assert( half_cast( 4097 ) == 4096.0_h ); +assert( half_cast( 4097 ) == 4100.0_h ); +assert( half_cast( std::numeric_limits::min() ) > 0.0_h ); +~~~~ + +When using round to nearest (either as default or through half_cast()) ties are by default resolved by rounding them away from zero (and thus equal to the behaviour of the round() function). But by redefining the [HALF_ROUND_TIES_TO_EVEN](\ref HALF_ROUND_TIES_TO_EVEN) preprocessor symbol to `1` (before including half.hpp) this default can be changed to the slightly slower but less biased and more IEEE-conformant behaviour of rounding half-way cases to the nearest even value. + +~~~~{.cpp} +#define HALF_ROUND_TIES_TO_EVEN 1 +#include +... +assert( half_cast(3.5_h) + == half_cast(4.5_h) ); +~~~~ + +Implementation {#implementation} +-------------- + +For performance reasons (and ease of implementation) many of the mathematical functions provided by the library as well as all arithmetic operations are actually carried out in single-precision under the hood, calling to the C++ standard library implementations of those functions whenever appropriate, meaning the arguments are converted to `float`s and the result back to [half](\ref half_float::half). But to reduce the conversion overhead as much as possible any temporary values inside of lengthy expressions are kept in single-precision as long as possible, while still maintaining a strong half-precision type to the outside world. Only when finally assigning the value to a [half](\ref half_float::half) or calling a function that works directly on [half](\ref half_float::half)s is the actual conversion done (or never, when further converting the result to `float`). + +This approach has two implications. First of all you have to treat the documentation on this site as a simplified version, describing the behaviour of the library as if implemented this way. The actual argument and return types of functions and operators may involve other internal types (feel free to generate the exact developer documentation from the Doxygen comments in the library's header file if you really need to). But nevertheless the behaviour is exactly like specified in the documentation. The other implication is, that in the presence of rounding errors or over-/underflows arithmetic expressions may produce different results when compared to converting to half-precision after each individual operation: + +~~~~{.cpp} +half a = std::numeric_limits::max() * 2.0_h / 2.0_h; // a = MAX +half b = half(std::numeric_limits::max() * 2.0_h) / 2.0_h; // b = INF +assert( a != b ); +~~~~ + +But this should only be a problem in very few cases. One last word has to be said when talking about performance. Even with its efforts in reducing conversion overhead as much as possible, the software half-precision implementation can most probably not beat the direct use of single-precision computations. Usually using actual `float` values for all computations and temproraries and using [half](\ref half_float::half)s only for storage is the recommended way. On the one hand this somehow makes the provided mathematical functions obsolete (especially in light of the implicit conversion from [half](\ref half_float::half) to `float`), but nevertheless the goal of this library was to provide a complete and conceptually clean half-precision implementation, to which the standard mathematical functions belong, even if usually not needed. + +IEEE conformance {#ieee} +---------------- + +The [half](\ref half_float::half) type uses the standard IEEE representation with 1 sign bit, 5 exponent bits and 10 mantissa bits (11 when counting the hidden bit). It supports all types of special values, like subnormal values, infinity and NaNs. But there are some limitations to the complete conformance to the IEEE 754 standard: + +- The implementation does not differentiate between signalling and quiet NaNs, this means operations on [half](\ref half_float::half)s are not specified to trap on signalling NaNs (though they may, see last point). +- Though arithmetic operations are internally rounded to single-precision using the underlying single-precision implementation's current rounding mode, those values are then converted to half-precision using the default half-precision rounding mode (changed by defining [HALF_ROUND_STYLE](\ref HALF_ROUND_STYLE) and [HALF_ROUND_TIES_TO_EVEN](\ref HALF_ROUND_TIES_TO_EVEN) accordingly). This mixture of rounding modes is also the reason why [std::numeric_limits::round_style](\ref std::numeric_limits::round_style) may actually return `std::round_indeterminate` when half- and single-precision rounding modes don't match. +- Because of internal truncation it may also be that certain single-precision NaNs will be wrongly converted to half-precision infinity, though this is very unlikely to happen, since most single-precision implementations don't tend to only set the lowest bits of a NaN mantissa. +- The implementation does not provide any floating point exceptions, thus arithmetic operations or mathematical functions are not specified to invoke proper floating point exceptions. But due to many functions implemented in single-precision, those may still invoke floating point exceptions of the underlying single-precision implementation. + +Some of those points could have been circumvented by controlling the floating point environment using `` or implementing a similar exception mechanism. But this would have required excessive runtime checks giving two high an impact on performance for something that is rarely ever needed. If you really need to rely on proper floating point exceptions, it is recommended to explicitly perform computations using the built-in floating point types to be on the safe side. In the same way, if you really need to rely on a particular rounding behaviour, it is recommended to either use single-precision computations and explicitly convert the result to half-precision using half_cast() and specifying the desired rounding mode, or synchronize the default half-precision rounding mode to the rounding mode of the single-precision implementation (most likely `HALF_ROUND_STYLE=1`, `HALF_ROUND_TIES_TO_EVEN=1`). But this is really considered an expert-scenario that should be used only when necessary, since actually working with half-precision usually comes with a certain tolerance/ignorance of exactness considerations and proper rounding comes with a certain performance cost. + + +------------------- +Credits and Contact {#contact} +=================== + +This library is developed by [Christian Rau](http://sourceforge.net/users/rauy) and released under the [MIT License](LICENSE.txt). If you have any questions or problems with it, feel free to contact me at [rauy AT users.sourceforge.net](mailto:rauy@users.sourceforge.net) or use any of the other means for [support](usergroup1.html). + +Additional credit goes to **Jeroen van der Zijp** for his paper on [Fast Half Float Conversions](ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf), whose algorithms have been used in the library for converting between half-precision and single-precision values. diff --git a/gpu/third_party/half/web/News.md b/gpu/third_party/half/web/News.md new file mode 100644 index 0000000..faca436 --- /dev/null +++ b/gpu/third_party/half/web/News.md @@ -0,0 +1,141 @@ +News {#news} +==== + +March 6, 2017 - Release 1.12.0 +------------------------------ + +[Version 1.12.0](http://sourceforge.net/projects/half/files/half/1.12.0) of the library has been released. It changes the behaviour of half_cast() when casting to/from builtin floating point types. Previously those were performed by an explicit intermediary cast to/from `float`. But this could lead to imprecise results, since the rounding from `double`/`long double` to `float` was not controlled by the rounding mode of the half_cast(). Now each half_cast() always rounds directly to/from the specified type using the given rounding mode and thus guarantees exact compliance to this rounding mode. Furthermore, a minor portability issue with logb() and ilogb() has been fixed, that could cause trouble on non-twos-complement implementations (if there are any at all). It was also tested for *MS Visual C++ 2015*. + +---------------------------------- +November 16, 2013 - Release 1.11.0 +---------------------------------- + +[Version 1.11.0](http://sourceforge.net/projects/half/files/half/1.11.0) of the library has been released. It further increases the flexibility of the rounding, by allowing the round to nearest behaviour to be configured more precisely. By default half-way cases during round to nearest are rounded away from zero (and thus analogous to the round() function), but by redefining [HALF_ROUND_TIES_TO_EVEN](\ref HALF_ROUND_TIES_TO_EVEN) to `1` this can be changed to the slower but less biased round to even. In addition to that the support for C++11 mathematical functions in light of unsupported single-precision versions has been completed by providing erf(), erfc(), lgamma() and tgamma() even if their `` counterparts are unavailable. Furthermore, it fixes a bug that made it impossible to disable support for C++11 mathematical functions in *VC++ 2013*. + +--------------------------------- +November 9, 2013 - Release 1.10.0 +--------------------------------- + +[Version 1.10.0](http://sourceforge.net/projects/half/files/half/1.10.0) of the library has been released. It adds the possibility of changing the default rounding mode for halfs (used for any float-to-half conversion) at compile-time by redefining the [HALF_ROUND_STYLE](\ref HALF_ROUND_STYLE) preprocessor symbol. In addition to that the behaviour of the half_cast() function was adjusted to respect the specified rounding mode for conversions to/from integer types, without a roundtrip over an additional conversion to/from `float`. The half_cast() now only supports built-in arithmetic types (apart from [half](\ref half_float::half)s, of course) and any further conversions from them to custom types have to be done explicitly. The usage and checks of C++11 features has been extended by support for type traits and TMP facilities from ``, controllable with the `HALF_ENABLE_CPP11_TYPE_TRAITS` symbol. Last but not least, the library now supports non-IEEE single-precision implementations, which are pretty unlikely nowadays, though. + +-------------------------------- +November 1, 2013 - Release 1.9.2 +-------------------------------- + +[Version 1.9.2](http://sourceforge.net/projects/half/files/half/1.9.2) of the library has been released. It was tested and fixed for *MS Visual C++ 2013* and *gcc 4.8*. In addition to that it removes some warnings on *MSVC* compilers in general. + +------------------------------ +August 8, 2013 - Release 1.9.1 +------------------------------ + +[Version 1.9.1](http://sourceforge.net/projects/half/files/half/1.9.1) of the library has been released. It fixes compilation problems with older *gcc* and *MSVC* versions. Furthermore it adds a small fix to the non-C++11 implementations of remainder() and remquo(), which could cause a missing symbol on implementations that do not bring `` functions into global namespace. + +------------------------------ +August 7, 2013 - Release 1.9.0 +------------------------------ + +[Version 1.9.0](http://sourceforge.net/projects/half/files/half/1.9.0) of the library has been released. This version fixes the behaviour of the half-precsion C++11 functions `nearbyint`, `rint`, `lrint` and `llrint`. Formerly those functions were implemented in terms of their respective single-precision versions from `` (and thus were only supported if the single-precision versions were available, too) and were thus using the current rounding mode of the underlying single-precision implementation. But it is conceptually more correct for those functions to use the rounding mode of the half-precision implementation (truncation). So now those functions are always supported and return the nearest integer according to [half](\ref half_float::half)'s internal rounding mode and thus behave equivalently to trunc() and `static_cast` respectively. Furthermore the support for C++11 mathematical functions in light of unsupported single-precision versions has been increased further, by providing remainder(), remquo() and cbrt() even if their `` counterparts are unavailable. + +-------------------------------- +January 22, 2013 - Release 1.8.1 +-------------------------------- + +[Version 1.8.1](http://sourceforge.net/projects/half/files/half/1.8.1) of the library has been released. This just fixes a compile error when including `half.hpp` in multiple files, resulting in multiple definitions of the nanh() function due to a missing `inline` specification. + +-------------------------------- +January 19, 2013 - Release 1.8.0 +-------------------------------- + +[Version 1.8.0](http://sourceforge.net/projects/half/files/half/1.8.0) of the library has been released. It adds support for a bunch of additional C++11 mathematical functions even if their single-precision counterparts are not supported, in particular exponential and logarithmic functions (exp2(), expm1(), log2(), log1p()), hyperbolic area functions (asinh(), acosh(), atanh()) and the hypotenuse function (hypot()). The fma() function now uses the default single-precision implementation even if the single-precision version from `` is available but not faster than the straight-forward implementation. Thus it is now always at least equally fast to the manual half-precision `x*y + z` operation (yet being correctly rounded as a single operation) and thus [FP_FAST_FMAH](\ref FP_FAST_FMAH) practically always defined. + +Furthermore, the internal expression implementation has been completely revised. This fixes issues with overload resolution which could occur when trying to call certain mathematical functions by unqualified invocation (relying on `using` declarations or ADL) and led to ambiguities or the incorrect preference of the standard library functions over the half-precision versions. + +-------------------------------- +October 26, 2012 - Release 1.7.0 +-------------------------------- + +[Version 1.7.0](http://sourceforge.net/projects/half/files/half/1.7.0) of the library has been released. It adds support for C++11 `noexcept` specifications. But due to the ongoing discussions about their appropriate usage in practice (and the author's limited experience with them) they are at the moment only used to provide a C++11-conformant `std::numeric_limits` specialization, with all its functions returning half-preicision constants now properly being `noexcept`. Furthermore, the automatic support for C++11 `long long` and the corresponding mathematical functions on *Microsoft* compilers has been extended all the way down to *VC++ 2003*. + +---------------------------------- +September 13, 2012 - Release 1.6.1 +---------------------------------- + +[Version 1.6.1](http://sourceforge.net/projects/half/files/half/1.6.1) of the library has been released. It makes the fma() and fdim() functions available even if the corresponding single-precision functions from C++11 `` are not supported. + +---------------------------------- +September 12, 2012 - Release 1.6.0 +---------------------------------- + +[Version 1.6.0](http://sourceforge.net/projects/half/files/half/1.6.0) of the library has been released. It fixes a major bug in the C++98 compatibility for non-VC compilers, which required C++11 `` functions even without C++11 support enabled. Furthermore, an additional preprocessor flag `HALF_ENABLE_CPP11_LONG_LONG` has been added, which controls the support for C++11 `long long` integers and the corresponding mathematical functions (actually only llround()). + +------------------------------- +August 17, 2012 - Release 1.5.1 +------------------------------- + +[Version 1.5.1](http://sourceforge.net/projects/half/files/half/1.5.1) of the library has been released. It fixes the `std::numeric_limits` specialization to always return `std::round_indeterminate` as `round_style`, even if the `float` version returns `std::round_toward_zero`. This is neccessary as the single-to-half conversion is not exactly round-toward-zero, since it maps overflows to +/-infinity instead of the maximum/minimum finite value. + +------------------------------- +August 16, 2012 - Release 1.5.0 +------------------------------- + +[Version 1.5.0](http://sourceforge.net/projects/half/files/half/1.5.0) of the library has been released. It adds a special half_cast() that can be used to cast between [half](\ref half_float::half) and any type convertible to/from `float`. In addition to doing an explicit conversion via `float` and thus avoiding any possible warnings about precision loss, it allows the explicit specification of the rounding mode to use for the single-to-half conversion (if any). This way you can choose a specific rounding mode if needed and can even synchronize it with the rounding mode of the underlying single-precision implementation (which is usually `std::round_to_nearest`). But this is more of an expert feature to be used when you are sure you really need it (which should rarely be the case) and most of the time the default rounding from single- to half-precision (`std::round_indeterminate`), which is the fastest, will be sufficient. Furthermore, the library has been tested successfully with Visual C++ 2008. + +------------------------------- +August 12, 2012 - Release 1.4.0 +------------------------------- + +[Version 1.4.0](http://sourceforge.net/projects/half/files/half/1.4.0) of the library has been released. It adds support for C++11 generalized constant expressions (`constexpr`). But due to the not constantly expressable half-single-conversions most arithmetic operators as well as the half-precision literals cannot be made `constexpr`. The only `constexpr` operators are the unary plus and minus as well as the zero-initializing default constructor. But now the `std::numeric_limits` specialization is C++11-conformant, with all its special half-precision constants being actual constant expressions. + +------------------------------- +August 11, 2012 - Release 1.3.1 +------------------------------- + +[Version 1.3.1](http://sourceforge.net/projects/half/files/half/1.3.1) of the library has been released. It fixes a bug with non-VC compilers that required the presence of `std::isnan` and `std::signbit` even if C++11 `` functions are unsupported/disabled. Furthermore the library has been tested successfully with Visual C++ 2005 and 2012. + +------------------------------- +August 10, 2012 - Release 1.3.0 +------------------------------- + +[Version 1.3.0](http://sourceforge.net/projects/half/files/half/1.3.0) of the library has been released. It makes the requirement for C++11's `` and `static_assert` optional and thus is now comletely C++98-compatible. Furthermore, all the C++11 features used by the library and detected automatically are now overridable by the user, by just defining the corresponding preprocessor symbols to 0 or 1, which is useful in cases where the automatic detection fails or where the support for a feature should be explicitly disabled. + +------------------------------ +August 7, 2012 - Release 1.2.0 +------------------------------ + +[Version 1.2.0](http://sourceforge.net/projects/half/files/half/1.2.0) of the library has been released. It adds preprocessor definitions for [HUGE_VALH](\ref HUGE_VALH) and (maybe) [FP_FAST_FMAH](\ref FP_FAST_FMAH) in correspondence with their respective single-precision counterparts from ``. It also fixes the preprocessor symbols it uses internally to be undefined properly after their use. Furthermore, the library has been tested successfully with *clang 3.1*. + +------------------------------ +August 7, 2012 - Release 1.1.2 +------------------------------ + +[Version 1.1.2](http://sourceforge.net/projects/half/files/half/1.1.2) of the library has been released. It fixes the `std::numeric_limits` specialization further, enabling it to return `std::round_toward_zero` instead of `std::round_indeterminate` when possible (though this is very unlikely). Additionally the `round_error()` has been corrected to reflect the worst-case round-toward-zero behaviour. Furthermore, the library has been tested successfully with *gcc 4.5*. + +------------------------------ +August 6, 2012 - Release 1.1.1 +------------------------------ + +[Version 1.1.1](http://sourceforge.net/projects/half/files/half/1.1.1) of the library has been released. It includes a minor fix to the `std::numeric_limits` specialization, which now returns a normalized number for `min()` according to the C++ standard. Additionally the `round_style` is now `std::round_indeterminate` due to the mixture of internal single-precision rounding with float-to-half truncation. + +------------------------------ +August 6, 2012 - Release 1.1.0 +------------------------------ + +[Version 1.1.0](http://sourceforge.net/projects/half/files/half/1.1.0) of the library has been released. It provides support for explicit half-precision literals using C++11's user-defined literals. It has been tested successfully with *gcc 4.7*. + +------------------------------------ +August 5, 2012 - First release 1.0.0 +------------------------------------ + +The first official release, [version 1.0.0](http://sourceforge.net/projects/half/files/half/1.0.0), of the library is finally out. + +--------------------------------------------- +August 1, 2012 - Code and Project-Web release +--------------------------------------------- + +The first version of the library has been checked into source control and is thus available to the public through the [SVN repository](http://sourceforge.net/p/half/code/), though still waiting for an explicit file release. Additionally the project web containing the library's documentation went online. + +-------------------------------- +July 30, 2012 - Project Kick-off +-------------------------------- + +The **half** project has finally been registered on [Sourceforge.net](http://sourceforge.net/projects/half/). diff --git a/gpu/third_party/half/web/half.hpp b/gpu/third_party/half/web/half.hpp new file mode 100644 index 0000000..fa4d6f3 --- /dev/null +++ b/gpu/third_party/half/web/half.hpp @@ -0,0 +1,936 @@ +// half - IEEE 754-based half-precision floating point library. +// +// Copyright (c) 2012-2017 Christian Rau +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is 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 Software. +// +// THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This is a dummy header file to provide a clean interface documentation to Doxygen, without any ugly internals. + +/// \file +/// Main header file of the library. + + +/// Default rounding mode. +/// This specifies the rounding mode used for all conversions between [half](\ref half_float::half)s and `float`s as well as +/// for the half_cast() if not specifying a rounding mode explicitly. It can be redefined (before including `half.hpp`) to one +/// of the standard rounding modes using their respective constants or the equivalent values of +/// [std::float_round_style](http://en.cppreference.com/w/cpp/types/numeric_limits/float_round_style): +/// +/// `std::float_round_style` | value | rounding +/// ---------------------------------|-------|------------------------- +/// `std::round_indeterminate` | -1 | fastest (default) +/// `std::round_toward_zero` | 0 | toward zero +/// `std::round_to_nearest` | 1 | to nearest +/// `std::round_toward_infinity` | 2 | toward positive infinity +/// `std::round_toward_neg_infinity` | 3 | toward negative infinity +/// +/// By default this is set to `-1` (`std::round_indeterminate`), which uses truncation (round toward zero, but with overflows +/// set to infinity) and is the fastest rounding mode possible. It can even be set to +/// [std::numeric_limits::round_style](http://en.cppreference.com/w/cpp/types/numeric_limits/round_style) to synchronize +/// the rounding mode with that of the underlying single-precision implementation. +#define HALF_ROUND_STYLE -1 + +/// Tie-breaking behaviour for round to nearest. +/// This specifies if ties in round to nearest should be resolved by rounding to the nearest even value. By default this is +/// defined to `0` resulting in the faster but slightly more biased behaviour of rounding away from zero in half-way cases (and +/// thus equal to the round() function), but can be redefined to `1` (before including half.hpp) if more IEEE-conformant +/// behaviour is needed. +#define HALF_ROUND_TIES_TO_EVEN 0 + +/// Value signaling overflow. +/// In correspondence with `HUGE_VAL[F|L]` from `` this symbol expands to a positive value signaling the overflow of an +/// operation, in particular it just evaluates to positive infinity. +/// +/// **See also:** Documentation for [HUGE_VAL](http://en.cppreference.com/w/cpp/numeric/math/HUGE_VAL) +#define HUGE_VALH std::numeric_limits::infinity() + +/// Fast half-precision fma function. +/// This symbol is only defined if the fma() function generally executes as fast as, or faster than, a separate +/// half-precision multiplication followed by an addition. Due to the internal single-precision implementation of all +/// arithmetic operations, this is in fact always the case. +/// +/// **See also:** Documentation for [FP_FAST_FMA](http://en.cppreference.com/w/cpp/numeric/math/fma) +#define FP_FAST_FMAH 1 + + +/// Main namespace for half precision functionality. +/// This namespace contains all the functionality provided by the library. +namespace half_float +{ + /// Half-precision floating point type. + /// This class implements an IEEE-conformant half-precision floating point type with the usual arithmetic operators and + /// conversions. It is implicitly convertible to single-precision floating point, which makes artihmetic expressions and + /// functions with mixed-type operands to be of the most precise operand type. Additionally all arithmetic operations + /// (and many mathematical functions) are carried out in single-precision internally. All conversions from single- to + /// half-precision are done using the library's default rounding mode, but temporary results inside chained arithmetic + /// expressions are kept in single-precision as long as possible (while of course still maintaining a strong half-precision type). + /// + /// According to the C++98/03 definition, the half type is not a POD type. But according to C++11's less strict and + /// extended definitions it is both a standard layout type and a trivially copyable type (even if not a POD type), which + /// means it can be standard-conformantly copied using raw binary copies. But in this context some more words about the + /// actual size of the type. Although the half is representing an IEEE 16-bit type, it does not neccessarily have to be of + /// exactly 16-bits size. But on any reasonable implementation the actual binary representation of this type will most + /// probably not ivolve any additional "magic" or padding beyond the simple binary representation of the underlying 16-bit + /// IEEE number, even if not strictly guaranteed by the standard. But even then it only has an actual size of 16 bits if + /// your C++ implementation supports an unsigned integer type of exactly 16 bits width. But this should be the case on + /// nearly any reasonable platform. + /// + /// So if your C++ implementation is not totally exotic or imposes special alignment requirements, it is a reasonable + /// assumption that the data of a half is just comprised of the 2 bytes of the underlying IEEE representation. + struct half + { + /// \name Construction and assignment + /// \{ + + /// Default constructor. + /// This initializes the half to 0. Although this does not match the builtin types' default-initialization semantics + /// and may be less efficient than no initialization, it is needed to provide proper value-initialization semantics. + constexpr half() noexcept; + + /// Conversion constructor. + /// \param rhs float to convert + explicit half(float rhs); + + /// Conversion to single-precision. + /// \return single precision value + operator float() const; + + /// Single-precision assignment. + /// \param rhs single-precision value to copy from + /// \return reference to this half + half& operator=(float rhs); + + /// \} + /// \name Arithmetic updates + /// \{ + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \tparam E type of concrete half expression + /// \param rhs half to add + /// \return reference to this half + half& operator+=(half rhs); + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \tparam E type of concrete half expression + /// \param rhs half to subtract + /// \return reference to this half + half& operator-=(half rhs); + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \tparam E type of concrete half expression + /// \param rhs half to multiply with + /// \return reference to this half + half& operator*=(half rhs); + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \tparam E type of concrete half expression + /// \param rhs half to divide by + /// \return reference to this half + half& operator/=(half rhs); + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \param rhs single-precision value to add + /// \return reference to this half + half& operator+=(float rhs); + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \param rhs single-precision value to subtract + /// \return reference to this half + half& operator-=(float rhs); + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \param rhs single-precision value to multiply with + /// \return reference to this half + half& operator*=(float rhs); + + /// Arithmetic assignment. + /// This operation uses the underlying single-precision implementation. + /// \param rhs single-precision value to divide by + /// \return reference to this half + half& operator/=(float rhs); + + /// \} + /// \name Increment and decrement + /// \{ + + /// Prefix increment. + /// This operation uses the underlying single-precision implementation. + /// \return incremented half value + half& operator++(); + + /// Prefix decrement. + /// This operation uses the underlying single-precision implementation. + /// \return decremented half value + half& operator--(); + + /// Postfix increment. + /// This operation uses the underlying single-precision implementation. + /// \return non-incremented half value + half operator++(int); + + /// Postfix decrement. + /// This operation uses the underlying single-precision implementation. + /// \return non-decremented half value + half operator--(int); + /// \} + }; + + + /// \name Comparison operators + /// \{ + + /// Comparison for equality. + /// \param a first operand + /// \param b second operand + /// \retval true if operands equal + /// \retval false else + bool operator==(half a, half b); + + /// Comparison for inequality. + /// \param a first operand + /// \param b second operand + /// \retval true if operands not equal + /// \retval false else + bool operator!=(half a, half b); + + /// Comparison for less than. + /// \param a first operand + /// \param b second operand + /// \retval true if \a a less than \a b + /// \retval false else + bool operator<(half a, half b); + + /// Comparison for greater than. + /// \param a first operand + /// \param b second operand + /// \retval true if \a a greater than \a b + /// \retval false else + bool operator>(half a, half b); + + /// Comparison for less equal. + /// \param a first operand + /// \param b second operand + /// \retval true if \a a less equal \a b + /// \retval false else + bool operator<=(half a, half b); + + /// Comparison for greater equal. + /// \param a first operand + /// \param b second operand + /// \retval true if \a a greater equal \a b + /// \retval false else + bool operator>=(half a, half b); + + /// \} + /// \name Arithmetic operators + /// \{ + + /// Add halfs. + /// This operation uses the underlying single-precision implementation. + /// \param a left operand + /// \param b right operand + /// \return sum of halfs + half operator+(half a, half b); + + /// Subtract halfs. + /// This operation uses the underlying single-precision implementation. + /// \param a left operand + /// \param b right operand + /// \return difference of halfs + half operator-(half a, half b); + + /// Multiply halfs. + /// This operation uses the underlying single-precision implementation. + /// \param a left operand + /// \param b right operand + /// \return product of halfs + half operator*(half a, half b); + + /// Divide halfs. + /// This operation uses the underlying single-precision implementation. + /// \param a left operand + /// \param b right operand + /// \return quotient of halfs + half operator/(half a, half b); + + /// Identity. + /// \param h operand + /// \return uncahnged operand + half constexpr operator+(half h); + + /// Negation. + /// \param h operand + /// \return negated operand + half constexpr operator-(half h); + + /// \} + /// \name Input and output + /// \{ + + /// Output operator. + /// \tparam charT character type + /// \tparam traits character traits + /// \param out output stream to write into + /// \param h half to write + /// \return reference to output stream + template std::basic_ostream& operator<<(std::basic_ostream &out, half h); + + /// Input operator. + /// \tparam charT character type + /// \tparam traits character traits + /// \param in input stream to read from + /// \param h half to read into + /// \return reference to input stream + template std::basic_istream& operator>>(std::basic_istream &in, half &h); + + /// \} + /// \name Basic mathematical operations + /// \{ + + /// Absolute value. + /// \param arg operand + /// \return absolute value of \a arg + half abs(half arg); + + /// Absolute value. + /// \param arg operand + /// \return absolute value of \a arg + half fabs(half arg); + + /// Remainder of division. + /// This function uses the underlying single-precision implementation. + /// \param x first operand + /// \param y second operand + /// \return remainder of floating point division. + half fmod(half x, half y); + + /// Remainder of division. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param x first operand + /// \param y second operand + /// \return remainder of floating point division. + half remainder(half x, half y); + + /// Remainder of division. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param x first operand + /// \param y second operand + /// \param quo address to store some bits of quotient at + /// \return remainder of floating point division. + half remquo(half x, half y, int *quo); + + /// Fused multiply add. + /// This function uses the underlying single-precision implementation from C++11 `` if it is supported **and** + /// faster than the straight-forward single-precision implementation (thus if `FP_FAST_FMAF` is defined). + /// \param x first operand + /// \param y second operand + /// \param z third operand + /// \return ( \a x * \a y ) + \a z rounded as one operation. + half fma(half x, half y, half z); + + /// Minimum of halfs. + /// \param x first operand + /// \param y second operand + /// \return minimum of operands + half fmin(half x, half y); + + /// Maximum of halfs. + /// \param x first operand + /// \param y second operand + /// \return maximum of operands + half fmax(half x, half y); + + /// Positive difference. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param x first operand + /// \param y second operand + /// \return \a x - \a y or 0 if difference negative + half fdim(half x, half y); + + /// Get NaN value. + /// \return quiet NaN + half nanh(const char*); + + /// \} + /// \name Exponential functions + /// \{ + + /// Exponential function. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return e raised to \a arg + half exp(half arg); + + /// Binary exponential. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return 2 raised to \a arg + half exp2(half arg); + + /// Exponential minus one. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return e raised to \a arg and subtracted by 1 + half expm1(half arg); + + /// Natural logorithm. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return logarithm of \a arg to base e + half log(half arg); + + /// Common logorithm. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return logarithm of \a arg to base 10 + half log10(half arg); + + /// Natural logorithm. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return logarithm of \a arg + 1 to base e + half log1p(half arg); + + /// Binary logorithm. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return logarithm of \a arg to base 2 + half log2(half arg); + + /// \} + /// \name Power functions + /// \{ + + /// Square root. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return square root of \a arg + half sqrt(half arg); + + /// Cubic root. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return cubic root of \a arg + half cbrt(half arg); + + /// Hypotenuse function. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param x first argument + /// \param y second argument + /// \return square root of sum of squares without internal over- or underflows + half hypot(half x, half y); + + /// Power function. + /// This function uses the underlying single-precision implementation. + /// \param base first argument + /// \param exp second argument + /// \return \a base raised to \a exp + half pow(half base, half exp); + + /// \} + /// \name Trigonometric functions + /// \{ + + /// Sine function. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return sine value of \a arg + half sin(half arg); + + /// Cosine function. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return cosine value of \a arg + half cos(half arg); + + /// Tangent function. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return tangent value of \a arg + half tan(half arg); + + /// Arc sine. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return arc sine value of \a arg + half asin(half arg); + + /// Arc cosine function. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return arc cosine value of \a arg + half acos(half arg); + + /// Arc tangent function. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return arc tangent value of \a arg + half atan(half arg); + + /// Arc tangent function. + /// This function uses the underlying single-precision implementation. + /// \param x first argument + /// \param y second argument + /// \return arc tangent value + half atan2(half x, half y); + + /// \} + /// \name Hyperbolic functions + /// \{ + + /// Hyperbolic sine. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return hyperbolic sine value of \a arg + half sinh(half arg); + + /// Hyperbolic cosine. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return hyperbolic cosine value of \a arg + half cosh(half arg); + + /// Hyperbolic tangent. + /// This function uses the underlying single-precision implementation. + /// \param arg function argument + /// \return hyperbolic tangent value of \a arg + half tanh(half arg); + + /// Hyperbolic area sine. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return hyperbolic area sine value of \a arg + half asinh(half arg); + + /// Hyperbolic area cosine. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return hyperbolic area cosine value of \a arg + half acosh(half arg); + + /// Hyperbolic area tangent. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return hyperbolic area tangent value of \a arg + half atanh(half arg); + + /// \} + /// \name Error and gamma functions + /// \{ + + /// Error function. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return error function value of \a arg + half erf(half arg); + + /// Complementary error function. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return 1 minus error function value of \a arg + half erfc(half arg); + + /// Natural logarithm of gamma function. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return natural logarith of gamma function for \a arg + half lgamma(half arg); + + /// Gamma function. + /// This function uses the underlying single-precision implementation if C++11 `` functions are supported. + /// \param arg function argument + /// \return gamma function value of \a arg + half tgamma(half arg); + + /// \} + /// \name Rounding + /// \{ + + /// Nearest integer not less than half value. + /// \param arg half to round + /// \return nearest integer not less than \a arg + half ceil(half arg); + + /// Nearest integer not greater than half value. + /// \param arg half to round + /// \return nearest integer not greater than \a arg + half floor(half arg); + + /// Nearest integer not greater in magnitude than half value. + /// \param arg half to round + /// \return nearest integer not greater in magnitude than \a arg + half trunc(half arg); + + /// Nearest integer. + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases + half round(half arg); + + /// Nearest integer. + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases + long lround(half arg); + + /// Nearest integer. + /// This function requires support for C++11 `long long`. + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases + long long llround(half arg); + + /// Nearest integer. + /// \tparam E type of half expression + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + half nearbyint(half arg); + + /// Nearest integer. + /// \tparam E type of half expression + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + half rint(half arg); + + /// Nearest integer. + /// \tparam E type of half expression + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + long lrint(half arg); + + /// Nearest integer. + /// This function requires support for C++11 `long long`. + /// \tparam E type of half expression + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + long long llrint(half arg); + + /// \} + /// \name Floating point manipulation + /// \{ + + /// Decompress floating point number. + /// \param arg number to decompress + /// \param exp address to store exponent at + /// \return significant in range [0.5, 1) + half frexp(half arg, int *exp); + + /// Multiply by power of two. + /// \param arg number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp + half ldexp(half arg, int exp); + + /// Extract integer and fractional parts. + /// \param x number to decompress + /// \param iptr address to store integer part at + /// \return fractional part + half modf(half x, half *iptr); + + /// Multiply by power of two. + /// \param x number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp + half scalbn(half x, int exp); + + /// Multiply by power of two. + /// \param x number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp + half scalbln(half x, long exp); + + /// Extract exponent. + /// \param arg number to query + /// \return floating point exponent + /// \retval FP_ILOGB0 for zero + /// \retval FP_ILOGBNAN for NaN + /// \retval MAX_INT for infinity + int ilogb(half arg); + + /// Extract exponent. + /// \param arg number to query + /// \return floating point exponent + half logb(half arg); + + /// Next representable value. + /// \param from value to compute next representable value for + /// \param to direction towards which to compute next value + /// \return next representable value after \a from in direction towards \a to + half nextafter(half from, half to); + + /// Next representable value. + /// \param from value to compute next representable value for + /// \param to direction towards which to compute next value + /// \return next representable value after \a from in direction towards \a to + half nexttoward(half from, long double to); + + /// Take sign. + /// \param x value to change sign for + /// \param y value to take sign from + /// \return value equal to \a x in magnitude and to \a y in sign + half copysign(half x, half y); + + /// \} + /// \name Floating point classification + /// \{ + + /// Classify floating point value. + /// \param arg number to classify + /// \retval FP_ZERO for positive and negative zero + /// \retval FP_SUBNORMAL for subnormal numbers + /// \retval FP_INFINITY for positive and negative infinity + /// \retval FP_NAN for NaNs + /// \retval FP_NORMAL for all other (normal) values + int fpclassify(half arg); + + /// Check if finite number. + /// \param arg number to check + /// \retval true if neither infinity nor NaN + /// \retval false else + bool isfinite(half arg); + + /// Check for infinity. + /// \param arg number to check + /// \retval true for positive or negative infinity + /// \retval false else + bool isinf(half arg); + + /// Check for NaN. + /// \param arg number to check + /// \retval true for NaNs + /// \retval false else + bool isnan(half arg); + + /// Check if normal number. + /// \param arg number to check + /// \retval true if normal number + /// \retval false if either subnormal, zero, infinity or NaN + bool isnormal(half arg); + + /// Check sign. + /// \param arg number to check + /// \retval true for negative number + /// \retval false for positive number + bool signbit(half arg); + + /// \} + /// \name Comparison + /// \{ + + /// Comparison for greater than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater than \a y + /// \retval false else + bool isgreater(half x, half y); + + /// Comparison for greater equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater equal \a y + /// \retval false else + bool isgreaterequal(half x, half y); + + /// Comparison for less than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less than \a y + /// \retval false else + bool isless(half x, half y); + + /// Comparison for less equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less equal \a y + /// \retval false else + bool islessequal(half x, half y); + + /// Comarison for less or greater. + /// \param x first operand + /// \param y second operand + /// \retval true if either less or greater + /// \retval false else + bool islessgreater(half x, half y); + + /// Check if unordered. + /// \param x first operand + /// \param y second operand + /// \retval true if unordered (one or two NaN operands) + /// \retval false else + bool isunordered(half x, half y); + + /// \} + /// \name Casting + /// \{ + + /// Cast to or from half-precision floating point number. + /// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted directly + /// using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do. It uses the + /// default rounding mode. + /// + /// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types + /// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler + /// error and casting between [half](\ref half_float::half)s is just a no-op. + /// \tparam T destination type (half or built-in arithmetic type) + /// \tparam U source type (half or built-in arithmetic type) + /// \param arg value to cast + /// \return \a arg converted to destination type + template T half_cast(const U &arg); + + /// Cast to or from half-precision floating point number. + /// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted directly + /// using the given rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do. + /// + /// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types + /// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler + /// error and casting between [half](\ref half_float::half)s is just a no-op. + /// \tparam T destination type (half or built-in arithmetic type) + /// \tparam R rounding mode to use (see [std::float_round_style](http://en.cppreference.com/w/cpp/types/numeric_limits/float_round_style)) + /// \tparam U source type (half or built-in arithmetic type) + /// \param arg value to cast + /// \return \a arg converted to destination type + template T half_cast(const U &arg); + /// \} + + + /// Library-defined half-precision literals. + /// Import this namespace to enable half-precision floating point literals (of course only if C++11 user-defined literals + /// are supported and enabled): + /// ~~~~{.cpp} + /// using namespace half_float::literal; + /// half_float::half = 4.2_h; + /// ~~~~ + namespace literal + { + /// Half literal. + /// While this returns an actual half-precision value, half literals can unfortunately not be constant expressions due + /// to rather involved conversions. + /// \param value literal value + /// \return half with given value (if representable) + half operator""_h(long double value); + } +} + + +/// Extensions to the C++ standard library. +namespace std +{ + /// Numeric limits for half-precision floats. + /// Because of the underlying single-precision implementation of many operations, it inherits some properties from + /// `std::numeric_limits`. + /// + /// **See also:** Documentation for [std::numeric_limits](http://en.cppreference.com/w/cpp/types/numeric_limits) + template<> struct numeric_limits : public std::numeric_limits + { + /// Supports signed values. + static constexpr bool is_signed = true; + + /// Is not exact. + static constexpr bool is_exact = false; + + /// Doesn't provide modulo arithmetic. + static constexpr bool is_modulo = false; + + /// IEEE conformant. + static constexpr bool is_iec559 = true; + + /// Supports infinity. + static constexpr bool has_infinity = true; + + /// Supports quiet NaNs. + static constexpr bool has_quiet_NaN = true; + + /// Supports subnormal values. + static constexpr std::float_denorm_style has_denorm = std::denorm_present; + + /// Rounding mode. + /// Due to the mix of internal single-precision computations (using the rounding mode of the underlying + /// single-precision implementation) with the rounding mode of the single-to-half conversions, the actual rounding + /// mode might be `std::round_indeterminate` if the default half-precision rounding mode doesn't match the + /// single-precision rounding mode. + static constexpr std::float_round_style round_style = /* unspecified */; + + /// Significant digits. + static constexpr int digits = 11; + + /// Significant decimal digits. + static constexpr int digits10 = 3; + + /// Required decimal digits to represent all possible values. + static constexpr int max_digits10 = 5; + + /// Number base. + static constexpr int radix = 2; + + /// One more than smallest exponent. + static constexpr int min_exponent = -13; + + /// Smallest normalized representable power of 10. + static constexpr int min_exponent10 = -4; + + /// One more than largest exponent + static constexpr int max_exponent = 16; + + /// Largest finitely representable power of 10. + static constexpr int max_exponent10 = 4; + + /// Smallest positive normal value. + static constexpr half_float::half min() noexcept; + + /// Smallest finite value. + static constexpr half_float::half lowest() noexcept; + + /// Largest finite value. + static constexpr half_float::half max() noexcept; + + /// Difference between one and next representable value. + static constexpr half_float::half epsilon() noexcept; + + /// Maximum rounding error. + static constexpr half_float::half round_error() noexcept; + + /// Positive infinity. + static constexpr half_float::half infinity() noexcept; + + /// Quiet NaN. + static constexpr half_float::half quiet_NaN() noexcept; + + /// Signalling NaN. + static constexpr half_float::half signaling_NaN() noexcept; + + /// Smallest positive subnormal value. + static constexpr half_float::half denorm_min() noexcept; + }; + + /// Hash function for half-precision floats. + /// This is only defined if C++11 `std::hash` is supported and enabled. + /// + /// **See also:** Documentation for [std::hash](http://en.cppreference.com/w/cpp/utility/hash) + template<> struct hash + { + /// Type of function argument. + typedef half_float::half argument_type; + + /// Function return type. + typedef std::size_t result_type; + + /// Compute hash function. + /// \param arg half to hash + /// \return hash value + std::size_t operator()(half_float::half arg) const; + }; +} diff --git a/gpu/third_party/half/web/layout.xml b/gpu/third_party/half/web/layout.xml new file mode 100644 index 0000000..d9b524e --- /dev/null +++ b/gpu/third_party/half/web/layout.xml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpu/third_party/half/web/web.vcxproj b/gpu/third_party/half/web/web.vcxproj new file mode 100644 index 0000000..890052e --- /dev/null +++ b/gpu/third_party/half/web/web.vcxproj @@ -0,0 +1,101 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {B36DE2E9-6E9C-4629-AEDA-8EFAE78E29D0} + Win32Proj + web + + + + Utility + true + Unicode + v140 + + + Utility + false + true + Unicode + v140 + + + + + + + + + + + + + true + $(ProjectDir) + + + false + $(ProjectDir) + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Document + "C:\Program Files\doxygen\bin\doxygen.exe" $(InputPath) + Generating Documentation + html + $(ProjectDir)layout.xml;$(ProjectDir)half.hpp;$(ProjectDir)Mainpage.md;$(ProjectDir)News.md;$(ProjectDir)../ChangeLog.txt + $(ProjectDir)layout.xml;$(ProjectDir)half.hpp;$(ProjectDir)Mainpage.md;$(ProjectDir)News.md;$(ProjectDir)../ChangeLog.txt + html + Generating Documentation + "C:\Program Files\doxygen\bin\doxygen.exe" $(InputPath) + + + + + + + + + + + \ No newline at end of file diff --git a/gpu/third_party/half/web/web.vcxproj.filters b/gpu/third_party/half/web/web.vcxproj.filters new file mode 100644 index 0000000..e1433a2 --- /dev/null +++ b/gpu/third_party/half/web/web.vcxproj.filters @@ -0,0 +1,29 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {e31a1aed-8ae0-4fb3-8b17-812dc67ff73e} + md;txt + + + + + Dokumentationsdateien + + + Dokumentationsdateien + + + + + Headerdateien + + + + + + \ No newline at end of file diff --git a/gpu/third_party/sirit/.clang-format b/gpu/third_party/sirit/.clang-format new file mode 100644 index 0000000..1c6b71b --- /dev/null +++ b/gpu/third_party/sirit/.clang-format @@ -0,0 +1,88 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^\<[^Q][^/.>]*\>' + Priority: -2 + - Regex: '^\<' + Priority: -1 + - Regex: '^\"' + Priority: 0 +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 150 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... diff --git a/gpu/third_party/sirit/.gitignore b/gpu/third_party/sirit/.gitignore new file mode 100644 index 0000000..7353e7e --- /dev/null +++ b/gpu/third_party/sirit/.gitignore @@ -0,0 +1,2 @@ +build +*.o diff --git a/gpu/third_party/sirit/.gitmodules b/gpu/third_party/sirit/.gitmodules new file mode 100644 index 0000000..e925e6a --- /dev/null +++ b/gpu/third_party/sirit/.gitmodules @@ -0,0 +1,3 @@ +[submodule "externals/SPIRV-Headers"] + path = externals/SPIRV-Headers + url = https://github.com/KhronosGroup/SPIRV-Headers diff --git a/gpu/third_party/sirit/CMakeLists.txt b/gpu/third_party/sirit/CMakeLists.txt new file mode 100644 index 0000000..5ed8529 --- /dev/null +++ b/gpu/third_party/sirit/CMakeLists.txt @@ -0,0 +1,97 @@ +# This file has been adapted from dynarmic + +cmake_minimum_required(VERSION 3.18) +project(sirit CXX) + +# Determine if we're built as a subproject (using add_subdirectory) +# or if this is the master project. +set(MASTER_PROJECT OFF) +if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(MASTER_PROJECT ON) +endif() + +# Sirit project options +option(SIRIT_TESTS "Build tests" OFF) +option(SIRIT_USE_SYSTEM_SPIRV_HEADERS "Use system SPIR-V headers" OFF) + +# Default to a Release build +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) + message(STATUS "Defaulting to a Release build") +endif() + +# Set hard requirements for C++ +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Warn on CMake API deprecations +set(CMAKE_WARN_DEPRECATED ON) + +# Disable in-source builds +set(CMAKE_DISABLE_SOURCE_CHANGES ON) +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + message(SEND_ERROR "In-source builds are not allowed.") +endif() + +# Add the module directory to the list of paths +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") + +# Compiler flags +if (MSVC) + set(SIRIT_CXX_FLAGS + /std:c++latest # CMAKE_CXX_STANDARD as no effect on MSVC until CMake 3.10. + /W4 + /w34263 # Non-virtual member function hides base class virtual function + /w44265 # Class has virtual functions, but destructor is not virtual + /w34456 # Declaration of 'var' hides previous local declaration + /w34457 # Declaration of 'var' hides function parameter + /w34458 # Declaration of 'var' hides class member + /w34459 # Declaration of 'var' hides global definition + /w34946 # Reinterpret-cast between related types + /wd4592 # Symbol will be dynamically initialized (implementation limitation) + /permissive- # Stricter C++ standards conformance + /MP + /Zi + /Zo + /EHsc + /Zc:inline # Omits inline functions from object-file output + /DNOMINMAX + /WX) + + if (CMAKE_VS_PLATFORM_TOOLSET MATCHES "LLVM-vs[0-9]+") + list(APPEND SIRIT_CXX_FLAGS + -Qunused-arguments + -Wno-missing-braces) + endif() +else() + set(SIRIT_CXX_FLAGS + -Wall + -Wextra + -Wcast-qual + -pedantic + -pedantic-errors + -Wfatal-errors + -Wno-missing-braces + -Wconversion + -Wsign-conversion + -Wshadow + -Werror) +endif() + +# Enable unit-testing. +enable_testing(true) + +# SPIR-V headers +if (SIRIT_USE_SYSTEM_SPIRV_HEADERS) + find_package(SPIRV-Headers REQUIRED) +else() + add_subdirectory(externals/SPIRV-Headers EXCLUDE_FROM_ALL) +endif() + +# Sirit project files +add_subdirectory(src) +if (SIRIT_TESTS) + add_subdirectory(tests) +endif() diff --git a/gpu/third_party/sirit/LICENSE.txt b/gpu/third_party/sirit/LICENSE.txt new file mode 100644 index 0000000..eff331d --- /dev/null +++ b/gpu/third_party/sirit/LICENSE.txt @@ -0,0 +1,24 @@ +Copyright (c) 2019, sirit +All rights reserved. + +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 the 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 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. diff --git a/gpu/third_party/sirit/README.md b/gpu/third_party/sirit/README.md new file mode 100644 index 0000000..72109bb --- /dev/null +++ b/gpu/third_party/sirit/README.md @@ -0,0 +1,53 @@ +Sirit +===== +A runtime SPIR-V assembler. It aims to ease dynamic SPIR-V code generation +without calling external applications (like Khronos' `spirv-as`) + +Its design aims to move code that does not belong in the application to the +library, without limiting its functionality. + +What Sirit does for you: +* Sort declaration opcodes +* Handle types and constant duplicates +* Emit SPIR-V opcodes + +What Sirit won't do for you: +* Avoid ID duplicates (e.g. emitting the same label twice) +* Dump code to disk +* Handle control flow +* Compile from a higher level language + + +It's in early stages of development, many instructions are missing since +they are written manually instead of being generated from a file. + +Example +------- + +```cpp +class MyModule : public Sirit::Module { +public: + MyModule() {} + ~MyModule() = default; + + void Generate() { + AddCapability(spv::Capability::Shader); + SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450); + + auto main_type{TypeFunction(TypeVoid())}; + auto main_func{OpFunction(TypeVoid(), spv::FunctionControlMask::MaskNone, main_type)}; + AddLabel(OpLabel()); + OpReturn(); + OpFunctionEnd(); + + AddEntryPoint(spv::ExecutionModel::Vertex, main_func, "main"); + } +}; + +// Then... + +MyModule module; +module.Generate(); + +std::vector code{module.Assemble()}; +``` diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/.gitattributes b/gpu/third_party/sirit/externals/SPIRV-Headers/.gitattributes new file mode 100644 index 0000000..3fa5aaf --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/.gitattributes @@ -0,0 +1,7 @@ +*.json text +*.h text +*.hpp text +*.hpp11 text +*.lua text +*.py text +*.xml diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/.github/dependabot.yml b/gpu/third_party/sirit/externals/SPIRV-Headers/.github/dependabot.yml new file mode 100644 index 0000000..2390d8c --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + groups: + github-actions: + patterns: + - "*" diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/.github/workflows/presubmit.yml b/gpu/third_party/sirit/externals/SPIRV-Headers/.github/workflows/presubmit.yml new file mode 100644 index 0000000..d7958ca --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/.github/workflows/presubmit.yml @@ -0,0 +1,123 @@ +name: Presubmit +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + name: Build ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@v4 + - name: Install Ubuntu packages + if: matrix.os == 'ubuntu-latest' + run: sudo apt install -y dos2unix + - name: Install macOS packages + if: matrix.os == 'macos-latest' + run: brew install dos2unix + - name: Build + run: | + mkdir build + cd build + cmake -DCMAKE_INSTALL_PREFIX=install .. + cmake --build . --target install + - name: Build spec tools + run: | + cd tools/buildHeaders + mkdir build + cd build + cmake .. + cmake --build . --target install + - name: Build headers + run: | + cd tools/buildHeaders + ./bin/makeHeaders + - name: Check generated headers + run: git diff --exit-code + + test_cmake_min_required: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.14.0 + - name: CMake build + run: | + cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug -G "Ninja" -D CMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/build/install/ + cmake --build build --target install + + test_cmake_latest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: lukka/get-cmake@latest + - name: CMake build + run: | + cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug -G "Ninja" + cmake --install build/ --prefix build/install + + add_subdirectory: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.15.0 + - name: Build spirv-headers with testing enabled + run: | + cmake -S . -B build/ -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug -G "Ninja" + cmake --build build + + find_package: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.15.0 + - name: Install spirv-headers + run: | + cmake -S . -B build/ + cmake --install build/ --prefix build/install + - name: Check spirv-headers find_package support + run: | + cmake -S tests/find_package -B tests/find_package/build/ -D CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/build/install + cmake --build tests/find_package/build/ + + find_pkg_config: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.15.0 + - name: Install spirv-headers + run: | + cmake -S . -B build/ -D CMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/build/install/ + cmake --install build/ + - name: Check spirv-headers pkg_config support + run: | + cmake -S tests/pkg_config -B tests/pkg_config/build/ -D CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/build/install + cmake --build tests/pkg_config/build/ + + # https://github.com/KhronosGroup/SPIRV-Headers/issues/282 + find_pkg_config_absolute: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.15.0 + - name: Install spirv-headers with CMAKE_INSTALL_INCLUDEDIR being absolute + run: | + cmake -S . -B build/ -D CMAKE_INSTALL_INCLUDEDIR=${GITHUB_WORKSPACE}/build/install/include -D CMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/build/install/ + cmake --install build/ + - name: Check spirv-headers pkg_config support + run: | + cmake -S tests/pkg_config -B tests/pkg_config/build/ -D CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/build/install + cmake --build tests/pkg_config/build/ diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/.gitignore b/gpu/third_party/sirit/externals/SPIRV-Headers/.gitignore new file mode 100644 index 0000000..f33592c --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/.gitignore @@ -0,0 +1,3 @@ +build +out +.DS_Store diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/BUILD.bazel b/gpu/third_party/sirit/externals/SPIRV-Headers/BUILD.bazel new file mode 100644 index 0000000..25634d9 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/BUILD.bazel @@ -0,0 +1,177 @@ +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) + +exports_files(["LICENSE"]) + +filegroup( + name = "spirv_core_grammar_1.0", + srcs = ["include/spirv/1.0/spirv.core.grammar.json"], +) + +filegroup( + name = "spirv_glsl_grammar_1.0", + srcs = ["include/spirv/1.0/extinst.glsl.std.450.grammar.json"], +) + +filegroup( + name = "spirv_opencl_grammar_1.0", + srcs = ["include/spirv/1.0/extinst.opencl.std.100.grammar.json"], +) + +filegroup( + name = "spirv_core_grammar_1.1", + srcs = ["include/spirv/1.1/spirv.core.grammar.json"], +) + +filegroup( + name = "spirv_glsl_grammar_1.1", + srcs = ["include/spirv/1.1/extinst.glsl.std.450.grammar.json"], +) + +filegroup( + name = "spirv_opencl_grammar_1.1", + srcs = ["include/spirv/1.1/extinst.opencl.std.100.grammar.json"], +) + +filegroup( + name = "spirv_core_grammar_1.2", + srcs = ["include/spirv/1.2/spirv.core.grammar.json"], +) + +filegroup( + name = "spirv_glsl_grammar_1.2", + srcs = ["include/spirv/1.2/extinst.glsl.std.450.grammar.json"], +) + +filegroup( + name = "spirv_opencl_grammar_1.2", + srcs = ["include/spirv/1.2/extinst.opencl.std.100.grammar.json"], +) + +filegroup( + name = "spirv_core_grammar_unified1", + srcs = ["include/spirv/unified1/spirv.core.grammar.json"], +) + +filegroup( + name = "spirv_glsl_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.glsl.std.450.grammar.json"], +) + +filegroup( + name = "spirv_opencl_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.opencl.std.100.grammar.json"], +) + +filegroup( + name = "spirv_xml_registry", + srcs = ["include/spirv/spir-v.xml"], +) + +filegroup( + name = "spirv_ext_inst_debuginfo_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.debuginfo.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_nonsemantic_clspvreflection_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_nonsemantic_vkspreflection_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_nonsemantic_debugprintf_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_opencl_debuginfo_100_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_nonsemantic_shader_debuginfo_100_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_spv_amd_gcn_shader_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_spv_amd_shader_ballot_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_spv_amd_shader_explicit_vertex_parameter_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json"], +) + +filegroup( + name = "spirv_ext_inst_spv_amd_shader_trinary_minmax_grammar_unified1", + srcs = ["include/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json"], +) + +cc_library( + name = "spirv_common_headers", + hdrs = [ + "include/spirv/1.0/GLSL.std.450.h", + "include/spirv/1.0/OpenCL.std.h", + "include/spirv/1.1/GLSL.std.450.h", + "include/spirv/1.1/OpenCL.std.h", + "include/spirv/1.2/GLSL.std.450.h", + "include/spirv/1.2/OpenCL.std.h", + "include/spirv/unified1/GLSL.std.450.h", + "include/spirv/unified1/NonSemanticClspvReflection.h", + "include/spirv/unified1/NonSemanticDebugPrintf.h", + "include/spirv/unified1/NonSemanticVkspReflection.h", + "include/spirv/unified1/OpenCL.std.h", + ], + includes = ["include"], +) + +cc_library( + name = "spirv_c_headers", + hdrs = [ + "include/spirv/1.0/spirv.h", + "include/spirv/1.1/spirv.h", + "include/spirv/1.2/spirv.h", + "include/spirv/unified1/spirv.h", + ], + includes = ["include"], + deps = [":spirv_common_headers"], +) + +cc_library( + name = "spirv_cpp_headers", + hdrs = [ + "include/spirv/1.0/spirv.hpp", + "include/spirv/1.1/spirv.hpp", + "include/spirv/1.2/spirv.hpp", + "include/spirv/unified1/spirv.hpp", + ], + includes = ["include"], + deps = [":spirv_common_headers"], +) + +cc_library( + name = "spirv_cpp11_headers", + hdrs = [ + "include/spirv/1.0/spirv.hpp11", + "include/spirv/1.1/spirv.hpp11", + "include/spirv/1.2/spirv.hpp11", + "include/spirv/unified1/spirv.hpp11", + ], + includes = ["include"], + deps = [":spirv_common_headers"], +) + diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/BUILD.gn b/gpu/third_party/sirit/externals/SPIRV-Headers/BUILD.gn new file mode 100644 index 0000000..34294e0 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2020-2024 Google LLC +# +# 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. + +config("spv_headers_public_config") { + include_dirs = [ "include" ] +} + +source_set("spv_headers") { + sources = [ + "include/spirv/1.2/GLSL.std.450.h", + "include/spirv/1.2/OpenCL.std.h", + "include/spirv/1.2/spirv.h", + "include/spirv/1.2/spirv.hpp", + "include/spirv/unified1/GLSL.std.450.h", + "include/spirv/unified1/NonSemanticClspvReflection.h", + "include/spirv/unified1/NonSemanticDebugPrintf.h", + "include/spirv/unified1/NonSemanticVkspReflection.h", + "include/spirv/unified1/OpenCL.std.h", + "include/spirv/unified1/spirv.h", + "include/spirv/unified1/spirv.hpp", + ] + + public_configs = [ ":spv_headers_public_config" ] +} diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/CMakeLists.txt b/gpu/third_party/sirit/externals/SPIRV-Headers/CMakeLists.txt new file mode 100644 index 0000000..b018b23 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/CMakeLists.txt @@ -0,0 +1,67 @@ +# 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. +cmake_minimum_required(VERSION 3.14) +project(SPIRV-Headers LANGUAGES CXX VERSION 1.5.5) + +if (CMAKE_VERSION VERSION_LESS "3.21") + # https://cmake.org/cmake/help/latest/variable/PROJECT_IS_TOP_LEVEL.html + string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL) +endif() + +add_library(SPIRV-Headers INTERFACE) +add_library(SPIRV-Headers::SPIRV-Headers ALIAS SPIRV-Headers) +target_include_directories(SPIRV-Headers INTERFACE $) + +option(SPIRV_HEADERS_ENABLE_TESTS "Test SPIRV-Headers" ${PROJECT_IS_TOP_LEVEL}) +option(SPIRV_HEADERS_ENABLE_INSTALL "Install SPIRV-Headers" ${PROJECT_IS_TOP_LEVEL}) + +if(SPIRV_HEADERS_ENABLE_TESTS) + add_subdirectory(tests) +endif() + +if(SPIRV_HEADERS_ENABLE_INSTALL) + include(GNUInstallDirs) + include(CMakePackageConfigHelpers) + + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + set(cmake_install_dir "${CMAKE_INSTALL_DATADIR}/cmake/SPIRV-Headers") + set(version_config "${CMAKE_CURRENT_BINARY_DIR}/generated/SPIRV-HeadersConfigVersion.cmake") + + write_basic_package_version_file("${version_config}" COMPATIBILITY SameMajorVersion ARCH_INDEPENDENT) + install(FILES "${version_config}" DESTINATION "${cmake_install_dir}") + + install(TARGETS SPIRV-Headers EXPORT "SPIRV-HeadersConfig" INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + install(EXPORT "SPIRV-HeadersConfig" NAMESPACE "SPIRV-Headers::" DESTINATION "${cmake_install_dir}") + + if (IS_ABSOLUTE ${CMAKE_INSTALL_INCLUDEDIR}) + set(SPIRV_HEADERS_PKGCONFIG_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}) + else() + set(SPIRV_HEADERS_PKGCONFIG_INCLUDE_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) + endif() + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Headers.pc.in ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Headers.pc @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Headers.pc" DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig) +endif() diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/CODE_OF_CONDUCT.md b/gpu/third_party/sirit/externals/SPIRV-Headers/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a11610b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/CODE_OF_CONDUCT.md @@ -0,0 +1 @@ +A reminder that this issue tracker is managed by the Khronos Group. Interactions here should follow the Khronos Code of Conduct (https://www.khronos.org/developers/code-of-conduct), which prohibits aggressive or derogatory language. Please keep the discussion friendly and civil. diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/LICENSE b/gpu/third_party/sirit/externals/SPIRV-Headers/LICENSE new file mode 100644 index 0000000..a02ace1 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/LICENSE @@ -0,0 +1,103 @@ +Files: All files except for those called out below. +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. + +--- + +Files: include/spirv/spir-v.xml +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. + +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. + +--- + +Files: tools/buildHeaders/jsoncpp/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +The author (Baptiste Lepilleur) explicitly disclaims copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is +released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +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 Software. + +THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +======================================================================== + +--- diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/README.md b/gpu/third_party/sirit/externals/SPIRV-Headers/README.md new file mode 100644 index 0000000..ed38828 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/README.md @@ -0,0 +1,226 @@ +# SPIR-V Headers + +This repository contains machine-readable files for the +[SPIR-V Registry](https://www.khronos.org/registry/spir-v/). +This includes: + +* Header files for various languages. +* JSON files describing the grammar for the SPIR-V core instruction set + and the extended instruction sets. +* The XML registry file. +* A tool to build the headers from the JSON grammar. + +Headers are provided in the [include](include) directory, with up-to-date +headers in the `unified1` subdirectory. Older headers are provided according to +their version. + +In contrast, the XML registry file has a linear history, so it is +not tied to SPIR-V specification versions. + +## How is this repository updated? + +When a new version or revision of the SPIR-V specification is published, +the SPIR-V Working Group will push new commits onto master, updating +the files under [include](include). + +[The SPIR-V XML registry file](include/spirv/spir-v.xml) +is updated by Khronos whenever a new enum range is allocated. + +Pull requests can be made to +- request allocation of new enum ranges in the XML registry file +- register a new magic number for a SPIR-V generator +- reserve specific tokens in the JSON grammar + +### Registering a SPIR-V Generator Magic Number + +Tools that generate SPIR-V should use a magic number in the SPIR-V to help identify the +generator. + +Care should be taken to follow existing precedent in populating the details of reserved tokens. +This includes: +- keeping generator numbers in numeric order +- filling out all the existing fields + +### Reserving tokens in the JSON grammar + +Care should be taken to follow existing precedent in populating the details of reserved tokens. +This includes: +- pointing to what extension has more information, when possible +- keeping enumerants in numeric order +- when there are aliases, listing the preferred spelling first +- adding the statement `"version" : "None"` + +## How to install the headers + +``` +mkdir build +cd build +cmake .. +cmake --build . --target install +``` + +Then, for example, you will have `/usr/local/include/spirv/unified1/spirv.h` + +If you want to install them somewhere else, then use +`-DCMAKE_INSTALL_PREFIX=/other/path` on the first `cmake` command. + +## Using the headers without installing + +### Using CMake +A CMake-based project can use the headers without installing, as follows: + +1. Add an `add_subdirectory` directive to include this source tree. +2. Use `${SPIRV-Headers_SOURCE_DIR}/include}` in a `target_include_directories` + directive. +3. In your C or C++ source code use `#include` directives that explicitly mention + the `spirv` path component. +``` +#include "spirv/unified1/GLSL.std.450.h" +#include "spirv/unified1/OpenCL.std.h" +#include "spirv/unified1/spirv.hpp" +``` + +See also the [example](example/) subdirectory. But since that example is +*inside* this repostory, it doesn't use and `add_subdirectory` directive. + +### Using Bazel +A Bazel-based project can use the headers without installing, as follows: + +1. Add SPIRV-Headers as a submodule of your project, and add a +`local_repository` to your `WORKSPACE` file. For example, if you place +SPIRV-Headers under `external/spirv-headers`, then add the following to your +`WORKSPACE` file: + +``` +local_repository( + name = "spirv_headers", + path = "external/spirv-headers", +) +``` + +2. Add one of the following to the `deps` attribute of your build target based +on your needs: +``` +@spirv_headers//:spirv_c_headers +@spirv_headers//:spirv_cpp_headers +@spirv_headers//:spirv_cpp11_headers +``` + +For example: + +``` +cc_library( + name = "project", + srcs = [ + # Path to project sources + ], + hdrs = [ + # Path to project headers + ], + deps = [ + "@spirv_tools//:spirv_c_headers", + # Other dependencies, + ], +) +``` + +3. In your C or C++ source code use `#include` directives that explicitly mention + the `spirv` path component. +``` +#include "spirv/unified1/GLSL.std.450.h" +#include "spirv/unified1/OpenCL.std.h" +#include "spirv/unified1/spirv.hpp" +``` + +## Generating headers from the JSON grammar for the SPIR-V core instruction set + +This will generally be done by Khronos, for a change to the JSON grammar. +However, the project for the tool to do this is included in this repository, +and can be used to test a PR, or even to include the results in the PR. +This is not required though. + +The header-generation project is under the `tools/buildHeaders` directory. +Use CMake to build and install the project, in a `build` subdirectory (under `tools/buildHeaders`). +There is then a bash script at `bin/makeHeaders` that shows how to use the built +header-generator binary to generate the headers from the JSON grammar. +(Execute `bin/makeHeaders` from the `tools/buildHeaders` directory.) +Here's a complete example: + +``` +cd tools/buildHeaders +mkdir build +cd build +cmake .. +cmake --build . --target install +cd .. +./bin/makeHeaders +``` + +Notes: +- this generator is used in a broader context within Khronos to generate the specification, + and that influences the languages used, for legacy reasons +- the C++ structures built may similarly include more than strictly necessary, for the same reason + +## Generating C headers for extended instruction sets + +The [GLSL.std.450.h](include/spirv/unified1/GLSL.std.450.h) +and [OpenCL.std.h](include/spirv/unified1/OpenCL.std.h) extended instruction set headers +are maintained manually. + +The C/C++ header for each of the other extended instruction sets +is generated from the corresponding JSON grammar file. For example, the +[OpenCLDebugInfo100.h](include/spirv/unified1/OpenCLDebugInfo100.h) header +is generated from the +[extinst.opencl.debuginfo.100.grammar.json](include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json) +grammar file. + +To generate these C/C++ headers, first make sure `python3` is in your PATH, then +invoke the build script as follows: +``` +cd tools/buildHeaders +python3 bin/makeExtinstHeaders.py +``` + +## FAQ + +* *How are different versions published?* + + The multiple versions of the headers have been simplified into a + single `unified1` view. The JSON grammar has a "version" field saying + what version things first showed up in. + +* *How do you handle the evolution of extended instruction sets?* + + Extended instruction sets evolve asynchronously from the core spec. + Right now there is only a single version of both the GLSL and OpenCL + headers. So we don't yet have a problematic example to resolve. + +## License + +``` +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. +``` diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/SECURITY.md b/gpu/third_party/sirit/externals/SPIRV-Headers/SECURITY.md new file mode 100644 index 0000000..9b51f0c --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Supported Versions + +Security updates are applied only to the latest release. + +## Reporting a Vulnerability + +If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. + +Please disclose it at [security advisory](https://github.com/KhronosGroup/SPIRV-Headers/security/advisories/new). + +This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure. diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/WORKSPACE b/gpu/third_party/sirit/externals/SPIRV-Headers/WORKSPACE new file mode 100644 index 0000000..e69de29 diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/cmake/SPIRV-Headers.pc.in b/gpu/third_party/sirit/externals/SPIRV-Headers/cmake/SPIRV-Headers.pc.in new file mode 100644 index 0000000..843b0a7 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/cmake/SPIRV-Headers.pc.in @@ -0,0 +1,8 @@ +includedir=@SPIRV_HEADERS_PKGCONFIG_INCLUDE_DIR@ + +Name: SPIRV-Headers +Description: Header files from the SPIR-V registry +Version: @CMAKE_PROJECT_VERSION@ +Requires: +Libs: +Cflags: -I${includedir} diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/GLSL.std.450.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/GLSL.std.450.h new file mode 100644 index 0000000..54cc00e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/OpenCL.std.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/OpenCL.std.h new file mode 100644 index 0000000..19a6688 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/extinst.glsl.std.450.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/extinst.glsl.std.450.grammar.json new file mode 100644 index 0000000..3d9f39e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/extinst.opencl.std.100.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/extinst.opencl.std.100.grammar.json new file mode 100644 index 0000000..4fe4506 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.core.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.core.grammar.json new file mode 100644 index 0000000..f3cfc4c --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.cs b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.cs new file mode 100644 index 0000000..de325cc --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.h new file mode 100644 index 0000000..bd5a9b9 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.hpp b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.hpp new file mode 100644 index 0000000..e98a89c --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.hpp11 b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.hpp11 new file mode 100644 index 0000000..8896e81 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.json new file mode 100644 index 0000000..9b0a8f3 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.lua b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.lua new file mode 100644 index 0000000..2bd33ba --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.py b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.0/spirv.py new file mode 100644 index 0000000..8a200e7 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/GLSL.std.450.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/GLSL.std.450.h new file mode 100644 index 0000000..54cc00e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/OpenCL.std.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/OpenCL.std.h new file mode 100644 index 0000000..19a6688 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/extinst.glsl.std.450.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/extinst.glsl.std.450.grammar.json new file mode 100644 index 0000000..3d9f39e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/extinst.opencl.std.100.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/extinst.opencl.std.100.grammar.json new file mode 100644 index 0000000..4fe4506 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.core.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.core.grammar.json new file mode 100644 index 0000000..c142e60 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.cs b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.cs new file mode 100644 index 0000000..99194e5 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.h new file mode 100644 index 0000000..971c3be --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.hpp b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.hpp new file mode 100644 index 0000000..c26ac1f --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.hpp11 b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.hpp11 new file mode 100644 index 0000000..992d43b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.json new file mode 100644 index 0000000..4c18e01 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.lua b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.lua new file mode 100644 index 0000000..ad34e0a --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.py b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.1/spirv.py new file mode 100644 index 0000000..519a597 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/GLSL.std.450.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/GLSL.std.450.h new file mode 100644 index 0000000..54cc00e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/OpenCL.std.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/OpenCL.std.h new file mode 100644 index 0000000..19a6688 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/extinst.glsl.std.450.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/extinst.glsl.std.450.grammar.json new file mode 100644 index 0000000..3d9f39e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/extinst.opencl.std.100.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/extinst.opencl.std.100.grammar.json new file mode 100644 index 0000000..4fe4506 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.core.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.core.grammar.json new file mode 100644 index 0000000..393ee3c --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.cs b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.cs new file mode 100644 index 0000000..493303d --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.h new file mode 100644 index 0000000..7c6d884 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.hpp b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.hpp new file mode 100644 index 0000000..57bd97a --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.hpp11 b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.hpp11 new file mode 100644 index 0000000..7a875fd --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.json new file mode 100644 index 0000000..9c0ff0a --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.lua b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.lua new file mode 100644 index 0000000..0de507d --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.py b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/1.2/spirv.py new file mode 100644 index 0000000..cefee4d --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/spir-v.xml b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/spir-v.xml new file mode 100644 index 0000000..f9b23ac --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/spir-v.xml @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_gcn_shader.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_gcn_shader.h new file mode 100644 index 0000000..e626a7a --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_shader_ballot.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_shader_ballot.h new file mode 100644 index 0000000..563c0b6 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h new file mode 100644 index 0000000..e663330 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_shader_trinary_minmax.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/AMD_shader_trinary_minmax.h new file mode 100644 index 0000000..dd51c5f --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/DebugInfo.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/DebugInfo.h new file mode 100644 index 0000000..a3c0af4 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h new file mode 100644 index 0000000..0594f90 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticClspvReflection.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticClspvReflection.h new file mode 100644 index 0000000..b6c27fa --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugBreak.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugBreak.h new file mode 100644 index 0000000..8604fe7 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugPrintf.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugPrintf.h new file mode 100644 index 0000000..bc24683 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h new file mode 100644 index 0000000..b276b56 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticVkspReflection.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/NonSemanticVkspReflection.h new file mode 100644 index 0000000..331a3d9 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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 = 2, + 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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/OpenCL.std.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/OpenCL.std.h new file mode 100644 index 0000000..ed74f20 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/OpenCLDebugInfo100.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/OpenCLDebugInfo100.h new file mode 100644 index 0000000..ffbd16f --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.debuginfo.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.debuginfo.grammar.json new file mode 100644 index 0000000..918a9e5 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json new file mode 100644 index 0000000..ac8fc6d --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json new file mode 100644 index 0000000..cfccc80 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json new file mode 100644 index 0000000..ae28883 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.debugbreak.grammar.json @@ -0,0 +1,9 @@ +{ + "revision" : 1, + "instructions" : [ + { + "opname" : "DebugBreak", + "opcode" : 1 + } + ] +} diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json new file mode 100644 index 0000000..71fa711 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json new file mode 100644 index 0000000..1eb2859 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json new file mode 100644 index 0000000..379457b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json @@ -0,0 +1,136 @@ +{ + "revision" : 2, + "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" }, + {"kind" : "LiteralInteger", "name" : "dispatchId" } + ] + }, + { + "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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json new file mode 100644 index 0000000..53b001c --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json new file mode 100644 index 0000000..21b7876 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-gcn-shader.grammar.json new file mode 100644 index 0000000..e18251b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-shader-ballot.grammar.json new file mode 100644 index 0000000..62a470e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json new file mode 100644 index 0000000..e156b1b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/extinst.spv-amd-shader-trinary-minmax.grammar.json new file mode 100644 index 0000000..c681976 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.bf b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.bf new file mode 100644 index 0000000..d14f43f --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.bf @@ -0,0 +1,2172 @@ +// 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, + CooperativeMatrixLayoutsARM = 4201, + 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, + RawAccessChainsNV = 5414, + 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, + ReplicatedCompositesEXT = 6024, + 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, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, + } + + [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 RawAccessChainOperandsShift + { + RobustnessPerComponentNV = 0, + RobustnessPerElementNV = 1, + } + + [AllowDuplicates, CRepr] public enum RawAccessChainOperandsMask + { + MaskNone = 0, + RobustnessPerComponentNV = 0x00000001, + RobustnessPerElementNV = 0x00000002, + } + + [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, + OpExtInstWithForwardRefsKHR = 4433, + 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, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + 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, + OpRawAccessChainNV = 5398, + 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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json new file mode 100644 index 0000000..980b5dc --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json @@ -0,0 +1,16971 @@ +{ + "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" : "OpExtInstWithForwardRefsKHR", + "class" : "Extension", + "opcode" : 4433, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ], + "extensions" : [ "SPV_KHR_relaxed_extended_instruction" ], + "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" : "OpConstantCompositeReplicateEXT", + "class" : "Constant-Creation", + "opcode" : 4461, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "ReplicatedCompositesEXT" ], + "version" : "None" + }, + { + "opname" : "OpSpecConstantCompositeReplicateEXT", + "class" : "Constant-Creation", + "opcode" : 4462, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "ReplicatedCompositesEXT" ], + "version" : "None" + }, + { + "opname" : "OpCompositeConstructReplicateEXT", + "class" : "Composite", + "opcode" : 4463, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "ReplicatedCompositesEXT" ], + "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" : "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" : "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" : "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" : "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" : "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" : "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" : "OpRawAccessChainNV", + "class" : "Memory", + "opcode" : 5398, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Byte stride'" }, + { "kind" : "IdRef", "name" : "'Element index'" }, + { "kind" : "IdRef", "name" : "'Byte offset'" }, + { "kind" : "RawAccessChainOperands", "quantifier" : "?" } + ], + "capabilities" : [ + "RawAccessChainsNV" + ], + "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" : "BitEnum", + "kind" : "RawAccessChainOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "RobustnessPerComponentNV", + "value" : "0x0001", + "capabilities" : [ "RawAccessChainsNV" ], + "version" : "None" + }, + { + "enumerant" : "RobustnessPerElementNV", + "value" : "0x0002", + "capabilities" : [ "RawAccessChainsNV" ], + "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" : "RayGenerationKHR", + "value" : 5313, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "RayGenerationNV", + "value" : 5313, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IntersectionKHR", + "value" : 5314, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "IntersectionNV", + "value" : 5314, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "AnyHitKHR", + "value" : 5315, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "AnyHitNV", + "value" : 5315, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ClosestHitKHR", + "value" : 5316, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "ClosestHitNV", + "value" : 5316, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "MissKHR", + "value" : 5317, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "MissNV", + "value" : 5317, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableKHR", + "value" : 5318, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableNV", + "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" : "OutputLinesEXT", + "value" : 5269, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputLinesNV", + "value" : 5269, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "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" : "OutputPrimitivesNV", + "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" : "OutputTrianglesEXT", + "value" : 5298, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "OutputTrianglesNV", + "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" : "CallableDataKHR", + "value" : 5328, + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "version" : "None" + }, + { + "enumerant" : "CallableDataNV", + "value" : 5328, + "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" : "IncomingCallableDataNV", + "value" : 5329, + "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" : "RayPayloadNV", + "value" : 5338, + "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" : "HitAttributeNV", + "value" : 5339, + "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" : "IncomingRayPayloadNV", + "value" : 5342, + "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" : "ShaderRecordBufferNV", + "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" : "PerPrimitiveEXT", + "value" : 5271, + "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], + "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], + "version" : "None" + }, + { + "enumerant" : "PerPrimitiveNV", + "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" : "LaunchIdKHR", + "value" : 5319, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "LaunchIdNV", + "value" : 5319, + "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" : "LaunchSizeNV", + "value" : 5320, + "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" : "WorldRayOriginNV", + "value" : 5321, + "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" : "WorldRayDirectionNV", + "value" : 5322, + "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" : "ObjectRayOriginNV", + "value" : 5323, + "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" : "ObjectRayDirectionNV", + "value" : 5324, + "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" : "RayTminNV", + "value" : 5325, + "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" : "RayTmaxNV", + "value" : 5326, + "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" : "InstanceCustomIndexNV", + "value" : 5327, + "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" : "ObjectToWorldNV", + "value" : 5330, + "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" : "WorldToObjectNV", + "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" : "HitKindKHR", + "value" : 5333, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "HitKindNV", + "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" : "IncomingRayFlagsKHR", + "value" : 5351, + "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], + "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], + "version" : "None" + }, + { + "enumerant" : "IncomingRayFlagsNV", + "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" : "CooperativeMatrixLayoutsARM", + "value" : 4201, + "extensions" : [ "SPV_ARM_cooperative_matrix_layouts" ], + "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" : "RawAccessChainsNV", + "value" : 5414, + "extensions" : [ "SPV_NV_raw_access_chains" ], + "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" : "ReplicatedCompositesEXT", + "value" : 6024, + "extensions" : [ "SPV_EXT_replicated_composites" ], + "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" + }, + { + "enumerant" : "RowBlockedInterleavedARM", + "value" : 4202, + "version" : "None" + }, + { + "enumerant" : "ColumnBlockedInterleavedARM", + "value" : 4203, + "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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.cs b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.cs new file mode 100644 index 0000000..aaba96f --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.cs @@ -0,0 +1,2171 @@ +// 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, + CooperativeMatrixLayoutsARM = 4201, + 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, + RawAccessChainsNV = 5414, + 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, + ReplicatedCompositesEXT = 6024, + 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, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, + } + + 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 RawAccessChainOperandsShift + { + RobustnessPerComponentNV = 0, + RobustnessPerElementNV = 1, + } + + public enum RawAccessChainOperandsMask + { + MaskNone = 0, + RobustnessPerComponentNV = 0x00000001, + RobustnessPerElementNV = 0x00000002, + } + + 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, + OpExtInstWithForwardRefsKHR = 4433, + 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, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + 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, + OpRawAccessChainNV = 5398, + 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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.h b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.h new file mode 100644 index 0000000..42790e0 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.h @@ -0,0 +1,4687 @@ +/* +** 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, + SpvCapabilityCooperativeMatrixLayoutsARM = 4201, + 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, + SpvCapabilityRawAccessChainsNV = 5414, + 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, + SpvCapabilityReplicatedCompositesEXT = 6024, + 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, + SpvCooperativeMatrixLayoutRowBlockedInterleavedARM = 4202, + SpvCooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203, + 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 SpvRawAccessChainOperandsShift_ { + SpvRawAccessChainOperandsRobustnessPerComponentNVShift = 0, + SpvRawAccessChainOperandsRobustnessPerElementNVShift = 1, + SpvRawAccessChainOperandsMax = 0x7fffffff, +} SpvRawAccessChainOperandsShift; + +typedef enum SpvRawAccessChainOperandsMask_ { + SpvRawAccessChainOperandsMaskNone = 0, + SpvRawAccessChainOperandsRobustnessPerComponentNVMask = 0x00000001, + SpvRawAccessChainOperandsRobustnessPerElementNVMask = 0x00000002, +} SpvRawAccessChainOperandsMask; + +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, + SpvOpExtInstWithForwardRefsKHR = 4433, + 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, + SpvOpConstantCompositeReplicateEXT = 4461, + SpvOpSpecConstantCompositeReplicateEXT = 4462, + SpvOpCompositeConstructReplicateEXT = 4463, + 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, + SpvOpRawAccessChainNV = 5398, + 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 SpvOpExtInstWithForwardRefsKHR: *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 SpvOpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeConstructReplicateEXT: *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 SpvOpReportIntersectionKHR: *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 SpvOpTypeAccelerationStructureKHR: *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 SpvOpRawAccessChainNV: *hasResult = true; *hasResultType = true; 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; + } +} +inline const char* SpvSourceLanguageToString(SpvSourceLanguage value) { + switch (value) { + case SpvSourceLanguageUnknown: return "Unknown"; + case SpvSourceLanguageESSL: return "ESSL"; + case SpvSourceLanguageGLSL: return "GLSL"; + case SpvSourceLanguageOpenCL_C: return "OpenCL_C"; + case SpvSourceLanguageOpenCL_CPP: return "OpenCL_CPP"; + case SpvSourceLanguageHLSL: return "HLSL"; + case SpvSourceLanguageCPP_for_OpenCL: return "CPP_for_OpenCL"; + case SpvSourceLanguageSYCL: return "SYCL"; + case SpvSourceLanguageHERO_C: return "HERO_C"; + case SpvSourceLanguageNZSL: return "NZSL"; + case SpvSourceLanguageWGSL: return "WGSL"; + case SpvSourceLanguageSlang: return "Slang"; + case SpvSourceLanguageZig: return "Zig"; + default: return "Unknown"; + } +} + +inline const char* SpvExecutionModelToString(SpvExecutionModel value) { + switch (value) { + case SpvExecutionModelVertex: return "Vertex"; + case SpvExecutionModelTessellationControl: return "TessellationControl"; + case SpvExecutionModelTessellationEvaluation: return "TessellationEvaluation"; + case SpvExecutionModelGeometry: return "Geometry"; + case SpvExecutionModelFragment: return "Fragment"; + case SpvExecutionModelGLCompute: return "GLCompute"; + case SpvExecutionModelKernel: return "Kernel"; + case SpvExecutionModelTaskNV: return "TaskNV"; + case SpvExecutionModelMeshNV: return "MeshNV"; + case SpvExecutionModelRayGenerationKHR: return "RayGenerationKHR"; + case SpvExecutionModelIntersectionKHR: return "IntersectionKHR"; + case SpvExecutionModelAnyHitKHR: return "AnyHitKHR"; + case SpvExecutionModelClosestHitKHR: return "ClosestHitKHR"; + case SpvExecutionModelMissKHR: return "MissKHR"; + case SpvExecutionModelCallableKHR: return "CallableKHR"; + case SpvExecutionModelTaskEXT: return "TaskEXT"; + case SpvExecutionModelMeshEXT: return "MeshEXT"; + default: return "Unknown"; + } +} + +inline const char* SpvAddressingModelToString(SpvAddressingModel value) { + switch (value) { + case SpvAddressingModelLogical: return "Logical"; + case SpvAddressingModelPhysical32: return "Physical32"; + case SpvAddressingModelPhysical64: return "Physical64"; + case SpvAddressingModelPhysicalStorageBuffer64: return "PhysicalStorageBuffer64"; + default: return "Unknown"; + } +} + +inline const char* SpvMemoryModelToString(SpvMemoryModel value) { + switch (value) { + case SpvMemoryModelSimple: return "Simple"; + case SpvMemoryModelGLSL450: return "GLSL450"; + case SpvMemoryModelOpenCL: return "OpenCL"; + case SpvMemoryModelVulkan: return "Vulkan"; + default: return "Unknown"; + } +} + +inline const char* SpvExecutionModeToString(SpvExecutionMode value) { + switch (value) { + case SpvExecutionModeInvocations: return "Invocations"; + case SpvExecutionModeSpacingEqual: return "SpacingEqual"; + case SpvExecutionModeSpacingFractionalEven: return "SpacingFractionalEven"; + case SpvExecutionModeSpacingFractionalOdd: return "SpacingFractionalOdd"; + case SpvExecutionModeVertexOrderCw: return "VertexOrderCw"; + case SpvExecutionModeVertexOrderCcw: return "VertexOrderCcw"; + case SpvExecutionModePixelCenterInteger: return "PixelCenterInteger"; + case SpvExecutionModeOriginUpperLeft: return "OriginUpperLeft"; + case SpvExecutionModeOriginLowerLeft: return "OriginLowerLeft"; + case SpvExecutionModeEarlyFragmentTests: return "EarlyFragmentTests"; + case SpvExecutionModePointMode: return "PointMode"; + case SpvExecutionModeXfb: return "Xfb"; + case SpvExecutionModeDepthReplacing: return "DepthReplacing"; + case SpvExecutionModeDepthGreater: return "DepthGreater"; + case SpvExecutionModeDepthLess: return "DepthLess"; + case SpvExecutionModeDepthUnchanged: return "DepthUnchanged"; + case SpvExecutionModeLocalSize: return "LocalSize"; + case SpvExecutionModeLocalSizeHint: return "LocalSizeHint"; + case SpvExecutionModeInputPoints: return "InputPoints"; + case SpvExecutionModeInputLines: return "InputLines"; + case SpvExecutionModeInputLinesAdjacency: return "InputLinesAdjacency"; + case SpvExecutionModeTriangles: return "Triangles"; + case SpvExecutionModeInputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case SpvExecutionModeQuads: return "Quads"; + case SpvExecutionModeIsolines: return "Isolines"; + case SpvExecutionModeOutputVertices: return "OutputVertices"; + case SpvExecutionModeOutputPoints: return "OutputPoints"; + case SpvExecutionModeOutputLineStrip: return "OutputLineStrip"; + case SpvExecutionModeOutputTriangleStrip: return "OutputTriangleStrip"; + case SpvExecutionModeVecTypeHint: return "VecTypeHint"; + case SpvExecutionModeContractionOff: return "ContractionOff"; + case SpvExecutionModeInitializer: return "Initializer"; + case SpvExecutionModeFinalizer: return "Finalizer"; + case SpvExecutionModeSubgroupSize: return "SubgroupSize"; + case SpvExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case SpvExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case SpvExecutionModeLocalSizeId: return "LocalSizeId"; + case SpvExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + case SpvExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT"; + case SpvExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT"; + case SpvExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT"; + case SpvExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlowKHR"; + case SpvExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case SpvExecutionModeDenormPreserve: return "DenormPreserve"; + case SpvExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case SpvExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case SpvExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case SpvExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case SpvExecutionModeEarlyAndLateFragmentTestsAMD: return "EarlyAndLateFragmentTestsAMD"; + case SpvExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case SpvExecutionModeCoalescingAMDX: return "CoalescingAMDX"; + case SpvExecutionModeMaxNodeRecursionAMDX: return "MaxNodeRecursionAMDX"; + case SpvExecutionModeStaticNumWorkgroupsAMDX: return "StaticNumWorkgroupsAMDX"; + case SpvExecutionModeShaderIndexAMDX: return "ShaderIndexAMDX"; + case SpvExecutionModeMaxNumWorkgroupsAMDX: return "MaxNumWorkgroupsAMDX"; + case SpvExecutionModeStencilRefUnchangedFrontAMD: return "StencilRefUnchangedFrontAMD"; + case SpvExecutionModeStencilRefGreaterFrontAMD: return "StencilRefGreaterFrontAMD"; + case SpvExecutionModeStencilRefLessFrontAMD: return "StencilRefLessFrontAMD"; + case SpvExecutionModeStencilRefUnchangedBackAMD: return "StencilRefUnchangedBackAMD"; + case SpvExecutionModeStencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD"; + case SpvExecutionModeStencilRefLessBackAMD: return "StencilRefLessBackAMD"; + case SpvExecutionModeQuadDerivativesKHR: return "QuadDerivativesKHR"; + case SpvExecutionModeRequireFullQuadsKHR: return "RequireFullQuadsKHR"; + case SpvExecutionModeOutputLinesEXT: return "OutputLinesEXT"; + case SpvExecutionModeOutputPrimitivesEXT: return "OutputPrimitivesEXT"; + case SpvExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; + case SpvExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; + case SpvExecutionModeOutputTrianglesEXT: return "OutputTrianglesEXT"; + case SpvExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case SpvExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case SpvExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case SpvExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case SpvExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case SpvExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case SpvExecutionModeSharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL"; + case SpvExecutionModeRoundingModeRTPINTEL: return "RoundingModeRTPINTEL"; + case SpvExecutionModeRoundingModeRTNINTEL: return "RoundingModeRTNINTEL"; + case SpvExecutionModeFloatingPointModeALTINTEL: return "FloatingPointModeALTINTEL"; + case SpvExecutionModeFloatingPointModeIEEEINTEL: return "FloatingPointModeIEEEINTEL"; + case SpvExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case SpvExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case SpvExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case SpvExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case SpvExecutionModeSchedulerTargetFmaxMhzINTEL: return "SchedulerTargetFmaxMhzINTEL"; + case SpvExecutionModeMaximallyReconvergesKHR: return "MaximallyReconvergesKHR"; + case SpvExecutionModeFPFastMathDefault: return "FPFastMathDefault"; + case SpvExecutionModeStreamingInterfaceINTEL: return "StreamingInterfaceINTEL"; + case SpvExecutionModeRegisterMapInterfaceINTEL: return "RegisterMapInterfaceINTEL"; + case SpvExecutionModeNamedBarrierCountINTEL: return "NamedBarrierCountINTEL"; + case SpvExecutionModeMaximumRegistersINTEL: return "MaximumRegistersINTEL"; + case SpvExecutionModeMaximumRegistersIdINTEL: return "MaximumRegistersIdINTEL"; + case SpvExecutionModeNamedMaximumRegistersINTEL: return "NamedMaximumRegistersINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvStorageClassToString(SpvStorageClass value) { + switch (value) { + case SpvStorageClassUniformConstant: return "UniformConstant"; + case SpvStorageClassInput: return "Input"; + case SpvStorageClassUniform: return "Uniform"; + case SpvStorageClassOutput: return "Output"; + case SpvStorageClassWorkgroup: return "Workgroup"; + case SpvStorageClassCrossWorkgroup: return "CrossWorkgroup"; + case SpvStorageClassPrivate: return "Private"; + case SpvStorageClassFunction: return "Function"; + case SpvStorageClassGeneric: return "Generic"; + case SpvStorageClassPushConstant: return "PushConstant"; + case SpvStorageClassAtomicCounter: return "AtomicCounter"; + case SpvStorageClassImage: return "Image"; + case SpvStorageClassStorageBuffer: return "StorageBuffer"; + case SpvStorageClassTileImageEXT: return "TileImageEXT"; + case SpvStorageClassNodePayloadAMDX: return "NodePayloadAMDX"; + case SpvStorageClassNodeOutputPayloadAMDX: return "NodeOutputPayloadAMDX"; + case SpvStorageClassCallableDataKHR: return "CallableDataKHR"; + case SpvStorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; + case SpvStorageClassRayPayloadKHR: return "RayPayloadKHR"; + case SpvStorageClassHitAttributeKHR: return "HitAttributeKHR"; + case SpvStorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case SpvStorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case SpvStorageClassPhysicalStorageBuffer: return "PhysicalStorageBuffer"; + case SpvStorageClassHitObjectAttributeNV: return "HitObjectAttributeNV"; + case SpvStorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT"; + case SpvStorageClassCodeSectionINTEL: return "CodeSectionINTEL"; + case SpvStorageClassDeviceOnlyINTEL: return "DeviceOnlyINTEL"; + case SpvStorageClassHostOnlyINTEL: return "HostOnlyINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvDimToString(SpvDim value) { + switch (value) { + case SpvDim1D: return "1D"; + case SpvDim2D: return "2D"; + case SpvDim3D: return "3D"; + case SpvDimCube: return "Cube"; + case SpvDimRect: return "Rect"; + case SpvDimBuffer: return "Buffer"; + case SpvDimSubpassData: return "SubpassData"; + case SpvDimTileImageDataEXT: return "TileImageDataEXT"; + default: return "Unknown"; + } +} + +inline const char* SpvSamplerAddressingModeToString(SpvSamplerAddressingMode value) { + switch (value) { + case SpvSamplerAddressingModeNone: return "None"; + case SpvSamplerAddressingModeClampToEdge: return "ClampToEdge"; + case SpvSamplerAddressingModeClamp: return "Clamp"; + case SpvSamplerAddressingModeRepeat: return "Repeat"; + case SpvSamplerAddressingModeRepeatMirrored: return "RepeatMirrored"; + default: return "Unknown"; + } +} + +inline const char* SpvSamplerFilterModeToString(SpvSamplerFilterMode value) { + switch (value) { + case SpvSamplerFilterModeNearest: return "Nearest"; + case SpvSamplerFilterModeLinear: return "Linear"; + default: return "Unknown"; + } +} + +inline const char* SpvImageFormatToString(SpvImageFormat value) { + switch (value) { + case SpvImageFormatUnknown: return "Unknown"; + case SpvImageFormatRgba32f: return "Rgba32f"; + case SpvImageFormatRgba16f: return "Rgba16f"; + case SpvImageFormatR32f: return "R32f"; + case SpvImageFormatRgba8: return "Rgba8"; + case SpvImageFormatRgba8Snorm: return "Rgba8Snorm"; + case SpvImageFormatRg32f: return "Rg32f"; + case SpvImageFormatRg16f: return "Rg16f"; + case SpvImageFormatR11fG11fB10f: return "R11fG11fB10f"; + case SpvImageFormatR16f: return "R16f"; + case SpvImageFormatRgba16: return "Rgba16"; + case SpvImageFormatRgb10A2: return "Rgb10A2"; + case SpvImageFormatRg16: return "Rg16"; + case SpvImageFormatRg8: return "Rg8"; + case SpvImageFormatR16: return "R16"; + case SpvImageFormatR8: return "R8"; + case SpvImageFormatRgba16Snorm: return "Rgba16Snorm"; + case SpvImageFormatRg16Snorm: return "Rg16Snorm"; + case SpvImageFormatRg8Snorm: return "Rg8Snorm"; + case SpvImageFormatR16Snorm: return "R16Snorm"; + case SpvImageFormatR8Snorm: return "R8Snorm"; + case SpvImageFormatRgba32i: return "Rgba32i"; + case SpvImageFormatRgba16i: return "Rgba16i"; + case SpvImageFormatRgba8i: return "Rgba8i"; + case SpvImageFormatR32i: return "R32i"; + case SpvImageFormatRg32i: return "Rg32i"; + case SpvImageFormatRg16i: return "Rg16i"; + case SpvImageFormatRg8i: return "Rg8i"; + case SpvImageFormatR16i: return "R16i"; + case SpvImageFormatR8i: return "R8i"; + case SpvImageFormatRgba32ui: return "Rgba32ui"; + case SpvImageFormatRgba16ui: return "Rgba16ui"; + case SpvImageFormatRgba8ui: return "Rgba8ui"; + case SpvImageFormatR32ui: return "R32ui"; + case SpvImageFormatRgb10a2ui: return "Rgb10a2ui"; + case SpvImageFormatRg32ui: return "Rg32ui"; + case SpvImageFormatRg16ui: return "Rg16ui"; + case SpvImageFormatRg8ui: return "Rg8ui"; + case SpvImageFormatR16ui: return "R16ui"; + case SpvImageFormatR8ui: return "R8ui"; + case SpvImageFormatR64ui: return "R64ui"; + case SpvImageFormatR64i: return "R64i"; + default: return "Unknown"; + } +} + +inline const char* SpvImageChannelOrderToString(SpvImageChannelOrder value) { + switch (value) { + case SpvImageChannelOrderR: return "R"; + case SpvImageChannelOrderA: return "A"; + case SpvImageChannelOrderRG: return "RG"; + case SpvImageChannelOrderRA: return "RA"; + case SpvImageChannelOrderRGB: return "RGB"; + case SpvImageChannelOrderRGBA: return "RGBA"; + case SpvImageChannelOrderBGRA: return "BGRA"; + case SpvImageChannelOrderARGB: return "ARGB"; + case SpvImageChannelOrderIntensity: return "Intensity"; + case SpvImageChannelOrderLuminance: return "Luminance"; + case SpvImageChannelOrderRx: return "Rx"; + case SpvImageChannelOrderRGx: return "RGx"; + case SpvImageChannelOrderRGBx: return "RGBx"; + case SpvImageChannelOrderDepth: return "Depth"; + case SpvImageChannelOrderDepthStencil: return "DepthStencil"; + case SpvImageChannelOrdersRGB: return "sRGB"; + case SpvImageChannelOrdersRGBx: return "sRGBx"; + case SpvImageChannelOrdersRGBA: return "sRGBA"; + case SpvImageChannelOrdersBGRA: return "sBGRA"; + case SpvImageChannelOrderABGR: return "ABGR"; + default: return "Unknown"; + } +} + +inline const char* SpvImageChannelDataTypeToString(SpvImageChannelDataType value) { + switch (value) { + case SpvImageChannelDataTypeSnormInt8: return "SnormInt8"; + case SpvImageChannelDataTypeSnormInt16: return "SnormInt16"; + case SpvImageChannelDataTypeUnormInt8: return "UnormInt8"; + case SpvImageChannelDataTypeUnormInt16: return "UnormInt16"; + case SpvImageChannelDataTypeUnormShort565: return "UnormShort565"; + case SpvImageChannelDataTypeUnormShort555: return "UnormShort555"; + case SpvImageChannelDataTypeUnormInt101010: return "UnormInt101010"; + case SpvImageChannelDataTypeSignedInt8: return "SignedInt8"; + case SpvImageChannelDataTypeSignedInt16: return "SignedInt16"; + case SpvImageChannelDataTypeSignedInt32: return "SignedInt32"; + case SpvImageChannelDataTypeUnsignedInt8: return "UnsignedInt8"; + case SpvImageChannelDataTypeUnsignedInt16: return "UnsignedInt16"; + case SpvImageChannelDataTypeUnsignedInt32: return "UnsignedInt32"; + case SpvImageChannelDataTypeHalfFloat: return "HalfFloat"; + case SpvImageChannelDataTypeFloat: return "Float"; + case SpvImageChannelDataTypeUnormInt24: return "UnormInt24"; + case SpvImageChannelDataTypeUnormInt101010_2: return "UnormInt101010_2"; + case SpvImageChannelDataTypeUnsignedIntRaw10EXT: return "UnsignedIntRaw10EXT"; + case SpvImageChannelDataTypeUnsignedIntRaw12EXT: return "UnsignedIntRaw12EXT"; + default: return "Unknown"; + } +} + +inline const char* SpvFPRoundingModeToString(SpvFPRoundingMode value) { + switch (value) { + case SpvFPRoundingModeRTE: return "RTE"; + case SpvFPRoundingModeRTZ: return "RTZ"; + case SpvFPRoundingModeRTP: return "RTP"; + case SpvFPRoundingModeRTN: return "RTN"; + default: return "Unknown"; + } +} + +inline const char* SpvLinkageTypeToString(SpvLinkageType value) { + switch (value) { + case SpvLinkageTypeExport: return "Export"; + case SpvLinkageTypeImport: return "Import"; + case SpvLinkageTypeLinkOnceODR: return "LinkOnceODR"; + default: return "Unknown"; + } +} + +inline const char* SpvAccessQualifierToString(SpvAccessQualifier value) { + switch (value) { + case SpvAccessQualifierReadOnly: return "ReadOnly"; + case SpvAccessQualifierWriteOnly: return "WriteOnly"; + case SpvAccessQualifierReadWrite: return "ReadWrite"; + default: return "Unknown"; + } +} + +inline const char* SpvFunctionParameterAttributeToString(SpvFunctionParameterAttribute value) { + switch (value) { + case SpvFunctionParameterAttributeZext: return "Zext"; + case SpvFunctionParameterAttributeSext: return "Sext"; + case SpvFunctionParameterAttributeByVal: return "ByVal"; + case SpvFunctionParameterAttributeSret: return "Sret"; + case SpvFunctionParameterAttributeNoAlias: return "NoAlias"; + case SpvFunctionParameterAttributeNoCapture: return "NoCapture"; + case SpvFunctionParameterAttributeNoWrite: return "NoWrite"; + case SpvFunctionParameterAttributeNoReadWrite: return "NoReadWrite"; + case SpvFunctionParameterAttributeRuntimeAlignedINTEL: return "RuntimeAlignedINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvDecorationToString(SpvDecoration value) { + switch (value) { + case SpvDecorationRelaxedPrecision: return "RelaxedPrecision"; + case SpvDecorationSpecId: return "SpecId"; + case SpvDecorationBlock: return "Block"; + case SpvDecorationBufferBlock: return "BufferBlock"; + case SpvDecorationRowMajor: return "RowMajor"; + case SpvDecorationColMajor: return "ColMajor"; + case SpvDecorationArrayStride: return "ArrayStride"; + case SpvDecorationMatrixStride: return "MatrixStride"; + case SpvDecorationGLSLShared: return "GLSLShared"; + case SpvDecorationGLSLPacked: return "GLSLPacked"; + case SpvDecorationCPacked: return "CPacked"; + case SpvDecorationBuiltIn: return "BuiltIn"; + case SpvDecorationNoPerspective: return "NoPerspective"; + case SpvDecorationFlat: return "Flat"; + case SpvDecorationPatch: return "Patch"; + case SpvDecorationCentroid: return "Centroid"; + case SpvDecorationSample: return "Sample"; + case SpvDecorationInvariant: return "Invariant"; + case SpvDecorationRestrict: return "Restrict"; + case SpvDecorationAliased: return "Aliased"; + case SpvDecorationVolatile: return "Volatile"; + case SpvDecorationConstant: return "Constant"; + case SpvDecorationCoherent: return "Coherent"; + case SpvDecorationNonWritable: return "NonWritable"; + case SpvDecorationNonReadable: return "NonReadable"; + case SpvDecorationUniform: return "Uniform"; + case SpvDecorationUniformId: return "UniformId"; + case SpvDecorationSaturatedConversion: return "SaturatedConversion"; + case SpvDecorationStream: return "Stream"; + case SpvDecorationLocation: return "Location"; + case SpvDecorationComponent: return "Component"; + case SpvDecorationIndex: return "Index"; + case SpvDecorationBinding: return "Binding"; + case SpvDecorationDescriptorSet: return "DescriptorSet"; + case SpvDecorationOffset: return "Offset"; + case SpvDecorationXfbBuffer: return "XfbBuffer"; + case SpvDecorationXfbStride: return "XfbStride"; + case SpvDecorationFuncParamAttr: return "FuncParamAttr"; + case SpvDecorationFPRoundingMode: return "FPRoundingMode"; + case SpvDecorationFPFastMathMode: return "FPFastMathMode"; + case SpvDecorationLinkageAttributes: return "LinkageAttributes"; + case SpvDecorationNoContraction: return "NoContraction"; + case SpvDecorationInputAttachmentIndex: return "InputAttachmentIndex"; + case SpvDecorationAlignment: return "Alignment"; + case SpvDecorationMaxByteOffset: return "MaxByteOffset"; + case SpvDecorationAlignmentId: return "AlignmentId"; + case SpvDecorationMaxByteOffsetId: return "MaxByteOffsetId"; + case SpvDecorationNoSignedWrap: return "NoSignedWrap"; + case SpvDecorationNoUnsignedWrap: return "NoUnsignedWrap"; + case SpvDecorationWeightTextureQCOM: return "WeightTextureQCOM"; + case SpvDecorationBlockMatchTextureQCOM: return "BlockMatchTextureQCOM"; + case SpvDecorationBlockMatchSamplerQCOM: return "BlockMatchSamplerQCOM"; + case SpvDecorationExplicitInterpAMD: return "ExplicitInterpAMD"; + case SpvDecorationNodeSharesPayloadLimitsWithAMDX: return "NodeSharesPayloadLimitsWithAMDX"; + case SpvDecorationNodeMaxPayloadsAMDX: return "NodeMaxPayloadsAMDX"; + case SpvDecorationTrackFinishWritingAMDX: return "TrackFinishWritingAMDX"; + case SpvDecorationPayloadNodeNameAMDX: return "PayloadNodeNameAMDX"; + case SpvDecorationOverrideCoverageNV: return "OverrideCoverageNV"; + case SpvDecorationPassthroughNV: return "PassthroughNV"; + case SpvDecorationViewportRelativeNV: return "ViewportRelativeNV"; + case SpvDecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; + case SpvDecorationPerPrimitiveEXT: return "PerPrimitiveEXT"; + case SpvDecorationPerViewNV: return "PerViewNV"; + case SpvDecorationPerTaskNV: return "PerTaskNV"; + case SpvDecorationPerVertexKHR: return "PerVertexKHR"; + case SpvDecorationNonUniform: return "NonUniform"; + case SpvDecorationRestrictPointer: return "RestrictPointer"; + case SpvDecorationAliasedPointer: return "AliasedPointer"; + case SpvDecorationHitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV"; + case SpvDecorationBindlessSamplerNV: return "BindlessSamplerNV"; + case SpvDecorationBindlessImageNV: return "BindlessImageNV"; + case SpvDecorationBoundSamplerNV: return "BoundSamplerNV"; + case SpvDecorationBoundImageNV: return "BoundImageNV"; + case SpvDecorationSIMTCallINTEL: return "SIMTCallINTEL"; + case SpvDecorationReferencedIndirectlyINTEL: return "ReferencedIndirectlyINTEL"; + case SpvDecorationClobberINTEL: return "ClobberINTEL"; + case SpvDecorationSideEffectsINTEL: return "SideEffectsINTEL"; + case SpvDecorationVectorComputeVariableINTEL: return "VectorComputeVariableINTEL"; + case SpvDecorationFuncParamIOKindINTEL: return "FuncParamIOKindINTEL"; + case SpvDecorationVectorComputeFunctionINTEL: return "VectorComputeFunctionINTEL"; + case SpvDecorationStackCallINTEL: return "StackCallINTEL"; + case SpvDecorationGlobalVariableOffsetINTEL: return "GlobalVariableOffsetINTEL"; + case SpvDecorationCounterBuffer: return "CounterBuffer"; + case SpvDecorationHlslSemanticGOOGLE: return "HlslSemanticGOOGLE"; + case SpvDecorationUserTypeGOOGLE: return "UserTypeGOOGLE"; + case SpvDecorationFunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL"; + case SpvDecorationFunctionDenormModeINTEL: return "FunctionDenormModeINTEL"; + case SpvDecorationRegisterINTEL: return "RegisterINTEL"; + case SpvDecorationMemoryINTEL: return "MemoryINTEL"; + case SpvDecorationNumbanksINTEL: return "NumbanksINTEL"; + case SpvDecorationBankwidthINTEL: return "BankwidthINTEL"; + case SpvDecorationMaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL"; + case SpvDecorationSinglepumpINTEL: return "SinglepumpINTEL"; + case SpvDecorationDoublepumpINTEL: return "DoublepumpINTEL"; + case SpvDecorationMaxReplicatesINTEL: return "MaxReplicatesINTEL"; + case SpvDecorationSimpleDualPortINTEL: return "SimpleDualPortINTEL"; + case SpvDecorationMergeINTEL: return "MergeINTEL"; + case SpvDecorationBankBitsINTEL: return "BankBitsINTEL"; + case SpvDecorationForcePow2DepthINTEL: return "ForcePow2DepthINTEL"; + case SpvDecorationStridesizeINTEL: return "StridesizeINTEL"; + case SpvDecorationWordsizeINTEL: return "WordsizeINTEL"; + case SpvDecorationTrueDualPortINTEL: return "TrueDualPortINTEL"; + case SpvDecorationBurstCoalesceINTEL: return "BurstCoalesceINTEL"; + case SpvDecorationCacheSizeINTEL: return "CacheSizeINTEL"; + case SpvDecorationDontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL"; + case SpvDecorationPrefetchINTEL: return "PrefetchINTEL"; + case SpvDecorationStallEnableINTEL: return "StallEnableINTEL"; + case SpvDecorationFuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL"; + case SpvDecorationMathOpDSPModeINTEL: return "MathOpDSPModeINTEL"; + case SpvDecorationAliasScopeINTEL: return "AliasScopeINTEL"; + case SpvDecorationNoAliasINTEL: return "NoAliasINTEL"; + case SpvDecorationInitiationIntervalINTEL: return "InitiationIntervalINTEL"; + case SpvDecorationMaxConcurrencyINTEL: return "MaxConcurrencyINTEL"; + case SpvDecorationPipelineEnableINTEL: return "PipelineEnableINTEL"; + case SpvDecorationBufferLocationINTEL: return "BufferLocationINTEL"; + case SpvDecorationIOPipeStorageINTEL: return "IOPipeStorageINTEL"; + case SpvDecorationFunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL"; + case SpvDecorationSingleElementVectorINTEL: return "SingleElementVectorINTEL"; + case SpvDecorationVectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL"; + case SpvDecorationMediaBlockIOINTEL: return "MediaBlockIOINTEL"; + case SpvDecorationStallFreeINTEL: return "StallFreeINTEL"; + case SpvDecorationFPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL"; + case SpvDecorationLatencyControlLabelINTEL: return "LatencyControlLabelINTEL"; + case SpvDecorationLatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL"; + case SpvDecorationConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL"; + case SpvDecorationRegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL"; + case SpvDecorationMMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL"; + case SpvDecorationMMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL"; + case SpvDecorationMMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL"; + case SpvDecorationMMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL"; + case SpvDecorationMMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL"; + case SpvDecorationMMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL"; + case SpvDecorationStableKernelArgumentINTEL: return "StableKernelArgumentINTEL"; + case SpvDecorationHostAccessINTEL: return "HostAccessINTEL"; + case SpvDecorationInitModeINTEL: return "InitModeINTEL"; + case SpvDecorationImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL"; + case SpvDecorationCacheControlLoadINTEL: return "CacheControlLoadINTEL"; + case SpvDecorationCacheControlStoreINTEL: return "CacheControlStoreINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvBuiltInToString(SpvBuiltIn value) { + switch (value) { + case SpvBuiltInPosition: return "Position"; + case SpvBuiltInPointSize: return "PointSize"; + case SpvBuiltInClipDistance: return "ClipDistance"; + case SpvBuiltInCullDistance: return "CullDistance"; + case SpvBuiltInVertexId: return "VertexId"; + case SpvBuiltInInstanceId: return "InstanceId"; + case SpvBuiltInPrimitiveId: return "PrimitiveId"; + case SpvBuiltInInvocationId: return "InvocationId"; + case SpvBuiltInLayer: return "Layer"; + case SpvBuiltInViewportIndex: return "ViewportIndex"; + case SpvBuiltInTessLevelOuter: return "TessLevelOuter"; + case SpvBuiltInTessLevelInner: return "TessLevelInner"; + case SpvBuiltInTessCoord: return "TessCoord"; + case SpvBuiltInPatchVertices: return "PatchVertices"; + case SpvBuiltInFragCoord: return "FragCoord"; + case SpvBuiltInPointCoord: return "PointCoord"; + case SpvBuiltInFrontFacing: return "FrontFacing"; + case SpvBuiltInSampleId: return "SampleId"; + case SpvBuiltInSamplePosition: return "SamplePosition"; + case SpvBuiltInSampleMask: return "SampleMask"; + case SpvBuiltInFragDepth: return "FragDepth"; + case SpvBuiltInHelperInvocation: return "HelperInvocation"; + case SpvBuiltInNumWorkgroups: return "NumWorkgroups"; + case SpvBuiltInWorkgroupSize: return "WorkgroupSize"; + case SpvBuiltInWorkgroupId: return "WorkgroupId"; + case SpvBuiltInLocalInvocationId: return "LocalInvocationId"; + case SpvBuiltInGlobalInvocationId: return "GlobalInvocationId"; + case SpvBuiltInLocalInvocationIndex: return "LocalInvocationIndex"; + case SpvBuiltInWorkDim: return "WorkDim"; + case SpvBuiltInGlobalSize: return "GlobalSize"; + case SpvBuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case SpvBuiltInGlobalOffset: return "GlobalOffset"; + case SpvBuiltInGlobalLinearId: return "GlobalLinearId"; + case SpvBuiltInSubgroupSize: return "SubgroupSize"; + case SpvBuiltInSubgroupMaxSize: return "SubgroupMaxSize"; + case SpvBuiltInNumSubgroups: return "NumSubgroups"; + case SpvBuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case SpvBuiltInSubgroupId: return "SubgroupId"; + case SpvBuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + case SpvBuiltInVertexIndex: return "VertexIndex"; + case SpvBuiltInInstanceIndex: return "InstanceIndex"; + case SpvBuiltInCoreIDARM: return "CoreIDARM"; + case SpvBuiltInCoreCountARM: return "CoreCountARM"; + case SpvBuiltInCoreMaxIDARM: return "CoreMaxIDARM"; + case SpvBuiltInWarpIDARM: return "WarpIDARM"; + case SpvBuiltInWarpMaxIDARM: return "WarpMaxIDARM"; + case SpvBuiltInSubgroupEqMask: return "SubgroupEqMask"; + case SpvBuiltInSubgroupGeMask: return "SubgroupGeMask"; + case SpvBuiltInSubgroupGtMask: return "SubgroupGtMask"; + case SpvBuiltInSubgroupLeMask: return "SubgroupLeMask"; + case SpvBuiltInSubgroupLtMask: return "SubgroupLtMask"; + case SpvBuiltInBaseVertex: return "BaseVertex"; + case SpvBuiltInBaseInstance: return "BaseInstance"; + case SpvBuiltInDrawIndex: return "DrawIndex"; + case SpvBuiltInPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + case SpvBuiltInDeviceIndex: return "DeviceIndex"; + case SpvBuiltInViewIndex: return "ViewIndex"; + case SpvBuiltInShadingRateKHR: return "ShadingRateKHR"; + case SpvBuiltInBaryCoordNoPerspAMD: return "BaryCoordNoPerspAMD"; + case SpvBuiltInBaryCoordNoPerspCentroidAMD: return "BaryCoordNoPerspCentroidAMD"; + case SpvBuiltInBaryCoordNoPerspSampleAMD: return "BaryCoordNoPerspSampleAMD"; + case SpvBuiltInBaryCoordSmoothAMD: return "BaryCoordSmoothAMD"; + case SpvBuiltInBaryCoordSmoothCentroidAMD: return "BaryCoordSmoothCentroidAMD"; + case SpvBuiltInBaryCoordSmoothSampleAMD: return "BaryCoordSmoothSampleAMD"; + case SpvBuiltInBaryCoordPullModelAMD: return "BaryCoordPullModelAMD"; + case SpvBuiltInFragStencilRefEXT: return "FragStencilRefEXT"; + case SpvBuiltInCoalescedInputCountAMDX: return "CoalescedInputCountAMDX"; + case SpvBuiltInShaderIndexAMDX: return "ShaderIndexAMDX"; + case SpvBuiltInViewportMaskNV: return "ViewportMaskNV"; + case SpvBuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case SpvBuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case SpvBuiltInPositionPerViewNV: return "PositionPerViewNV"; + case SpvBuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case SpvBuiltInFullyCoveredEXT: return "FullyCoveredEXT"; + case SpvBuiltInTaskCountNV: return "TaskCountNV"; + case SpvBuiltInPrimitiveCountNV: return "PrimitiveCountNV"; + case SpvBuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case SpvBuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case SpvBuiltInCullDistancePerViewNV: return "CullDistancePerViewNV"; + case SpvBuiltInLayerPerViewNV: return "LayerPerViewNV"; + case SpvBuiltInMeshViewCountNV: return "MeshViewCountNV"; + case SpvBuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; + case SpvBuiltInBaryCoordKHR: return "BaryCoordKHR"; + case SpvBuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR"; + case SpvBuiltInFragSizeEXT: return "FragSizeEXT"; + case SpvBuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; + case SpvBuiltInPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case SpvBuiltInPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case SpvBuiltInPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case SpvBuiltInCullPrimitiveEXT: return "CullPrimitiveEXT"; + case SpvBuiltInLaunchIdKHR: return "LaunchIdKHR"; + case SpvBuiltInLaunchSizeKHR: return "LaunchSizeKHR"; + case SpvBuiltInWorldRayOriginKHR: return "WorldRayOriginKHR"; + case SpvBuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case SpvBuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case SpvBuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case SpvBuiltInRayTminKHR: return "RayTminKHR"; + case SpvBuiltInRayTmaxKHR: return "RayTmaxKHR"; + case SpvBuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case SpvBuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; + case SpvBuiltInWorldToObjectKHR: return "WorldToObjectKHR"; + case SpvBuiltInHitTNV: return "HitTNV"; + case SpvBuiltInHitKindKHR: return "HitKindKHR"; + case SpvBuiltInCurrentRayTimeNV: return "CurrentRayTimeNV"; + case SpvBuiltInHitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR"; + case SpvBuiltInHitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV"; + case SpvBuiltInHitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV"; + case SpvBuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case SpvBuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case SpvBuiltInWarpsPerSMNV: return "WarpsPerSMNV"; + case SpvBuiltInSMCountNV: return "SMCountNV"; + case SpvBuiltInWarpIDNV: return "WarpIDNV"; + case SpvBuiltInSMIDNV: return "SMIDNV"; + case SpvBuiltInHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case SpvBuiltInHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; + case SpvBuiltInCullMaskKHR: return "CullMaskKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvScopeToString(SpvScope value) { + switch (value) { + case SpvScopeCrossDevice: return "CrossDevice"; + case SpvScopeDevice: return "Device"; + case SpvScopeWorkgroup: return "Workgroup"; + case SpvScopeSubgroup: return "Subgroup"; + case SpvScopeInvocation: return "Invocation"; + case SpvScopeQueueFamily: return "QueueFamily"; + case SpvScopeShaderCallKHR: return "ShaderCallKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvGroupOperationToString(SpvGroupOperation value) { + switch (value) { + case SpvGroupOperationReduce: return "Reduce"; + case SpvGroupOperationInclusiveScan: return "InclusiveScan"; + case SpvGroupOperationExclusiveScan: return "ExclusiveScan"; + case SpvGroupOperationClusteredReduce: return "ClusteredReduce"; + case SpvGroupOperationPartitionedReduceNV: return "PartitionedReduceNV"; + case SpvGroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; + case SpvGroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; + default: return "Unknown"; + } +} + +inline const char* SpvKernelEnqueueFlagsToString(SpvKernelEnqueueFlags value) { + switch (value) { + case SpvKernelEnqueueFlagsNoWait: return "NoWait"; + case SpvKernelEnqueueFlagsWaitKernel: return "WaitKernel"; + case SpvKernelEnqueueFlagsWaitWorkGroup: return "WaitWorkGroup"; + default: return "Unknown"; + } +} + +inline const char* SpvCapabilityToString(SpvCapability value) { + switch (value) { + case SpvCapabilityMatrix: return "Matrix"; + case SpvCapabilityShader: return "Shader"; + case SpvCapabilityGeometry: return "Geometry"; + case SpvCapabilityTessellation: return "Tessellation"; + case SpvCapabilityAddresses: return "Addresses"; + case SpvCapabilityLinkage: return "Linkage"; + case SpvCapabilityKernel: return "Kernel"; + case SpvCapabilityVector16: return "Vector16"; + case SpvCapabilityFloat16Buffer: return "Float16Buffer"; + case SpvCapabilityFloat16: return "Float16"; + case SpvCapabilityFloat64: return "Float64"; + case SpvCapabilityInt64: return "Int64"; + case SpvCapabilityInt64Atomics: return "Int64Atomics"; + case SpvCapabilityImageBasic: return "ImageBasic"; + case SpvCapabilityImageReadWrite: return "ImageReadWrite"; + case SpvCapabilityImageMipmap: return "ImageMipmap"; + case SpvCapabilityPipes: return "Pipes"; + case SpvCapabilityGroups: return "Groups"; + case SpvCapabilityDeviceEnqueue: return "DeviceEnqueue"; + case SpvCapabilityLiteralSampler: return "LiteralSampler"; + case SpvCapabilityAtomicStorage: return "AtomicStorage"; + case SpvCapabilityInt16: return "Int16"; + case SpvCapabilityTessellationPointSize: return "TessellationPointSize"; + case SpvCapabilityGeometryPointSize: return "GeometryPointSize"; + case SpvCapabilityImageGatherExtended: return "ImageGatherExtended"; + case SpvCapabilityStorageImageMultisample: return "StorageImageMultisample"; + case SpvCapabilityUniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; + case SpvCapabilitySampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; + case SpvCapabilityStorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; + case SpvCapabilityStorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; + case SpvCapabilityClipDistance: return "ClipDistance"; + case SpvCapabilityCullDistance: return "CullDistance"; + case SpvCapabilityImageCubeArray: return "ImageCubeArray"; + case SpvCapabilitySampleRateShading: return "SampleRateShading"; + case SpvCapabilityImageRect: return "ImageRect"; + case SpvCapabilitySampledRect: return "SampledRect"; + case SpvCapabilityGenericPointer: return "GenericPointer"; + case SpvCapabilityInt8: return "Int8"; + case SpvCapabilityInputAttachment: return "InputAttachment"; + case SpvCapabilitySparseResidency: return "SparseResidency"; + case SpvCapabilityMinLod: return "MinLod"; + case SpvCapabilitySampled1D: return "Sampled1D"; + case SpvCapabilityImage1D: return "Image1D"; + case SpvCapabilitySampledCubeArray: return "SampledCubeArray"; + case SpvCapabilitySampledBuffer: return "SampledBuffer"; + case SpvCapabilityImageBuffer: return "ImageBuffer"; + case SpvCapabilityImageMSArray: return "ImageMSArray"; + case SpvCapabilityStorageImageExtendedFormats: return "StorageImageExtendedFormats"; + case SpvCapabilityImageQuery: return "ImageQuery"; + case SpvCapabilityDerivativeControl: return "DerivativeControl"; + case SpvCapabilityInterpolationFunction: return "InterpolationFunction"; + case SpvCapabilityTransformFeedback: return "TransformFeedback"; + case SpvCapabilityGeometryStreams: return "GeometryStreams"; + case SpvCapabilityStorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; + case SpvCapabilityStorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; + case SpvCapabilityMultiViewport: return "MultiViewport"; + case SpvCapabilitySubgroupDispatch: return "SubgroupDispatch"; + case SpvCapabilityNamedBarrier: return "NamedBarrier"; + case SpvCapabilityPipeStorage: return "PipeStorage"; + case SpvCapabilityGroupNonUniform: return "GroupNonUniform"; + case SpvCapabilityGroupNonUniformVote: return "GroupNonUniformVote"; + case SpvCapabilityGroupNonUniformArithmetic: return "GroupNonUniformArithmetic"; + case SpvCapabilityGroupNonUniformBallot: return "GroupNonUniformBallot"; + case SpvCapabilityGroupNonUniformShuffle: return "GroupNonUniformShuffle"; + case SpvCapabilityGroupNonUniformShuffleRelative: return "GroupNonUniformShuffleRelative"; + case SpvCapabilityGroupNonUniformClustered: return "GroupNonUniformClustered"; + case SpvCapabilityGroupNonUniformQuad: return "GroupNonUniformQuad"; + case SpvCapabilityShaderLayer: return "ShaderLayer"; + case SpvCapabilityShaderViewportIndex: return "ShaderViewportIndex"; + case SpvCapabilityUniformDecoration: return "UniformDecoration"; + case SpvCapabilityCoreBuiltinsARM: return "CoreBuiltinsARM"; + case SpvCapabilityTileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; + case SpvCapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; + case SpvCapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case SpvCapabilityCooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM"; + case SpvCapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; + case SpvCapabilitySubgroupBallotKHR: return "SubgroupBallotKHR"; + case SpvCapabilityDrawParameters: return "DrawParameters"; + case SpvCapabilityWorkgroupMemoryExplicitLayoutKHR: return "WorkgroupMemoryExplicitLayoutKHR"; + case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; + case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; + case SpvCapabilitySubgroupVoteKHR: return "SubgroupVoteKHR"; + case SpvCapabilityStorageBuffer16BitAccess: return "StorageBuffer16BitAccess"; + case SpvCapabilityStorageUniform16: return "StorageUniform16"; + case SpvCapabilityStoragePushConstant16: return "StoragePushConstant16"; + case SpvCapabilityStorageInputOutput16: return "StorageInputOutput16"; + case SpvCapabilityDeviceGroup: return "DeviceGroup"; + case SpvCapabilityMultiView: return "MultiView"; + case SpvCapabilityVariablePointersStorageBuffer: return "VariablePointersStorageBuffer"; + case SpvCapabilityVariablePointers: return "VariablePointers"; + case SpvCapabilityAtomicStorageOps: return "AtomicStorageOps"; + case SpvCapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; + case SpvCapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case SpvCapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case SpvCapabilityStoragePushConstant8: return "StoragePushConstant8"; + case SpvCapabilityDenormPreserve: return "DenormPreserve"; + case SpvCapabilityDenormFlushToZero: return "DenormFlushToZero"; + case SpvCapabilitySignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case SpvCapabilityRoundingModeRTE: return "RoundingModeRTE"; + case SpvCapabilityRoundingModeRTZ: return "RoundingModeRTZ"; + case SpvCapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; + case SpvCapabilityRayQueryKHR: return "RayQueryKHR"; + case SpvCapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; + case SpvCapabilityRayTracingKHR: return "RayTracingKHR"; + case SpvCapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; + case SpvCapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; + case SpvCapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; + case SpvCapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; + case SpvCapabilityFloat16ImageAMD: return "Float16ImageAMD"; + case SpvCapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; + case SpvCapabilityFragmentMaskAMD: return "FragmentMaskAMD"; + case SpvCapabilityStencilExportEXT: return "StencilExportEXT"; + case SpvCapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case SpvCapabilityInt64ImageEXT: return "Int64ImageEXT"; + case SpvCapabilityShaderClockKHR: return "ShaderClockKHR"; + case SpvCapabilityShaderEnqueueAMDX: return "ShaderEnqueueAMDX"; + case SpvCapabilityQuadControlKHR: return "QuadControlKHR"; + case SpvCapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; + case SpvCapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case SpvCapabilityShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; + case SpvCapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case SpvCapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; + case SpvCapabilityPerViewAttributesNV: return "PerViewAttributesNV"; + case SpvCapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; + case SpvCapabilityMeshShadingNV: return "MeshShadingNV"; + case SpvCapabilityImageFootprintNV: return "ImageFootprintNV"; + case SpvCapabilityMeshShadingEXT: return "MeshShadingEXT"; + case SpvCapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR"; + case SpvCapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; + case SpvCapabilityFragmentDensityEXT: return "FragmentDensityEXT"; + case SpvCapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; + case SpvCapabilityShaderNonUniform: return "ShaderNonUniform"; + case SpvCapabilityRuntimeDescriptorArray: return "RuntimeDescriptorArray"; + case SpvCapabilityInputAttachmentArrayDynamicIndexing: return "InputAttachmentArrayDynamicIndexing"; + case SpvCapabilityUniformTexelBufferArrayDynamicIndexing: return "UniformTexelBufferArrayDynamicIndexing"; + case SpvCapabilityStorageTexelBufferArrayDynamicIndexing: return "StorageTexelBufferArrayDynamicIndexing"; + case SpvCapabilityUniformBufferArrayNonUniformIndexing: return "UniformBufferArrayNonUniformIndexing"; + case SpvCapabilitySampledImageArrayNonUniformIndexing: return "SampledImageArrayNonUniformIndexing"; + case SpvCapabilityStorageBufferArrayNonUniformIndexing: return "StorageBufferArrayNonUniformIndexing"; + case SpvCapabilityStorageImageArrayNonUniformIndexing: return "StorageImageArrayNonUniformIndexing"; + case SpvCapabilityInputAttachmentArrayNonUniformIndexing: return "InputAttachmentArrayNonUniformIndexing"; + case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing: return "UniformTexelBufferArrayNonUniformIndexing"; + case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing: return "StorageTexelBufferArrayNonUniformIndexing"; + case SpvCapabilityRayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR"; + case SpvCapabilityRayTracingNV: return "RayTracingNV"; + case SpvCapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; + case SpvCapabilityVulkanMemoryModel: return "VulkanMemoryModel"; + case SpvCapabilityVulkanMemoryModelDeviceScope: return "VulkanMemoryModelDeviceScope"; + case SpvCapabilityPhysicalStorageBufferAddresses: return "PhysicalStorageBufferAddresses"; + case SpvCapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; + case SpvCapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case SpvCapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case SpvCapabilityFragmentShaderSampleInterlockEXT: return "FragmentShaderSampleInterlockEXT"; + case SpvCapabilityFragmentShaderShadingRateInterlockEXT: return "FragmentShaderShadingRateInterlockEXT"; + case SpvCapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + case SpvCapabilityFragmentShaderPixelInterlockEXT: return "FragmentShaderPixelInterlockEXT"; + case SpvCapabilityDemoteToHelperInvocation: return "DemoteToHelperInvocation"; + case SpvCapabilityDisplacementMicromapNV: return "DisplacementMicromapNV"; + case SpvCapabilityRayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT"; + case SpvCapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV"; + case SpvCapabilityBindlessTextureNV: return "BindlessTextureNV"; + case SpvCapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR"; + case SpvCapabilityAtomicFloat16VectorNV: return "AtomicFloat16VectorNV"; + case SpvCapabilityRayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV"; + case SpvCapabilityRawAccessChainsNV: return "RawAccessChainsNV"; + case SpvCapabilitySubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; + case SpvCapabilitySubgroupBufferBlockIOINTEL: return "SubgroupBufferBlockIOINTEL"; + case SpvCapabilitySubgroupImageBlockIOINTEL: return "SubgroupImageBlockIOINTEL"; + case SpvCapabilitySubgroupImageMediaBlockIOINTEL: return "SubgroupImageMediaBlockIOINTEL"; + case SpvCapabilityRoundToInfinityINTEL: return "RoundToInfinityINTEL"; + case SpvCapabilityFloatingPointModeINTEL: return "FloatingPointModeINTEL"; + case SpvCapabilityIntegerFunctions2INTEL: return "IntegerFunctions2INTEL"; + case SpvCapabilityFunctionPointersINTEL: return "FunctionPointersINTEL"; + case SpvCapabilityIndirectReferencesINTEL: return "IndirectReferencesINTEL"; + case SpvCapabilityAsmINTEL: return "AsmINTEL"; + case SpvCapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; + case SpvCapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; + case SpvCapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; + case SpvCapabilityVectorComputeINTEL: return "VectorComputeINTEL"; + case SpvCapabilityVectorAnyINTEL: return "VectorAnyINTEL"; + case SpvCapabilityExpectAssumeKHR: return "ExpectAssumeKHR"; + case SpvCapabilitySubgroupAvcMotionEstimationINTEL: return "SubgroupAvcMotionEstimationINTEL"; + case SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL: return "SubgroupAvcMotionEstimationIntraINTEL"; + case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL"; + case SpvCapabilityVariableLengthArrayINTEL: return "VariableLengthArrayINTEL"; + case SpvCapabilityFunctionFloatControlINTEL: return "FunctionFloatControlINTEL"; + case SpvCapabilityFPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL"; + case SpvCapabilityFPFastMathModeINTEL: return "FPFastMathModeINTEL"; + case SpvCapabilityArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL"; + case SpvCapabilityArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL"; + case SpvCapabilityUnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL"; + case SpvCapabilityFPGALoopControlsINTEL: return "FPGALoopControlsINTEL"; + case SpvCapabilityKernelAttributesINTEL: return "KernelAttributesINTEL"; + case SpvCapabilityFPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL"; + case SpvCapabilityFPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL"; + case SpvCapabilityFPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL"; + case SpvCapabilityLoopFuseINTEL: return "LoopFuseINTEL"; + case SpvCapabilityFPGADSPControlINTEL: return "FPGADSPControlINTEL"; + case SpvCapabilityMemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL"; + case SpvCapabilityFPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL"; + case SpvCapabilityFPGABufferLocationINTEL: return "FPGABufferLocationINTEL"; + case SpvCapabilityArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL"; + case SpvCapabilityUSMStorageClassesINTEL: return "USMStorageClassesINTEL"; + case SpvCapabilityRuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL"; + case SpvCapabilityIOPipesINTEL: return "IOPipesINTEL"; + case SpvCapabilityBlockingPipesINTEL: return "BlockingPipesINTEL"; + case SpvCapabilityFPGARegINTEL: return "FPGARegINTEL"; + case SpvCapabilityDotProductInputAll: return "DotProductInputAll"; + case SpvCapabilityDotProductInput4x8Bit: return "DotProductInput4x8Bit"; + case SpvCapabilityDotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked"; + case SpvCapabilityDotProduct: return "DotProduct"; + case SpvCapabilityRayCullMaskKHR: return "RayCullMaskKHR"; + case SpvCapabilityCooperativeMatrixKHR: return "CooperativeMatrixKHR"; + case SpvCapabilityReplicatedCompositesEXT: return "ReplicatedCompositesEXT"; + case SpvCapabilityBitInstructions: return "BitInstructions"; + case SpvCapabilityGroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR"; + case SpvCapabilityFloatControls2: return "FloatControls2"; + case SpvCapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case SpvCapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + case SpvCapabilityLongCompositesINTEL: return "LongCompositesINTEL"; + case SpvCapabilityOptNoneINTEL: return "OptNoneINTEL"; + case SpvCapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; + case SpvCapabilityDebugInfoModuleINTEL: return "DebugInfoModuleINTEL"; + case SpvCapabilityBFloat16ConversionINTEL: return "BFloat16ConversionINTEL"; + case SpvCapabilitySplitBarrierINTEL: return "SplitBarrierINTEL"; + case SpvCapabilityFPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL"; + case SpvCapabilityFPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL"; + case SpvCapabilityFPMaxErrorINTEL: return "FPMaxErrorINTEL"; + case SpvCapabilityFPGALatencyControlINTEL: return "FPGALatencyControlINTEL"; + case SpvCapabilityFPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL"; + case SpvCapabilityGlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL"; + case SpvCapabilityGlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL"; + case SpvCapabilityGroupUniformArithmeticKHR: return "GroupUniformArithmeticKHR"; + case SpvCapabilityMaskedGatherScatterINTEL: return "MaskedGatherScatterINTEL"; + case SpvCapabilityCacheControlsINTEL: return "CacheControlsINTEL"; + case SpvCapabilityRegisterLimitsINTEL: return "RegisterLimitsINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvRayQueryIntersectionToString(SpvRayQueryIntersection value) { + switch (value) { + case SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR: return "RayQueryCandidateIntersectionKHR"; + case SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR: return "RayQueryCommittedIntersectionKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvRayQueryCommittedIntersectionTypeToString(SpvRayQueryCommittedIntersectionType value) { + switch (value) { + case SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR: return "RayQueryCommittedIntersectionNoneKHR"; + case SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR: return "RayQueryCommittedIntersectionTriangleKHR"; + case SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR: return "RayQueryCommittedIntersectionGeneratedKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvRayQueryCandidateIntersectionTypeToString(SpvRayQueryCandidateIntersectionType value) { + switch (value) { + case SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR: return "RayQueryCandidateIntersectionTriangleKHR"; + case SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR: return "RayQueryCandidateIntersectionAABBKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvFPDenormModeToString(SpvFPDenormMode value) { + switch (value) { + case SpvFPDenormModePreserve: return "Preserve"; + case SpvFPDenormModeFlushToZero: return "FlushToZero"; + default: return "Unknown"; + } +} + +inline const char* SpvFPOperationModeToString(SpvFPOperationMode value) { + switch (value) { + case SpvFPOperationModeIEEE: return "IEEE"; + case SpvFPOperationModeALT: return "ALT"; + default: return "Unknown"; + } +} + +inline const char* SpvQuantizationModesToString(SpvQuantizationModes value) { + switch (value) { + case SpvQuantizationModesTRN: return "TRN"; + case SpvQuantizationModesTRN_ZERO: return "TRN_ZERO"; + case SpvQuantizationModesRND: return "RND"; + case SpvQuantizationModesRND_ZERO: return "RND_ZERO"; + case SpvQuantizationModesRND_INF: return "RND_INF"; + case SpvQuantizationModesRND_MIN_INF: return "RND_MIN_INF"; + case SpvQuantizationModesRND_CONV: return "RND_CONV"; + case SpvQuantizationModesRND_CONV_ODD: return "RND_CONV_ODD"; + default: return "Unknown"; + } +} + +inline const char* SpvOverflowModesToString(SpvOverflowModes value) { + switch (value) { + case SpvOverflowModesWRAP: return "WRAP"; + case SpvOverflowModesSAT: return "SAT"; + case SpvOverflowModesSAT_ZERO: return "SAT_ZERO"; + case SpvOverflowModesSAT_SYM: return "SAT_SYM"; + default: return "Unknown"; + } +} + +inline const char* SpvPackedVectorFormatToString(SpvPackedVectorFormat value) { + switch (value) { + case SpvPackedVectorFormatPackedVectorFormat4x8Bit: return "PackedVectorFormat4x8Bit"; + default: return "Unknown"; + } +} + +inline const char* SpvCooperativeMatrixLayoutToString(SpvCooperativeMatrixLayout value) { + switch (value) { + case SpvCooperativeMatrixLayoutRowMajorKHR: return "RowMajorKHR"; + case SpvCooperativeMatrixLayoutColumnMajorKHR: return "ColumnMajorKHR"; + case SpvCooperativeMatrixLayoutRowBlockedInterleavedARM: return "RowBlockedInterleavedARM"; + case SpvCooperativeMatrixLayoutColumnBlockedInterleavedARM: return "ColumnBlockedInterleavedARM"; + default: return "Unknown"; + } +} + +inline const char* SpvCooperativeMatrixUseToString(SpvCooperativeMatrixUse value) { + switch (value) { + case SpvCooperativeMatrixUseMatrixAKHR: return "MatrixAKHR"; + case SpvCooperativeMatrixUseMatrixBKHR: return "MatrixBKHR"; + case SpvCooperativeMatrixUseMatrixAccumulatorKHR: return "MatrixAccumulatorKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvInitializationModeQualifierToString(SpvInitializationModeQualifier value) { + switch (value) { + case SpvInitializationModeQualifierInitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL"; + case SpvInitializationModeQualifierInitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvHostAccessQualifierToString(SpvHostAccessQualifier value) { + switch (value) { + case SpvHostAccessQualifierNoneINTEL: return "NoneINTEL"; + case SpvHostAccessQualifierReadINTEL: return "ReadINTEL"; + case SpvHostAccessQualifierWriteINTEL: return "WriteINTEL"; + case SpvHostAccessQualifierReadWriteINTEL: return "ReadWriteINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvLoadCacheControlToString(SpvLoadCacheControl value) { + switch (value) { + case SpvLoadCacheControlUncachedINTEL: return "UncachedINTEL"; + case SpvLoadCacheControlCachedINTEL: return "CachedINTEL"; + case SpvLoadCacheControlStreamingINTEL: return "StreamingINTEL"; + case SpvLoadCacheControlInvalidateAfterReadINTEL: return "InvalidateAfterReadINTEL"; + case SpvLoadCacheControlConstCachedINTEL: return "ConstCachedINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvStoreCacheControlToString(SpvStoreCacheControl value) { + switch (value) { + case SpvStoreCacheControlUncachedINTEL: return "UncachedINTEL"; + case SpvStoreCacheControlWriteThroughINTEL: return "WriteThroughINTEL"; + case SpvStoreCacheControlWriteBackINTEL: return "WriteBackINTEL"; + case SpvStoreCacheControlStreamingINTEL: return "StreamingINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvNamedMaximumNumberOfRegistersToString(SpvNamedMaximumNumberOfRegisters value) { + switch (value) { + case SpvNamedMaximumNumberOfRegistersAutoINTEL: return "AutoINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvOpToString(SpvOp value) { + switch (value) { + case SpvOpNop: return "OpNop"; + case SpvOpUndef: return "OpUndef"; + case SpvOpSourceContinued: return "OpSourceContinued"; + case SpvOpSource: return "OpSource"; + case SpvOpSourceExtension: return "OpSourceExtension"; + case SpvOpName: return "OpName"; + case SpvOpMemberName: return "OpMemberName"; + case SpvOpString: return "OpString"; + case SpvOpLine: return "OpLine"; + case SpvOpExtension: return "OpExtension"; + case SpvOpExtInstImport: return "OpExtInstImport"; + case SpvOpExtInst: return "OpExtInst"; + case SpvOpMemoryModel: return "OpMemoryModel"; + case SpvOpEntryPoint: return "OpEntryPoint"; + case SpvOpExecutionMode: return "OpExecutionMode"; + case SpvOpCapability: return "OpCapability"; + case SpvOpTypeVoid: return "OpTypeVoid"; + case SpvOpTypeBool: return "OpTypeBool"; + case SpvOpTypeInt: return "OpTypeInt"; + case SpvOpTypeFloat: return "OpTypeFloat"; + case SpvOpTypeVector: return "OpTypeVector"; + case SpvOpTypeMatrix: return "OpTypeMatrix"; + case SpvOpTypeImage: return "OpTypeImage"; + case SpvOpTypeSampler: return "OpTypeSampler"; + case SpvOpTypeSampledImage: return "OpTypeSampledImage"; + case SpvOpTypeArray: return "OpTypeArray"; + case SpvOpTypeRuntimeArray: return "OpTypeRuntimeArray"; + case SpvOpTypeStruct: return "OpTypeStruct"; + case SpvOpTypeOpaque: return "OpTypeOpaque"; + case SpvOpTypePointer: return "OpTypePointer"; + case SpvOpTypeFunction: return "OpTypeFunction"; + case SpvOpTypeEvent: return "OpTypeEvent"; + case SpvOpTypeDeviceEvent: return "OpTypeDeviceEvent"; + case SpvOpTypeReserveId: return "OpTypeReserveId"; + case SpvOpTypeQueue: return "OpTypeQueue"; + case SpvOpTypePipe: return "OpTypePipe"; + case SpvOpTypeForwardPointer: return "OpTypeForwardPointer"; + case SpvOpConstantTrue: return "OpConstantTrue"; + case SpvOpConstantFalse: return "OpConstantFalse"; + case SpvOpConstant: return "OpConstant"; + case SpvOpConstantComposite: return "OpConstantComposite"; + case SpvOpConstantSampler: return "OpConstantSampler"; + case SpvOpConstantNull: return "OpConstantNull"; + case SpvOpSpecConstantTrue: return "OpSpecConstantTrue"; + case SpvOpSpecConstantFalse: return "OpSpecConstantFalse"; + case SpvOpSpecConstant: return "OpSpecConstant"; + case SpvOpSpecConstantComposite: return "OpSpecConstantComposite"; + case SpvOpSpecConstantOp: return "OpSpecConstantOp"; + case SpvOpFunction: return "OpFunction"; + case SpvOpFunctionParameter: return "OpFunctionParameter"; + case SpvOpFunctionEnd: return "OpFunctionEnd"; + case SpvOpFunctionCall: return "OpFunctionCall"; + case SpvOpVariable: return "OpVariable"; + case SpvOpImageTexelPointer: return "OpImageTexelPointer"; + case SpvOpLoad: return "OpLoad"; + case SpvOpStore: return "OpStore"; + case SpvOpCopyMemory: return "OpCopyMemory"; + case SpvOpCopyMemorySized: return "OpCopyMemorySized"; + case SpvOpAccessChain: return "OpAccessChain"; + case SpvOpInBoundsAccessChain: return "OpInBoundsAccessChain"; + case SpvOpPtrAccessChain: return "OpPtrAccessChain"; + case SpvOpArrayLength: return "OpArrayLength"; + case SpvOpGenericPtrMemSemantics: return "OpGenericPtrMemSemantics"; + case SpvOpInBoundsPtrAccessChain: return "OpInBoundsPtrAccessChain"; + case SpvOpDecorate: return "OpDecorate"; + case SpvOpMemberDecorate: return "OpMemberDecorate"; + case SpvOpDecorationGroup: return "OpDecorationGroup"; + case SpvOpGroupDecorate: return "OpGroupDecorate"; + case SpvOpGroupMemberDecorate: return "OpGroupMemberDecorate"; + case SpvOpVectorExtractDynamic: return "OpVectorExtractDynamic"; + case SpvOpVectorInsertDynamic: return "OpVectorInsertDynamic"; + case SpvOpVectorShuffle: return "OpVectorShuffle"; + case SpvOpCompositeConstruct: return "OpCompositeConstruct"; + case SpvOpCompositeExtract: return "OpCompositeExtract"; + case SpvOpCompositeInsert: return "OpCompositeInsert"; + case SpvOpCopyObject: return "OpCopyObject"; + case SpvOpTranspose: return "OpTranspose"; + case SpvOpSampledImage: return "OpSampledImage"; + case SpvOpImageSampleImplicitLod: return "OpImageSampleImplicitLod"; + case SpvOpImageSampleExplicitLod: return "OpImageSampleExplicitLod"; + case SpvOpImageSampleDrefImplicitLod: return "OpImageSampleDrefImplicitLod"; + case SpvOpImageSampleDrefExplicitLod: return "OpImageSampleDrefExplicitLod"; + case SpvOpImageSampleProjImplicitLod: return "OpImageSampleProjImplicitLod"; + case SpvOpImageSampleProjExplicitLod: return "OpImageSampleProjExplicitLod"; + case SpvOpImageSampleProjDrefImplicitLod: return "OpImageSampleProjDrefImplicitLod"; + case SpvOpImageSampleProjDrefExplicitLod: return "OpImageSampleProjDrefExplicitLod"; + case SpvOpImageFetch: return "OpImageFetch"; + case SpvOpImageGather: return "OpImageGather"; + case SpvOpImageDrefGather: return "OpImageDrefGather"; + case SpvOpImageRead: return "OpImageRead"; + case SpvOpImageWrite: return "OpImageWrite"; + case SpvOpImage: return "OpImage"; + case SpvOpImageQueryFormat: return "OpImageQueryFormat"; + case SpvOpImageQueryOrder: return "OpImageQueryOrder"; + case SpvOpImageQuerySizeLod: return "OpImageQuerySizeLod"; + case SpvOpImageQuerySize: return "OpImageQuerySize"; + case SpvOpImageQueryLod: return "OpImageQueryLod"; + case SpvOpImageQueryLevels: return "OpImageQueryLevels"; + case SpvOpImageQuerySamples: return "OpImageQuerySamples"; + case SpvOpConvertFToU: return "OpConvertFToU"; + case SpvOpConvertFToS: return "OpConvertFToS"; + case SpvOpConvertSToF: return "OpConvertSToF"; + case SpvOpConvertUToF: return "OpConvertUToF"; + case SpvOpUConvert: return "OpUConvert"; + case SpvOpSConvert: return "OpSConvert"; + case SpvOpFConvert: return "OpFConvert"; + case SpvOpQuantizeToF16: return "OpQuantizeToF16"; + case SpvOpConvertPtrToU: return "OpConvertPtrToU"; + case SpvOpSatConvertSToU: return "OpSatConvertSToU"; + case SpvOpSatConvertUToS: return "OpSatConvertUToS"; + case SpvOpConvertUToPtr: return "OpConvertUToPtr"; + case SpvOpPtrCastToGeneric: return "OpPtrCastToGeneric"; + case SpvOpGenericCastToPtr: return "OpGenericCastToPtr"; + case SpvOpGenericCastToPtrExplicit: return "OpGenericCastToPtrExplicit"; + case SpvOpBitcast: return "OpBitcast"; + case SpvOpSNegate: return "OpSNegate"; + case SpvOpFNegate: return "OpFNegate"; + case SpvOpIAdd: return "OpIAdd"; + case SpvOpFAdd: return "OpFAdd"; + case SpvOpISub: return "OpISub"; + case SpvOpFSub: return "OpFSub"; + case SpvOpIMul: return "OpIMul"; + case SpvOpFMul: return "OpFMul"; + case SpvOpUDiv: return "OpUDiv"; + case SpvOpSDiv: return "OpSDiv"; + case SpvOpFDiv: return "OpFDiv"; + case SpvOpUMod: return "OpUMod"; + case SpvOpSRem: return "OpSRem"; + case SpvOpSMod: return "OpSMod"; + case SpvOpFRem: return "OpFRem"; + case SpvOpFMod: return "OpFMod"; + case SpvOpVectorTimesScalar: return "OpVectorTimesScalar"; + case SpvOpMatrixTimesScalar: return "OpMatrixTimesScalar"; + case SpvOpVectorTimesMatrix: return "OpVectorTimesMatrix"; + case SpvOpMatrixTimesVector: return "OpMatrixTimesVector"; + case SpvOpMatrixTimesMatrix: return "OpMatrixTimesMatrix"; + case SpvOpOuterProduct: return "OpOuterProduct"; + case SpvOpDot: return "OpDot"; + case SpvOpIAddCarry: return "OpIAddCarry"; + case SpvOpISubBorrow: return "OpISubBorrow"; + case SpvOpUMulExtended: return "OpUMulExtended"; + case SpvOpSMulExtended: return "OpSMulExtended"; + case SpvOpAny: return "OpAny"; + case SpvOpAll: return "OpAll"; + case SpvOpIsNan: return "OpIsNan"; + case SpvOpIsInf: return "OpIsInf"; + case SpvOpIsFinite: return "OpIsFinite"; + case SpvOpIsNormal: return "OpIsNormal"; + case SpvOpSignBitSet: return "OpSignBitSet"; + case SpvOpLessOrGreater: return "OpLessOrGreater"; + case SpvOpOrdered: return "OpOrdered"; + case SpvOpUnordered: return "OpUnordered"; + case SpvOpLogicalEqual: return "OpLogicalEqual"; + case SpvOpLogicalNotEqual: return "OpLogicalNotEqual"; + case SpvOpLogicalOr: return "OpLogicalOr"; + case SpvOpLogicalAnd: return "OpLogicalAnd"; + case SpvOpLogicalNot: return "OpLogicalNot"; + case SpvOpSelect: return "OpSelect"; + case SpvOpIEqual: return "OpIEqual"; + case SpvOpINotEqual: return "OpINotEqual"; + case SpvOpUGreaterThan: return "OpUGreaterThan"; + case SpvOpSGreaterThan: return "OpSGreaterThan"; + case SpvOpUGreaterThanEqual: return "OpUGreaterThanEqual"; + case SpvOpSGreaterThanEqual: return "OpSGreaterThanEqual"; + case SpvOpULessThan: return "OpULessThan"; + case SpvOpSLessThan: return "OpSLessThan"; + case SpvOpULessThanEqual: return "OpULessThanEqual"; + case SpvOpSLessThanEqual: return "OpSLessThanEqual"; + case SpvOpFOrdEqual: return "OpFOrdEqual"; + case SpvOpFUnordEqual: return "OpFUnordEqual"; + case SpvOpFOrdNotEqual: return "OpFOrdNotEqual"; + case SpvOpFUnordNotEqual: return "OpFUnordNotEqual"; + case SpvOpFOrdLessThan: return "OpFOrdLessThan"; + case SpvOpFUnordLessThan: return "OpFUnordLessThan"; + case SpvOpFOrdGreaterThan: return "OpFOrdGreaterThan"; + case SpvOpFUnordGreaterThan: return "OpFUnordGreaterThan"; + case SpvOpFOrdLessThanEqual: return "OpFOrdLessThanEqual"; + case SpvOpFUnordLessThanEqual: return "OpFUnordLessThanEqual"; + case SpvOpFOrdGreaterThanEqual: return "OpFOrdGreaterThanEqual"; + case SpvOpFUnordGreaterThanEqual: return "OpFUnordGreaterThanEqual"; + case SpvOpShiftRightLogical: return "OpShiftRightLogical"; + case SpvOpShiftRightArithmetic: return "OpShiftRightArithmetic"; + case SpvOpShiftLeftLogical: return "OpShiftLeftLogical"; + case SpvOpBitwiseOr: return "OpBitwiseOr"; + case SpvOpBitwiseXor: return "OpBitwiseXor"; + case SpvOpBitwiseAnd: return "OpBitwiseAnd"; + case SpvOpNot: return "OpNot"; + case SpvOpBitFieldInsert: return "OpBitFieldInsert"; + case SpvOpBitFieldSExtract: return "OpBitFieldSExtract"; + case SpvOpBitFieldUExtract: return "OpBitFieldUExtract"; + case SpvOpBitReverse: return "OpBitReverse"; + case SpvOpBitCount: return "OpBitCount"; + case SpvOpDPdx: return "OpDPdx"; + case SpvOpDPdy: return "OpDPdy"; + case SpvOpFwidth: return "OpFwidth"; + case SpvOpDPdxFine: return "OpDPdxFine"; + case SpvOpDPdyFine: return "OpDPdyFine"; + case SpvOpFwidthFine: return "OpFwidthFine"; + case SpvOpDPdxCoarse: return "OpDPdxCoarse"; + case SpvOpDPdyCoarse: return "OpDPdyCoarse"; + case SpvOpFwidthCoarse: return "OpFwidthCoarse"; + case SpvOpEmitVertex: return "OpEmitVertex"; + case SpvOpEndPrimitive: return "OpEndPrimitive"; + case SpvOpEmitStreamVertex: return "OpEmitStreamVertex"; + case SpvOpEndStreamPrimitive: return "OpEndStreamPrimitive"; + case SpvOpControlBarrier: return "OpControlBarrier"; + case SpvOpMemoryBarrier: return "OpMemoryBarrier"; + case SpvOpAtomicLoad: return "OpAtomicLoad"; + case SpvOpAtomicStore: return "OpAtomicStore"; + case SpvOpAtomicExchange: return "OpAtomicExchange"; + case SpvOpAtomicCompareExchange: return "OpAtomicCompareExchange"; + case SpvOpAtomicCompareExchangeWeak: return "OpAtomicCompareExchangeWeak"; + case SpvOpAtomicIIncrement: return "OpAtomicIIncrement"; + case SpvOpAtomicIDecrement: return "OpAtomicIDecrement"; + case SpvOpAtomicIAdd: return "OpAtomicIAdd"; + case SpvOpAtomicISub: return "OpAtomicISub"; + case SpvOpAtomicSMin: return "OpAtomicSMin"; + case SpvOpAtomicUMin: return "OpAtomicUMin"; + case SpvOpAtomicSMax: return "OpAtomicSMax"; + case SpvOpAtomicUMax: return "OpAtomicUMax"; + case SpvOpAtomicAnd: return "OpAtomicAnd"; + case SpvOpAtomicOr: return "OpAtomicOr"; + case SpvOpAtomicXor: return "OpAtomicXor"; + case SpvOpPhi: return "OpPhi"; + case SpvOpLoopMerge: return "OpLoopMerge"; + case SpvOpSelectionMerge: return "OpSelectionMerge"; + case SpvOpLabel: return "OpLabel"; + case SpvOpBranch: return "OpBranch"; + case SpvOpBranchConditional: return "OpBranchConditional"; + case SpvOpSwitch: return "OpSwitch"; + case SpvOpKill: return "OpKill"; + case SpvOpReturn: return "OpReturn"; + case SpvOpReturnValue: return "OpReturnValue"; + case SpvOpUnreachable: return "OpUnreachable"; + case SpvOpLifetimeStart: return "OpLifetimeStart"; + case SpvOpLifetimeStop: return "OpLifetimeStop"; + case SpvOpGroupAsyncCopy: return "OpGroupAsyncCopy"; + case SpvOpGroupWaitEvents: return "OpGroupWaitEvents"; + case SpvOpGroupAll: return "OpGroupAll"; + case SpvOpGroupAny: return "OpGroupAny"; + case SpvOpGroupBroadcast: return "OpGroupBroadcast"; + case SpvOpGroupIAdd: return "OpGroupIAdd"; + case SpvOpGroupFAdd: return "OpGroupFAdd"; + case SpvOpGroupFMin: return "OpGroupFMin"; + case SpvOpGroupUMin: return "OpGroupUMin"; + case SpvOpGroupSMin: return "OpGroupSMin"; + case SpvOpGroupFMax: return "OpGroupFMax"; + case SpvOpGroupUMax: return "OpGroupUMax"; + case SpvOpGroupSMax: return "OpGroupSMax"; + case SpvOpReadPipe: return "OpReadPipe"; + case SpvOpWritePipe: return "OpWritePipe"; + case SpvOpReservedReadPipe: return "OpReservedReadPipe"; + case SpvOpReservedWritePipe: return "OpReservedWritePipe"; + case SpvOpReserveReadPipePackets: return "OpReserveReadPipePackets"; + case SpvOpReserveWritePipePackets: return "OpReserveWritePipePackets"; + case SpvOpCommitReadPipe: return "OpCommitReadPipe"; + case SpvOpCommitWritePipe: return "OpCommitWritePipe"; + case SpvOpIsValidReserveId: return "OpIsValidReserveId"; + case SpvOpGetNumPipePackets: return "OpGetNumPipePackets"; + case SpvOpGetMaxPipePackets: return "OpGetMaxPipePackets"; + case SpvOpGroupReserveReadPipePackets: return "OpGroupReserveReadPipePackets"; + case SpvOpGroupReserveWritePipePackets: return "OpGroupReserveWritePipePackets"; + case SpvOpGroupCommitReadPipe: return "OpGroupCommitReadPipe"; + case SpvOpGroupCommitWritePipe: return "OpGroupCommitWritePipe"; + case SpvOpEnqueueMarker: return "OpEnqueueMarker"; + case SpvOpEnqueueKernel: return "OpEnqueueKernel"; + case SpvOpGetKernelNDrangeSubGroupCount: return "OpGetKernelNDrangeSubGroupCount"; + case SpvOpGetKernelNDrangeMaxSubGroupSize: return "OpGetKernelNDrangeMaxSubGroupSize"; + case SpvOpGetKernelWorkGroupSize: return "OpGetKernelWorkGroupSize"; + case SpvOpGetKernelPreferredWorkGroupSizeMultiple: return "OpGetKernelPreferredWorkGroupSizeMultiple"; + case SpvOpRetainEvent: return "OpRetainEvent"; + case SpvOpReleaseEvent: return "OpReleaseEvent"; + case SpvOpCreateUserEvent: return "OpCreateUserEvent"; + case SpvOpIsValidEvent: return "OpIsValidEvent"; + case SpvOpSetUserEventStatus: return "OpSetUserEventStatus"; + case SpvOpCaptureEventProfilingInfo: return "OpCaptureEventProfilingInfo"; + case SpvOpGetDefaultQueue: return "OpGetDefaultQueue"; + case SpvOpBuildNDRange: return "OpBuildNDRange"; + case SpvOpImageSparseSampleImplicitLod: return "OpImageSparseSampleImplicitLod"; + case SpvOpImageSparseSampleExplicitLod: return "OpImageSparseSampleExplicitLod"; + case SpvOpImageSparseSampleDrefImplicitLod: return "OpImageSparseSampleDrefImplicitLod"; + case SpvOpImageSparseSampleDrefExplicitLod: return "OpImageSparseSampleDrefExplicitLod"; + case SpvOpImageSparseSampleProjImplicitLod: return "OpImageSparseSampleProjImplicitLod"; + case SpvOpImageSparseSampleProjExplicitLod: return "OpImageSparseSampleProjExplicitLod"; + case SpvOpImageSparseSampleProjDrefImplicitLod: return "OpImageSparseSampleProjDrefImplicitLod"; + case SpvOpImageSparseSampleProjDrefExplicitLod: return "OpImageSparseSampleProjDrefExplicitLod"; + case SpvOpImageSparseFetch: return "OpImageSparseFetch"; + case SpvOpImageSparseGather: return "OpImageSparseGather"; + case SpvOpImageSparseDrefGather: return "OpImageSparseDrefGather"; + case SpvOpImageSparseTexelsResident: return "OpImageSparseTexelsResident"; + case SpvOpNoLine: return "OpNoLine"; + case SpvOpAtomicFlagTestAndSet: return "OpAtomicFlagTestAndSet"; + case SpvOpAtomicFlagClear: return "OpAtomicFlagClear"; + case SpvOpImageSparseRead: return "OpImageSparseRead"; + case SpvOpSizeOf: return "OpSizeOf"; + case SpvOpTypePipeStorage: return "OpTypePipeStorage"; + case SpvOpConstantPipeStorage: return "OpConstantPipeStorage"; + case SpvOpCreatePipeFromPipeStorage: return "OpCreatePipeFromPipeStorage"; + case SpvOpGetKernelLocalSizeForSubgroupCount: return "OpGetKernelLocalSizeForSubgroupCount"; + case SpvOpGetKernelMaxNumSubgroups: return "OpGetKernelMaxNumSubgroups"; + case SpvOpTypeNamedBarrier: return "OpTypeNamedBarrier"; + case SpvOpNamedBarrierInitialize: return "OpNamedBarrierInitialize"; + case SpvOpMemoryNamedBarrier: return "OpMemoryNamedBarrier"; + case SpvOpModuleProcessed: return "OpModuleProcessed"; + case SpvOpExecutionModeId: return "OpExecutionModeId"; + case SpvOpDecorateId: return "OpDecorateId"; + case SpvOpGroupNonUniformElect: return "OpGroupNonUniformElect"; + case SpvOpGroupNonUniformAll: return "OpGroupNonUniformAll"; + case SpvOpGroupNonUniformAny: return "OpGroupNonUniformAny"; + case SpvOpGroupNonUniformAllEqual: return "OpGroupNonUniformAllEqual"; + case SpvOpGroupNonUniformBroadcast: return "OpGroupNonUniformBroadcast"; + case SpvOpGroupNonUniformBroadcastFirst: return "OpGroupNonUniformBroadcastFirst"; + case SpvOpGroupNonUniformBallot: return "OpGroupNonUniformBallot"; + case SpvOpGroupNonUniformInverseBallot: return "OpGroupNonUniformInverseBallot"; + case SpvOpGroupNonUniformBallotBitExtract: return "OpGroupNonUniformBallotBitExtract"; + case SpvOpGroupNonUniformBallotBitCount: return "OpGroupNonUniformBallotBitCount"; + case SpvOpGroupNonUniformBallotFindLSB: return "OpGroupNonUniformBallotFindLSB"; + case SpvOpGroupNonUniformBallotFindMSB: return "OpGroupNonUniformBallotFindMSB"; + case SpvOpGroupNonUniformShuffle: return "OpGroupNonUniformShuffle"; + case SpvOpGroupNonUniformShuffleXor: return "OpGroupNonUniformShuffleXor"; + case SpvOpGroupNonUniformShuffleUp: return "OpGroupNonUniformShuffleUp"; + case SpvOpGroupNonUniformShuffleDown: return "OpGroupNonUniformShuffleDown"; + case SpvOpGroupNonUniformIAdd: return "OpGroupNonUniformIAdd"; + case SpvOpGroupNonUniformFAdd: return "OpGroupNonUniformFAdd"; + case SpvOpGroupNonUniformIMul: return "OpGroupNonUniformIMul"; + case SpvOpGroupNonUniformFMul: return "OpGroupNonUniformFMul"; + case SpvOpGroupNonUniformSMin: return "OpGroupNonUniformSMin"; + case SpvOpGroupNonUniformUMin: return "OpGroupNonUniformUMin"; + case SpvOpGroupNonUniformFMin: return "OpGroupNonUniformFMin"; + case SpvOpGroupNonUniformSMax: return "OpGroupNonUniformSMax"; + case SpvOpGroupNonUniformUMax: return "OpGroupNonUniformUMax"; + case SpvOpGroupNonUniformFMax: return "OpGroupNonUniformFMax"; + case SpvOpGroupNonUniformBitwiseAnd: return "OpGroupNonUniformBitwiseAnd"; + case SpvOpGroupNonUniformBitwiseOr: return "OpGroupNonUniformBitwiseOr"; + case SpvOpGroupNonUniformBitwiseXor: return "OpGroupNonUniformBitwiseXor"; + case SpvOpGroupNonUniformLogicalAnd: return "OpGroupNonUniformLogicalAnd"; + case SpvOpGroupNonUniformLogicalOr: return "OpGroupNonUniformLogicalOr"; + case SpvOpGroupNonUniformLogicalXor: return "OpGroupNonUniformLogicalXor"; + case SpvOpGroupNonUniformQuadBroadcast: return "OpGroupNonUniformQuadBroadcast"; + case SpvOpGroupNonUniformQuadSwap: return "OpGroupNonUniformQuadSwap"; + case SpvOpCopyLogical: return "OpCopyLogical"; + case SpvOpPtrEqual: return "OpPtrEqual"; + case SpvOpPtrNotEqual: return "OpPtrNotEqual"; + case SpvOpPtrDiff: return "OpPtrDiff"; + case SpvOpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT"; + case SpvOpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT"; + case SpvOpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT"; + case SpvOpTerminateInvocation: return "OpTerminateInvocation"; + case SpvOpSubgroupBallotKHR: return "OpSubgroupBallotKHR"; + case SpvOpSubgroupFirstInvocationKHR: return "OpSubgroupFirstInvocationKHR"; + case SpvOpSubgroupAllKHR: return "OpSubgroupAllKHR"; + case SpvOpSubgroupAnyKHR: return "OpSubgroupAnyKHR"; + case SpvOpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR"; + case SpvOpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR"; + case SpvOpSubgroupReadInvocationKHR: return "OpSubgroupReadInvocationKHR"; + case SpvOpExtInstWithForwardRefsKHR: return "OpExtInstWithForwardRefsKHR"; + case SpvOpTraceRayKHR: return "OpTraceRayKHR"; + case SpvOpExecuteCallableKHR: return "OpExecuteCallableKHR"; + case SpvOpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR"; + case SpvOpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case SpvOpTerminateRayKHR: return "OpTerminateRayKHR"; + case SpvOpSDot: return "OpSDot"; + case SpvOpUDot: return "OpUDot"; + case SpvOpSUDot: return "OpSUDot"; + case SpvOpSDotAccSat: return "OpSDotAccSat"; + case SpvOpUDotAccSat: return "OpUDotAccSat"; + case SpvOpSUDotAccSat: return "OpSUDotAccSat"; + case SpvOpTypeCooperativeMatrixKHR: return "OpTypeCooperativeMatrixKHR"; + case SpvOpCooperativeMatrixLoadKHR: return "OpCooperativeMatrixLoadKHR"; + case SpvOpCooperativeMatrixStoreKHR: return "OpCooperativeMatrixStoreKHR"; + case SpvOpCooperativeMatrixMulAddKHR: return "OpCooperativeMatrixMulAddKHR"; + case SpvOpCooperativeMatrixLengthKHR: return "OpCooperativeMatrixLengthKHR"; + case SpvOpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT"; + case SpvOpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT"; + case SpvOpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT"; + case SpvOpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; + case SpvOpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case SpvOpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case SpvOpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case SpvOpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case SpvOpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case SpvOpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case SpvOpImageSampleWeightedQCOM: return "OpImageSampleWeightedQCOM"; + case SpvOpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; + case SpvOpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + case SpvOpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; + case SpvOpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM"; + case SpvOpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM"; + case SpvOpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; + case SpvOpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; + case SpvOpGroupIAddNonUniformAMD: return "OpGroupIAddNonUniformAMD"; + case SpvOpGroupFAddNonUniformAMD: return "OpGroupFAddNonUniformAMD"; + case SpvOpGroupFMinNonUniformAMD: return "OpGroupFMinNonUniformAMD"; + case SpvOpGroupUMinNonUniformAMD: return "OpGroupUMinNonUniformAMD"; + case SpvOpGroupSMinNonUniformAMD: return "OpGroupSMinNonUniformAMD"; + case SpvOpGroupFMaxNonUniformAMD: return "OpGroupFMaxNonUniformAMD"; + case SpvOpGroupUMaxNonUniformAMD: return "OpGroupUMaxNonUniformAMD"; + case SpvOpGroupSMaxNonUniformAMD: return "OpGroupSMaxNonUniformAMD"; + case SpvOpFragmentMaskFetchAMD: return "OpFragmentMaskFetchAMD"; + case SpvOpFragmentFetchAMD: return "OpFragmentFetchAMD"; + case SpvOpReadClockKHR: return "OpReadClockKHR"; + case SpvOpFinalizeNodePayloadsAMDX: return "OpFinalizeNodePayloadsAMDX"; + case SpvOpFinishWritingNodePayloadAMDX: return "OpFinishWritingNodePayloadAMDX"; + case SpvOpInitializeNodePayloadsAMDX: return "OpInitializeNodePayloadsAMDX"; + case SpvOpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; + case SpvOpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; + case SpvOpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; + case SpvOpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; + case SpvOpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; + case SpvOpHitObjectGetWorldToObjectNV: return "OpHitObjectGetWorldToObjectNV"; + case SpvOpHitObjectGetObjectToWorldNV: return "OpHitObjectGetObjectToWorldNV"; + case SpvOpHitObjectGetObjectRayDirectionNV: return "OpHitObjectGetObjectRayDirectionNV"; + case SpvOpHitObjectGetObjectRayOriginNV: return "OpHitObjectGetObjectRayOriginNV"; + case SpvOpHitObjectTraceRayMotionNV: return "OpHitObjectTraceRayMotionNV"; + case SpvOpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV"; + case SpvOpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV"; + case SpvOpHitObjectRecordEmptyNV: return "OpHitObjectRecordEmptyNV"; + case SpvOpHitObjectTraceRayNV: return "OpHitObjectTraceRayNV"; + case SpvOpHitObjectRecordHitNV: return "OpHitObjectRecordHitNV"; + case SpvOpHitObjectRecordHitWithIndexNV: return "OpHitObjectRecordHitWithIndexNV"; + case SpvOpHitObjectRecordMissNV: return "OpHitObjectRecordMissNV"; + case SpvOpHitObjectExecuteShaderNV: return "OpHitObjectExecuteShaderNV"; + case SpvOpHitObjectGetCurrentTimeNV: return "OpHitObjectGetCurrentTimeNV"; + case SpvOpHitObjectGetAttributesNV: return "OpHitObjectGetAttributesNV"; + case SpvOpHitObjectGetHitKindNV: return "OpHitObjectGetHitKindNV"; + case SpvOpHitObjectGetPrimitiveIndexNV: return "OpHitObjectGetPrimitiveIndexNV"; + case SpvOpHitObjectGetGeometryIndexNV: return "OpHitObjectGetGeometryIndexNV"; + case SpvOpHitObjectGetInstanceIdNV: return "OpHitObjectGetInstanceIdNV"; + case SpvOpHitObjectGetInstanceCustomIndexNV: return "OpHitObjectGetInstanceCustomIndexNV"; + case SpvOpHitObjectGetWorldRayDirectionNV: return "OpHitObjectGetWorldRayDirectionNV"; + case SpvOpHitObjectGetWorldRayOriginNV: return "OpHitObjectGetWorldRayOriginNV"; + case SpvOpHitObjectGetRayTMaxNV: return "OpHitObjectGetRayTMaxNV"; + case SpvOpHitObjectGetRayTMinNV: return "OpHitObjectGetRayTMinNV"; + case SpvOpHitObjectIsEmptyNV: return "OpHitObjectIsEmptyNV"; + case SpvOpHitObjectIsHitNV: return "OpHitObjectIsHitNV"; + case SpvOpHitObjectIsMissNV: return "OpHitObjectIsMissNV"; + case SpvOpReorderThreadWithHitObjectNV: return "OpReorderThreadWithHitObjectNV"; + case SpvOpReorderThreadWithHintNV: return "OpReorderThreadWithHintNV"; + case SpvOpTypeHitObjectNV: return "OpTypeHitObjectNV"; + case SpvOpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; + case SpvOpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT"; + case SpvOpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT"; + case SpvOpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; + case SpvOpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case SpvOpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV"; + case SpvOpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV"; + case SpvOpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case SpvOpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case SpvOpTerminateRayNV: return "OpTerminateRayNV"; + case SpvOpTraceNV: return "OpTraceNV"; + case SpvOpTraceMotionNV: return "OpTraceMotionNV"; + case SpvOpTraceRayMotionNV: return "OpTraceRayMotionNV"; + case SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR: return "OpRayQueryGetIntersectionTriangleVertexPositionsKHR"; + case SpvOpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case SpvOpExecuteCallableNV: return "OpExecuteCallableNV"; + case SpvOpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case SpvOpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case SpvOpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case SpvOpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case SpvOpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case SpvOpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case SpvOpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + case SpvOpDemoteToHelperInvocation: return "OpDemoteToHelperInvocation"; + case SpvOpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + case SpvOpConvertUToImageNV: return "OpConvertUToImageNV"; + case SpvOpConvertUToSamplerNV: return "OpConvertUToSamplerNV"; + case SpvOpConvertImageToUNV: return "OpConvertImageToUNV"; + case SpvOpConvertSamplerToUNV: return "OpConvertSamplerToUNV"; + case SpvOpConvertUToSampledImageNV: return "OpConvertUToSampledImageNV"; + case SpvOpConvertSampledImageToUNV: return "OpConvertSampledImageToUNV"; + case SpvOpSamplerImageAddressingModeNV: return "OpSamplerImageAddressingModeNV"; + case SpvOpRawAccessChainNV: return "OpRawAccessChainNV"; + case SpvOpSubgroupShuffleINTEL: return "OpSubgroupShuffleINTEL"; + case SpvOpSubgroupShuffleDownINTEL: return "OpSubgroupShuffleDownINTEL"; + case SpvOpSubgroupShuffleUpINTEL: return "OpSubgroupShuffleUpINTEL"; + case SpvOpSubgroupShuffleXorINTEL: return "OpSubgroupShuffleXorINTEL"; + case SpvOpSubgroupBlockReadINTEL: return "OpSubgroupBlockReadINTEL"; + case SpvOpSubgroupBlockWriteINTEL: return "OpSubgroupBlockWriteINTEL"; + case SpvOpSubgroupImageBlockReadINTEL: return "OpSubgroupImageBlockReadINTEL"; + case SpvOpSubgroupImageBlockWriteINTEL: return "OpSubgroupImageBlockWriteINTEL"; + case SpvOpSubgroupImageMediaBlockReadINTEL: return "OpSubgroupImageMediaBlockReadINTEL"; + case SpvOpSubgroupImageMediaBlockWriteINTEL: return "OpSubgroupImageMediaBlockWriteINTEL"; + case SpvOpUCountLeadingZerosINTEL: return "OpUCountLeadingZerosINTEL"; + case SpvOpUCountTrailingZerosINTEL: return "OpUCountTrailingZerosINTEL"; + case SpvOpAbsISubINTEL: return "OpAbsISubINTEL"; + case SpvOpAbsUSubINTEL: return "OpAbsUSubINTEL"; + case SpvOpIAddSatINTEL: return "OpIAddSatINTEL"; + case SpvOpUAddSatINTEL: return "OpUAddSatINTEL"; + case SpvOpIAverageINTEL: return "OpIAverageINTEL"; + case SpvOpUAverageINTEL: return "OpUAverageINTEL"; + case SpvOpIAverageRoundedINTEL: return "OpIAverageRoundedINTEL"; + case SpvOpUAverageRoundedINTEL: return "OpUAverageRoundedINTEL"; + case SpvOpISubSatINTEL: return "OpISubSatINTEL"; + case SpvOpUSubSatINTEL: return "OpUSubSatINTEL"; + case SpvOpIMul32x16INTEL: return "OpIMul32x16INTEL"; + case SpvOpUMul32x16INTEL: return "OpUMul32x16INTEL"; + case SpvOpConstantFunctionPointerINTEL: return "OpConstantFunctionPointerINTEL"; + case SpvOpFunctionPointerCallINTEL: return "OpFunctionPointerCallINTEL"; + case SpvOpAsmTargetINTEL: return "OpAsmTargetINTEL"; + case SpvOpAsmINTEL: return "OpAsmINTEL"; + case SpvOpAsmCallINTEL: return "OpAsmCallINTEL"; + case SpvOpAtomicFMinEXT: return "OpAtomicFMinEXT"; + case SpvOpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; + case SpvOpAssumeTrueKHR: return "OpAssumeTrueKHR"; + case SpvOpExpectKHR: return "OpExpectKHR"; + case SpvOpDecorateString: return "OpDecorateString"; + case SpvOpMemberDecorateString: return "OpMemberDecorateString"; + case SpvOpVmeImageINTEL: return "OpVmeImageINTEL"; + case SpvOpTypeVmeImageINTEL: return "OpTypeVmeImageINTEL"; + case SpvOpTypeAvcImePayloadINTEL: return "OpTypeAvcImePayloadINTEL"; + case SpvOpTypeAvcRefPayloadINTEL: return "OpTypeAvcRefPayloadINTEL"; + case SpvOpTypeAvcSicPayloadINTEL: return "OpTypeAvcSicPayloadINTEL"; + case SpvOpTypeAvcMcePayloadINTEL: return "OpTypeAvcMcePayloadINTEL"; + case SpvOpTypeAvcMceResultINTEL: return "OpTypeAvcMceResultINTEL"; + case SpvOpTypeAvcImeResultINTEL: return "OpTypeAvcImeResultINTEL"; + case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: return "OpTypeAvcImeResultSingleReferenceStreamoutINTEL"; + case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: return "OpTypeAvcImeResultDualReferenceStreamoutINTEL"; + case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: return "OpTypeAvcImeSingleReferenceStreaminINTEL"; + case SpvOpTypeAvcImeDualReferenceStreaminINTEL: return "OpTypeAvcImeDualReferenceStreaminINTEL"; + case SpvOpTypeAvcRefResultINTEL: return "OpTypeAvcRefResultINTEL"; + case SpvOpTypeAvcSicResultINTEL: return "OpTypeAvcSicResultINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL"; + case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL"; + case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: return "OpSubgroupAvcMceSetInterShapePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL"; + case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: return "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL"; + case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL"; + case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL"; + case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL"; + case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: return "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL"; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL"; + case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: return "OpSubgroupAvcMceSetAcOnlyHaarINTEL"; + case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL"; + case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL"; + case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL"; + case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: return "OpSubgroupAvcMceConvertToImePayloadINTEL"; + case SpvOpSubgroupAvcMceConvertToImeResultINTEL: return "OpSubgroupAvcMceConvertToImeResultINTEL"; + case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: return "OpSubgroupAvcMceConvertToRefPayloadINTEL"; + case SpvOpSubgroupAvcMceConvertToRefResultINTEL: return "OpSubgroupAvcMceConvertToRefResultINTEL"; + case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: return "OpSubgroupAvcMceConvertToSicPayloadINTEL"; + case SpvOpSubgroupAvcMceConvertToSicResultINTEL: return "OpSubgroupAvcMceConvertToSicResultINTEL"; + case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: return "OpSubgroupAvcMceGetMotionVectorsINTEL"; + case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: return "OpSubgroupAvcMceGetInterDistortionsINTEL"; + case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: return "OpSubgroupAvcMceGetBestInterDistortionsINTEL"; + case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: return "OpSubgroupAvcMceGetInterMajorShapeINTEL"; + case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: return "OpSubgroupAvcMceGetInterMinorShapeINTEL"; + case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: return "OpSubgroupAvcMceGetInterDirectionsINTEL"; + case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: return "OpSubgroupAvcMceGetInterMotionVectorCountINTEL"; + case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: return "OpSubgroupAvcMceGetInterReferenceIdsINTEL"; + case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL"; + case SpvOpSubgroupAvcImeInitializeINTEL: return "OpSubgroupAvcImeInitializeINTEL"; + case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: return "OpSubgroupAvcImeSetSingleReferenceINTEL"; + case SpvOpSubgroupAvcImeSetDualReferenceINTEL: return "OpSubgroupAvcImeSetDualReferenceINTEL"; + case SpvOpSubgroupAvcImeRefWindowSizeINTEL: return "OpSubgroupAvcImeRefWindowSizeINTEL"; + case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: return "OpSubgroupAvcImeAdjustRefOffsetINTEL"; + case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: return "OpSubgroupAvcImeConvertToMcePayloadINTEL"; + case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: return "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL"; + case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: return "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL"; + case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: return "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL"; + case SpvOpSubgroupAvcImeSetWeightedSadINTEL: return "OpSubgroupAvcImeSetWeightedSadINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL"; + case SpvOpSubgroupAvcImeConvertToMceResultINTEL: return "OpSubgroupAvcImeConvertToMceResultINTEL"; + case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: return "OpSubgroupAvcImeGetDualReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL"; + case SpvOpSubgroupAvcImeGetBorderReachedINTEL: return "OpSubgroupAvcImeGetBorderReachedINTEL"; + case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: return "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL"; + case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: return "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL"; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL"; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL"; + case SpvOpSubgroupAvcFmeInitializeINTEL: return "OpSubgroupAvcFmeInitializeINTEL"; + case SpvOpSubgroupAvcBmeInitializeINTEL: return "OpSubgroupAvcBmeInitializeINTEL"; + case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: return "OpSubgroupAvcRefConvertToMcePayloadINTEL"; + case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: return "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL"; + case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: return "OpSubgroupAvcRefSetBilinearFilterEnableINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL"; + case SpvOpSubgroupAvcRefConvertToMceResultINTEL: return "OpSubgroupAvcRefConvertToMceResultINTEL"; + case SpvOpSubgroupAvcSicInitializeINTEL: return "OpSubgroupAvcSicInitializeINTEL"; + case SpvOpSubgroupAvcSicConfigureSkcINTEL: return "OpSubgroupAvcSicConfigureSkcINTEL"; + case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaINTEL"; + case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL"; + case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: return "OpSubgroupAvcSicGetMotionVectorMaskINTEL"; + case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: return "OpSubgroupAvcSicConvertToMcePayloadINTEL"; + case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL"; + case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL"; + case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL"; + case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: return "OpSubgroupAvcSicSetBilinearFilterEnableINTEL"; + case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: return "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL"; + case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: return "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL"; + case SpvOpSubgroupAvcSicEvaluateIpeINTEL: return "OpSubgroupAvcSicEvaluateIpeINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL"; + case SpvOpSubgroupAvcSicConvertToMceResultINTEL: return "OpSubgroupAvcSicConvertToMceResultINTEL"; + case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: return "OpSubgroupAvcSicGetIpeLumaShapeINTEL"; + case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL"; + case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL"; + case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: return "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL"; + case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: return "OpSubgroupAvcSicGetIpeChromaModeINTEL"; + case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL"; + case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL"; + case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: return "OpSubgroupAvcSicGetInterRawSadsINTEL"; + case SpvOpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL"; + case SpvOpSaveMemoryINTEL: return "OpSaveMemoryINTEL"; + case SpvOpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL"; + case SpvOpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL"; + case SpvOpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL"; + case SpvOpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL"; + case SpvOpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL"; + case SpvOpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL"; + case SpvOpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL"; + case SpvOpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL"; + case SpvOpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL"; + case SpvOpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL"; + case SpvOpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL"; + case SpvOpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL"; + case SpvOpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL"; + case SpvOpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL"; + case SpvOpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL"; + case SpvOpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL"; + case SpvOpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL"; + case SpvOpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL"; + case SpvOpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL"; + case SpvOpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL"; + case SpvOpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL"; + case SpvOpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL"; + case SpvOpArbitraryFloatLog1pINTEL: return "OpArbitraryFloatLog1pINTEL"; + case SpvOpArbitraryFloatExpINTEL: return "OpArbitraryFloatExpINTEL"; + case SpvOpArbitraryFloatExp2INTEL: return "OpArbitraryFloatExp2INTEL"; + case SpvOpArbitraryFloatExp10INTEL: return "OpArbitraryFloatExp10INTEL"; + case SpvOpArbitraryFloatExpm1INTEL: return "OpArbitraryFloatExpm1INTEL"; + case SpvOpArbitraryFloatSinINTEL: return "OpArbitraryFloatSinINTEL"; + case SpvOpArbitraryFloatCosINTEL: return "OpArbitraryFloatCosINTEL"; + case SpvOpArbitraryFloatSinCosINTEL: return "OpArbitraryFloatSinCosINTEL"; + case SpvOpArbitraryFloatSinPiINTEL: return "OpArbitraryFloatSinPiINTEL"; + case SpvOpArbitraryFloatCosPiINTEL: return "OpArbitraryFloatCosPiINTEL"; + case SpvOpArbitraryFloatASinINTEL: return "OpArbitraryFloatASinINTEL"; + case SpvOpArbitraryFloatASinPiINTEL: return "OpArbitraryFloatASinPiINTEL"; + case SpvOpArbitraryFloatACosINTEL: return "OpArbitraryFloatACosINTEL"; + case SpvOpArbitraryFloatACosPiINTEL: return "OpArbitraryFloatACosPiINTEL"; + case SpvOpArbitraryFloatATanINTEL: return "OpArbitraryFloatATanINTEL"; + case SpvOpArbitraryFloatATanPiINTEL: return "OpArbitraryFloatATanPiINTEL"; + case SpvOpArbitraryFloatATan2INTEL: return "OpArbitraryFloatATan2INTEL"; + case SpvOpArbitraryFloatPowINTEL: return "OpArbitraryFloatPowINTEL"; + case SpvOpArbitraryFloatPowRINTEL: return "OpArbitraryFloatPowRINTEL"; + case SpvOpArbitraryFloatPowNINTEL: return "OpArbitraryFloatPowNINTEL"; + case SpvOpLoopControlINTEL: return "OpLoopControlINTEL"; + case SpvOpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL"; + case SpvOpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL"; + case SpvOpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL"; + case SpvOpFixedSqrtINTEL: return "OpFixedSqrtINTEL"; + case SpvOpFixedRecipINTEL: return "OpFixedRecipINTEL"; + case SpvOpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL"; + case SpvOpFixedSinINTEL: return "OpFixedSinINTEL"; + case SpvOpFixedCosINTEL: return "OpFixedCosINTEL"; + case SpvOpFixedSinCosINTEL: return "OpFixedSinCosINTEL"; + case SpvOpFixedSinPiINTEL: return "OpFixedSinPiINTEL"; + case SpvOpFixedCosPiINTEL: return "OpFixedCosPiINTEL"; + case SpvOpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL"; + case SpvOpFixedLogINTEL: return "OpFixedLogINTEL"; + case SpvOpFixedExpINTEL: return "OpFixedExpINTEL"; + case SpvOpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL"; + case SpvOpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL"; + case SpvOpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL"; + case SpvOpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL"; + case SpvOpFPGARegINTEL: return "OpFPGARegINTEL"; + case SpvOpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case SpvOpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case SpvOpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case SpvOpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case SpvOpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case SpvOpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case SpvOpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case SpvOpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case SpvOpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case SpvOpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case SpvOpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case SpvOpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case SpvOpTypeBufferSurfaceINTEL: return "OpTypeBufferSurfaceINTEL"; + case SpvOpTypeStructContinuedINTEL: return "OpTypeStructContinuedINTEL"; + case SpvOpConstantCompositeContinuedINTEL: return "OpConstantCompositeContinuedINTEL"; + case SpvOpSpecConstantCompositeContinuedINTEL: return "OpSpecConstantCompositeContinuedINTEL"; + case SpvOpCompositeConstructContinuedINTEL: return "OpCompositeConstructContinuedINTEL"; + case SpvOpConvertFToBF16INTEL: return "OpConvertFToBF16INTEL"; + case SpvOpConvertBF16ToFINTEL: return "OpConvertBF16ToFINTEL"; + case SpvOpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL"; + case SpvOpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL"; + case SpvOpGroupIMulKHR: return "OpGroupIMulKHR"; + case SpvOpGroupFMulKHR: return "OpGroupFMulKHR"; + case SpvOpGroupBitwiseAndKHR: return "OpGroupBitwiseAndKHR"; + case SpvOpGroupBitwiseOrKHR: return "OpGroupBitwiseOrKHR"; + case SpvOpGroupBitwiseXorKHR: return "OpGroupBitwiseXorKHR"; + case SpvOpGroupLogicalAndKHR: return "OpGroupLogicalAndKHR"; + case SpvOpGroupLogicalOrKHR: return "OpGroupLogicalOrKHR"; + case SpvOpGroupLogicalXorKHR: return "OpGroupLogicalXorKHR"; + case SpvOpMaskedGatherINTEL: return "OpMaskedGatherINTEL"; + case SpvOpMaskedScatterINTEL: return "OpMaskedScatterINTEL"; + default: return "Unknown"; + } +} + +#endif /* SPV_ENABLE_UTILITY_CODE */ + +#endif + diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.hpp b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.hpp new file mode 100644 index 0000000..2ebc387 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.hpp @@ -0,0 +1,4736 @@ +// 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, + CapabilityCooperativeMatrixLayoutsARM = 4201, + 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, + CapabilityRawAccessChainsNV = 5414, + 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, + CapabilityReplicatedCompositesEXT = 6024, + 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, + CooperativeMatrixLayoutRowBlockedInterleavedARM = 4202, + CooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203, + 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 RawAccessChainOperandsShift { + RawAccessChainOperandsRobustnessPerComponentNVShift = 0, + RawAccessChainOperandsRobustnessPerElementNVShift = 1, + RawAccessChainOperandsMax = 0x7fffffff, +}; + +enum RawAccessChainOperandsMask { + RawAccessChainOperandsMaskNone = 0, + RawAccessChainOperandsRobustnessPerComponentNVMask = 0x00000001, + RawAccessChainOperandsRobustnessPerElementNVMask = 0x00000002, +}; + +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, + OpExtInstWithForwardRefsKHR = 4433, + 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, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + 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, + OpRawAccessChainNV = 5398, + 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 OpExtInstWithForwardRefsKHR: *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 OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case OpCompositeConstructReplicateEXT: *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 OpReportIntersectionKHR: *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 OpTypeAccelerationStructureKHR: *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 OpRawAccessChainNV: *hasResult = true; *hasResultType = true; 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; + } +} +inline const char* SourceLanguageToString(SourceLanguage value) { + switch (value) { + case SourceLanguageUnknown: return "Unknown"; + case SourceLanguageESSL: return "ESSL"; + case SourceLanguageGLSL: return "GLSL"; + case SourceLanguageOpenCL_C: return "OpenCL_C"; + case SourceLanguageOpenCL_CPP: return "OpenCL_CPP"; + case SourceLanguageHLSL: return "HLSL"; + case SourceLanguageCPP_for_OpenCL: return "CPP_for_OpenCL"; + case SourceLanguageSYCL: return "SYCL"; + case SourceLanguageHERO_C: return "HERO_C"; + case SourceLanguageNZSL: return "NZSL"; + case SourceLanguageWGSL: return "WGSL"; + case SourceLanguageSlang: return "Slang"; + case SourceLanguageZig: return "Zig"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModelToString(ExecutionModel value) { + switch (value) { + case ExecutionModelVertex: return "Vertex"; + case ExecutionModelTessellationControl: return "TessellationControl"; + case ExecutionModelTessellationEvaluation: return "TessellationEvaluation"; + case ExecutionModelGeometry: return "Geometry"; + case ExecutionModelFragment: return "Fragment"; + case ExecutionModelGLCompute: return "GLCompute"; + case ExecutionModelKernel: return "Kernel"; + case ExecutionModelTaskNV: return "TaskNV"; + case ExecutionModelMeshNV: return "MeshNV"; + case ExecutionModelRayGenerationKHR: return "RayGenerationKHR"; + case ExecutionModelIntersectionKHR: return "IntersectionKHR"; + case ExecutionModelAnyHitKHR: return "AnyHitKHR"; + case ExecutionModelClosestHitKHR: return "ClosestHitKHR"; + case ExecutionModelMissKHR: return "MissKHR"; + case ExecutionModelCallableKHR: return "CallableKHR"; + case ExecutionModelTaskEXT: return "TaskEXT"; + case ExecutionModelMeshEXT: return "MeshEXT"; + default: return "Unknown"; + } +} + +inline const char* AddressingModelToString(AddressingModel value) { + switch (value) { + case AddressingModelLogical: return "Logical"; + case AddressingModelPhysical32: return "Physical32"; + case AddressingModelPhysical64: return "Physical64"; + case AddressingModelPhysicalStorageBuffer64: return "PhysicalStorageBuffer64"; + default: return "Unknown"; + } +} + +inline const char* MemoryModelToString(MemoryModel value) { + switch (value) { + case MemoryModelSimple: return "Simple"; + case MemoryModelGLSL450: return "GLSL450"; + case MemoryModelOpenCL: return "OpenCL"; + case MemoryModelVulkan: return "Vulkan"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModeToString(ExecutionMode value) { + switch (value) { + case ExecutionModeInvocations: return "Invocations"; + case ExecutionModeSpacingEqual: return "SpacingEqual"; + case ExecutionModeSpacingFractionalEven: return "SpacingFractionalEven"; + case ExecutionModeSpacingFractionalOdd: return "SpacingFractionalOdd"; + case ExecutionModeVertexOrderCw: return "VertexOrderCw"; + case ExecutionModeVertexOrderCcw: return "VertexOrderCcw"; + case ExecutionModePixelCenterInteger: return "PixelCenterInteger"; + case ExecutionModeOriginUpperLeft: return "OriginUpperLeft"; + case ExecutionModeOriginLowerLeft: return "OriginLowerLeft"; + case ExecutionModeEarlyFragmentTests: return "EarlyFragmentTests"; + case ExecutionModePointMode: return "PointMode"; + case ExecutionModeXfb: return "Xfb"; + case ExecutionModeDepthReplacing: return "DepthReplacing"; + case ExecutionModeDepthGreater: return "DepthGreater"; + case ExecutionModeDepthLess: return "DepthLess"; + case ExecutionModeDepthUnchanged: return "DepthUnchanged"; + case ExecutionModeLocalSize: return "LocalSize"; + case ExecutionModeLocalSizeHint: return "LocalSizeHint"; + case ExecutionModeInputPoints: return "InputPoints"; + case ExecutionModeInputLines: return "InputLines"; + case ExecutionModeInputLinesAdjacency: return "InputLinesAdjacency"; + case ExecutionModeTriangles: return "Triangles"; + case ExecutionModeInputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case ExecutionModeQuads: return "Quads"; + case ExecutionModeIsolines: return "Isolines"; + case ExecutionModeOutputVertices: return "OutputVertices"; + case ExecutionModeOutputPoints: return "OutputPoints"; + case ExecutionModeOutputLineStrip: return "OutputLineStrip"; + case ExecutionModeOutputTriangleStrip: return "OutputTriangleStrip"; + case ExecutionModeVecTypeHint: return "VecTypeHint"; + case ExecutionModeContractionOff: return "ContractionOff"; + case ExecutionModeInitializer: return "Initializer"; + case ExecutionModeFinalizer: return "Finalizer"; + case ExecutionModeSubgroupSize: return "SubgroupSize"; + case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case ExecutionModeLocalSizeId: return "LocalSizeId"; + case ExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + case ExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT"; + case ExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT"; + case ExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT"; + case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlowKHR"; + case ExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case ExecutionModeDenormPreserve: return "DenormPreserve"; + case ExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case ExecutionModeEarlyAndLateFragmentTestsAMD: return "EarlyAndLateFragmentTestsAMD"; + case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case ExecutionModeCoalescingAMDX: return "CoalescingAMDX"; + case ExecutionModeMaxNodeRecursionAMDX: return "MaxNodeRecursionAMDX"; + case ExecutionModeStaticNumWorkgroupsAMDX: return "StaticNumWorkgroupsAMDX"; + case ExecutionModeShaderIndexAMDX: return "ShaderIndexAMDX"; + case ExecutionModeMaxNumWorkgroupsAMDX: return "MaxNumWorkgroupsAMDX"; + case ExecutionModeStencilRefUnchangedFrontAMD: return "StencilRefUnchangedFrontAMD"; + case ExecutionModeStencilRefGreaterFrontAMD: return "StencilRefGreaterFrontAMD"; + case ExecutionModeStencilRefLessFrontAMD: return "StencilRefLessFrontAMD"; + case ExecutionModeStencilRefUnchangedBackAMD: return "StencilRefUnchangedBackAMD"; + case ExecutionModeStencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD"; + case ExecutionModeStencilRefLessBackAMD: return "StencilRefLessBackAMD"; + case ExecutionModeQuadDerivativesKHR: return "QuadDerivativesKHR"; + case ExecutionModeRequireFullQuadsKHR: return "RequireFullQuadsKHR"; + case ExecutionModeOutputLinesEXT: return "OutputLinesEXT"; + case ExecutionModeOutputPrimitivesEXT: return "OutputPrimitivesEXT"; + case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; + case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; + case ExecutionModeOutputTrianglesEXT: return "OutputTrianglesEXT"; + case ExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case ExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case ExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case ExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case ExecutionModeSharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL"; + case ExecutionModeRoundingModeRTPINTEL: return "RoundingModeRTPINTEL"; + case ExecutionModeRoundingModeRTNINTEL: return "RoundingModeRTNINTEL"; + case ExecutionModeFloatingPointModeALTINTEL: return "FloatingPointModeALTINTEL"; + case ExecutionModeFloatingPointModeIEEEINTEL: return "FloatingPointModeIEEEINTEL"; + case ExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case ExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case ExecutionModeSchedulerTargetFmaxMhzINTEL: return "SchedulerTargetFmaxMhzINTEL"; + case ExecutionModeMaximallyReconvergesKHR: return "MaximallyReconvergesKHR"; + case ExecutionModeFPFastMathDefault: return "FPFastMathDefault"; + case ExecutionModeStreamingInterfaceINTEL: return "StreamingInterfaceINTEL"; + case ExecutionModeRegisterMapInterfaceINTEL: return "RegisterMapInterfaceINTEL"; + case ExecutionModeNamedBarrierCountINTEL: return "NamedBarrierCountINTEL"; + case ExecutionModeMaximumRegistersINTEL: return "MaximumRegistersINTEL"; + case ExecutionModeMaximumRegistersIdINTEL: return "MaximumRegistersIdINTEL"; + case ExecutionModeNamedMaximumRegistersINTEL: return "NamedMaximumRegistersINTEL"; + default: return "Unknown"; + } +} + +inline const char* StorageClassToString(StorageClass value) { + switch (value) { + case StorageClassUniformConstant: return "UniformConstant"; + case StorageClassInput: return "Input"; + case StorageClassUniform: return "Uniform"; + case StorageClassOutput: return "Output"; + case StorageClassWorkgroup: return "Workgroup"; + case StorageClassCrossWorkgroup: return "CrossWorkgroup"; + case StorageClassPrivate: return "Private"; + case StorageClassFunction: return "Function"; + case StorageClassGeneric: return "Generic"; + case StorageClassPushConstant: return "PushConstant"; + case StorageClassAtomicCounter: return "AtomicCounter"; + case StorageClassImage: return "Image"; + case StorageClassStorageBuffer: return "StorageBuffer"; + case StorageClassTileImageEXT: return "TileImageEXT"; + case StorageClassNodePayloadAMDX: return "NodePayloadAMDX"; + case StorageClassNodeOutputPayloadAMDX: return "NodeOutputPayloadAMDX"; + case StorageClassCallableDataKHR: return "CallableDataKHR"; + case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; + case StorageClassRayPayloadKHR: return "RayPayloadKHR"; + case StorageClassHitAttributeKHR: return "HitAttributeKHR"; + case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case StorageClassPhysicalStorageBuffer: return "PhysicalStorageBuffer"; + case StorageClassHitObjectAttributeNV: return "HitObjectAttributeNV"; + case StorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT"; + case StorageClassCodeSectionINTEL: return "CodeSectionINTEL"; + case StorageClassDeviceOnlyINTEL: return "DeviceOnlyINTEL"; + case StorageClassHostOnlyINTEL: return "HostOnlyINTEL"; + default: return "Unknown"; + } +} + +inline const char* DimToString(Dim value) { + switch (value) { + case Dim1D: return "1D"; + case Dim2D: return "2D"; + case Dim3D: return "3D"; + case DimCube: return "Cube"; + case DimRect: return "Rect"; + case DimBuffer: return "Buffer"; + case DimSubpassData: return "SubpassData"; + case DimTileImageDataEXT: return "TileImageDataEXT"; + default: return "Unknown"; + } +} + +inline const char* SamplerAddressingModeToString(SamplerAddressingMode value) { + switch (value) { + case SamplerAddressingModeNone: return "None"; + case SamplerAddressingModeClampToEdge: return "ClampToEdge"; + case SamplerAddressingModeClamp: return "Clamp"; + case SamplerAddressingModeRepeat: return "Repeat"; + case SamplerAddressingModeRepeatMirrored: return "RepeatMirrored"; + default: return "Unknown"; + } +} + +inline const char* SamplerFilterModeToString(SamplerFilterMode value) { + switch (value) { + case SamplerFilterModeNearest: return "Nearest"; + case SamplerFilterModeLinear: return "Linear"; + default: return "Unknown"; + } +} + +inline const char* ImageFormatToString(ImageFormat value) { + switch (value) { + case ImageFormatUnknown: return "Unknown"; + case ImageFormatRgba32f: return "Rgba32f"; + case ImageFormatRgba16f: return "Rgba16f"; + case ImageFormatR32f: return "R32f"; + case ImageFormatRgba8: return "Rgba8"; + case ImageFormatRgba8Snorm: return "Rgba8Snorm"; + case ImageFormatRg32f: return "Rg32f"; + case ImageFormatRg16f: return "Rg16f"; + case ImageFormatR11fG11fB10f: return "R11fG11fB10f"; + case ImageFormatR16f: return "R16f"; + case ImageFormatRgba16: return "Rgba16"; + case ImageFormatRgb10A2: return "Rgb10A2"; + case ImageFormatRg16: return "Rg16"; + case ImageFormatRg8: return "Rg8"; + case ImageFormatR16: return "R16"; + case ImageFormatR8: return "R8"; + case ImageFormatRgba16Snorm: return "Rgba16Snorm"; + case ImageFormatRg16Snorm: return "Rg16Snorm"; + case ImageFormatRg8Snorm: return "Rg8Snorm"; + case ImageFormatR16Snorm: return "R16Snorm"; + case ImageFormatR8Snorm: return "R8Snorm"; + case ImageFormatRgba32i: return "Rgba32i"; + case ImageFormatRgba16i: return "Rgba16i"; + case ImageFormatRgba8i: return "Rgba8i"; + case ImageFormatR32i: return "R32i"; + case ImageFormatRg32i: return "Rg32i"; + case ImageFormatRg16i: return "Rg16i"; + case ImageFormatRg8i: return "Rg8i"; + case ImageFormatR16i: return "R16i"; + case ImageFormatR8i: return "R8i"; + case ImageFormatRgba32ui: return "Rgba32ui"; + case ImageFormatRgba16ui: return "Rgba16ui"; + case ImageFormatRgba8ui: return "Rgba8ui"; + case ImageFormatR32ui: return "R32ui"; + case ImageFormatRgb10a2ui: return "Rgb10a2ui"; + case ImageFormatRg32ui: return "Rg32ui"; + case ImageFormatRg16ui: return "Rg16ui"; + case ImageFormatRg8ui: return "Rg8ui"; + case ImageFormatR16ui: return "R16ui"; + case ImageFormatR8ui: return "R8ui"; + case ImageFormatR64ui: return "R64ui"; + case ImageFormatR64i: return "R64i"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelOrderToString(ImageChannelOrder value) { + switch (value) { + case ImageChannelOrderR: return "R"; + case ImageChannelOrderA: return "A"; + case ImageChannelOrderRG: return "RG"; + case ImageChannelOrderRA: return "RA"; + case ImageChannelOrderRGB: return "RGB"; + case ImageChannelOrderRGBA: return "RGBA"; + case ImageChannelOrderBGRA: return "BGRA"; + case ImageChannelOrderARGB: return "ARGB"; + case ImageChannelOrderIntensity: return "Intensity"; + case ImageChannelOrderLuminance: return "Luminance"; + case ImageChannelOrderRx: return "Rx"; + case ImageChannelOrderRGx: return "RGx"; + case ImageChannelOrderRGBx: return "RGBx"; + case ImageChannelOrderDepth: return "Depth"; + case ImageChannelOrderDepthStencil: return "DepthStencil"; + case ImageChannelOrdersRGB: return "sRGB"; + case ImageChannelOrdersRGBx: return "sRGBx"; + case ImageChannelOrdersRGBA: return "sRGBA"; + case ImageChannelOrdersBGRA: return "sBGRA"; + case ImageChannelOrderABGR: return "ABGR"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelDataTypeToString(ImageChannelDataType value) { + switch (value) { + case ImageChannelDataTypeSnormInt8: return "SnormInt8"; + case ImageChannelDataTypeSnormInt16: return "SnormInt16"; + case ImageChannelDataTypeUnormInt8: return "UnormInt8"; + case ImageChannelDataTypeUnormInt16: return "UnormInt16"; + case ImageChannelDataTypeUnormShort565: return "UnormShort565"; + case ImageChannelDataTypeUnormShort555: return "UnormShort555"; + case ImageChannelDataTypeUnormInt101010: return "UnormInt101010"; + case ImageChannelDataTypeSignedInt8: return "SignedInt8"; + case ImageChannelDataTypeSignedInt16: return "SignedInt16"; + case ImageChannelDataTypeSignedInt32: return "SignedInt32"; + case ImageChannelDataTypeUnsignedInt8: return "UnsignedInt8"; + case ImageChannelDataTypeUnsignedInt16: return "UnsignedInt16"; + case ImageChannelDataTypeUnsignedInt32: return "UnsignedInt32"; + case ImageChannelDataTypeHalfFloat: return "HalfFloat"; + case ImageChannelDataTypeFloat: return "Float"; + case ImageChannelDataTypeUnormInt24: return "UnormInt24"; + case ImageChannelDataTypeUnormInt101010_2: return "UnormInt101010_2"; + case ImageChannelDataTypeUnsignedIntRaw10EXT: return "UnsignedIntRaw10EXT"; + case ImageChannelDataTypeUnsignedIntRaw12EXT: return "UnsignedIntRaw12EXT"; + default: return "Unknown"; + } +} + +inline const char* FPRoundingModeToString(FPRoundingMode value) { + switch (value) { + case FPRoundingModeRTE: return "RTE"; + case FPRoundingModeRTZ: return "RTZ"; + case FPRoundingModeRTP: return "RTP"; + case FPRoundingModeRTN: return "RTN"; + default: return "Unknown"; + } +} + +inline const char* LinkageTypeToString(LinkageType value) { + switch (value) { + case LinkageTypeExport: return "Export"; + case LinkageTypeImport: return "Import"; + case LinkageTypeLinkOnceODR: return "LinkOnceODR"; + default: return "Unknown"; + } +} + +inline const char* AccessQualifierToString(AccessQualifier value) { + switch (value) { + case AccessQualifierReadOnly: return "ReadOnly"; + case AccessQualifierWriteOnly: return "WriteOnly"; + case AccessQualifierReadWrite: return "ReadWrite"; + default: return "Unknown"; + } +} + +inline const char* FunctionParameterAttributeToString(FunctionParameterAttribute value) { + switch (value) { + case FunctionParameterAttributeZext: return "Zext"; + case FunctionParameterAttributeSext: return "Sext"; + case FunctionParameterAttributeByVal: return "ByVal"; + case FunctionParameterAttributeSret: return "Sret"; + case FunctionParameterAttributeNoAlias: return "NoAlias"; + case FunctionParameterAttributeNoCapture: return "NoCapture"; + case FunctionParameterAttributeNoWrite: return "NoWrite"; + case FunctionParameterAttributeNoReadWrite: return "NoReadWrite"; + case FunctionParameterAttributeRuntimeAlignedINTEL: return "RuntimeAlignedINTEL"; + default: return "Unknown"; + } +} + +inline const char* DecorationToString(Decoration value) { + switch (value) { + case DecorationRelaxedPrecision: return "RelaxedPrecision"; + case DecorationSpecId: return "SpecId"; + case DecorationBlock: return "Block"; + case DecorationBufferBlock: return "BufferBlock"; + case DecorationRowMajor: return "RowMajor"; + case DecorationColMajor: return "ColMajor"; + case DecorationArrayStride: return "ArrayStride"; + case DecorationMatrixStride: return "MatrixStride"; + case DecorationGLSLShared: return "GLSLShared"; + case DecorationGLSLPacked: return "GLSLPacked"; + case DecorationCPacked: return "CPacked"; + case DecorationBuiltIn: return "BuiltIn"; + case DecorationNoPerspective: return "NoPerspective"; + case DecorationFlat: return "Flat"; + case DecorationPatch: return "Patch"; + case DecorationCentroid: return "Centroid"; + case DecorationSample: return "Sample"; + case DecorationInvariant: return "Invariant"; + case DecorationRestrict: return "Restrict"; + case DecorationAliased: return "Aliased"; + case DecorationVolatile: return "Volatile"; + case DecorationConstant: return "Constant"; + case DecorationCoherent: return "Coherent"; + case DecorationNonWritable: return "NonWritable"; + case DecorationNonReadable: return "NonReadable"; + case DecorationUniform: return "Uniform"; + case DecorationUniformId: return "UniformId"; + case DecorationSaturatedConversion: return "SaturatedConversion"; + case DecorationStream: return "Stream"; + case DecorationLocation: return "Location"; + case DecorationComponent: return "Component"; + case DecorationIndex: return "Index"; + case DecorationBinding: return "Binding"; + case DecorationDescriptorSet: return "DescriptorSet"; + case DecorationOffset: return "Offset"; + case DecorationXfbBuffer: return "XfbBuffer"; + case DecorationXfbStride: return "XfbStride"; + case DecorationFuncParamAttr: return "FuncParamAttr"; + case DecorationFPRoundingMode: return "FPRoundingMode"; + case DecorationFPFastMathMode: return "FPFastMathMode"; + case DecorationLinkageAttributes: return "LinkageAttributes"; + case DecorationNoContraction: return "NoContraction"; + case DecorationInputAttachmentIndex: return "InputAttachmentIndex"; + case DecorationAlignment: return "Alignment"; + case DecorationMaxByteOffset: return "MaxByteOffset"; + case DecorationAlignmentId: return "AlignmentId"; + case DecorationMaxByteOffsetId: return "MaxByteOffsetId"; + case DecorationNoSignedWrap: return "NoSignedWrap"; + case DecorationNoUnsignedWrap: return "NoUnsignedWrap"; + case DecorationWeightTextureQCOM: return "WeightTextureQCOM"; + case DecorationBlockMatchTextureQCOM: return "BlockMatchTextureQCOM"; + case DecorationBlockMatchSamplerQCOM: return "BlockMatchSamplerQCOM"; + case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; + case DecorationNodeSharesPayloadLimitsWithAMDX: return "NodeSharesPayloadLimitsWithAMDX"; + case DecorationNodeMaxPayloadsAMDX: return "NodeMaxPayloadsAMDX"; + case DecorationTrackFinishWritingAMDX: return "TrackFinishWritingAMDX"; + case DecorationPayloadNodeNameAMDX: return "PayloadNodeNameAMDX"; + case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; + case DecorationPassthroughNV: return "PassthroughNV"; + case DecorationViewportRelativeNV: return "ViewportRelativeNV"; + case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; + case DecorationPerPrimitiveEXT: return "PerPrimitiveEXT"; + case DecorationPerViewNV: return "PerViewNV"; + case DecorationPerTaskNV: return "PerTaskNV"; + case DecorationPerVertexKHR: return "PerVertexKHR"; + case DecorationNonUniform: return "NonUniform"; + case DecorationRestrictPointer: return "RestrictPointer"; + case DecorationAliasedPointer: return "AliasedPointer"; + case DecorationHitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV"; + case DecorationBindlessSamplerNV: return "BindlessSamplerNV"; + case DecorationBindlessImageNV: return "BindlessImageNV"; + case DecorationBoundSamplerNV: return "BoundSamplerNV"; + case DecorationBoundImageNV: return "BoundImageNV"; + case DecorationSIMTCallINTEL: return "SIMTCallINTEL"; + case DecorationReferencedIndirectlyINTEL: return "ReferencedIndirectlyINTEL"; + case DecorationClobberINTEL: return "ClobberINTEL"; + case DecorationSideEffectsINTEL: return "SideEffectsINTEL"; + case DecorationVectorComputeVariableINTEL: return "VectorComputeVariableINTEL"; + case DecorationFuncParamIOKindINTEL: return "FuncParamIOKindINTEL"; + case DecorationVectorComputeFunctionINTEL: return "VectorComputeFunctionINTEL"; + case DecorationStackCallINTEL: return "StackCallINTEL"; + case DecorationGlobalVariableOffsetINTEL: return "GlobalVariableOffsetINTEL"; + case DecorationCounterBuffer: return "CounterBuffer"; + case DecorationHlslSemanticGOOGLE: return "HlslSemanticGOOGLE"; + case DecorationUserTypeGOOGLE: return "UserTypeGOOGLE"; + case DecorationFunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL"; + case DecorationFunctionDenormModeINTEL: return "FunctionDenormModeINTEL"; + case DecorationRegisterINTEL: return "RegisterINTEL"; + case DecorationMemoryINTEL: return "MemoryINTEL"; + case DecorationNumbanksINTEL: return "NumbanksINTEL"; + case DecorationBankwidthINTEL: return "BankwidthINTEL"; + case DecorationMaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL"; + case DecorationSinglepumpINTEL: return "SinglepumpINTEL"; + case DecorationDoublepumpINTEL: return "DoublepumpINTEL"; + case DecorationMaxReplicatesINTEL: return "MaxReplicatesINTEL"; + case DecorationSimpleDualPortINTEL: return "SimpleDualPortINTEL"; + case DecorationMergeINTEL: return "MergeINTEL"; + case DecorationBankBitsINTEL: return "BankBitsINTEL"; + case DecorationForcePow2DepthINTEL: return "ForcePow2DepthINTEL"; + case DecorationStridesizeINTEL: return "StridesizeINTEL"; + case DecorationWordsizeINTEL: return "WordsizeINTEL"; + case DecorationTrueDualPortINTEL: return "TrueDualPortINTEL"; + case DecorationBurstCoalesceINTEL: return "BurstCoalesceINTEL"; + case DecorationCacheSizeINTEL: return "CacheSizeINTEL"; + case DecorationDontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL"; + case DecorationPrefetchINTEL: return "PrefetchINTEL"; + case DecorationStallEnableINTEL: return "StallEnableINTEL"; + case DecorationFuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL"; + case DecorationMathOpDSPModeINTEL: return "MathOpDSPModeINTEL"; + case DecorationAliasScopeINTEL: return "AliasScopeINTEL"; + case DecorationNoAliasINTEL: return "NoAliasINTEL"; + case DecorationInitiationIntervalINTEL: return "InitiationIntervalINTEL"; + case DecorationMaxConcurrencyINTEL: return "MaxConcurrencyINTEL"; + case DecorationPipelineEnableINTEL: return "PipelineEnableINTEL"; + case DecorationBufferLocationINTEL: return "BufferLocationINTEL"; + case DecorationIOPipeStorageINTEL: return "IOPipeStorageINTEL"; + case DecorationFunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL"; + case DecorationSingleElementVectorINTEL: return "SingleElementVectorINTEL"; + case DecorationVectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL"; + case DecorationMediaBlockIOINTEL: return "MediaBlockIOINTEL"; + case DecorationStallFreeINTEL: return "StallFreeINTEL"; + case DecorationFPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL"; + case DecorationLatencyControlLabelINTEL: return "LatencyControlLabelINTEL"; + case DecorationLatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL"; + case DecorationConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL"; + case DecorationRegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL"; + case DecorationMMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL"; + case DecorationMMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL"; + case DecorationMMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL"; + case DecorationMMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL"; + case DecorationMMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL"; + case DecorationMMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL"; + case DecorationStableKernelArgumentINTEL: return "StableKernelArgumentINTEL"; + case DecorationHostAccessINTEL: return "HostAccessINTEL"; + case DecorationInitModeINTEL: return "InitModeINTEL"; + case DecorationImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL"; + case DecorationCacheControlLoadINTEL: return "CacheControlLoadINTEL"; + case DecorationCacheControlStoreINTEL: return "CacheControlStoreINTEL"; + default: return "Unknown"; + } +} + +inline const char* BuiltInToString(BuiltIn value) { + switch (value) { + case BuiltInPosition: return "Position"; + case BuiltInPointSize: return "PointSize"; + case BuiltInClipDistance: return "ClipDistance"; + case BuiltInCullDistance: return "CullDistance"; + case BuiltInVertexId: return "VertexId"; + case BuiltInInstanceId: return "InstanceId"; + case BuiltInPrimitiveId: return "PrimitiveId"; + case BuiltInInvocationId: return "InvocationId"; + case BuiltInLayer: return "Layer"; + case BuiltInViewportIndex: return "ViewportIndex"; + case BuiltInTessLevelOuter: return "TessLevelOuter"; + case BuiltInTessLevelInner: return "TessLevelInner"; + case BuiltInTessCoord: return "TessCoord"; + case BuiltInPatchVertices: return "PatchVertices"; + case BuiltInFragCoord: return "FragCoord"; + case BuiltInPointCoord: return "PointCoord"; + case BuiltInFrontFacing: return "FrontFacing"; + case BuiltInSampleId: return "SampleId"; + case BuiltInSamplePosition: return "SamplePosition"; + case BuiltInSampleMask: return "SampleMask"; + case BuiltInFragDepth: return "FragDepth"; + case BuiltInHelperInvocation: return "HelperInvocation"; + case BuiltInNumWorkgroups: return "NumWorkgroups"; + case BuiltInWorkgroupSize: return "WorkgroupSize"; + case BuiltInWorkgroupId: return "WorkgroupId"; + case BuiltInLocalInvocationId: return "LocalInvocationId"; + case BuiltInGlobalInvocationId: return "GlobalInvocationId"; + case BuiltInLocalInvocationIndex: return "LocalInvocationIndex"; + case BuiltInWorkDim: return "WorkDim"; + case BuiltInGlobalSize: return "GlobalSize"; + case BuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case BuiltInGlobalOffset: return "GlobalOffset"; + case BuiltInGlobalLinearId: return "GlobalLinearId"; + case BuiltInSubgroupSize: return "SubgroupSize"; + case BuiltInSubgroupMaxSize: return "SubgroupMaxSize"; + case BuiltInNumSubgroups: return "NumSubgroups"; + case BuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case BuiltInSubgroupId: return "SubgroupId"; + case BuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + case BuiltInVertexIndex: return "VertexIndex"; + case BuiltInInstanceIndex: return "InstanceIndex"; + case BuiltInCoreIDARM: return "CoreIDARM"; + case BuiltInCoreCountARM: return "CoreCountARM"; + case BuiltInCoreMaxIDARM: return "CoreMaxIDARM"; + case BuiltInWarpIDARM: return "WarpIDARM"; + case BuiltInWarpMaxIDARM: return "WarpMaxIDARM"; + case BuiltInSubgroupEqMask: return "SubgroupEqMask"; + case BuiltInSubgroupGeMask: return "SubgroupGeMask"; + case BuiltInSubgroupGtMask: return "SubgroupGtMask"; + case BuiltInSubgroupLeMask: return "SubgroupLeMask"; + case BuiltInSubgroupLtMask: return "SubgroupLtMask"; + case BuiltInBaseVertex: return "BaseVertex"; + case BuiltInBaseInstance: return "BaseInstance"; + case BuiltInDrawIndex: return "DrawIndex"; + case BuiltInPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + case BuiltInDeviceIndex: return "DeviceIndex"; + case BuiltInViewIndex: return "ViewIndex"; + case BuiltInShadingRateKHR: return "ShadingRateKHR"; + case BuiltInBaryCoordNoPerspAMD: return "BaryCoordNoPerspAMD"; + case BuiltInBaryCoordNoPerspCentroidAMD: return "BaryCoordNoPerspCentroidAMD"; + case BuiltInBaryCoordNoPerspSampleAMD: return "BaryCoordNoPerspSampleAMD"; + case BuiltInBaryCoordSmoothAMD: return "BaryCoordSmoothAMD"; + case BuiltInBaryCoordSmoothCentroidAMD: return "BaryCoordSmoothCentroidAMD"; + case BuiltInBaryCoordSmoothSampleAMD: return "BaryCoordSmoothSampleAMD"; + case BuiltInBaryCoordPullModelAMD: return "BaryCoordPullModelAMD"; + case BuiltInFragStencilRefEXT: return "FragStencilRefEXT"; + case BuiltInCoalescedInputCountAMDX: return "CoalescedInputCountAMDX"; + case BuiltInShaderIndexAMDX: return "ShaderIndexAMDX"; + case BuiltInViewportMaskNV: return "ViewportMaskNV"; + case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case BuiltInPositionPerViewNV: return "PositionPerViewNV"; + case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case BuiltInFullyCoveredEXT: return "FullyCoveredEXT"; + case BuiltInTaskCountNV: return "TaskCountNV"; + case BuiltInPrimitiveCountNV: return "PrimitiveCountNV"; + case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV"; + case BuiltInLayerPerViewNV: return "LayerPerViewNV"; + case BuiltInMeshViewCountNV: return "MeshViewCountNV"; + case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; + case BuiltInBaryCoordKHR: return "BaryCoordKHR"; + case BuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR"; + case BuiltInFragSizeEXT: return "FragSizeEXT"; + case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; + case BuiltInPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case BuiltInPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case BuiltInPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case BuiltInCullPrimitiveEXT: return "CullPrimitiveEXT"; + case BuiltInLaunchIdKHR: return "LaunchIdKHR"; + case BuiltInLaunchSizeKHR: return "LaunchSizeKHR"; + case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR"; + case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case BuiltInRayTminKHR: return "RayTminKHR"; + case BuiltInRayTmaxKHR: return "RayTmaxKHR"; + case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; + case BuiltInWorldToObjectKHR: return "WorldToObjectKHR"; + case BuiltInHitTNV: return "HitTNV"; + case BuiltInHitKindKHR: return "HitKindKHR"; + case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV"; + case BuiltInHitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR"; + case BuiltInHitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV"; + case BuiltInHitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV"; + case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case BuiltInWarpsPerSMNV: return "WarpsPerSMNV"; + case BuiltInSMCountNV: return "SMCountNV"; + case BuiltInWarpIDNV: return "WarpIDNV"; + case BuiltInSMIDNV: return "SMIDNV"; + case BuiltInHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case BuiltInHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; + case BuiltInCullMaskKHR: return "CullMaskKHR"; + default: return "Unknown"; + } +} + +inline const char* ScopeToString(Scope value) { + switch (value) { + case ScopeCrossDevice: return "CrossDevice"; + case ScopeDevice: return "Device"; + case ScopeWorkgroup: return "Workgroup"; + case ScopeSubgroup: return "Subgroup"; + case ScopeInvocation: return "Invocation"; + case ScopeQueueFamily: return "QueueFamily"; + case ScopeShaderCallKHR: return "ShaderCallKHR"; + default: return "Unknown"; + } +} + +inline const char* GroupOperationToString(GroupOperation value) { + switch (value) { + case GroupOperationReduce: return "Reduce"; + case GroupOperationInclusiveScan: return "InclusiveScan"; + case GroupOperationExclusiveScan: return "ExclusiveScan"; + case GroupOperationClusteredReduce: return "ClusteredReduce"; + case GroupOperationPartitionedReduceNV: return "PartitionedReduceNV"; + case GroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; + case GroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; + default: return "Unknown"; + } +} + +inline const char* KernelEnqueueFlagsToString(KernelEnqueueFlags value) { + switch (value) { + case KernelEnqueueFlagsNoWait: return "NoWait"; + case KernelEnqueueFlagsWaitKernel: return "WaitKernel"; + case KernelEnqueueFlagsWaitWorkGroup: return "WaitWorkGroup"; + default: return "Unknown"; + } +} + +inline const char* CapabilityToString(Capability value) { + switch (value) { + case CapabilityMatrix: return "Matrix"; + case CapabilityShader: return "Shader"; + case CapabilityGeometry: return "Geometry"; + case CapabilityTessellation: return "Tessellation"; + case CapabilityAddresses: return "Addresses"; + case CapabilityLinkage: return "Linkage"; + case CapabilityKernel: return "Kernel"; + case CapabilityVector16: return "Vector16"; + case CapabilityFloat16Buffer: return "Float16Buffer"; + case CapabilityFloat16: return "Float16"; + case CapabilityFloat64: return "Float64"; + case CapabilityInt64: return "Int64"; + case CapabilityInt64Atomics: return "Int64Atomics"; + case CapabilityImageBasic: return "ImageBasic"; + case CapabilityImageReadWrite: return "ImageReadWrite"; + case CapabilityImageMipmap: return "ImageMipmap"; + case CapabilityPipes: return "Pipes"; + case CapabilityGroups: return "Groups"; + case CapabilityDeviceEnqueue: return "DeviceEnqueue"; + case CapabilityLiteralSampler: return "LiteralSampler"; + case CapabilityAtomicStorage: return "AtomicStorage"; + case CapabilityInt16: return "Int16"; + case CapabilityTessellationPointSize: return "TessellationPointSize"; + case CapabilityGeometryPointSize: return "GeometryPointSize"; + case CapabilityImageGatherExtended: return "ImageGatherExtended"; + case CapabilityStorageImageMultisample: return "StorageImageMultisample"; + case CapabilityUniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; + case CapabilitySampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; + case CapabilityStorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; + case CapabilityStorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; + case CapabilityClipDistance: return "ClipDistance"; + case CapabilityCullDistance: return "CullDistance"; + case CapabilityImageCubeArray: return "ImageCubeArray"; + case CapabilitySampleRateShading: return "SampleRateShading"; + case CapabilityImageRect: return "ImageRect"; + case CapabilitySampledRect: return "SampledRect"; + case CapabilityGenericPointer: return "GenericPointer"; + case CapabilityInt8: return "Int8"; + case CapabilityInputAttachment: return "InputAttachment"; + case CapabilitySparseResidency: return "SparseResidency"; + case CapabilityMinLod: return "MinLod"; + case CapabilitySampled1D: return "Sampled1D"; + case CapabilityImage1D: return "Image1D"; + case CapabilitySampledCubeArray: return "SampledCubeArray"; + case CapabilitySampledBuffer: return "SampledBuffer"; + case CapabilityImageBuffer: return "ImageBuffer"; + case CapabilityImageMSArray: return "ImageMSArray"; + case CapabilityStorageImageExtendedFormats: return "StorageImageExtendedFormats"; + case CapabilityImageQuery: return "ImageQuery"; + case CapabilityDerivativeControl: return "DerivativeControl"; + case CapabilityInterpolationFunction: return "InterpolationFunction"; + case CapabilityTransformFeedback: return "TransformFeedback"; + case CapabilityGeometryStreams: return "GeometryStreams"; + case CapabilityStorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; + case CapabilityStorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; + case CapabilityMultiViewport: return "MultiViewport"; + case CapabilitySubgroupDispatch: return "SubgroupDispatch"; + case CapabilityNamedBarrier: return "NamedBarrier"; + case CapabilityPipeStorage: return "PipeStorage"; + case CapabilityGroupNonUniform: return "GroupNonUniform"; + case CapabilityGroupNonUniformVote: return "GroupNonUniformVote"; + case CapabilityGroupNonUniformArithmetic: return "GroupNonUniformArithmetic"; + case CapabilityGroupNonUniformBallot: return "GroupNonUniformBallot"; + case CapabilityGroupNonUniformShuffle: return "GroupNonUniformShuffle"; + case CapabilityGroupNonUniformShuffleRelative: return "GroupNonUniformShuffleRelative"; + case CapabilityGroupNonUniformClustered: return "GroupNonUniformClustered"; + case CapabilityGroupNonUniformQuad: return "GroupNonUniformQuad"; + case CapabilityShaderLayer: return "ShaderLayer"; + case CapabilityShaderViewportIndex: return "ShaderViewportIndex"; + case CapabilityUniformDecoration: return "UniformDecoration"; + case CapabilityCoreBuiltinsARM: return "CoreBuiltinsARM"; + case CapabilityTileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; + case CapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; + case CapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case CapabilityCooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM"; + case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; + case CapabilitySubgroupBallotKHR: return "SubgroupBallotKHR"; + case CapabilityDrawParameters: return "DrawParameters"; + case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "WorkgroupMemoryExplicitLayoutKHR"; + case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; + case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; + case CapabilitySubgroupVoteKHR: return "SubgroupVoteKHR"; + case CapabilityStorageBuffer16BitAccess: return "StorageBuffer16BitAccess"; + case CapabilityStorageUniform16: return "StorageUniform16"; + case CapabilityStoragePushConstant16: return "StoragePushConstant16"; + case CapabilityStorageInputOutput16: return "StorageInputOutput16"; + case CapabilityDeviceGroup: return "DeviceGroup"; + case CapabilityMultiView: return "MultiView"; + case CapabilityVariablePointersStorageBuffer: return "VariablePointersStorageBuffer"; + case CapabilityVariablePointers: return "VariablePointers"; + case CapabilityAtomicStorageOps: return "AtomicStorageOps"; + case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; + case CapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case CapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case CapabilityStoragePushConstant8: return "StoragePushConstant8"; + case CapabilityDenormPreserve: return "DenormPreserve"; + case CapabilityDenormFlushToZero: return "DenormFlushToZero"; + case CapabilitySignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case CapabilityRoundingModeRTE: return "RoundingModeRTE"; + case CapabilityRoundingModeRTZ: return "RoundingModeRTZ"; + case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; + case CapabilityRayQueryKHR: return "RayQueryKHR"; + case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; + case CapabilityRayTracingKHR: return "RayTracingKHR"; + case CapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; + case CapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; + case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; + case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; + case CapabilityFloat16ImageAMD: return "Float16ImageAMD"; + case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; + case CapabilityFragmentMaskAMD: return "FragmentMaskAMD"; + case CapabilityStencilExportEXT: return "StencilExportEXT"; + case CapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case CapabilityInt64ImageEXT: return "Int64ImageEXT"; + case CapabilityShaderClockKHR: return "ShaderClockKHR"; + case CapabilityShaderEnqueueAMDX: return "ShaderEnqueueAMDX"; + case CapabilityQuadControlKHR: return "QuadControlKHR"; + case CapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; + case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case CapabilityShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; + case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; + case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; + case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; + case CapabilityMeshShadingNV: return "MeshShadingNV"; + case CapabilityImageFootprintNV: return "ImageFootprintNV"; + case CapabilityMeshShadingEXT: return "MeshShadingEXT"; + case CapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR"; + case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; + case CapabilityFragmentDensityEXT: return "FragmentDensityEXT"; + case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; + case CapabilityShaderNonUniform: return "ShaderNonUniform"; + case CapabilityRuntimeDescriptorArray: return "RuntimeDescriptorArray"; + case CapabilityInputAttachmentArrayDynamicIndexing: return "InputAttachmentArrayDynamicIndexing"; + case CapabilityUniformTexelBufferArrayDynamicIndexing: return "UniformTexelBufferArrayDynamicIndexing"; + case CapabilityStorageTexelBufferArrayDynamicIndexing: return "StorageTexelBufferArrayDynamicIndexing"; + case CapabilityUniformBufferArrayNonUniformIndexing: return "UniformBufferArrayNonUniformIndexing"; + case CapabilitySampledImageArrayNonUniformIndexing: return "SampledImageArrayNonUniformIndexing"; + case CapabilityStorageBufferArrayNonUniformIndexing: return "StorageBufferArrayNonUniformIndexing"; + case CapabilityStorageImageArrayNonUniformIndexing: return "StorageImageArrayNonUniformIndexing"; + case CapabilityInputAttachmentArrayNonUniformIndexing: return "InputAttachmentArrayNonUniformIndexing"; + case CapabilityUniformTexelBufferArrayNonUniformIndexing: return "UniformTexelBufferArrayNonUniformIndexing"; + case CapabilityStorageTexelBufferArrayNonUniformIndexing: return "StorageTexelBufferArrayNonUniformIndexing"; + case CapabilityRayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR"; + case CapabilityRayTracingNV: return "RayTracingNV"; + case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; + case CapabilityVulkanMemoryModel: return "VulkanMemoryModel"; + case CapabilityVulkanMemoryModelDeviceScope: return "VulkanMemoryModelDeviceScope"; + case CapabilityPhysicalStorageBufferAddresses: return "PhysicalStorageBufferAddresses"; + case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; + case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case CapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case CapabilityFragmentShaderSampleInterlockEXT: return "FragmentShaderSampleInterlockEXT"; + case CapabilityFragmentShaderShadingRateInterlockEXT: return "FragmentShaderShadingRateInterlockEXT"; + case CapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + case CapabilityFragmentShaderPixelInterlockEXT: return "FragmentShaderPixelInterlockEXT"; + case CapabilityDemoteToHelperInvocation: return "DemoteToHelperInvocation"; + case CapabilityDisplacementMicromapNV: return "DisplacementMicromapNV"; + case CapabilityRayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT"; + case CapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV"; + case CapabilityBindlessTextureNV: return "BindlessTextureNV"; + case CapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR"; + case CapabilityAtomicFloat16VectorNV: return "AtomicFloat16VectorNV"; + case CapabilityRayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV"; + case CapabilityRawAccessChainsNV: return "RawAccessChainsNV"; + case CapabilitySubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; + case CapabilitySubgroupBufferBlockIOINTEL: return "SubgroupBufferBlockIOINTEL"; + case CapabilitySubgroupImageBlockIOINTEL: return "SubgroupImageBlockIOINTEL"; + case CapabilitySubgroupImageMediaBlockIOINTEL: return "SubgroupImageMediaBlockIOINTEL"; + case CapabilityRoundToInfinityINTEL: return "RoundToInfinityINTEL"; + case CapabilityFloatingPointModeINTEL: return "FloatingPointModeINTEL"; + case CapabilityIntegerFunctions2INTEL: return "IntegerFunctions2INTEL"; + case CapabilityFunctionPointersINTEL: return "FunctionPointersINTEL"; + case CapabilityIndirectReferencesINTEL: return "IndirectReferencesINTEL"; + case CapabilityAsmINTEL: return "AsmINTEL"; + case CapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; + case CapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; + case CapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; + case CapabilityVectorComputeINTEL: return "VectorComputeINTEL"; + case CapabilityVectorAnyINTEL: return "VectorAnyINTEL"; + case CapabilityExpectAssumeKHR: return "ExpectAssumeKHR"; + case CapabilitySubgroupAvcMotionEstimationINTEL: return "SubgroupAvcMotionEstimationINTEL"; + case CapabilitySubgroupAvcMotionEstimationIntraINTEL: return "SubgroupAvcMotionEstimationIntraINTEL"; + case CapabilitySubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL"; + case CapabilityVariableLengthArrayINTEL: return "VariableLengthArrayINTEL"; + case CapabilityFunctionFloatControlINTEL: return "FunctionFloatControlINTEL"; + case CapabilityFPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL"; + case CapabilityFPFastMathModeINTEL: return "FPFastMathModeINTEL"; + case CapabilityArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL"; + case CapabilityArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL"; + case CapabilityUnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL"; + case CapabilityFPGALoopControlsINTEL: return "FPGALoopControlsINTEL"; + case CapabilityKernelAttributesINTEL: return "KernelAttributesINTEL"; + case CapabilityFPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL"; + case CapabilityFPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL"; + case CapabilityFPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL"; + case CapabilityLoopFuseINTEL: return "LoopFuseINTEL"; + case CapabilityFPGADSPControlINTEL: return "FPGADSPControlINTEL"; + case CapabilityMemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL"; + case CapabilityFPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL"; + case CapabilityFPGABufferLocationINTEL: return "FPGABufferLocationINTEL"; + case CapabilityArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL"; + case CapabilityUSMStorageClassesINTEL: return "USMStorageClassesINTEL"; + case CapabilityRuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL"; + case CapabilityIOPipesINTEL: return "IOPipesINTEL"; + case CapabilityBlockingPipesINTEL: return "BlockingPipesINTEL"; + case CapabilityFPGARegINTEL: return "FPGARegINTEL"; + case CapabilityDotProductInputAll: return "DotProductInputAll"; + case CapabilityDotProductInput4x8Bit: return "DotProductInput4x8Bit"; + case CapabilityDotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked"; + case CapabilityDotProduct: return "DotProduct"; + case CapabilityRayCullMaskKHR: return "RayCullMaskKHR"; + case CapabilityCooperativeMatrixKHR: return "CooperativeMatrixKHR"; + case CapabilityReplicatedCompositesEXT: return "ReplicatedCompositesEXT"; + case CapabilityBitInstructions: return "BitInstructions"; + case CapabilityGroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR"; + case CapabilityFloatControls2: return "FloatControls2"; + case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + case CapabilityLongCompositesINTEL: return "LongCompositesINTEL"; + case CapabilityOptNoneINTEL: return "OptNoneINTEL"; + case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; + case CapabilityDebugInfoModuleINTEL: return "DebugInfoModuleINTEL"; + case CapabilityBFloat16ConversionINTEL: return "BFloat16ConversionINTEL"; + case CapabilitySplitBarrierINTEL: return "SplitBarrierINTEL"; + case CapabilityFPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL"; + case CapabilityFPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL"; + case CapabilityFPMaxErrorINTEL: return "FPMaxErrorINTEL"; + case CapabilityFPGALatencyControlINTEL: return "FPGALatencyControlINTEL"; + case CapabilityFPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL"; + case CapabilityGlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL"; + case CapabilityGlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL"; + case CapabilityGroupUniformArithmeticKHR: return "GroupUniformArithmeticKHR"; + case CapabilityMaskedGatherScatterINTEL: return "MaskedGatherScatterINTEL"; + case CapabilityCacheControlsINTEL: return "CacheControlsINTEL"; + case CapabilityRegisterLimitsINTEL: return "RegisterLimitsINTEL"; + default: return "Unknown"; + } +} + +inline const char* RayQueryIntersectionToString(RayQueryIntersection value) { + switch (value) { + case RayQueryIntersectionRayQueryCandidateIntersectionKHR: return "RayQueryCandidateIntersectionKHR"; + case RayQueryIntersectionRayQueryCommittedIntersectionKHR: return "RayQueryCommittedIntersectionKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCommittedIntersectionTypeToString(RayQueryCommittedIntersectionType value) { + switch (value) { + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR: return "RayQueryCommittedIntersectionNoneKHR"; + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR: return "RayQueryCommittedIntersectionTriangleKHR"; + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR: return "RayQueryCommittedIntersectionGeneratedKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCandidateIntersectionTypeToString(RayQueryCandidateIntersectionType value) { + switch (value) { + case RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR: return "RayQueryCandidateIntersectionTriangleKHR"; + case RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR: return "RayQueryCandidateIntersectionAABBKHR"; + default: return "Unknown"; + } +} + +inline const char* FPDenormModeToString(FPDenormMode value) { + switch (value) { + case FPDenormModePreserve: return "Preserve"; + case FPDenormModeFlushToZero: return "FlushToZero"; + default: return "Unknown"; + } +} + +inline const char* FPOperationModeToString(FPOperationMode value) { + switch (value) { + case FPOperationModeIEEE: return "IEEE"; + case FPOperationModeALT: return "ALT"; + default: return "Unknown"; + } +} + +inline const char* QuantizationModesToString(QuantizationModes value) { + switch (value) { + case QuantizationModesTRN: return "TRN"; + case QuantizationModesTRN_ZERO: return "TRN_ZERO"; + case QuantizationModesRND: return "RND"; + case QuantizationModesRND_ZERO: return "RND_ZERO"; + case QuantizationModesRND_INF: return "RND_INF"; + case QuantizationModesRND_MIN_INF: return "RND_MIN_INF"; + case QuantizationModesRND_CONV: return "RND_CONV"; + case QuantizationModesRND_CONV_ODD: return "RND_CONV_ODD"; + default: return "Unknown"; + } +} + +inline const char* OverflowModesToString(OverflowModes value) { + switch (value) { + case OverflowModesWRAP: return "WRAP"; + case OverflowModesSAT: return "SAT"; + case OverflowModesSAT_ZERO: return "SAT_ZERO"; + case OverflowModesSAT_SYM: return "SAT_SYM"; + default: return "Unknown"; + } +} + +inline const char* PackedVectorFormatToString(PackedVectorFormat value) { + switch (value) { + case PackedVectorFormatPackedVectorFormat4x8Bit: return "PackedVectorFormat4x8Bit"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixLayoutToString(CooperativeMatrixLayout value) { + switch (value) { + case CooperativeMatrixLayoutRowMajorKHR: return "RowMajorKHR"; + case CooperativeMatrixLayoutColumnMajorKHR: return "ColumnMajorKHR"; + case CooperativeMatrixLayoutRowBlockedInterleavedARM: return "RowBlockedInterleavedARM"; + case CooperativeMatrixLayoutColumnBlockedInterleavedARM: return "ColumnBlockedInterleavedARM"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixUseToString(CooperativeMatrixUse value) { + switch (value) { + case CooperativeMatrixUseMatrixAKHR: return "MatrixAKHR"; + case CooperativeMatrixUseMatrixBKHR: return "MatrixBKHR"; + case CooperativeMatrixUseMatrixAccumulatorKHR: return "MatrixAccumulatorKHR"; + default: return "Unknown"; + } +} + +inline const char* InitializationModeQualifierToString(InitializationModeQualifier value) { + switch (value) { + case InitializationModeQualifierInitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL"; + case InitializationModeQualifierInitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL"; + default: return "Unknown"; + } +} + +inline const char* HostAccessQualifierToString(HostAccessQualifier value) { + switch (value) { + case HostAccessQualifierNoneINTEL: return "NoneINTEL"; + case HostAccessQualifierReadINTEL: return "ReadINTEL"; + case HostAccessQualifierWriteINTEL: return "WriteINTEL"; + case HostAccessQualifierReadWriteINTEL: return "ReadWriteINTEL"; + default: return "Unknown"; + } +} + +inline const char* LoadCacheControlToString(LoadCacheControl value) { + switch (value) { + case LoadCacheControlUncachedINTEL: return "UncachedINTEL"; + case LoadCacheControlCachedINTEL: return "CachedINTEL"; + case LoadCacheControlStreamingINTEL: return "StreamingINTEL"; + case LoadCacheControlInvalidateAfterReadINTEL: return "InvalidateAfterReadINTEL"; + case LoadCacheControlConstCachedINTEL: return "ConstCachedINTEL"; + default: return "Unknown"; + } +} + +inline const char* StoreCacheControlToString(StoreCacheControl value) { + switch (value) { + case StoreCacheControlUncachedINTEL: return "UncachedINTEL"; + case StoreCacheControlWriteThroughINTEL: return "WriteThroughINTEL"; + case StoreCacheControlWriteBackINTEL: return "WriteBackINTEL"; + case StoreCacheControlStreamingINTEL: return "StreamingINTEL"; + default: return "Unknown"; + } +} + +inline const char* NamedMaximumNumberOfRegistersToString(NamedMaximumNumberOfRegisters value) { + switch (value) { + case NamedMaximumNumberOfRegistersAutoINTEL: return "AutoINTEL"; + default: return "Unknown"; + } +} + +inline const char* OpToString(Op value) { + switch (value) { + case OpNop: return "OpNop"; + case OpUndef: return "OpUndef"; + case OpSourceContinued: return "OpSourceContinued"; + case OpSource: return "OpSource"; + case OpSourceExtension: return "OpSourceExtension"; + case OpName: return "OpName"; + case OpMemberName: return "OpMemberName"; + case OpString: return "OpString"; + case OpLine: return "OpLine"; + case OpExtension: return "OpExtension"; + case OpExtInstImport: return "OpExtInstImport"; + case OpExtInst: return "OpExtInst"; + case OpMemoryModel: return "OpMemoryModel"; + case OpEntryPoint: return "OpEntryPoint"; + case OpExecutionMode: return "OpExecutionMode"; + case OpCapability: return "OpCapability"; + case OpTypeVoid: return "OpTypeVoid"; + case OpTypeBool: return "OpTypeBool"; + case OpTypeInt: return "OpTypeInt"; + case OpTypeFloat: return "OpTypeFloat"; + case OpTypeVector: return "OpTypeVector"; + case OpTypeMatrix: return "OpTypeMatrix"; + case OpTypeImage: return "OpTypeImage"; + case OpTypeSampler: return "OpTypeSampler"; + case OpTypeSampledImage: return "OpTypeSampledImage"; + case OpTypeArray: return "OpTypeArray"; + case OpTypeRuntimeArray: return "OpTypeRuntimeArray"; + case OpTypeStruct: return "OpTypeStruct"; + case OpTypeOpaque: return "OpTypeOpaque"; + case OpTypePointer: return "OpTypePointer"; + case OpTypeFunction: return "OpTypeFunction"; + case OpTypeEvent: return "OpTypeEvent"; + case OpTypeDeviceEvent: return "OpTypeDeviceEvent"; + case OpTypeReserveId: return "OpTypeReserveId"; + case OpTypeQueue: return "OpTypeQueue"; + case OpTypePipe: return "OpTypePipe"; + case OpTypeForwardPointer: return "OpTypeForwardPointer"; + case OpConstantTrue: return "OpConstantTrue"; + case OpConstantFalse: return "OpConstantFalse"; + case OpConstant: return "OpConstant"; + case OpConstantComposite: return "OpConstantComposite"; + case OpConstantSampler: return "OpConstantSampler"; + case OpConstantNull: return "OpConstantNull"; + case OpSpecConstantTrue: return "OpSpecConstantTrue"; + case OpSpecConstantFalse: return "OpSpecConstantFalse"; + case OpSpecConstant: return "OpSpecConstant"; + case OpSpecConstantComposite: return "OpSpecConstantComposite"; + case OpSpecConstantOp: return "OpSpecConstantOp"; + case OpFunction: return "OpFunction"; + case OpFunctionParameter: return "OpFunctionParameter"; + case OpFunctionEnd: return "OpFunctionEnd"; + case OpFunctionCall: return "OpFunctionCall"; + case OpVariable: return "OpVariable"; + case OpImageTexelPointer: return "OpImageTexelPointer"; + case OpLoad: return "OpLoad"; + case OpStore: return "OpStore"; + case OpCopyMemory: return "OpCopyMemory"; + case OpCopyMemorySized: return "OpCopyMemorySized"; + case OpAccessChain: return "OpAccessChain"; + case OpInBoundsAccessChain: return "OpInBoundsAccessChain"; + case OpPtrAccessChain: return "OpPtrAccessChain"; + case OpArrayLength: return "OpArrayLength"; + case OpGenericPtrMemSemantics: return "OpGenericPtrMemSemantics"; + case OpInBoundsPtrAccessChain: return "OpInBoundsPtrAccessChain"; + case OpDecorate: return "OpDecorate"; + case OpMemberDecorate: return "OpMemberDecorate"; + case OpDecorationGroup: return "OpDecorationGroup"; + case OpGroupDecorate: return "OpGroupDecorate"; + case OpGroupMemberDecorate: return "OpGroupMemberDecorate"; + case OpVectorExtractDynamic: return "OpVectorExtractDynamic"; + case OpVectorInsertDynamic: return "OpVectorInsertDynamic"; + case OpVectorShuffle: return "OpVectorShuffle"; + case OpCompositeConstruct: return "OpCompositeConstruct"; + case OpCompositeExtract: return "OpCompositeExtract"; + case OpCompositeInsert: return "OpCompositeInsert"; + case OpCopyObject: return "OpCopyObject"; + case OpTranspose: return "OpTranspose"; + case OpSampledImage: return "OpSampledImage"; + case OpImageSampleImplicitLod: return "OpImageSampleImplicitLod"; + case OpImageSampleExplicitLod: return "OpImageSampleExplicitLod"; + case OpImageSampleDrefImplicitLod: return "OpImageSampleDrefImplicitLod"; + case OpImageSampleDrefExplicitLod: return "OpImageSampleDrefExplicitLod"; + case OpImageSampleProjImplicitLod: return "OpImageSampleProjImplicitLod"; + case OpImageSampleProjExplicitLod: return "OpImageSampleProjExplicitLod"; + case OpImageSampleProjDrefImplicitLod: return "OpImageSampleProjDrefImplicitLod"; + case OpImageSampleProjDrefExplicitLod: return "OpImageSampleProjDrefExplicitLod"; + case OpImageFetch: return "OpImageFetch"; + case OpImageGather: return "OpImageGather"; + case OpImageDrefGather: return "OpImageDrefGather"; + case OpImageRead: return "OpImageRead"; + case OpImageWrite: return "OpImageWrite"; + case OpImage: return "OpImage"; + case OpImageQueryFormat: return "OpImageQueryFormat"; + case OpImageQueryOrder: return "OpImageQueryOrder"; + case OpImageQuerySizeLod: return "OpImageQuerySizeLod"; + case OpImageQuerySize: return "OpImageQuerySize"; + case OpImageQueryLod: return "OpImageQueryLod"; + case OpImageQueryLevels: return "OpImageQueryLevels"; + case OpImageQuerySamples: return "OpImageQuerySamples"; + case OpConvertFToU: return "OpConvertFToU"; + case OpConvertFToS: return "OpConvertFToS"; + case OpConvertSToF: return "OpConvertSToF"; + case OpConvertUToF: return "OpConvertUToF"; + case OpUConvert: return "OpUConvert"; + case OpSConvert: return "OpSConvert"; + case OpFConvert: return "OpFConvert"; + case OpQuantizeToF16: return "OpQuantizeToF16"; + case OpConvertPtrToU: return "OpConvertPtrToU"; + case OpSatConvertSToU: return "OpSatConvertSToU"; + case OpSatConvertUToS: return "OpSatConvertUToS"; + case OpConvertUToPtr: return "OpConvertUToPtr"; + case OpPtrCastToGeneric: return "OpPtrCastToGeneric"; + case OpGenericCastToPtr: return "OpGenericCastToPtr"; + case OpGenericCastToPtrExplicit: return "OpGenericCastToPtrExplicit"; + case OpBitcast: return "OpBitcast"; + case OpSNegate: return "OpSNegate"; + case OpFNegate: return "OpFNegate"; + case OpIAdd: return "OpIAdd"; + case OpFAdd: return "OpFAdd"; + case OpISub: return "OpISub"; + case OpFSub: return "OpFSub"; + case OpIMul: return "OpIMul"; + case OpFMul: return "OpFMul"; + case OpUDiv: return "OpUDiv"; + case OpSDiv: return "OpSDiv"; + case OpFDiv: return "OpFDiv"; + case OpUMod: return "OpUMod"; + case OpSRem: return "OpSRem"; + case OpSMod: return "OpSMod"; + case OpFRem: return "OpFRem"; + case OpFMod: return "OpFMod"; + case OpVectorTimesScalar: return "OpVectorTimesScalar"; + case OpMatrixTimesScalar: return "OpMatrixTimesScalar"; + case OpVectorTimesMatrix: return "OpVectorTimesMatrix"; + case OpMatrixTimesVector: return "OpMatrixTimesVector"; + case OpMatrixTimesMatrix: return "OpMatrixTimesMatrix"; + case OpOuterProduct: return "OpOuterProduct"; + case OpDot: return "OpDot"; + case OpIAddCarry: return "OpIAddCarry"; + case OpISubBorrow: return "OpISubBorrow"; + case OpUMulExtended: return "OpUMulExtended"; + case OpSMulExtended: return "OpSMulExtended"; + case OpAny: return "OpAny"; + case OpAll: return "OpAll"; + case OpIsNan: return "OpIsNan"; + case OpIsInf: return "OpIsInf"; + case OpIsFinite: return "OpIsFinite"; + case OpIsNormal: return "OpIsNormal"; + case OpSignBitSet: return "OpSignBitSet"; + case OpLessOrGreater: return "OpLessOrGreater"; + case OpOrdered: return "OpOrdered"; + case OpUnordered: return "OpUnordered"; + case OpLogicalEqual: return "OpLogicalEqual"; + case OpLogicalNotEqual: return "OpLogicalNotEqual"; + case OpLogicalOr: return "OpLogicalOr"; + case OpLogicalAnd: return "OpLogicalAnd"; + case OpLogicalNot: return "OpLogicalNot"; + case OpSelect: return "OpSelect"; + case OpIEqual: return "OpIEqual"; + case OpINotEqual: return "OpINotEqual"; + case OpUGreaterThan: return "OpUGreaterThan"; + case OpSGreaterThan: return "OpSGreaterThan"; + case OpUGreaterThanEqual: return "OpUGreaterThanEqual"; + case OpSGreaterThanEqual: return "OpSGreaterThanEqual"; + case OpULessThan: return "OpULessThan"; + case OpSLessThan: return "OpSLessThan"; + case OpULessThanEqual: return "OpULessThanEqual"; + case OpSLessThanEqual: return "OpSLessThanEqual"; + case OpFOrdEqual: return "OpFOrdEqual"; + case OpFUnordEqual: return "OpFUnordEqual"; + case OpFOrdNotEqual: return "OpFOrdNotEqual"; + case OpFUnordNotEqual: return "OpFUnordNotEqual"; + case OpFOrdLessThan: return "OpFOrdLessThan"; + case OpFUnordLessThan: return "OpFUnordLessThan"; + case OpFOrdGreaterThan: return "OpFOrdGreaterThan"; + case OpFUnordGreaterThan: return "OpFUnordGreaterThan"; + case OpFOrdLessThanEqual: return "OpFOrdLessThanEqual"; + case OpFUnordLessThanEqual: return "OpFUnordLessThanEqual"; + case OpFOrdGreaterThanEqual: return "OpFOrdGreaterThanEqual"; + case OpFUnordGreaterThanEqual: return "OpFUnordGreaterThanEqual"; + case OpShiftRightLogical: return "OpShiftRightLogical"; + case OpShiftRightArithmetic: return "OpShiftRightArithmetic"; + case OpShiftLeftLogical: return "OpShiftLeftLogical"; + case OpBitwiseOr: return "OpBitwiseOr"; + case OpBitwiseXor: return "OpBitwiseXor"; + case OpBitwiseAnd: return "OpBitwiseAnd"; + case OpNot: return "OpNot"; + case OpBitFieldInsert: return "OpBitFieldInsert"; + case OpBitFieldSExtract: return "OpBitFieldSExtract"; + case OpBitFieldUExtract: return "OpBitFieldUExtract"; + case OpBitReverse: return "OpBitReverse"; + case OpBitCount: return "OpBitCount"; + case OpDPdx: return "OpDPdx"; + case OpDPdy: return "OpDPdy"; + case OpFwidth: return "OpFwidth"; + case OpDPdxFine: return "OpDPdxFine"; + case OpDPdyFine: return "OpDPdyFine"; + case OpFwidthFine: return "OpFwidthFine"; + case OpDPdxCoarse: return "OpDPdxCoarse"; + case OpDPdyCoarse: return "OpDPdyCoarse"; + case OpFwidthCoarse: return "OpFwidthCoarse"; + case OpEmitVertex: return "OpEmitVertex"; + case OpEndPrimitive: return "OpEndPrimitive"; + case OpEmitStreamVertex: return "OpEmitStreamVertex"; + case OpEndStreamPrimitive: return "OpEndStreamPrimitive"; + case OpControlBarrier: return "OpControlBarrier"; + case OpMemoryBarrier: return "OpMemoryBarrier"; + case OpAtomicLoad: return "OpAtomicLoad"; + case OpAtomicStore: return "OpAtomicStore"; + case OpAtomicExchange: return "OpAtomicExchange"; + case OpAtomicCompareExchange: return "OpAtomicCompareExchange"; + case OpAtomicCompareExchangeWeak: return "OpAtomicCompareExchangeWeak"; + case OpAtomicIIncrement: return "OpAtomicIIncrement"; + case OpAtomicIDecrement: return "OpAtomicIDecrement"; + case OpAtomicIAdd: return "OpAtomicIAdd"; + case OpAtomicISub: return "OpAtomicISub"; + case OpAtomicSMin: return "OpAtomicSMin"; + case OpAtomicUMin: return "OpAtomicUMin"; + case OpAtomicSMax: return "OpAtomicSMax"; + case OpAtomicUMax: return "OpAtomicUMax"; + case OpAtomicAnd: return "OpAtomicAnd"; + case OpAtomicOr: return "OpAtomicOr"; + case OpAtomicXor: return "OpAtomicXor"; + case OpPhi: return "OpPhi"; + case OpLoopMerge: return "OpLoopMerge"; + case OpSelectionMerge: return "OpSelectionMerge"; + case OpLabel: return "OpLabel"; + case OpBranch: return "OpBranch"; + case OpBranchConditional: return "OpBranchConditional"; + case OpSwitch: return "OpSwitch"; + case OpKill: return "OpKill"; + case OpReturn: return "OpReturn"; + case OpReturnValue: return "OpReturnValue"; + case OpUnreachable: return "OpUnreachable"; + case OpLifetimeStart: return "OpLifetimeStart"; + case OpLifetimeStop: return "OpLifetimeStop"; + case OpGroupAsyncCopy: return "OpGroupAsyncCopy"; + case OpGroupWaitEvents: return "OpGroupWaitEvents"; + case OpGroupAll: return "OpGroupAll"; + case OpGroupAny: return "OpGroupAny"; + case OpGroupBroadcast: return "OpGroupBroadcast"; + case OpGroupIAdd: return "OpGroupIAdd"; + case OpGroupFAdd: return "OpGroupFAdd"; + case OpGroupFMin: return "OpGroupFMin"; + case OpGroupUMin: return "OpGroupUMin"; + case OpGroupSMin: return "OpGroupSMin"; + case OpGroupFMax: return "OpGroupFMax"; + case OpGroupUMax: return "OpGroupUMax"; + case OpGroupSMax: return "OpGroupSMax"; + case OpReadPipe: return "OpReadPipe"; + case OpWritePipe: return "OpWritePipe"; + case OpReservedReadPipe: return "OpReservedReadPipe"; + case OpReservedWritePipe: return "OpReservedWritePipe"; + case OpReserveReadPipePackets: return "OpReserveReadPipePackets"; + case OpReserveWritePipePackets: return "OpReserveWritePipePackets"; + case OpCommitReadPipe: return "OpCommitReadPipe"; + case OpCommitWritePipe: return "OpCommitWritePipe"; + case OpIsValidReserveId: return "OpIsValidReserveId"; + case OpGetNumPipePackets: return "OpGetNumPipePackets"; + case OpGetMaxPipePackets: return "OpGetMaxPipePackets"; + case OpGroupReserveReadPipePackets: return "OpGroupReserveReadPipePackets"; + case OpGroupReserveWritePipePackets: return "OpGroupReserveWritePipePackets"; + case OpGroupCommitReadPipe: return "OpGroupCommitReadPipe"; + case OpGroupCommitWritePipe: return "OpGroupCommitWritePipe"; + case OpEnqueueMarker: return "OpEnqueueMarker"; + case OpEnqueueKernel: return "OpEnqueueKernel"; + case OpGetKernelNDrangeSubGroupCount: return "OpGetKernelNDrangeSubGroupCount"; + case OpGetKernelNDrangeMaxSubGroupSize: return "OpGetKernelNDrangeMaxSubGroupSize"; + case OpGetKernelWorkGroupSize: return "OpGetKernelWorkGroupSize"; + case OpGetKernelPreferredWorkGroupSizeMultiple: return "OpGetKernelPreferredWorkGroupSizeMultiple"; + case OpRetainEvent: return "OpRetainEvent"; + case OpReleaseEvent: return "OpReleaseEvent"; + case OpCreateUserEvent: return "OpCreateUserEvent"; + case OpIsValidEvent: return "OpIsValidEvent"; + case OpSetUserEventStatus: return "OpSetUserEventStatus"; + case OpCaptureEventProfilingInfo: return "OpCaptureEventProfilingInfo"; + case OpGetDefaultQueue: return "OpGetDefaultQueue"; + case OpBuildNDRange: return "OpBuildNDRange"; + case OpImageSparseSampleImplicitLod: return "OpImageSparseSampleImplicitLod"; + case OpImageSparseSampleExplicitLod: return "OpImageSparseSampleExplicitLod"; + case OpImageSparseSampleDrefImplicitLod: return "OpImageSparseSampleDrefImplicitLod"; + case OpImageSparseSampleDrefExplicitLod: return "OpImageSparseSampleDrefExplicitLod"; + case OpImageSparseSampleProjImplicitLod: return "OpImageSparseSampleProjImplicitLod"; + case OpImageSparseSampleProjExplicitLod: return "OpImageSparseSampleProjExplicitLod"; + case OpImageSparseSampleProjDrefImplicitLod: return "OpImageSparseSampleProjDrefImplicitLod"; + case OpImageSparseSampleProjDrefExplicitLod: return "OpImageSparseSampleProjDrefExplicitLod"; + case OpImageSparseFetch: return "OpImageSparseFetch"; + case OpImageSparseGather: return "OpImageSparseGather"; + case OpImageSparseDrefGather: return "OpImageSparseDrefGather"; + case OpImageSparseTexelsResident: return "OpImageSparseTexelsResident"; + case OpNoLine: return "OpNoLine"; + case OpAtomicFlagTestAndSet: return "OpAtomicFlagTestAndSet"; + case OpAtomicFlagClear: return "OpAtomicFlagClear"; + case OpImageSparseRead: return "OpImageSparseRead"; + case OpSizeOf: return "OpSizeOf"; + case OpTypePipeStorage: return "OpTypePipeStorage"; + case OpConstantPipeStorage: return "OpConstantPipeStorage"; + case OpCreatePipeFromPipeStorage: return "OpCreatePipeFromPipeStorage"; + case OpGetKernelLocalSizeForSubgroupCount: return "OpGetKernelLocalSizeForSubgroupCount"; + case OpGetKernelMaxNumSubgroups: return "OpGetKernelMaxNumSubgroups"; + case OpTypeNamedBarrier: return "OpTypeNamedBarrier"; + case OpNamedBarrierInitialize: return "OpNamedBarrierInitialize"; + case OpMemoryNamedBarrier: return "OpMemoryNamedBarrier"; + case OpModuleProcessed: return "OpModuleProcessed"; + case OpExecutionModeId: return "OpExecutionModeId"; + case OpDecorateId: return "OpDecorateId"; + case OpGroupNonUniformElect: return "OpGroupNonUniformElect"; + case OpGroupNonUniformAll: return "OpGroupNonUniformAll"; + case OpGroupNonUniformAny: return "OpGroupNonUniformAny"; + case OpGroupNonUniformAllEqual: return "OpGroupNonUniformAllEqual"; + case OpGroupNonUniformBroadcast: return "OpGroupNonUniformBroadcast"; + case OpGroupNonUniformBroadcastFirst: return "OpGroupNonUniformBroadcastFirst"; + case OpGroupNonUniformBallot: return "OpGroupNonUniformBallot"; + case OpGroupNonUniformInverseBallot: return "OpGroupNonUniformInverseBallot"; + case OpGroupNonUniformBallotBitExtract: return "OpGroupNonUniformBallotBitExtract"; + case OpGroupNonUniformBallotBitCount: return "OpGroupNonUniformBallotBitCount"; + case OpGroupNonUniformBallotFindLSB: return "OpGroupNonUniformBallotFindLSB"; + case OpGroupNonUniformBallotFindMSB: return "OpGroupNonUniformBallotFindMSB"; + case OpGroupNonUniformShuffle: return "OpGroupNonUniformShuffle"; + case OpGroupNonUniformShuffleXor: return "OpGroupNonUniformShuffleXor"; + case OpGroupNonUniformShuffleUp: return "OpGroupNonUniformShuffleUp"; + case OpGroupNonUniformShuffleDown: return "OpGroupNonUniformShuffleDown"; + case OpGroupNonUniformIAdd: return "OpGroupNonUniformIAdd"; + case OpGroupNonUniformFAdd: return "OpGroupNonUniformFAdd"; + case OpGroupNonUniformIMul: return "OpGroupNonUniformIMul"; + case OpGroupNonUniformFMul: return "OpGroupNonUniformFMul"; + case OpGroupNonUniformSMin: return "OpGroupNonUniformSMin"; + case OpGroupNonUniformUMin: return "OpGroupNonUniformUMin"; + case OpGroupNonUniformFMin: return "OpGroupNonUniformFMin"; + case OpGroupNonUniformSMax: return "OpGroupNonUniformSMax"; + case OpGroupNonUniformUMax: return "OpGroupNonUniformUMax"; + case OpGroupNonUniformFMax: return "OpGroupNonUniformFMax"; + case OpGroupNonUniformBitwiseAnd: return "OpGroupNonUniformBitwiseAnd"; + case OpGroupNonUniformBitwiseOr: return "OpGroupNonUniformBitwiseOr"; + case OpGroupNonUniformBitwiseXor: return "OpGroupNonUniformBitwiseXor"; + case OpGroupNonUniformLogicalAnd: return "OpGroupNonUniformLogicalAnd"; + case OpGroupNonUniformLogicalOr: return "OpGroupNonUniformLogicalOr"; + case OpGroupNonUniformLogicalXor: return "OpGroupNonUniformLogicalXor"; + case OpGroupNonUniformQuadBroadcast: return "OpGroupNonUniformQuadBroadcast"; + case OpGroupNonUniformQuadSwap: return "OpGroupNonUniformQuadSwap"; + case OpCopyLogical: return "OpCopyLogical"; + case OpPtrEqual: return "OpPtrEqual"; + case OpPtrNotEqual: return "OpPtrNotEqual"; + case OpPtrDiff: return "OpPtrDiff"; + case OpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT"; + case OpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT"; + case OpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT"; + case OpTerminateInvocation: return "OpTerminateInvocation"; + case OpSubgroupBallotKHR: return "OpSubgroupBallotKHR"; + case OpSubgroupFirstInvocationKHR: return "OpSubgroupFirstInvocationKHR"; + case OpSubgroupAllKHR: return "OpSubgroupAllKHR"; + case OpSubgroupAnyKHR: return "OpSubgroupAnyKHR"; + case OpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR"; + case OpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR"; + case OpSubgroupReadInvocationKHR: return "OpSubgroupReadInvocationKHR"; + case OpExtInstWithForwardRefsKHR: return "OpExtInstWithForwardRefsKHR"; + case OpTraceRayKHR: return "OpTraceRayKHR"; + case OpExecuteCallableKHR: return "OpExecuteCallableKHR"; + case OpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR"; + case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case OpTerminateRayKHR: return "OpTerminateRayKHR"; + case OpSDot: return "OpSDot"; + case OpUDot: return "OpUDot"; + case OpSUDot: return "OpSUDot"; + case OpSDotAccSat: return "OpSDotAccSat"; + case OpUDotAccSat: return "OpUDotAccSat"; + case OpSUDotAccSat: return "OpSUDotAccSat"; + case OpTypeCooperativeMatrixKHR: return "OpTypeCooperativeMatrixKHR"; + case OpCooperativeMatrixLoadKHR: return "OpCooperativeMatrixLoadKHR"; + case OpCooperativeMatrixStoreKHR: return "OpCooperativeMatrixStoreKHR"; + case OpCooperativeMatrixMulAddKHR: return "OpCooperativeMatrixMulAddKHR"; + case OpCooperativeMatrixLengthKHR: return "OpCooperativeMatrixLengthKHR"; + case OpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT"; + case OpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT"; + case OpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT"; + case OpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; + case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case OpImageSampleWeightedQCOM: return "OpImageSampleWeightedQCOM"; + case OpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; + case OpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + case OpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; + case OpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM"; + case OpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM"; + case OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; + case OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; + case OpGroupIAddNonUniformAMD: return "OpGroupIAddNonUniformAMD"; + case OpGroupFAddNonUniformAMD: return "OpGroupFAddNonUniformAMD"; + case OpGroupFMinNonUniformAMD: return "OpGroupFMinNonUniformAMD"; + case OpGroupUMinNonUniformAMD: return "OpGroupUMinNonUniformAMD"; + case OpGroupSMinNonUniformAMD: return "OpGroupSMinNonUniformAMD"; + case OpGroupFMaxNonUniformAMD: return "OpGroupFMaxNonUniformAMD"; + case OpGroupUMaxNonUniformAMD: return "OpGroupUMaxNonUniformAMD"; + case OpGroupSMaxNonUniformAMD: return "OpGroupSMaxNonUniformAMD"; + case OpFragmentMaskFetchAMD: return "OpFragmentMaskFetchAMD"; + case OpFragmentFetchAMD: return "OpFragmentFetchAMD"; + case OpReadClockKHR: return "OpReadClockKHR"; + case OpFinalizeNodePayloadsAMDX: return "OpFinalizeNodePayloadsAMDX"; + case OpFinishWritingNodePayloadAMDX: return "OpFinishWritingNodePayloadAMDX"; + case OpInitializeNodePayloadsAMDX: return "OpInitializeNodePayloadsAMDX"; + case OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; + case OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; + case OpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; + case OpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; + case OpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; + case OpHitObjectGetWorldToObjectNV: return "OpHitObjectGetWorldToObjectNV"; + case OpHitObjectGetObjectToWorldNV: return "OpHitObjectGetObjectToWorldNV"; + case OpHitObjectGetObjectRayDirectionNV: return "OpHitObjectGetObjectRayDirectionNV"; + case OpHitObjectGetObjectRayOriginNV: return "OpHitObjectGetObjectRayOriginNV"; + case OpHitObjectTraceRayMotionNV: return "OpHitObjectTraceRayMotionNV"; + case OpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV"; + case OpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV"; + case OpHitObjectRecordEmptyNV: return "OpHitObjectRecordEmptyNV"; + case OpHitObjectTraceRayNV: return "OpHitObjectTraceRayNV"; + case OpHitObjectRecordHitNV: return "OpHitObjectRecordHitNV"; + case OpHitObjectRecordHitWithIndexNV: return "OpHitObjectRecordHitWithIndexNV"; + case OpHitObjectRecordMissNV: return "OpHitObjectRecordMissNV"; + case OpHitObjectExecuteShaderNV: return "OpHitObjectExecuteShaderNV"; + case OpHitObjectGetCurrentTimeNV: return "OpHitObjectGetCurrentTimeNV"; + case OpHitObjectGetAttributesNV: return "OpHitObjectGetAttributesNV"; + case OpHitObjectGetHitKindNV: return "OpHitObjectGetHitKindNV"; + case OpHitObjectGetPrimitiveIndexNV: return "OpHitObjectGetPrimitiveIndexNV"; + case OpHitObjectGetGeometryIndexNV: return "OpHitObjectGetGeometryIndexNV"; + case OpHitObjectGetInstanceIdNV: return "OpHitObjectGetInstanceIdNV"; + case OpHitObjectGetInstanceCustomIndexNV: return "OpHitObjectGetInstanceCustomIndexNV"; + case OpHitObjectGetWorldRayDirectionNV: return "OpHitObjectGetWorldRayDirectionNV"; + case OpHitObjectGetWorldRayOriginNV: return "OpHitObjectGetWorldRayOriginNV"; + case OpHitObjectGetRayTMaxNV: return "OpHitObjectGetRayTMaxNV"; + case OpHitObjectGetRayTMinNV: return "OpHitObjectGetRayTMinNV"; + case OpHitObjectIsEmptyNV: return "OpHitObjectIsEmptyNV"; + case OpHitObjectIsHitNV: return "OpHitObjectIsHitNV"; + case OpHitObjectIsMissNV: return "OpHitObjectIsMissNV"; + case OpReorderThreadWithHitObjectNV: return "OpReorderThreadWithHitObjectNV"; + case OpReorderThreadWithHintNV: return "OpReorderThreadWithHintNV"; + case OpTypeHitObjectNV: return "OpTypeHitObjectNV"; + case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; + case OpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT"; + case OpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT"; + case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; + case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case OpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV"; + case OpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV"; + case OpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case OpTerminateRayNV: return "OpTerminateRayNV"; + case OpTraceNV: return "OpTraceNV"; + case OpTraceMotionNV: return "OpTraceMotionNV"; + case OpTraceRayMotionNV: return "OpTraceRayMotionNV"; + case OpRayQueryGetIntersectionTriangleVertexPositionsKHR: return "OpRayQueryGetIntersectionTriangleVertexPositionsKHR"; + case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case OpExecuteCallableNV: return "OpExecuteCallableNV"; + case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + case OpDemoteToHelperInvocation: return "OpDemoteToHelperInvocation"; + case OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + case OpConvertUToImageNV: return "OpConvertUToImageNV"; + case OpConvertUToSamplerNV: return "OpConvertUToSamplerNV"; + case OpConvertImageToUNV: return "OpConvertImageToUNV"; + case OpConvertSamplerToUNV: return "OpConvertSamplerToUNV"; + case OpConvertUToSampledImageNV: return "OpConvertUToSampledImageNV"; + case OpConvertSampledImageToUNV: return "OpConvertSampledImageToUNV"; + case OpSamplerImageAddressingModeNV: return "OpSamplerImageAddressingModeNV"; + case OpRawAccessChainNV: return "OpRawAccessChainNV"; + case OpSubgroupShuffleINTEL: return "OpSubgroupShuffleINTEL"; + case OpSubgroupShuffleDownINTEL: return "OpSubgroupShuffleDownINTEL"; + case OpSubgroupShuffleUpINTEL: return "OpSubgroupShuffleUpINTEL"; + case OpSubgroupShuffleXorINTEL: return "OpSubgroupShuffleXorINTEL"; + case OpSubgroupBlockReadINTEL: return "OpSubgroupBlockReadINTEL"; + case OpSubgroupBlockWriteINTEL: return "OpSubgroupBlockWriteINTEL"; + case OpSubgroupImageBlockReadINTEL: return "OpSubgroupImageBlockReadINTEL"; + case OpSubgroupImageBlockWriteINTEL: return "OpSubgroupImageBlockWriteINTEL"; + case OpSubgroupImageMediaBlockReadINTEL: return "OpSubgroupImageMediaBlockReadINTEL"; + case OpSubgroupImageMediaBlockWriteINTEL: return "OpSubgroupImageMediaBlockWriteINTEL"; + case OpUCountLeadingZerosINTEL: return "OpUCountLeadingZerosINTEL"; + case OpUCountTrailingZerosINTEL: return "OpUCountTrailingZerosINTEL"; + case OpAbsISubINTEL: return "OpAbsISubINTEL"; + case OpAbsUSubINTEL: return "OpAbsUSubINTEL"; + case OpIAddSatINTEL: return "OpIAddSatINTEL"; + case OpUAddSatINTEL: return "OpUAddSatINTEL"; + case OpIAverageINTEL: return "OpIAverageINTEL"; + case OpUAverageINTEL: return "OpUAverageINTEL"; + case OpIAverageRoundedINTEL: return "OpIAverageRoundedINTEL"; + case OpUAverageRoundedINTEL: return "OpUAverageRoundedINTEL"; + case OpISubSatINTEL: return "OpISubSatINTEL"; + case OpUSubSatINTEL: return "OpUSubSatINTEL"; + case OpIMul32x16INTEL: return "OpIMul32x16INTEL"; + case OpUMul32x16INTEL: return "OpUMul32x16INTEL"; + case OpConstantFunctionPointerINTEL: return "OpConstantFunctionPointerINTEL"; + case OpFunctionPointerCallINTEL: return "OpFunctionPointerCallINTEL"; + case OpAsmTargetINTEL: return "OpAsmTargetINTEL"; + case OpAsmINTEL: return "OpAsmINTEL"; + case OpAsmCallINTEL: return "OpAsmCallINTEL"; + case OpAtomicFMinEXT: return "OpAtomicFMinEXT"; + case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; + case OpAssumeTrueKHR: return "OpAssumeTrueKHR"; + case OpExpectKHR: return "OpExpectKHR"; + case OpDecorateString: return "OpDecorateString"; + case OpMemberDecorateString: return "OpMemberDecorateString"; + case OpVmeImageINTEL: return "OpVmeImageINTEL"; + case OpTypeVmeImageINTEL: return "OpTypeVmeImageINTEL"; + case OpTypeAvcImePayloadINTEL: return "OpTypeAvcImePayloadINTEL"; + case OpTypeAvcRefPayloadINTEL: return "OpTypeAvcRefPayloadINTEL"; + case OpTypeAvcSicPayloadINTEL: return "OpTypeAvcSicPayloadINTEL"; + case OpTypeAvcMcePayloadINTEL: return "OpTypeAvcMcePayloadINTEL"; + case OpTypeAvcMceResultINTEL: return "OpTypeAvcMceResultINTEL"; + case OpTypeAvcImeResultINTEL: return "OpTypeAvcImeResultINTEL"; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: return "OpTypeAvcImeResultSingleReferenceStreamoutINTEL"; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: return "OpTypeAvcImeResultDualReferenceStreamoutINTEL"; + case OpTypeAvcImeSingleReferenceStreaminINTEL: return "OpTypeAvcImeSingleReferenceStreaminINTEL"; + case OpTypeAvcImeDualReferenceStreaminINTEL: return "OpTypeAvcImeDualReferenceStreaminINTEL"; + case OpTypeAvcRefResultINTEL: return "OpTypeAvcRefResultINTEL"; + case OpTypeAvcSicResultINTEL: return "OpTypeAvcSicResultINTEL"; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL"; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL"; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: return "OpSubgroupAvcMceSetInterShapePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL"; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: return "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL"; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: return "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL"; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL"; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: return "OpSubgroupAvcMceSetAcOnlyHaarINTEL"; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL"; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL"; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL"; + case OpSubgroupAvcMceConvertToImePayloadINTEL: return "OpSubgroupAvcMceConvertToImePayloadINTEL"; + case OpSubgroupAvcMceConvertToImeResultINTEL: return "OpSubgroupAvcMceConvertToImeResultINTEL"; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: return "OpSubgroupAvcMceConvertToRefPayloadINTEL"; + case OpSubgroupAvcMceConvertToRefResultINTEL: return "OpSubgroupAvcMceConvertToRefResultINTEL"; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: return "OpSubgroupAvcMceConvertToSicPayloadINTEL"; + case OpSubgroupAvcMceConvertToSicResultINTEL: return "OpSubgroupAvcMceConvertToSicResultINTEL"; + case OpSubgroupAvcMceGetMotionVectorsINTEL: return "OpSubgroupAvcMceGetMotionVectorsINTEL"; + case OpSubgroupAvcMceGetInterDistortionsINTEL: return "OpSubgroupAvcMceGetInterDistortionsINTEL"; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: return "OpSubgroupAvcMceGetBestInterDistortionsINTEL"; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: return "OpSubgroupAvcMceGetInterMajorShapeINTEL"; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: return "OpSubgroupAvcMceGetInterMinorShapeINTEL"; + case OpSubgroupAvcMceGetInterDirectionsINTEL: return "OpSubgroupAvcMceGetInterDirectionsINTEL"; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: return "OpSubgroupAvcMceGetInterMotionVectorCountINTEL"; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: return "OpSubgroupAvcMceGetInterReferenceIdsINTEL"; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL"; + case OpSubgroupAvcImeInitializeINTEL: return "OpSubgroupAvcImeInitializeINTEL"; + case OpSubgroupAvcImeSetSingleReferenceINTEL: return "OpSubgroupAvcImeSetSingleReferenceINTEL"; + case OpSubgroupAvcImeSetDualReferenceINTEL: return "OpSubgroupAvcImeSetDualReferenceINTEL"; + case OpSubgroupAvcImeRefWindowSizeINTEL: return "OpSubgroupAvcImeRefWindowSizeINTEL"; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: return "OpSubgroupAvcImeAdjustRefOffsetINTEL"; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: return "OpSubgroupAvcImeConvertToMcePayloadINTEL"; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: return "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL"; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: return "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL"; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: return "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL"; + case OpSubgroupAvcImeSetWeightedSadINTEL: return "OpSubgroupAvcImeSetWeightedSadINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL"; + case OpSubgroupAvcImeConvertToMceResultINTEL: return "OpSubgroupAvcImeConvertToMceResultINTEL"; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL"; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: return "OpSubgroupAvcImeGetDualReferenceStreaminINTEL"; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL"; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL"; + case OpSubgroupAvcImeGetBorderReachedINTEL: return "OpSubgroupAvcImeGetBorderReachedINTEL"; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: return "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL"; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: return "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL"; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL"; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL"; + case OpSubgroupAvcFmeInitializeINTEL: return "OpSubgroupAvcFmeInitializeINTEL"; + case OpSubgroupAvcBmeInitializeINTEL: return "OpSubgroupAvcBmeInitializeINTEL"; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: return "OpSubgroupAvcRefConvertToMcePayloadINTEL"; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: return "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL"; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: return "OpSubgroupAvcRefSetBilinearFilterEnableINTEL"; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL"; + case OpSubgroupAvcRefConvertToMceResultINTEL: return "OpSubgroupAvcRefConvertToMceResultINTEL"; + case OpSubgroupAvcSicInitializeINTEL: return "OpSubgroupAvcSicInitializeINTEL"; + case OpSubgroupAvcSicConfigureSkcINTEL: return "OpSubgroupAvcSicConfigureSkcINTEL"; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaINTEL"; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL"; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: return "OpSubgroupAvcSicGetMotionVectorMaskINTEL"; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: return "OpSubgroupAvcSicConvertToMcePayloadINTEL"; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL"; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL"; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL"; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: return "OpSubgroupAvcSicSetBilinearFilterEnableINTEL"; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: return "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL"; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: return "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL"; + case OpSubgroupAvcSicEvaluateIpeINTEL: return "OpSubgroupAvcSicEvaluateIpeINTEL"; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL"; + case OpSubgroupAvcSicConvertToMceResultINTEL: return "OpSubgroupAvcSicConvertToMceResultINTEL"; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: return "OpSubgroupAvcSicGetIpeLumaShapeINTEL"; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL"; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL"; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: return "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL"; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: return "OpSubgroupAvcSicGetIpeChromaModeINTEL"; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL"; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL"; + case OpSubgroupAvcSicGetInterRawSadsINTEL: return "OpSubgroupAvcSicGetInterRawSadsINTEL"; + case OpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL"; + case OpSaveMemoryINTEL: return "OpSaveMemoryINTEL"; + case OpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL"; + case OpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL"; + case OpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL"; + case OpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL"; + case OpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL"; + case OpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL"; + case OpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL"; + case OpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL"; + case OpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL"; + case OpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL"; + case OpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL"; + case OpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL"; + case OpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL"; + case OpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL"; + case OpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL"; + case OpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL"; + case OpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL"; + case OpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL"; + case OpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL"; + case OpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL"; + case OpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL"; + case OpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL"; + case OpArbitraryFloatLog1pINTEL: return "OpArbitraryFloatLog1pINTEL"; + case OpArbitraryFloatExpINTEL: return "OpArbitraryFloatExpINTEL"; + case OpArbitraryFloatExp2INTEL: return "OpArbitraryFloatExp2INTEL"; + case OpArbitraryFloatExp10INTEL: return "OpArbitraryFloatExp10INTEL"; + case OpArbitraryFloatExpm1INTEL: return "OpArbitraryFloatExpm1INTEL"; + case OpArbitraryFloatSinINTEL: return "OpArbitraryFloatSinINTEL"; + case OpArbitraryFloatCosINTEL: return "OpArbitraryFloatCosINTEL"; + case OpArbitraryFloatSinCosINTEL: return "OpArbitraryFloatSinCosINTEL"; + case OpArbitraryFloatSinPiINTEL: return "OpArbitraryFloatSinPiINTEL"; + case OpArbitraryFloatCosPiINTEL: return "OpArbitraryFloatCosPiINTEL"; + case OpArbitraryFloatASinINTEL: return "OpArbitraryFloatASinINTEL"; + case OpArbitraryFloatASinPiINTEL: return "OpArbitraryFloatASinPiINTEL"; + case OpArbitraryFloatACosINTEL: return "OpArbitraryFloatACosINTEL"; + case OpArbitraryFloatACosPiINTEL: return "OpArbitraryFloatACosPiINTEL"; + case OpArbitraryFloatATanINTEL: return "OpArbitraryFloatATanINTEL"; + case OpArbitraryFloatATanPiINTEL: return "OpArbitraryFloatATanPiINTEL"; + case OpArbitraryFloatATan2INTEL: return "OpArbitraryFloatATan2INTEL"; + case OpArbitraryFloatPowINTEL: return "OpArbitraryFloatPowINTEL"; + case OpArbitraryFloatPowRINTEL: return "OpArbitraryFloatPowRINTEL"; + case OpArbitraryFloatPowNINTEL: return "OpArbitraryFloatPowNINTEL"; + case OpLoopControlINTEL: return "OpLoopControlINTEL"; + case OpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL"; + case OpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL"; + case OpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL"; + case OpFixedSqrtINTEL: return "OpFixedSqrtINTEL"; + case OpFixedRecipINTEL: return "OpFixedRecipINTEL"; + case OpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL"; + case OpFixedSinINTEL: return "OpFixedSinINTEL"; + case OpFixedCosINTEL: return "OpFixedCosINTEL"; + case OpFixedSinCosINTEL: return "OpFixedSinCosINTEL"; + case OpFixedSinPiINTEL: return "OpFixedSinPiINTEL"; + case OpFixedCosPiINTEL: return "OpFixedCosPiINTEL"; + case OpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL"; + case OpFixedLogINTEL: return "OpFixedLogINTEL"; + case OpFixedExpINTEL: return "OpFixedExpINTEL"; + case OpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL"; + case OpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL"; + case OpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL"; + case OpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL"; + case OpFPGARegINTEL: return "OpFPGARegINTEL"; + case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case OpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case OpTypeBufferSurfaceINTEL: return "OpTypeBufferSurfaceINTEL"; + case OpTypeStructContinuedINTEL: return "OpTypeStructContinuedINTEL"; + case OpConstantCompositeContinuedINTEL: return "OpConstantCompositeContinuedINTEL"; + case OpSpecConstantCompositeContinuedINTEL: return "OpSpecConstantCompositeContinuedINTEL"; + case OpCompositeConstructContinuedINTEL: return "OpCompositeConstructContinuedINTEL"; + case OpConvertFToBF16INTEL: return "OpConvertFToBF16INTEL"; + case OpConvertBF16ToFINTEL: return "OpConvertBF16ToFINTEL"; + case OpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL"; + case OpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL"; + case OpGroupIMulKHR: return "OpGroupIMulKHR"; + case OpGroupFMulKHR: return "OpGroupFMulKHR"; + case OpGroupBitwiseAndKHR: return "OpGroupBitwiseAndKHR"; + case OpGroupBitwiseOrKHR: return "OpGroupBitwiseOrKHR"; + case OpGroupBitwiseXorKHR: return "OpGroupBitwiseXorKHR"; + case OpGroupLogicalAndKHR: return "OpGroupLogicalAndKHR"; + case OpGroupLogicalOrKHR: return "OpGroupLogicalOrKHR"; + case OpGroupLogicalXorKHR: return "OpGroupLogicalXorKHR"; + case OpMaskedGatherINTEL: return "OpMaskedGatherINTEL"; + case OpMaskedScatterINTEL: return "OpMaskedScatterINTEL"; + default: return "Unknown"; + } +} + +#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)); } +inline RawAccessChainOperandsMask operator|(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) | unsigned(b)); } +inline RawAccessChainOperandsMask operator&(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) & unsigned(b)); } +inline RawAccessChainOperandsMask operator^(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) ^ unsigned(b)); } +inline RawAccessChainOperandsMask operator~(RawAccessChainOperandsMask a) { return RawAccessChainOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.hpp11 b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.hpp11 new file mode 100644 index 0000000..25177a4 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.hpp11 @@ -0,0 +1,4736 @@ +// 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, + CooperativeMatrixLayoutsARM = 4201, + 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, + RawAccessChainsNV = 5414, + 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, + ReplicatedCompositesEXT = 6024, + 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, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, + 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 RawAccessChainOperandsShift : unsigned { + RobustnessPerComponentNV = 0, + RobustnessPerElementNV = 1, + Max = 0x7fffffff, +}; + +enum class RawAccessChainOperandsMask : unsigned { + MaskNone = 0, + RobustnessPerComponentNV = 0x00000001, + RobustnessPerElementNV = 0x00000002, +}; + +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, + OpExtInstWithForwardRefsKHR = 4433, + 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, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + 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, + OpRawAccessChainNV = 5398, + 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::OpExtInstWithForwardRefsKHR: *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::OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeConstructReplicateEXT: *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::OpReportIntersectionKHR: *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::OpTypeAccelerationStructureKHR: *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::OpRawAccessChainNV: *hasResult = true; *hasResultType = true; 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; + } +} +inline const char* SourceLanguageToString(SourceLanguage value) { + switch (value) { + case SourceLanguageUnknown: return "Unknown"; + case SourceLanguageESSL: return "ESSL"; + case SourceLanguageGLSL: return "GLSL"; + case SourceLanguageOpenCL_C: return "OpenCL_C"; + case SourceLanguageOpenCL_CPP: return "OpenCL_CPP"; + case SourceLanguageHLSL: return "HLSL"; + case SourceLanguageCPP_for_OpenCL: return "CPP_for_OpenCL"; + case SourceLanguageSYCL: return "SYCL"; + case SourceLanguageHERO_C: return "HERO_C"; + case SourceLanguageNZSL: return "NZSL"; + case SourceLanguageWGSL: return "WGSL"; + case SourceLanguageSlang: return "Slang"; + case SourceLanguageZig: return "Zig"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModelToString(ExecutionModel value) { + switch (value) { + case ExecutionModelVertex: return "Vertex"; + case ExecutionModelTessellationControl: return "TessellationControl"; + case ExecutionModelTessellationEvaluation: return "TessellationEvaluation"; + case ExecutionModelGeometry: return "Geometry"; + case ExecutionModelFragment: return "Fragment"; + case ExecutionModelGLCompute: return "GLCompute"; + case ExecutionModelKernel: return "Kernel"; + case ExecutionModelTaskNV: return "TaskNV"; + case ExecutionModelMeshNV: return "MeshNV"; + case ExecutionModelRayGenerationKHR: return "RayGenerationKHR"; + case ExecutionModelIntersectionKHR: return "IntersectionKHR"; + case ExecutionModelAnyHitKHR: return "AnyHitKHR"; + case ExecutionModelClosestHitKHR: return "ClosestHitKHR"; + case ExecutionModelMissKHR: return "MissKHR"; + case ExecutionModelCallableKHR: return "CallableKHR"; + case ExecutionModelTaskEXT: return "TaskEXT"; + case ExecutionModelMeshEXT: return "MeshEXT"; + default: return "Unknown"; + } +} + +inline const char* AddressingModelToString(AddressingModel value) { + switch (value) { + case AddressingModelLogical: return "Logical"; + case AddressingModelPhysical32: return "Physical32"; + case AddressingModelPhysical64: return "Physical64"; + case AddressingModelPhysicalStorageBuffer64: return "PhysicalStorageBuffer64"; + default: return "Unknown"; + } +} + +inline const char* MemoryModelToString(MemoryModel value) { + switch (value) { + case MemoryModelSimple: return "Simple"; + case MemoryModelGLSL450: return "GLSL450"; + case MemoryModelOpenCL: return "OpenCL"; + case MemoryModelVulkan: return "Vulkan"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModeToString(ExecutionMode value) { + switch (value) { + case ExecutionModeInvocations: return "Invocations"; + case ExecutionModeSpacingEqual: return "SpacingEqual"; + case ExecutionModeSpacingFractionalEven: return "SpacingFractionalEven"; + case ExecutionModeSpacingFractionalOdd: return "SpacingFractionalOdd"; + case ExecutionModeVertexOrderCw: return "VertexOrderCw"; + case ExecutionModeVertexOrderCcw: return "VertexOrderCcw"; + case ExecutionModePixelCenterInteger: return "PixelCenterInteger"; + case ExecutionModeOriginUpperLeft: return "OriginUpperLeft"; + case ExecutionModeOriginLowerLeft: return "OriginLowerLeft"; + case ExecutionModeEarlyFragmentTests: return "EarlyFragmentTests"; + case ExecutionModePointMode: return "PointMode"; + case ExecutionModeXfb: return "Xfb"; + case ExecutionModeDepthReplacing: return "DepthReplacing"; + case ExecutionModeDepthGreater: return "DepthGreater"; + case ExecutionModeDepthLess: return "DepthLess"; + case ExecutionModeDepthUnchanged: return "DepthUnchanged"; + case ExecutionModeLocalSize: return "LocalSize"; + case ExecutionModeLocalSizeHint: return "LocalSizeHint"; + case ExecutionModeInputPoints: return "InputPoints"; + case ExecutionModeInputLines: return "InputLines"; + case ExecutionModeInputLinesAdjacency: return "InputLinesAdjacency"; + case ExecutionModeTriangles: return "Triangles"; + case ExecutionModeInputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case ExecutionModeQuads: return "Quads"; + case ExecutionModeIsolines: return "Isolines"; + case ExecutionModeOutputVertices: return "OutputVertices"; + case ExecutionModeOutputPoints: return "OutputPoints"; + case ExecutionModeOutputLineStrip: return "OutputLineStrip"; + case ExecutionModeOutputTriangleStrip: return "OutputTriangleStrip"; + case ExecutionModeVecTypeHint: return "VecTypeHint"; + case ExecutionModeContractionOff: return "ContractionOff"; + case ExecutionModeInitializer: return "Initializer"; + case ExecutionModeFinalizer: return "Finalizer"; + case ExecutionModeSubgroupSize: return "SubgroupSize"; + case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case ExecutionModeLocalSizeId: return "LocalSizeId"; + case ExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + case ExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT"; + case ExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT"; + case ExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT"; + case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlowKHR"; + case ExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case ExecutionModeDenormPreserve: return "DenormPreserve"; + case ExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case ExecutionModeEarlyAndLateFragmentTestsAMD: return "EarlyAndLateFragmentTestsAMD"; + case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case ExecutionModeCoalescingAMDX: return "CoalescingAMDX"; + case ExecutionModeMaxNodeRecursionAMDX: return "MaxNodeRecursionAMDX"; + case ExecutionModeStaticNumWorkgroupsAMDX: return "StaticNumWorkgroupsAMDX"; + case ExecutionModeShaderIndexAMDX: return "ShaderIndexAMDX"; + case ExecutionModeMaxNumWorkgroupsAMDX: return "MaxNumWorkgroupsAMDX"; + case ExecutionModeStencilRefUnchangedFrontAMD: return "StencilRefUnchangedFrontAMD"; + case ExecutionModeStencilRefGreaterFrontAMD: return "StencilRefGreaterFrontAMD"; + case ExecutionModeStencilRefLessFrontAMD: return "StencilRefLessFrontAMD"; + case ExecutionModeStencilRefUnchangedBackAMD: return "StencilRefUnchangedBackAMD"; + case ExecutionModeStencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD"; + case ExecutionModeStencilRefLessBackAMD: return "StencilRefLessBackAMD"; + case ExecutionModeQuadDerivativesKHR: return "QuadDerivativesKHR"; + case ExecutionModeRequireFullQuadsKHR: return "RequireFullQuadsKHR"; + case ExecutionModeOutputLinesEXT: return "OutputLinesEXT"; + case ExecutionModeOutputPrimitivesEXT: return "OutputPrimitivesEXT"; + case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; + case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; + case ExecutionModeOutputTrianglesEXT: return "OutputTrianglesEXT"; + case ExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case ExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case ExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case ExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case ExecutionModeSharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL"; + case ExecutionModeRoundingModeRTPINTEL: return "RoundingModeRTPINTEL"; + case ExecutionModeRoundingModeRTNINTEL: return "RoundingModeRTNINTEL"; + case ExecutionModeFloatingPointModeALTINTEL: return "FloatingPointModeALTINTEL"; + case ExecutionModeFloatingPointModeIEEEINTEL: return "FloatingPointModeIEEEINTEL"; + case ExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case ExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case ExecutionModeSchedulerTargetFmaxMhzINTEL: return "SchedulerTargetFmaxMhzINTEL"; + case ExecutionModeMaximallyReconvergesKHR: return "MaximallyReconvergesKHR"; + case ExecutionModeFPFastMathDefault: return "FPFastMathDefault"; + case ExecutionModeStreamingInterfaceINTEL: return "StreamingInterfaceINTEL"; + case ExecutionModeRegisterMapInterfaceINTEL: return "RegisterMapInterfaceINTEL"; + case ExecutionModeNamedBarrierCountINTEL: return "NamedBarrierCountINTEL"; + case ExecutionModeMaximumRegistersINTEL: return "MaximumRegistersINTEL"; + case ExecutionModeMaximumRegistersIdINTEL: return "MaximumRegistersIdINTEL"; + case ExecutionModeNamedMaximumRegistersINTEL: return "NamedMaximumRegistersINTEL"; + default: return "Unknown"; + } +} + +inline const char* StorageClassToString(StorageClass value) { + switch (value) { + case StorageClassUniformConstant: return "UniformConstant"; + case StorageClassInput: return "Input"; + case StorageClassUniform: return "Uniform"; + case StorageClassOutput: return "Output"; + case StorageClassWorkgroup: return "Workgroup"; + case StorageClassCrossWorkgroup: return "CrossWorkgroup"; + case StorageClassPrivate: return "Private"; + case StorageClassFunction: return "Function"; + case StorageClassGeneric: return "Generic"; + case StorageClassPushConstant: return "PushConstant"; + case StorageClassAtomicCounter: return "AtomicCounter"; + case StorageClassImage: return "Image"; + case StorageClassStorageBuffer: return "StorageBuffer"; + case StorageClassTileImageEXT: return "TileImageEXT"; + case StorageClassNodePayloadAMDX: return "NodePayloadAMDX"; + case StorageClassNodeOutputPayloadAMDX: return "NodeOutputPayloadAMDX"; + case StorageClassCallableDataKHR: return "CallableDataKHR"; + case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; + case StorageClassRayPayloadKHR: return "RayPayloadKHR"; + case StorageClassHitAttributeKHR: return "HitAttributeKHR"; + case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case StorageClassPhysicalStorageBuffer: return "PhysicalStorageBuffer"; + case StorageClassHitObjectAttributeNV: return "HitObjectAttributeNV"; + case StorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT"; + case StorageClassCodeSectionINTEL: return "CodeSectionINTEL"; + case StorageClassDeviceOnlyINTEL: return "DeviceOnlyINTEL"; + case StorageClassHostOnlyINTEL: return "HostOnlyINTEL"; + default: return "Unknown"; + } +} + +inline const char* DimToString(Dim value) { + switch (value) { + case Dim1D: return "1D"; + case Dim2D: return "2D"; + case Dim3D: return "3D"; + case DimCube: return "Cube"; + case DimRect: return "Rect"; + case DimBuffer: return "Buffer"; + case DimSubpassData: return "SubpassData"; + case DimTileImageDataEXT: return "TileImageDataEXT"; + default: return "Unknown"; + } +} + +inline const char* SamplerAddressingModeToString(SamplerAddressingMode value) { + switch (value) { + case SamplerAddressingModeNone: return "None"; + case SamplerAddressingModeClampToEdge: return "ClampToEdge"; + case SamplerAddressingModeClamp: return "Clamp"; + case SamplerAddressingModeRepeat: return "Repeat"; + case SamplerAddressingModeRepeatMirrored: return "RepeatMirrored"; + default: return "Unknown"; + } +} + +inline const char* SamplerFilterModeToString(SamplerFilterMode value) { + switch (value) { + case SamplerFilterModeNearest: return "Nearest"; + case SamplerFilterModeLinear: return "Linear"; + default: return "Unknown"; + } +} + +inline const char* ImageFormatToString(ImageFormat value) { + switch (value) { + case ImageFormatUnknown: return "Unknown"; + case ImageFormatRgba32f: return "Rgba32f"; + case ImageFormatRgba16f: return "Rgba16f"; + case ImageFormatR32f: return "R32f"; + case ImageFormatRgba8: return "Rgba8"; + case ImageFormatRgba8Snorm: return "Rgba8Snorm"; + case ImageFormatRg32f: return "Rg32f"; + case ImageFormatRg16f: return "Rg16f"; + case ImageFormatR11fG11fB10f: return "R11fG11fB10f"; + case ImageFormatR16f: return "R16f"; + case ImageFormatRgba16: return "Rgba16"; + case ImageFormatRgb10A2: return "Rgb10A2"; + case ImageFormatRg16: return "Rg16"; + case ImageFormatRg8: return "Rg8"; + case ImageFormatR16: return "R16"; + case ImageFormatR8: return "R8"; + case ImageFormatRgba16Snorm: return "Rgba16Snorm"; + case ImageFormatRg16Snorm: return "Rg16Snorm"; + case ImageFormatRg8Snorm: return "Rg8Snorm"; + case ImageFormatR16Snorm: return "R16Snorm"; + case ImageFormatR8Snorm: return "R8Snorm"; + case ImageFormatRgba32i: return "Rgba32i"; + case ImageFormatRgba16i: return "Rgba16i"; + case ImageFormatRgba8i: return "Rgba8i"; + case ImageFormatR32i: return "R32i"; + case ImageFormatRg32i: return "Rg32i"; + case ImageFormatRg16i: return "Rg16i"; + case ImageFormatRg8i: return "Rg8i"; + case ImageFormatR16i: return "R16i"; + case ImageFormatR8i: return "R8i"; + case ImageFormatRgba32ui: return "Rgba32ui"; + case ImageFormatRgba16ui: return "Rgba16ui"; + case ImageFormatRgba8ui: return "Rgba8ui"; + case ImageFormatR32ui: return "R32ui"; + case ImageFormatRgb10a2ui: return "Rgb10a2ui"; + case ImageFormatRg32ui: return "Rg32ui"; + case ImageFormatRg16ui: return "Rg16ui"; + case ImageFormatRg8ui: return "Rg8ui"; + case ImageFormatR16ui: return "R16ui"; + case ImageFormatR8ui: return "R8ui"; + case ImageFormatR64ui: return "R64ui"; + case ImageFormatR64i: return "R64i"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelOrderToString(ImageChannelOrder value) { + switch (value) { + case ImageChannelOrderR: return "R"; + case ImageChannelOrderA: return "A"; + case ImageChannelOrderRG: return "RG"; + case ImageChannelOrderRA: return "RA"; + case ImageChannelOrderRGB: return "RGB"; + case ImageChannelOrderRGBA: return "RGBA"; + case ImageChannelOrderBGRA: return "BGRA"; + case ImageChannelOrderARGB: return "ARGB"; + case ImageChannelOrderIntensity: return "Intensity"; + case ImageChannelOrderLuminance: return "Luminance"; + case ImageChannelOrderRx: return "Rx"; + case ImageChannelOrderRGx: return "RGx"; + case ImageChannelOrderRGBx: return "RGBx"; + case ImageChannelOrderDepth: return "Depth"; + case ImageChannelOrderDepthStencil: return "DepthStencil"; + case ImageChannelOrdersRGB: return "sRGB"; + case ImageChannelOrdersRGBx: return "sRGBx"; + case ImageChannelOrdersRGBA: return "sRGBA"; + case ImageChannelOrdersBGRA: return "sBGRA"; + case ImageChannelOrderABGR: return "ABGR"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelDataTypeToString(ImageChannelDataType value) { + switch (value) { + case ImageChannelDataTypeSnormInt8: return "SnormInt8"; + case ImageChannelDataTypeSnormInt16: return "SnormInt16"; + case ImageChannelDataTypeUnormInt8: return "UnormInt8"; + case ImageChannelDataTypeUnormInt16: return "UnormInt16"; + case ImageChannelDataTypeUnormShort565: return "UnormShort565"; + case ImageChannelDataTypeUnormShort555: return "UnormShort555"; + case ImageChannelDataTypeUnormInt101010: return "UnormInt101010"; + case ImageChannelDataTypeSignedInt8: return "SignedInt8"; + case ImageChannelDataTypeSignedInt16: return "SignedInt16"; + case ImageChannelDataTypeSignedInt32: return "SignedInt32"; + case ImageChannelDataTypeUnsignedInt8: return "UnsignedInt8"; + case ImageChannelDataTypeUnsignedInt16: return "UnsignedInt16"; + case ImageChannelDataTypeUnsignedInt32: return "UnsignedInt32"; + case ImageChannelDataTypeHalfFloat: return "HalfFloat"; + case ImageChannelDataTypeFloat: return "Float"; + case ImageChannelDataTypeUnormInt24: return "UnormInt24"; + case ImageChannelDataTypeUnormInt101010_2: return "UnormInt101010_2"; + case ImageChannelDataTypeUnsignedIntRaw10EXT: return "UnsignedIntRaw10EXT"; + case ImageChannelDataTypeUnsignedIntRaw12EXT: return "UnsignedIntRaw12EXT"; + default: return "Unknown"; + } +} + +inline const char* FPRoundingModeToString(FPRoundingMode value) { + switch (value) { + case FPRoundingModeRTE: return "RTE"; + case FPRoundingModeRTZ: return "RTZ"; + case FPRoundingModeRTP: return "RTP"; + case FPRoundingModeRTN: return "RTN"; + default: return "Unknown"; + } +} + +inline const char* LinkageTypeToString(LinkageType value) { + switch (value) { + case LinkageTypeExport: return "Export"; + case LinkageTypeImport: return "Import"; + case LinkageTypeLinkOnceODR: return "LinkOnceODR"; + default: return "Unknown"; + } +} + +inline const char* AccessQualifierToString(AccessQualifier value) { + switch (value) { + case AccessQualifierReadOnly: return "ReadOnly"; + case AccessQualifierWriteOnly: return "WriteOnly"; + case AccessQualifierReadWrite: return "ReadWrite"; + default: return "Unknown"; + } +} + +inline const char* FunctionParameterAttributeToString(FunctionParameterAttribute value) { + switch (value) { + case FunctionParameterAttributeZext: return "Zext"; + case FunctionParameterAttributeSext: return "Sext"; + case FunctionParameterAttributeByVal: return "ByVal"; + case FunctionParameterAttributeSret: return "Sret"; + case FunctionParameterAttributeNoAlias: return "NoAlias"; + case FunctionParameterAttributeNoCapture: return "NoCapture"; + case FunctionParameterAttributeNoWrite: return "NoWrite"; + case FunctionParameterAttributeNoReadWrite: return "NoReadWrite"; + case FunctionParameterAttributeRuntimeAlignedINTEL: return "RuntimeAlignedINTEL"; + default: return "Unknown"; + } +} + +inline const char* DecorationToString(Decoration value) { + switch (value) { + case DecorationRelaxedPrecision: return "RelaxedPrecision"; + case DecorationSpecId: return "SpecId"; + case DecorationBlock: return "Block"; + case DecorationBufferBlock: return "BufferBlock"; + case DecorationRowMajor: return "RowMajor"; + case DecorationColMajor: return "ColMajor"; + case DecorationArrayStride: return "ArrayStride"; + case DecorationMatrixStride: return "MatrixStride"; + case DecorationGLSLShared: return "GLSLShared"; + case DecorationGLSLPacked: return "GLSLPacked"; + case DecorationCPacked: return "CPacked"; + case DecorationBuiltIn: return "BuiltIn"; + case DecorationNoPerspective: return "NoPerspective"; + case DecorationFlat: return "Flat"; + case DecorationPatch: return "Patch"; + case DecorationCentroid: return "Centroid"; + case DecorationSample: return "Sample"; + case DecorationInvariant: return "Invariant"; + case DecorationRestrict: return "Restrict"; + case DecorationAliased: return "Aliased"; + case DecorationVolatile: return "Volatile"; + case DecorationConstant: return "Constant"; + case DecorationCoherent: return "Coherent"; + case DecorationNonWritable: return "NonWritable"; + case DecorationNonReadable: return "NonReadable"; + case DecorationUniform: return "Uniform"; + case DecorationUniformId: return "UniformId"; + case DecorationSaturatedConversion: return "SaturatedConversion"; + case DecorationStream: return "Stream"; + case DecorationLocation: return "Location"; + case DecorationComponent: return "Component"; + case DecorationIndex: return "Index"; + case DecorationBinding: return "Binding"; + case DecorationDescriptorSet: return "DescriptorSet"; + case DecorationOffset: return "Offset"; + case DecorationXfbBuffer: return "XfbBuffer"; + case DecorationXfbStride: return "XfbStride"; + case DecorationFuncParamAttr: return "FuncParamAttr"; + case DecorationFPRoundingMode: return "FPRoundingMode"; + case DecorationFPFastMathMode: return "FPFastMathMode"; + case DecorationLinkageAttributes: return "LinkageAttributes"; + case DecorationNoContraction: return "NoContraction"; + case DecorationInputAttachmentIndex: return "InputAttachmentIndex"; + case DecorationAlignment: return "Alignment"; + case DecorationMaxByteOffset: return "MaxByteOffset"; + case DecorationAlignmentId: return "AlignmentId"; + case DecorationMaxByteOffsetId: return "MaxByteOffsetId"; + case DecorationNoSignedWrap: return "NoSignedWrap"; + case DecorationNoUnsignedWrap: return "NoUnsignedWrap"; + case DecorationWeightTextureQCOM: return "WeightTextureQCOM"; + case DecorationBlockMatchTextureQCOM: return "BlockMatchTextureQCOM"; + case DecorationBlockMatchSamplerQCOM: return "BlockMatchSamplerQCOM"; + case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; + case DecorationNodeSharesPayloadLimitsWithAMDX: return "NodeSharesPayloadLimitsWithAMDX"; + case DecorationNodeMaxPayloadsAMDX: return "NodeMaxPayloadsAMDX"; + case DecorationTrackFinishWritingAMDX: return "TrackFinishWritingAMDX"; + case DecorationPayloadNodeNameAMDX: return "PayloadNodeNameAMDX"; + case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; + case DecorationPassthroughNV: return "PassthroughNV"; + case DecorationViewportRelativeNV: return "ViewportRelativeNV"; + case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; + case DecorationPerPrimitiveEXT: return "PerPrimitiveEXT"; + case DecorationPerViewNV: return "PerViewNV"; + case DecorationPerTaskNV: return "PerTaskNV"; + case DecorationPerVertexKHR: return "PerVertexKHR"; + case DecorationNonUniform: return "NonUniform"; + case DecorationRestrictPointer: return "RestrictPointer"; + case DecorationAliasedPointer: return "AliasedPointer"; + case DecorationHitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV"; + case DecorationBindlessSamplerNV: return "BindlessSamplerNV"; + case DecorationBindlessImageNV: return "BindlessImageNV"; + case DecorationBoundSamplerNV: return "BoundSamplerNV"; + case DecorationBoundImageNV: return "BoundImageNV"; + case DecorationSIMTCallINTEL: return "SIMTCallINTEL"; + case DecorationReferencedIndirectlyINTEL: return "ReferencedIndirectlyINTEL"; + case DecorationClobberINTEL: return "ClobberINTEL"; + case DecorationSideEffectsINTEL: return "SideEffectsINTEL"; + case DecorationVectorComputeVariableINTEL: return "VectorComputeVariableINTEL"; + case DecorationFuncParamIOKindINTEL: return "FuncParamIOKindINTEL"; + case DecorationVectorComputeFunctionINTEL: return "VectorComputeFunctionINTEL"; + case DecorationStackCallINTEL: return "StackCallINTEL"; + case DecorationGlobalVariableOffsetINTEL: return "GlobalVariableOffsetINTEL"; + case DecorationCounterBuffer: return "CounterBuffer"; + case DecorationHlslSemanticGOOGLE: return "HlslSemanticGOOGLE"; + case DecorationUserTypeGOOGLE: return "UserTypeGOOGLE"; + case DecorationFunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL"; + case DecorationFunctionDenormModeINTEL: return "FunctionDenormModeINTEL"; + case DecorationRegisterINTEL: return "RegisterINTEL"; + case DecorationMemoryINTEL: return "MemoryINTEL"; + case DecorationNumbanksINTEL: return "NumbanksINTEL"; + case DecorationBankwidthINTEL: return "BankwidthINTEL"; + case DecorationMaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL"; + case DecorationSinglepumpINTEL: return "SinglepumpINTEL"; + case DecorationDoublepumpINTEL: return "DoublepumpINTEL"; + case DecorationMaxReplicatesINTEL: return "MaxReplicatesINTEL"; + case DecorationSimpleDualPortINTEL: return "SimpleDualPortINTEL"; + case DecorationMergeINTEL: return "MergeINTEL"; + case DecorationBankBitsINTEL: return "BankBitsINTEL"; + case DecorationForcePow2DepthINTEL: return "ForcePow2DepthINTEL"; + case DecorationStridesizeINTEL: return "StridesizeINTEL"; + case DecorationWordsizeINTEL: return "WordsizeINTEL"; + case DecorationTrueDualPortINTEL: return "TrueDualPortINTEL"; + case DecorationBurstCoalesceINTEL: return "BurstCoalesceINTEL"; + case DecorationCacheSizeINTEL: return "CacheSizeINTEL"; + case DecorationDontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL"; + case DecorationPrefetchINTEL: return "PrefetchINTEL"; + case DecorationStallEnableINTEL: return "StallEnableINTEL"; + case DecorationFuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL"; + case DecorationMathOpDSPModeINTEL: return "MathOpDSPModeINTEL"; + case DecorationAliasScopeINTEL: return "AliasScopeINTEL"; + case DecorationNoAliasINTEL: return "NoAliasINTEL"; + case DecorationInitiationIntervalINTEL: return "InitiationIntervalINTEL"; + case DecorationMaxConcurrencyINTEL: return "MaxConcurrencyINTEL"; + case DecorationPipelineEnableINTEL: return "PipelineEnableINTEL"; + case DecorationBufferLocationINTEL: return "BufferLocationINTEL"; + case DecorationIOPipeStorageINTEL: return "IOPipeStorageINTEL"; + case DecorationFunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL"; + case DecorationSingleElementVectorINTEL: return "SingleElementVectorINTEL"; + case DecorationVectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL"; + case DecorationMediaBlockIOINTEL: return "MediaBlockIOINTEL"; + case DecorationStallFreeINTEL: return "StallFreeINTEL"; + case DecorationFPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL"; + case DecorationLatencyControlLabelINTEL: return "LatencyControlLabelINTEL"; + case DecorationLatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL"; + case DecorationConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL"; + case DecorationRegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL"; + case DecorationMMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL"; + case DecorationMMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL"; + case DecorationMMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL"; + case DecorationMMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL"; + case DecorationMMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL"; + case DecorationMMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL"; + case DecorationStableKernelArgumentINTEL: return "StableKernelArgumentINTEL"; + case DecorationHostAccessINTEL: return "HostAccessINTEL"; + case DecorationInitModeINTEL: return "InitModeINTEL"; + case DecorationImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL"; + case DecorationCacheControlLoadINTEL: return "CacheControlLoadINTEL"; + case DecorationCacheControlStoreINTEL: return "CacheControlStoreINTEL"; + default: return "Unknown"; + } +} + +inline const char* BuiltInToString(BuiltIn value) { + switch (value) { + case BuiltInPosition: return "Position"; + case BuiltInPointSize: return "PointSize"; + case BuiltInClipDistance: return "ClipDistance"; + case BuiltInCullDistance: return "CullDistance"; + case BuiltInVertexId: return "VertexId"; + case BuiltInInstanceId: return "InstanceId"; + case BuiltInPrimitiveId: return "PrimitiveId"; + case BuiltInInvocationId: return "InvocationId"; + case BuiltInLayer: return "Layer"; + case BuiltInViewportIndex: return "ViewportIndex"; + case BuiltInTessLevelOuter: return "TessLevelOuter"; + case BuiltInTessLevelInner: return "TessLevelInner"; + case BuiltInTessCoord: return "TessCoord"; + case BuiltInPatchVertices: return "PatchVertices"; + case BuiltInFragCoord: return "FragCoord"; + case BuiltInPointCoord: return "PointCoord"; + case BuiltInFrontFacing: return "FrontFacing"; + case BuiltInSampleId: return "SampleId"; + case BuiltInSamplePosition: return "SamplePosition"; + case BuiltInSampleMask: return "SampleMask"; + case BuiltInFragDepth: return "FragDepth"; + case BuiltInHelperInvocation: return "HelperInvocation"; + case BuiltInNumWorkgroups: return "NumWorkgroups"; + case BuiltInWorkgroupSize: return "WorkgroupSize"; + case BuiltInWorkgroupId: return "WorkgroupId"; + case BuiltInLocalInvocationId: return "LocalInvocationId"; + case BuiltInGlobalInvocationId: return "GlobalInvocationId"; + case BuiltInLocalInvocationIndex: return "LocalInvocationIndex"; + case BuiltInWorkDim: return "WorkDim"; + case BuiltInGlobalSize: return "GlobalSize"; + case BuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case BuiltInGlobalOffset: return "GlobalOffset"; + case BuiltInGlobalLinearId: return "GlobalLinearId"; + case BuiltInSubgroupSize: return "SubgroupSize"; + case BuiltInSubgroupMaxSize: return "SubgroupMaxSize"; + case BuiltInNumSubgroups: return "NumSubgroups"; + case BuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case BuiltInSubgroupId: return "SubgroupId"; + case BuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + case BuiltInVertexIndex: return "VertexIndex"; + case BuiltInInstanceIndex: return "InstanceIndex"; + case BuiltInCoreIDARM: return "CoreIDARM"; + case BuiltInCoreCountARM: return "CoreCountARM"; + case BuiltInCoreMaxIDARM: return "CoreMaxIDARM"; + case BuiltInWarpIDARM: return "WarpIDARM"; + case BuiltInWarpMaxIDARM: return "WarpMaxIDARM"; + case BuiltInSubgroupEqMask: return "SubgroupEqMask"; + case BuiltInSubgroupGeMask: return "SubgroupGeMask"; + case BuiltInSubgroupGtMask: return "SubgroupGtMask"; + case BuiltInSubgroupLeMask: return "SubgroupLeMask"; + case BuiltInSubgroupLtMask: return "SubgroupLtMask"; + case BuiltInBaseVertex: return "BaseVertex"; + case BuiltInBaseInstance: return "BaseInstance"; + case BuiltInDrawIndex: return "DrawIndex"; + case BuiltInPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + case BuiltInDeviceIndex: return "DeviceIndex"; + case BuiltInViewIndex: return "ViewIndex"; + case BuiltInShadingRateKHR: return "ShadingRateKHR"; + case BuiltInBaryCoordNoPerspAMD: return "BaryCoordNoPerspAMD"; + case BuiltInBaryCoordNoPerspCentroidAMD: return "BaryCoordNoPerspCentroidAMD"; + case BuiltInBaryCoordNoPerspSampleAMD: return "BaryCoordNoPerspSampleAMD"; + case BuiltInBaryCoordSmoothAMD: return "BaryCoordSmoothAMD"; + case BuiltInBaryCoordSmoothCentroidAMD: return "BaryCoordSmoothCentroidAMD"; + case BuiltInBaryCoordSmoothSampleAMD: return "BaryCoordSmoothSampleAMD"; + case BuiltInBaryCoordPullModelAMD: return "BaryCoordPullModelAMD"; + case BuiltInFragStencilRefEXT: return "FragStencilRefEXT"; + case BuiltInCoalescedInputCountAMDX: return "CoalescedInputCountAMDX"; + case BuiltInShaderIndexAMDX: return "ShaderIndexAMDX"; + case BuiltInViewportMaskNV: return "ViewportMaskNV"; + case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case BuiltInPositionPerViewNV: return "PositionPerViewNV"; + case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case BuiltInFullyCoveredEXT: return "FullyCoveredEXT"; + case BuiltInTaskCountNV: return "TaskCountNV"; + case BuiltInPrimitiveCountNV: return "PrimitiveCountNV"; + case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV"; + case BuiltInLayerPerViewNV: return "LayerPerViewNV"; + case BuiltInMeshViewCountNV: return "MeshViewCountNV"; + case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; + case BuiltInBaryCoordKHR: return "BaryCoordKHR"; + case BuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR"; + case BuiltInFragSizeEXT: return "FragSizeEXT"; + case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; + case BuiltInPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case BuiltInPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case BuiltInPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case BuiltInCullPrimitiveEXT: return "CullPrimitiveEXT"; + case BuiltInLaunchIdKHR: return "LaunchIdKHR"; + case BuiltInLaunchSizeKHR: return "LaunchSizeKHR"; + case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR"; + case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case BuiltInRayTminKHR: return "RayTminKHR"; + case BuiltInRayTmaxKHR: return "RayTmaxKHR"; + case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; + case BuiltInWorldToObjectKHR: return "WorldToObjectKHR"; + case BuiltInHitTNV: return "HitTNV"; + case BuiltInHitKindKHR: return "HitKindKHR"; + case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV"; + case BuiltInHitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR"; + case BuiltInHitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV"; + case BuiltInHitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV"; + case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case BuiltInWarpsPerSMNV: return "WarpsPerSMNV"; + case BuiltInSMCountNV: return "SMCountNV"; + case BuiltInWarpIDNV: return "WarpIDNV"; + case BuiltInSMIDNV: return "SMIDNV"; + case BuiltInHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case BuiltInHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; + case BuiltInCullMaskKHR: return "CullMaskKHR"; + default: return "Unknown"; + } +} + +inline const char* ScopeToString(Scope value) { + switch (value) { + case ScopeCrossDevice: return "CrossDevice"; + case ScopeDevice: return "Device"; + case ScopeWorkgroup: return "Workgroup"; + case ScopeSubgroup: return "Subgroup"; + case ScopeInvocation: return "Invocation"; + case ScopeQueueFamily: return "QueueFamily"; + case ScopeShaderCallKHR: return "ShaderCallKHR"; + default: return "Unknown"; + } +} + +inline const char* GroupOperationToString(GroupOperation value) { + switch (value) { + case GroupOperationReduce: return "Reduce"; + case GroupOperationInclusiveScan: return "InclusiveScan"; + case GroupOperationExclusiveScan: return "ExclusiveScan"; + case GroupOperationClusteredReduce: return "ClusteredReduce"; + case GroupOperationPartitionedReduceNV: return "PartitionedReduceNV"; + case GroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; + case GroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; + default: return "Unknown"; + } +} + +inline const char* KernelEnqueueFlagsToString(KernelEnqueueFlags value) { + switch (value) { + case KernelEnqueueFlagsNoWait: return "NoWait"; + case KernelEnqueueFlagsWaitKernel: return "WaitKernel"; + case KernelEnqueueFlagsWaitWorkGroup: return "WaitWorkGroup"; + default: return "Unknown"; + } +} + +inline const char* CapabilityToString(Capability value) { + switch (value) { + case CapabilityMatrix: return "Matrix"; + case CapabilityShader: return "Shader"; + case CapabilityGeometry: return "Geometry"; + case CapabilityTessellation: return "Tessellation"; + case CapabilityAddresses: return "Addresses"; + case CapabilityLinkage: return "Linkage"; + case CapabilityKernel: return "Kernel"; + case CapabilityVector16: return "Vector16"; + case CapabilityFloat16Buffer: return "Float16Buffer"; + case CapabilityFloat16: return "Float16"; + case CapabilityFloat64: return "Float64"; + case CapabilityInt64: return "Int64"; + case CapabilityInt64Atomics: return "Int64Atomics"; + case CapabilityImageBasic: return "ImageBasic"; + case CapabilityImageReadWrite: return "ImageReadWrite"; + case CapabilityImageMipmap: return "ImageMipmap"; + case CapabilityPipes: return "Pipes"; + case CapabilityGroups: return "Groups"; + case CapabilityDeviceEnqueue: return "DeviceEnqueue"; + case CapabilityLiteralSampler: return "LiteralSampler"; + case CapabilityAtomicStorage: return "AtomicStorage"; + case CapabilityInt16: return "Int16"; + case CapabilityTessellationPointSize: return "TessellationPointSize"; + case CapabilityGeometryPointSize: return "GeometryPointSize"; + case CapabilityImageGatherExtended: return "ImageGatherExtended"; + case CapabilityStorageImageMultisample: return "StorageImageMultisample"; + case CapabilityUniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; + case CapabilitySampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; + case CapabilityStorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; + case CapabilityStorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; + case CapabilityClipDistance: return "ClipDistance"; + case CapabilityCullDistance: return "CullDistance"; + case CapabilityImageCubeArray: return "ImageCubeArray"; + case CapabilitySampleRateShading: return "SampleRateShading"; + case CapabilityImageRect: return "ImageRect"; + case CapabilitySampledRect: return "SampledRect"; + case CapabilityGenericPointer: return "GenericPointer"; + case CapabilityInt8: return "Int8"; + case CapabilityInputAttachment: return "InputAttachment"; + case CapabilitySparseResidency: return "SparseResidency"; + case CapabilityMinLod: return "MinLod"; + case CapabilitySampled1D: return "Sampled1D"; + case CapabilityImage1D: return "Image1D"; + case CapabilitySampledCubeArray: return "SampledCubeArray"; + case CapabilitySampledBuffer: return "SampledBuffer"; + case CapabilityImageBuffer: return "ImageBuffer"; + case CapabilityImageMSArray: return "ImageMSArray"; + case CapabilityStorageImageExtendedFormats: return "StorageImageExtendedFormats"; + case CapabilityImageQuery: return "ImageQuery"; + case CapabilityDerivativeControl: return "DerivativeControl"; + case CapabilityInterpolationFunction: return "InterpolationFunction"; + case CapabilityTransformFeedback: return "TransformFeedback"; + case CapabilityGeometryStreams: return "GeometryStreams"; + case CapabilityStorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; + case CapabilityStorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; + case CapabilityMultiViewport: return "MultiViewport"; + case CapabilitySubgroupDispatch: return "SubgroupDispatch"; + case CapabilityNamedBarrier: return "NamedBarrier"; + case CapabilityPipeStorage: return "PipeStorage"; + case CapabilityGroupNonUniform: return "GroupNonUniform"; + case CapabilityGroupNonUniformVote: return "GroupNonUniformVote"; + case CapabilityGroupNonUniformArithmetic: return "GroupNonUniformArithmetic"; + case CapabilityGroupNonUniformBallot: return "GroupNonUniformBallot"; + case CapabilityGroupNonUniformShuffle: return "GroupNonUniformShuffle"; + case CapabilityGroupNonUniformShuffleRelative: return "GroupNonUniformShuffleRelative"; + case CapabilityGroupNonUniformClustered: return "GroupNonUniformClustered"; + case CapabilityGroupNonUniformQuad: return "GroupNonUniformQuad"; + case CapabilityShaderLayer: return "ShaderLayer"; + case CapabilityShaderViewportIndex: return "ShaderViewportIndex"; + case CapabilityUniformDecoration: return "UniformDecoration"; + case CapabilityCoreBuiltinsARM: return "CoreBuiltinsARM"; + case CapabilityTileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; + case CapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; + case CapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case CapabilityCooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM"; + case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; + case CapabilitySubgroupBallotKHR: return "SubgroupBallotKHR"; + case CapabilityDrawParameters: return "DrawParameters"; + case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "WorkgroupMemoryExplicitLayoutKHR"; + case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; + case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; + case CapabilitySubgroupVoteKHR: return "SubgroupVoteKHR"; + case CapabilityStorageBuffer16BitAccess: return "StorageBuffer16BitAccess"; + case CapabilityStorageUniform16: return "StorageUniform16"; + case CapabilityStoragePushConstant16: return "StoragePushConstant16"; + case CapabilityStorageInputOutput16: return "StorageInputOutput16"; + case CapabilityDeviceGroup: return "DeviceGroup"; + case CapabilityMultiView: return "MultiView"; + case CapabilityVariablePointersStorageBuffer: return "VariablePointersStorageBuffer"; + case CapabilityVariablePointers: return "VariablePointers"; + case CapabilityAtomicStorageOps: return "AtomicStorageOps"; + case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; + case CapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case CapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case CapabilityStoragePushConstant8: return "StoragePushConstant8"; + case CapabilityDenormPreserve: return "DenormPreserve"; + case CapabilityDenormFlushToZero: return "DenormFlushToZero"; + case CapabilitySignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case CapabilityRoundingModeRTE: return "RoundingModeRTE"; + case CapabilityRoundingModeRTZ: return "RoundingModeRTZ"; + case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; + case CapabilityRayQueryKHR: return "RayQueryKHR"; + case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; + case CapabilityRayTracingKHR: return "RayTracingKHR"; + case CapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; + case CapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; + case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; + case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; + case CapabilityFloat16ImageAMD: return "Float16ImageAMD"; + case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; + case CapabilityFragmentMaskAMD: return "FragmentMaskAMD"; + case CapabilityStencilExportEXT: return "StencilExportEXT"; + case CapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case CapabilityInt64ImageEXT: return "Int64ImageEXT"; + case CapabilityShaderClockKHR: return "ShaderClockKHR"; + case CapabilityShaderEnqueueAMDX: return "ShaderEnqueueAMDX"; + case CapabilityQuadControlKHR: return "QuadControlKHR"; + case CapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; + case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case CapabilityShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; + case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; + case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; + case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; + case CapabilityMeshShadingNV: return "MeshShadingNV"; + case CapabilityImageFootprintNV: return "ImageFootprintNV"; + case CapabilityMeshShadingEXT: return "MeshShadingEXT"; + case CapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR"; + case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; + case CapabilityFragmentDensityEXT: return "FragmentDensityEXT"; + case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; + case CapabilityShaderNonUniform: return "ShaderNonUniform"; + case CapabilityRuntimeDescriptorArray: return "RuntimeDescriptorArray"; + case CapabilityInputAttachmentArrayDynamicIndexing: return "InputAttachmentArrayDynamicIndexing"; + case CapabilityUniformTexelBufferArrayDynamicIndexing: return "UniformTexelBufferArrayDynamicIndexing"; + case CapabilityStorageTexelBufferArrayDynamicIndexing: return "StorageTexelBufferArrayDynamicIndexing"; + case CapabilityUniformBufferArrayNonUniformIndexing: return "UniformBufferArrayNonUniformIndexing"; + case CapabilitySampledImageArrayNonUniformIndexing: return "SampledImageArrayNonUniformIndexing"; + case CapabilityStorageBufferArrayNonUniformIndexing: return "StorageBufferArrayNonUniformIndexing"; + case CapabilityStorageImageArrayNonUniformIndexing: return "StorageImageArrayNonUniformIndexing"; + case CapabilityInputAttachmentArrayNonUniformIndexing: return "InputAttachmentArrayNonUniformIndexing"; + case CapabilityUniformTexelBufferArrayNonUniformIndexing: return "UniformTexelBufferArrayNonUniformIndexing"; + case CapabilityStorageTexelBufferArrayNonUniformIndexing: return "StorageTexelBufferArrayNonUniformIndexing"; + case CapabilityRayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR"; + case CapabilityRayTracingNV: return "RayTracingNV"; + case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; + case CapabilityVulkanMemoryModel: return "VulkanMemoryModel"; + case CapabilityVulkanMemoryModelDeviceScope: return "VulkanMemoryModelDeviceScope"; + case CapabilityPhysicalStorageBufferAddresses: return "PhysicalStorageBufferAddresses"; + case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; + case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case CapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case CapabilityFragmentShaderSampleInterlockEXT: return "FragmentShaderSampleInterlockEXT"; + case CapabilityFragmentShaderShadingRateInterlockEXT: return "FragmentShaderShadingRateInterlockEXT"; + case CapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + case CapabilityFragmentShaderPixelInterlockEXT: return "FragmentShaderPixelInterlockEXT"; + case CapabilityDemoteToHelperInvocation: return "DemoteToHelperInvocation"; + case CapabilityDisplacementMicromapNV: return "DisplacementMicromapNV"; + case CapabilityRayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT"; + case CapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV"; + case CapabilityBindlessTextureNV: return "BindlessTextureNV"; + case CapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR"; + case CapabilityAtomicFloat16VectorNV: return "AtomicFloat16VectorNV"; + case CapabilityRayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV"; + case CapabilityRawAccessChainsNV: return "RawAccessChainsNV"; + case CapabilitySubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; + case CapabilitySubgroupBufferBlockIOINTEL: return "SubgroupBufferBlockIOINTEL"; + case CapabilitySubgroupImageBlockIOINTEL: return "SubgroupImageBlockIOINTEL"; + case CapabilitySubgroupImageMediaBlockIOINTEL: return "SubgroupImageMediaBlockIOINTEL"; + case CapabilityRoundToInfinityINTEL: return "RoundToInfinityINTEL"; + case CapabilityFloatingPointModeINTEL: return "FloatingPointModeINTEL"; + case CapabilityIntegerFunctions2INTEL: return "IntegerFunctions2INTEL"; + case CapabilityFunctionPointersINTEL: return "FunctionPointersINTEL"; + case CapabilityIndirectReferencesINTEL: return "IndirectReferencesINTEL"; + case CapabilityAsmINTEL: return "AsmINTEL"; + case CapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; + case CapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; + case CapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; + case CapabilityVectorComputeINTEL: return "VectorComputeINTEL"; + case CapabilityVectorAnyINTEL: return "VectorAnyINTEL"; + case CapabilityExpectAssumeKHR: return "ExpectAssumeKHR"; + case CapabilitySubgroupAvcMotionEstimationINTEL: return "SubgroupAvcMotionEstimationINTEL"; + case CapabilitySubgroupAvcMotionEstimationIntraINTEL: return "SubgroupAvcMotionEstimationIntraINTEL"; + case CapabilitySubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL"; + case CapabilityVariableLengthArrayINTEL: return "VariableLengthArrayINTEL"; + case CapabilityFunctionFloatControlINTEL: return "FunctionFloatControlINTEL"; + case CapabilityFPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL"; + case CapabilityFPFastMathModeINTEL: return "FPFastMathModeINTEL"; + case CapabilityArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL"; + case CapabilityArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL"; + case CapabilityUnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL"; + case CapabilityFPGALoopControlsINTEL: return "FPGALoopControlsINTEL"; + case CapabilityKernelAttributesINTEL: return "KernelAttributesINTEL"; + case CapabilityFPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL"; + case CapabilityFPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL"; + case CapabilityFPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL"; + case CapabilityLoopFuseINTEL: return "LoopFuseINTEL"; + case CapabilityFPGADSPControlINTEL: return "FPGADSPControlINTEL"; + case CapabilityMemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL"; + case CapabilityFPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL"; + case CapabilityFPGABufferLocationINTEL: return "FPGABufferLocationINTEL"; + case CapabilityArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL"; + case CapabilityUSMStorageClassesINTEL: return "USMStorageClassesINTEL"; + case CapabilityRuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL"; + case CapabilityIOPipesINTEL: return "IOPipesINTEL"; + case CapabilityBlockingPipesINTEL: return "BlockingPipesINTEL"; + case CapabilityFPGARegINTEL: return "FPGARegINTEL"; + case CapabilityDotProductInputAll: return "DotProductInputAll"; + case CapabilityDotProductInput4x8Bit: return "DotProductInput4x8Bit"; + case CapabilityDotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked"; + case CapabilityDotProduct: return "DotProduct"; + case CapabilityRayCullMaskKHR: return "RayCullMaskKHR"; + case CapabilityCooperativeMatrixKHR: return "CooperativeMatrixKHR"; + case CapabilityReplicatedCompositesEXT: return "ReplicatedCompositesEXT"; + case CapabilityBitInstructions: return "BitInstructions"; + case CapabilityGroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR"; + case CapabilityFloatControls2: return "FloatControls2"; + case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + case CapabilityLongCompositesINTEL: return "LongCompositesINTEL"; + case CapabilityOptNoneINTEL: return "OptNoneINTEL"; + case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; + case CapabilityDebugInfoModuleINTEL: return "DebugInfoModuleINTEL"; + case CapabilityBFloat16ConversionINTEL: return "BFloat16ConversionINTEL"; + case CapabilitySplitBarrierINTEL: return "SplitBarrierINTEL"; + case CapabilityFPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL"; + case CapabilityFPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL"; + case CapabilityFPMaxErrorINTEL: return "FPMaxErrorINTEL"; + case CapabilityFPGALatencyControlINTEL: return "FPGALatencyControlINTEL"; + case CapabilityFPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL"; + case CapabilityGlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL"; + case CapabilityGlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL"; + case CapabilityGroupUniformArithmeticKHR: return "GroupUniformArithmeticKHR"; + case CapabilityMaskedGatherScatterINTEL: return "MaskedGatherScatterINTEL"; + case CapabilityCacheControlsINTEL: return "CacheControlsINTEL"; + case CapabilityRegisterLimitsINTEL: return "RegisterLimitsINTEL"; + default: return "Unknown"; + } +} + +inline const char* RayQueryIntersectionToString(RayQueryIntersection value) { + switch (value) { + case RayQueryIntersectionRayQueryCandidateIntersectionKHR: return "RayQueryCandidateIntersectionKHR"; + case RayQueryIntersectionRayQueryCommittedIntersectionKHR: return "RayQueryCommittedIntersectionKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCommittedIntersectionTypeToString(RayQueryCommittedIntersectionType value) { + switch (value) { + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR: return "RayQueryCommittedIntersectionNoneKHR"; + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR: return "RayQueryCommittedIntersectionTriangleKHR"; + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR: return "RayQueryCommittedIntersectionGeneratedKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCandidateIntersectionTypeToString(RayQueryCandidateIntersectionType value) { + switch (value) { + case RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR: return "RayQueryCandidateIntersectionTriangleKHR"; + case RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR: return "RayQueryCandidateIntersectionAABBKHR"; + default: return "Unknown"; + } +} + +inline const char* FPDenormModeToString(FPDenormMode value) { + switch (value) { + case FPDenormModePreserve: return "Preserve"; + case FPDenormModeFlushToZero: return "FlushToZero"; + default: return "Unknown"; + } +} + +inline const char* FPOperationModeToString(FPOperationMode value) { + switch (value) { + case FPOperationModeIEEE: return "IEEE"; + case FPOperationModeALT: return "ALT"; + default: return "Unknown"; + } +} + +inline const char* QuantizationModesToString(QuantizationModes value) { + switch (value) { + case QuantizationModesTRN: return "TRN"; + case QuantizationModesTRN_ZERO: return "TRN_ZERO"; + case QuantizationModesRND: return "RND"; + case QuantizationModesRND_ZERO: return "RND_ZERO"; + case QuantizationModesRND_INF: return "RND_INF"; + case QuantizationModesRND_MIN_INF: return "RND_MIN_INF"; + case QuantizationModesRND_CONV: return "RND_CONV"; + case QuantizationModesRND_CONV_ODD: return "RND_CONV_ODD"; + default: return "Unknown"; + } +} + +inline const char* OverflowModesToString(OverflowModes value) { + switch (value) { + case OverflowModesWRAP: return "WRAP"; + case OverflowModesSAT: return "SAT"; + case OverflowModesSAT_ZERO: return "SAT_ZERO"; + case OverflowModesSAT_SYM: return "SAT_SYM"; + default: return "Unknown"; + } +} + +inline const char* PackedVectorFormatToString(PackedVectorFormat value) { + switch (value) { + case PackedVectorFormatPackedVectorFormat4x8Bit: return "PackedVectorFormat4x8Bit"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixLayoutToString(CooperativeMatrixLayout value) { + switch (value) { + case CooperativeMatrixLayoutRowMajorKHR: return "RowMajorKHR"; + case CooperativeMatrixLayoutColumnMajorKHR: return "ColumnMajorKHR"; + case CooperativeMatrixLayoutRowBlockedInterleavedARM: return "RowBlockedInterleavedARM"; + case CooperativeMatrixLayoutColumnBlockedInterleavedARM: return "ColumnBlockedInterleavedARM"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixUseToString(CooperativeMatrixUse value) { + switch (value) { + case CooperativeMatrixUseMatrixAKHR: return "MatrixAKHR"; + case CooperativeMatrixUseMatrixBKHR: return "MatrixBKHR"; + case CooperativeMatrixUseMatrixAccumulatorKHR: return "MatrixAccumulatorKHR"; + default: return "Unknown"; + } +} + +inline const char* InitializationModeQualifierToString(InitializationModeQualifier value) { + switch (value) { + case InitializationModeQualifierInitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL"; + case InitializationModeQualifierInitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL"; + default: return "Unknown"; + } +} + +inline const char* HostAccessQualifierToString(HostAccessQualifier value) { + switch (value) { + case HostAccessQualifierNoneINTEL: return "NoneINTEL"; + case HostAccessQualifierReadINTEL: return "ReadINTEL"; + case HostAccessQualifierWriteINTEL: return "WriteINTEL"; + case HostAccessQualifierReadWriteINTEL: return "ReadWriteINTEL"; + default: return "Unknown"; + } +} + +inline const char* LoadCacheControlToString(LoadCacheControl value) { + switch (value) { + case LoadCacheControlUncachedINTEL: return "UncachedINTEL"; + case LoadCacheControlCachedINTEL: return "CachedINTEL"; + case LoadCacheControlStreamingINTEL: return "StreamingINTEL"; + case LoadCacheControlInvalidateAfterReadINTEL: return "InvalidateAfterReadINTEL"; + case LoadCacheControlConstCachedINTEL: return "ConstCachedINTEL"; + default: return "Unknown"; + } +} + +inline const char* StoreCacheControlToString(StoreCacheControl value) { + switch (value) { + case StoreCacheControlUncachedINTEL: return "UncachedINTEL"; + case StoreCacheControlWriteThroughINTEL: return "WriteThroughINTEL"; + case StoreCacheControlWriteBackINTEL: return "WriteBackINTEL"; + case StoreCacheControlStreamingINTEL: return "StreamingINTEL"; + default: return "Unknown"; + } +} + +inline const char* NamedMaximumNumberOfRegistersToString(NamedMaximumNumberOfRegisters value) { + switch (value) { + case NamedMaximumNumberOfRegistersAutoINTEL: return "AutoINTEL"; + default: return "Unknown"; + } +} + +inline const char* OpToString(Op value) { + switch (value) { + case OpNop: return "OpNop"; + case OpUndef: return "OpUndef"; + case OpSourceContinued: return "OpSourceContinued"; + case OpSource: return "OpSource"; + case OpSourceExtension: return "OpSourceExtension"; + case OpName: return "OpName"; + case OpMemberName: return "OpMemberName"; + case OpString: return "OpString"; + case OpLine: return "OpLine"; + case OpExtension: return "OpExtension"; + case OpExtInstImport: return "OpExtInstImport"; + case OpExtInst: return "OpExtInst"; + case OpMemoryModel: return "OpMemoryModel"; + case OpEntryPoint: return "OpEntryPoint"; + case OpExecutionMode: return "OpExecutionMode"; + case OpCapability: return "OpCapability"; + case OpTypeVoid: return "OpTypeVoid"; + case OpTypeBool: return "OpTypeBool"; + case OpTypeInt: return "OpTypeInt"; + case OpTypeFloat: return "OpTypeFloat"; + case OpTypeVector: return "OpTypeVector"; + case OpTypeMatrix: return "OpTypeMatrix"; + case OpTypeImage: return "OpTypeImage"; + case OpTypeSampler: return "OpTypeSampler"; + case OpTypeSampledImage: return "OpTypeSampledImage"; + case OpTypeArray: return "OpTypeArray"; + case OpTypeRuntimeArray: return "OpTypeRuntimeArray"; + case OpTypeStruct: return "OpTypeStruct"; + case OpTypeOpaque: return "OpTypeOpaque"; + case OpTypePointer: return "OpTypePointer"; + case OpTypeFunction: return "OpTypeFunction"; + case OpTypeEvent: return "OpTypeEvent"; + case OpTypeDeviceEvent: return "OpTypeDeviceEvent"; + case OpTypeReserveId: return "OpTypeReserveId"; + case OpTypeQueue: return "OpTypeQueue"; + case OpTypePipe: return "OpTypePipe"; + case OpTypeForwardPointer: return "OpTypeForwardPointer"; + case OpConstantTrue: return "OpConstantTrue"; + case OpConstantFalse: return "OpConstantFalse"; + case OpConstant: return "OpConstant"; + case OpConstantComposite: return "OpConstantComposite"; + case OpConstantSampler: return "OpConstantSampler"; + case OpConstantNull: return "OpConstantNull"; + case OpSpecConstantTrue: return "OpSpecConstantTrue"; + case OpSpecConstantFalse: return "OpSpecConstantFalse"; + case OpSpecConstant: return "OpSpecConstant"; + case OpSpecConstantComposite: return "OpSpecConstantComposite"; + case OpSpecConstantOp: return "OpSpecConstantOp"; + case OpFunction: return "OpFunction"; + case OpFunctionParameter: return "OpFunctionParameter"; + case OpFunctionEnd: return "OpFunctionEnd"; + case OpFunctionCall: return "OpFunctionCall"; + case OpVariable: return "OpVariable"; + case OpImageTexelPointer: return "OpImageTexelPointer"; + case OpLoad: return "OpLoad"; + case OpStore: return "OpStore"; + case OpCopyMemory: return "OpCopyMemory"; + case OpCopyMemorySized: return "OpCopyMemorySized"; + case OpAccessChain: return "OpAccessChain"; + case OpInBoundsAccessChain: return "OpInBoundsAccessChain"; + case OpPtrAccessChain: return "OpPtrAccessChain"; + case OpArrayLength: return "OpArrayLength"; + case OpGenericPtrMemSemantics: return "OpGenericPtrMemSemantics"; + case OpInBoundsPtrAccessChain: return "OpInBoundsPtrAccessChain"; + case OpDecorate: return "OpDecorate"; + case OpMemberDecorate: return "OpMemberDecorate"; + case OpDecorationGroup: return "OpDecorationGroup"; + case OpGroupDecorate: return "OpGroupDecorate"; + case OpGroupMemberDecorate: return "OpGroupMemberDecorate"; + case OpVectorExtractDynamic: return "OpVectorExtractDynamic"; + case OpVectorInsertDynamic: return "OpVectorInsertDynamic"; + case OpVectorShuffle: return "OpVectorShuffle"; + case OpCompositeConstruct: return "OpCompositeConstruct"; + case OpCompositeExtract: return "OpCompositeExtract"; + case OpCompositeInsert: return "OpCompositeInsert"; + case OpCopyObject: return "OpCopyObject"; + case OpTranspose: return "OpTranspose"; + case OpSampledImage: return "OpSampledImage"; + case OpImageSampleImplicitLod: return "OpImageSampleImplicitLod"; + case OpImageSampleExplicitLod: return "OpImageSampleExplicitLod"; + case OpImageSampleDrefImplicitLod: return "OpImageSampleDrefImplicitLod"; + case OpImageSampleDrefExplicitLod: return "OpImageSampleDrefExplicitLod"; + case OpImageSampleProjImplicitLod: return "OpImageSampleProjImplicitLod"; + case OpImageSampleProjExplicitLod: return "OpImageSampleProjExplicitLod"; + case OpImageSampleProjDrefImplicitLod: return "OpImageSampleProjDrefImplicitLod"; + case OpImageSampleProjDrefExplicitLod: return "OpImageSampleProjDrefExplicitLod"; + case OpImageFetch: return "OpImageFetch"; + case OpImageGather: return "OpImageGather"; + case OpImageDrefGather: return "OpImageDrefGather"; + case OpImageRead: return "OpImageRead"; + case OpImageWrite: return "OpImageWrite"; + case OpImage: return "OpImage"; + case OpImageQueryFormat: return "OpImageQueryFormat"; + case OpImageQueryOrder: return "OpImageQueryOrder"; + case OpImageQuerySizeLod: return "OpImageQuerySizeLod"; + case OpImageQuerySize: return "OpImageQuerySize"; + case OpImageQueryLod: return "OpImageQueryLod"; + case OpImageQueryLevels: return "OpImageQueryLevels"; + case OpImageQuerySamples: return "OpImageQuerySamples"; + case OpConvertFToU: return "OpConvertFToU"; + case OpConvertFToS: return "OpConvertFToS"; + case OpConvertSToF: return "OpConvertSToF"; + case OpConvertUToF: return "OpConvertUToF"; + case OpUConvert: return "OpUConvert"; + case OpSConvert: return "OpSConvert"; + case OpFConvert: return "OpFConvert"; + case OpQuantizeToF16: return "OpQuantizeToF16"; + case OpConvertPtrToU: return "OpConvertPtrToU"; + case OpSatConvertSToU: return "OpSatConvertSToU"; + case OpSatConvertUToS: return "OpSatConvertUToS"; + case OpConvertUToPtr: return "OpConvertUToPtr"; + case OpPtrCastToGeneric: return "OpPtrCastToGeneric"; + case OpGenericCastToPtr: return "OpGenericCastToPtr"; + case OpGenericCastToPtrExplicit: return "OpGenericCastToPtrExplicit"; + case OpBitcast: return "OpBitcast"; + case OpSNegate: return "OpSNegate"; + case OpFNegate: return "OpFNegate"; + case OpIAdd: return "OpIAdd"; + case OpFAdd: return "OpFAdd"; + case OpISub: return "OpISub"; + case OpFSub: return "OpFSub"; + case OpIMul: return "OpIMul"; + case OpFMul: return "OpFMul"; + case OpUDiv: return "OpUDiv"; + case OpSDiv: return "OpSDiv"; + case OpFDiv: return "OpFDiv"; + case OpUMod: return "OpUMod"; + case OpSRem: return "OpSRem"; + case OpSMod: return "OpSMod"; + case OpFRem: return "OpFRem"; + case OpFMod: return "OpFMod"; + case OpVectorTimesScalar: return "OpVectorTimesScalar"; + case OpMatrixTimesScalar: return "OpMatrixTimesScalar"; + case OpVectorTimesMatrix: return "OpVectorTimesMatrix"; + case OpMatrixTimesVector: return "OpMatrixTimesVector"; + case OpMatrixTimesMatrix: return "OpMatrixTimesMatrix"; + case OpOuterProduct: return "OpOuterProduct"; + case OpDot: return "OpDot"; + case OpIAddCarry: return "OpIAddCarry"; + case OpISubBorrow: return "OpISubBorrow"; + case OpUMulExtended: return "OpUMulExtended"; + case OpSMulExtended: return "OpSMulExtended"; + case OpAny: return "OpAny"; + case OpAll: return "OpAll"; + case OpIsNan: return "OpIsNan"; + case OpIsInf: return "OpIsInf"; + case OpIsFinite: return "OpIsFinite"; + case OpIsNormal: return "OpIsNormal"; + case OpSignBitSet: return "OpSignBitSet"; + case OpLessOrGreater: return "OpLessOrGreater"; + case OpOrdered: return "OpOrdered"; + case OpUnordered: return "OpUnordered"; + case OpLogicalEqual: return "OpLogicalEqual"; + case OpLogicalNotEqual: return "OpLogicalNotEqual"; + case OpLogicalOr: return "OpLogicalOr"; + case OpLogicalAnd: return "OpLogicalAnd"; + case OpLogicalNot: return "OpLogicalNot"; + case OpSelect: return "OpSelect"; + case OpIEqual: return "OpIEqual"; + case OpINotEqual: return "OpINotEqual"; + case OpUGreaterThan: return "OpUGreaterThan"; + case OpSGreaterThan: return "OpSGreaterThan"; + case OpUGreaterThanEqual: return "OpUGreaterThanEqual"; + case OpSGreaterThanEqual: return "OpSGreaterThanEqual"; + case OpULessThan: return "OpULessThan"; + case OpSLessThan: return "OpSLessThan"; + case OpULessThanEqual: return "OpULessThanEqual"; + case OpSLessThanEqual: return "OpSLessThanEqual"; + case OpFOrdEqual: return "OpFOrdEqual"; + case OpFUnordEqual: return "OpFUnordEqual"; + case OpFOrdNotEqual: return "OpFOrdNotEqual"; + case OpFUnordNotEqual: return "OpFUnordNotEqual"; + case OpFOrdLessThan: return "OpFOrdLessThan"; + case OpFUnordLessThan: return "OpFUnordLessThan"; + case OpFOrdGreaterThan: return "OpFOrdGreaterThan"; + case OpFUnordGreaterThan: return "OpFUnordGreaterThan"; + case OpFOrdLessThanEqual: return "OpFOrdLessThanEqual"; + case OpFUnordLessThanEqual: return "OpFUnordLessThanEqual"; + case OpFOrdGreaterThanEqual: return "OpFOrdGreaterThanEqual"; + case OpFUnordGreaterThanEqual: return "OpFUnordGreaterThanEqual"; + case OpShiftRightLogical: return "OpShiftRightLogical"; + case OpShiftRightArithmetic: return "OpShiftRightArithmetic"; + case OpShiftLeftLogical: return "OpShiftLeftLogical"; + case OpBitwiseOr: return "OpBitwiseOr"; + case OpBitwiseXor: return "OpBitwiseXor"; + case OpBitwiseAnd: return "OpBitwiseAnd"; + case OpNot: return "OpNot"; + case OpBitFieldInsert: return "OpBitFieldInsert"; + case OpBitFieldSExtract: return "OpBitFieldSExtract"; + case OpBitFieldUExtract: return "OpBitFieldUExtract"; + case OpBitReverse: return "OpBitReverse"; + case OpBitCount: return "OpBitCount"; + case OpDPdx: return "OpDPdx"; + case OpDPdy: return "OpDPdy"; + case OpFwidth: return "OpFwidth"; + case OpDPdxFine: return "OpDPdxFine"; + case OpDPdyFine: return "OpDPdyFine"; + case OpFwidthFine: return "OpFwidthFine"; + case OpDPdxCoarse: return "OpDPdxCoarse"; + case OpDPdyCoarse: return "OpDPdyCoarse"; + case OpFwidthCoarse: return "OpFwidthCoarse"; + case OpEmitVertex: return "OpEmitVertex"; + case OpEndPrimitive: return "OpEndPrimitive"; + case OpEmitStreamVertex: return "OpEmitStreamVertex"; + case OpEndStreamPrimitive: return "OpEndStreamPrimitive"; + case OpControlBarrier: return "OpControlBarrier"; + case OpMemoryBarrier: return "OpMemoryBarrier"; + case OpAtomicLoad: return "OpAtomicLoad"; + case OpAtomicStore: return "OpAtomicStore"; + case OpAtomicExchange: return "OpAtomicExchange"; + case OpAtomicCompareExchange: return "OpAtomicCompareExchange"; + case OpAtomicCompareExchangeWeak: return "OpAtomicCompareExchangeWeak"; + case OpAtomicIIncrement: return "OpAtomicIIncrement"; + case OpAtomicIDecrement: return "OpAtomicIDecrement"; + case OpAtomicIAdd: return "OpAtomicIAdd"; + case OpAtomicISub: return "OpAtomicISub"; + case OpAtomicSMin: return "OpAtomicSMin"; + case OpAtomicUMin: return "OpAtomicUMin"; + case OpAtomicSMax: return "OpAtomicSMax"; + case OpAtomicUMax: return "OpAtomicUMax"; + case OpAtomicAnd: return "OpAtomicAnd"; + case OpAtomicOr: return "OpAtomicOr"; + case OpAtomicXor: return "OpAtomicXor"; + case OpPhi: return "OpPhi"; + case OpLoopMerge: return "OpLoopMerge"; + case OpSelectionMerge: return "OpSelectionMerge"; + case OpLabel: return "OpLabel"; + case OpBranch: return "OpBranch"; + case OpBranchConditional: return "OpBranchConditional"; + case OpSwitch: return "OpSwitch"; + case OpKill: return "OpKill"; + case OpReturn: return "OpReturn"; + case OpReturnValue: return "OpReturnValue"; + case OpUnreachable: return "OpUnreachable"; + case OpLifetimeStart: return "OpLifetimeStart"; + case OpLifetimeStop: return "OpLifetimeStop"; + case OpGroupAsyncCopy: return "OpGroupAsyncCopy"; + case OpGroupWaitEvents: return "OpGroupWaitEvents"; + case OpGroupAll: return "OpGroupAll"; + case OpGroupAny: return "OpGroupAny"; + case OpGroupBroadcast: return "OpGroupBroadcast"; + case OpGroupIAdd: return "OpGroupIAdd"; + case OpGroupFAdd: return "OpGroupFAdd"; + case OpGroupFMin: return "OpGroupFMin"; + case OpGroupUMin: return "OpGroupUMin"; + case OpGroupSMin: return "OpGroupSMin"; + case OpGroupFMax: return "OpGroupFMax"; + case OpGroupUMax: return "OpGroupUMax"; + case OpGroupSMax: return "OpGroupSMax"; + case OpReadPipe: return "OpReadPipe"; + case OpWritePipe: return "OpWritePipe"; + case OpReservedReadPipe: return "OpReservedReadPipe"; + case OpReservedWritePipe: return "OpReservedWritePipe"; + case OpReserveReadPipePackets: return "OpReserveReadPipePackets"; + case OpReserveWritePipePackets: return "OpReserveWritePipePackets"; + case OpCommitReadPipe: return "OpCommitReadPipe"; + case OpCommitWritePipe: return "OpCommitWritePipe"; + case OpIsValidReserveId: return "OpIsValidReserveId"; + case OpGetNumPipePackets: return "OpGetNumPipePackets"; + case OpGetMaxPipePackets: return "OpGetMaxPipePackets"; + case OpGroupReserveReadPipePackets: return "OpGroupReserveReadPipePackets"; + case OpGroupReserveWritePipePackets: return "OpGroupReserveWritePipePackets"; + case OpGroupCommitReadPipe: return "OpGroupCommitReadPipe"; + case OpGroupCommitWritePipe: return "OpGroupCommitWritePipe"; + case OpEnqueueMarker: return "OpEnqueueMarker"; + case OpEnqueueKernel: return "OpEnqueueKernel"; + case OpGetKernelNDrangeSubGroupCount: return "OpGetKernelNDrangeSubGroupCount"; + case OpGetKernelNDrangeMaxSubGroupSize: return "OpGetKernelNDrangeMaxSubGroupSize"; + case OpGetKernelWorkGroupSize: return "OpGetKernelWorkGroupSize"; + case OpGetKernelPreferredWorkGroupSizeMultiple: return "OpGetKernelPreferredWorkGroupSizeMultiple"; + case OpRetainEvent: return "OpRetainEvent"; + case OpReleaseEvent: return "OpReleaseEvent"; + case OpCreateUserEvent: return "OpCreateUserEvent"; + case OpIsValidEvent: return "OpIsValidEvent"; + case OpSetUserEventStatus: return "OpSetUserEventStatus"; + case OpCaptureEventProfilingInfo: return "OpCaptureEventProfilingInfo"; + case OpGetDefaultQueue: return "OpGetDefaultQueue"; + case OpBuildNDRange: return "OpBuildNDRange"; + case OpImageSparseSampleImplicitLod: return "OpImageSparseSampleImplicitLod"; + case OpImageSparseSampleExplicitLod: return "OpImageSparseSampleExplicitLod"; + case OpImageSparseSampleDrefImplicitLod: return "OpImageSparseSampleDrefImplicitLod"; + case OpImageSparseSampleDrefExplicitLod: return "OpImageSparseSampleDrefExplicitLod"; + case OpImageSparseSampleProjImplicitLod: return "OpImageSparseSampleProjImplicitLod"; + case OpImageSparseSampleProjExplicitLod: return "OpImageSparseSampleProjExplicitLod"; + case OpImageSparseSampleProjDrefImplicitLod: return "OpImageSparseSampleProjDrefImplicitLod"; + case OpImageSparseSampleProjDrefExplicitLod: return "OpImageSparseSampleProjDrefExplicitLod"; + case OpImageSparseFetch: return "OpImageSparseFetch"; + case OpImageSparseGather: return "OpImageSparseGather"; + case OpImageSparseDrefGather: return "OpImageSparseDrefGather"; + case OpImageSparseTexelsResident: return "OpImageSparseTexelsResident"; + case OpNoLine: return "OpNoLine"; + case OpAtomicFlagTestAndSet: return "OpAtomicFlagTestAndSet"; + case OpAtomicFlagClear: return "OpAtomicFlagClear"; + case OpImageSparseRead: return "OpImageSparseRead"; + case OpSizeOf: return "OpSizeOf"; + case OpTypePipeStorage: return "OpTypePipeStorage"; + case OpConstantPipeStorage: return "OpConstantPipeStorage"; + case OpCreatePipeFromPipeStorage: return "OpCreatePipeFromPipeStorage"; + case OpGetKernelLocalSizeForSubgroupCount: return "OpGetKernelLocalSizeForSubgroupCount"; + case OpGetKernelMaxNumSubgroups: return "OpGetKernelMaxNumSubgroups"; + case OpTypeNamedBarrier: return "OpTypeNamedBarrier"; + case OpNamedBarrierInitialize: return "OpNamedBarrierInitialize"; + case OpMemoryNamedBarrier: return "OpMemoryNamedBarrier"; + case OpModuleProcessed: return "OpModuleProcessed"; + case OpExecutionModeId: return "OpExecutionModeId"; + case OpDecorateId: return "OpDecorateId"; + case OpGroupNonUniformElect: return "OpGroupNonUniformElect"; + case OpGroupNonUniformAll: return "OpGroupNonUniformAll"; + case OpGroupNonUniformAny: return "OpGroupNonUniformAny"; + case OpGroupNonUniformAllEqual: return "OpGroupNonUniformAllEqual"; + case OpGroupNonUniformBroadcast: return "OpGroupNonUniformBroadcast"; + case OpGroupNonUniformBroadcastFirst: return "OpGroupNonUniformBroadcastFirst"; + case OpGroupNonUniformBallot: return "OpGroupNonUniformBallot"; + case OpGroupNonUniformInverseBallot: return "OpGroupNonUniformInverseBallot"; + case OpGroupNonUniformBallotBitExtract: return "OpGroupNonUniformBallotBitExtract"; + case OpGroupNonUniformBallotBitCount: return "OpGroupNonUniformBallotBitCount"; + case OpGroupNonUniformBallotFindLSB: return "OpGroupNonUniformBallotFindLSB"; + case OpGroupNonUniformBallotFindMSB: return "OpGroupNonUniformBallotFindMSB"; + case OpGroupNonUniformShuffle: return "OpGroupNonUniformShuffle"; + case OpGroupNonUniformShuffleXor: return "OpGroupNonUniformShuffleXor"; + case OpGroupNonUniformShuffleUp: return "OpGroupNonUniformShuffleUp"; + case OpGroupNonUniformShuffleDown: return "OpGroupNonUniformShuffleDown"; + case OpGroupNonUniformIAdd: return "OpGroupNonUniformIAdd"; + case OpGroupNonUniformFAdd: return "OpGroupNonUniformFAdd"; + case OpGroupNonUniformIMul: return "OpGroupNonUniformIMul"; + case OpGroupNonUniformFMul: return "OpGroupNonUniformFMul"; + case OpGroupNonUniformSMin: return "OpGroupNonUniformSMin"; + case OpGroupNonUniformUMin: return "OpGroupNonUniformUMin"; + case OpGroupNonUniformFMin: return "OpGroupNonUniformFMin"; + case OpGroupNonUniformSMax: return "OpGroupNonUniformSMax"; + case OpGroupNonUniformUMax: return "OpGroupNonUniformUMax"; + case OpGroupNonUniformFMax: return "OpGroupNonUniformFMax"; + case OpGroupNonUniformBitwiseAnd: return "OpGroupNonUniformBitwiseAnd"; + case OpGroupNonUniformBitwiseOr: return "OpGroupNonUniformBitwiseOr"; + case OpGroupNonUniformBitwiseXor: return "OpGroupNonUniformBitwiseXor"; + case OpGroupNonUniformLogicalAnd: return "OpGroupNonUniformLogicalAnd"; + case OpGroupNonUniformLogicalOr: return "OpGroupNonUniformLogicalOr"; + case OpGroupNonUniformLogicalXor: return "OpGroupNonUniformLogicalXor"; + case OpGroupNonUniformQuadBroadcast: return "OpGroupNonUniformQuadBroadcast"; + case OpGroupNonUniformQuadSwap: return "OpGroupNonUniformQuadSwap"; + case OpCopyLogical: return "OpCopyLogical"; + case OpPtrEqual: return "OpPtrEqual"; + case OpPtrNotEqual: return "OpPtrNotEqual"; + case OpPtrDiff: return "OpPtrDiff"; + case OpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT"; + case OpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT"; + case OpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT"; + case OpTerminateInvocation: return "OpTerminateInvocation"; + case OpSubgroupBallotKHR: return "OpSubgroupBallotKHR"; + case OpSubgroupFirstInvocationKHR: return "OpSubgroupFirstInvocationKHR"; + case OpSubgroupAllKHR: return "OpSubgroupAllKHR"; + case OpSubgroupAnyKHR: return "OpSubgroupAnyKHR"; + case OpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR"; + case OpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR"; + case OpSubgroupReadInvocationKHR: return "OpSubgroupReadInvocationKHR"; + case OpExtInstWithForwardRefsKHR: return "OpExtInstWithForwardRefsKHR"; + case OpTraceRayKHR: return "OpTraceRayKHR"; + case OpExecuteCallableKHR: return "OpExecuteCallableKHR"; + case OpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR"; + case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case OpTerminateRayKHR: return "OpTerminateRayKHR"; + case OpSDot: return "OpSDot"; + case OpUDot: return "OpUDot"; + case OpSUDot: return "OpSUDot"; + case OpSDotAccSat: return "OpSDotAccSat"; + case OpUDotAccSat: return "OpUDotAccSat"; + case OpSUDotAccSat: return "OpSUDotAccSat"; + case OpTypeCooperativeMatrixKHR: return "OpTypeCooperativeMatrixKHR"; + case OpCooperativeMatrixLoadKHR: return "OpCooperativeMatrixLoadKHR"; + case OpCooperativeMatrixStoreKHR: return "OpCooperativeMatrixStoreKHR"; + case OpCooperativeMatrixMulAddKHR: return "OpCooperativeMatrixMulAddKHR"; + case OpCooperativeMatrixLengthKHR: return "OpCooperativeMatrixLengthKHR"; + case OpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT"; + case OpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT"; + case OpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT"; + case OpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; + case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case OpImageSampleWeightedQCOM: return "OpImageSampleWeightedQCOM"; + case OpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; + case OpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + case OpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; + case OpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM"; + case OpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM"; + case OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; + case OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; + case OpGroupIAddNonUniformAMD: return "OpGroupIAddNonUniformAMD"; + case OpGroupFAddNonUniformAMD: return "OpGroupFAddNonUniformAMD"; + case OpGroupFMinNonUniformAMD: return "OpGroupFMinNonUniformAMD"; + case OpGroupUMinNonUniformAMD: return "OpGroupUMinNonUniformAMD"; + case OpGroupSMinNonUniformAMD: return "OpGroupSMinNonUniformAMD"; + case OpGroupFMaxNonUniformAMD: return "OpGroupFMaxNonUniformAMD"; + case OpGroupUMaxNonUniformAMD: return "OpGroupUMaxNonUniformAMD"; + case OpGroupSMaxNonUniformAMD: return "OpGroupSMaxNonUniformAMD"; + case OpFragmentMaskFetchAMD: return "OpFragmentMaskFetchAMD"; + case OpFragmentFetchAMD: return "OpFragmentFetchAMD"; + case OpReadClockKHR: return "OpReadClockKHR"; + case OpFinalizeNodePayloadsAMDX: return "OpFinalizeNodePayloadsAMDX"; + case OpFinishWritingNodePayloadAMDX: return "OpFinishWritingNodePayloadAMDX"; + case OpInitializeNodePayloadsAMDX: return "OpInitializeNodePayloadsAMDX"; + case OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; + case OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; + case OpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; + case OpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; + case OpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; + case OpHitObjectGetWorldToObjectNV: return "OpHitObjectGetWorldToObjectNV"; + case OpHitObjectGetObjectToWorldNV: return "OpHitObjectGetObjectToWorldNV"; + case OpHitObjectGetObjectRayDirectionNV: return "OpHitObjectGetObjectRayDirectionNV"; + case OpHitObjectGetObjectRayOriginNV: return "OpHitObjectGetObjectRayOriginNV"; + case OpHitObjectTraceRayMotionNV: return "OpHitObjectTraceRayMotionNV"; + case OpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV"; + case OpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV"; + case OpHitObjectRecordEmptyNV: return "OpHitObjectRecordEmptyNV"; + case OpHitObjectTraceRayNV: return "OpHitObjectTraceRayNV"; + case OpHitObjectRecordHitNV: return "OpHitObjectRecordHitNV"; + case OpHitObjectRecordHitWithIndexNV: return "OpHitObjectRecordHitWithIndexNV"; + case OpHitObjectRecordMissNV: return "OpHitObjectRecordMissNV"; + case OpHitObjectExecuteShaderNV: return "OpHitObjectExecuteShaderNV"; + case OpHitObjectGetCurrentTimeNV: return "OpHitObjectGetCurrentTimeNV"; + case OpHitObjectGetAttributesNV: return "OpHitObjectGetAttributesNV"; + case OpHitObjectGetHitKindNV: return "OpHitObjectGetHitKindNV"; + case OpHitObjectGetPrimitiveIndexNV: return "OpHitObjectGetPrimitiveIndexNV"; + case OpHitObjectGetGeometryIndexNV: return "OpHitObjectGetGeometryIndexNV"; + case OpHitObjectGetInstanceIdNV: return "OpHitObjectGetInstanceIdNV"; + case OpHitObjectGetInstanceCustomIndexNV: return "OpHitObjectGetInstanceCustomIndexNV"; + case OpHitObjectGetWorldRayDirectionNV: return "OpHitObjectGetWorldRayDirectionNV"; + case OpHitObjectGetWorldRayOriginNV: return "OpHitObjectGetWorldRayOriginNV"; + case OpHitObjectGetRayTMaxNV: return "OpHitObjectGetRayTMaxNV"; + case OpHitObjectGetRayTMinNV: return "OpHitObjectGetRayTMinNV"; + case OpHitObjectIsEmptyNV: return "OpHitObjectIsEmptyNV"; + case OpHitObjectIsHitNV: return "OpHitObjectIsHitNV"; + case OpHitObjectIsMissNV: return "OpHitObjectIsMissNV"; + case OpReorderThreadWithHitObjectNV: return "OpReorderThreadWithHitObjectNV"; + case OpReorderThreadWithHintNV: return "OpReorderThreadWithHintNV"; + case OpTypeHitObjectNV: return "OpTypeHitObjectNV"; + case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; + case OpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT"; + case OpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT"; + case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; + case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case OpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV"; + case OpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV"; + case OpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case OpTerminateRayNV: return "OpTerminateRayNV"; + case OpTraceNV: return "OpTraceNV"; + case OpTraceMotionNV: return "OpTraceMotionNV"; + case OpTraceRayMotionNV: return "OpTraceRayMotionNV"; + case OpRayQueryGetIntersectionTriangleVertexPositionsKHR: return "OpRayQueryGetIntersectionTriangleVertexPositionsKHR"; + case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case OpExecuteCallableNV: return "OpExecuteCallableNV"; + case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + case OpDemoteToHelperInvocation: return "OpDemoteToHelperInvocation"; + case OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + case OpConvertUToImageNV: return "OpConvertUToImageNV"; + case OpConvertUToSamplerNV: return "OpConvertUToSamplerNV"; + case OpConvertImageToUNV: return "OpConvertImageToUNV"; + case OpConvertSamplerToUNV: return "OpConvertSamplerToUNV"; + case OpConvertUToSampledImageNV: return "OpConvertUToSampledImageNV"; + case OpConvertSampledImageToUNV: return "OpConvertSampledImageToUNV"; + case OpSamplerImageAddressingModeNV: return "OpSamplerImageAddressingModeNV"; + case OpRawAccessChainNV: return "OpRawAccessChainNV"; + case OpSubgroupShuffleINTEL: return "OpSubgroupShuffleINTEL"; + case OpSubgroupShuffleDownINTEL: return "OpSubgroupShuffleDownINTEL"; + case OpSubgroupShuffleUpINTEL: return "OpSubgroupShuffleUpINTEL"; + case OpSubgroupShuffleXorINTEL: return "OpSubgroupShuffleXorINTEL"; + case OpSubgroupBlockReadINTEL: return "OpSubgroupBlockReadINTEL"; + case OpSubgroupBlockWriteINTEL: return "OpSubgroupBlockWriteINTEL"; + case OpSubgroupImageBlockReadINTEL: return "OpSubgroupImageBlockReadINTEL"; + case OpSubgroupImageBlockWriteINTEL: return "OpSubgroupImageBlockWriteINTEL"; + case OpSubgroupImageMediaBlockReadINTEL: return "OpSubgroupImageMediaBlockReadINTEL"; + case OpSubgroupImageMediaBlockWriteINTEL: return "OpSubgroupImageMediaBlockWriteINTEL"; + case OpUCountLeadingZerosINTEL: return "OpUCountLeadingZerosINTEL"; + case OpUCountTrailingZerosINTEL: return "OpUCountTrailingZerosINTEL"; + case OpAbsISubINTEL: return "OpAbsISubINTEL"; + case OpAbsUSubINTEL: return "OpAbsUSubINTEL"; + case OpIAddSatINTEL: return "OpIAddSatINTEL"; + case OpUAddSatINTEL: return "OpUAddSatINTEL"; + case OpIAverageINTEL: return "OpIAverageINTEL"; + case OpUAverageINTEL: return "OpUAverageINTEL"; + case OpIAverageRoundedINTEL: return "OpIAverageRoundedINTEL"; + case OpUAverageRoundedINTEL: return "OpUAverageRoundedINTEL"; + case OpISubSatINTEL: return "OpISubSatINTEL"; + case OpUSubSatINTEL: return "OpUSubSatINTEL"; + case OpIMul32x16INTEL: return "OpIMul32x16INTEL"; + case OpUMul32x16INTEL: return "OpUMul32x16INTEL"; + case OpConstantFunctionPointerINTEL: return "OpConstantFunctionPointerINTEL"; + case OpFunctionPointerCallINTEL: return "OpFunctionPointerCallINTEL"; + case OpAsmTargetINTEL: return "OpAsmTargetINTEL"; + case OpAsmINTEL: return "OpAsmINTEL"; + case OpAsmCallINTEL: return "OpAsmCallINTEL"; + case OpAtomicFMinEXT: return "OpAtomicFMinEXT"; + case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; + case OpAssumeTrueKHR: return "OpAssumeTrueKHR"; + case OpExpectKHR: return "OpExpectKHR"; + case OpDecorateString: return "OpDecorateString"; + case OpMemberDecorateString: return "OpMemberDecorateString"; + case OpVmeImageINTEL: return "OpVmeImageINTEL"; + case OpTypeVmeImageINTEL: return "OpTypeVmeImageINTEL"; + case OpTypeAvcImePayloadINTEL: return "OpTypeAvcImePayloadINTEL"; + case OpTypeAvcRefPayloadINTEL: return "OpTypeAvcRefPayloadINTEL"; + case OpTypeAvcSicPayloadINTEL: return "OpTypeAvcSicPayloadINTEL"; + case OpTypeAvcMcePayloadINTEL: return "OpTypeAvcMcePayloadINTEL"; + case OpTypeAvcMceResultINTEL: return "OpTypeAvcMceResultINTEL"; + case OpTypeAvcImeResultINTEL: return "OpTypeAvcImeResultINTEL"; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: return "OpTypeAvcImeResultSingleReferenceStreamoutINTEL"; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: return "OpTypeAvcImeResultDualReferenceStreamoutINTEL"; + case OpTypeAvcImeSingleReferenceStreaminINTEL: return "OpTypeAvcImeSingleReferenceStreaminINTEL"; + case OpTypeAvcImeDualReferenceStreaminINTEL: return "OpTypeAvcImeDualReferenceStreaminINTEL"; + case OpTypeAvcRefResultINTEL: return "OpTypeAvcRefResultINTEL"; + case OpTypeAvcSicResultINTEL: return "OpTypeAvcSicResultINTEL"; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL"; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL"; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: return "OpSubgroupAvcMceSetInterShapePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL"; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: return "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL"; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: return "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL"; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL"; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: return "OpSubgroupAvcMceSetAcOnlyHaarINTEL"; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL"; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL"; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL"; + case OpSubgroupAvcMceConvertToImePayloadINTEL: return "OpSubgroupAvcMceConvertToImePayloadINTEL"; + case OpSubgroupAvcMceConvertToImeResultINTEL: return "OpSubgroupAvcMceConvertToImeResultINTEL"; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: return "OpSubgroupAvcMceConvertToRefPayloadINTEL"; + case OpSubgroupAvcMceConvertToRefResultINTEL: return "OpSubgroupAvcMceConvertToRefResultINTEL"; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: return "OpSubgroupAvcMceConvertToSicPayloadINTEL"; + case OpSubgroupAvcMceConvertToSicResultINTEL: return "OpSubgroupAvcMceConvertToSicResultINTEL"; + case OpSubgroupAvcMceGetMotionVectorsINTEL: return "OpSubgroupAvcMceGetMotionVectorsINTEL"; + case OpSubgroupAvcMceGetInterDistortionsINTEL: return "OpSubgroupAvcMceGetInterDistortionsINTEL"; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: return "OpSubgroupAvcMceGetBestInterDistortionsINTEL"; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: return "OpSubgroupAvcMceGetInterMajorShapeINTEL"; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: return "OpSubgroupAvcMceGetInterMinorShapeINTEL"; + case OpSubgroupAvcMceGetInterDirectionsINTEL: return "OpSubgroupAvcMceGetInterDirectionsINTEL"; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: return "OpSubgroupAvcMceGetInterMotionVectorCountINTEL"; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: return "OpSubgroupAvcMceGetInterReferenceIdsINTEL"; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL"; + case OpSubgroupAvcImeInitializeINTEL: return "OpSubgroupAvcImeInitializeINTEL"; + case OpSubgroupAvcImeSetSingleReferenceINTEL: return "OpSubgroupAvcImeSetSingleReferenceINTEL"; + case OpSubgroupAvcImeSetDualReferenceINTEL: return "OpSubgroupAvcImeSetDualReferenceINTEL"; + case OpSubgroupAvcImeRefWindowSizeINTEL: return "OpSubgroupAvcImeRefWindowSizeINTEL"; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: return "OpSubgroupAvcImeAdjustRefOffsetINTEL"; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: return "OpSubgroupAvcImeConvertToMcePayloadINTEL"; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: return "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL"; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: return "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL"; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: return "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL"; + case OpSubgroupAvcImeSetWeightedSadINTEL: return "OpSubgroupAvcImeSetWeightedSadINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL"; + case OpSubgroupAvcImeConvertToMceResultINTEL: return "OpSubgroupAvcImeConvertToMceResultINTEL"; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL"; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: return "OpSubgroupAvcImeGetDualReferenceStreaminINTEL"; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL"; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL"; + case OpSubgroupAvcImeGetBorderReachedINTEL: return "OpSubgroupAvcImeGetBorderReachedINTEL"; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: return "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL"; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: return "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL"; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL"; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL"; + case OpSubgroupAvcFmeInitializeINTEL: return "OpSubgroupAvcFmeInitializeINTEL"; + case OpSubgroupAvcBmeInitializeINTEL: return "OpSubgroupAvcBmeInitializeINTEL"; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: return "OpSubgroupAvcRefConvertToMcePayloadINTEL"; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: return "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL"; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: return "OpSubgroupAvcRefSetBilinearFilterEnableINTEL"; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL"; + case OpSubgroupAvcRefConvertToMceResultINTEL: return "OpSubgroupAvcRefConvertToMceResultINTEL"; + case OpSubgroupAvcSicInitializeINTEL: return "OpSubgroupAvcSicInitializeINTEL"; + case OpSubgroupAvcSicConfigureSkcINTEL: return "OpSubgroupAvcSicConfigureSkcINTEL"; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaINTEL"; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL"; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: return "OpSubgroupAvcSicGetMotionVectorMaskINTEL"; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: return "OpSubgroupAvcSicConvertToMcePayloadINTEL"; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL"; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL"; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL"; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: return "OpSubgroupAvcSicSetBilinearFilterEnableINTEL"; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: return "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL"; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: return "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL"; + case OpSubgroupAvcSicEvaluateIpeINTEL: return "OpSubgroupAvcSicEvaluateIpeINTEL"; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL"; + case OpSubgroupAvcSicConvertToMceResultINTEL: return "OpSubgroupAvcSicConvertToMceResultINTEL"; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: return "OpSubgroupAvcSicGetIpeLumaShapeINTEL"; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL"; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL"; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: return "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL"; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: return "OpSubgroupAvcSicGetIpeChromaModeINTEL"; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL"; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL"; + case OpSubgroupAvcSicGetInterRawSadsINTEL: return "OpSubgroupAvcSicGetInterRawSadsINTEL"; + case OpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL"; + case OpSaveMemoryINTEL: return "OpSaveMemoryINTEL"; + case OpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL"; + case OpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL"; + case OpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL"; + case OpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL"; + case OpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL"; + case OpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL"; + case OpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL"; + case OpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL"; + case OpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL"; + case OpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL"; + case OpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL"; + case OpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL"; + case OpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL"; + case OpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL"; + case OpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL"; + case OpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL"; + case OpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL"; + case OpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL"; + case OpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL"; + case OpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL"; + case OpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL"; + case OpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL"; + case OpArbitraryFloatLog1pINTEL: return "OpArbitraryFloatLog1pINTEL"; + case OpArbitraryFloatExpINTEL: return "OpArbitraryFloatExpINTEL"; + case OpArbitraryFloatExp2INTEL: return "OpArbitraryFloatExp2INTEL"; + case OpArbitraryFloatExp10INTEL: return "OpArbitraryFloatExp10INTEL"; + case OpArbitraryFloatExpm1INTEL: return "OpArbitraryFloatExpm1INTEL"; + case OpArbitraryFloatSinINTEL: return "OpArbitraryFloatSinINTEL"; + case OpArbitraryFloatCosINTEL: return "OpArbitraryFloatCosINTEL"; + case OpArbitraryFloatSinCosINTEL: return "OpArbitraryFloatSinCosINTEL"; + case OpArbitraryFloatSinPiINTEL: return "OpArbitraryFloatSinPiINTEL"; + case OpArbitraryFloatCosPiINTEL: return "OpArbitraryFloatCosPiINTEL"; + case OpArbitraryFloatASinINTEL: return "OpArbitraryFloatASinINTEL"; + case OpArbitraryFloatASinPiINTEL: return "OpArbitraryFloatASinPiINTEL"; + case OpArbitraryFloatACosINTEL: return "OpArbitraryFloatACosINTEL"; + case OpArbitraryFloatACosPiINTEL: return "OpArbitraryFloatACosPiINTEL"; + case OpArbitraryFloatATanINTEL: return "OpArbitraryFloatATanINTEL"; + case OpArbitraryFloatATanPiINTEL: return "OpArbitraryFloatATanPiINTEL"; + case OpArbitraryFloatATan2INTEL: return "OpArbitraryFloatATan2INTEL"; + case OpArbitraryFloatPowINTEL: return "OpArbitraryFloatPowINTEL"; + case OpArbitraryFloatPowRINTEL: return "OpArbitraryFloatPowRINTEL"; + case OpArbitraryFloatPowNINTEL: return "OpArbitraryFloatPowNINTEL"; + case OpLoopControlINTEL: return "OpLoopControlINTEL"; + case OpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL"; + case OpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL"; + case OpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL"; + case OpFixedSqrtINTEL: return "OpFixedSqrtINTEL"; + case OpFixedRecipINTEL: return "OpFixedRecipINTEL"; + case OpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL"; + case OpFixedSinINTEL: return "OpFixedSinINTEL"; + case OpFixedCosINTEL: return "OpFixedCosINTEL"; + case OpFixedSinCosINTEL: return "OpFixedSinCosINTEL"; + case OpFixedSinPiINTEL: return "OpFixedSinPiINTEL"; + case OpFixedCosPiINTEL: return "OpFixedCosPiINTEL"; + case OpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL"; + case OpFixedLogINTEL: return "OpFixedLogINTEL"; + case OpFixedExpINTEL: return "OpFixedExpINTEL"; + case OpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL"; + case OpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL"; + case OpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL"; + case OpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL"; + case OpFPGARegINTEL: return "OpFPGARegINTEL"; + case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case OpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case OpTypeBufferSurfaceINTEL: return "OpTypeBufferSurfaceINTEL"; + case OpTypeStructContinuedINTEL: return "OpTypeStructContinuedINTEL"; + case OpConstantCompositeContinuedINTEL: return "OpConstantCompositeContinuedINTEL"; + case OpSpecConstantCompositeContinuedINTEL: return "OpSpecConstantCompositeContinuedINTEL"; + case OpCompositeConstructContinuedINTEL: return "OpCompositeConstructContinuedINTEL"; + case OpConvertFToBF16INTEL: return "OpConvertFToBF16INTEL"; + case OpConvertBF16ToFINTEL: return "OpConvertBF16ToFINTEL"; + case OpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL"; + case OpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL"; + case OpGroupIMulKHR: return "OpGroupIMulKHR"; + case OpGroupFMulKHR: return "OpGroupFMulKHR"; + case OpGroupBitwiseAndKHR: return "OpGroupBitwiseAndKHR"; + case OpGroupBitwiseOrKHR: return "OpGroupBitwiseOrKHR"; + case OpGroupBitwiseXorKHR: return "OpGroupBitwiseXorKHR"; + case OpGroupLogicalAndKHR: return "OpGroupLogicalAndKHR"; + case OpGroupLogicalOrKHR: return "OpGroupLogicalOrKHR"; + case OpGroupLogicalXorKHR: return "OpGroupLogicalXorKHR"; + case OpMaskedGatherINTEL: return "OpMaskedGatherINTEL"; + case OpMaskedScatterINTEL: return "OpMaskedScatterINTEL"; + default: return "Unknown"; + } +} + +#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)); } +constexpr RawAccessChainOperandsMask operator|(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) | unsigned(b)); } +constexpr RawAccessChainOperandsMask operator&(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) & unsigned(b)); } +constexpr RawAccessChainOperandsMask operator^(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr RawAccessChainOperandsMask operator~(RawAccessChainOperandsMask a) { return RawAccessChainOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.json b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.json new file mode 100644 index 0000000..430c74f --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.json @@ -0,0 +1,2164 @@ +{ + "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, + "CooperativeMatrixLayoutsARM": 4201, + "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, + "RawAccessChainsNV": 5414, + "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, + "ReplicatedCompositesEXT": 6024, + "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, + "RowBlockedInterleavedARM": 4202, + "ColumnBlockedInterleavedARM": 4203 + } + }, + { + "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": "RawAccessChainOperands", + "Type": "Bit", + "Values": + { + "RobustnessPerComponentNV": 0, + "RobustnessPerElementNV": 1 + } + }, + { + "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, + "OpExtInstWithForwardRefsKHR": 4433, + "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, + "OpConstantCompositeReplicateEXT": 4461, + "OpSpecConstantCompositeReplicateEXT": 4462, + "OpCompositeConstructReplicateEXT": 4463, + "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, + "OpRawAccessChainNV": 5398, + "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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.lua b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.lua new file mode 100644 index 0000000..8f3ded0 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.lua @@ -0,0 +1,2105 @@ +-- 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, + CooperativeMatrixLayoutsARM = 4201, + 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, + RawAccessChainsNV = 5414, + 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, + ReplicatedCompositesEXT = 6024, + 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, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, + }, + + 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, + }, + + RawAccessChainOperandsShift = { + RobustnessPerComponentNV = 0, + RobustnessPerElementNV = 1, + }, + + RawAccessChainOperandsMask = { + MaskNone = 0, + RobustnessPerComponentNV = 0x00000001, + RobustnessPerElementNV = 0x00000002, + }, + + 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, + OpExtInstWithForwardRefsKHR = 4433, + 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, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + 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, + OpRawAccessChainNV = 5398, + 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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.py b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.py new file mode 100644 index 0000000..23c0fcc --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spirv.py @@ -0,0 +1,2105 @@ +# 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, + 'CooperativeMatrixLayoutsARM' : 4201, + '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, + 'RawAccessChainsNV' : 5414, + '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, + 'ReplicatedCompositesEXT' : 6024, + '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, + 'RowBlockedInterleavedARM' : 4202, + 'ColumnBlockedInterleavedARM' : 4203, + }, + + '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, + }, + + 'RawAccessChainOperandsShift' : { + 'RobustnessPerComponentNV' : 0, + 'RobustnessPerElementNV' : 1, + }, + + 'RawAccessChainOperandsMask' : { + 'MaskNone' : 0, + 'RobustnessPerComponentNV' : 0x00000001, + 'RobustnessPerElementNV' : 0x00000002, + }, + + '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, + 'OpExtInstWithForwardRefsKHR' : 4433, + '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, + 'OpConstantCompositeReplicateEXT' : 4461, + 'OpSpecConstantCompositeReplicateEXT' : 4462, + 'OpCompositeConstructReplicateEXT' : 4463, + '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, + 'OpRawAccessChainNV' : 5398, + '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/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spv.d b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spv.d new file mode 100644 index 0000000..295678e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/include/spirv/unified1/spv.d @@ -0,0 +1,2173 @@ +/+ + + 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. + +/ + +module spv; + +enum uint MagicNumber = 0x07230203; +enum uint Version = 0x00010600; +enum uint Revision = 1; +enum uint OpCodeMask = 0xffff; +enum uint WordCountShift = 16; + +enum SourceLanguage : uint +{ + 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, +} + +enum ExecutionModel : uint +{ + 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, +} + +enum AddressingModel : uint +{ + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, +} + +enum MemoryModel : uint +{ + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, +} + +enum ExecutionMode : uint +{ + 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, +} + +enum StorageClass : uint +{ + 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, +} + +enum Dim : uint +{ + _1D = 0, + _2D = 1, + _3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, +} + +enum SamplerAddressingMode : uint +{ + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, +} + +enum SamplerFilterMode : uint +{ + Nearest = 0, + Linear = 1, +} + +enum ImageFormat : uint +{ + 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, +} + +enum ImageChannelOrder : uint +{ + 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, +} + +enum ImageChannelDataType : uint +{ + 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, +} + +enum ImageOperandsShift : uint +{ + 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, +} + +enum ImageOperandsMask : uint +{ + 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 FPFastMathModeShift : uint +{ + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, +} + +enum FPFastMathModeMask : uint +{ + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, +} + +enum FPRoundingMode : uint +{ + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, +} + +enum LinkageType : uint +{ + Export = 0, + Import = 1, + LinkOnceODR = 2, +} + +enum AccessQualifier : uint +{ + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, +} + +enum FunctionParameterAttribute : uint +{ + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, +} + +enum Decoration : uint +{ + 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, +} + +enum BuiltIn : uint +{ + 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, +} + +enum SelectionControlShift : uint +{ + Flatten = 0, + DontFlatten = 1, +} + +enum SelectionControlMask : uint +{ + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +} + +enum LoopControlShift : uint +{ + 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, +} + +enum LoopControlMask : uint +{ + 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 FunctionControlShift : uint +{ + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneINTEL = 16, +} + +enum FunctionControlMask : uint +{ + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneINTEL = 0x00010000, +} + +enum MemorySemanticsShift : uint +{ + 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, +} + +enum MemorySemanticsMask : uint +{ + 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 MemoryAccessShift : uint +{ + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, +} + +enum MemoryAccessMask : uint +{ + 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 Scope : uint +{ + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, +} + +enum GroupOperation : uint +{ + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, +} + +enum KernelEnqueueFlags : uint +{ + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, +} + +enum KernelProfilingInfoShift : uint +{ + CmdExecTime = 0, +} + +enum KernelProfilingInfoMask : uint +{ + MaskNone = 0, + CmdExecTime = 0x00000001, +} + +enum Capability : uint +{ + 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, + CooperativeMatrixLayoutsARM = 4201, + 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, + RawAccessChainsNV = 5414, + 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, + ReplicatedCompositesEXT = 6024, + 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, +} + +enum RayFlagsShift : uint +{ + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, +} + +enum RayFlagsMask : uint +{ + 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 RayQueryIntersection : uint +{ + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, +} + +enum RayQueryCommittedIntersectionType : uint +{ + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, +} + +enum RayQueryCandidateIntersectionType : uint +{ + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, +} + +enum FragmentShadingRateShift : uint +{ + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, +} + +enum FragmentShadingRateMask : uint +{ + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, +} + +enum FPDenormMode : uint +{ + Preserve = 0, + FlushToZero = 1, +} + +enum FPOperationMode : uint +{ + IEEE = 0, + ALT = 1, +} + +enum QuantizationModes : uint +{ + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, +} + +enum OverflowModes : uint +{ + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, +} + +enum PackedVectorFormat : uint +{ + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, +} + +enum CooperativeMatrixOperandsShift : uint +{ + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, +} + +enum CooperativeMatrixOperandsMask : uint +{ + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, +} + +enum CooperativeMatrixLayout : uint +{ + RowMajorKHR = 0, + ColumnMajorKHR = 1, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, +} + +enum CooperativeMatrixUse : uint +{ + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, +} + +enum InitializationModeQualifier : uint +{ + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, +} + +enum HostAccessQualifier : uint +{ + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, +} + +enum LoadCacheControl : uint +{ + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, +} + +enum StoreCacheControl : uint +{ + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, +} + +enum NamedMaximumNumberOfRegisters : uint +{ + AutoINTEL = 0, +} + +enum RawAccessChainOperandsShift : uint +{ + RobustnessPerComponentNV = 0, + RobustnessPerElementNV = 1, +} + +enum RawAccessChainOperandsMask : uint +{ + MaskNone = 0, + RobustnessPerComponentNV = 0x00000001, + RobustnessPerElementNV = 0x00000002, +} + +enum Op : uint +{ + 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, + OpExtInstWithForwardRefsKHR = 4433, + 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, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + 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, + OpRawAccessChainNV = 5398, + 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/gpu/third_party/sirit/externals/SPIRV-Headers/tests/CMakeLists.txt b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/CMakeLists.txt new file mode 100644 index 0000000..ebf7e12 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/CMakeLists.txt @@ -0,0 +1,47 @@ +# 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. + +add_library(spirv_headers_simple_test STATIC) + +target_sources(spirv_headers_simple_test PRIVATE + example.cpp +) + +target_link_libraries(spirv_headers_simple_test PRIVATE + SPIRV-Headers::SPIRV-Headers +) + +if (NOT TARGET SPIRV-Headers) + message(FATAL_ERROR "SPIRV-Headers target not defined!") +endif() + +if (NOT PROJECT_NAME STREQUAL "SPIRV-Headers") + message(FATAL_ERROR "PROJECT_NAME changed!") # Needed for backcompat with SPIRV-Tools. +endif() + +if (NOT DEFINED SPIRV-Headers_SOURCE_DIR) + message(FATAL_ERROR "SPIRV-Headers_SOURCE_DIR not defined!") # Needed for backcompat with SPIRV-Tools. +endif() diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tests/example.cpp b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/example.cpp new file mode 100644 index 0000000..1920e80 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/example.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2016-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. + +#include +#include +#include + +namespace { + +const GLSLstd450 kSin = GLSLstd450Sin; +const OpenCLLIB::Entrypoints kNative_cos = OpenCLLIB::Native_cos; +const spv::Op kNop = spv::OpNop; + +} // anonymous namespace diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tests/find_package/CMakeLists.txt b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/find_package/CMakeLists.txt new file mode 100644 index 0000000..4735db5 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/find_package/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.0) + +project(TEST_FIND_PACKAGE LANGUAGES CXX) + +add_library(find_package_example STATIC + ${CMAKE_CURRENT_SOURCE_DIR}/../example.cpp +) + +find_package(SPIRV-Headers REQUIRED CONFIG) + +if (NOT TARGET SPIRV-Headers::SPIRV-Headers) + message(FATAL_ERROR "SPIRV-Headers::SPIRV-Headers target not defined") +endif() + +target_link_libraries(find_package_example PRIVATE + SPIRV-Headers::SPIRV-Headers +) + +if (NOT DEFINED SPIRV-Headers_VERSION) + message(FATAL_ERROR "SPIRV-Headers_VERSION not provided!") +endif() + +message(STATUS "SPIRV-Headers_VERSION = ${SPIRV-Headers_VERSION}") diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tests/pkg_config/CMakeLists.txt b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/pkg_config/CMakeLists.txt new file mode 100644 index 0000000..b2897e2 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tests/pkg_config/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.14) + +project(TEST_PKGCONFIG LANGUAGES CXX) + +add_library(pkgconfig_example STATIC) + +target_sources(pkgconfig_example PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../example.cpp +) + +find_package(PkgConfig REQUIRED) + +pkg_check_modules(SPIRV_HEADERS REQUIRED IMPORTED_TARGET SPIRV-Headers) + +target_link_libraries(pkgconfig_example PRIVATE + PkgConfig::SPIRV_HEADERS +) + +if (NOT DEFINED SPIRV_HEADERS_VERSION) + message(FATAL_ERROR "SPIRV_HEADERS_VERSION not defined!") +endif() + +message(STATUS "PkgConfig::SPIRV_HEADERS version = ${SPIRV_HEADERS_VERSION}") diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/CMakeLists.txt b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/CMakeLists.txt new file mode 100644 index 0000000..fa7ef50 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.0) + +set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "prefix" FORCE) + +project(buildSpvHeaders) + +set(SOURCES + main.cpp + jsonToSpirv.cpp + header.cpp + jsoncpp/dist/jsoncpp.cpp) + +set(HEADERS + jsonToSpirv.h + header.h + jsoncpp/dist/json/json.h) + +if(CMAKE_COMPILER_IS_GNUCXX) + add_definitions(-std=c++11) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_definitions(-std=c++11) +endif() + +add_executable(buildSpvHeaders ${SOURCES} ${HEADERS}) + +install(TARGETS buildSpvHeaders RUNTIME DESTINATION bin) diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py new file mode 100755 index 0000000..ccd843b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017-2024 Google LLC +# +# 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. + +"""Generates a C language headers from a SPIR-V JSON grammar file""" + +import errno +import json +import os.path +import re + +DEFAULT_COPYRIGHT="""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. +""".split('\n') + +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_UNIFIED1_{}_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)) + + # Ensre the file ends in an end of line + parts.append('') + + 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} = {4},{1}{2}{3}_BitWidthPadding = 0x7fffffff{5};'.format( + '{', '\n ', prefix, var, value, '\n}') + + def enum_prefix(self, prefix, name): + return 'enum {}{} {}'.format(prefix, name, '{') + + def enum_end(self, prefix, enum): + return ' {}{}Max = 0x7fffffff\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-name', + type=str, required=True, + help='The name to use in tokens') + parser.add_argument('--extinst-grammar', metavar='', + type=str, required=True, + help='input JSON grammar file for extended instruction set') + parser.add_argument('--extinst-output-base', metavar='', + type=str, required=True, + help='Basename 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()) + if 'copyright' in grammar_json: + copyright = grammar_json['copyright'] + else: + copyright = DEFAULT_COPYRIGHT + if 'version' in grammar_json: + version = grammar_json['version'] + else: + version = 0 + if 'operand_kinds' in grammar_json: + operand_kinds = grammar_json['operand_kinds'] + else: + operand_kinds = [] + + grammar = ExtInstGrammar(name = args.extinst_name, + copyright = copyright, + instructions = grammar_json['instructions'], + operand_kinds = operand_kinds, + version = version, + revision = grammar_json['revision']) + make_path_to_file(args.extinst_output_base) + with open(args.extinst_output_base + '.h', 'w') as f: + f.write(CGenerator().generate(grammar)) + + +if __name__ == '__main__': + main() diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py new file mode 100755 index 0000000..96ce008 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +"""Generate C headers for certain extended instruction sets""" + +import subprocess +import os + +# Assume we are running from the tools/buildHeaders directory +os.chdir('../../include/spirv/unified1') + +def mk_extinst(name, grammar_file): + """Generate one C header from a grammar""" + script = '../../../tools/buildHeaders/bin/generate_language_headers.py' + subprocess.check_call(['python3', + script, + '--extinst-name=' + name, + '--extinst-grammar=' + grammar_file, + '--extinst-output-base=' + name]) + subprocess.check_call(['dos2unix', name + '.h']) + + +mk_extinst('DebugInfo', 'extinst.debuginfo.grammar.json') +mk_extinst('OpenCLDebugInfo100', 'extinst.opencl.debuginfo.100.grammar.json') +mk_extinst('AMD_gcn_shader', 'extinst.spv-amd-gcn-shader.grammar.json') +mk_extinst('AMD_shader_ballot', 'extinst.spv-amd-shader-ballot.grammar.json') +mk_extinst('AMD_shader_explicit_vertex_parameter', 'extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json') +mk_extinst('AMD_shader_trinary_minmax', 'extinst.spv-amd-shader-trinary-minmax.grammar.json') +mk_extinst('NonSemanticDebugPrintf', 'extinst.nonsemantic.debugprintf.grammar.json') +mk_extinst('NonSemanticClspvReflection', 'extinst.nonsemantic.clspvreflection.grammar.json') +mk_extinst('NonSemanticDebugBreak', 'extinst.nonsemantic.debugbreak.grammar.json') +mk_extinst('NonSemanticVkspReflection', 'extinst.nonsemantic.vkspreflection.grammar.json') diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders new file mode 100755 index 0000000..853c467 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -ex + +python3 bin/makeExtinstHeaders.py + +cd ../../include/spirv/unified1 +../../../tools/buildHeaders/build/install/bin/buildSpvHeaders -H spirv.core.grammar.json +dos2unix spirv.* spv.* diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/header.cpp b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/header.cpp new file mode 100644 index 0000000..9dd4e40 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/header.cpp @@ -0,0 +1,942 @@ +// 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. + +// +// Print headers for SPIR-V in several languages. +// +// To change the header information, change the C++-built database in doc.*. +// +// Then, use "spriv -h " - e.g, spriv.{h,hpp,lua,py,etc}: +// replace the auto-generated header, or "spirv -H" to generate all +// supported language headers to predefined names in the current directory. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jsoncpp/dist/json/json.h" + +#include "header.h" +#include "jsonToSpirv.h" + +// snprintf and _snprintf are not quite the same, but close enough +// for our use. +#ifdef _MSC_VER +#pragma warning(disable:4996) +#define snprintf _snprintf +#endif + +// This file converts SPIR-V definitions to an internal JSON +// representation, and then generates language specific +// data from that single internal form. + +// Initially, the internal form is created from C++ data, +// though this can be changed to a JSON master in time. + +namespace { + class TPrinter { + protected: + TPrinter(); + + static const int DocMagicNumber = 0x07230203; + static const int DocVersion = 0x00010600; + static const int DocRevision = 1; + #define DocRevisionString "1" + static const std::string DocCopyright; + static const std::string DocComment1; + static const std::string DocComment2; + + enum enumStyle_t { + enumNoMask, + enumCount, + enumShift, + enumMask, + enumHex, + }; + + static std::string styleStr(enumStyle_t s) { + return s == enumShift ? "Shift" : + s == enumMask ? "Mask" : ""; + } + + friend std::ostream& operator<<(std::ostream&, const TPrinter&); + + virtual void printAll(std::ostream&) const; + virtual void printComments(std::ostream&) const; + virtual void printPrologue(std::ostream&) const { } + virtual void printDefs(std::ostream&) const; + virtual void printEpilogue(std::ostream&) const { } + virtual void printMeta(std::ostream&) const; + virtual void printTypes(std::ostream&) const { } + virtual void printUtility(std::ostream&) const { }; + + virtual std::string escapeComment(const std::string& s) const; + + // Default printComments() uses these comment strings + virtual std::string commentBeg() const { return ""; } + virtual std::string commentEnd(bool isLast) const { return ""; } + virtual std::string commentBOL() const { return ""; } + virtual std::string commentEOL(bool isLast) const { return ""; } + + typedef std::pair valpair_t; + + // for printing enum values + virtual std::string enumBeg(const std::string&, enumStyle_t) const { return ""; } + virtual std::string enumEnd(const std::string&, enumStyle_t, bool isLast = false) const { + return ""; + } + virtual std::string enumFmt(const std::string&, const valpair_t&, + enumStyle_t, bool isLast = false) const { + return ""; + } + virtual std::string maxEnumFmt(const std::string&, const valpair_t&, + enumStyle_t) const { + return ""; + } + + virtual std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast = false) const { + return ""; + } + + std::vector getSortedVals(const Json::Value&) const; + + virtual std::string indent(int count = 1) const { + return std::string(count * 4, ' '); // default indent level = 4 + } + + static std::string fmtNum(const char* fmt, unsigned val) { + char buff[16]; // ample for 8 hex digits + 0x + snprintf(buff, sizeof(buff), fmt, val); + buff[sizeof(buff)-1] = '\0'; // MSVC doesn't promise null termination + return buff; + } + + static std::string fmtStyleVal(unsigned v, enumStyle_t style); + + // If the enum value name would start with a sigit, prepend the enum name. + // E.g, "3D" -> "Dim3D". + static std::string prependIfDigit(const std::string& ename, const std::string& vname) { + return (std::isdigit(vname[0]) ? ename : std::string("")) + vname; + } + + void addComment(Json::Value& node, const std::string& str); + + Json::Value spvRoot; // JSON SPIR-V data + }; + + // Format value as mask or value + std::string TPrinter::fmtStyleVal(unsigned v, enumStyle_t style) + { + switch (style) { + case enumMask: + return fmtNum("0x%08x", 1< + TPrinter::getSortedVals(const Json::Value& p) const + { + std::vector values; + + for (auto e = p.begin(); e != p.end(); ++e) + values.push_back(valpair_t(e->asUInt(), e.name())); + + // Use a stable sort because we might have aliases, e.g. + // SubgropuBallot (might be in future core) vs. SubgroupBallotKHR. + std::stable_sort(values.begin(), values.end()); + + return values; + } + + // Escape comment characters if needed + std::string TPrinter::escapeComment(const std::string& s) const { return s; } + + // Format comments in language specific way + void TPrinter::printComments(std::ostream& out) const + { + const int commentCount = spvRoot["spv"]["meta"]["Comment"].size(); + int commentNum = 0; + + for (const auto& comment : spvRoot["spv"]["meta"]["Comment"]) { + out << commentBeg(); + + for (int line = 0; line < int(comment.size()); ++line) + out << commentBOL() << escapeComment(comment[line].asString()) << + commentEOL((line+1) == comment.size()) << std::endl; + + out << commentEnd(++commentNum == commentCount) << std::endl; + } + } + + // Format header metadata + void TPrinter::printMeta(std::ostream& out) const + { + const Json::Value& meta = spvRoot["spv"]["meta"]; + + const auto print = [&](const char* name, const char* fmt, bool isLast) { + out << fmtConstInt(meta[name].asUInt(), name, fmt, isLast); + }; + + print("MagicNumber", "0x%08lx", false); + print("Version", "0x%08lx", false); + print("Revision", "%d", false); + print("OpCodeMask", "0x%04x", false); + print("WordCountShift", "%d", true); + } + + // Format value definitions in language specific way + void TPrinter::printDefs(std::ostream& out) const + { + const Json::Value& enums = spvRoot["spv"]["enum"]; + + for (auto opClass = enums.begin(); opClass != enums.end(); ++opClass) { + const bool isMask = (*opClass)["Type"].asString() == "Bit"; + const auto opName = (*opClass)["Name"].asString(); + const auto opPrefix = opName == "Op" ? "" : opName; + + for (enumStyle_t style = (isMask ? enumShift : enumCount); + style <= (isMask ? enumMask : enumCount); style = enumStyle_t(int(style)+1)) { + + out << enumBeg(opName, style); + + if (style == enumMask) + out << enumFmt(opPrefix, valpair_t(0, "MaskNone"), enumNoMask); + + const auto sorted = getSortedVals((*opClass)["Values"]); + + std::string maxEnum = maxEnumFmt(opName, valpair_t(0x7FFFFFFF, "Max"), enumHex); + + bool printMax = (style != enumMask && maxEnum.size() > 0); + + for (const auto& v : sorted) + out << enumFmt(opPrefix, v, style, !printMax && v.second == sorted.back().second); + + if (printMax) + out << maxEnum; + + auto nextOpClass = opClass; + out << enumEnd(opName, style, ++nextOpClass == enums.end()); + } + } + } + + void TPrinter::printAll(std::ostream& out) const + { + printComments(out); + printPrologue(out); + printTypes(out); + printMeta(out); + printDefs(out); + printUtility(out); + printEpilogue(out); + } + + // Stream entire header to output + std::ostream& operator<<(std::ostream& out, const TPrinter &p) + { + p.printAll(out); + return out; + } + + // JSON printer. Rather than use the default printer, we supply our own so + // we can control the printing order within various containers. + class TPrinterJSON final : public TPrinter { + private: + void printPrologue(std::ostream& out) const override { out << "{\n" + indent() + "\"spv\":\n" + indent() + "{\n"; } + void printEpilogue(std::ostream& out) const override { out << indent() + "}\n}\n"; } + + std::string escapeComment(const std::string& s) const override { + std::string newStr; + for (auto c : s) { + if (c == '"') { + newStr += '\\'; + newStr += c; + } else { + newStr += c; + } + } + return newStr; + } + + std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast) const override { + return indent(3) + '"' + name + "\": " + fmtNum("%d", val) + (isLast ? "\n" : ",\n"); + } + + void printMeta(std::ostream& out) const override + { + out << indent(2) + "\"meta\":\n" + indent(2) + "{\n"; + printComments(out); + TPrinter::printMeta(out); + out << indent(2) + "},\n"; + } + + std::string commentBeg() const override { return indent(4) + "[\n"; } + std::string commentEnd(bool isLast) const override { return indent(4) + (isLast ? "]" : "],"); } + std::string commentBOL() const override { return indent(5) + '"'; } + std::string commentEOL(bool isLast) const override { return (isLast ? "\"" : "\","); } + + void printComments(std::ostream& out) const override + { + out << indent(3) + "\"Comment\":\n" + indent(3) + "[\n"; + TPrinter::printComments(out); + out << indent(3) + "],\n"; + } + + void printDefs(std::ostream& out) const override + { + out << indent(2) + "\"enum\":\n" + indent(2) + "[\n"; + TPrinter::printDefs(out); + out << indent(2) + "]\n"; + } + + void printAll(std::ostream& out) const override + { + printPrologue(out); + printMeta(out); + printDefs(out); + printEpilogue(out); + } + + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + if (style == enumMask) + return ""; + return indent(3) + "{\n" + + indent(4) + "\"Name\": \"" + s + "\",\n" + + indent(4) + "\"Type\": " + (style == enumShift ? "\"Bit\"" : "\"Value\"") + ",\n" + + indent(4) + "\"Values\":\n" + + indent(4) + "{\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + if (style == enumMask) + return ""; + return indent(4) + "}\n" + + indent(3) + "}" + (isLast ? "" : ",") + "\n"; + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + if (style == enumMask || style == enumNoMask) + return ""; + return indent(5) + '"' + prependIfDigit(s, v.second) + "\": " + fmtNum("%d", v.first) + + (isLast ? "\n" : ",\n"); + } + }; + + // base for C and C++ + class TPrinterCBase : public TPrinter { + protected: + virtual void printPrologue(std::ostream& out) const override { + out << "#ifndef spirv_" << headerGuardSuffix() << std::endl + << "#define spirv_" << headerGuardSuffix() << std::endl + << std::endl; + } + + void printMeta(std::ostream& out) const override { + out << "#define SPV_VERSION 0x" << std::hex << DocVersion << std::dec << "\n"; + out << "#define SPV_REVISION " << DocRevision << "\n"; + out << "\n"; + + return TPrinter::printMeta(out); + } + + virtual void printEpilogue(std::ostream& out) const override { + out << "#endif" << std::endl; + } + + virtual void printTypes(std::ostream& out) const override { + out << "typedef unsigned int " << pre() << "Id;\n\n"; + } + + virtual std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast) const override + { + return std::string("static const unsigned int ") + pre() + name + + " = " + fmtNum(fmt, val) + (isLast ? ";\n\n" : ";\n"); + } + + virtual std::string pre() const { return ""; } // C name prefix + virtual std::string headerGuardSuffix() const = 0; + + virtual std::string fmtEnumUse(const std::string& opPrefix, const std::string& name) const { return pre() + name; } + + virtual void printUtility(std::ostream& out) const override + { + out << "#ifdef SPV_ENABLE_UTILITY_CODE" << std::endl; + out << "#ifndef __cplusplus" << std::endl; + out << "#include " << std::endl; + out << "#endif" << std::endl; + + printHasResultType(out); + printStringFunctions(out); + + out << "#endif /* SPV_ENABLE_UTILITY_CODE */" << std::endl << std::endl; + } + + void printHasResultType(std::ostream& out) const { + const Json::Value& enums = spvRoot["spv"]["enum"]; + + std::set seenValues; + + for (auto opClass = enums.begin(); opClass != enums.end(); ++opClass) { + const auto opName = (*opClass)["Name"].asString(); + if (opName != "Op") { + continue; + } + + + out << "inline void " << pre() << "HasResultAndType(" << pre() << opName << " opcode, bool *hasResult, bool *hasResultType) {" << std::endl; + out << " *hasResult = *hasResultType = false;" << std::endl; + out << " switch (opcode) {" << std::endl; + out << " default: /* unknown opcode */ break;" << std::endl; + + for (auto& inst : spv::InstructionDesc) { + + // Filter out duplicate enum values, which would break the switch statement. + // These are probably just extension enums promoted to core. + if (seenValues.find(inst.value) != seenValues.end()) { + continue; + } + seenValues.insert(inst.value); + + std::string name = inst.name; + out << " case " << fmtEnumUse("Op", name) << ": *hasResult = " << (inst.hasResult() ? "true" : "false") << "; *hasResultType = " << (inst.hasType() ? "true" : "false") << "; break;" << std::endl; + } + + out << " }" << std::endl; + out << "}" << std::endl; + } + } + + void printStringFunctions(std::ostream& out) const { + const Json::Value& enums = spvRoot["spv"]["enum"]; + + for (auto it = enums.begin(); it != enums.end(); ++it) { + const auto type = (*it)["Type"].asString(); + // Skip bitmasks + if (type == "Bit") { + continue; + } + const auto name = (*it)["Name"].asString(); + const auto sorted = getSortedVals((*it)["Values"]); + + std::set seenValues; + std::string fullName = pre() + name; + + out << "inline const char* " << fullName << "ToString(" << fullName << " value) {" << std::endl; + out << " switch (value) {" << std::endl; + for (const auto& v : sorted) { + // Filter out duplicate enum values, which would break the switch statement. + // These are probably just extension enums promoted to core. + if (seenValues.count(v.first)) { + continue; + } + seenValues.insert(v.first); + + std::string label{name + v.second}; + if (name == "Op") { + label = v.second; + } + out << " " << "case " << pre() << label << ": return " << "\"" << v.second << "\";" << std::endl; + } + out << " default: return \"Unknown\";" << std::endl; + out << " }" << std::endl; + out << "}" << std::endl << std::endl; + } + } + }; + + // C printer + class TPrinterC final : public TPrinterCBase { + private: + std::string commentBeg() const override { return "/*\n"; } + std::string commentEnd(bool isLast) const override { return "*/\n"; } + std::string commentBOL() const override { return "** "; } + + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return std::string("typedef enum ") + pre() + s + styleStr(style) + "_ {\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + return "} " + pre() + s + styleStr(style) + ";\n\n"; + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent() + pre() + s + v.second + styleStr(style) + " = " + fmtStyleVal(v.first, style) + ",\n"; + } + + std::string maxEnumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style) const override { + return enumFmt(s, v, style, true); + } + + std::string pre() const override { return "Spv"; } // C name prefix + std::string headerGuardSuffix() const override { return "H"; } + }; + + // C++ printer + class TPrinterCPP : public TPrinterCBase { + protected: + void printMaskOperators(std::ostream& out, const std::string& specifiers) const { + const Json::Value& enums = spvRoot["spv"]["enum"]; + + out << "// Overload bitwise operators for mask bit combining\n\n"; + + for (auto opClass = enums.begin(); opClass != enums.end(); ++opClass) { + const bool isMask = (*opClass)["Type"].asString() == "Bit"; + const auto opName = (*opClass)["Name"].asString(); + + if (isMask) { + const auto typeName = opName + styleStr(enumMask); + + // Overload operator| + out << specifiers << " " << typeName << " operator|(" << typeName << " a, " << typeName << " b) { return " << + typeName << "(unsigned(a) | unsigned(b)); }\n"; + // Overload operator& + out << specifiers << " " << typeName << " operator&(" << typeName << " a, " << typeName << " b) { return " << + typeName << "(unsigned(a) & unsigned(b)); }\n"; + // Overload operator^ + out << specifiers << " " << typeName << " operator^(" << typeName << " a, " << typeName << " b) { return " << + typeName << "(unsigned(a) ^ unsigned(b)); }\n"; + // Overload operator~ + out << specifiers << " " << typeName << " operator~(" << typeName << " a) { return " << + typeName << "(~unsigned(a)); }\n"; + } + } + } + private: + void printPrologue(std::ostream& out) const override { + TPrinterCBase::printPrologue(out); + out << "namespace spv {\n\n"; + } + + void printEpilogue(std::ostream& out) const override { + printMaskOperators(out, "inline"); + out << "\n} // end namespace spv\n\n"; + out << "#endif // #ifndef spirv_" << headerGuardSuffix() << std::endl; + } + + std::string commentBOL() const override { return "// "; } + + + virtual std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return std::string("enum ") + s + styleStr(style) + " {\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + return "};\n\n"; + } + + virtual std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent() + s + v.second + styleStr(style) + " = " + fmtStyleVal(v.first, style) + ",\n"; + } + + virtual std::string maxEnumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style) const override { + return enumFmt(s, v, style, true); + } + + // The C++ and C++11 headers define types with the same name. So they + // should use the same header guard. + std::string headerGuardSuffix() const override { return "HPP"; } + + std::string operators; + }; + + // C++11 printer (uses enum classes) + class TPrinterCPP11 final : public TPrinterCPP { + private: + void printEpilogue(std::ostream& out) const override { + printMaskOperators(out, "constexpr"); + out << "\n} // end namespace spv\n\n"; + out << "#endif // #ifndef spirv_" << headerGuardSuffix() << std::endl; + } + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return std::string("enum class ") + s + styleStr(style) + " : unsigned {\n"; + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent() + prependIfDigit(s, v.second) + " = " + fmtStyleVal(v.first, style) + ",\n"; + } + + std::string maxEnumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style) const override { + return enumFmt(s, v, style, true); + } + + // Add type prefix for scoped enum + virtual std::string fmtEnumUse(const std::string& opPrefix, const std::string& name) const override { return opPrefix + "::" + name; } + + std::string headerGuardSuffix() const override { return "HPP"; } + }; + + // LUA printer + class TPrinterLua final : public TPrinter { + private: + void printPrologue(std::ostream& out) const override { out << "spv = {\n"; } + + void printEpilogue(std::ostream& out) const override { out << "}\n"; } + + std::string commentBOL() const override { return "-- "; } + + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return indent() + s + styleStr(style) + " = {\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + return indent() + "},\n\n"; + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent(2) + prependIfDigit(s, v.second) + " = " + fmtStyleVal(v.first, style) + ",\n"; + } + + virtual std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast) const override + { + return indent() + name + " = " + fmtNum(fmt, val) + (isLast ? ",\n\n" : ",\n"); + } + }; + + // Python printer + class TPrinterPython final : public TPrinter { + private: + void printPrologue(std::ostream& out) const override { out << "spv = {\n"; } + + void printEpilogue(std::ostream& out) const override { out << "}\n"; } + + std::string commentBOL() const override { return "# "; } + + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return indent() + "'" + s + styleStr(style) + "'" + " : {\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + return indent() + "},\n\n"; + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent(2) + "'" + prependIfDigit(s, v.second) + "'" + " : " + fmtStyleVal(v.first, style) + ",\n"; + } + + std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast) const override + { + return indent() + "'" + name + "'" + " : " + fmtNum(fmt, val) + (isLast ? ",\n\n" : ",\n"); + } + }; + + // C# printer + class TPrinterCSharp final : public TPrinter { + private: + std::string commentBOL() const override { return "// "; } + + void printPrologue(std::ostream& out) const override { + out << "namespace Spv\n{\n\n"; + out << indent() << "public static class Specification\n"; + out << indent() << "{\n"; + } + + void printEpilogue(std::ostream& out) const override { + out << indent() << "}\n"; + out << "}\n"; + } + + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return indent(2) + "public enum " + s + styleStr(style) + "\n" + indent(2) + "{\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + return indent(2) + "}" + + (isLast ? "\n" : "\n\n"); + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent(3) + prependIfDigit(s, v.second) + " = " + fmtStyleVal(v.first, style) + ",\n"; + } + + std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast) const override { + return indent(2) + std::string("public const uint ") + name + + " = " + fmtNum(fmt, val) + (isLast ? ";\n\n" : ";\n"); + } + }; + + // D printer + class TPrinterD final : public TPrinter { + private: + std::string commentBeg() const override { return "/+\n"; } + std::string commentBOL() const override { return " + "; } + std::string commentEnd(bool isLast) const override { return " +/\n"; } + + void printPrologue(std::ostream& out) const override { + out << "module spv;\n\n"; + } + + void printEpilogue(std::ostream& out) const override { + } + + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return "enum " + s + styleStr(style) + " : uint\n{\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + return std::string("}\n\n"); + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent() + prependIfDigit("_", v.second) + " = " + fmtStyleVal(v.first, style) + ",\n"; + } + + std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast) const override { + return std::string("enum uint ") + name + + " = " + fmtNum(fmt, val) + (isLast ? ";\n\n" : ";\n"); + } + }; + + // Beef printer + class TPrinterBeef final : public TPrinter { + private: + std::string commentBOL() const override { return "// "; } + + void printPrologue(std::ostream& out) const override { + out << "namespace Spv\n{\n"; + out << indent() << "using System;\n\n"; + out << indent() << "public static class Specification\n"; + out << indent() << "{\n"; + } + + void printEpilogue(std::ostream& out) const override { + out << indent() << "}\n"; + out << "}\n"; + } + + std::string enumBeg(const std::string& s, enumStyle_t style) const override { + return indent(2) + "[AllowDuplicates, CRepr] public enum " + s + styleStr(style) + "\n" + indent(2) + "{\n"; + } + + std::string enumEnd(const std::string& s, enumStyle_t style, bool isLast) const override { + return indent(2) + "}" + +(isLast ? "\n" : "\n\n"); + } + + std::string enumFmt(const std::string& s, const valpair_t& v, + enumStyle_t style, bool isLast) const override { + return indent(3) + prependIfDigit(s, v.second) + " = " + fmtStyleVal(v.first, style) + ",\n"; + } + + std::string fmtConstInt(unsigned val, const std::string& name, + const char* fmt, bool isLast) const override { + return indent(2) + std::string("public const uint32 ") + name + + " = " + fmtNum(fmt, val) + (isLast ? ";\n\n" : ";\n"); + } + }; + +} // namespace + +namespace spv { + void PrintAllHeaders() + { + // TODO: Once MSVC 2012 is no longer a factor, use brace initializers here + std::vector> langInfo; + + langInfo.push_back(std::make_pair(ELangC, "spirv.h")); + langInfo.push_back(std::make_pair(ELangCPP, "spirv.hpp")); + langInfo.push_back(std::make_pair(ELangCPP11, "spirv.hpp11")); + langInfo.push_back(std::make_pair(ELangJSON, "spirv.json")); + langInfo.push_back(std::make_pair(ELangLua, "spirv.lua")); + langInfo.push_back(std::make_pair(ELangPython, "spirv.py")); + langInfo.push_back(std::make_pair(ELangCSharp, "spirv.cs")); + langInfo.push_back(std::make_pair(ELangD, "spv.d")); + langInfo.push_back(std::make_pair(ELangBeef, "spirv.bf")); + + for (const auto& lang : langInfo) { + std::ofstream out(lang.second, std::ios::out); + + if ((out.rdstate() & std::ifstream::failbit)) { + std::cerr << "Unable to open file: " << lang.second << std::endl; + } else { + PrintHeader(lang.first, out); + } + } + } + + // Print header for given language to given output stream + void PrintHeader(TLanguage lang, std::ostream& out) + { + typedef std::unique_ptr TPrinterPtr; + TPrinterPtr p; + + switch (lang) { + case ELangC: p = TPrinterPtr(new TPrinterC); break; + case ELangCPP: p = TPrinterPtr(new TPrinterCPP); break; + case ELangCPP11: p = TPrinterPtr(new TPrinterCPP11); break; + case ELangJSON: p = TPrinterPtr(new TPrinterJSON); break; + case ELangLua: p = TPrinterPtr(new TPrinterLua); break; + case ELangPython: p = TPrinterPtr(new TPrinterPython); break; + case ELangCSharp: p = TPrinterPtr(new TPrinterCSharp); break; + case ELangD: p = TPrinterPtr(new TPrinterD); break; + case ELangBeef: p = TPrinterPtr(new TPrinterBeef); break; + case ELangAll: PrintAllHeaders(); break; + default: + std::cerr << "Unknown language." << std::endl; + return; + } + + // Print the data in the requested format + if (p) + out << *p << std::endl; + + // object is auto-deleted + } + +} // namespace spv diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/header.h b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/header.h new file mode 100644 index 0000000..6854f80 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/header.h @@ -0,0 +1,55 @@ +// 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. + +// +// Print headers for SPIR-V in several languages. +// + +#pragma once +#ifndef header +#define header + +#include + +namespace spv { + // Languages supported + enum TLanguage { + ELangC, // C + ELangCPP, // C++03 + ELangCPP11, // C++11 + ELangJSON, // JSON + ELangLua, // Lua + ELangPython, // Python + ELangCSharp, // CSharp + ELangD, // D + ELangBeef, // Beef + + ELangAll, // print headers in all languages to files + }; + + // Generate header for requested language + void PrintHeader(TLanguage, std::ostream&); +} // namespace spv + +#endif // header diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp new file mode 100644 index 0000000..22beba7 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp @@ -0,0 +1,855 @@ +// 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. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jsoncpp/dist/json/json.h" + +#include "jsonToSpirv.h" + +namespace { +// Returns true if the given string is a valid SPIR-V version. +bool validSpirvVersionString(const std::string s) { + return + s == "1.0" || + s == "1.1" || + s == "1.2" || + s == "1.3" || + s == "1.4" || + s == "1.5" || + s == "1.6"; +} + +// Returns true if the given string is a valid version +// specifier in the grammar file. +bool validSpirvVersionStringSpecifier(const std::string s) { + return s == "None" || validSpirvVersionString(s); +} +} // anonymous namespace + +namespace spv { + +bool IsLegacyDoublyEnabledInstruction(const std::string& instruction) { + static std::unordered_set allowed = { + "OpSubgroupBallotKHR", + "OpSubgroupFirstInvocationKHR", + "OpSubgroupAllKHR", + "OpSubgroupAnyKHR", + "OpSubgroupAllEqualKHR", + "OpSubgroupReadInvocationKHR", + "OpTraceRayKHR", + "OpExecuteCallableKHR", + "OpConvertUToAccelerationStructureKHR", + "OpIgnoreIntersectionKHR", + "OpTerminateRayKHR", + "OpTypeRayQueryKHR", + "OpRayQueryInitializeKHR", + "OpRayQueryTerminateKHR", + "OpRayQueryGenerateIntersectionKHR", + "OpRayQueryConfirmIntersectionKHR", + "OpRayQueryProceedKHR", + "OpRayQueryGetIntersectionTypeKHR", + "OpGroupIAddNonUniformAMD", + "OpGroupFAddNonUniformAMD", + "OpGroupFMinNonUniformAMD", + "OpGroupUMinNonUniformAMD", + "OpGroupSMinNonUniformAMD", + "OpGroupFMaxNonUniformAMD", + "OpGroupUMaxNonUniformAMD", + "OpGroupSMaxNonUniformAMD", + "OpFragmentMaskFetchAMD", + "OpFragmentFetchAMD", + "OpImageSampleFootprintNV", + "OpGroupNonUniformPartitionNV", + "OpWritePackedPrimitiveIndices4x8NV", + "OpReportIntersectionNV", + "OpReportIntersectionKHR", + "OpIgnoreIntersectionNV", + "OpTerminateRayNV", + "OpTraceNV", + "OpTraceMotionNV", + "OpTraceRayMotionNV", + "OpTypeAccelerationStructureNV", + "OpTypeAccelerationStructureKHR", + "OpExecuteCallableNV", + "OpTypeCooperativeMatrixNV", + "OpCooperativeMatrixLoadNV", + "OpCooperativeMatrixStoreNV", + "OpCooperativeMatrixMulAddNV", + "OpCooperativeMatrixLengthNV", + "OpBeginInvocationInterlockEXT", + "OpEndInvocationInterlockEXT", + "OpIsHelperInvocationEXT", + "OpConstantFunctionPointerINTEL", + "OpFunctionPointerCallINTEL", + "OpAssumeTrueKHR", + "OpExpectKHR", + "OpLoopControlINTEL", + "OpAliasDomainDeclINTEL", + "OpAliasScopeDeclINTEL", + "OpAliasScopeListDeclINTEL", + "OpReadPipeBlockingINTEL", + "OpWritePipeBlockingINTEL", + "OpFPGARegINTEL", + "OpRayQueryGetRayTMinKHR", + "OpRayQueryGetRayFlagsKHR", + "OpRayQueryGetIntersectionTKHR", + "OpRayQueryGetIntersectionInstanceCustomIndexKHR", + "OpRayQueryGetIntersectionInstanceIdKHR", + "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", + "OpRayQueryGetIntersectionGeometryIndexKHR", + "OpRayQueryGetIntersectionPrimitiveIndexKHR", + "OpRayQueryGetIntersectionBarycentricsKHR", + "OpRayQueryGetIntersectionFrontFaceKHR", + "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR", + "OpRayQueryGetIntersectionObjectRayDirectionKHR", + "OpRayQueryGetIntersectionObjectRayOriginKHR", + "OpRayQueryGetWorldRayDirectionKHR", + "OpRayQueryGetWorldRayOriginKHR", + "OpRayQueryGetIntersectionObjectToWorldKHR", + "OpRayQueryGetIntersectionWorldToObjectKHR", + "OpAtomicFAddEXT", + }; + return allowed.count(instruction) != 0; +} + +bool EnumValue::IsValid(OperandClass oc, const std::string& context) const +{ + bool result = true; + if (firstVersion.empty()) { + std::cerr << "Error: " << context << " " << name << " \"version\" must be set, probably to \"None\"" << std::endl; + result = false; + } else if (!validSpirvVersionStringSpecifier(firstVersion)) { + std::cerr << "Error: " << context << " " << name << " \"version\" is invalid: " << firstVersion << std::endl; + result = false; + } + if (!lastVersion.empty() && !validSpirvVersionString(lastVersion)) { + std::cerr << "Error: " << context << " " << name << " \"lastVersion\" is invalid: " << lastVersion << std::endl; + result = false; + } + + // When a feature is introduced by an extension, the firstVersion is set to + // "None". There are three cases: + // - A new capability should be guarded/enabled by the extension + // - A new instruction should be: + // - Guarded/enabled by a new capability. + // - Not enabled by *both* a capability and an extension. + // There are many existing instructions that are already like this, + // and we grandparent them as allowed. + // - Other enums fall into two cases: + // 1. The enum is part of a new operand kind introduced by the extension. + // In this case we rely on transitivity: The use of the operand occurs + // in a new instruction that itself is guarded; or as the operand of + // another operand that itself is (recursively) guarded. + // 2. The enum is a new case in an existing operand kind. This case + // should be guarded by a capability. However, we do not check this + // here. Checking it requires more context than we have here. + if (oc == OperandOpcode) { + const bool instruction_unusable = + (firstVersion == "None") && extensions.empty() && capabilities.empty(); + if (instruction_unusable) { + std::cerr << "Error: " << context << " " << name << " is not usable: " + << "its version is set to \"None\", and it is not enabled by a " + << "capability or extension. Guard it with a capability." + << std::endl; + result = false; + } + // Complain if an instruction is not in any core version and also enabled by + // both an extension and a capability. + // It's important to check the "not in any core version" case, because, + // for example, OpTerminateInvocation is in SPIR-V 1.6 *and* enabled by an + // extension, and guarded by the Shader capability. + const bool instruction_doubly_enabled = (firstVersion == "None") && + !extensions.empty() && + !capabilities.empty(); + if (instruction_doubly_enabled && !IsLegacyDoublyEnabledInstruction(name)) { + std::cerr << "Error: " << context << " " << name << " is doubly-enabled: " + << "it is enabled by both a capability and an extension. " + << "Guard it with a capability only." << std::endl; + result = false; + } + } + if (oc == OperandCapability) { + // If capability X lists capabilities Y and Z, then Y and Z are *enabled* + // when X is enabled. They are not *guards* on X's use. + // Only versions and extensions can guard a capability. + const bool capability_unusable = + (firstVersion == "None") && extensions.empty(); + if (capability_unusable) { + std::cerr << "Error: " << context << " " << name << " is not usable: " + << "its version is set to \"None\", and it is not enabled by " + << "an extension. Guard it with an extension." << std::endl; + result = false; + } + } + + return result; +} + +// The set of objects that hold all the instruction/operand +// parameterization information. +InstructionValues InstructionDesc; + +// The ordered list (in printing order) of printing classes +// (specification subsections). +PrintingClasses InstructionPrintingClasses; + +// Note: There is no entry for OperandOpcode. Use InstructionDesc instead. +EnumDefinition OperandClassParams[OperandOpcode]; +EnumValues SourceLanguageParams; +EnumValues ExecutionModelParams; +EnumValues AddressingParams; +EnumValues MemoryParams; +EnumValues ExecutionModeParams; +EnumValues StorageParams; +EnumValues SamplerAddressingModeParams; +EnumValues SamplerFilterModeParams; +EnumValues ImageFormatParams; +EnumValues ImageChannelOrderParams; +EnumValues ImageChannelDataTypeParams; +EnumValues ImageOperandsParams; +EnumValues FPFastMathParams; +EnumValues FPRoundingModeParams; +EnumValues FPDenormModeParams; +EnumValues FPOperationModeParams; +EnumValues QuantizationModesParams; +EnumValues OverflowModesParams; +EnumValues LinkageTypeParams; +EnumValues DecorationParams; +EnumValues BuiltInParams; +EnumValues DimensionalityParams; +EnumValues FuncParamAttrParams; +EnumValues AccessQualifierParams; +EnumValues GroupOperationParams; +EnumValues LoopControlParams; +EnumValues SelectionControlParams; +EnumValues FunctionControlParams; +EnumValues MemorySemanticsParams; +EnumValues MemoryAccessParams; +EnumValues ScopeParams; +EnumValues KernelEnqueueFlagsParams; +EnumValues KernelProfilingInfoParams; +EnumValues CapabilityParams; +EnumValues RayFlagsParams; +EnumValues RayQueryIntersectionParams; +EnumValues RayQueryCommittedIntersectionTypeParams; +EnumValues RayQueryCandidateIntersectionTypeParams; +EnumValues FragmentShadingRateParams; +EnumValues PackedVectorFormatParams; +EnumValues CooperativeMatrixOperandsParams; +EnumValues CooperativeMatrixLayoutParams; +EnumValues CooperativeMatrixUseParams; +EnumValues InitializationModeQualifierParams; +EnumValues HostAccessQualifierParams; +EnumValues LoadCacheControlParams; +EnumValues StoreCacheControlParams; +EnumValues NamedMaximumNumberOfRegistersParams; +EnumValues RawAccessChainOperandsParams; + +std::pair ReadFile(const std::string& path) +{ + std::ifstream fstream(path, std::ios::in); + if (fstream) { + std::string contents; + fstream.seekg(0, std::ios::end); + contents.reserve((unsigned int)fstream.tellg()); + fstream.seekg(0, std::ios::beg); + contents.assign((std::istreambuf_iterator(fstream)), + std::istreambuf_iterator()); + return std::make_pair(true, contents); + } + return std::make_pair(false, ""); +} + +struct ClassOptionality { + OperandClass type; + bool optional; +}; + +// Converts the |operandKind| and |quantifier| pair used to describe operands +// in the JSON grammar to OperandClass and optionality used in this repo. +ClassOptionality ToOperandClassAndOptionality(const std::string& operandKind, const std::string& quantifier) +{ + assert(quantifier.empty() || quantifier == "?" || quantifier == "*"); + + if (operandKind == "IdRef") { + if (quantifier.empty()) + return {OperandId, false}; + else if (quantifier == "?") + return {OperandId, true}; + else + return {OperandVariableIds, false}; + } else if (operandKind == "LiteralInteger") { + if (quantifier.empty()) + return {OperandLiteralNumber, false}; + if (quantifier == "?") + return {OperandOptionalLiteral, true}; + else + return {OperandVariableLiterals, false}; + } else if (operandKind == "LiteralString") { + if (quantifier.empty()) + return {OperandLiteralString, false}; + else if (quantifier == "?") + return {OperandLiteralString, true}; + else { + return {OperandOptionalLiteralStrings, false}; + } + } else if (operandKind == "PairLiteralIntegerIdRef") { + // Used by OpSwitch in the grammar + return {OperandVariableLiteralId, false}; + } else if (operandKind == "PairIdRefLiteralInteger") { + // Used by OpGroupMemberDecorate in the grammar + return {OperandVariableIdLiteral, false}; + } else if (operandKind == "PairIdRefIdRef") { + // Used by OpPhi in the grammar + return {OperandVariableIds, false}; + } else { + OperandClass type = OperandNone; + if (operandKind == "IdMemorySemantics" || operandKind == "MemorySemantics") { + type = OperandMemorySemantics; + } else if (operandKind == "IdScope" || operandKind == "Scope") { + type = OperandScope; + } else if (operandKind == "LiteralExtInstInteger") { + type = OperandLiteralNumber; + } else if (operandKind == "LiteralSpecConstantOpInteger") { + type = OperandLiteralNumber; + } else if (operandKind == "LiteralContextDependentNumber") { + type = OperandAnySizeLiteralNumber; + } else if (operandKind == "LiteralFloat") { + type = OperandLiteralNumber; + } else if (operandKind == "SourceLanguage") { + type = OperandSource; + } else if (operandKind == "ExecutionModel") { + type = OperandExecutionModel; + } else if (operandKind == "AddressingModel") { + type = OperandAddressing; + } else if (operandKind == "MemoryModel") { + type = OperandMemory; + } else if (operandKind == "ExecutionMode") { + type = OperandExecutionMode; + } else if (operandKind == "StorageClass") { + type = OperandStorage; + } else if (operandKind == "Dim") { + type = OperandDimensionality; + } else if (operandKind == "SamplerAddressingMode") { + type = OperandSamplerAddressingMode; + } else if (operandKind == "SamplerFilterMode") { + type = OperandSamplerFilterMode; + } else if (operandKind == "ImageFormat") { + type = OperandSamplerImageFormat; + } else if (operandKind == "ImageChannelOrder") { + type = OperandImageChannelOrder; + } else if (operandKind == "ImageChannelDataType") { + type = OperandImageChannelDataType; + } else if (operandKind == "FPRoundingMode") { + type = OperandFPRoundingMode; + } else if (operandKind == "FPDenormMode") { + type = OperandFPDenormMode; + } else if (operandKind == "FPOperationMode") { + type = OperandFPOperationMode; + } else if (operandKind == "QuantizationModes") { + type = OperandQuantizationModes; + } else if (operandKind == "OverflowModes") { + type = OperandOverflowModes; + } else if (operandKind == "LinkageType") { + type = OperandLinkageType; + } else if (operandKind == "AccessQualifier") { + type = OperandAccessQualifier; + } else if (operandKind == "FunctionParameterAttribute") { + type = OperandFuncParamAttr; + } else if (operandKind == "Decoration") { + type = OperandDecoration; + } else if (operandKind == "BuiltIn") { + type = OperandBuiltIn; + } else if (operandKind == "GroupOperation") { + type = OperandGroupOperation; + } else if (operandKind == "KernelEnqueueFlags") { + type = OperandKernelEnqueueFlags; + } else if (operandKind == "KernelProfilingInfo") { + type = OperandKernelProfilingInfo; + } else if (operandKind == "Capability") { + type = OperandCapability; + } else if (operandKind == "ImageOperands") { + type = OperandImageOperands; + } else if (operandKind == "FPFastMathMode") { + type = OperandFPFastMath; + } else if (operandKind == "SelectionControl") { + type = OperandSelect; + } else if (operandKind == "LoopControl") { + type = OperandLoop; + } else if (operandKind == "FunctionControl") { + type = OperandFunction; + } else if (operandKind == "MemoryAccess") { + type = OperandMemoryOperands; + } else if (operandKind == "RayFlags") { + type = OperandRayFlags; + } else if (operandKind == "RayQueryIntersection") { + type = OperandRayQueryIntersection; + } else if (operandKind == "RayQueryCommittedIntersectionType") { + type = OperandRayQueryCommittedIntersectionType; + } else if (operandKind == "RayQueryCandidateIntersectionType") { + type = OperandRayQueryCandidateIntersectionType; + } else if (operandKind == "FragmentShadingRate") { + type = OperandFragmentShadingRate; + } else if (operandKind == "PackedVectorFormat") { + type = OperandPackedVectorFormat; + } else if (operandKind == "CooperativeMatrixOperands") { + type = OperandCooperativeMatrixOperands; + } else if (operandKind == "CooperativeMatrixLayout") { + type = OperandCooperativeMatrixLayout; + } else if (operandKind == "CooperativeMatrixUse") { + type = OperandCooperativeMatrixUse; + } else if (operandKind == "InitializationModeQualifier") { + type = OperandInitializationModeQualifier; + } else if (operandKind == "HostAccessQualifier") { + type = OperandHostAccessQualifier; + } else if (operandKind == "LoadCacheControl") { + type = OperandLoadCacheControl; + } else if (operandKind == "StoreCacheControl") { + type = OperandStoreCacheControl; + } else if (operandKind == "NamedMaximumNumberOfRegisters") { + type = OperandNamedMaximumNumberOfRegisters; + } else if (operandKind == "RawAccessChainOperands") { + type = OperandRawAccessChainOperands; + } + + if (type == OperandNone) { + std::cerr << "Unhandled operand kind found: " << operandKind << std::endl; + exit(1); + } + return {type, !quantifier.empty()}; + } +} + +bool IsTypeOrResultId(const std::string& str, bool* isType, bool* isResult) +{ + if (str == "IdResultType") + return *isType = true; + if (str == "IdResult") + return *isResult = true; + return false; +} + +// Given a number string, returns the position of the only bits set in the number. +// So it requires the number is a power of two. +unsigned int NumberStringToBit(const std::string& str) +{ + char* parseEnd; + unsigned int value = (unsigned int)std::strtol(str.c_str(), &parseEnd, 16); + assert(!(value & (value - 1)) && "input number is not a power of 2"); + unsigned int bit = 0; + for (; value; value >>= 1) ++bit; + return bit; +} + +// Given two pairs (name and in core) compares if the order is correct for naming +// conventions. The conventions are: +// * Core +// * KHR +// * EXT +// * Vendor (no preference between vendors) +// +// Returns true if the order is valid. +bool SuffixComparison(const std::string& prev, bool prevCore, + const std::string& cur, bool curCore) +{ + // Duplicate entry + if (prev == cur) return false; + + if (prevCore) return true; + if (curCore) return false; + + // Both are suffixed names. + const bool prevKHR = prev.substr(prev.size() - 3) == "KHR"; + const bool prevEXT = prev.substr(prev.size() - 3) == "EXT"; + const bool curKHR = cur.substr(cur.size() - 3) == "KHR"; + const bool curEXT = cur.substr(cur.size() - 3) == "EXT"; + + if (prevKHR) return true; + if (curKHR) return false; + if (prevEXT) return true; + if (curEXT) return false; + + return true; +} + +void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders) +{ + // only do this once. + static bool initialized = false; + if (initialized) + return; + initialized = true; + + size_t errorCount = 0; + + // Read the JSON grammar file. + bool fileReadOk = false; + std::string content; + std::tie(fileReadOk, content) = ReadFile(jsonPath); + if (!fileReadOk) { + std::cerr << "Failed to read JSON grammar file: " + << jsonPath << std::endl; + exit(1); + } + + // Decode the JSON grammar file. + Json::Reader reader; + Json::Value root; + if (!reader.parse(content, root)) { + std::cerr << "Failed to parse JSON grammar:\n" + << reader.getFormattedErrorMessages(); + exit(1); + } + + // Layouts for all instructions. + + // A lambda for returning capabilities from a JSON object as strings. + const auto getCaps = [](const Json::Value& object) { + EnumCaps result; + const auto& caps = object["capabilities"]; + if (!caps.empty()) { + assert(caps.isArray()); + for (const auto& cap : caps) { + result.emplace_back(cap.asString()); + } + } + return result; + }; + + // A lambda for returning extensions from a JSON object as strings. + const auto getExts = [](const Json::Value& object) { + Extensions result; + const auto& exts = object["extensions"]; + if (!exts.empty()) { + assert(exts.isArray()); + for (const auto& ext : exts) { + result.emplace_back(ext.asString()); + } + } + return result; + }; + + // set up the printing classes + std::unordered_set tags; // short-lived local for error checking below + const Json::Value printingClasses = root["instruction_printing_class"]; + for (const auto& printingClass : printingClasses) { + if (printingClass["tag"].asString().size() > 0) + tags.insert(printingClass["tag"].asString()); // just for error checking + else { + std::cerr << "Error: each instruction_printing_class requires a non-empty \"tag\"" << std::endl; + std::exit(1); + } + if (buildingHeaders || printingClass["tag"].asString() != "@exclude") { + InstructionPrintingClasses.push_back({printingClass["tag"].asString(), + printingClass["heading"].asString()}); + } + } + + // process the instructions + const Json::Value insts = root["instructions"]; + unsigned maxOpcode = 0; + std::string maxName = ""; + bool maxCore = false; + bool firstOpcode = true; + for (const auto& inst : insts) { + const auto printingClass = inst["class"].asString(); + if (printingClass.size() == 0) { + std::cerr << "Error: " << inst["opname"].asString() + << " requires a non-empty printing \"class\" tag" << std::endl; + std::exit(1); + } + if (!buildingHeaders && printingClass == "@exclude") + continue; + if (tags.find(printingClass) == tags.end()) { + std::cerr << "Error: " << inst["opname"].asString() + << " requires a \"class\" declared as a \"tag\" in \"instruction printing_class\"" + << std::endl; + std::exit(1); + } + const auto opcode = inst["opcode"].asUInt(); + const std::string name = inst["opname"].asString(); + std::string version = inst["version"].asString(); + if (firstOpcode) { + maxOpcode = opcode; + maxName = name; + maxCore = version != "None"; + firstOpcode = false; + } else { + if (maxOpcode > opcode) { + std::cerr << "Error: " << name + << " is out of order. It follows the instruction with opcode " << maxOpcode + << std::endl; + std::exit(1); + } else if (maxOpcode == opcode && + !SuffixComparison(maxName, maxCore, name, + version != "None")) { + std::cerr << "Error: " << name + << " is out of order. It follows alias " << maxName + << std::endl; + std::exit(1); + } else { + maxOpcode = opcode; + maxName = name; + maxCore = version != "None"; + } + } + EnumCaps caps = getCaps(inst); + std::string lastVersion = inst["lastVersion"].asString(); + Extensions exts = getExts(inst); + OperandParameters operands; + bool defResultId = false; + bool defTypeId = false; + for (const auto& operand : inst["operands"]) { + const std::string kind = operand["kind"].asString(); + const std::string quantifier = operand.get("quantifier", "").asString(); + const std::string doc = operand.get("name", "").asString(); + if (!IsTypeOrResultId(kind, &defTypeId, &defResultId)) { + const auto p = ToOperandClassAndOptionality(kind, quantifier); + operands.push(p.type, doc, p.optional); + } + } + InstructionDesc.emplace_back( + std::move(EnumValue(opcode, name, + std::move(caps), std::move(version), std::move(lastVersion), std::move(exts), + std::move(operands))), + printingClass, defTypeId, defResultId); + if (!InstructionDesc.back().IsValid(OperandOpcode, "instruction")) { + errorCount++; + } + } + + // Specific additional context-dependent operands + + // Populate dest with EnumValue objects constructed from source. + const auto populateEnumValues = [&getCaps,&getExts,&errorCount](EnumValues* dest, const Json::Value& source, bool bitEnum) { + // A lambda for determining the numeric value to be used for a given + // enumerant in JSON form, and whether that value is a 0 in a bitfield. + auto getValue = [&bitEnum](const Json::Value& enumerant) { + std::pair result{0u,false}; + if (!bitEnum) { + result.first = enumerant["value"].asUInt(); + } else { + const unsigned int bit = NumberStringToBit(enumerant["value"].asString()); + if (bit == 0) + result.second = true; + else + result.first = bit - 1; // This is the *shift* amount. + } + return result; + }; + + unsigned maxValue = 0; + std::string maxName = ""; + bool maxCore = false; + bool firstValue = true; + for (const auto& enumerant : source["enumerants"]) { + unsigned value; + bool skip_zero_in_bitfield; + std::tie(value, skip_zero_in_bitfield) = getValue(enumerant); + std::string name = enumerant["enumerant"].asString(); + std::string version = enumerant["version"].asString(); + if (skip_zero_in_bitfield) + continue; + if (firstValue) { + maxValue = value; + maxName = name; + maxCore = version != "None"; + firstValue = false; + } else { + if (maxValue > value) { + std::cerr << "Error: " << source["kind"] << " enumerant " << name + << " is out of order. It has value " << value + << " but follows the enumerant with value " << maxValue << std::endl; + std::exit(1); + } else if (maxValue == value && + !SuffixComparison(maxName, maxCore, name, + version != "None")) { + std::cerr << "Error: " << source["kind"] << " enumerant " << name + << " is out of order. It follows alias " << maxName << std::endl; + std::exit(1); + } else { + maxValue = value; + maxName = name; + maxCore = version != "None"; + } + } + EnumCaps caps(getCaps(enumerant)); + std::string lastVersion = enumerant["lastVersion"].asString(); + Extensions exts(getExts(enumerant)); + OperandParameters params; + const Json::Value& paramsJson = enumerant["parameters"]; + if (!paramsJson.empty()) { // This enumerant has parameters. + assert(paramsJson.isArray()); + for (const auto& param : paramsJson) { + const std::string kind = param["kind"].asString(); + const std::string doc = param.get("name", "").asString(); + const auto p = ToOperandClassAndOptionality(kind, ""); // All parameters are required! + params.push(p.type, doc); + } + } + dest->emplace_back( + value, enumerant["enumerant"].asString(), + std::move(caps), std::move(version), std::move(lastVersion), std::move(exts), std::move(params)); + } + }; + + const auto establishOperandClass = [&populateEnumValues,&errorCount]( + const std::string& enumName, spv::OperandClass operandClass, + spv::EnumValues* enumValues, const Json::Value& operandEnum, const std::string& category) { + assert(category == "BitEnum" || category == "ValueEnum"); + bool bitEnum = (category == "BitEnum"); + if (!operandEnum["version"].empty()) { + std::cerr << "Error: container for " << enumName << " operand_kind must not have a version field" << std::endl; + errorCount++; + } + populateEnumValues(enumValues, operandEnum, bitEnum); + const std::string errContext = "enum " + enumName; + for (const auto& e: *enumValues) { + if (!e.IsValid(operandClass, errContext)) { + errorCount++; + } + } + OperandClassParams[operandClass].set(enumName, enumValues, bitEnum); + }; + + const Json::Value operandEnums = root["operand_kinds"]; + for (const auto& operandEnum : operandEnums) { + const std::string enumName = operandEnum["kind"].asString(); + const std::string category = operandEnum["category"].asString(); + if (enumName == "SourceLanguage") { + establishOperandClass(enumName, OperandSource, &SourceLanguageParams, operandEnum, category); + } else if (enumName == "Decoration") { + establishOperandClass(enumName, OperandDecoration, &DecorationParams, operandEnum, category); + } else if (enumName == "ExecutionMode") { + establishOperandClass(enumName, OperandExecutionMode, &ExecutionModeParams, operandEnum, category); + } else if (enumName == "Capability") { + establishOperandClass(enumName, OperandCapability, &CapabilityParams, operandEnum, category); + } else if (enumName == "AddressingModel") { + establishOperandClass(enumName, OperandAddressing, &AddressingParams, operandEnum, category); + } else if (enumName == "MemoryModel") { + establishOperandClass(enumName, OperandMemory, &MemoryParams, operandEnum, category); + } else if (enumName == "MemorySemantics") { + establishOperandClass(enumName, OperandMemorySemantics, &MemorySemanticsParams, operandEnum, category); + } else if (enumName == "ExecutionModel") { + establishOperandClass(enumName, OperandExecutionModel, &ExecutionModelParams, operandEnum, category); + } else if (enumName == "StorageClass") { + establishOperandClass(enumName, OperandStorage, &StorageParams, operandEnum, category); + } else if (enumName == "SamplerAddressingMode") { + establishOperandClass(enumName, OperandSamplerAddressingMode, &SamplerAddressingModeParams, operandEnum, category); + } else if (enumName == "SamplerFilterMode") { + establishOperandClass(enumName, OperandSamplerFilterMode, &SamplerFilterModeParams, operandEnum, category); + } else if (enumName == "ImageFormat") { + establishOperandClass(enumName, OperandSamplerImageFormat, &ImageFormatParams, operandEnum, category); + } else if (enumName == "ImageChannelOrder") { + establishOperandClass(enumName, OperandImageChannelOrder, &ImageChannelOrderParams, operandEnum, category); + } else if (enumName == "ImageChannelDataType") { + establishOperandClass(enumName, OperandImageChannelDataType, &ImageChannelDataTypeParams, operandEnum, category); + } else if (enumName == "ImageOperands") { + establishOperandClass(enumName, OperandImageOperands, &ImageOperandsParams, operandEnum, category); + } else if (enumName == "FPFastMathMode") { + establishOperandClass(enumName, OperandFPFastMath, &FPFastMathParams, operandEnum, category); + } else if (enumName == "FPRoundingMode") { + establishOperandClass(enumName, OperandFPRoundingMode, &FPRoundingModeParams, operandEnum, category); + } else if (enumName == "FPDenormMode") { + establishOperandClass(enumName, OperandFPDenormMode, &FPDenormModeParams, operandEnum, category); + } else if (enumName == "FPOperationMode") { + establishOperandClass(enumName, OperandFPOperationMode, &FPOperationModeParams, operandEnum, category); + } else if (enumName == "QuantizationModes") { + establishOperandClass(enumName, OperandQuantizationModes, &QuantizationModesParams, operandEnum, category); + } else if (enumName == "OverflowModes") { + establishOperandClass(enumName, OperandOverflowModes, &OverflowModesParams, operandEnum, category); + } else if (enumName == "LinkageType") { + establishOperandClass(enumName, OperandLinkageType, &LinkageTypeParams, operandEnum, category); + } else if (enumName == "FunctionParameterAttribute") { + establishOperandClass(enumName, OperandFuncParamAttr, &FuncParamAttrParams, operandEnum, category); + } else if (enumName == "AccessQualifier") { + establishOperandClass(enumName, OperandAccessQualifier, &AccessQualifierParams, operandEnum, category); + } else if (enumName == "BuiltIn") { + establishOperandClass(enumName, OperandBuiltIn, &BuiltInParams, operandEnum, category); + } else if (enumName == "SelectionControl") { + establishOperandClass(enumName, OperandSelect, &SelectionControlParams, operandEnum, category); + } else if (enumName == "LoopControl") { + establishOperandClass(enumName, OperandLoop, &LoopControlParams, operandEnum, category); + } else if (enumName == "FunctionControl") { + establishOperandClass(enumName, OperandFunction, &FunctionControlParams, operandEnum, category); + } else if (enumName == "Dim") { + establishOperandClass(enumName, OperandDimensionality, &DimensionalityParams, operandEnum, category); + } else if (enumName == "MemoryAccess") { + establishOperandClass(enumName, OperandMemoryOperands, &MemoryAccessParams, operandEnum, category); + } else if (enumName == "Scope") { + establishOperandClass(enumName, OperandScope, &ScopeParams, operandEnum, category); + } else if (enumName == "GroupOperation") { + establishOperandClass(enumName, OperandGroupOperation, &GroupOperationParams, operandEnum, category); + } else if (enumName == "KernelEnqueueFlags") { + establishOperandClass(enumName, OperandKernelEnqueueFlags, &KernelEnqueueFlagsParams, operandEnum, category); + } else if (enumName == "KernelProfilingInfo") { + establishOperandClass(enumName, OperandKernelProfilingInfo, &KernelProfilingInfoParams, operandEnum, category); + } else if (enumName == "RayFlags") { + establishOperandClass(enumName, OperandRayFlags, &RayFlagsParams, operandEnum, category); + } else if (enumName == "RayQueryIntersection") { + establishOperandClass(enumName, OperandRayQueryIntersection, &RayQueryIntersectionParams, operandEnum, category); + } else if (enumName == "RayQueryCommittedIntersectionType") { + establishOperandClass(enumName, OperandRayQueryCommittedIntersectionType, &RayQueryCommittedIntersectionTypeParams, operandEnum, category); + } else if (enumName == "RayQueryCandidateIntersectionType") { + establishOperandClass(enumName, OperandRayQueryCandidateIntersectionType, &RayQueryCandidateIntersectionTypeParams, operandEnum, category); + } else if (enumName == "FragmentShadingRate") { + establishOperandClass(enumName, OperandFragmentShadingRate, &FragmentShadingRateParams, operandEnum, category); + } else if (enumName == "PackedVectorFormat") { + establishOperandClass(enumName, OperandPackedVectorFormat, &PackedVectorFormatParams, operandEnum, category); + } else if (enumName == "CooperativeMatrixOperands") { + establishOperandClass(enumName, OperandCooperativeMatrixOperands, &CooperativeMatrixOperandsParams, operandEnum, category); + } else if (enumName == "CooperativeMatrixLayout") { + establishOperandClass(enumName, OperandCooperativeMatrixLayout, &CooperativeMatrixLayoutParams, operandEnum, category); + } else if (enumName == "CooperativeMatrixUse") { + establishOperandClass(enumName, OperandCooperativeMatrixUse, &CooperativeMatrixUseParams, operandEnum, category); + } else if (enumName == "InitializationModeQualifier") { + establishOperandClass(enumName, OperandInitializationModeQualifier, &InitializationModeQualifierParams, operandEnum, category); + } else if (enumName == "HostAccessQualifier") { + establishOperandClass(enumName, OperandHostAccessQualifier, &HostAccessQualifierParams, operandEnum, category); + } else if (enumName == "LoadCacheControl") { + establishOperandClass(enumName, OperandLoadCacheControl, &LoadCacheControlParams, operandEnum, category); + } else if (enumName == "StoreCacheControl") { + establishOperandClass(enumName, OperandStoreCacheControl, &StoreCacheControlParams, operandEnum, category); + } else if (enumName == "NamedMaximumNumberOfRegisters") { + establishOperandClass(enumName, OperandNamedMaximumNumberOfRegisters, &NamedMaximumNumberOfRegistersParams, operandEnum, category); + } else if (enumName == "RawAccessChainOperands") { + establishOperandClass(enumName, OperandRawAccessChainOperands, &RawAccessChainOperandsParams, operandEnum, category); + } + } + + if (errorCount > 0) { + std::exit(1); + } +} + +}; // end namespace spv diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h new file mode 100644 index 0000000..c8de68f --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h @@ -0,0 +1,315 @@ +// 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. + +#pragma once +#ifndef JSON_TO_SPIRV +#define JSON_TO_SPIRV + +#include +#include +#include +#include + +namespace spv { + + // Reads the file in the given |path|. Returns true and the contents of the +// file on success; otherwise, returns false and an empty string. +std::pair ReadFile(const std::string& path); + +// Fill in all the parameters +void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders); + +// For parameterizing operands. +// The ordering here affects the printing order in the SPIR-V specification. +// Please add new operand classes at the end. +enum OperandClass { + OperandNone, + OperandId, + OperandVariableIds, + OperandOptionalLiteral, + OperandOptionalLiteralString, + OperandOptionalLiteralStrings, + OperandVariableLiterals, + OperandVariableIdLiteral, + OperandVariableLiteralId, + OperandAnySizeLiteralNumber, + OperandLiteralNumber, + OperandLiteralString, + OperandSource, + OperandExecutionModel, + OperandAddressing, + OperandMemory, + OperandExecutionMode, + OperandStorage, + OperandDimensionality, + OperandSamplerAddressingMode, + OperandSamplerFilterMode, + OperandSamplerImageFormat, + OperandImageChannelOrder, + OperandImageChannelDataType, + OperandImageOperands, + OperandFPFastMath, + OperandFPRoundingMode, + OperandLinkageType, + OperandAccessQualifier, + OperandFuncParamAttr, + OperandDecoration, + OperandBuiltIn, + OperandSelect, + OperandLoop, + OperandFunction, + OperandMemorySemantics, + OperandMemoryOperands, + OperandScope, + OperandGroupOperation, + OperandKernelEnqueueFlags, + OperandKernelProfilingInfo, + OperandCapability, + OperandRayFlags, + OperandRayQueryIntersection, + OperandRayQueryCommittedIntersectionType, + OperandRayQueryCandidateIntersectionType, + OperandFragmentShadingRate, + OperandFPDenormMode, + OperandFPOperationMode, + OperandQuantizationModes, + OperandOverflowModes, + OperandPackedVectorFormat, + OperandCooperativeMatrixOperands, + OperandCooperativeMatrixLayout, + OperandCooperativeMatrixUse, + OperandInitializationModeQualifier, + OperandHostAccessQualifier, + OperandLoadCacheControl, + OperandStoreCacheControl, + OperandNamedMaximumNumberOfRegisters, + OperandRawAccessChainOperands, + + OperandOpcode, + + OperandCount +}; + +// For direct representation of the JSON grammar "instruction_printing_class". +struct PrintingClass { + std::string tag; + std::string heading; +}; +using PrintingClasses = std::vector; + +// Any specific enum can have a set of capabilities that allow it: +typedef std::vector EnumCaps; + +// A set of extensions. +typedef std::vector Extensions; + +// Parameterize a set of operands with their OperandClass(es) and descriptions. +class OperandParameters { +public: + OperandParameters() { } + void push(OperandClass oc, const std::string& d, bool opt = false) + { + opClass.push_back(oc); + desc.push_back(d); + optional.push_back(opt); + } + void setOptional(); + OperandClass getClass(int op) const { return opClass[op]; } + const char* getDesc(int op) const { return desc[op].c_str(); } + bool isOptional(int op) const { return optional[op]; } + int getNum() const { return (int)opClass.size(); } + +protected: + std::vector opClass; + std::vector desc; + std::vector optional; +}; + +// An ordered sequence of EValue. We'll preserve the order found in the +// JSON file. You can look up a value by enum or by name. If there are +// duplicate values, then take the first. We assume names are unique. +// The EValue must have an unsigned |value| field and a string |name| field. +template +class EnumValuesContainer { +public: + using ContainerType = std::vector; + using iterator = typename ContainerType::iterator; + using const_iterator = typename ContainerType::const_iterator; + + EnumValuesContainer() {} + + // Constructs an EValue in place as a new element at the end of the + // sequence. + template + void emplace_back(Args&&... args) { + values.emplace_back(std::forward(args)...); + } + + // Returns the first EValue in the sequence with the given value. + // More than one EValue might have the same value. + EValue& operator[](unsigned value) { + auto where = std::find_if(begin(), end(), [&value](const EValue& e) { + return value == e.value; + }); + assert((where != end()) && "Could not find enum in the enum list"); + return *where; + } + // gets *all* entries for the value, including the first one + void gatherAliases(unsigned value, std::vector& aliases) { + std::for_each(begin(), end(), [&](EValue& e) { + if (value == e.value) + aliases.push_back(&e);}); + } + // Returns the EValue with the given name. We assume uniqueness + // by name. + EValue& at(std::string name) { + auto where = std::find_if(begin(), end(), [&name](const EValue& e) { + return name == e.name; + }); + assert((where != end()) && "Could not find name in the enum list"); + return *where; + } + + iterator begin() { return values.begin(); } + iterator end() { return values.end(); } + EValue& back() { return values.back(); } + +private: + ContainerType values; +}; + +// A single enumerant value. Corresponds to a row in an enumeration table +// in the spec. +class EnumValue { +public: + EnumValue() : value(0), desc(nullptr) {} + EnumValue(unsigned int the_value, const std::string& the_name, EnumCaps&& the_caps, + const std::string& the_firstVersion, const std::string& the_lastVersion, + Extensions&& the_extensions, OperandParameters&& the_operands) : + value(the_value), name(the_name), capabilities(std::move(the_caps)), + firstVersion(std::move(the_firstVersion)), lastVersion(std::move(the_lastVersion)), + extensions(std::move(the_extensions)), operands(std::move(the_operands)), desc(nullptr) { } + + // For ValueEnum, the value from the JSON file. + // For BitEnum, the index of the bit position represented by this mask. + // (That is, what you shift 1 by to get the mask.) + unsigned value; + std::string name; + EnumCaps capabilities; + std::string firstVersion; + std::string lastVersion; + // A feature only be enabled by certain extensions. + // An empty list means the feature does not require an extension. + // Normally, only Capability enums are enabled by extension. In turn, + // other enums and instructions are enabled by those capabilities. + Extensions extensions; + OperandParameters operands; + const char* desc; + + // Returns true if this enum is valid, in isolation. + // Otherwise emits a diagnostic to std::cerr and returns false. + bool IsValid(OperandClass oc, const std::string& context) const; +}; + +using EnumValues = EnumValuesContainer; + +// Parameterize a set of enumerants that form an enum +class EnumDefinition { +public: + EnumDefinition() : + desc(0), bitmask(false), enumValues(nullptr) { } + void set(const std::string& enumName, EnumValues* enumValuesArg, bool mask = false) + { + codeName = enumName; + bitmask = mask; + enumValues = enumValuesArg; + } + // Returns the first EnumValue in the sequence with the given value. + // More than one EnumValue might have the same value. Only valid + // if enumValues has been populated. + EnumValue& operator[](unsigned value) { + assert(enumValues != nullptr); + return (*enumValues)[value]; + } + // Returns the name of the first EnumValue with the given value. + // Assumes enumValues has been populated. + const char* getName(unsigned value) { + return (*this)[value].name.c_str(); + } + + using iterator = EnumValues::iterator; + iterator begin() { return enumValues->begin(); } + iterator end() { return enumValues->end(); } + + std::string codeName; // name to use when declaring headers for code + const char* desc; + bool bitmask; // true if these enumerants combine into a bitmask + EnumValues* enumValues; // parameters for each individual enumerant +}; + +// Parameterize an instruction's logical format, including its known set of operands, +// per OperandParameters above. +class InstructionValue : public EnumValue { +public: + InstructionValue(EnumValue&& e, const std::string& printClass, bool has_type, bool has_result) + : EnumValue(std::move(e)), + printingClass(printClass), + opDesc("TBD"), + typePresent(has_type), + resultPresent(has_result), + alias(this) { } + InstructionValue(const InstructionValue& v) + { + *this = v; + alias = this; + } + + bool hasResult() const { return resultPresent != 0; } + bool hasType() const { return typePresent != 0; } + void setAlias(const InstructionValue& a) { alias = &a; } + const InstructionValue& getAlias() const { return *alias; } + bool isAlias() const { return alias != this; } + + std::string printingClass; + const char* opDesc; + +protected: + int typePresent : 1; + int resultPresent : 1; + const InstructionValue* alias; // correct only after discovering the aliases; otherwise points to this +}; + +using InstructionValues = EnumValuesContainer; + +// Parameterization info for all instructions. +extern InstructionValues InstructionDesc; +extern PrintingClasses InstructionPrintingClasses; + +// These hold definitions of the enumerants used for operands. +// This is indexed by OperandClass, but not including OperandOpcode. +extern EnumDefinition OperandClassParams[]; + +}; // end namespace spv + +#endif // JSON_TO_SPIRV diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/json/json-forwards.h b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/json/json-forwards.h new file mode 100644 index 0000000..ccbdb2b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/json/json-forwards.h @@ -0,0 +1,255 @@ +/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/). +/// It is intended to be used with #include "json/json-forwards.h" +/// This header provides forward declaration for all JsonCpp types. + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +The author (Baptiste Lepilleur) explicitly disclaims copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is +released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +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 Software. + +THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + +#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED +# define JSON_FORWARD_AMALGATED_H_INCLUDED +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +#define JSON_IS_AMALGAMATION + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_CONFIG_H_INCLUDED +#define JSON_CONFIG_H_INCLUDED + +/// If defined, indicates that json library is embedded in CppTL library. +//# define JSON_IN_CPPTL 1 + +/// If defined, indicates that json may leverage CppTL library +//# define JSON_USE_CPPTL 1 +/// If defined, indicates that cpptl vector based map should be used instead of +/// std::map +/// as Value container. +//# define JSON_USE_CPPTL_SMALLMAP 1 + +// If non-zero, the library uses exceptions to report bad input instead of C +// assertion macros. The default is to use exceptions. +#ifndef JSON_USE_EXCEPTION +#define JSON_USE_EXCEPTION 1 +#endif + +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +/// Remarks: it is automatically defined in the generated amalgated header. +// #define JSON_IS_AMALGAMATION + +#ifdef JSON_IN_CPPTL +#include +#ifndef JSON_USE_CPPTL +#define JSON_USE_CPPTL 1 +#endif +#endif + +#ifdef JSON_IN_CPPTL +#define JSON_API CPPTL_API +#elif defined(JSON_DLL_BUILD) +#if defined(_MSC_VER) +#define JSON_API __declspec(dllexport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#elif defined(JSON_DLL) +#if defined(_MSC_VER) +#define JSON_API __declspec(dllimport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#endif // ifdef JSON_IN_CPPTL +#if !defined(JSON_API) +#define JSON_API +#endif + +// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for +// integer +// Storages, and 64 bits integer support is disabled. +// #define JSON_NO_INT64 1 + +#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6 +// Microsoft Visual Studio 6 only support conversion from __int64 to double +// (no conversion from unsigned __int64). +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' +// characters in the debug information) +// All projects I've ever seen with VS6 were using this globally (not bothering +// with pragma push/pop). +#pragma warning(disable : 4786) +#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 + +#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 +/// Indicates that the following function is deprecated. +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#elif defined(__clang__) && defined(__has_feature) +#if __has_feature(attribute_deprecated_with_message) +#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) +#endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) +#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) +#endif + +#if !defined(JSONCPP_DEPRECATED) +#define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +namespace Json { +typedef int Int; +typedef unsigned int UInt; +#if defined(JSON_NO_INT64) +typedef int LargestInt; +typedef unsigned int LargestUInt; +#undef JSON_HAS_INT64 +#else // if defined(JSON_NO_INT64) +// For Microsoft Visual use specific types as long long is not supported +#if defined(_MSC_VER) // Microsoft Visual Studio +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else // if defined(_MSC_VER) // Other platforms, use long long +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif // if defined(_MSC_VER) +typedef Int64 LargestInt; +typedef UInt64 LargestUInt; +#define JSON_HAS_INT64 +#endif // if defined(JSON_NO_INT64) +} // end namespace Json + +#endif // JSON_CONFIG_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_FORWARDS_H_INCLUDED +#define JSON_FORWARDS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +// writer.h +class FastWriter; +class StyledWriter; + +// reader.h +class Reader; + +// features.h +class Features; + +// value.h +typedef unsigned int ArrayIndex; +class StaticString; +class Path; +class PathArgument; +class Value; +class ValueIteratorBase; +class ValueIterator; +class ValueConstIterator; + +} // namespace Json + +#endif // JSON_FORWARDS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + + + + + +#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/json/json.h b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/json/json.h new file mode 100644 index 0000000..e01991e --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/json/json.h @@ -0,0 +1,2017 @@ +/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/). +/// It is intended to be used with #include "json/json.h" + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +The author (Baptiste Lepilleur) explicitly disclaims copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is +released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +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 Software. + +THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + +#ifndef JSON_AMALGATED_H_INCLUDED +# define JSON_AMALGATED_H_INCLUDED +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +#define JSON_IS_AMALGAMATION + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + +// DO NOT EDIT. This file is generated by CMake from "version" +// and "version.h.in" files. +// Run CMake configure step to update it. +#ifndef JSON_VERSION_H_INCLUDED +# define JSON_VERSION_H_INCLUDED + +# define JSONCPP_VERSION_STRING "1.6.2" +# define JSONCPP_VERSION_MAJOR 1 +# define JSONCPP_VERSION_MINOR 6 +# define JSONCPP_VERSION_PATCH 2 +# define JSONCPP_VERSION_QUALIFIER +# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) + +#endif // JSON_VERSION_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_CONFIG_H_INCLUDED +#define JSON_CONFIG_H_INCLUDED + +/// If defined, indicates that json library is embedded in CppTL library. +//# define JSON_IN_CPPTL 1 + +/// If defined, indicates that json may leverage CppTL library +//# define JSON_USE_CPPTL 1 +/// If defined, indicates that cpptl vector based map should be used instead of +/// std::map +/// as Value container. +//# define JSON_USE_CPPTL_SMALLMAP 1 + +// If non-zero, the library uses exceptions to report bad input instead of C +// assertion macros. The default is to use exceptions. +#ifndef JSON_USE_EXCEPTION +#define JSON_USE_EXCEPTION 1 +#endif + +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +/// Remarks: it is automatically defined in the generated amalgated header. +// #define JSON_IS_AMALGAMATION + +#ifdef JSON_IN_CPPTL +#include +#ifndef JSON_USE_CPPTL +#define JSON_USE_CPPTL 1 +#endif +#endif + +#ifdef JSON_IN_CPPTL +#define JSON_API CPPTL_API +#elif defined(JSON_DLL_BUILD) +#if defined(_MSC_VER) +#define JSON_API __declspec(dllexport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#elif defined(JSON_DLL) +#if defined(_MSC_VER) +#define JSON_API __declspec(dllimport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#endif // ifdef JSON_IN_CPPTL +#if !defined(JSON_API) +#define JSON_API +#endif + +// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for +// integer +// Storages, and 64 bits integer support is disabled. +// #define JSON_NO_INT64 1 + +#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6 +// Microsoft Visual Studio 6 only support conversion from __int64 to double +// (no conversion from unsigned __int64). +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' +// characters in the debug information) +// All projects I've ever seen with VS6 were using this globally (not bothering +// with pragma push/pop). +#pragma warning(disable : 4786) +#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 + +#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 +/// Indicates that the following function is deprecated. +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#elif defined(__clang__) && defined(__has_feature) +#if __has_feature(attribute_deprecated_with_message) +#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) +#endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) +#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) +#endif + +#if !defined(JSONCPP_DEPRECATED) +#define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +namespace Json { +typedef int Int; +typedef unsigned int UInt; +#if defined(JSON_NO_INT64) +typedef int LargestInt; +typedef unsigned int LargestUInt; +#undef JSON_HAS_INT64 +#else // if defined(JSON_NO_INT64) +// For Microsoft Visual use specific types as long long is not supported +#if defined(_MSC_VER) // Microsoft Visual Studio +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else // if defined(_MSC_VER) // Other platforms, use long long +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif // if defined(_MSC_VER) +typedef Int64 LargestInt; +typedef UInt64 LargestUInt; +#define JSON_HAS_INT64 +#endif // if defined(JSON_NO_INT64) +} // end namespace Json + +#endif // JSON_CONFIG_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_FORWARDS_H_INCLUDED +#define JSON_FORWARDS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +// writer.h +class FastWriter; +class StyledWriter; + +// reader.h +class Reader; + +// features.h +class Features; + +// value.h +typedef unsigned int ArrayIndex; +class StaticString; +class Path; +class PathArgument; +class Value; +class ValueIteratorBase; +class ValueIterator; +class ValueConstIterator; + +} // namespace Json + +#endif // JSON_FORWARDS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/features.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_FEATURES_H_INCLUDED +#define CPPTL_JSON_FEATURES_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +/** \brief Configuration passed to reader and writer. + * This configuration object can be used to force the Reader or Writer + * to behave in a standard conforming way. + */ +class JSON_API Features { +public: + /** \brief A configuration that allows all features and assumes all strings + * are UTF-8. + * - C & C++ comments are allowed + * - Root object can be any JSON value + * - Assumes Value strings are encoded in UTF-8 + */ + static Features all(); + + /** \brief A configuration that is strictly compatible with the JSON + * specification. + * - Comments are forbidden. + * - Root object must be either an array or an object value. + * - Assumes Value strings are encoded in UTF-8 + */ + static Features strictMode(); + + /** \brief Initialize the configuration like JsonConfig::allFeatures; + */ + Features(); + + /// \c true if comments are allowed. Default: \c true. + bool allowComments_; + + /// \c true if root must be either an array or an object value. Default: \c + /// false. + bool strictRoot_; + + /// \c true if dropped null placeholders are allowed. Default: \c false. + bool allowDroppedNullPlaceholders_; + + /// \c true if numeric object key are allowed. Default: \c false. + bool allowNumericKeys_; +}; + +} // namespace Json + +#endif // CPPTL_JSON_FEATURES_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/features.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/value.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_H_INCLUDED +#define CPPTL_JSON_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include + +#ifndef JSON_USE_CPPTL_SMALLMAP +#include +#else +#include +#endif +#ifdef JSON_USE_CPPTL +#include +#endif + +// Disable warning C4251: : needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +/** \brief JSON (JavaScript Object Notation). + */ +namespace Json { + +/** Base class for all exceptions we throw. + * + * We use nothing but these internally. Of course, STL can throw others. + */ +class JSON_API Exception; +/** Exceptions which the user cannot easily avoid. + * + * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input + * + * \remark derived from Json::Exception + */ +class JSON_API RuntimeError; +/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. + * + * These are precondition-violations (user bugs) and internal errors (our bugs). + * + * \remark derived from Json::Exception + */ +class JSON_API LogicError; + +/// used internally +void throwRuntimeError(std::string const& msg); +/// used internally +void throwLogicError(std::string const& msg); + +/** \brief Type of the value held by a Value object. + */ +enum ValueType { + nullValue = 0, ///< 'null' value + intValue, ///< signed integer value + uintValue, ///< unsigned integer value + realValue, ///< double value + stringValue, ///< UTF-8 string value + booleanValue, ///< bool value + arrayValue, ///< array value (ordered list) + objectValue ///< object value (collection of name/value pairs). +}; + +enum CommentPlacement { + commentBefore = 0, ///< a comment placed on the line before a value + commentAfterOnSameLine, ///< a comment just after a value on the same line + commentAfter, ///< a comment on the line after a value (only make sense for + /// root value) + numberOfCommentPlacement +}; + +//# ifdef JSON_USE_CPPTL +// typedef CppTL::AnyEnumerator EnumMemberNames; +// typedef CppTL::AnyEnumerator EnumValues; +//# endif + +/** \brief Lightweight wrapper to tag static string. + * + * Value constructor and objectValue member assignement takes advantage of the + * StaticString and avoid the cost of string duplication when storing the + * string or the member name. + * + * Example of usage: + * \code + * Json::Value aValue( StaticString("some text") ); + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ +class JSON_API StaticString { +public: + explicit StaticString(const char* czstring) : c_str_(czstring) {} + + operator const char*() const { return c_str_; } + + const char* c_str() const { return c_str_; } + +private: + const char* c_str_; +}; + +/** \brief Represents a JSON value. + * + * This class is a discriminated union wrapper that can represents a: + * - signed integer [range: Value::minInt - Value::maxInt] + * - unsigned integer (range: 0 - Value::maxUInt) + * - double + * - UTF-8 string + * - boolean + * - 'null' + * - an ordered list of Value + * - collection of name/value pairs (javascript object) + * + * The type of the held value is represented by a #ValueType and + * can be obtained using type(). + * + * Values of an #objectValue or #arrayValue can be accessed using operator[]() + * methods. + * Non-const methods will automatically create the a #nullValue element + * if it does not exist. + * The sequence of an #arrayValue will be automatically resized and initialized + * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. + * + * The get() methods can be used to obtain default value in the case the + * required element does not exist. + * + * It is possible to iterate over the list of a #objectValue values using + * the getMemberNames() method. + * + * \note #Value string-length fit in size_t, but keys must be < 2^30. + * (The reason is an implementation detail.) A #CharReader will raise an + * exception if a bound is exceeded to avoid security holes in your app, + * but the Value API does *not* check bounds. That is the responsibility + * of the caller. + */ +class JSON_API Value { + friend class ValueIteratorBase; +public: + typedef std::vector Members; + typedef ValueIterator iterator; + typedef ValueConstIterator const_iterator; + typedef Json::UInt UInt; + typedef Json::Int Int; +#if defined(JSON_HAS_INT64) + typedef Json::UInt64 UInt64; + typedef Json::Int64 Int64; +#endif // defined(JSON_HAS_INT64) + typedef Json::LargestInt LargestInt; + typedef Json::LargestUInt LargestUInt; + typedef Json::ArrayIndex ArrayIndex; + + static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). + static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null + /// Minimum signed integer value that can be stored in a Json::Value. + static const LargestInt minLargestInt; + /// Maximum signed integer value that can be stored in a Json::Value. + static const LargestInt maxLargestInt; + /// Maximum unsigned integer value that can be stored in a Json::Value. + static const LargestUInt maxLargestUInt; + + /// Minimum signed int value that can be stored in a Json::Value. + static const Int minInt; + /// Maximum signed int value that can be stored in a Json::Value. + static const Int maxInt; + /// Maximum unsigned int value that can be stored in a Json::Value. + static const UInt maxUInt; + +#if defined(JSON_HAS_INT64) + /// Minimum signed 64 bits int value that can be stored in a Json::Value. + static const Int64 minInt64; + /// Maximum signed 64 bits int value that can be stored in a Json::Value. + static const Int64 maxInt64; + /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. + static const UInt64 maxUInt64; +#endif // defined(JSON_HAS_INT64) + +private: +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + class CZString { + public: + enum DuplicationPolicy { + noDuplication = 0, + duplicate, + duplicateOnCopy + }; + CZString(ArrayIndex index); + CZString(char const* str, unsigned length, DuplicationPolicy allocate); + CZString(CZString const& other); + ~CZString(); + CZString& operator=(CZString other); + bool operator<(CZString const& other) const; + bool operator==(CZString const& other) const; + ArrayIndex index() const; + //const char* c_str() const; ///< \deprecated + char const* data() const; + unsigned length() const; + bool isStaticString() const; + + private: + void swap(CZString& other); + + struct StringStorage { + unsigned policy_: 2; + unsigned length_: 30; // 1GB max + }; + + char const* cstr_; // actually, a prefixed string, unless policy is noDup + union { + ArrayIndex index_; + StringStorage storage_; + }; + }; + +public: +#ifndef JSON_USE_CPPTL_SMALLMAP + typedef std::map ObjectValues; +#else + typedef CppTL::SmallMap ObjectValues; +#endif // ifndef JSON_USE_CPPTL_SMALLMAP +#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + +public: + /** \brief Create a default Value of the given type. + + This is a very useful constructor. + To create an empty array, pass arrayValue. + To create an empty object, pass objectValue. + Another Value can then be set to this one by assignment. +This is useful since clear() and resize() will not alter types. + + Examples: +\code +Json::Value null_value; // null +Json::Value arr_value(Json::arrayValue); // [] +Json::Value obj_value(Json::objectValue); // {} +\endcode + */ + Value(ValueType type = nullValue); + Value(Int value); + Value(UInt value); +#if defined(JSON_HAS_INT64) + Value(Int64 value); + Value(UInt64 value); +#endif // if defined(JSON_HAS_INT64) + Value(double value); + Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) + Value(const char* beginValue, const char* endValue); ///< Copy all, incl zeroes. + /** \brief Constructs a value from a static string. + + * Like other value string constructor but do not duplicate the string for + * internal storage. The given string must remain alive after the call to this + * constructor. + * \note This works only for null-terminated strings. (We cannot change the + * size of this class, so we have nowhere to store the length, + * which might be computed later for various operations.) + * + * Example of usage: + * \code + * static StaticString foo("some text"); + * Json::Value aValue(foo); + * \endcode + */ + Value(const StaticString& value); + Value(const std::string& value); ///< Copy data() til size(). Embedded zeroes too. +#ifdef JSON_USE_CPPTL + Value(const CppTL::ConstString& value); +#endif + Value(bool value); + /// Deep copy. + Value(const Value& other); + ~Value(); + + /// Deep copy, then swap(other). + /// \note Over-write existing comments. To preserve comments, use #swapPayload(). + Value& operator=(Value other); + /// Swap everything. + void swap(Value& other); + /// Swap values but leave comments and source offsets in place. + void swapPayload(Value& other); + + ValueType type() const; + + /// Compare payload only, not comments etc. + bool operator<(const Value& other) const; + bool operator<=(const Value& other) const; + bool operator>=(const Value& other) const; + bool operator>(const Value& other) const; + bool operator==(const Value& other) const; + bool operator!=(const Value& other) const; + int compare(const Value& other) const; + + const char* asCString() const; ///< Embedded zeroes could cause you trouble! + std::string asString() const; ///< Embedded zeroes are possible. + /** Get raw char* of string-value. + * \return false if !string. (Seg-fault if str or end are NULL.) + */ + bool getString( + char const** str, char const** end) const; +#ifdef JSON_USE_CPPTL + CppTL::ConstString asConstString() const; +#endif + Int asInt() const; + UInt asUInt() const; +#if defined(JSON_HAS_INT64) + Int64 asInt64() const; + UInt64 asUInt64() const; +#endif // if defined(JSON_HAS_INT64) + LargestInt asLargestInt() const; + LargestUInt asLargestUInt() const; + float asFloat() const; + double asDouble() const; + bool asBool() const; + + bool isNull() const; + bool isBool() const; + bool isInt() const; + bool isInt64() const; + bool isUInt() const; + bool isUInt64() const; + bool isIntegral() const; + bool isDouble() const; + bool isNumeric() const; + bool isString() const; + bool isArray() const; + bool isObject() const; + + bool isConvertibleTo(ValueType other) const; + + /// Number of values in array or object + ArrayIndex size() const; + + /// \brief Return true if empty array, empty object, or null; + /// otherwise, false. + bool empty() const; + + /// Return isNull() + bool operator!() const; + + /// Remove all object members and array elements. + /// \pre type() is arrayValue, objectValue, or nullValue + /// \post type() is unchanged + void clear(); + + /// Resize the array to size elements. + /// New elements are initialized to null. + /// May only be called on nullValue or arrayValue. + /// \pre type() is arrayValue or nullValue + /// \post type() is arrayValue + void resize(ArrayIndex size); + + /// Access an array element (zero based index ). + /// If the array contains less than index element, then null value are + /// inserted + /// in the array so that its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value& operator[](ArrayIndex index); + + /// Access an array element (zero based index ). + /// If the array contains less than index element, then null value are + /// inserted + /// in the array so that its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value& operator[](int index); + + /// Access an array element (zero based index ) + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value& operator[](ArrayIndex index) const; + + /// Access an array element (zero based index ) + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value& operator[](int index) const; + + /// If the array contains at least index+1 elements, returns the element + /// value, + /// otherwise returns defaultValue. + Value get(ArrayIndex index, const Value& defaultValue) const; + /// Return true if index < size(). + bool isValidIndex(ArrayIndex index) const; + /// \brief Append value to array at the end. + /// + /// Equivalent to jsonvalue[jsonvalue.size()] = value; + Value& append(const Value& value); + + /// Access an object value by name, create a null member if it does not exist. + /// \note Because of our implementation, keys are limited to 2^30 -1 chars. + /// Exceeding that will cause an exception. + Value& operator[](const char* key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const char* key) const; + /// Access an object value by name, create a null member if it does not exist. + /// \param key may contain embedded nulls. + Value& operator[](const std::string& key); + /// Access an object value by name, returns null if there is no member with + /// that name. + /// \param key may contain embedded nulls. + const Value& operator[](const std::string& key) const; + /** \brief Access an object value by name, create a null member if it does not + exist. + + * If the object has no entry for that name, then the member name used to store + * the new entry is not duplicated. + * Example of use: + * \code + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ + Value& operator[](const StaticString& key); +#ifdef JSON_USE_CPPTL + /// Access an object value by name, create a null member if it does not exist. + Value& operator[](const CppTL::ConstString& key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const CppTL::ConstString& key) const; +#endif + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + Value get(const char* key, const Value& defaultValue) const; + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + /// \param key may contain embedded nulls. + Value get(const char* key, const char* end, const Value& defaultValue) const; + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + /// \param key may contain embedded nulls. + Value get(const std::string& key, const Value& defaultValue) const; +#ifdef JSON_USE_CPPTL + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + Value get(const CppTL::ConstString& key, const Value& defaultValue) const; +#endif + /// Most general and efficient version of isMember()const, get()const, + /// and operator[]const + /// \note As stated elsewhere, behavior is undefined if (end-key) >= 2^30 + Value const* find(char const* key, char const* end) const; + /// Most general and efficient version of object-mutators. + /// \note As stated elsewhere, behavior is undefined if (end-key) >= 2^30 + /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. + Value const* demand(char const* key, char const* end); + /// \brief Remove and return the named member. + /// + /// Do nothing if it did not exist. + /// \return the removed Value, or null. + /// \pre type() is objectValue or nullValue + /// \post type() is unchanged + /// \deprecated + Value removeMember(const char* key); + /// Same as removeMember(const char*) + /// \param key may contain embedded nulls. + /// \deprecated + Value removeMember(const std::string& key); + /// Same as removeMember(const char* key, const char* end, Value* removed), + /// but 'key' is null-terminated. + bool removeMember(const char* key, Value* removed); + /** \brief Remove the named map member. + + Update 'removed' iff removed. + \param key may contain embedded nulls. + \return true iff removed (no exceptions) + */ + bool removeMember(std::string const& key, Value* removed); + /// Same as removeMember(std::string const& key, Value* removed) + bool removeMember(const char* key, const char* end, Value* removed); + /** \brief Remove the indexed array element. + + O(n) expensive operations. + Update 'removed' iff removed. + \return true iff removed (no exceptions) + */ + bool removeIndex(ArrayIndex i, Value* removed); + + /// Return true if the object has a member named key. + /// \note 'key' must be null-terminated. + bool isMember(const char* key) const; + /// Return true if the object has a member named key. + /// \param key may contain embedded nulls. + bool isMember(const std::string& key) const; + /// Same as isMember(std::string const& key)const + bool isMember(const char* key, const char* end) const; +#ifdef JSON_USE_CPPTL + /// Return true if the object has a member named key. + bool isMember(const CppTL::ConstString& key) const; +#endif + + /// \brief Return a list of the member names. + /// + /// If null, return an empty list. + /// \pre type() is objectValue or nullValue + /// \post if type() was nullValue, it remains nullValue + Members getMemberNames() const; + + //# ifdef JSON_USE_CPPTL + // EnumMemberNames enumMemberNames() const; + // EnumValues enumValues() const; + //# endif + + /// \deprecated Always pass len. + JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.") + void setComment(const char* comment, CommentPlacement placement); + /// Comments must be //... or /* ... */ + void setComment(const char* comment, size_t len, CommentPlacement placement); + /// Comments must be //... or /* ... */ + void setComment(const std::string& comment, CommentPlacement placement); + bool hasComment(CommentPlacement placement) const; + /// Include delimiters and embedded newlines. + std::string getComment(CommentPlacement placement) const; + + std::string toStyledString() const; + + const_iterator begin() const; + const_iterator end() const; + + iterator begin(); + iterator end(); + + // Accessors for the [start, limit) range of bytes within the JSON text from + // which this value was parsed, if any. + void setOffsetStart(size_t start); + void setOffsetLimit(size_t limit); + size_t getOffsetStart() const; + size_t getOffsetLimit() const; + +private: + void initBasic(ValueType type, bool allocated = false); + + Value& resolveReference(const char* key); + Value& resolveReference(const char* key, const char* end); + + struct CommentInfo { + CommentInfo(); + ~CommentInfo(); + + void setComment(const char* text, size_t len); + + char* comment_; + }; + + // struct MemberNamesTransform + //{ + // typedef const char *result_type; + // const char *operator()( const CZString &name ) const + // { + // return name.c_str(); + // } + //}; + + union ValueHolder { + LargestInt int_; + LargestUInt uint_; + double real_; + bool bool_; + char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ + ObjectValues* map_; + } value_; + ValueType type_ : 8; + unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. + // If not allocated_, string_ must be null-terminated. + CommentInfo* comments_; + + // [start, limit) byte offsets in the source JSON text from which this Value + // was extracted. + size_t start_; + size_t limit_; +}; + +/** \brief Experimental and untested: represents an element of the "path" to + * access a node. + */ +class JSON_API PathArgument { +public: + friend class Path; + + PathArgument(); + PathArgument(ArrayIndex index); + PathArgument(const char* key); + PathArgument(const std::string& key); + +private: + enum Kind { + kindNone = 0, + kindIndex, + kindKey + }; + std::string key_; + ArrayIndex index_; + Kind kind_; +}; + +/** \brief Experimental and untested: represents a "path" to access a node. + * + * Syntax: + * - "." => root node + * - ".[n]" => elements at index 'n' of root node (an array value) + * - ".name" => member named 'name' of root node (an object value) + * - ".name1.name2.name3" + * - ".[0][1][2].name1[3]" + * - ".%" => member name is provided as parameter + * - ".[%]" => index is provied as parameter + */ +class JSON_API Path { +public: + Path(const std::string& path, + const PathArgument& a1 = PathArgument(), + const PathArgument& a2 = PathArgument(), + const PathArgument& a3 = PathArgument(), + const PathArgument& a4 = PathArgument(), + const PathArgument& a5 = PathArgument()); + + const Value& resolve(const Value& root) const; + Value resolve(const Value& root, const Value& defaultValue) const; + /// Creates the "path" to access the specified node and returns a reference on + /// the node. + Value& make(Value& root) const; + +private: + typedef std::vector InArgs; + typedef std::vector Args; + + void makePath(const std::string& path, const InArgs& in); + void addPathInArg(const std::string& path, + const InArgs& in, + InArgs::const_iterator& itInArg, + PathArgument::Kind kind); + void invalidPath(const std::string& path, int location); + + Args args_; +}; + +/** \brief base class for Value iterators. + * + */ +class JSON_API ValueIteratorBase { +public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef unsigned int size_t; + typedef int difference_type; + typedef ValueIteratorBase SelfType; + + bool operator==(const SelfType& other) const { return isEqual(other); } + + bool operator!=(const SelfType& other) const { return !isEqual(other); } + + difference_type operator-(const SelfType& other) const { + return other.computeDistance(*this); + } + + /// Return either the index or the member name of the referenced value as a + /// Value. + Value key() const; + + /// Return the index of the referenced Value, or -1 if it is not an arrayValue. + UInt index() const; + + /// Return the member name of the referenced Value, or "" if it is not an + /// objectValue. + /// \note Avoid `c_str()` on result, as embedded zeroes are possible. + std::string name() const; + + /// Return the member name of the referenced Value. "" if it is not an + /// objectValue. + /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. + JSONCPP_DEPRECATED("Use `key = name();` instead.") + char const* memberName() const; + /// Return the member name of the referenced Value, or NULL if it is not an + /// objectValue. + /// \note Better version than memberName(). Allows embedded nulls. + char const* memberName(char const** end) const; + +protected: + Value& deref() const; + + void increment(); + + void decrement(); + + difference_type computeDistance(const SelfType& other) const; + + bool isEqual(const SelfType& other) const; + + void copy(const SelfType& other); + +private: + Value::ObjectValues::iterator current_; + // Indicates that iterator is for a null value. + bool isNull_; + +public: + // For some reason, BORLAND needs these at the end, rather + // than earlier. No idea why. + ValueIteratorBase(); + explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); +}; + +/** \brief const iterator for object and array value. + * + */ +class JSON_API ValueConstIterator : public ValueIteratorBase { + friend class Value; + +public: + typedef const Value value_type; + //typedef unsigned int size_t; + //typedef int difference_type; + typedef const Value& reference; + typedef const Value* pointer; + typedef ValueConstIterator SelfType; + + ValueConstIterator(); + +private: +/*! \internal Use by Value to create an iterator. + */ + explicit ValueConstIterator(const Value::ObjectValues::iterator& current); +public: + SelfType& operator=(const ValueIteratorBase& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + reference operator*() const { return deref(); } + + pointer operator->() const { return &deref(); } +}; + +/** \brief Iterator for object and array value. + */ +class JSON_API ValueIterator : public ValueIteratorBase { + friend class Value; + +public: + typedef Value value_type; + typedef unsigned int size_t; + typedef int difference_type; + typedef Value& reference; + typedef Value* pointer; + typedef ValueIterator SelfType; + + ValueIterator(); + ValueIterator(const ValueConstIterator& other); + ValueIterator(const ValueIterator& other); + +private: +/*! \internal Use by Value to create an iterator. + */ + explicit ValueIterator(const Value::ObjectValues::iterator& current); +public: + SelfType& operator=(const SelfType& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + reference operator*() const { return deref(); } + + pointer operator->() const { return &deref(); } +}; + +} // namespace Json + + +namespace std { +/// Specialize std::swap() for Json::Value. +template<> +inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); } +} + + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // CPPTL_JSON_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/value.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/reader.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_READER_H_INCLUDED +#define CPPTL_JSON_READER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "features.h" +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include +#include +#include + +// Disable warning C4251: : needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +namespace Json { + +/** \brief Unserialize a JSON document into a + *Value. + * + * \deprecated Use CharReader and CharReaderBuilder. + */ +class JSON_API Reader { +public: + typedef char Char; + typedef const Char* Location; + + /** \brief An error tagged with where in the JSON text it was encountered. + * + * The offsets give the [start, limit) range of bytes within the text. Note + * that this is bytes, not codepoints. + * + */ + struct StructuredError { + size_t offset_start; + size_t offset_limit; + std::string message; + }; + + /** \brief Constructs a Reader allowing all features + * for parsing. + */ + Reader(); + + /** \brief Constructs a Reader allowing the specified feature set + * for parsing. + */ + Reader(const Features& features); + + /** \brief Read a Value from a JSON + * document. + * \param document UTF-8 encoded string containing the document to read. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them + * back during + * serialization, \c false to discard comments. + * This parameter is ignored if + * Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an + * error occurred. + */ + bool + parse(const std::string& document, Value& root, bool collectComments = true); + + /** \brief Read a Value from a JSON + document. + * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the + document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string of the + document to read. + * Must be >= beginDoc. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them + back during + * serialization, \c false to discard comments. + * This parameter is ignored if + Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an + error occurred. + */ + bool parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments = true); + + /// \brief Parse from input stream. + /// \see Json::operator>>(std::istream&, Json::Value&). + bool parse(std::istream& is, Value& root, bool collectComments = true); + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * \return Formatted error message with the list of errors with their location + * in + * the parsed document. An empty string is returned if no error + * occurred + * during parsing. + * \deprecated Use getFormattedErrorMessages() instead (typo fix). + */ + JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") + std::string getFormatedErrorMessages() const; + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * \return Formatted error message with the list of errors with their location + * in + * the parsed document. An empty string is returned if no error + * occurred + * during parsing. + */ + std::string getFormattedErrorMessages() const; + + /** \brief Returns a vector of structured erros encounted while parsing. + * \return A (possibly empty) vector of StructuredError objects. Currently + * only one error can be returned, but the caller should tolerate + * multiple + * errors. This can occur if the parser recovers from a non-fatal + * parse error and then encounters additional errors. + */ + std::vector getStructuredErrors() const; + + /** \brief Add a semantic error message. + * \param value JSON Value location associated with the error + * \param message The error message. + * \return \c true if the error was successfully added, \c false if the + * Value offset exceeds the document size. + */ + bool pushError(const Value& value, const std::string& message); + + /** \brief Add a semantic error message with extra context. + * \param value JSON Value location associated with the error + * \param message The error message. + * \param extra Additional JSON Value location to contextualize the error + * \return \c true if the error was successfully added, \c false if either + * Value offset exceeds the document size. + */ + bool pushError(const Value& value, const std::string& message, const Value& extra); + + /** \brief Return whether there are any errors. + * \return \c true if there are no errors to report \c false if + * errors have occurred. + */ + bool good() const; + +private: + enum TokenType { + tokenEndOfStream = 0, + tokenObjectBegin, + tokenObjectEnd, + tokenArrayBegin, + tokenArrayEnd, + tokenString, + tokenNumber, + tokenTrue, + tokenFalse, + tokenNull, + tokenArraySeparator, + tokenMemberSeparator, + tokenComment, + tokenError + }; + + class Token { + public: + TokenType type_; + Location start_; + Location end_; + }; + + class ErrorInfo { + public: + Token token_; + std::string message_; + Location extra_; + }; + + typedef std::deque Errors; + + bool readToken(Token& token); + void skipSpaces(); + bool match(Location pattern, int patternLength); + bool readComment(); + bool readCStyleComment(); + bool readCppStyleComment(); + bool readString(); + void readNumber(); + bool readValue(); + bool readObject(Token& token); + bool readArray(Token& token); + bool decodeNumber(Token& token); + bool decodeNumber(Token& token, Value& decoded); + bool decodeString(Token& token); + bool decodeString(Token& token, std::string& decoded); + bool decodeDouble(Token& token); + bool decodeDouble(Token& token, Value& decoded); + bool decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool addError(const std::string& message, Token& token, Location extra = 0); + bool recoverFromError(TokenType skipUntilToken); + bool addErrorAndRecover(const std::string& message, + Token& token, + TokenType skipUntilToken); + void skipUntilSpace(); + Value& currentValue(); + Char getNextChar(); + void + getLocationLineAndColumn(Location location, int& line, int& column) const; + std::string getLocationLineAndColumn(Location location) const; + void addComment(Location begin, Location end, CommentPlacement placement); + void skipCommentTokens(Token& token); + + typedef std::stack Nodes; + Nodes nodes_; + Errors errors_; + std::string document_; + Location begin_; + Location end_; + Location current_; + Location lastValueEnd_; + Value* lastValue_; + std::string commentsBefore_; + Features features_; + bool collectComments_; +}; // Reader + +/** Interface for reading JSON from a char array. + */ +class JSON_API CharReader { +public: + virtual ~CharReader() {} + /** \brief Read a Value from a JSON + document. + * The document must be a UTF-8 encoded string containing the document to read. + * + * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the + document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string of the + document to read. + * Must be >= beginDoc. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param errs [out] Formatted error messages (if not NULL) + * a user friendly string that lists errors in the parsed + * document. + * \return \c true if the document was successfully parsed, \c false if an + error occurred. + */ + virtual bool parse( + char const* beginDoc, char const* endDoc, + Value* root, std::string* errs) = 0; + + class Factory { + public: + virtual ~Factory() {} + /** \brief Allocate a CharReader via operator new(). + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + virtual CharReader* newCharReader() const = 0; + }; // Factory +}; // CharReader + +/** \brief Build a CharReader implementation. + +Usage: +\code + using namespace Json; + CharReaderBuilder builder; + builder["collectComments"] = false; + Value value; + std::string errs; + bool ok = parseFromStream(builder, std::cin, &value, &errs); +\endcode +*/ +class JSON_API CharReaderBuilder : public CharReader::Factory { +public: + // Note: We use a Json::Value so that we can add data-members to this class + // without a major version bump. + /** Configuration of this builder. + These are case-sensitive. + Available settings (case-sensitive): + - `"collectComments": false or true` + - true to collect comment and allow writing them + back during serialization, false to discard comments. + This parameter is ignored if allowComments is false. + - `"allowComments": false or true` + - true if comments are allowed. + - `"strictRoot": false or true` + - true if root must be either an array or an object value + - `"allowDroppedNullPlaceholders": false or true` + - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) + - `"allowNumericKeys": false or true` + - true if numeric object keys are allowed. + - `"allowSingleQuotes": false or true` + - true if '' are allowed for strings (both keys and values) + - `"stackLimit": integer` + - Exceeding stackLimit (recursive depth of `readValue()`) will + cause an exception. + - This is a security issue (seg-faults caused by deeply nested JSON), + so the default is low. + - `"failIfExtra": false or true` + - If true, `parse()` returns false when extra non-whitespace trails + the JSON value in the input string. + - `"rejectDupKeys": false or true` + - If true, `parse()` returns false when a key is duplicated within an object. + + You can examine 'settings_` yourself + to see the defaults. You can also write and read them just like any + JSON Value. + \sa setDefaults() + */ + Json::Value settings_; + + CharReaderBuilder(); + virtual ~CharReaderBuilder(); + + virtual CharReader* newCharReader() const; + + /** \return true if 'settings' are legal and consistent; + * otherwise, indicate bad settings via 'invalid'. + */ + bool validate(Json::Value* invalid) const; + + /** A simple way to update a specific setting. + */ + Value& operator[](std::string key); + + /** Called by ctor, but you can use this to reset settings_. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults + */ + static void setDefaults(Json::Value* settings); + /** Same as old Features::strictMode(). + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode + */ + static void strictMode(Json::Value* settings); +}; + +/** Consume entire stream and use its begin/end. + * Someday we might have a real StreamReader, but for now this + * is convenient. + */ +bool JSON_API parseFromStream( + CharReader::Factory const&, + std::istream&, + Value* root, std::string* errs); + +/** \brief Read from 'sin' into 'root'. + + Always keep comments from the input JSON. + + This can be used to read a file into a particular sub-object. + For example: + \code + Json::Value root; + cin >> root["dir"]["file"]; + cout << root; + \endcode + Result: + \verbatim + { + "dir": { + "file": { + // The input stream JSON would be nested here. + } + } + } + \endverbatim + \throw std::exception on parse error. + \see Json::operator<<() +*/ +JSON_API std::istream& operator>>(std::istream&, Value&); + +} // namespace Json + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // CPPTL_JSON_READER_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/reader.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/writer.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_WRITER_H_INCLUDED +#define JSON_WRITER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include + +// Disable warning C4251: : needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +namespace Json { + +class Value; + +/** + +Usage: +\code + using namespace Json; + void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { + std::unique_ptr const writer( + factory.newStreamWriter()); + writer->write(value, &std::cout); + std::cout << std::endl; // add lf and flush + } +\endcode +*/ +class JSON_API StreamWriter { +protected: + std::ostream* sout_; // not owned; will not delete +public: + StreamWriter(); + virtual ~StreamWriter(); + /** Write Value into document as configured in sub-class. + Do not take ownership of sout, but maintain a reference during function. + \pre sout != NULL + \return zero on success (For now, we always return zero, so check the stream instead.) + \throw std::exception possibly, depending on configuration + */ + virtual int write(Value const& root, std::ostream* sout) = 0; + + /** \brief A simple abstract factory. + */ + class JSON_API Factory { + public: + virtual ~Factory(); + /** \brief Allocate a CharReader via operator new(). + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + virtual StreamWriter* newStreamWriter() const = 0; + }; // Factory +}; // StreamWriter + +/** \brief Write into stringstream, then return string, for convenience. + * A StreamWriter will be created from the factory, used, and then deleted. + */ +std::string JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); + + +/** \brief Build a StreamWriter implementation. + +Usage: +\code + using namespace Json; + Value value = ...; + StreamWriterBuilder builder; + builder["commentStyle"] = "None"; + builder["indentation"] = " "; // or whatever you like + std::unique_ptr writer( + builder.newStreamWriter()); + writer->write(value, &std::cout); + std::cout << std::endl; // add lf and flush +\endcode +*/ +class JSON_API StreamWriterBuilder : public StreamWriter::Factory { +public: + // Note: We use a Json::Value so that we can add data-members to this class + // without a major version bump. + /** Configuration of this builder. + Available settings (case-sensitive): + - "commentStyle": "None" or "All" + - "indentation": "" + - "enableYAMLCompatibility": false or true + - slightly change the whitespace around colons + - "dropNullPlaceholders": false or true + - Drop the "null" string from the writer's output for nullValues. + Strictly speaking, this is not valid JSON. But when the output is being + fed to a browser's Javascript, it makes for smaller output and the + browser can handle the output just fine. + + You can examine 'settings_` yourself + to see the defaults. You can also write and read them just like any + JSON Value. + \sa setDefaults() + */ + Json::Value settings_; + + StreamWriterBuilder(); + virtual ~StreamWriterBuilder(); + + /** + * \throw std::exception if something goes wrong (e.g. invalid settings) + */ + virtual StreamWriter* newStreamWriter() const; + + /** \return true if 'settings' are legal and consistent; + * otherwise, indicate bad settings via 'invalid'. + */ + bool validate(Json::Value* invalid) const; + /** A simple way to update a specific setting. + */ + Value& operator[](std::string key); + + /** Called by ctor, but you can use this to reset settings_. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults + */ + static void setDefaults(Json::Value* settings); +}; + +/** \brief Abstract class for writers. + * \deprecated Use StreamWriter. (And really, this is an implementation detail.) + */ +class JSON_API Writer { +public: + virtual ~Writer(); + + virtual std::string write(const Value& root) = 0; +}; + +/** \brief Outputs a Value in JSON format + *without formatting (not human friendly). + * + * The JSON document is written in a single line. It is not intended for 'human' + *consumption, + * but may be usefull to support feature such as RPC where bandwith is limited. + * \sa Reader, Value + * \deprecated Use StreamWriterBuilder. + */ +class JSON_API FastWriter : public Writer { + +public: + FastWriter(); + virtual ~FastWriter() {} + + void enableYAMLCompatibility(); + + /** \brief Drop the "null" string from the writer's output for nullValues. + * Strictly speaking, this is not valid JSON. But when the output is being + * fed to a browser's Javascript, it makes for smaller output and the + * browser can handle the output just fine. + */ + void dropNullPlaceholders(); + + void omitEndingLineFeed(); + +public: // overridden from Writer + virtual std::string write(const Value& root); + +private: + void writeValue(const Value& value); + + std::string document_; + bool yamlCompatiblityEnabled_; + bool dropNullPlaceholders_; + bool omitEndingLineFeed_; +}; + +/** \brief Writes a Value in JSON format in a + *human friendly way. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + *line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + *types, + * and all the values fit on one lines, then print the array on a single + *line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + *#CommentPlacement. + * + * \sa Reader, Value, Value::setComment() + * \deprecated Use StreamWriterBuilder. + */ +class JSON_API StyledWriter : public Writer { +public: + StyledWriter(); + virtual ~StyledWriter() {} + +public: // overridden from Writer + /** \brief Serialize a Value in JSON format. + * \param root Value to serialize. + * \return String containing the JSON document that represents the root value. + */ + virtual std::string write(const Value& root); + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultineArray(const Value& value); + void pushValue(const std::string& value); + void writeIndent(); + void writeWithIndent(const std::string& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + bool hasCommentForValue(const Value& value); + static std::string normalizeEOL(const std::string& text); + + typedef std::vector ChildValues; + + ChildValues childValues_; + std::string document_; + std::string indentString_; + int rightMargin_; + int indentSize_; + bool addChildValues_; +}; + +/** \brief Writes a Value in JSON format in a + human friendly way, + to a stream rather than to a string. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + types, + * and all the values fit on one lines, then print the array on a single + line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + #CommentPlacement. + * + * \param indentation Each level will be indented by this amount extra. + * \sa Reader, Value, Value::setComment() + * \deprecated Use StreamWriterBuilder. + */ +class JSON_API StyledStreamWriter { +public: + StyledStreamWriter(std::string indentation = "\t"); + ~StyledStreamWriter() {} + +public: + /** \brief Serialize a Value in JSON format. + * \param out Stream to write to. (Can be ostringstream, e.g.) + * \param root Value to serialize. + * \note There is no point in deriving from Writer, since write() should not + * return a value. + */ + void write(std::ostream& out, const Value& root); + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultineArray(const Value& value); + void pushValue(const std::string& value); + void writeIndent(); + void writeWithIndent(const std::string& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + bool hasCommentForValue(const Value& value); + static std::string normalizeEOL(const std::string& text); + + typedef std::vector ChildValues; + + ChildValues childValues_; + std::ostream* document_; + std::string indentString_; + int rightMargin_; + std::string indentation_; + bool addChildValues_ : 1; + bool indented_ : 1; +}; + +#if defined(JSON_HAS_INT64) +std::string JSON_API valueToString(Int value); +std::string JSON_API valueToString(UInt value); +#endif // if defined(JSON_HAS_INT64) +std::string JSON_API valueToString(LargestInt value); +std::string JSON_API valueToString(LargestUInt value); +std::string JSON_API valueToString(double value); +std::string JSON_API valueToString(bool value); +std::string JSON_API valueToQuotedString(const char* value); + +/// \brief Output using the StyledStreamWriter. +/// \see Json::operator>>() +JSON_API std::ostream& operator<<(std::ostream&, const Value& root); + +} // namespace Json + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // JSON_WRITER_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/writer.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/assertions.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED +#define CPPTL_JSON_ASSERTIONS_H_INCLUDED + +#include +#include + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +/** It should not be possible for a maliciously designed file to + * cause an abort() or seg-fault, so these macros are used only + * for pre-condition violations and internal logic errors. + */ +#if JSON_USE_EXCEPTION + +// @todo <= add detail about condition in exception +# define JSON_ASSERT(condition) \ + {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} + +# define JSON_FAIL_MESSAGE(message) \ + { \ + std::ostringstream oss; oss << message; \ + Json::throwLogicError(oss.str()); \ + abort(); \ + } + +#else // JSON_USE_EXCEPTION + +# define JSON_ASSERT(condition) assert(condition) + +// The call to assert() will show the failure message in debug builds. In +// release builds we abort, for a core-dump or debugger. +# define JSON_FAIL_MESSAGE(message) \ + { \ + std::ostringstream oss; oss << message; \ + assert(false && oss.str().c_str()); \ + abort(); \ + } + + +#endif + +#define JSON_ASSERT_MESSAGE(condition, message) \ + if (!(condition)) { \ + JSON_FAIL_MESSAGE(message); \ + } + +#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/assertions.h +// ////////////////////////////////////////////////////////////////////// + + + + + +#endif //ifndef JSON_AMALGATED_H_INCLUDED diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/jsoncpp.cpp b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/jsoncpp.cpp new file mode 100644 index 0000000..1304914 --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/jsoncpp/dist/jsoncpp.cpp @@ -0,0 +1,5124 @@ +/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/). +/// It is intended to be used with #include "json/json.h" + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +The author (Baptiste Lepilleur) explicitly disclaims copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is +released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +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 Software. + +THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + + +#include "json/json.h" + +#ifndef JSON_IS_AMALGAMATION +#error "Compile with -I PATH_TO_JSON_DIRECTORY" +#endif + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_tool.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED +#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED + +/* This header provides common string manipulation support, such as UTF-8, + * portable conversion from/to string... + * + * It is an internal header that must not be exposed. + */ + +namespace Json { + +/// Converts a unicode code-point to UTF-8. +static inline std::string codePointToUTF8(unsigned int cp) { + std::string result; + + // based on description from http://en.wikipedia.org/wiki/UTF-8 + + if (cp <= 0x7f) { + result.resize(1); + result[0] = static_cast(cp); + } else if (cp <= 0x7FF) { + result.resize(2); + result[1] = static_cast(0x80 | (0x3f & cp)); + result[0] = static_cast(0xC0 | (0x1f & (cp >> 6))); + } else if (cp <= 0xFFFF) { + result.resize(3); + result[2] = static_cast(0x80 | (0x3f & cp)); + result[1] = 0x80 | static_cast((0x3f & (cp >> 6))); + result[0] = 0xE0 | static_cast((0xf & (cp >> 12))); + } else if (cp <= 0x10FFFF) { + result.resize(4); + result[3] = static_cast(0x80 | (0x3f & cp)); + result[2] = static_cast(0x80 | (0x3f & (cp >> 6))); + result[1] = static_cast(0x80 | (0x3f & (cp >> 12))); + result[0] = static_cast(0xF0 | (0x7 & (cp >> 18))); + } + + return result; +} + +/// Returns true if ch is a control character (in range [0,32[). +static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; } + +enum { + /// Constant that specify the size of the buffer that must be passed to + /// uintToString. + uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1 +}; + +// Defines a char buffer for use with uintToString(). +typedef char UIntToStringBuffer[uintToStringBufferSize]; + +/** Converts an unsigned integer to string. + * @param value Unsigned interger to convert to string + * @param current Input/Output string buffer. + * Must have at least uintToStringBufferSize chars free. + */ +static inline void uintToString(LargestUInt value, char*& current) { + *--current = 0; + do { + *--current = char(value % 10) + '0'; + value /= 10; + } while (value != 0); +} + +/** Change ',' to '.' everywhere in buffer. + * + * We had a sophisticated way, but it did not work in WinCE. + * @see https://github.com/open-source-parsers/jsoncpp/pull/9 + */ +static inline void fixNumericLocale(char* begin, char* end) { + while (begin < end) { + if (*begin == ',') { + *begin = '.'; + } + ++begin; + } +} + +} // namespace Json { + +#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_tool.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_reader.cpp +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2011 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include +#include "json_tool.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below +#define snprintf _snprintf +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 +// Disable warning about strdup being deprecated. +#pragma warning(disable : 4996) +#endif + +static int const stackLimit_g = 1000; +static int stackDepth_g = 0; // see readValue() + +namespace Json { + +#if __cplusplus >= 201103L +typedef std::unique_ptr CharReaderPtr; +#else +typedef std::auto_ptr CharReaderPtr; +#endif + +// Implementation of class Features +// //////////////////////////////// + +Features::Features() + : allowComments_(true), strictRoot_(false), + allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} + +Features Features::all() { return Features(); } + +Features Features::strictMode() { + Features features; + features.allowComments_ = false; + features.strictRoot_ = true; + features.allowDroppedNullPlaceholders_ = false; + features.allowNumericKeys_ = false; + return features; +} + +// Implementation of class Reader +// //////////////////////////////// + +static bool containsNewLine(Reader::Location begin, Reader::Location end) { + for (; begin < end; ++begin) + if (*begin == '\n' || *begin == '\r') + return true; + return false; +} + +// Class Reader +// ////////////////////////////////////////////////////////////////// + +Reader::Reader() + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(Features::all()), + collectComments_() {} + +Reader::Reader(const Features& features) + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(features), collectComments_() { +} + +bool +Reader::parse(const std::string& document, Value& root, bool collectComments) { + document_ = document; + const char* begin = document_.c_str(); + const char* end = begin + document_.length(); + return parse(begin, end, root, collectComments); +} + +bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { + // std::istream_iterator begin(sin); + // std::istream_iterator end; + // Those would allow streamed input from a file, if parse() were a + // template function. + + // Since std::string is reference-counted, this at least does not + // create an extra copy. + std::string doc; + std::getline(sin, doc, (char)EOF); + return parse(doc, root, collectComments); +} + +bool Reader::parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments) { + if (!features_.allowComments_) { + collectComments = false; + } + + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = 0; + lastValue_ = 0; + commentsBefore_ = ""; + errors_.clear(); + while (!nodes_.empty()) + nodes_.pop(); + nodes_.push(&root); + + stackDepth_g = 0; // Yes, this is bad coding, but options are limited. + bool successful = readValue(); + Token token; + skipCommentTokens(token); + if (collectComments_ && !commentsBefore_.empty()) + root.setComment(commentsBefore_, commentAfter); + if (features_.strictRoot_) { + if (!root.isArray() && !root.isObject()) { + // Set error location to start of doc, ideally should be first token found + // in doc + token.type_ = tokenError; + token.start_ = beginDoc; + token.end_ = endDoc; + addError( + "A valid JSON document must be either an array or an object value.", + token); + return false; + } + } + return successful; +} + +bool Reader::readValue() { + // This is a non-reentrant way to support a stackLimit. Terrible! + // But this deprecated class has a security problem: Bad input can + // cause a seg-fault. This seems like a fair, binary-compatible way + // to prevent the problem. + if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue()."); + ++stackDepth_g; + + Token token; + skipCommentTokens(token); + bool successful = true; + + if (collectComments_ && !commentsBefore_.empty()) { + currentValue().setComment(commentsBefore_, commentBefore); + commentsBefore_ = ""; + } + + switch (token.type_) { + case tokenObjectBegin: + successful = readObject(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenArrayBegin: + successful = readArray(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenNumber: + successful = decodeNumber(token); + break; + case tokenString: + successful = decodeString(token); + break; + case tokenTrue: + { + Value v(true); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenFalse: + { + Value v(false); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenNull: + { + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } // Else, fall through... + default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return addError("Syntax error: value, object or array expected.", token); + } + + if (collectComments_) { + lastValueEnd_ = current_; + lastValue_ = ¤tValue(); + } + + --stackDepth_g; + return successful; +} + +void Reader::skipCommentTokens(Token& token) { + if (features_.allowComments_) { + do { + readToken(token); + } while (token.type_ == tokenComment); + } else { + readToken(token); + } +} + +bool Reader::readToken(Token& token) { + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); + bool ok = true; + switch (c) { + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + token.type_ = tokenNumber; + readNumber(); + break; + case 't': + token.type_ = tokenTrue; + ok = match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = match("ull", 3); + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; + } + if (!ok) + token.type_ = tokenError; + token.end_ = current_; + return true; +} + +void Reader::skipSpaces() { + while (current_ != end_) { + Char c = *current_; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n') + ++current_; + else + break; + } +} + +bool Reader::match(Location pattern, int patternLength) { + if (end_ - current_ < patternLength) + return false; + int index = patternLength; + while (index--) + if (current_[index] != pattern[index]) + return false; + current_ += patternLength; + return true; +} + +bool Reader::readComment() { + Location commentBegin = current_ - 1; + Char c = getNextChar(); + bool successful = false; + if (c == '*') + successful = readCStyleComment(); + else if (c == '/') + successful = readCppStyleComment(); + if (!successful) + return false; + + if (collectComments_) { + CommentPlacement placement = commentBefore; + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, current_)) + placement = commentAfterOnSameLine; + } + + addComment(commentBegin, current_, placement); + } + return true; +} + +static std::string normalizeEOL(Reader::Location begin, Reader::Location end) { + std::string normalized; + normalized.reserve(end - begin); + Reader::Location current = begin; + while (current != end) { + char c = *current++; + if (c == '\r') { + if (current != end && *current == '\n') + // convert dos EOL + ++current; + // convert Mac EOL + normalized += '\n'; + } else { + normalized += c; + } + } + return normalized; +} + +void +Reader::addComment(Location begin, Location end, CommentPlacement placement) { + assert(collectComments_); + const std::string& normalized = normalizeEOL(begin, end); + if (placement == commentAfterOnSameLine) { + assert(lastValue_ != 0); + lastValue_->setComment(normalized, placement); + } else { + commentsBefore_ += normalized; + } +} + +bool Reader::readCStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '*' && *current_ == '/') + break; + } + return getNextChar() == '/'; +} + +bool Reader::readCppStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '\n') + break; + if (c == '\r') { + // Consume DOS EOL. It will be normalized in addComment. + if (current_ != end_ && *current_ == '\n') + getNextChar(); + // Break on Moc OS 9 EOL. + break; + } + } + return true; +} + +void Reader::readNumber() { + const char *p = current_; + char c = '0'; // stopgap for already consumed character + // integral part + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : 0; + // fractional part + if (c == '.') { + c = (current_ = p) < end_ ? *p++ : 0; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : 0; + } + // exponential part + if (c == 'e' || c == 'E') { + c = (current_ = p) < end_ ? *p++ : 0; + if (c == '+' || c == '-') + c = (current_ = p) < end_ ? *p++ : 0; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : 0; + } +} + +bool Reader::readString() { + Char c = 0; + while (current_ != end_) { + c = getNextChar(); + if (c == '\\') + getNextChar(); + else if (c == '"') + break; + } + return c == '"'; +} + +bool Reader::readObject(Token& tokenStart) { + Token tokenName; + std::string name; + Value init(objectValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + while (readToken(tokenName)) { + bool initialTokenOk = true; + while (tokenName.type_ == tokenComment && initialTokenOk) + initialTokenOk = readToken(tokenName); + if (!initialTokenOk) + break; + if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object + return true; + name = ""; + if (tokenName.type_ == tokenString) { + if (!decodeString(tokenName, name)) + return recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { + Value numberName; + if (!decodeNumber(tokenName, numberName)) + return recoverFromError(tokenObjectEnd); + name = numberName.asString(); + } else { + break; + } + + Token colon; + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover( + "Missing ':' after object member name", colon, tokenObjectEnd); + } + Value& value = currentValue()[name]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenObjectEnd); + + Token comma; + if (!readToken(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && + comma.type_ != tokenComment)) { + return addErrorAndRecover( + "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + } + bool finalizeTokenOk = true; + while (comma.type_ == tokenComment && finalizeTokenOk) + finalizeTokenOk = readToken(comma); + if (comma.type_ == tokenObjectEnd) + return true; + } + return addErrorAndRecover( + "Missing '}' or object member name", tokenName, tokenObjectEnd); +} + +bool Reader::readArray(Token& tokenStart) { + Value init(arrayValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + skipSpaces(); + if (*current_ == ']') // empty array + { + Token endArray; + readToken(endArray); + return true; + } + int index = 0; + for (;;) { + Value& value = currentValue()[index++]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenArrayEnd); + + Token token; + // Accept Comment after last item in the array. + ok = readToken(token); + while (token.type_ == tokenComment && ok) { + ok = readToken(token); + } + bool badTokenType = + (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + if (!ok || badTokenType) { + return addErrorAndRecover( + "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + } + if (token.type_ == tokenArrayEnd) + break; + } + return true; +} + +bool Reader::decodeNumber(Token& token) { + Value decoded; + if (!decodeNumber(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeNumber(Token& token, Value& decoded) { + // Attempts to parse the number as an integer. If the number is + // larger than the maximum supported value of an integer then + // we decode the number as a double. + Location current = token.start_; + bool isNegative = *current == '-'; + if (isNegative) + ++current; + // TODO: Help the compiler do the div and mod at compile time or get rid of them. + Value::LargestUInt maxIntegerValue = + isNegative ? Value::LargestUInt(-Value::minLargestInt) + : Value::maxLargestUInt; + Value::LargestUInt threshold = maxIntegerValue / 10; + Value::LargestUInt value = 0; + while (current < token.end_) { + Char c = *current++; + if (c < '0' || c > '9') + return decodeDouble(token, decoded); + Value::UInt digit(c - '0'); + if (value >= threshold) { + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, b) this is the last digit, and + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || current != token.end_ || + digit > maxIntegerValue % 10) { + return decodeDouble(token, decoded); + } + } + value = value * 10 + digit; + } + if (isNegative) + decoded = -Value::LargestInt(value); + else if (value <= Value::LargestUInt(Value::maxInt)) + decoded = Value::LargestInt(value); + else + decoded = value; + return true; +} + +bool Reader::decodeDouble(Token& token) { + Value decoded; + if (!decodeDouble(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeDouble(Token& token, Value& decoded) { + double value = 0; + const int bufferSize = 32; + int count; + int length = int(token.end_ - token.start_); + + // Sanity check to avoid buffer overflow exploits. + if (length < 0) { + return addError("Unable to parse token length", token); + } + + // Avoid using a string constant for the format control string given to + // sscanf, as this can cause hard to debug crashes on OS X. See here for more + // info: + // + // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html + char format[] = "%lf"; + + if (length <= bufferSize) { + Char buffer[bufferSize + 1]; + memcpy(buffer, token.start_, length); + buffer[length] = 0; + count = sscanf(buffer, format, &value); + } else { + std::string buffer(token.start_, token.end_); + count = sscanf(buffer.c_str(), format, &value); + } + + if (count != 1) + return addError("'" + std::string(token.start_, token.end_) + + "' is not a number.", + token); + decoded = value; + return true; +} + +bool Reader::decodeString(Token& token) { + std::string decoded_string; + if (!decodeString(token, decoded_string)) + return false; + Value decoded(decoded_string); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeString(Token& token, std::string& decoded) { + decoded.reserve(token.end_ - token.start_ - 2); + Location current = token.start_ + 1; // skip '"' + Location end = token.end_ - 1; // do not include '"' + while (current != end) { + Char c = *current++; + if (c == '"') + break; + else if (c == '\\') { + if (current == end) + return addError("Empty escape sequence in string", token, current); + Char escape = *current++; + switch (escape) { + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return addError("Bad escape sequence in string", token, current); + } + } else { + decoded += c; + } + } + return true; +} + +bool Reader::decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode) { + + if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) + return false; + if (unicode >= 0xD800 && unicode <= 0xDBFF) { + // surrogate pairs + if (end - current < 6) + return addError( + "additional six characters expected to parse unicode surrogate pair.", + token, + current); + unsigned int surrogatePair; + if (*(current++) == '\\' && *(current++) == 'u') { + if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + } else + return false; + } else + return addError("expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, + current); + } + return true; +} + +bool Reader::decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode) { + if (end - current < 4) + return addError( + "Bad unicode escape sequence in string: four digits expected.", + token, + current); + unicode = 0; + for (int index = 0; index < 4; ++index) { + Char c = *current++; + unicode *= 16; + if (c >= '0' && c <= '9') + unicode += c - '0'; + else if (c >= 'a' && c <= 'f') + unicode += c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + unicode += c - 'A' + 10; + else + return addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, + current); + } + return true; +} + +bool +Reader::addError(const std::string& message, Token& token, Location extra) { + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = extra; + errors_.push_back(info); + return false; +} + +bool Reader::recoverFromError(TokenType skipUntilToken) { + int errorCount = int(errors_.size()); + Token skip; + for (;;) { + if (!readToken(skip)) + errors_.resize(errorCount); // discard errors caused by recovery + if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) + break; + } + errors_.resize(errorCount); + return false; +} + +bool Reader::addErrorAndRecover(const std::string& message, + Token& token, + TokenType skipUntilToken) { + addError(message, token); + return recoverFromError(skipUntilToken); +} + +Value& Reader::currentValue() { return *(nodes_.top()); } + +Reader::Char Reader::getNextChar() { + if (current_ == end_) + return 0; + return *current_++; +} + +void Reader::getLocationLineAndColumn(Location location, + int& line, + int& column) const { + Location current = begin_; + Location lastLineStart = current; + line = 0; + while (current < location && current != end_) { + Char c = *current++; + if (c == '\r') { + if (*current == '\n') + ++current; + lastLineStart = current; + ++line; + } else if (c == '\n') { + lastLineStart = current; + ++line; + } + } + // column & line start at 1 + column = int(location - lastLineStart) + 1; + ++line; +} + +std::string Reader::getLocationLineAndColumn(Location location) const { + int line, column; + getLocationLineAndColumn(location, line, column); + char buffer[18 + 16 + 16 + 1]; +#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) +#if defined(WINCE) + _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#else + sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#endif +#else + snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#endif + return buffer; +} + +// Deprecated. Preserved for backward compatibility +std::string Reader::getFormatedErrorMessages() const { + return getFormattedErrorMessages(); +} + +std::string Reader::getFormattedErrorMessages() const { + std::string formattedMessage; + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { + const ErrorInfo& error = *itError; + formattedMessage += + "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; + formattedMessage += " " + error.message_ + "\n"; + if (error.extra_) + formattedMessage += + "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; + } + return formattedMessage; +} + +std::vector Reader::getStructuredErrors() const { + std::vector allErrors; + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { + const ErrorInfo& error = *itError; + Reader::StructuredError structured; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; + structured.message = error.message_; + allErrors.push_back(structured); + } + return allErrors; +} + +bool Reader::pushError(const Value& value, const std::string& message) { + size_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = end_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = 0; + errors_.push_back(info); + return true; +} + +bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) { + size_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length + || extra.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = begin_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = begin_ + extra.getOffsetStart(); + errors_.push_back(info); + return true; +} + +bool Reader::good() const { + return !errors_.size(); +} + +// exact copy of Features +class OurFeatures { +public: + static OurFeatures all(); + OurFeatures(); + bool allowComments_; + bool strictRoot_; + bool allowDroppedNullPlaceholders_; + bool allowNumericKeys_; + bool allowSingleQuotes_; + bool failIfExtra_; + bool rejectDupKeys_; + int stackLimit_; +}; // OurFeatures + +// exact copy of Implementation of class Features +// //////////////////////////////// + +OurFeatures::OurFeatures() + : allowComments_(true), strictRoot_(false) + , allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) + , allowSingleQuotes_(false) + , failIfExtra_(false) +{ +} + +OurFeatures OurFeatures::all() { return OurFeatures(); } + +// Implementation of class Reader +// //////////////////////////////// + +// exact copy of Reader, renamed to OurReader +class OurReader { +public: + typedef char Char; + typedef const Char* Location; + struct StructuredError { + size_t offset_start; + size_t offset_limit; + std::string message; + }; + + OurReader(OurFeatures const& features); + bool parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments = true); + std::string getFormattedErrorMessages() const; + std::vector getStructuredErrors() const; + bool pushError(const Value& value, const std::string& message); + bool pushError(const Value& value, const std::string& message, const Value& extra); + bool good() const; + +private: + OurReader(OurReader const&); // no impl + void operator=(OurReader const&); // no impl + + enum TokenType { + tokenEndOfStream = 0, + tokenObjectBegin, + tokenObjectEnd, + tokenArrayBegin, + tokenArrayEnd, + tokenString, + tokenNumber, + tokenTrue, + tokenFalse, + tokenNull, + tokenArraySeparator, + tokenMemberSeparator, + tokenComment, + tokenError + }; + + class Token { + public: + TokenType type_; + Location start_; + Location end_; + }; + + class ErrorInfo { + public: + Token token_; + std::string message_; + Location extra_; + }; + + typedef std::deque Errors; + + bool readToken(Token& token); + void skipSpaces(); + bool match(Location pattern, int patternLength); + bool readComment(); + bool readCStyleComment(); + bool readCppStyleComment(); + bool readString(); + bool readStringSingleQuote(); + void readNumber(); + bool readValue(); + bool readObject(Token& token); + bool readArray(Token& token); + bool decodeNumber(Token& token); + bool decodeNumber(Token& token, Value& decoded); + bool decodeString(Token& token); + bool decodeString(Token& token, std::string& decoded); + bool decodeDouble(Token& token); + bool decodeDouble(Token& token, Value& decoded); + bool decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool addError(const std::string& message, Token& token, Location extra = 0); + bool recoverFromError(TokenType skipUntilToken); + bool addErrorAndRecover(const std::string& message, + Token& token, + TokenType skipUntilToken); + void skipUntilSpace(); + Value& currentValue(); + Char getNextChar(); + void + getLocationLineAndColumn(Location location, int& line, int& column) const; + std::string getLocationLineAndColumn(Location location) const; + void addComment(Location begin, Location end, CommentPlacement placement); + void skipCommentTokens(Token& token); + + typedef std::stack Nodes; + Nodes nodes_; + Errors errors_; + std::string document_; + Location begin_; + Location end_; + Location current_; + Location lastValueEnd_; + Value* lastValue_; + std::string commentsBefore_; + int stackDepth_; + + OurFeatures const features_; + bool collectComments_; +}; // OurReader + +// complete copy of Read impl, for OurReader + +OurReader::OurReader(OurFeatures const& features) + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(features), collectComments_() { +} + +bool OurReader::parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments) { + if (!features_.allowComments_) { + collectComments = false; + } + + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = 0; + lastValue_ = 0; + commentsBefore_ = ""; + errors_.clear(); + while (!nodes_.empty()) + nodes_.pop(); + nodes_.push(&root); + + stackDepth_ = 0; + bool successful = readValue(); + Token token; + skipCommentTokens(token); + if (features_.failIfExtra_) { + if (token.type_ != tokenError && token.type_ != tokenEndOfStream) { + addError("Extra non-whitespace after JSON value.", token); + return false; + } + } + if (collectComments_ && !commentsBefore_.empty()) + root.setComment(commentsBefore_, commentAfter); + if (features_.strictRoot_) { + if (!root.isArray() && !root.isObject()) { + // Set error location to start of doc, ideally should be first token found + // in doc + token.type_ = tokenError; + token.start_ = beginDoc; + token.end_ = endDoc; + addError( + "A valid JSON document must be either an array or an object value.", + token); + return false; + } + } + return successful; +} + +bool OurReader::readValue() { + if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); + ++stackDepth_; + Token token; + skipCommentTokens(token); + bool successful = true; + + if (collectComments_ && !commentsBefore_.empty()) { + currentValue().setComment(commentsBefore_, commentBefore); + commentsBefore_ = ""; + } + + switch (token.type_) { + case tokenObjectBegin: + successful = readObject(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenArrayBegin: + successful = readArray(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenNumber: + successful = decodeNumber(token); + break; + case tokenString: + successful = decodeString(token); + break; + case tokenTrue: + { + Value v(true); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenFalse: + { + Value v(false); + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenNull: + { + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + } + break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; + Value v; + currentValue().swapPayload(v); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } // else, fall through ... + default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return addError("Syntax error: value, object or array expected.", token); + } + + if (collectComments_) { + lastValueEnd_ = current_; + lastValue_ = ¤tValue(); + } + + --stackDepth_; + return successful; +} + +void OurReader::skipCommentTokens(Token& token) { + if (features_.allowComments_) { + do { + readToken(token); + } while (token.type_ == tokenComment); + } else { + readToken(token); + } +} + +bool OurReader::readToken(Token& token) { + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); + bool ok = true; + switch (c) { + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '\'': + if (features_.allowSingleQuotes_) { + token.type_ = tokenString; + ok = readStringSingleQuote(); + break; + } // else continue + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + token.type_ = tokenNumber; + readNumber(); + break; + case 't': + token.type_ = tokenTrue; + ok = match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = match("ull", 3); + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; + } + if (!ok) + token.type_ = tokenError; + token.end_ = current_; + return true; +} + +void OurReader::skipSpaces() { + while (current_ != end_) { + Char c = *current_; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n') + ++current_; + else + break; + } +} + +bool OurReader::match(Location pattern, int patternLength) { + if (end_ - current_ < patternLength) + return false; + int index = patternLength; + while (index--) + if (current_[index] != pattern[index]) + return false; + current_ += patternLength; + return true; +} + +bool OurReader::readComment() { + Location commentBegin = current_ - 1; + Char c = getNextChar(); + bool successful = false; + if (c == '*') + successful = readCStyleComment(); + else if (c == '/') + successful = readCppStyleComment(); + if (!successful) + return false; + + if (collectComments_) { + CommentPlacement placement = commentBefore; + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, current_)) + placement = commentAfterOnSameLine; + } + + addComment(commentBegin, current_, placement); + } + return true; +} + +void +OurReader::addComment(Location begin, Location end, CommentPlacement placement) { + assert(collectComments_); + const std::string& normalized = normalizeEOL(begin, end); + if (placement == commentAfterOnSameLine) { + assert(lastValue_ != 0); + lastValue_->setComment(normalized, placement); + } else { + commentsBefore_ += normalized; + } +} + +bool OurReader::readCStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '*' && *current_ == '/') + break; + } + return getNextChar() == '/'; +} + +bool OurReader::readCppStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '\n') + break; + if (c == '\r') { + // Consume DOS EOL. It will be normalized in addComment. + if (current_ != end_ && *current_ == '\n') + getNextChar(); + // Break on Moc OS 9 EOL. + break; + } + } + return true; +} + +void OurReader::readNumber() { + const char *p = current_; + char c = '0'; // stopgap for already consumed character + // integral part + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : 0; + // fractional part + if (c == '.') { + c = (current_ = p) < end_ ? *p++ : 0; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : 0; + } + // exponential part + if (c == 'e' || c == 'E') { + c = (current_ = p) < end_ ? *p++ : 0; + if (c == '+' || c == '-') + c = (current_ = p) < end_ ? *p++ : 0; + while (c >= '0' && c <= '9') + c = (current_ = p) < end_ ? *p++ : 0; + } +} +bool OurReader::readString() { + Char c = 0; + while (current_ != end_) { + c = getNextChar(); + if (c == '\\') + getNextChar(); + else if (c == '"') + break; + } + return c == '"'; +} + + +bool OurReader::readStringSingleQuote() { + Char c = 0; + while (current_ != end_) { + c = getNextChar(); + if (c == '\\') + getNextChar(); + else if (c == '\'') + break; + } + return c == '\''; +} + +bool OurReader::readObject(Token& tokenStart) { + Token tokenName; + std::string name; + Value init(objectValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + while (readToken(tokenName)) { + bool initialTokenOk = true; + while (tokenName.type_ == tokenComment && initialTokenOk) + initialTokenOk = readToken(tokenName); + if (!initialTokenOk) + break; + if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object + return true; + name = ""; + if (tokenName.type_ == tokenString) { + if (!decodeString(tokenName, name)) + return recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { + Value numberName; + if (!decodeNumber(tokenName, numberName)) + return recoverFromError(tokenObjectEnd); + name = numberName.asString(); + } else { + break; + } + + Token colon; + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover( + "Missing ':' after object member name", colon, tokenObjectEnd); + } + if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30"); + if (features_.rejectDupKeys_ && currentValue().isMember(name)) { + std::string msg = "Duplicate key: '" + name + "'"; + return addErrorAndRecover( + msg, tokenName, tokenObjectEnd); + } + Value& value = currentValue()[name]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenObjectEnd); + + Token comma; + if (!readToken(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && + comma.type_ != tokenComment)) { + return addErrorAndRecover( + "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + } + bool finalizeTokenOk = true; + while (comma.type_ == tokenComment && finalizeTokenOk) + finalizeTokenOk = readToken(comma); + if (comma.type_ == tokenObjectEnd) + return true; + } + return addErrorAndRecover( + "Missing '}' or object member name", tokenName, tokenObjectEnd); +} + +bool OurReader::readArray(Token& tokenStart) { + Value init(arrayValue); + currentValue().swapPayload(init); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + skipSpaces(); + if (*current_ == ']') // empty array + { + Token endArray; + readToken(endArray); + return true; + } + int index = 0; + for (;;) { + Value& value = currentValue()[index++]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenArrayEnd); + + Token token; + // Accept Comment after last item in the array. + ok = readToken(token); + while (token.type_ == tokenComment && ok) { + ok = readToken(token); + } + bool badTokenType = + (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + if (!ok || badTokenType) { + return addErrorAndRecover( + "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + } + if (token.type_ == tokenArrayEnd) + break; + } + return true; +} + +bool OurReader::decodeNumber(Token& token) { + Value decoded; + if (!decodeNumber(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool OurReader::decodeNumber(Token& token, Value& decoded) { + // Attempts to parse the number as an integer. If the number is + // larger than the maximum supported value of an integer then + // we decode the number as a double. + Location current = token.start_; + bool isNegative = *current == '-'; + if (isNegative) + ++current; + // TODO: Help the compiler do the div and mod at compile time or get rid of them. + Value::LargestUInt maxIntegerValue = + isNegative ? Value::LargestUInt(-Value::minLargestInt) + : Value::maxLargestUInt; + Value::LargestUInt threshold = maxIntegerValue / 10; + Value::LargestUInt value = 0; + while (current < token.end_) { + Char c = *current++; + if (c < '0' || c > '9') + return decodeDouble(token, decoded); + Value::UInt digit(c - '0'); + if (value >= threshold) { + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, b) this is the last digit, and + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || current != token.end_ || + digit > maxIntegerValue % 10) { + return decodeDouble(token, decoded); + } + } + value = value * 10 + digit; + } + if (isNegative) + decoded = -Value::LargestInt(value); + else if (value <= Value::LargestUInt(Value::maxInt)) + decoded = Value::LargestInt(value); + else + decoded = value; + return true; +} + +bool OurReader::decodeDouble(Token& token) { + Value decoded; + if (!decodeDouble(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool OurReader::decodeDouble(Token& token, Value& decoded) { + double value = 0; + const int bufferSize = 32; + int count; + int length = int(token.end_ - token.start_); + + // Sanity check to avoid buffer overflow exploits. + if (length < 0) { + return addError("Unable to parse token length", token); + } + + // Avoid using a string constant for the format control string given to + // sscanf, as this can cause hard to debug crashes on OS X. See here for more + // info: + // + // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html + char format[] = "%lf"; + + if (length <= bufferSize) { + Char buffer[bufferSize + 1]; + memcpy(buffer, token.start_, length); + buffer[length] = 0; + count = sscanf(buffer, format, &value); + } else { + std::string buffer(token.start_, token.end_); + count = sscanf(buffer.c_str(), format, &value); + } + + if (count != 1) + return addError("'" + std::string(token.start_, token.end_) + + "' is not a number.", + token); + decoded = value; + return true; +} + +bool OurReader::decodeString(Token& token) { + std::string decoded_string; + if (!decodeString(token, decoded_string)) + return false; + Value decoded(decoded_string); + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool OurReader::decodeString(Token& token, std::string& decoded) { + decoded.reserve(token.end_ - token.start_ - 2); + Location current = token.start_ + 1; // skip '"' + Location end = token.end_ - 1; // do not include '"' + while (current != end) { + Char c = *current++; + if (c == '"') + break; + else if (c == '\\') { + if (current == end) + return addError("Empty escape sequence in string", token, current); + Char escape = *current++; + switch (escape) { + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return addError("Bad escape sequence in string", token, current); + } + } else { + decoded += c; + } + } + return true; +} + +bool OurReader::decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode) { + + if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) + return false; + if (unicode >= 0xD800 && unicode <= 0xDBFF) { + // surrogate pairs + if (end - current < 6) + return addError( + "additional six characters expected to parse unicode surrogate pair.", + token, + current); + unsigned int surrogatePair; + if (*(current++) == '\\' && *(current++) == 'u') { + if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + } else + return false; + } else + return addError("expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, + current); + } + return true; +} + +bool OurReader::decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode) { + if (end - current < 4) + return addError( + "Bad unicode escape sequence in string: four digits expected.", + token, + current); + unicode = 0; + for (int index = 0; index < 4; ++index) { + Char c = *current++; + unicode *= 16; + if (c >= '0' && c <= '9') + unicode += c - '0'; + else if (c >= 'a' && c <= 'f') + unicode += c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + unicode += c - 'A' + 10; + else + return addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, + current); + } + return true; +} + +bool +OurReader::addError(const std::string& message, Token& token, Location extra) { + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = extra; + errors_.push_back(info); + return false; +} + +bool OurReader::recoverFromError(TokenType skipUntilToken) { + int errorCount = int(errors_.size()); + Token skip; + for (;;) { + if (!readToken(skip)) + errors_.resize(errorCount); // discard errors caused by recovery + if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) + break; + } + errors_.resize(errorCount); + return false; +} + +bool OurReader::addErrorAndRecover(const std::string& message, + Token& token, + TokenType skipUntilToken) { + addError(message, token); + return recoverFromError(skipUntilToken); +} + +Value& OurReader::currentValue() { return *(nodes_.top()); } + +OurReader::Char OurReader::getNextChar() { + if (current_ == end_) + return 0; + return *current_++; +} + +void OurReader::getLocationLineAndColumn(Location location, + int& line, + int& column) const { + Location current = begin_; + Location lastLineStart = current; + line = 0; + while (current < location && current != end_) { + Char c = *current++; + if (c == '\r') { + if (*current == '\n') + ++current; + lastLineStart = current; + ++line; + } else if (c == '\n') { + lastLineStart = current; + ++line; + } + } + // column & line start at 1 + column = int(location - lastLineStart) + 1; + ++line; +} + +std::string OurReader::getLocationLineAndColumn(Location location) const { + int line, column; + getLocationLineAndColumn(location, line, column); + char buffer[18 + 16 + 16 + 1]; +#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) +#if defined(WINCE) + _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#else + sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#endif +#else + snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#endif + return buffer; +} + +std::string OurReader::getFormattedErrorMessages() const { + std::string formattedMessage; + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { + const ErrorInfo& error = *itError; + formattedMessage += + "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; + formattedMessage += " " + error.message_ + "\n"; + if (error.extra_) + formattedMessage += + "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; + } + return formattedMessage; +} + +std::vector OurReader::getStructuredErrors() const { + std::vector allErrors; + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { + const ErrorInfo& error = *itError; + OurReader::StructuredError structured; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; + structured.message = error.message_; + allErrors.push_back(structured); + } + return allErrors; +} + +bool OurReader::pushError(const Value& value, const std::string& message) { + size_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = end_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = 0; + errors_.push_back(info); + return true; +} + +bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) { + size_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length + || extra.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = begin_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = begin_ + extra.getOffsetStart(); + errors_.push_back(info); + return true; +} + +bool OurReader::good() const { + return !errors_.size(); +} + + +class OurCharReader : public CharReader { + bool const collectComments_; + OurReader reader_; +public: + OurCharReader( + bool collectComments, + OurFeatures const& features) + : collectComments_(collectComments) + , reader_(features) + {} + virtual bool parse( + char const* beginDoc, char const* endDoc, + Value* root, std::string* errs) { + bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); + if (errs) { + *errs = reader_.getFormattedErrorMessages(); + } + return ok; + } +}; + +CharReaderBuilder::CharReaderBuilder() +{ + setDefaults(&settings_); +} +CharReaderBuilder::~CharReaderBuilder() +{} +CharReader* CharReaderBuilder::newCharReader() const +{ + bool collectComments = settings_["collectComments"].asBool(); + OurFeatures features = OurFeatures::all(); + features.allowComments_ = settings_["allowComments"].asBool(); + features.strictRoot_ = settings_["strictRoot"].asBool(); + features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); + features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); + features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); + features.stackLimit_ = settings_["stackLimit"].asInt(); + features.failIfExtra_ = settings_["failIfExtra"].asBool(); + features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); + return new OurCharReader(collectComments, features); +} +static void getValidReaderKeys(std::set* valid_keys) +{ + valid_keys->clear(); + valid_keys->insert("collectComments"); + valid_keys->insert("allowComments"); + valid_keys->insert("strictRoot"); + valid_keys->insert("allowDroppedNullPlaceholders"); + valid_keys->insert("allowNumericKeys"); + valid_keys->insert("allowSingleQuotes"); + valid_keys->insert("stackLimit"); + valid_keys->insert("failIfExtra"); + valid_keys->insert("rejectDupKeys"); +} +bool CharReaderBuilder::validate(Json::Value* invalid) const +{ + Json::Value my_invalid; + if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL + Json::Value& inv = *invalid; + std::set valid_keys; + getValidReaderKeys(&valid_keys); + Value::Members keys = settings_.getMemberNames(); + size_t n = keys.size(); + for (size_t i = 0; i < n; ++i) { + std::string const& key = keys[i]; + if (valid_keys.find(key) == valid_keys.end()) { + inv[key] = settings_[key]; + } + } + return 0u == inv.size(); +} +Value& CharReaderBuilder::operator[](std::string key) +{ + return settings_[key]; +} +// static +void CharReaderBuilder::strictMode(Json::Value* settings) +{ +//! [CharReaderBuilderStrictMode] + (*settings)["allowComments"] = false; + (*settings)["strictRoot"] = true; + (*settings)["allowDroppedNullPlaceholders"] = false; + (*settings)["allowNumericKeys"] = false; + (*settings)["allowSingleQuotes"] = false; + (*settings)["failIfExtra"] = true; + (*settings)["rejectDupKeys"] = true; +//! [CharReaderBuilderStrictMode] +} +// static +void CharReaderBuilder::setDefaults(Json::Value* settings) +{ +//! [CharReaderBuilderDefaults] + (*settings)["collectComments"] = true; + (*settings)["allowComments"] = true; + (*settings)["strictRoot"] = false; + (*settings)["allowDroppedNullPlaceholders"] = false; + (*settings)["allowNumericKeys"] = false; + (*settings)["allowSingleQuotes"] = false; + (*settings)["stackLimit"] = 1000; + (*settings)["failIfExtra"] = false; + (*settings)["rejectDupKeys"] = false; +//! [CharReaderBuilderDefaults] +} + +////////////////////////////////// +// global functions + +bool parseFromStream( + CharReader::Factory const& fact, std::istream& sin, + Value* root, std::string* errs) +{ + std::ostringstream ssin; + ssin << sin.rdbuf(); + std::string doc = ssin.str(); + char const* begin = doc.data(); + char const* end = begin + doc.size(); + // Note that we do not actually need a null-terminator. + CharReaderPtr const reader(fact.newCharReader()); + return reader->parse(begin, end, root, errs); +} + +std::istream& operator>>(std::istream& sin, Value& root) { + CharReaderBuilder b; + std::string errs; + bool ok = parseFromStream(b, sin, &root, &errs); + if (!ok) { + fprintf(stderr, + "Error from reader: %s", + errs.c_str()); + + throwRuntimeError("reader error"); + } + return sin; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_reader.cpp +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_valueiterator.inl +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +// included by json_value.cpp + +namespace Json { + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIteratorBase +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIteratorBase::ValueIteratorBase() + : current_(), isNull_(true) { +} + +ValueIteratorBase::ValueIteratorBase( + const Value::ObjectValues::iterator& current) + : current_(current), isNull_(false) {} + +Value& ValueIteratorBase::deref() const { + return current_->second; +} + +void ValueIteratorBase::increment() { + ++current_; +} + +void ValueIteratorBase::decrement() { + --current_; +} + +ValueIteratorBase::difference_type +ValueIteratorBase::computeDistance(const SelfType& other) const { +#ifdef JSON_USE_CPPTL_SMALLMAP + return other.current_ - current_; +#else + // Iterator for null value are initialized using the default + // constructor, which initialize current_ to the default + // std::map::iterator. As begin() and end() are two instance + // of the default std::map::iterator, they can not be compared. + // To allow this, we handle this comparison specifically. + if (isNull_ && other.isNull_) { + return 0; + } + + // Usage of std::distance is not portable (does not compile with Sun Studio 12 + // RogueWave STL, + // which is the one used by default). + // Using a portable hand-made version for non random iterator instead: + // return difference_type( std::distance( current_, other.current_ ) ); + difference_type myDistance = 0; + for (Value::ObjectValues::iterator it = current_; it != other.current_; + ++it) { + ++myDistance; + } + return myDistance; +#endif +} + +bool ValueIteratorBase::isEqual(const SelfType& other) const { + if (isNull_) { + return other.isNull_; + } + return current_ == other.current_; +} + +void ValueIteratorBase::copy(const SelfType& other) { + current_ = other.current_; + isNull_ = other.isNull_; +} + +Value ValueIteratorBase::key() const { + const Value::CZString czstring = (*current_).first; + if (czstring.data()) { + if (czstring.isStaticString()) + return Value(StaticString(czstring.data())); + return Value(czstring.data(), czstring.data() + czstring.length()); + } + return Value(czstring.index()); +} + +UInt ValueIteratorBase::index() const { + const Value::CZString czstring = (*current_).first; + if (!czstring.data()) + return czstring.index(); + return Value::UInt(-1); +} + +std::string ValueIteratorBase::name() const { + char const* key; + char const* end; + key = memberName(&end); + if (!key) return std::string(); + return std::string(key, end); +} + +char const* ValueIteratorBase::memberName() const { + const char* name = (*current_).first.data(); + return name ? name : ""; +} + +char const* ValueIteratorBase::memberName(char const** end) const { + const char* name = (*current_).first.data(); + if (!name) { + *end = NULL; + return NULL; + } + *end = name + (*current_).first.length(); + return name; +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueConstIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueConstIterator::ValueConstIterator() {} + +ValueConstIterator::ValueConstIterator( + const Value::ObjectValues::iterator& current) + : ValueIteratorBase(current) {} + +ValueConstIterator& ValueConstIterator:: +operator=(const ValueIteratorBase& other) { + copy(other); + return *this; +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIterator::ValueIterator() {} + +ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) + : ValueIteratorBase(current) {} + +ValueIterator::ValueIterator(const ValueConstIterator& other) + : ValueIteratorBase(other) {} + +ValueIterator::ValueIterator(const ValueIterator& other) + : ValueIteratorBase(other) {} + +ValueIterator& ValueIterator::operator=(const SelfType& other) { + copy(other); + return *this; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_valueiterator.inl +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_value.cpp +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2011 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include +#include +#include +#ifdef JSON_USE_CPPTL +#include +#endif +#include // size_t +#include // min() + +#define JSON_ASSERT_UNREACHABLE assert(false) + +namespace Json { + +// This is a walkaround to avoid the static initialization of Value::null. +// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of +// 8 (instead of 4) as a bit of future-proofing. +#if defined(__ARMEL__) +#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) +#else +#define ALIGNAS(byte_alignment) +#endif +static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; +const unsigned char& kNullRef = kNull[0]; +const Value& Value::null = reinterpret_cast(kNullRef); +const Value& Value::nullRef = null; + +const Int Value::minInt = Int(~(UInt(-1) / 2)); +const Int Value::maxInt = Int(UInt(-1) / 2); +const UInt Value::maxUInt = UInt(-1); +#if defined(JSON_HAS_INT64) +const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2)); +const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2); +const UInt64 Value::maxUInt64 = UInt64(-1); +// The constant is hard-coded because some compiler have trouble +// converting Value::maxUInt64 to a double correctly (AIX/xlC). +// Assumes that UInt64 is a 64 bits integer. +static const double maxUInt64AsDouble = 18446744073709551615.0; +#endif // defined(JSON_HAS_INT64) +const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); +const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2); +const LargestUInt Value::maxLargestUInt = LargestUInt(-1); + +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) +template +static inline bool InRange(double d, T min, U max) { + return d >= min && d <= max; +} +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) +static inline double integerToDouble(Json::UInt64 value) { + return static_cast(Int64(value / 2)) * 2.0 + Int64(value & 1); +} + +template static inline double integerToDouble(T value) { + return static_cast(value); +} + +template +static inline bool InRange(double d, T min, U max) { + return d >= integerToDouble(min) && d <= integerToDouble(max); +} +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + +/** Duplicates the specified string value. + * @param value Pointer to the string to duplicate. Must be zero-terminated if + * length is "unknown". + * @param length Length of the value. if equals to unknown, then it will be + * computed using strlen(value). + * @return Pointer on the duplicate instance of string. + */ +static inline char* duplicateStringValue(const char* value, + size_t length) { + // Avoid an integer overflow in the call to malloc below by limiting length + // to a sane value. + if (length >= (size_t)Value::maxInt) + length = Value::maxInt - 1; + + char* newString = static_cast(malloc(length + 1)); + if (newString == NULL) { + throwRuntimeError( + "in Json::Value::duplicateStringValue(): " + "Failed to allocate string value buffer"); + } + memcpy(newString, value, length); + newString[length] = 0; + return newString; +} + +/* Record the length as a prefix. + */ +static inline char* duplicateAndPrefixStringValue( + const char* value, + unsigned int length) +{ + // Avoid an integer overflow in the call to malloc below by limiting length + // to a sane value. + JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U, + "in Json::Value::duplicateAndPrefixStringValue(): " + "length too big for prefixing"); + unsigned actualLength = length + sizeof(unsigned) + 1U; + char* newString = static_cast(malloc(actualLength)); + if (newString == 0) { + throwRuntimeError( + "in Json::Value::duplicateAndPrefixStringValue(): " + "Failed to allocate string value buffer"); + } + *reinterpret_cast(newString) = length; + memcpy(newString + sizeof(unsigned), value, length); + newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later + return newString; +} +inline static void decodePrefixedString( + bool isPrefixed, char const* prefixed, + unsigned* length, char const** value) +{ + if (!isPrefixed) { + *length = strlen(prefixed); + *value = prefixed; + } else { + *length = *reinterpret_cast(prefixed); + *value = prefixed + sizeof(unsigned); + } +} +/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue(). + */ +static inline void releaseStringValue(char* value) { free(value); } + +} // namespace Json + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ValueInternals... +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +#if !defined(JSON_IS_AMALGAMATION) + +#include "json_valueiterator.inl" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +class JSON_API Exception : public std::exception { +public: + Exception(std::string const& msg); + virtual ~Exception() throw(); + virtual char const* what() const throw(); +protected: + std::string const msg_; +}; +class JSON_API RuntimeError : public Exception { +public: + RuntimeError(std::string const& msg); +}; +class JSON_API LogicError : public Exception { +public: + LogicError(std::string const& msg); +}; + +Exception::Exception(std::string const& msg) + : msg_(msg) +{} +Exception::~Exception() throw() +{} +char const* Exception::what() const throw() +{ + return msg_.c_str(); +} +RuntimeError::RuntimeError(std::string const& msg) + : Exception(msg) +{} +LogicError::LogicError(std::string const& msg) + : Exception(msg) +{} +void throwRuntimeError(std::string const& msg) +{ + throw RuntimeError(msg); +} +void throwLogicError(std::string const& msg) +{ + throw LogicError(msg); +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::CommentInfo +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +Value::CommentInfo::CommentInfo() : comment_(0) {} + +Value::CommentInfo::~CommentInfo() { + if (comment_) + releaseStringValue(comment_); +} + +void Value::CommentInfo::setComment(const char* text, size_t len) { + if (comment_) { + releaseStringValue(comment_); + comment_ = 0; + } + JSON_ASSERT(text != 0); + JSON_ASSERT_MESSAGE( + text[0] == '\0' || text[0] == '/', + "in Json::Value::setComment(): Comments must start with /"); + // It seems that /**/ style comments are acceptable as well. + comment_ = duplicateStringValue(text, len); +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::CZString +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +// Notes: policy_ indicates if the string was allocated when +// a string is stored. + +Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {} + +Value::CZString::CZString(char const* str, unsigned length, DuplicationPolicy allocate) + : cstr_(str) +{ + // allocate != duplicate + storage_.policy_ = allocate; + storage_.length_ = length; +} + +Value::CZString::CZString(const CZString& other) + : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0 + ? duplicateStringValue(other.cstr_, other.storage_.length_) + : other.cstr_) +{ + storage_.policy_ = (other.cstr_ + ? (other.storage_.policy_ == noDuplication + ? noDuplication : duplicate) + : other.storage_.policy_); + storage_.length_ = other.storage_.length_; +} + +Value::CZString::~CZString() { + if (cstr_ && storage_.policy_ == duplicate) + releaseStringValue(const_cast(cstr_)); +} + +void Value::CZString::swap(CZString& other) { + std::swap(cstr_, other.cstr_); + std::swap(index_, other.index_); +} + +Value::CZString& Value::CZString::operator=(CZString other) { + swap(other); + return *this; +} + +bool Value::CZString::operator<(const CZString& other) const { + if (!cstr_) return index_ < other.index_; + //return strcmp(cstr_, other.cstr_) < 0; + // Assume both are strings. + unsigned this_len = this->storage_.length_; + unsigned other_len = other.storage_.length_; + unsigned min_len = std::min(this_len, other_len); + int comp = memcmp(this->cstr_, other.cstr_, min_len); + if (comp < 0) return true; + if (comp > 0) return false; + return (this_len < other_len); +} + +bool Value::CZString::operator==(const CZString& other) const { + if (!cstr_) return index_ == other.index_; + //return strcmp(cstr_, other.cstr_) == 0; + // Assume both are strings. + unsigned this_len = this->storage_.length_; + unsigned other_len = other.storage_.length_; + if (this_len != other_len) return false; + int comp = memcmp(this->cstr_, other.cstr_, this_len); + return comp == 0; +} + +ArrayIndex Value::CZString::index() const { return index_; } + +//const char* Value::CZString::c_str() const { return cstr_; } +const char* Value::CZString::data() const { return cstr_; } +unsigned Value::CZString::length() const { return storage_.length_; } +bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; } + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::Value +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +/*! \internal Default constructor initialization must be equivalent to: + * memset( this, 0, sizeof(Value) ) + * This optimization is used in ValueInternalMap fast allocator. + */ +Value::Value(ValueType type) { + initBasic(type); + switch (type) { + case nullValue: + break; + case intValue: + case uintValue: + value_.int_ = 0; + break; + case realValue: + value_.real_ = 0.0; + break; + case stringValue: + value_.string_ = 0; + break; + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(); + break; + case booleanValue: + value_.bool_ = false; + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + +Value::Value(Int value) { + initBasic(intValue); + value_.int_ = value; +} + +Value::Value(UInt value) { + initBasic(uintValue); + value_.uint_ = value; +} +#if defined(JSON_HAS_INT64) +Value::Value(Int64 value) { + initBasic(intValue); + value_.int_ = value; +} +Value::Value(UInt64 value) { + initBasic(uintValue); + value_.uint_ = value; +} +#endif // defined(JSON_HAS_INT64) + +Value::Value(double value) { + initBasic(realValue); + value_.real_ = value; +} + +Value::Value(const char* value) { + initBasic(stringValue, true); + value_.string_ = duplicateAndPrefixStringValue(value, static_cast(strlen(value))); +} + +Value::Value(const char* beginValue, const char* endValue) { + initBasic(stringValue, true); + value_.string_ = + duplicateAndPrefixStringValue(beginValue, static_cast(endValue - beginValue)); +} + +Value::Value(const std::string& value) { + initBasic(stringValue, true); + value_.string_ = + duplicateAndPrefixStringValue(value.data(), static_cast(value.length())); +} + +Value::Value(const StaticString& value) { + initBasic(stringValue); + value_.string_ = const_cast(value.c_str()); +} + +#ifdef JSON_USE_CPPTL +Value::Value(const CppTL::ConstString& value) { + initBasic(stringValue, true); + value_.string_ = duplicateAndPrefixStringValue(value, static_cast(value.length())); +} +#endif + +Value::Value(bool value) { + initBasic(booleanValue); + value_.bool_ = value; +} + +Value::Value(Value const& other) + : type_(other.type_), allocated_(false) + , + comments_(0), start_(other.start_), limit_(other.limit_) +{ + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + value_ = other.value_; + break; + case stringValue: + if (other.value_.string_ && other.allocated_) { + unsigned len; + char const* str; + decodePrefixedString(other.allocated_, other.value_.string_, + &len, &str); + value_.string_ = duplicateAndPrefixStringValue(str, len); + allocated_ = true; + } else { + value_.string_ = other.value_.string_; + allocated_ = false; + } + break; + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(*other.value_.map_); + break; + default: + JSON_ASSERT_UNREACHABLE; + } + if (other.comments_) { + comments_ = new CommentInfo[numberOfCommentPlacement]; + for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { + const CommentInfo& otherComment = other.comments_[comment]; + if (otherComment.comment_) + comments_[comment].setComment( + otherComment.comment_, strlen(otherComment.comment_)); + } + } +} + +Value::~Value() { + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + break; + case stringValue: + if (allocated_) + releaseStringValue(value_.string_); + break; + case arrayValue: + case objectValue: + delete value_.map_; + break; + default: + JSON_ASSERT_UNREACHABLE; + } + + if (comments_) + delete[] comments_; +} + +Value& Value::operator=(Value other) { + swap(other); + return *this; +} + +void Value::swapPayload(Value& other) { + ValueType temp = type_; + type_ = other.type_; + other.type_ = temp; + std::swap(value_, other.value_); + int temp2 = allocated_; + allocated_ = other.allocated_; + other.allocated_ = temp2; +} + +void Value::swap(Value& other) { + swapPayload(other); + std::swap(comments_, other.comments_); + std::swap(start_, other.start_); + std::swap(limit_, other.limit_); +} + +ValueType Value::type() const { return type_; } + +int Value::compare(const Value& other) const { + if (*this < other) + return -1; + if (*this > other) + return 1; + return 0; +} + +bool Value::operator<(const Value& other) const { + int typeDelta = type_ - other.type_; + if (typeDelta) + return typeDelta < 0 ? true : false; + switch (type_) { + case nullValue: + return false; + case intValue: + return value_.int_ < other.value_.int_; + case uintValue: + return value_.uint_ < other.value_.uint_; + case realValue: + return value_.real_ < other.value_.real_; + case booleanValue: + return value_.bool_ < other.value_.bool_; + case stringValue: + { + if ((value_.string_ == 0) || (other.value_.string_ == 0)) { + if (other.value_.string_) return true; + else return false; + } + unsigned this_len; + unsigned other_len; + char const* this_str; + char const* other_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); + unsigned min_len = std::min(this_len, other_len); + int comp = memcmp(this_str, other_str, min_len); + if (comp < 0) return true; + if (comp > 0) return false; + return (this_len < other_len); + } + case arrayValue: + case objectValue: { + int delta = int(value_.map_->size() - other.value_.map_->size()); + if (delta) + return delta < 0; + return (*value_.map_) < (*other.value_.map_); + } + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable +} + +bool Value::operator<=(const Value& other) const { return !(other < *this); } + +bool Value::operator>=(const Value& other) const { return !(*this < other); } + +bool Value::operator>(const Value& other) const { return other < *this; } + +bool Value::operator==(const Value& other) const { + // if ( type_ != other.type_ ) + // GCC 2.95.3 says: + // attempt to take address of bit-field structure member `Json::Value::type_' + // Beats me, but a temp solves the problem. + int temp = other.type_; + if (type_ != temp) + return false; + switch (type_) { + case nullValue: + return true; + case intValue: + return value_.int_ == other.value_.int_; + case uintValue: + return value_.uint_ == other.value_.uint_; + case realValue: + return value_.real_ == other.value_.real_; + case booleanValue: + return value_.bool_ == other.value_.bool_; + case stringValue: + { + if ((value_.string_ == 0) || (other.value_.string_ == 0)) { + return (value_.string_ == other.value_.string_); + } + unsigned this_len; + unsigned other_len; + char const* this_str; + char const* other_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); + if (this_len != other_len) return false; + int comp = memcmp(this_str, other_str, this_len); + return comp == 0; + } + case arrayValue: + case objectValue: + return value_.map_->size() == other.value_.map_->size() && + (*value_.map_) == (*other.value_.map_); + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable +} + +bool Value::operator!=(const Value& other) const { return !(*this == other); } + +const char* Value::asCString() const { + JSON_ASSERT_MESSAGE(type_ == stringValue, + "in Json::Value::asCString(): requires stringValue"); + if (value_.string_ == 0) return 0; + unsigned this_len; + char const* this_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + return this_str; +} + +bool Value::getString(char const** str, char const** end) const { + if (type_ != stringValue) return false; + if (value_.string_ == 0) return false; + unsigned length; + decodePrefixedString(this->allocated_, this->value_.string_, &length, str); + *end = *str + length; + return true; +} + +std::string Value::asString() const { + switch (type_) { + case nullValue: + return ""; + case stringValue: + { + if (value_.string_ == 0) return ""; + unsigned this_len; + char const* this_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + return std::string(this_str, this_len); + } + case booleanValue: + return value_.bool_ ? "true" : "false"; + case intValue: + return valueToString(value_.int_); + case uintValue: + return valueToString(value_.uint_); + case realValue: + return valueToString(value_.real_); + default: + JSON_FAIL_MESSAGE("Type is not convertible to string"); + } +} + +#ifdef JSON_USE_CPPTL +CppTL::ConstString Value::asConstString() const { + unsigned len; + char const* str; + decodePrefixedString(allocated_, value_.string_, + &len, &str); + return CppTL::ConstString(str, len); +} +#endif + +Value::Int Value::asInt() const { + switch (type_) { + case intValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); + return Int(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); + return Int(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), + "double out of Int range"); + return Int(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to Int."); +} + +Value::UInt Value::asUInt() const { + switch (type_) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); + return UInt(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); + return UInt(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), + "double out of UInt range"); + return UInt(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to UInt."); +} + +#if defined(JSON_HAS_INT64) + +Value::Int64 Value::asInt64() const { + switch (type_) { + case intValue: + return Int64(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); + return Int64(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), + "double out of Int64 range"); + return Int64(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to Int64."); +} + +Value::UInt64 Value::asUInt64() const { + switch (type_) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); + return UInt64(value_.int_); + case uintValue: + return UInt64(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), + "double out of UInt64 range"); + return UInt64(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to UInt64."); +} +#endif // if defined(JSON_HAS_INT64) + +LargestInt Value::asLargestInt() const { +#if defined(JSON_NO_INT64) + return asInt(); +#else + return asInt64(); +#endif +} + +LargestUInt Value::asLargestUInt() const { +#if defined(JSON_NO_INT64) + return asUInt(); +#else + return asUInt64(); +#endif +} + +double Value::asDouble() const { + switch (type_) { + case intValue: + return static_cast(value_.int_); + case uintValue: +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast(value_.uint_); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return integerToDouble(value_.uint_); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + case realValue: + return value_.real_; + case nullValue: + return 0.0; + case booleanValue: + return value_.bool_ ? 1.0 : 0.0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to double."); +} + +float Value::asFloat() const { + switch (type_) { + case intValue: + return static_cast(value_.int_); + case uintValue: +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast(value_.uint_); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return integerToDouble(value_.uint_); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + case realValue: + return static_cast(value_.real_); + case nullValue: + return 0.0; + case booleanValue: + return value_.bool_ ? 1.0f : 0.0f; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to float."); +} + +bool Value::asBool() const { + switch (type_) { + case booleanValue: + return value_.bool_; + case nullValue: + return false; + case intValue: + return value_.int_ ? true : false; + case uintValue: + return value_.uint_ ? true : false; + case realValue: + return value_.real_ ? true : false; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to bool."); +} + +bool Value::isConvertibleTo(ValueType other) const { + switch (other) { + case nullValue: + return (isNumeric() && asDouble() == 0.0) || + (type_ == booleanValue && value_.bool_ == false) || + (type_ == stringValue && asString() == "") || + (type_ == arrayValue && value_.map_->size() == 0) || + (type_ == objectValue && value_.map_->size() == 0) || + type_ == nullValue; + case intValue: + return isInt() || + (type_ == realValue && InRange(value_.real_, minInt, maxInt)) || + type_ == booleanValue || type_ == nullValue; + case uintValue: + return isUInt() || + (type_ == realValue && InRange(value_.real_, 0, maxUInt)) || + type_ == booleanValue || type_ == nullValue; + case realValue: + return isNumeric() || type_ == booleanValue || type_ == nullValue; + case booleanValue: + return isNumeric() || type_ == booleanValue || type_ == nullValue; + case stringValue: + return isNumeric() || type_ == booleanValue || type_ == stringValue || + type_ == nullValue; + case arrayValue: + return type_ == arrayValue || type_ == nullValue; + case objectValue: + return type_ == objectValue || type_ == nullValue; + } + JSON_ASSERT_UNREACHABLE; + return false; +} + +/// Number of values in array or object +ArrayIndex Value::size() const { + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + case stringValue: + return 0; + case arrayValue: // size of the array is highest index + 1 + if (!value_.map_->empty()) { + ObjectValues::const_iterator itLast = value_.map_->end(); + --itLast; + return (*itLast).first.index() + 1; + } + return 0; + case objectValue: + return ArrayIndex(value_.map_->size()); + } + JSON_ASSERT_UNREACHABLE; + return 0; // unreachable; +} + +bool Value::empty() const { + if (isNull() || isArray() || isObject()) + return size() == 0u; + else + return false; +} + +bool Value::operator!() const { return isNull(); } + +void Value::clear() { + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || + type_ == objectValue, + "in Json::Value::clear(): requires complex value"); + start_ = 0; + limit_ = 0; + switch (type_) { + case arrayValue: + case objectValue: + value_.map_->clear(); + break; + default: + break; + } +} + +void Value::resize(ArrayIndex newSize) { + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue, + "in Json::Value::resize(): requires arrayValue"); + if (type_ == nullValue) + *this = Value(arrayValue); + ArrayIndex oldSize = size(); + if (newSize == 0) + clear(); + else if (newSize > oldSize) + (*this)[newSize - 1]; + else { + for (ArrayIndex index = newSize; index < oldSize; ++index) { + value_.map_->erase(index); + } + assert(size() == newSize); + } +} + +Value& Value::operator[](ArrayIndex index) { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == arrayValue, + "in Json::Value::operator[](ArrayIndex): requires arrayValue"); + if (type_ == nullValue) + *this = Value(arrayValue); + CZString key(index); + ObjectValues::iterator it = value_.map_->lower_bound(key); + if (it != value_.map_->end() && (*it).first == key) + return (*it).second; + + ObjectValues::value_type defaultValue(key, nullRef); + it = value_.map_->insert(it, defaultValue); + return (*it).second; +} + +Value& Value::operator[](int index) { + JSON_ASSERT_MESSAGE( + index >= 0, + "in Json::Value::operator[](int index): index cannot be negative"); + return (*this)[ArrayIndex(index)]; +} + +const Value& Value::operator[](ArrayIndex index) const { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == arrayValue, + "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); + if (type_ == nullValue) + return nullRef; + CZString key(index); + ObjectValues::const_iterator it = value_.map_->find(key); + if (it == value_.map_->end()) + return nullRef; + return (*it).second; +} + +const Value& Value::operator[](int index) const { + JSON_ASSERT_MESSAGE( + index >= 0, + "in Json::Value::operator[](int index) const: index cannot be negative"); + return (*this)[ArrayIndex(index)]; +} + +void Value::initBasic(ValueType type, bool allocated) { + type_ = type; + allocated_ = allocated; + comments_ = 0; + start_ = 0; + limit_ = 0; +} + +// Access an object value by name, create a null member if it does not exist. +// @pre Type of '*this' is object or null. +// @param key is null-terminated. +Value& Value::resolveReference(const char* key) { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == objectValue, + "in Json::Value::resolveReference(): requires objectValue"); + if (type_ == nullValue) + *this = Value(objectValue); + CZString actualKey( + key, static_cast(strlen(key)), CZString::noDuplication); // NOTE! + ObjectValues::iterator it = value_.map_->lower_bound(actualKey); + if (it != value_.map_->end() && (*it).first == actualKey) + return (*it).second; + + ObjectValues::value_type defaultValue(actualKey, nullRef); + it = value_.map_->insert(it, defaultValue); + Value& value = (*it).second; + return value; +} + +// @param key is not null-terminated. +Value& Value::resolveReference(char const* key, char const* end) +{ + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == objectValue, + "in Json::Value::resolveReference(key, end): requires objectValue"); + if (type_ == nullValue) + *this = Value(objectValue); + CZString actualKey( + key, static_cast(end-key), CZString::duplicateOnCopy); + ObjectValues::iterator it = value_.map_->lower_bound(actualKey); + if (it != value_.map_->end() && (*it).first == actualKey) + return (*it).second; + + ObjectValues::value_type defaultValue(actualKey, nullRef); + it = value_.map_->insert(it, defaultValue); + Value& value = (*it).second; + return value; +} + +Value Value::get(ArrayIndex index, const Value& defaultValue) const { + const Value* value = &((*this)[index]); + return value == &nullRef ? defaultValue : *value; +} + +bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } + +Value const* Value::find(char const* key, char const* end) const +{ + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == objectValue, + "in Json::Value::find(key, end, found): requires objectValue or nullValue"); + if (type_ == nullValue) return NULL; + CZString actualKey(key, static_cast(end-key), CZString::noDuplication); + ObjectValues::const_iterator it = value_.map_->find(actualKey); + if (it == value_.map_->end()) return NULL; + return &(*it).second; +} +const Value& Value::operator[](const char* key) const +{ + Value const* found = find(key, key + strlen(key)); + if (!found) return nullRef; + return *found; +} +Value const& Value::operator[](std::string const& key) const +{ + Value const* found = find(key.data(), key.data() + key.length()); + if (!found) return nullRef; + return *found; +} + +Value& Value::operator[](const char* key) { + return resolveReference(key, key + strlen(key)); +} + +Value& Value::operator[](const std::string& key) { + return resolveReference(key.data(), key.data() + key.length()); +} + +Value& Value::operator[](const StaticString& key) { + return resolveReference(key.c_str()); +} + +#ifdef JSON_USE_CPPTL +Value& Value::operator[](const CppTL::ConstString& key) { + return resolveReference(key.c_str(), key.end_c_str()); +} +Value const& Value::operator[](CppTL::ConstString const& key) const +{ + Value const* found = find(key.c_str(), key.end_c_str()); + if (!found) return nullRef; + return *found; +} +#endif + +Value& Value::append(const Value& value) { return (*this)[size()] = value; } + +Value Value::get(char const* key, char const* end, Value const& defaultValue) const +{ + Value const* found = find(key, end); + return !found ? defaultValue : *found; +} +Value Value::get(char const* key, Value const& defaultValue) const +{ + return get(key, key + strlen(key), defaultValue); +} +Value Value::get(std::string const& key, Value const& defaultValue) const +{ + return get(key.data(), key.data() + key.length(), defaultValue); +} + + +bool Value::removeMember(const char* key, const char* end, Value* removed) +{ + if (type_ != objectValue) { + return false; + } + CZString actualKey(key, static_cast(end-key), CZString::noDuplication); + ObjectValues::iterator it = value_.map_->find(actualKey); + if (it == value_.map_->end()) + return false; + *removed = it->second; + value_.map_->erase(it); + return true; +} +bool Value::removeMember(const char* key, Value* removed) +{ + return removeMember(key, key + strlen(key), removed); +} +bool Value::removeMember(std::string const& key, Value* removed) +{ + return removeMember(key.data(), key.data() + key.length(), removed); +} +Value Value::removeMember(const char* key) +{ + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, + "in Json::Value::removeMember(): requires objectValue"); + if (type_ == nullValue) + return nullRef; + + Value removed; // null + removeMember(key, key + strlen(key), &removed); + return removed; // still null if removeMember() did nothing +} +Value Value::removeMember(const std::string& key) +{ + return removeMember(key.c_str()); +} + +bool Value::removeIndex(ArrayIndex index, Value* removed) { + if (type_ != arrayValue) { + return false; + } + CZString key(index); + ObjectValues::iterator it = value_.map_->find(key); + if (it == value_.map_->end()) { + return false; + } + *removed = it->second; + ArrayIndex oldSize = size(); + // shift left all items left, into the place of the "removed" + for (ArrayIndex i = index; i < (oldSize - 1); ++i){ + CZString key(i); + (*value_.map_)[key] = (*this)[i + 1]; + } + // erase the last one ("leftover") + CZString keyLast(oldSize - 1); + ObjectValues::iterator itLast = value_.map_->find(keyLast); + value_.map_->erase(itLast); + return true; +} + +#ifdef JSON_USE_CPPTL +Value Value::get(const CppTL::ConstString& key, + const Value& defaultValue) const { + return get(key.c_str(), key.end_c_str(), defaultValue); +} +#endif + +bool Value::isMember(char const* key, char const* end) const +{ + Value const* value = find(key, end); + return NULL != value; +} +bool Value::isMember(char const* key) const +{ + return isMember(key, key + strlen(key)); +} +bool Value::isMember(std::string const& key) const +{ + return isMember(key.data(), key.data() + key.length()); +} + +#ifdef JSON_USE_CPPTL +bool Value::isMember(const CppTL::ConstString& key) const { + return isMember(key.c_str(), key.end_c_str()); +} +#endif + +Value::Members Value::getMemberNames() const { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == objectValue, + "in Json::Value::getMemberNames(), value must be objectValue"); + if (type_ == nullValue) + return Value::Members(); + Members members; + members.reserve(value_.map_->size()); + ObjectValues::const_iterator it = value_.map_->begin(); + ObjectValues::const_iterator itEnd = value_.map_->end(); + for (; it != itEnd; ++it) { + members.push_back(std::string((*it).first.data(), + (*it).first.length())); + } + return members; +} +// +//# ifdef JSON_USE_CPPTL +// EnumMemberNames +// Value::enumMemberNames() const +//{ +// if ( type_ == objectValue ) +// { +// return CppTL::Enum::any( CppTL::Enum::transform( +// CppTL::Enum::keys( *(value_.map_), CppTL::Type() ), +// MemberNamesTransform() ) ); +// } +// return EnumMemberNames(); +//} +// +// +// EnumValues +// Value::enumValues() const +//{ +// if ( type_ == objectValue || type_ == arrayValue ) +// return CppTL::Enum::anyValues( *(value_.map_), +// CppTL::Type() ); +// return EnumValues(); +//} +// +//# endif + +static bool IsIntegral(double d) { + double integral_part; + return modf(d, &integral_part) == 0.0; +} + +bool Value::isNull() const { return type_ == nullValue; } + +bool Value::isBool() const { return type_ == booleanValue; } + +bool Value::isInt() const { + switch (type_) { + case intValue: + return value_.int_ >= minInt && value_.int_ <= maxInt; + case uintValue: + return value_.uint_ <= UInt(maxInt); + case realValue: + return value_.real_ >= minInt && value_.real_ <= maxInt && + IsIntegral(value_.real_); + default: + break; + } + return false; +} + +bool Value::isUInt() const { + switch (type_) { + case intValue: + return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); + case uintValue: + return value_.uint_ <= maxUInt; + case realValue: + return value_.real_ >= 0 && value_.real_ <= maxUInt && + IsIntegral(value_.real_); + default: + break; + } + return false; +} + +bool Value::isInt64() const { +#if defined(JSON_HAS_INT64) + switch (type_) { + case intValue: + return true; + case uintValue: + return value_.uint_ <= UInt64(maxInt64); + case realValue: + // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a + // double, so double(maxInt64) will be rounded up to 2^63. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= double(minInt64) && + value_.real_ < double(maxInt64) && IsIntegral(value_.real_); + default: + break; + } +#endif // JSON_HAS_INT64 + return false; +} + +bool Value::isUInt64() const { +#if defined(JSON_HAS_INT64) + switch (type_) { + case intValue: + return value_.int_ >= 0; + case uintValue: + return true; + case realValue: + // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a + // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble && + IsIntegral(value_.real_); + default: + break; + } +#endif // JSON_HAS_INT64 + return false; +} + +bool Value::isIntegral() const { +#if defined(JSON_HAS_INT64) + return isInt64() || isUInt64(); +#else + return isInt() || isUInt(); +#endif +} + +bool Value::isDouble() const { return type_ == realValue || isIntegral(); } + +bool Value::isNumeric() const { return isIntegral() || isDouble(); } + +bool Value::isString() const { return type_ == stringValue; } + +bool Value::isArray() const { return type_ == arrayValue; } + +bool Value::isObject() const { return type_ == objectValue; } + +void Value::setComment(const char* comment, size_t len, CommentPlacement placement) { + if (!comments_) + comments_ = new CommentInfo[numberOfCommentPlacement]; + if ((len > 0) && (comment[len-1] == '\n')) { + // Always discard trailing newline, to aid indentation. + len -= 1; + } + comments_[placement].setComment(comment, len); +} + +void Value::setComment(const char* comment, CommentPlacement placement) { + setComment(comment, strlen(comment), placement); +} + +void Value::setComment(const std::string& comment, CommentPlacement placement) { + setComment(comment.c_str(), comment.length(), placement); +} + +bool Value::hasComment(CommentPlacement placement) const { + return comments_ != 0 && comments_[placement].comment_ != 0; +} + +std::string Value::getComment(CommentPlacement placement) const { + if (hasComment(placement)) + return comments_[placement].comment_; + return ""; +} + +void Value::setOffsetStart(size_t start) { start_ = start; } + +void Value::setOffsetLimit(size_t limit) { limit_ = limit; } + +size_t Value::getOffsetStart() const { return start_; } + +size_t Value::getOffsetLimit() const { return limit_; } + +std::string Value::toStyledString() const { + StyledWriter writer; + return writer.write(*this); +} + +Value::const_iterator Value::begin() const { + switch (type_) { + case arrayValue: + case objectValue: + if (value_.map_) + return const_iterator(value_.map_->begin()); + break; + default: + break; + } + return const_iterator(); +} + +Value::const_iterator Value::end() const { + switch (type_) { + case arrayValue: + case objectValue: + if (value_.map_) + return const_iterator(value_.map_->end()); + break; + default: + break; + } + return const_iterator(); +} + +Value::iterator Value::begin() { + switch (type_) { + case arrayValue: + case objectValue: + if (value_.map_) + return iterator(value_.map_->begin()); + break; + default: + break; + } + return iterator(); +} + +Value::iterator Value::end() { + switch (type_) { + case arrayValue: + case objectValue: + if (value_.map_) + return iterator(value_.map_->end()); + break; + default: + break; + } + return iterator(); +} + +// class PathArgument +// ////////////////////////////////////////////////////////////////// + +PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {} + +PathArgument::PathArgument(ArrayIndex index) + : key_(), index_(index), kind_(kindIndex) {} + +PathArgument::PathArgument(const char* key) + : key_(key), index_(), kind_(kindKey) {} + +PathArgument::PathArgument(const std::string& key) + : key_(key.c_str()), index_(), kind_(kindKey) {} + +// class Path +// ////////////////////////////////////////////////////////////////// + +Path::Path(const std::string& path, + const PathArgument& a1, + const PathArgument& a2, + const PathArgument& a3, + const PathArgument& a4, + const PathArgument& a5) { + InArgs in; + in.push_back(&a1); + in.push_back(&a2); + in.push_back(&a3); + in.push_back(&a4); + in.push_back(&a5); + makePath(path, in); +} + +void Path::makePath(const std::string& path, const InArgs& in) { + const char* current = path.c_str(); + const char* end = current + path.length(); + InArgs::const_iterator itInArg = in.begin(); + while (current != end) { + if (*current == '[') { + ++current; + if (*current == '%') + addPathInArg(path, in, itInArg, PathArgument::kindIndex); + else { + ArrayIndex index = 0; + for (; current != end && *current >= '0' && *current <= '9'; ++current) + index = index * 10 + ArrayIndex(*current - '0'); + args_.push_back(index); + } + if (current == end || *current++ != ']') + invalidPath(path, int(current - path.c_str())); + } else if (*current == '%') { + addPathInArg(path, in, itInArg, PathArgument::kindKey); + ++current; + } else if (*current == '.') { + ++current; + } else { + const char* beginName = current; + while (current != end && !strchr("[.", *current)) + ++current; + args_.push_back(std::string(beginName, current)); + } + } +} + +void Path::addPathInArg(const std::string& /*path*/, + const InArgs& in, + InArgs::const_iterator& itInArg, + PathArgument::Kind kind) { + if (itInArg == in.end()) { + // Error: missing argument %d + } else if ((*itInArg)->kind_ != kind) { + // Error: bad argument type + } else { + args_.push_back(**itInArg); + } +} + +void Path::invalidPath(const std::string& /*path*/, int /*location*/) { + // Error: invalid path. +} + +const Value& Path::resolve(const Value& root) const { + const Value* node = &root; + for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + const PathArgument& arg = *it; + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray() || !node->isValidIndex(arg.index_)) { + // Error: unable to resolve path (array value expected at position... + } + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) { + // Error: unable to resolve path (object value expected at position...) + } + node = &((*node)[arg.key_]); + if (node == &Value::nullRef) { + // Error: unable to resolve path (object has no member named '' at + // position...) + } + } + } + return *node; +} + +Value Path::resolve(const Value& root, const Value& defaultValue) const { + const Value* node = &root; + for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + const PathArgument& arg = *it; + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray() || !node->isValidIndex(arg.index_)) + return defaultValue; + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) + return defaultValue; + node = &((*node)[arg.key_]); + if (node == &Value::nullRef) + return defaultValue; + } + } + return *node; +} + +Value& Path::make(Value& root) const { + Value* node = &root; + for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + const PathArgument& arg = *it; + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray()) { + // Error: node is not an array at position ... + } + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) { + // Error: node is not an object at position... + } + node = &((*node)[arg.key_]); + } + } + return *node; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_value.cpp +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: src/lib_json/json_writer.cpp +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2011 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include +#include "json_tool.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0 +#include +#define isfinite _finite +#elif defined(__sun) && defined(__SVR4) //Solaris +#include +#define isfinite finite +#else +#include +#define isfinite std::isfinite +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below +#define snprintf _snprintf +#elif defined(__ANDROID__) +#define snprintf snprintf +#elif __cplusplus >= 201103L +#define snprintf std::snprintf +#endif + +#if defined(__BORLANDC__) +#include +#define isfinite _finite +#define snprintf _snprintf +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 +// Disable warning about strdup being deprecated. +#pragma warning(disable : 4996) +#endif + +namespace Json { + +#if __cplusplus >= 201103L +typedef std::unique_ptr StreamWriterPtr; +#else +typedef std::auto_ptr StreamWriterPtr; +#endif + +static bool containsControlCharacter(const char* str) { + while (*str) { + if (isControlCharacter(*(str++))) + return true; + } + return false; +} + +static bool containsControlCharacter0(const char* str, unsigned len) { + char const* end = str + len; + while (end != str) { + if (isControlCharacter(*str) || 0==*str) + return true; + ++str; + } + return false; +} + +std::string valueToString(LargestInt value) { + UIntToStringBuffer buffer; + char* current = buffer + sizeof(buffer); + bool isNegative = value < 0; + if (isNegative) + value = -value; + uintToString(LargestUInt(value), current); + if (isNegative) + *--current = '-'; + assert(current >= buffer); + return current; +} + +std::string valueToString(LargestUInt value) { + UIntToStringBuffer buffer; + char* current = buffer + sizeof(buffer); + uintToString(value, current); + assert(current >= buffer); + return current; +} + +#if defined(JSON_HAS_INT64) + +std::string valueToString(Int value) { + return valueToString(LargestInt(value)); +} + +std::string valueToString(UInt value) { + return valueToString(LargestUInt(value)); +} + +#endif // # if defined(JSON_HAS_INT64) + +std::string valueToString(double value) { + // Allocate a buffer that is more than large enough to store the 16 digits of + // precision requested below. + char buffer[32]; + int len = -1; + +// Print into the buffer. We need not request the alternative representation +// that always has a decimal point because JSON doesn't distingish the +// concepts of reals and integers. +#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with + // visual studio 2005 to + // avoid warning. +#if defined(WINCE) + len = _snprintf(buffer, sizeof(buffer), "%.17g", value); +#else + len = sprintf_s(buffer, sizeof(buffer), "%.17g", value); +#endif +#else + if (isfinite(value)) { + len = snprintf(buffer, sizeof(buffer), "%.17g", value); + } else { + // IEEE standard states that NaN values will not compare to themselves + if (value != value) { + len = snprintf(buffer, sizeof(buffer), "null"); + } else if (value < 0) { + len = snprintf(buffer, sizeof(buffer), "-1e+9999"); + } else { + len = snprintf(buffer, sizeof(buffer), "1e+9999"); + } + // For those, we do not need to call fixNumLoc, but it is fast. + } +#endif + assert(len >= 0); + fixNumericLocale(buffer, buffer + len); + return buffer; +} + +std::string valueToString(bool value) { return value ? "true" : "false"; } + +std::string valueToQuotedString(const char* value) { + if (value == NULL) + return ""; + // Not sure how to handle unicode... + if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && + !containsControlCharacter(value)) + return std::string("\"") + value + "\""; + // We have to walk value and escape any special characters. + // Appending to std::string is not efficient, but this should be rare. + // (Note: forward slashes are *not* rare, but I am not escaping them.) + std::string::size_type maxsize = + strlen(value) * 2 + 3; // allescaped+quotes+NULL + std::string result; + result.reserve(maxsize); // to avoid lots of mallocs + result += "\""; + for (const char* c = value; *c != 0; ++c) { + switch (*c) { + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\f': + result += "\\f"; + break; + case '\n': + result += "\\n"; + break; + case '\r': + result += "\\r"; + break; + case '\t': + result += "\\t"; + break; + // case '/': + // Even though \/ is considered a legal escape in JSON, a bare + // slash is also legal, so I see no reason to escape it. + // (I hope I am not misunderstanding something. + // blep notes: actually escaping \/ may be useful in javascript to avoid (*c); + result += oss.str(); + } else { + result += *c; + } + break; + } + } + result += "\""; + return result; +} + +// https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp +static char const* strnpbrk(char const* s, char const* accept, size_t n) { + assert((s || !n) && accept); + + char const* const end = s + n; + for (char const* cur = s; cur < end; ++cur) { + int const c = *cur; + for (char const* a = accept; *a; ++a) { + if (*a == c) { + return cur; + } + } + } + return NULL; +} +static std::string valueToQuotedStringN(const char* value, unsigned length) { + if (value == NULL) + return ""; + // Not sure how to handle unicode... + if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL && + !containsControlCharacter0(value, length)) + return std::string("\"") + value + "\""; + // We have to walk value and escape any special characters. + // Appending to std::string is not efficient, but this should be rare. + // (Note: forward slashes are *not* rare, but I am not escaping them.) + std::string::size_type maxsize = + length * 2 + 3; // allescaped+quotes+NULL + std::string result; + result.reserve(maxsize); // to avoid lots of mallocs + result += "\""; + char const* end = value + length; + for (const char* c = value; c != end; ++c) { + switch (*c) { + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\f': + result += "\\f"; + break; + case '\n': + result += "\\n"; + break; + case '\r': + result += "\\r"; + break; + case '\t': + result += "\\t"; + break; + // case '/': + // Even though \/ is considered a legal escape in JSON, a bare + // slash is also legal, so I see no reason to escape it. + // (I hope I am not misunderstanding something.) + // blep notes: actually escaping \/ may be useful in javascript to avoid (*c); + result += oss.str(); + } else { + result += *c; + } + break; + } + } + result += "\""; + return result; +} + +// Class Writer +// ////////////////////////////////////////////////////////////////// +Writer::~Writer() {} + +// Class FastWriter +// ////////////////////////////////////////////////////////////////// + +FastWriter::FastWriter() + : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false), + omitEndingLineFeed_(false) {} + +void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; } + +void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } + +void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; } + +std::string FastWriter::write(const Value& root) { + document_ = ""; + writeValue(root); + if (!omitEndingLineFeed_) + document_ += "\n"; + return document_; +} + +void FastWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + if (!dropNullPlaceholders_) + document_ += "null"; + break; + case intValue: + document_ += valueToString(value.asLargestInt()); + break; + case uintValue: + document_ += valueToString(value.asLargestUInt()); + break; + case realValue: + document_ += valueToString(value.asDouble()); + break; + case stringValue: + { + // Is NULL possible for value.string_? + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) document_ += valueToQuotedStringN(str, static_cast(end-str)); + break; + } + case booleanValue: + document_ += valueToString(value.asBool()); + break; + case arrayValue: { + document_ += '['; + int size = value.size(); + for (int index = 0; index < size; ++index) { + if (index > 0) + document_ += ','; + writeValue(value[index]); + } + document_ += ']'; + } break; + case objectValue: { + Value::Members members(value.getMemberNames()); + document_ += '{'; + for (Value::Members::iterator it = members.begin(); it != members.end(); + ++it) { + const std::string& name = *it; + if (it != members.begin()) + document_ += ','; + document_ += valueToQuotedStringN(name.data(), name.length()); + document_ += yamlCompatiblityEnabled_ ? ": " : ":"; + writeValue(value[name]); + } + document_ += '}'; + } break; + } +} + +// Class StyledWriter +// ////////////////////////////////////////////////////////////////// + +StyledWriter::StyledWriter() + : rightMargin_(74), indentSize_(3), addChildValues_() {} + +std::string StyledWriter::write(const Value& root) { + document_ = ""; + addChildValues_ = false; + indentString_ = ""; + writeCommentBeforeValue(root); + writeValue(root); + writeCommentAfterValueOnSameLine(root); + document_ += "\n"; + return document_; +} + +void StyledWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + pushValue("null"); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble())); + break; + case stringValue: + { + // Is NULL possible for value.string_? + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) pushValue(valueToQuotedStringN(str, static_cast(end-str))); + else pushValue(""); + break; + } + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + const std::string& name = *it; + const Value& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedString(name.c_str())); + document_ += " : "; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + document_ += ','; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void StyledWriter::writeArrayValue(const Value& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isArrayMultiLine = isMultineArray(value); + if (isArrayMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + const Value& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + writeIndent(); + writeValue(childValue); + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + document_ += ','; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + document_ += "[ "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + document_ += ", "; + document_ += childValues_[index]; + } + document_ += " ]"; + } + } +} + +bool StyledWriter::isMultineArray(const Value& value) { + int size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (int index = 0; index < size && !isMultiLine; ++index) { + const Value& childValue = value[index]; + isMultiLine = + isMultiLine || ((childValue.isArray() || childValue.isObject()) && + childValue.size() > 0); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (int index = 0; index < size; ++index) { + if (hasCommentForValue(value[index])) { + isMultiLine = true; + } + writeValue(value[index]); + lineLength += int(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void StyledWriter::pushValue(const std::string& value) { + if (addChildValues_) + childValues_.push_back(value); + else + document_ += value; +} + +void StyledWriter::writeIndent() { + if (!document_.empty()) { + char last = document_[document_.length() - 1]; + if (last == ' ') // already indented + return; + if (last != '\n') // Comments may add new-line + document_ += '\n'; + } + document_ += indentString_; +} + +void StyledWriter::writeWithIndent(const std::string& value) { + writeIndent(); + document_ += value; +} + +void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); } + +void StyledWriter::unindent() { + assert(int(indentString_.size()) >= indentSize_); + indentString_.resize(indentString_.size() - indentSize_); +} + +void StyledWriter::writeCommentBeforeValue(const Value& root) { + if (!root.hasComment(commentBefore)) + return; + + document_ += "\n"; + writeIndent(); + const std::string& comment = root.getComment(commentBefore); + std::string::const_iterator iter = comment.begin(); + while (iter != comment.end()) { + document_ += *iter; + if (*iter == '\n' && + (iter != comment.end() && *(iter + 1) == '/')) + writeIndent(); + ++iter; + } + + // Comments are stripped of trailing newlines, so add one here + document_ += "\n"; +} + +void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) { + if (root.hasComment(commentAfterOnSameLine)) + document_ += " " + root.getComment(commentAfterOnSameLine); + + if (root.hasComment(commentAfter)) { + document_ += "\n"; + document_ += root.getComment(commentAfter); + document_ += "\n"; + } +} + +bool StyledWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +// Class StyledStreamWriter +// ////////////////////////////////////////////////////////////////// + +StyledStreamWriter::StyledStreamWriter(std::string indentation) + : document_(NULL), rightMargin_(74), indentation_(indentation), + addChildValues_() {} + +void StyledStreamWriter::write(std::ostream& out, const Value& root) { + document_ = &out; + addChildValues_ = false; + indentString_ = ""; + indented_ = true; + writeCommentBeforeValue(root); + if (!indented_) writeIndent(); + indented_ = true; + writeValue(root); + writeCommentAfterValueOnSameLine(root); + *document_ << "\n"; + document_ = NULL; // Forget the stream, for safety. +} + +void StyledStreamWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + pushValue("null"); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble())); + break; + case stringValue: + { + // Is NULL possible for value.string_? + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) pushValue(valueToQuotedStringN(str, static_cast(end-str))); + else pushValue(""); + break; + } + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + const std::string& name = *it; + const Value& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedString(name.c_str())); + *document_ << " : "; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void StyledStreamWriter::writeArrayValue(const Value& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isArrayMultiLine = isMultineArray(value); + if (isArrayMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + const Value& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + if (!indented_) writeIndent(); + indented_ = true; + writeValue(childValue); + indented_ = false; + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + *document_ << "[ "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + *document_ << ", "; + *document_ << childValues_[index]; + } + *document_ << " ]"; + } + } +} + +bool StyledStreamWriter::isMultineArray(const Value& value) { + int size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (int index = 0; index < size && !isMultiLine; ++index) { + const Value& childValue = value[index]; + isMultiLine = + isMultiLine || ((childValue.isArray() || childValue.isObject()) && + childValue.size() > 0); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (int index = 0; index < size; ++index) { + if (hasCommentForValue(value[index])) { + isMultiLine = true; + } + writeValue(value[index]); + lineLength += int(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void StyledStreamWriter::pushValue(const std::string& value) { + if (addChildValues_) + childValues_.push_back(value); + else + *document_ << value; +} + +void StyledStreamWriter::writeIndent() { + // blep intended this to look at the so-far-written string + // to determine whether we are already indented, but + // with a stream we cannot do that. So we rely on some saved state. + // The caller checks indented_. + *document_ << '\n' << indentString_; +} + +void StyledStreamWriter::writeWithIndent(const std::string& value) { + if (!indented_) writeIndent(); + *document_ << value; + indented_ = false; +} + +void StyledStreamWriter::indent() { indentString_ += indentation_; } + +void StyledStreamWriter::unindent() { + assert(indentString_.size() >= indentation_.size()); + indentString_.resize(indentString_.size() - indentation_.size()); +} + +void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { + if (!root.hasComment(commentBefore)) + return; + + if (!indented_) writeIndent(); + const std::string& comment = root.getComment(commentBefore); + std::string::const_iterator iter = comment.begin(); + while (iter != comment.end()) { + *document_ << *iter; + if (*iter == '\n' && + (iter != comment.end() && *(iter + 1) == '/')) + // writeIndent(); // would include newline + *document_ << indentString_; + ++iter; + } + indented_ = false; +} + +void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) { + if (root.hasComment(commentAfterOnSameLine)) + *document_ << ' ' << root.getComment(commentAfterOnSameLine); + + if (root.hasComment(commentAfter)) { + writeIndent(); + *document_ << root.getComment(commentAfter); + } + indented_ = false; +} + +bool StyledStreamWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +////////////////////////// +// BuiltStyledStreamWriter + +/// Scoped enums are not available until C++11. +struct CommentStyle { + /// Decide whether to write comments. + enum Enum { + None, ///< Drop all comments. + Most, ///< Recover odd behavior of previous versions (not implemented yet). + All ///< Keep all comments. + }; +}; + +struct BuiltStyledStreamWriter : public StreamWriter +{ + BuiltStyledStreamWriter( + std::string const& indentation, + CommentStyle::Enum cs, + std::string const& colonSymbol, + std::string const& nullSymbol, + std::string const& endingLineFeedSymbol); + virtual int write(Value const& root, std::ostream* sout); +private: + void writeValue(Value const& value); + void writeArrayValue(Value const& value); + bool isMultineArray(Value const& value); + void pushValue(std::string const& value); + void writeIndent(); + void writeWithIndent(std::string const& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(Value const& root); + void writeCommentAfterValueOnSameLine(Value const& root); + static bool hasCommentForValue(const Value& value); + + typedef std::vector ChildValues; + + ChildValues childValues_; + std::string indentString_; + int rightMargin_; + std::string indentation_; + CommentStyle::Enum cs_; + std::string colonSymbol_; + std::string nullSymbol_; + std::string endingLineFeedSymbol_; + bool addChildValues_ : 1; + bool indented_ : 1; +}; +BuiltStyledStreamWriter::BuiltStyledStreamWriter( + std::string const& indentation, + CommentStyle::Enum cs, + std::string const& colonSymbol, + std::string const& nullSymbol, + std::string const& endingLineFeedSymbol) + : rightMargin_(74) + , indentation_(indentation) + , cs_(cs) + , colonSymbol_(colonSymbol) + , nullSymbol_(nullSymbol) + , endingLineFeedSymbol_(endingLineFeedSymbol) + , addChildValues_(false) + , indented_(false) +{ +} +int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout) +{ + sout_ = sout; + addChildValues_ = false; + indented_ = true; + indentString_ = ""; + writeCommentBeforeValue(root); + if (!indented_) writeIndent(); + indented_ = true; + writeValue(root); + writeCommentAfterValueOnSameLine(root); + *sout_ << endingLineFeedSymbol_; + sout_ = NULL; + return 0; +} +void BuiltStyledStreamWriter::writeValue(Value const& value) { + switch (value.type()) { + case nullValue: + pushValue(nullSymbol_); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble())); + break; + case stringValue: + { + // Is NULL is possible for value.string_? + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) pushValue(valueToQuotedStringN(str, static_cast(end-str))); + else pushValue(""); + break; + } + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + std::string const& name = *it; + Value const& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedStringN(name.data(), name.length())); + *sout_ << colonSymbol_; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *sout_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value); + if (isMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + Value const& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + if (!indented_) writeIndent(); + indented_ = true; + writeValue(childValue); + indented_ = false; + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *sout_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + *sout_ << "["; + if (!indentation_.empty()) *sout_ << " "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + *sout_ << ", "; + *sout_ << childValues_[index]; + } + if (!indentation_.empty()) *sout_ << " "; + *sout_ << "]"; + } + } +} + +bool BuiltStyledStreamWriter::isMultineArray(Value const& value) { + int size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (int index = 0; index < size && !isMultiLine; ++index) { + Value const& childValue = value[index]; + isMultiLine = + isMultiLine || ((childValue.isArray() || childValue.isObject()) && + childValue.size() > 0); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (int index = 0; index < size; ++index) { + if (hasCommentForValue(value[index])) { + isMultiLine = true; + } + writeValue(value[index]); + lineLength += int(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void BuiltStyledStreamWriter::pushValue(std::string const& value) { + if (addChildValues_) + childValues_.push_back(value); + else + *sout_ << value; +} + +void BuiltStyledStreamWriter::writeIndent() { + // blep intended this to look at the so-far-written string + // to determine whether we are already indented, but + // with a stream we cannot do that. So we rely on some saved state. + // The caller checks indented_. + + if (!indentation_.empty()) { + // In this case, drop newlines too. + *sout_ << '\n' << indentString_; + } +} + +void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) { + if (!indented_) writeIndent(); + *sout_ << value; + indented_ = false; +} + +void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; } + +void BuiltStyledStreamWriter::unindent() { + assert(indentString_.size() >= indentation_.size()); + indentString_.resize(indentString_.size() - indentation_.size()); +} + +void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { + if (cs_ == CommentStyle::None) return; + if (!root.hasComment(commentBefore)) + return; + + if (!indented_) writeIndent(); + const std::string& comment = root.getComment(commentBefore); + std::string::const_iterator iter = comment.begin(); + while (iter != comment.end()) { + *sout_ << *iter; + if (*iter == '\n' && + (iter != comment.end() && *(iter + 1) == '/')) + // writeIndent(); // would write extra newline + *sout_ << indentString_; + ++iter; + } + indented_ = false; +} + +void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) { + if (cs_ == CommentStyle::None) return; + if (root.hasComment(commentAfterOnSameLine)) + *sout_ << " " + root.getComment(commentAfterOnSameLine); + + if (root.hasComment(commentAfter)) { + writeIndent(); + *sout_ << root.getComment(commentAfter); + } +} + +// static +bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +/////////////// +// StreamWriter + +StreamWriter::StreamWriter() + : sout_(NULL) +{ +} +StreamWriter::~StreamWriter() +{ +} +StreamWriter::Factory::~Factory() +{} +StreamWriterBuilder::StreamWriterBuilder() +{ + setDefaults(&settings_); +} +StreamWriterBuilder::~StreamWriterBuilder() +{} +StreamWriter* StreamWriterBuilder::newStreamWriter() const +{ + std::string indentation = settings_["indentation"].asString(); + std::string cs_str = settings_["commentStyle"].asString(); + bool eyc = settings_["enableYAMLCompatibility"].asBool(); + bool dnp = settings_["dropNullPlaceholders"].asBool(); + CommentStyle::Enum cs = CommentStyle::All; + if (cs_str == "All") { + cs = CommentStyle::All; + } else if (cs_str == "None") { + cs = CommentStyle::None; + } else { + throwRuntimeError("commentStyle must be 'All' or 'None'"); + } + std::string colonSymbol = " : "; + if (eyc) { + colonSymbol = ": "; + } else if (indentation.empty()) { + colonSymbol = ":"; + } + std::string nullSymbol = "null"; + if (dnp) { + nullSymbol = ""; + } + std::string endingLineFeedSymbol = ""; + return new BuiltStyledStreamWriter( + indentation, cs, + colonSymbol, nullSymbol, endingLineFeedSymbol); +} +static void getValidWriterKeys(std::set* valid_keys) +{ + valid_keys->clear(); + valid_keys->insert("indentation"); + valid_keys->insert("commentStyle"); + valid_keys->insert("enableYAMLCompatibility"); + valid_keys->insert("dropNullPlaceholders"); +} +bool StreamWriterBuilder::validate(Json::Value* invalid) const +{ + Json::Value my_invalid; + if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL + Json::Value& inv = *invalid; + std::set valid_keys; + getValidWriterKeys(&valid_keys); + Value::Members keys = settings_.getMemberNames(); + size_t n = keys.size(); + for (size_t i = 0; i < n; ++i) { + std::string const& key = keys[i]; + if (valid_keys.find(key) == valid_keys.end()) { + inv[key] = settings_[key]; + } + } + return 0u == inv.size(); +} +Value& StreamWriterBuilder::operator[](std::string key) +{ + return settings_[key]; +} +// static +void StreamWriterBuilder::setDefaults(Json::Value* settings) +{ + //! [StreamWriterBuilderDefaults] + (*settings)["commentStyle"] = "All"; + (*settings)["indentation"] = "\t"; + (*settings)["enableYAMLCompatibility"] = false; + (*settings)["dropNullPlaceholders"] = false; + //! [StreamWriterBuilderDefaults] +} + +std::string writeString(StreamWriter::Factory const& builder, Value const& root) { + std::ostringstream sout; + StreamWriterPtr const writer(builder.newStreamWriter()); + writer->write(root, &sout); + return sout.str(); +} + +std::ostream& operator<<(std::ostream& sout, Value const& root) { + StreamWriterBuilder builder; + StreamWriterPtr const writer(builder.newStreamWriter()); + writer->write(root, &sout); + return sout; +} + +} // namespace Json + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: src/lib_json/json_writer.cpp +// ////////////////////////////////////////////////////////////////////// + + + + + diff --git a/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/main.cpp b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/main.cpp new file mode 100644 index 0000000..6e6a03b --- /dev/null +++ b/gpu/third_party/sirit/externals/SPIRV-Headers/tools/buildHeaders/main.cpp @@ -0,0 +1,130 @@ +// 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. + +//#include +#include +#include + +#include "jsonToSpirv.h" +#include "header.h" + +// Command-line options +enum TOptions { + EOptionNone = 0x000, + EOptionPrintHeader = 0x008, +}; + +std::string jsonPath; +int Options; +spv::TLanguage Language; + +void Usage() +{ + printf("Usage: spirv option [file]\n" + "\n" + " -h print header for given language to stdout, from one of:\n" + " C - C99 header\n" + " C++ - C++03 or greater header (also accepts C++03)\n" + " C++11 - C++11 or greater header\n" + " JSON - JSON format data\n" + " Lua - Lua module\n" + " Python - Python module (also accepts Py)\n" + " C# - C# module (also accepts CSharp)\n" + " D - D module\n" + " Beef - Beef module\n" + " -H print header in all supported languages to files in current directory\n" + ); +} + +std::string tolower_s(std::string s) +{ + std::transform(s.begin(), s.end(), s.begin(), ::tolower); + return s; +} + +bool ProcessArguments(int argc, char* argv[]) +{ + argc--; + argv++; + for (; argc >= 1; argc--, argv++) { + if (argv[0][0] == '-') { + switch (argv[0][1]) { + case 'H': + Options |= EOptionPrintHeader; + Language = spv::ELangAll; + break; + case 'h': { + if (argc < 2) + return false; + + Options |= EOptionPrintHeader; + const std::string language(tolower_s(argv[1])); + + if (language == "c") { + Language = spv::ELangC; + } else if (language == "c++" || language == "c++03") { + Language = spv::ELangCPP; + } else if (language == "c++11") { + Language = spv::ELangCPP11; + } else if (language == "json") { + Language = spv::ELangJSON; + } else if (language == "lua") { + Language = spv::ELangLua; + } else if (language == "python" || language == "py") { + Language = spv::ELangPython; + } else if (language == "c#" || language == "csharp") { + Language = spv::ELangCSharp; + } else if (language == "d") { + Language = spv::ELangD; + } else if (language == "beef") { + Language = spv::ELangBeef; + } else + return false; + + return true; + } + default: + return false; + } + } else { + jsonPath = std::string(argv[0]); + } + } + + return true; +} + +int main(int argc, char* argv[]) +{ + if (argc < 2 || ! ProcessArguments(argc, argv)) { + Usage(); + return 1; + } + + spv::jsonToSpirv(jsonPath, (Options & EOptionPrintHeader) != 0); + if (Options & EOptionPrintHeader) + spv::PrintHeader(Language, std::cout); + + return 0; +} diff --git a/gpu/third_party/sirit/include/sirit/sirit.h b/gpu/third_party/sirit/include/sirit/sirit.h new file mode 100644 index 0000000..441dc88 --- /dev/null +++ b/gpu/third_party/sirit/include/sirit/sirit.h @@ -0,0 +1,1537 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Sirit { + +constexpr std::uint32_t GENERATOR_MAGIC_NUMBER = 0; + +class Declarations; +class Operand; +class Stream; + +using Literal = + std::variant; + +using MemoryAccessLiteral = std::variant; + +struct Id { + std::uint32_t value; +}; + +[[nodiscard]] inline bool ValidId(Id id) noexcept { + return id.value != 0; +} + +class Module { +public: + explicit Module(std::uint32_t version = spv::Version); + ~Module(); + + /** + * Assembles current module into a SPIR-V stream. + * It can be called multiple times but it's recommended to copy code + * externally. + * @return A stream of bytes representing a SPIR-V module. + */ + std::vector Assemble() const; + + /// Patches deferred phi nodes calling the passed function on each phi argument + void PatchDeferredPhi(const std::function(std::size_t arg, Id parent)>& func); + + /// Adds a SPIR-V extension. + void AddExtension(std::string extension_name); + + /// Adds a module capability. + void AddCapability(spv::Capability capability); + + /// Sets module memory model. + void SetMemoryModel(spv::AddressingModel addressing_model_, spv::MemoryModel memory_model_); + + /// Adds an entry point. + void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string_view name, + std::span interfaces = {}); + + /// Adds an entry point. + // TODO: Change std::is_convertible_v to std::convertible_to when compilers + // support it; same elsewhere. + template + requires(...&& std::is_convertible_v) void AddEntryPoint( + spv::ExecutionModel execution_model, Id entry_point, std::string_view name, + Ts&&... interfaces) { + AddEntryPoint(execution_model, std::move(entry_point), name, + std::span({interfaces...})); + } + + /// Declare an execution mode for an entry point. + void AddExecutionMode(Id entry_point, spv::ExecutionMode mode, + std::span literals = {}); + + /// Declare an execution mode for an entry point. + template + requires(...&& std::is_convertible_v) void AddExecutionMode( + Id entry_point, spv::ExecutionMode mode, Ts&&... literals) { + AddExecutionMode(entry_point, mode, std::span({literals...})); + } + + /** + * Adds an existing label to the code + * @param label Label to insert into code. + * @return Returns label. + */ + Id AddLabel(Id label); + + /** + * Adds a label to the code + * @return Returns the created label. + */ + Id AddLabel() { + return AddLabel(OpLabel()); + } + + /// Adds a local variable to the code + Id AddLocalVariable(Id result_type, spv::StorageClass storage_class, + std::optional initializer = std::nullopt); + + /// Adds a global variable + Id AddGlobalVariable(Id result_type, spv::StorageClass storage_class, + std::optional initializer = std::nullopt); + + // Types + + /// Returns type void. + Id TypeVoid(); + + /// Returns type bool. + Id TypeBool(); + + /// Returns type integer. + Id TypeInt(int width, bool is_signed); + + /// Returns type signed integer. + Id TypeSInt(int width); + + /// Returns type unsigned integer. + Id TypeUInt(int width); + + /// Returns type float. + Id TypeFloat(int width); + + /// Returns type vector. + Id TypeVector(Id component_type, int component_count); + + /// Returns type matrix. + Id TypeMatrix(Id column_type, int column_count); + + /// Returns type image. + Id TypeImage(Id sampled_type, spv::Dim dim, int depth, bool arrayed, bool ms, int sampled, + spv::ImageFormat image_format, + std::optional access_qualifier = std::nullopt); + + /// Returns type sampler. + Id TypeSampler(); + + /// Returns type sampled image. + Id TypeSampledImage(Id image_type); + + /// Returns type array. + Id TypeArray(Id element_type, Id length); + + /// Returns type runtime array. + Id TypeRuntimeArray(Id element_type); + + /// Returns type struct. + Id TypeStruct(std::span members = {}); + + /// Returns type struct. + template + requires(...&& std::is_convertible_v) Id TypeStruct(Ts&&... members) { + return TypeStruct(std::span({members...})); + } + + /// Returns type opaque. + Id TypeOpaque(std::string_view name); + + /// Returns type pointer. + Id TypePointer(spv::StorageClass storage_class, Id type); + + /// Returns type function. + Id TypeFunction(Id return_type, std::span arguments = {}); + + /// Returns type function. + template + requires(...&& std::is_convertible_v) Id + TypeFunction(Id return_type, Ts&&... arguments) { + return TypeFunction(return_type, std::span({arguments...})); + } + + /// Returns type event. + Id TypeEvent(); + + /// Returns type device event. + Id TypeDeviceEvent(); + + /// Returns type reserve id. + Id TypeReserveId(); + + /// Returns type queue. + Id TypeQueue(); + + /// Returns type pipe. + Id TypePipe(spv::AccessQualifier access_qualifier); + + // Constant + + /// Returns a true scalar constant. + Id ConstantTrue(Id result_type); + + /// Returns a false scalar constant. + Id ConstantFalse(Id result_type); + + /// Returns a numeric scalar constant. + Id Constant(Id result_type, const Literal& literal); + + /// Returns a numeric scalar constant. + Id ConstantComposite(Id result_type, std::span constituents); + + /// Returns a numeric scalar constant. + template + requires(...&& std::is_convertible_v) Id + ConstantComposite(Id result_type, Ts&&... constituents) { + return ConstantComposite(result_type, std::span({constituents...})); + } + + /// Returns a sampler constant. + Id ConstantSampler(Id result_type, spv::SamplerAddressingMode addressing_mode, bool normalized, + spv::SamplerFilterMode filter_mode); + + /// Returns a null constant value. + Id ConstantNull(Id result_type); + + // Function + + /// Declares a function. + Id OpFunction(Id result_type, spv::FunctionControlMask function_control, Id function_type); + + /// Ends a function. + void OpFunctionEnd(); + + /// Call a function. + Id OpFunctionCall(Id result_type, Id function, std::span arguments = {}); + + /// Call a function. + template + requires(...&& std::is_convertible_v) Id + OpFunctionCall(Id result_type, Id function, Ts&&... arguments) { + return OpFunctionCall(result_type, function, std::span({arguments...})); + } + + /// Declare a formal parameter of the current function. + Id OpFunctionParameter(Id result_type); + + // Flow + + /** + * The SSA phi function. + * + * @param result_type The result type. + * @param operands An immutable span of variable, parent block pairs + */ + Id OpPhi(Id result_type, std::span operands); + + template + requires(...&& std::is_convertible_v) Id + OpPhi(Id result_type, Ts&&... operands) { + return OpPhi(result_type, std::span({operands...})); + } + + /** + * The SSA phi function. This instruction will be revisited when patching phi nodes. + * + * @param result_type The result type. + * @param blocks An immutable span of block pairs. + */ + Id DeferredOpPhi(Id result_type, std::span blocks); + + /// Declare a structured loop. + Id OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control, + std::span literals = {}); + + /// Declare a structured loop. + template + requires(...&& std::is_convertible_v) Id + OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control, + Ts&&... literals) { + return OpLoopMerge(merge_block, continue_target, loop_control, + std::span({literals...})); + } + + /// Declare a structured selection. + Id OpSelectionMerge(Id merge_block, spv::SelectionControlMask selection_control); + + /// The block label instruction: Any reference to a block is through this ref. + Id OpLabel(); + + /// The block label instruction: Any reference to a block is through this ref. + Id OpLabel(std::string_view label_name) { + return Name(OpLabel(), label_name); + } + + /// Unconditional jump to label. + Id OpBranch(Id target_label); + + /// If condition is true branch to true_label, otherwise branch to + /// false_label. + Id OpBranchConditional(Id condition, Id true_label, Id false_label, + std::uint32_t true_weight = 0, std::uint32_t false_weight = 0); + + /// Multi-way branch to one of the operand label. + Id OpSwitch(Id selector, Id default_label, std::span literals, + std::span labels); + + /// Returns with no value from a function with void return type. + void OpReturn(); + + /// Behavior is undefined if this instruction is executed. + void OpUnreachable(); + + /// Return a value from a function. + Id OpReturnValue(Id value); + + /// Fragment-shader discard. + void OpKill(); + + /// Demote fragment shader invocation to a helper invocation + void OpDemoteToHelperInvocationEXT(); + + // Debug + + /// Assign a name string to a reference. + /// @return target + Id Name(Id target, std::string_view name); + + /// Assign a name string to a member of a structure type. + /// @return type + Id MemberName(Id type, std::uint32_t member, std::string_view name); + + /// Assign a Result to a string for use by other debug instructions. + Id String(std::string_view string); + + /// Add source-level location information + Id OpLine(Id file, Literal line, Literal column); + + // Memory + + /// Form a pointer to a texel of an image. Use of such a pointer is limited to atomic + /// operations. + Id OpImageTexelPointer(Id result_type, Id image, Id coordinate, Id sample); + + /// Load through a pointer. + Id OpLoad(Id result_type, Id pointer, + std::span memory_access = {}); + + /// Load through a pointer. + template + requires(...&& std::is_convertible_v) Id + OpLoad(Id result_type, Id pointer, Ts&&... memory_access) { + return OpLoad(result_type, pointer, std::span({memory_access...})); + } + + /// Store through a pointer. + Id OpStore(Id pointer, Id object, + std::span memory_access = {}); + + /// Store through a pointer. + template + requires(...&& std::is_convertible_v) Id + OpStore(Id pointer, Id object, Ts&&... memory_access) { + return OpStore(pointer, object, std::span({memory_access...})); + } + + /// Create a pointer into a composite object that can be used with OpLoad and OpStore. + Id OpAccessChain(Id result_type, Id base, std::span indexes = {}); + + /// Create a pointer into a composite object that can be used with OpLoad and OpStore. + template + requires(...&& std::is_convertible_v) Id + OpAccessChain(Id result_type, Id base, Ts&&... indexes) { + return OpAccessChain(result_type, base, std::span({indexes...})); + } + + /// Extract a single, dynamically selected, component of a vector. + Id OpVectorExtractDynamic(Id result_type, Id vector, Id index); + + /// Make a copy of a vector, with a single, variably selected, component modified. + Id OpVectorInsertDynamic(Id result_type, Id vector, Id component, Id index); + + /// Select arbitrary components from two vectors to make a new vector. + Id OpVectorShuffle(Id result_type, Id vector_1, Id vector_2, std::span components); + + /// Select arbitrary components from two vectors to make a new vector. + template + requires(...&& std::is_convertible_v) Id + OpVectorShuffle(Id result_type, Id vector_1, Id vector_2, Ts&&... components) { + const Literal stack_literals[] = {std::forward(components)...}; + return OpVectorShuffle(result_type, vector_1, vector_2, std::span{stack_literals}); + } + + /// Make a copy of a composite object, while modifying one part of it. + Id OpCompositeInsert(Id result_type, Id object, Id composite, + std::span indexes = {}); + + /// Make a copy of a composite object, while modifying one part of it. + template + requires(...&& std::is_convertible_v) Id + OpCompositeInsert(Id result_type, Id object, Id composite, Ts&&... indexes) { + const Literal stack_indexes[] = {std::forward(indexes)...}; + return OpCompositeInsert(result_type, object, composite, + std::span{stack_indexes}); + } + + /// Extract a part of a composite object. + Id OpCompositeExtract(Id result_type, Id composite, std::span indexes = {}); + + /// Extract a part of a composite object. + template + requires(...&& std::is_convertible_v) Id + OpCompositeExtract(Id result_type, Id composite, Ts&&... indexes) { + const Literal stack_indexes[] = {std::forward(indexes)...}; + return OpCompositeExtract(result_type, composite, std::span{stack_indexes}); + } + + /// Construct a new composite object from a set of constituent objects that will fully form it. + Id OpCompositeConstruct(Id result_type, std::span ids); + + /// Construct a new composite object from a set of constituent objects that will fully form it. + template + requires(...&& std::is_convertible_v) Id + OpCompositeConstruct(Id result_type, Ts&&... ids) { + return OpCompositeConstruct(result_type, std::span({ids...})); + } + + // Annotation + + /// Add a decoration to target. + Id Decorate(Id target, spv::Decoration decoration, std::span literals = {}); + + /// Add a decoration to target. + template + requires(...&& std::is_convertible_v) Id + Decorate(Id target, spv::Decoration decoration, Ts&&... literals) { + const Literal stack_literals[] = {std::forward(literals)...}; + return Decorate(target, decoration, std::span{stack_literals}); + } + + /// Add a decoration to target. + template + requires std::is_enum_v Id Decorate(Id target, spv::Decoration decoration, T literal) { + return Decorate(target, decoration, static_cast(literal)); + } + + Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration, + std::span literals = {}); + + template + requires(...&& std::is_convertible_v) Id + MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration, + Ts&&... literals) { + const Literal stack_literals[] = {std::forward(literals)...}; + return MemberDecorate(structure_type, member, decoration, + std::span{stack_literals}); + } + + // Misc + + /// Make an intermediate object whose value is undefined. + Id OpUndef(Id result_type); + + /// Emits the current values of all output variables to the current output primitive. + void OpEmitVertex(); + + /// Finish the current primitive and start a new one. No vertex is emitted. + void OpEndPrimitive(); + + /// Emits the current values of all output variables to the current output primitive. After + /// execution, the values of all output variables are undefined. + void OpEmitStreamVertex(Id stream); + + /// Finish the current primitive and start a new one. No vertex is emitted. + void OpEndStreamPrimitive(Id stream); + + Id OpReadClockKHR(Id result_type, Id scope); + + // Barrier + + /// Wait for other invocations of this module to reach the current point of execution. + Id OpControlBarrier(Id execution, Id memory, Id semantics); + + /// Control the order that memory accesses are observed. + Id OpMemoryBarrier(Id scope, Id semantics); + + // Logical + + /// Result is true if any component of Vector is true, otherwise result is false. + Id OpAny(Id result_type, Id vector); + + /// Result is true if all components of Vector are true, otherwise result is false. + Id OpAll(Id result_type, Id vector); + + /// Result is true if x is an IEEE NaN, otherwise result is false. + Id OpIsNan(Id result_type, Id operand); + + /// Result is true if x is an IEEE Inf, otherwise result is false. + Id OpIsInf(Id result_type, Id operand); + + /// Result is true if Operand 1 and Operand 2 have the same value. Result is false if Operand 1 + /// and Operand 2 have different values. + Id OpLogicalEqual(Id result_type, Id operand_1, Id operand_2); + + /// Result is true if Operand 1 and Operand 2 have different values. Result is false if Operand + /// 1 and Operand 2 have the same value. + Id OpLogicalNotEqual(Id result_type, Id operand_1, Id operand_2); + + /// Result is true if either Operand 1 or Operand 2 is true. Result is false if both Operand 1 + /// and Operand 2 are false. + Id OpLogicalOr(Id result_type, Id operand_1, Id operand_2); + + /// Result is true if both Operand 1 and Operand 2 are true. Result is false if either Operand 1 + /// or Operand 2 are false. + Id OpLogicalAnd(Id result_type, Id operand_1, Id operand_2); + + /// Result is true if Operand is false. Result is false if Operand is true. + Id OpLogicalNot(Id result_type, Id operand); + + /// Select components from two objects. + Id OpSelect(Id result_type, Id condition, Id operand_1, Id operand_2); + + /// Integer comparison for equality. + Id OpIEqual(Id result_type, Id operand_1, Id operand_2); + + /// Integer comparison for inequality. + Id OpINotEqual(Id result_type, Id operand_1, Id operand_2); + + /// Unsigned-integer comparison if Operand 1 is greater than Operand 2. + Id OpUGreaterThan(Id result_type, Id operand_1, Id operand_2); + + /// Signed-integer comparison if Operand 1 is greater than Operand 2. + Id OpSGreaterThan(Id result_type, Id operand_1, Id operand_2); + + /// Unsigned-integer comparison if Operand 1 is greater than or equal to Operand 2. + Id OpUGreaterThanEqual(Id result_type, Id operand_1, Id operand_2); + + /// Signed-integer comparison if Operand 1 is greater than or equal to Operand 2. + Id OpSGreaterThanEqual(Id result_type, Id operand_1, Id operand_2); + + /// Unsigned-integer comparison if Operand 1 is less than Operand 2. + Id OpULessThan(Id result_type, Id operand_1, Id operand_2); + + /// Signed-integer comparison if Operand 1 is less than Operand 2. + Id OpSLessThan(Id result_type, Id operand_1, Id operand_2); + + /// Unsigned-integer comparison if Operand 1 is less than or equal to Operand 2. + Id OpULessThanEqual(Id result_type, Id operand_1, Id operand_2); + + /// Signed-integer comparison if Operand 1 is less than or equal to Operand 2. + Id OpSLessThanEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison for being ordered and equal. + Id OpFOrdEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison for being unordered or equal. + Id OpFUnordEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison for being ordered and not equal. + Id OpFOrdNotEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison for being unordered or not equal. + Id OpFUnordNotEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are ordered and Operand 1 is less than Operand 2. + Id OpFOrdLessThan(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are unordered or Operand 1 is less than Operand 2. + Id OpFUnordLessThan(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are ordered and Operand 1 is greater than Operand 2. + Id OpFOrdGreaterThan(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are unordered or Operand 1 is greater than Operand 2. + Id OpFUnordGreaterThan(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are ordered and Operand 1 is less than or equal to + /// Operand 2. + Id OpFOrdLessThanEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are unordered or Operand 1 is less than or equal to + /// Operand 2. + Id OpFUnordLessThanEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are ordered and Operand 1 is greater than or equal to + /// Operand 2. + Id OpFOrdGreaterThanEqual(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point comparison if operands are unordered or Operand 1 is greater than or equal to + /// Operand 2. + Id OpFUnordGreaterThanEqual(Id result_type, Id operand_1, Id operand_2); + + // Conversion + + /// Convert (value preserving) from floating point to unsigned integer, with round toward 0.0. + Id OpConvertFToU(Id result_type, Id operand); + + /// Convert (value preserving) from floating point to signed integer, with round toward 0.0. + Id OpConvertFToS(Id result_type, Id operand); + + /// Convert (value preserving) from signed integer to floating point. + Id OpConvertSToF(Id result_type, Id operand); + + /// Convert (value preserving) from unsigned integer to floating point. + Id OpConvertUToF(Id result_type, Id operand); + + /// Convert (value preserving) from unsigned integer to pointer. + Id OpConvertUToPtr(Id result_type, Id operand); + + /// Convert (value preserving) from pointer to unsigned integer. + Id OpConvertPtrToU(Id result_type, Id operand); + + /// Convert (value preserving) unsigned width. This is either a truncate or a zero extend. + Id OpUConvert(Id result_type, Id operand); + + /// Convert (value preserving) signed width. This is either a truncate or a sign extend. + Id OpSConvert(Id result_type, Id operand); + + /// Convert (value preserving) floating-point width. + Id OpFConvert(Id result_type, Id operand); + + /// Quantize a floating-point value to what is expressible by a 16-bit floating-point value. + Id OpQuantizeToF16(Id result_type, Id operand); + + /// Bit pattern-preserving type conversion. + Id OpBitcast(Id result_type, Id operand); + + // Bit + + /// Shift the bits in Base right by the number of bits specified in Shift. + /// The most-significant bits will be zero filled. + Id OpShiftRightLogical(Id result_type, Id base, Id shift); + + /// Shift the bits in Base right by the number of bits specified in Shift. + /// The most-significant bits will be filled with the sign bit from Base. + Id OpShiftRightArithmetic(Id result_type, Id base, Id shift); + + /// Shift the bits in Base left by the number of bits specified in Shift. + /// The least-significant bits will be zero filled. + Id OpShiftLeftLogical(Id result_type, Id base, Id shift); + + /// Does a bitwise Or between operands 1 and 2. + Id OpBitwiseOr(Id result_type, Id operand_1, Id operand_2); + + /// Does a bitwise Xor between operands 1 and 2. + Id OpBitwiseXor(Id result_type, Id operand_1, Id operand_2); + + /// Result is 1 if both Operand 1 and Operand 2 are 1. Result is 0 if either + /// Operand 1 or Operand 2 are 0. + Id OpBitwiseAnd(Id result_type, Id operand_1, Id operand_2); + + /// Does a bitwise Not on the operand. + Id OpNot(Id result_type, Id operand); + + /// Make a copy of an object, with a modified bit field that comes from another object. + Id OpBitFieldInsert(Id result_type, Id base, Id insert, Id offset, Id count); + + /// Extract a bit field from an object, with sign extension. + Id OpBitFieldSExtract(Id result_type, Id base, Id offset, Id count); + + /// Extract a bit field from an object, without sign extension. + Id OpBitFieldUExtract(Id result_type, Id base, Id offset, Id count); + + /// Reverse the bits in an object. + Id OpBitReverse(Id result_type, Id base); + + /// Count the number of set bits in an object. + Id OpBitCount(Id result_type, Id base); + + // Arithmetic + + /// Floating-point subtract of Operand from zero. + Id OpSNegate(Id result_type, Id operand); + + /// Floating-point subtract of Operand from zero. + Id OpFNegate(Id result_type, Id operand); + + /// Integer addition of Operand 1 and Operand 2. + Id OpIAdd(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point addition of Operand 1 and Operand 2. + Id OpFAdd(Id result_type, Id operand_1, Id operand_2); + + /// Integer substraction of Operand 1 and Operand 2. + Id OpISub(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point subtraction of Operand 1 and Operand 2. + Id OpFSub(Id result_type, Id operand_1, Id operand_2); + + /// Integer multiplication of Operand 1 and Operand 2. + Id OpIMul(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point multiplication of Operand 1 and Operand 2. + Id OpFMul(Id result_type, Id operand_1, Id operand_2); + + /// Full signed interger multiplication of Operand 1 and Operand 2. + Id OpSMulExtended(Id result_type, Id operand_1, Id operand_2); + + /// Full unsigned interger multiplication of Operand 1 and Operand 2. + Id OpUMulExtended(Id result_type, Id operand_1, Id operand_2); + + /// Unsigned-integer division of Operand 1 divided by Operand 2. + Id OpUDiv(Id result_type, Id operand_1, Id operand_2); + + /// signed-integer division of Operand 1 divided by Operand 2. + Id OpSDiv(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point division of Operand 1 divided by Operand 2. + Id OpFDiv(Id result_type, Id operand_1, Id operand_2); + + /// Unsigned modulo operation of Operand 1 modulo Operand 2. + Id OpUMod(Id result_type, Id operand_1, Id operand_2); + + /// Signed modulo operation of Operand 1 modulo Operand 2. + Id OpSMod(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point modulo operation of Operand 1 modulo Operand 2. + Id OpFMod(Id result_type, Id operand_1, Id operand_2); + + /// Signed reminder operation of Operand 1 modulo Operand 2. + Id OpSRem(Id result_type, Id operand_1, Id operand_2); + + /// Floating-point reminder operation of Operand 1 modulo Operand 2. + Id OpFRem(Id result_type, Id operand_1, Id operand_2); + + /// Result is the unsigned integer addition of Operand 1 and Operand 2, including its carry. + Id OpIAddCarry(Id result_type, Id operand_1, Id operand_2); + + /// Multiplication of floating-point vector Operand 1 with scalar Operand 2. + Id OpVectorTimesScalar(Id result_type, Id operand_1, Id operand_2); + + /// Dot product of floating-point vector Operand 1 and vector Operand 2. + Id OpDot(Id result_type, Id operand_1, Id operand_2); + + // Extensions + + /// Execute an instruction in an imported set of extended instructions. + Id OpExtInst(Id result_type, Id set, std::uint32_t instruction, std::span operands); + + /// Execute an instruction in an imported set of extended instructions. + template + requires(...&& std::is_convertible_v) Id + OpExtInst(Id result_type, Id set, std::uint32_t instruction, Ts&&... operands) { + return OpExtInst(result_type, set, instruction, std::span({operands...})); + } + + /// Result is x if x >= 0; otherwise result is -x. + Id OpFAbs(Id result_type, Id x); + + /// Result is x if x >= 0; otherwise result is -x. + Id OpSAbs(Id result_type, Id x); + + /// Result is the value equal to the nearest whole number to x. The fraction 0.5 will round in a + /// direction chosen by the implementation, presumably the direction that is fastest. + Id OpRound(Id result_type, Id x); + + /// Result is the value equal to the nearest whole number to x. A fractional part of 0.5 will + /// round toward the nearest even whole number. + Id OpRoundEven(Id result_type, Id x); + + /// Result is the value equal to the nearest whole number to x whose absolute value is not + /// larger than the absolute value of x. + Id OpTrunc(Id result_type, Id x); + + /// Result is 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0. + Id OpFSign(Id result_type, Id x); + + /// Result is 1 if x > 0, 0 if x = 0, or -1 if x < 0, where x is interpreted as a signed + /// integer. + Id OpSSign(Id result_type, Id x); + + /// Result is the value equal to the nearest whole number that is less than or equal to x. + Id OpFloor(Id result_type, Id x); + + /// Result is the value equal to the nearest whole number that is greater than or equal to x. + Id OpCeil(Id result_type, Id x); + + /// Result is x - floor x. + Id OpFract(Id result_type, Id x); + + /// The standard trigonometric sine of x radians. + Id OpSin(Id result_type, Id x); + + /// The standard trigonometric cosine of x radians. + Id OpCos(Id result_type, Id x); + + /// Arc sine. Result is an angle, in radians, whose sine is x. The range of result values is + /// [-pi / 2, pi / 2]. Result is undefined if abs x > 1. + Id OpAsin(Id result_type, Id x); + + /// Arc cosine. Result is an angle, in radians, whose cosine is x. The range of result values is + /// [0, pi]. Result is undefined if abs x > 1. + Id OpAcos(Id result_type, Id x); + + /// Result is x raised to the y power. Result is undefined if x < 0. Result is undefined if x = + /// 0 and y <= 0. + Id OpPow(Id result_type, Id x, Id y); + + /// Result is the natural exponentiation of x. + Id OpExp(Id result_type, Id x); + + /// Result is the natural logarithm of x. Result is undefined if x <= 0. + Id OpLog(Id result_type, Id x); + + /// Result is 2 raised to the x power. + Id OpExp2(Id result_type, Id x); + + /// Result is the base-2 logarithm of x. Result is undefined if x <= 0. + Id OpLog2(Id result_type, Id x); + + /// Result is the square root of x. Result is undefined if x < 0. + Id OpSqrt(Id result_type, Id x); + + /// Result is the reciprocal of sqrt x. Result is undefined if x <= 0. + Id OpInverseSqrt(Id result_type, Id x); + + /// Result is a floating-point number from x and the corresponding integral exponent of two in exp. + Id OpLdexp(Id result_type, Id x, Id exp); + + /// Result is y if y < x; otherwise result is x. Which operand is the result is undefined if one + /// of the operands is a NaN. + Id OpFMin(Id result_type, Id x, Id y); + + /// Result is y if y < x; otherwise result is x, where x and y are interpreted as unsigned + /// integers. + Id OpUMin(Id result_type, Id x, Id y); + + /// Result is y if y < x; otherwise result is x, where x and y are interpreted as signed + /// integers. + Id OpSMin(Id result_type, Id x, Id y); + + /// Result is y if y < x, either x or y if both x and y are zeros, otherwise x. If one operand is a NaN, the other + /// operand is the result. If both operands are NaN, the result is a NaN. + Id OpNMin(Id result_type, Id x, Id y); + + /// Result is y if x < y; otherwise result is x. Which operand is the result is undefined if one + /// of the operands is a NaN. + Id OpFMax(Id result_type, Id x, Id y); + + /// Result is y if x < y; otherwise result is x, where x and y are interpreted as unsigned + /// integers. + Id OpUMax(Id result_type, Id x, Id y); + + /// Result is y if x < y; otherwise result is x, where x and y are interpreted as signed + /// integers. + Id OpSMax(Id result_type, Id x, Id y); + + /// Result is y if x < y, either x or y if both x and y are zeros, otherwise x. If one operand is a NaN, the other + /// operand is the result. If both operands are NaN, the result is a NaN. + Id OpNMax(Id result_type, Id x, Id y); + + /// Result is min(max(x, minVal), maxVal). Result is undefined if minVal > maxVal.The semantics + /// used by min() and max() are those of FMin and FMax. + Id OpFClamp(Id result_type, Id x, Id min_val, Id max_val); + + /// Result is min(max(x, minVal), maxVal), where x, minVal and maxVal are interpreted as + /// unsigned integers. Result is undefined if minVal > maxVal. + Id OpUClamp(Id result_type, Id x, Id min_val, Id max_val); + + /// Result is min(max(x, minVal), maxVal), where x, minVal and maxVal are interpreted as signed + /// integers. Result is undefined if minVal > maxVal. + Id OpSClamp(Id result_type, Id x, Id min_val, Id max_val); + + /// Computes a * b + c. + Id OpFma(Id result_type, Id a, Id b, Id c); + + /// Result is a structure containing x split into a floating-point significand in the range + /// (-1.0, 0.5] or [0.5, 1.0) and an integral exponent of 2, such that: x = significand * 2^exponent + Id OpFrexpStruct(Id result_type, Id x); + + /// Result is the unsigned integer obtained by converting the components of a two-component + /// floating-point vector to the 16-bit OpTypeFloat, and then packing these two 16-bit integers + /// into a 32-bit unsigned integer. + Id OpPackHalf2x16(Id result_type, Id v); + + /// Result is the two-component floating-point vector with components obtained by unpacking a + /// 32-bit unsigned integer into a pair of floating-point 16-bit values. + Id OpUnpackHalf2x16(Id result_type, Id v); + + /// Result is the unsigned integer obtained by converting the components of a two-component + /// unsigned normalized floating-point vector to 16-bit integer values, and then packing these + /// two 16-bit integers into a 32-bit unsigned integer. + Id OpPackUnorm2x16(Id result_type, Id v); + + /// Result is the two-component floating-point vector with components obtained by unpacking a + /// 32-bit unsigned integer into a pair of unsigned normalized 16-bit values. + Id OpUnpackUnorm2x16(Id result_type, Id v); + + /// Result is the unsigned integer obtained by converting the components of a two-component + /// signed normalized floating-point vector to 16-bit integer values, and then packing these + /// two 16-bit integers into a 32-bit unsigned integer. + Id OpPackSnorm2x16(Id result_type, Id v); + + /// Result is the two-component floating-point vector with components obtained by unpacking a + /// 32-bit unsigned integer into a pair of signed normalized 16-bit values. + Id OpUnpackSnorm2x16(Id result_type, Id v); + + /// Result is the unsigned integer obtained by converting the components of a four-component + /// unsigned normalized floating-point vector to 8-bit integer values, and then packing these + /// four 8-bit integers into a 32-bit unsigned integer. + Id OpPackUnorm4x8(Id result_type, Id v); + + /// Result is the four-component floating-point vector with components obtained by unpacking a + /// 32-bit unsigned integer into four unsigned normalized 8-bit values. + Id OpUnpackUnorm4x8(Id result_type, Id v); + + /// Result is the unsigned integer obtained by converting the components of a four-component + /// signed normalized floating-point vector to 8-bit integer values, and then packing these + /// four 8-bit integers into a 32-bit unsigned integer. + Id OpPackSnorm4x8(Id result_type, Id v); + + /// Result is the four-component floating-point vector with components obtained by unpacking a + /// 32-bit unsigned integer into four signed normalized 8-bit values. + Id OpUnpackSnorm4x8(Id result_type, Id v); + + /// Integer least-significant bit. + Id OpFindILsb(Id result_type, Id value); + + /// Signed-integer most-significant bit, with value interpreted as a signed integer. + Id OpFindSMsb(Id result_type, Id value); + + /// Unsigned-integer most-significant bit. + Id OpFindUMsb(Id result_type, Id value); + + /// Result is the value of the input interpolant sampled at a location inside both the pixel and + /// the primitive being processed. + Id OpInterpolateAtCentroid(Id result_type, Id interpolant); + + /// Result is the value of the input interpolant variable at the location of sample number + /// sample. + Id OpInterpolateAtSample(Id result_type, Id interpolant, Id sample); + + /// Result is the value of the input interpolant variable sampled at an offset from the center + /// of the pixel specified by offset. + Id OpInterpolateAtOffset(Id result_type, Id interpolant, Id offset); + + /// Result is the vector in the same direction as x but with a length of 1. + Id OpNormalize(Id result_type, Id x); + + /// Result is the cross product of x and y. + Id OpCross(Id result_type, Id x, Id y); + + /// Result is the length of vector x. + Id OpLength(Id result_type, Id x); + + /// Result is the linear blend of x and y i.e x * (1 - a) + y * a + Id OpFMix(Id result_type, Id x, Id y, Id a); + + // Derivatives + + /// Same result as either OpDPdxFine or OpDPdxCoarse on the input. + /// Selection of which one is based on external factors. + Id OpDPdx(Id result_type, Id operand); + + /// Same result as either OpDPdyFine or OpDPdyCoarse on the input. + /// Selection of which one is based on external factors. + Id OpDPdy(Id result_type, Id operand); + + /// Result is the same as computing the sum of the absolute values of OpDPdx and OpDPdy + /// on the input. + Id OpFwidth(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window x coordinate. + /// Uses local differencing based on the value of the input for the current fragment and + /// its immediate neighbor(s). + Id OpDPdxFine(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window y coordinate. + /// Uses local differencing based on the value of the input for the current fragment and + /// its immediate neighbor(s). + Id OpDPdyFine(Id result_type, Id operand); + + /// Result is the same as computing the sum of the absolute values of OpDPdxFine and OpDPdyFine + /// on the input. + Id OpFwidthFine(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window x coordinate. + /// Uses local differencing based on the value of the input for the current fragment's + /// neighbors, and possibly, but not necessarily, includes the value of the input for the + /// current fragment. That is, over a given area, the implementation can compute x derivatives + /// in fewer unique locations than would be allowed for OpDPdxFine. + Id OpDPdxCoarse(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window y coordinate. + /// Uses local differencing based on the value of the input for the current fragment's + /// neighbors, and possibly, but not necessarily, includes the value of the input for the + /// current fragment. That is, over a given area, the implementation can compute y derivatives + /// in fewer unique locations than would be allowed for OpDPdyFine. + Id OpDPdyCoarse(Id result_type, Id operand); + + /// Result is the same as computing the sum of the absolute values of OpDPdxCoarse and + /// OpDPdyCoarse on the input. + Id OpFwidthCoarse(Id result_type, Id operand); + + // Image + + /// Create a sampled image, containing both a sampler and an image. + Id OpSampledImage(Id result_type, Id image, Id sampler); + + /// Sample an image with an implicit level of detail. + Id OpImageSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Sample an image with an implicit level of detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleImplicitLod(result_type, sampled_image, coordinate, image_operands, + std::span({operands...})); + } + + /// Sample an image using an explicit level of detail. + Id OpImageSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, + std::span operands = {}); + + /// Sample an image using an explicit level of detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleExplicitLod(result_type, sampled_image, coordinate, image_operands, + std::span({operands...})); + } + + /// Sample an image doing depth-comparison with an implicit level of detail. + Id OpImageSampleDrefImplicitLod( + Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Sample an image doing depth-comparison with an implicit level of detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleDrefImplicitLod(result_type, sampled_image, coordinate, dref, + image_operands, std::span({operands...})); + } + + /// Sample an image doing depth-comparison using an explicit level of detail. + Id OpImageSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, + std::span operands = {}); + + /// Sample an image doing depth-comparison using an explicit level of detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleDrefExplicitLod(result_type, sampled_image, coordinate, dref, + image_operands, std::span({operands...})); + } + + /// Sample an image with with a project coordinate and an implicit level of detail. + Id OpImageSampleProjImplicitLod( + Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Sample an image with with a project coordinate and an implicit level of detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleProjImplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleProjImplicitLod(result_type, sampled_image, coordinate, image_operands, + std::span({operands...})); + } + + /// Sample an image with a project coordinate using an explicit level of detail. + Id OpImageSampleProjExplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, + std::span operands = {}); + + /// Sample an image with a project coordinate using an explicit level of detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleProjExplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleProjExplicitLod(result_type, sampled_image, coordinate, image_operands, + std::span({operands...})); + } + + /// Sample an image with a project coordinate, doing depth-comparison, with an implicit level of + /// detail. + Id OpImageSampleProjDrefImplicitLod( + Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Sample an image with a project coordinate, doing depth-comparison, with an implicit level of + /// detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleProjDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleProjDrefImplicitLod(result_type, sampled_image, coordinate, dref, + image_operands, std::span({operands...})); + } + + /// Sample an image with a project coordinate, doing depth-comparison, using an explicit level + /// of detail. + Id OpImageSampleProjDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, + std::span operands = {}); + + /// Sample an image with a project coordinate, doing depth-comparison, using an explicit level + /// of detail. + template + requires(...&& std::is_convertible_v) Id + OpImageSampleProjDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageSampleProjDrefExplicitLod(result_type, sampled_image, coordinate, dref, + image_operands, std::span({operands...})); + } + + /// Fetch a single texel from an image whose Sampled operand is 1. + Id OpImageFetch(Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Fetch a single texel from an image whose Sampled operand is 1. + template + requires(...&& std::is_convertible_v) Id + OpImageFetch(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageFetch(result_type, sampled_image, coordinate, image_operands, + std::span({operands...})); + } + + /// Gathers the requested component from four texels. + Id OpImageGather(Id result_type, Id sampled_image, Id coordinate, Id component, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Gathers the requested component from four texels. + template + requires(...&& std::is_convertible_v) Id + OpImageGather(Id result_type, Id sampled_image, Id coordinate, Id component, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageGather(result_type, sampled_image, coordinate, component, image_operands, + std::span({operands...})); + } + + /// Gathers the requested depth-comparison from four texels. + Id OpImageDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Gathers the requested depth-comparison from four texels. + template + requires(...&& std::is_convertible_v) Id + OpImageDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageDrefGather(result_type, sampled_image, coordinate, dref, image_operands, + std::span({operands...})); + } + + /// Read a texel from an image without a sampler. + Id OpImageRead(Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Read a texel from an image without a sampler. + template + requires(...&& std::is_convertible_v) Id + OpImageRead(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, Ts&&... operands) { + return OpImageRead(result_type, sampled_image, coordinate, image_operands, + std::span({operands...})); + } + + /// Write a texel to an image without a sampler. + Id OpImageWrite(Id image, Id coordinate, Id texel, + std::optional image_operands = std::nullopt, + std::span operands = {}); + + /// Write a texel to an image without a sampler. + template + requires(...&& std::is_convertible_v) Id + OpImageWrite(Id image, Id coordinate, Id texel, spv::ImageOperandsMask image_operands, + Ts&&... operands) { + return OpImageWrite(image, coordinate, texel, image_operands, + std::span({operands...})); + } + + /// Extract the image from a sampled image. + Id OpImage(Id result_type, Id sampled_image); + + /// Query the dimensions of Image for mipmap level for Level of Detail. + Id OpImageQuerySizeLod(Id result_type, Id image, Id level_of_detail); + + /// Query the dimensions of Image, with no level of detail. + Id OpImageQuerySize(Id result_type, Id image); + + /// Query the mipmap level and the level of detail for a hypothetical sampling of Image at + /// Coordinate using an implicit level of detail. + Id OpImageQueryLod(Id result_type, Id image, Id coordinate); + + /// Query the number of mipmap levels accessible through Image. + Id OpImageQueryLevels(Id result_type, Id image); + + /// Query the number of samples available per texel fetch in a multisample image. + Id OpImageQuerySamples(Id result_type, Id image); + + /// Sample a sparse image with an implicit level of detail. + Id OpImageSparseSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands, + std::span operands); + + /// Sample a sparse image using an explicit level of detail. + Id OpImageSparseSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, + std::span operands); + + /// Sample a sparse image doing depth-comparison with an implicit level of detail. + Id OpImageSparseSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands, + std::span operands); + + /// Sample a sparse image doing depth-comparison using an explicit level of detail. + Id OpImageSparseSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, + std::span operands); + + /// Fetch a single texel from a sampled sparse image. + Id OpImageSparseFetch(Id result_type, Id image, Id coordinate, + std::optional image_operands, + std::span operands); + + /// Gathers the requested component from four texels of a sparse image. + Id OpImageSparseGather(Id result_type, Id sampled_image, Id coordinate, Id component, + std::optional image_operands, + std::span operands); + + /// Gathers the requested depth-comparison from four texels of a sparse image. + Id OpImageSparseDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands, + std::span operands); + + /// Translates a Resident Code into a Boolean. Result is false if any of the texels were in + /// uncommitted texture memory, and true otherwise. + Id OpImageSparseTexelsResident(Id result_type, Id resident_code); + + /// Read a texel from a sparse image without a sampler. + Id OpImageSparseRead(Id result_type, Id image, Id coordinate, + std::optional image_operands, + std::span operands); + + // Group + + /// Computes a bitfield value combining the Predicate value from all invocations in the current + /// Subgroup that execute the same dynamic instance of this instruction. + Id OpSubgroupBallotKHR(Id result_type, Id predicate); + + /// Return the value from the invocation in the subgroup with an invocation ID equal to index. + /// The index must be the same for all active invocations in the subgroup, otherwise the results + /// are undefined. + Id OpSubgroupReadInvocationKHR(Id result_type, Id value, Id index); + + /// TBD + Id OpSubgroupAllKHR(Id result_type, Id predicate); + + /// TBD + Id OpSubgroupAnyKHR(Id result_type, Id predicate); + + /// TBD + Id OpSubgroupAllEqualKHR(Id result_type, Id predicate); + + // Find the least significant bit set to 1 in Value, considering only the bits in Value required + // to represent all bits of the scope restricted tangle. If none of the considered bits is set to 1, + // the resulting value is undefined. + Id OpGroupNonUniformBallotFindLSB(Id result_type, Id scope, Id value); + + // An integer add group operation of all Value operands contributed by all tangled invocations + // within the Execution scope. + Id OpGroupNonUniformIAdd(Id result_type, Id scope, spv::GroupOperation group_operation, Id value); + + // Result is the Value of the invocation identified by the id Id to all active invocations in + // the group. + Id OpGroupNonUniformBroadcast(Id result_type, Id scope, Id value, Id id); + + // Result is the Value of the invocation from the active invocation with the lowest id + // in the group to all active invocations in the group. + Id OpGroupNonUniformBroadcastFirst(Id result_type, Id scope, Id value); + + /// Result is the Value of the invocation identified by the id invocation_id. + Id OpGroupNonUniformShuffle(Id result_type, Id scope, Id value, Id invocation_id); + + /// Return the value of the invocation identified by the current invocation's id within the + /// group xor'ed with mask. + Id OpGroupNonUniformShuffleXor(Id result_type, Id scope, Id value, Id mask); + + /// Result is true only in the tangled invocation with the lowest id within the Execution scope, + /// otherwise result is false. + Id OpGroupNonUniformElect(Id result_type, Id scope); + + /// Evaluates a predicate for all active invocations in the group, resulting in + /// true if predicate evaluates to true for all active invocations in the + /// group, otherwise the result is false. + Id OpGroupNonUniformAll(Id result_type, Id scope, Id predicate); + + /// Evaluates a predicate for all active invocations in the group, + /// resulting in true if predicate evaluates to true for any active + /// invocation in the group, otherwise the result is false. + Id OpGroupNonUniformAny(Id result_type, Id scope, Id predicate); + + /// Evaluates a value for all active invocations in the group. The result + /// is true if Value is equal for all active invocations in the group. + /// Otherwise, the result is false. + Id OpGroupNonUniformAllEqual(Id result_type, Id scope, Id value); + + /// Result is a bitfield value combining the Predicate value from all + /// invocations in the group that execute the same dynamic instance of this + /// instruction. The bit is set to one if the corresponding invocation is + /// active and the Predicate for that invocation evaluated to true; + /// otherwise, it is set to zero. + Id OpGroupNonUniformBallot(Id result_type, Id scope, Id predicate); + + /// Evaluates a value for all tangled invocations within the Execution scope, + /// resulting in true if the bit in Value for the corresponding invocation is set to 1, + /// otherwise the result is false. + Id OpGroupNonUniformInverseBallot(Id result_type, Id scope, Id value); + + /// Result is the number of bits that are set to 1 in Value, considering only + /// the bits in Value required to represent all bits of the scope restricted tangle. + Id OpGroupNonUniformBallotBitCount(Id result_type, Id scope, spv::GroupOperation group_op, Id value); + + /// Result is the Value of the invocation within the quad with a quad index equal to Index. + Id OpGroupNonUniformQuadBroadcast(Id result_type, Id scope, Id value, Id index); + + // Atomic + + /// Atomically load through Pointer using the given Semantics. All subparts of the value that is + /// loaded will be read atomically with respect to all other atomic accesses to it within Scope. + Id OpAtomicLoad(Id result_type, Id pointer, Id memory, Id semantics); + + /// Atomically store through Pointer using the given Semantics. All subparts of Value will be + /// written atomically with respect to all other atomic accesses to it within Scope. + Id OpAtomicStore(Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value from copying Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicExchange(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value from Value only if Original Value equals Comparator, and + /// 3) store the New Value back through Pointer only if 'Original Value equaled Comparator. + Id OpAtomicCompareExchange(Id result_type, Id pointer, Id memory, Id equal, Id unequal, + Id value, Id comparator); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value through integer addition of 1 to Original Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicIIncrement(Id result_type, Id pointer, Id memory, Id semantics); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value through integer subtraction of 1 from Original Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicIDecrement(Id result_type, Id pointer, Id memory, Id semantics); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by integer addition of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicIAdd(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by integer subtraction of Value from Original Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicISub(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by finding the smallest signed integer of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicSMin(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by finding the smallest unsigned integer of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicUMin(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by finding the largest signed integer of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicSMax(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by finding the largest unsigned integer of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicUMax(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by finding the largest 32bit float of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicFMax(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by finding the smallest 32bit float of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicFMin(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by the bitwise AND of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicAnd(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by the bitwise OR of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicOr(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Perform the following steps atomically with respect to any other atomic accesses within + /// Scope to the same location: + /// 1) load through Pointer to get an Original Value, + /// 2) get a New Value by the bitwise exclusive OR of Original Value and Value, and + /// 3) store the New Value back through Pointer. + Id OpAtomicXor(Id result_type, Id pointer, Id memory, Id semantics, Id value); + + /// Print a message for vulkan layers to use, e.g. renderdoc + /// Usage is like C printf + Id OpDebugPrintf(Id fmt, std::span fmt_args); + + /// Returns a two-component floating point vector that represents the 2D texture coordinates + /// that would be used for accessing the selected cube map face for the given cube map texture + /// coordinates given as a parameter. + Id OpCubeFaceCoordAMD(Id result_type, Id cube_coords); + + /// Returns a single floating point value that represents the index of the cube map face that + /// would be accessed by texture lookup functions for the cube map texture coordinates given + /// as parameter. + Id OpCubeFaceIndexAMD(Id result_type, Id cube_coords); + + /// Returns a 64-bit value representing the current execution clock as seen by the shader + /// processor. + Id OpTimeAMD(Id result_type); + + /// Result is the minimum of x, y, and z. Which operand is the result is undefined if one + /// of the operands is a NaN. + Id OpFMin3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the minimum of x, y, and z, interpreted as unsigned integers. + Id OpUMin3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the minimum of x, y, and z, interpreted as signed integers. + Id OpSMin3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the maximum of x, y, and z. Which operand is the result is undefined if one + /// of the operands is a NaN. + Id OpFMax3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the maximum of x, y, and z, interpreted as unsigned integers. + Id OpUMax3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the maximum of x, y, and z, interpreted as signed integers. + Id OpSMax3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the middle of x, y, and z. Which operand is the result is undefined if one + /// of the operands is a NaN. + Id OpFMid3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the middle of x, y, and z, interpreted as unsigned integers. + Id OpUMid3AMD(Id result_type, Id x, Id y, Id z); + + /// Result is the middle of x, y, and z, interpreted as signed integers. + Id OpSMid3AMD(Id result_type, Id x, Id y, Id z); + + /// Returns the value of the input without any interpolation, i.e. the raw output value of previous shader stage. + Id OpInterpolateAtVertexAMD(Id result_type, Id interpolant, Id vertex_index); + +private: + Id GetGLSLstd450(); + Id GetNonSemanticDebugPrintf(); + Id GetAmdGcnShader(); + Id GetAmdShaderTrinaryMinMax(); + Id GetAmdExplicitVertexParameter(); + + std::uint32_t version{}; + std::uint32_t bound{}; + + std::unordered_set extensions; + std::unordered_set capabilities; + std::optional glsl_std_450; + std::optional non_semantic_debug_printf; + std::optional amd_gcn_shader; + std::optional amd_shader_trinary_minmax; + std::optional amd_explicit_vertex_parameter; + + spv::AddressingModel addressing_model{spv::AddressingModel::Logical}; + spv::MemoryModel memory_model{spv::MemoryModel::GLSL450}; + + std::unique_ptr ext_inst_imports; + std::unique_ptr entry_points; + std::unique_ptr execution_modes; + std::unique_ptr debug; + std::unique_ptr debug_name; + std::unique_ptr annotations; + std::unique_ptr declarations; + std::unique_ptr global_variables; + std::unique_ptr code; + std::vector deferred_phi_nodes; +}; + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/.gitignore b/gpu/third_party/sirit/src/.gitignore new file mode 100644 index 0000000..06d55cb --- /dev/null +++ b/gpu/third_party/sirit/src/.gitignore @@ -0,0 +1 @@ +sirit.h diff --git a/gpu/third_party/sirit/src/CMakeLists.txt b/gpu/third_party/sirit/src/CMakeLists.txt new file mode 100644 index 0000000..18f3e1b --- /dev/null +++ b/gpu/third_party/sirit/src/CMakeLists.txt @@ -0,0 +1,32 @@ +add_library(sirit + ../include/sirit/sirit.h + sirit.cpp + stream.h + common_types.h + instructions/type.cpp + instructions/constant.cpp + instructions/function.cpp + instructions/flow.cpp + instructions/debug.cpp + instructions/derivatives.cpp + instructions/memory.cpp + instructions/annotation.cpp + instructions/misc.cpp + instructions/logical.cpp + instructions/conversion.cpp + instructions/bit.cpp + instructions/arithmetic.cpp + instructions/extension.cpp + instructions/image.cpp + instructions/group.cpp + instructions/barrier.cpp + instructions/atomic.cpp +) + +target_compile_options(sirit PRIVATE ${SIRIT_CXX_FLAGS}) + +target_include_directories(sirit + PUBLIC ../include + PRIVATE .) + +target_link_libraries(sirit PUBLIC SPIRV-Headers::SPIRV-Headers) diff --git a/gpu/third_party/sirit/src/common_types.h b/gpu/third_party/sirit/src/common_types.h new file mode 100644 index 0000000..42df6f6 --- /dev/null +++ b/gpu/third_party/sirit/src/common_types.h @@ -0,0 +1,31 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#pragma once + +#include +#include + +namespace Sirit { + +using u8 = std::uint8_t; +using u16 = std::uint16_t; +using u32 = std::uint32_t; +using u64 = std::uint64_t; +using uptr = std::uintptr_t; + +using s8 = std::int8_t; +using s16 = std::int16_t; +using s32 = std::int32_t; +using s64 = std::int64_t; +using sptr = std::intptr_t; + +using f32 = float; +using f64 = double; +static_assert(sizeof(f32) == sizeof(u32), "f32 must be 32 bits wide"); +static_assert(sizeof(f64) == sizeof(u64), "f64 must be 64 bits wide"); + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/annotation.cpp b/gpu/third_party/sirit/src/instructions/annotation.cpp new file mode 100644 index 0000000..e3524bb --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/annotation.cpp @@ -0,0 +1,27 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::Decorate(Id target, spv::Decoration decoration, std::span literals) { + annotations->Reserve(3 + literals.size()); + return *annotations << spv::Op::OpDecorate << target << decoration << literals << EndOp{}; +} + +Id Module::MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration, + std::span literals) { + annotations->Reserve(4 + literals.size()); + return *annotations << spv::Op::OpMemberDecorate << structure_type << member << decoration + << literals << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/arithmetic.cpp b/gpu/third_party/sirit/src/instructions/arithmetic.cpp new file mode 100644 index 0000000..04963e1 --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/arithmetic.cpp @@ -0,0 +1,48 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +#define DEFINE_UNARY(funcname, opcode) \ + Id Module::funcname(Id result_type, Id operand) { \ + code->Reserve(4); \ + return *code << OpId{opcode, result_type} << operand << EndOp{}; \ + } + +#define DEFINE_BINARY(funcname, opcode) \ + Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \ + code->Reserve(5); \ + return *code << OpId{opcode, result_type} << operand_1 << operand_2 << EndOp{}; \ + } + +DEFINE_UNARY(OpSNegate, spv::Op::OpSNegate) +DEFINE_UNARY(OpFNegate, spv::Op::OpFNegate) + +DEFINE_BINARY(OpIAdd, spv::Op::OpIAdd) +DEFINE_BINARY(OpFAdd, spv::Op::OpFAdd) +DEFINE_BINARY(OpISub, spv::Op::OpISub) +DEFINE_BINARY(OpFSub, spv::Op::OpFSub) +DEFINE_BINARY(OpIMul, spv::Op::OpIMul) +DEFINE_BINARY(OpUMulExtended, spv::Op::OpUMulExtended) +DEFINE_BINARY(OpSMulExtended, spv::Op::OpSMulExtended) +DEFINE_BINARY(OpFMul, spv::Op::OpFMul) +DEFINE_BINARY(OpUDiv, spv::Op::OpUDiv) +DEFINE_BINARY(OpSDiv, spv::Op::OpSDiv) +DEFINE_BINARY(OpFDiv, spv::Op::OpFDiv) +DEFINE_BINARY(OpUMod, spv::Op::OpUMod) +DEFINE_BINARY(OpSMod, spv::Op::OpSMod) +DEFINE_BINARY(OpFMod, spv::Op::OpFMod) +DEFINE_BINARY(OpSRem, spv::Op::OpSRem) +DEFINE_BINARY(OpFRem, spv::Op::OpFRem) +DEFINE_BINARY(OpIAddCarry, spv::Op::OpIAddCarry) +DEFINE_BINARY(OpVectorTimesScalar, spv::Op::OpVectorTimesScalar) +DEFINE_BINARY(OpDot, spv::Op::OpDot) + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/atomic.cpp b/gpu/third_party/sirit/src/instructions/atomic.cpp new file mode 100644 index 0000000..c12f9b1 --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/atomic.cpp @@ -0,0 +1,115 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpAtomicLoad(Id result_type, Id pointer, Id memory, Id semantics) { + code->Reserve(6); + return *code << OpId{spv::Op::OpAtomicLoad, result_type} << pointer << memory << semantics + << EndOp{}; +} + +Id Module::OpAtomicStore(Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(5); + return *code << spv::Op::OpAtomicStore << pointer << memory << semantics << value << EndOp{}; +} + +Id Module::OpAtomicExchange(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicExchange, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicCompareExchange(Id result_type, Id pointer, Id memory, Id equal, Id unequal, + Id value, Id comparator) { + code->Reserve(9); + return *code << OpId{spv::Op::OpAtomicCompareExchange, result_type} << pointer << memory + << equal << unequal << value << comparator << EndOp{}; +} + +Id Module::OpAtomicIIncrement(Id result_type, Id pointer, Id memory, Id semantics) { + code->Reserve(6); + return *code << OpId{spv::Op::OpAtomicIIncrement, result_type} << pointer << memory << semantics + << EndOp{}; +} + +Id Module::OpAtomicIDecrement(Id result_type, Id pointer, Id memory, Id semantics) { + code->Reserve(6); + return *code << OpId{spv::Op::OpAtomicIDecrement, result_type} << pointer << memory << semantics + << EndOp{}; +} + +Id Module::OpAtomicIAdd(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicIAdd, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicISub(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicISub, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicSMin(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicSMin, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicUMin(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicUMin, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicSMax(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicSMax, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicUMax(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicUMax, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicFMax(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicFMaxEXT, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicFMin(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicFMinEXT, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicAnd(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicAnd, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicOr(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicOr, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +Id Module::OpAtomicXor(Id result_type, Id pointer, Id memory, Id semantics, Id value) { + code->Reserve(7); + return *code << OpId{spv::Op::OpAtomicXor, result_type} << pointer << memory << semantics + << value << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/barrier.cpp b/gpu/third_party/sirit/src/instructions/barrier.cpp new file mode 100644 index 0000000..646b5cf --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/barrier.cpp @@ -0,0 +1,23 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpControlBarrier(Id execution, Id memory, Id semantics) { + code->Reserve(4); + return *code << spv::Op::OpControlBarrier << execution << memory << semantics << EndOp{}; +} + +Id Module::OpMemoryBarrier(Id scope, Id semantics) { + code->Reserve(3); + return *code << spv::Op::OpMemoryBarrier << scope << semantics << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/bit.cpp b/gpu/third_party/sirit/src/instructions/bit.cpp new file mode 100644 index 0000000..c860613 --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/bit.cpp @@ -0,0 +1,76 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpShiftRightLogical(Id result_type, Id base, Id shift) { + code->Reserve(5); + return *code << OpId{spv::Op::OpShiftRightLogical, result_type} << base << shift << EndOp{}; +} + +Id Module::OpShiftRightArithmetic(Id result_type, Id base, Id shift) { + code->Reserve(5); + return *code << OpId{spv::Op::OpShiftRightArithmetic, result_type} << base << shift << EndOp{}; +} + +Id Module::OpShiftLeftLogical(Id result_type, Id base, Id shift) { + code->Reserve(5); + return *code << OpId{spv::Op::OpShiftLeftLogical, result_type} << base << shift << EndOp{}; +} + +Id Module::OpBitwiseOr(Id result_type, Id operand_1, Id operand_2) { + code->Reserve(5); + return *code << OpId{spv::Op::OpBitwiseOr, result_type} << operand_1 << operand_2 << EndOp{}; +} + +Id Module::OpBitwiseXor(Id result_type, Id operand_1, Id operand_2) { + code->Reserve(5); + return *code << OpId{spv::Op::OpBitwiseXor, result_type} << operand_1 << operand_2 << EndOp{}; +} + +Id Module::OpBitwiseAnd(Id result_type, Id operand_1, Id operand_2) { + code->Reserve(5); + return *code << OpId{spv::Op::OpBitwiseAnd, result_type} << operand_1 << operand_2 << EndOp{}; +} + +Id Module::OpNot(Id result_type, Id operand) { + code->Reserve(4); + return *code << OpId{spv::Op::OpNot, result_type} << operand << EndOp{}; +} + +Id Module::OpBitFieldInsert(Id result_type, Id base, Id insert, Id offset, Id count) { + code->Reserve(7); + return *code << OpId{spv::Op::OpBitFieldInsert, result_type} << base << insert << offset + << count << EndOp{}; +} + +Id Module::OpBitFieldSExtract(Id result_type, Id base, Id offset, Id count) { + code->Reserve(6); + return *code << OpId{spv::Op::OpBitFieldSExtract, result_type} << base << offset << count + << EndOp{}; +} + +Id Module::OpBitFieldUExtract(Id result_type, Id base, Id offset, Id count) { + code->Reserve(6); + return *code << OpId{spv::Op::OpBitFieldUExtract, result_type} << base << offset << count + << EndOp{}; +} + +Id Module::OpBitReverse(Id result_type, Id base) { + code->Reserve(4); + return *code << OpId{spv::Op::OpBitReverse, result_type} << base << EndOp{}; +} + +Id Module::OpBitCount(Id result_type, Id base) { + code->Reserve(4); + return *code << OpId{spv::Op::OpBitCount, result_type} << base << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/constant.cpp b/gpu/third_party/sirit/src/instructions/constant.cpp new file mode 100644 index 0000000..612049c --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/constant.cpp @@ -0,0 +1,48 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::ConstantTrue(Id result_type) { + declarations->Reserve(3); + return *declarations << OpId{spv::Op::OpConstantTrue, result_type} << EndOp{}; +} + +Id Module::ConstantFalse(Id result_type) { + declarations->Reserve(3); + return *declarations << OpId{spv::Op::OpConstantFalse, result_type} << EndOp{}; +} + +Id Module::Constant(Id result_type, const Literal& literal) { + declarations->Reserve(3 + 2); + return *declarations << OpId{spv::Op::OpConstant, result_type} << literal << EndOp{}; +} + +Id Module::ConstantComposite(Id result_type, std::span constituents) { + declarations->Reserve(3 + constituents.size()); + return *declarations << OpId{spv::Op::OpConstantComposite, result_type} << constituents + << EndOp{}; +} + +Id Module::ConstantSampler(Id result_type, spv::SamplerAddressingMode addressing_mode, + bool normalized, spv::SamplerFilterMode filter_mode) { + declarations->Reserve(6); + return *declarations << OpId{spv::Op::OpConstantSampler, result_type} << addressing_mode + << normalized << filter_mode << EndOp{}; +} + +Id Module::ConstantNull(Id result_type) { + declarations->Reserve(3); + return *declarations << OpId{spv::Op::OpConstantNull, result_type} << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/conversion.cpp b/gpu/third_party/sirit/src/instructions/conversion.cpp new file mode 100644 index 0000000..9163eda --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/conversion.cpp @@ -0,0 +1,31 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +#define DEFINE_UNARY(opcode) \ + Id Module::opcode(Id result_type, Id operand) { \ + code->Reserve(4); \ + return *code << OpId{spv::Op::opcode, result_type} << operand << EndOp{}; \ + } + +DEFINE_UNARY(OpConvertFToU) +DEFINE_UNARY(OpConvertFToS) +DEFINE_UNARY(OpConvertSToF) +DEFINE_UNARY(OpConvertUToF) +DEFINE_UNARY(OpConvertUToPtr) +DEFINE_UNARY(OpConvertPtrToU) +DEFINE_UNARY(OpUConvert) +DEFINE_UNARY(OpSConvert) +DEFINE_UNARY(OpFConvert) +DEFINE_UNARY(OpQuantizeToF16) +DEFINE_UNARY(OpBitcast) + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/debug.cpp b/gpu/third_party/sirit/src/instructions/debug.cpp new file mode 100644 index 0000000..2907e66 --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/debug.cpp @@ -0,0 +1,36 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "common_types.h" +#include "stream.h" + +namespace Sirit { + +Id Module::Name(Id target, std::string_view name) { + debug_name->Reserve(3 + WordsInString(name)); + *debug_name << spv::Op::OpName << target << name << EndOp{}; + return target; +} + +Id Module::MemberName(Id type, u32 member, std::string_view name) { + debug_name->Reserve(4 + WordsInString(name)); + *debug_name << spv::Op::OpMemberName << type << member << name << EndOp{}; + return type; +} + +Id Module::String(std::string_view string) { + debug->Reserve(3 + WordsInString(string)); + return *debug << OpId{spv::Op::OpString} << string << EndOp{}; +} + +Id Module::OpLine(Id file, Literal line, Literal column) { + debug->Reserve(4); + return *debug << spv::Op::OpLine << file << line << column << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/derivatives.cpp b/gpu/third_party/sirit/src/instructions/derivatives.cpp new file mode 100644 index 0000000..c944e2a --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/derivatives.cpp @@ -0,0 +1,29 @@ +/* This file is part of the sirit project. + * Copyright (c) 2021 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +#define DEFINE_UNARY(funcname, opcode) \ + Id Module::funcname(Id result_type, Id operand) { \ + code->Reserve(4); \ + return *code << OpId{opcode, result_type} << operand << EndOp{}; \ + } + +DEFINE_UNARY(OpDPdx, spv::Op::OpDPdx) +DEFINE_UNARY(OpDPdy, spv::Op::OpDPdy) +DEFINE_UNARY(OpFwidth, spv::Op::OpFwidth) +DEFINE_UNARY(OpDPdxFine, spv::Op::OpDPdxFine) +DEFINE_UNARY(OpDPdyFine, spv::Op::OpDPdyFine) +DEFINE_UNARY(OpFwidthFine, spv::Op::OpFwidthFine) +DEFINE_UNARY(OpDPdxCoarse, spv::Op::OpDPdxCoarse) +DEFINE_UNARY(OpDPdyCoarse, spv::Op::OpDPdyCoarse) +DEFINE_UNARY(OpFwidthCoarse, spv::Op::OpFwidthCoarse) + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/extension.cpp b/gpu/third_party/sirit/src/instructions/extension.cpp new file mode 100644 index 0000000..ea26615 --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/extension.cpp @@ -0,0 +1,127 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include +#include +#include +#include +#include +#include + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpExtInst(Id result_type, Id set, u32 instruction, std::span operands) { + code->Reserve(5 + operands.size()); + return *code << OpId{spv::Op::OpExtInst, result_type} << set << instruction << operands + << EndOp{}; +} + +#define DEFINE_NULLARY(ext, funcname, opcode) \ + Id Module::funcname(Id result_type) { \ + return OpExtInst(result_type, ext, opcode); \ + } + +#define DEFINE_UNARY(ext, funcname, opcode) \ + Id Module::funcname(Id result_type, Id operand) { \ + return OpExtInst(result_type, ext, opcode, operand); \ + } + +#define DEFINE_BINARY(ext, funcname, opcode) \ + Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \ + return OpExtInst(result_type, ext, opcode, operand_1, operand_2); \ + } + +#define DEFINE_TRINARY(ext, funcname, opcode) \ + Id Module::funcname(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \ + return OpExtInst(result_type, ext, opcode, operand_1, operand_2, operand_3); \ + } + +DEFINE_UNARY(GetGLSLstd450(), OpFAbs, GLSLstd450FAbs) +DEFINE_UNARY(GetGLSLstd450(), OpSAbs, GLSLstd450SAbs) +DEFINE_UNARY(GetGLSLstd450(), OpRound, GLSLstd450Round) +DEFINE_UNARY(GetGLSLstd450(), OpRoundEven, GLSLstd450RoundEven) +DEFINE_UNARY(GetGLSLstd450(), OpTrunc, GLSLstd450Trunc) +DEFINE_UNARY(GetGLSLstd450(), OpFSign, GLSLstd450FSign) +DEFINE_UNARY(GetGLSLstd450(), OpSSign, GLSLstd450SSign) +DEFINE_UNARY(GetGLSLstd450(), OpFloor, GLSLstd450Floor) +DEFINE_UNARY(GetGLSLstd450(), OpCeil, GLSLstd450Ceil) +DEFINE_UNARY(GetGLSLstd450(), OpFract, GLSLstd450Fract) +DEFINE_UNARY(GetGLSLstd450(), OpSin, GLSLstd450Sin) +DEFINE_UNARY(GetGLSLstd450(), OpCos, GLSLstd450Cos) +DEFINE_UNARY(GetGLSLstd450(), OpAsin, GLSLstd450Asin) +DEFINE_UNARY(GetGLSLstd450(), OpAcos, GLSLstd450Acos) +DEFINE_BINARY(GetGLSLstd450(), OpPow, GLSLstd450Pow) +DEFINE_UNARY(GetGLSLstd450(), OpExp, GLSLstd450Exp) +DEFINE_UNARY(GetGLSLstd450(), OpLog, GLSLstd450Log) +DEFINE_UNARY(GetGLSLstd450(), OpExp2, GLSLstd450Exp2) +DEFINE_UNARY(GetGLSLstd450(), OpLog2, GLSLstd450Log2) +DEFINE_UNARY(GetGLSLstd450(), OpSqrt, GLSLstd450Sqrt) +DEFINE_UNARY(GetGLSLstd450(), OpInverseSqrt, GLSLstd450InverseSqrt) +DEFINE_BINARY(GetGLSLstd450(), OpLdexp, GLSLstd450Ldexp) +DEFINE_BINARY(GetGLSLstd450(), OpFMin, GLSLstd450FMin) +DEFINE_BINARY(GetGLSLstd450(), OpUMin, GLSLstd450UMin) +DEFINE_BINARY(GetGLSLstd450(), OpSMin, GLSLstd450SMin) +DEFINE_BINARY(GetGLSLstd450(), OpNMin, GLSLstd450NMin) +DEFINE_BINARY(GetGLSLstd450(), OpFMax, GLSLstd450FMax) +DEFINE_BINARY(GetGLSLstd450(), OpUMax, GLSLstd450UMax) +DEFINE_BINARY(GetGLSLstd450(), OpSMax, GLSLstd450SMax) +DEFINE_BINARY(GetGLSLstd450(), OpNMax, GLSLstd450NMax) +DEFINE_TRINARY(GetGLSLstd450(), OpFClamp, GLSLstd450FClamp) +DEFINE_TRINARY(GetGLSLstd450(), OpUClamp, GLSLstd450UClamp) +DEFINE_TRINARY(GetGLSLstd450(), OpSClamp, GLSLstd450SClamp) +DEFINE_TRINARY(GetGLSLstd450(), OpFma, GLSLstd450Fma) +DEFINE_UNARY(GetGLSLstd450(), OpFrexpStruct, GLSLstd450FrexpStruct) +DEFINE_UNARY(GetGLSLstd450(), OpPackHalf2x16, GLSLstd450PackHalf2x16) +DEFINE_UNARY(GetGLSLstd450(), OpUnpackHalf2x16, GLSLstd450UnpackHalf2x16) +DEFINE_UNARY(GetGLSLstd450(), OpPackUnorm2x16, GLSLstd450PackUnorm2x16) +DEFINE_UNARY(GetGLSLstd450(), OpUnpackUnorm2x16, GLSLstd450UnpackUnorm2x16) +DEFINE_UNARY(GetGLSLstd450(), OpPackSnorm2x16, GLSLstd450PackSnorm2x16) +DEFINE_UNARY(GetGLSLstd450(), OpUnpackSnorm2x16, GLSLstd450UnpackSnorm2x16) +DEFINE_UNARY(GetGLSLstd450(), OpPackUnorm4x8, GLSLstd450PackUnorm4x8) +DEFINE_UNARY(GetGLSLstd450(), OpUnpackUnorm4x8, GLSLstd450UnpackUnorm4x8) +DEFINE_UNARY(GetGLSLstd450(), OpPackSnorm4x8, GLSLstd450PackSnorm4x8) +DEFINE_UNARY(GetGLSLstd450(), OpUnpackSnorm4x8, GLSLstd450UnpackSnorm4x8) +DEFINE_UNARY(GetGLSLstd450(), OpFindILsb, GLSLstd450FindILsb) +DEFINE_UNARY(GetGLSLstd450(), OpFindSMsb, GLSLstd450FindSMsb) +DEFINE_UNARY(GetGLSLstd450(), OpFindUMsb, GLSLstd450FindUMsb) +DEFINE_UNARY(GetGLSLstd450(), OpInterpolateAtCentroid, GLSLstd450InterpolateAtCentroid) +DEFINE_BINARY(GetGLSLstd450(), OpInterpolateAtSample, GLSLstd450InterpolateAtSample) +DEFINE_BINARY(GetGLSLstd450(), OpInterpolateAtOffset, GLSLstd450InterpolateAtOffset) +DEFINE_UNARY(GetGLSLstd450(), OpNormalize, GLSLstd450Normalize) +DEFINE_BINARY(GetGLSLstd450(), OpCross, GLSLstd450Cross) +DEFINE_UNARY(GetGLSLstd450(), OpLength, GLSLstd450Length) +DEFINE_TRINARY(GetGLSLstd450(), OpFMix, GLSLstd450FMix) + +Id Module::OpDebugPrintf(Id fmt, std::span fmt_args) { + std::vector operands; + operands.push_back(fmt); + std::copy(fmt_args.begin(), fmt_args.end(), std::back_inserter(operands)); + return OpExtInst(TypeVoid(), GetNonSemanticDebugPrintf(), NonSemanticDebugPrintfDebugPrintf, + operands); +} + +DEFINE_UNARY(GetAmdGcnShader(), OpCubeFaceCoordAMD, AMD_gcn_shaderCubeFaceCoordAMD) +DEFINE_UNARY(GetAmdGcnShader(), OpCubeFaceIndexAMD, AMD_gcn_shaderCubeFaceIndexAMD) +DEFINE_NULLARY(GetAmdGcnShader(), OpTimeAMD, AMD_gcn_shaderTimeAMD) + +DEFINE_BINARY(GetAmdExplicitVertexParameter(), OpInterpolateAtVertexAMD, AMD_shader_explicit_vertex_parameterInterpolateAtVertexAMD) + +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpFMin3AMD, AMD_shader_trinary_minmaxFMin3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpUMin3AMD, AMD_shader_trinary_minmaxUMin3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpSMin3AMD, AMD_shader_trinary_minmaxSMin3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpFMax3AMD, AMD_shader_trinary_minmaxFMax3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpUMax3AMD, AMD_shader_trinary_minmaxUMax3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpSMax3AMD, AMD_shader_trinary_minmaxSMax3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpFMid3AMD, AMD_shader_trinary_minmaxFMid3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpUMid3AMD, AMD_shader_trinary_minmaxUMid3AMD) +DEFINE_TRINARY(GetAmdShaderTrinaryMinMax(), OpSMid3AMD, AMD_shader_trinary_minmaxSMid3AMD) + + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/flow.cpp b/gpu/third_party/sirit/src/instructions/flow.cpp new file mode 100644 index 0000000..e462dcb --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/flow.cpp @@ -0,0 +1,100 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpPhi(Id result_type, std::span operands) { + assert(operands.size() % 2 == 0); + code->Reserve(3 + operands.size()); + return *code << OpId{spv::Op::OpPhi, result_type} << operands << EndOp{}; +} + +Id Module::DeferredOpPhi(Id result_type, std::span blocks) { + deferred_phi_nodes.push_back(code->LocalAddress()); + code->Reserve(3 + blocks.size() * 2); + *code << OpId{spv::Op::OpPhi, result_type}; + for (const Id block : blocks) { + *code << u32{0} << block; + } + return *code << EndOp{}; +} + +Id Module::OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control, + std::span literals) { + code->Reserve(4 + literals.size()); + return *code << spv::Op::OpLoopMerge << merge_block << continue_target << loop_control + << literals << EndOp{}; +} + +Id Module::OpSelectionMerge(Id merge_block, spv::SelectionControlMask selection_control) { + code->Reserve(3); + return *code << spv::Op::OpSelectionMerge << merge_block << selection_control << EndOp{}; +} + +Id Module::OpLabel() { + return Id{++bound}; +} + +Id Module::OpBranch(Id target_label) { + code->Reserve(2); + return *code << spv::Op::OpBranch << target_label << EndOp{}; +} + +Id Module::OpBranchConditional(Id condition, Id true_label, Id false_label, u32 true_weight, + u32 false_weight) { + code->Reserve(6); + *code << spv::Op::OpBranchConditional << condition << true_label << false_label; + if (true_weight != 0 || false_weight != 0) { + *code << true_weight << false_weight; + } + return *code << EndOp{}; +} + +Id Module::OpSwitch(Id selector, Id default_label, std::span literals, + std::span labels) { + assert(literals.size() == labels.size()); + const size_t size = literals.size(); + code->Reserve(3 + size * 2); + + *code << spv::Op::OpSwitch << selector << default_label; + for (std::size_t i = 0; i < size; ++i) { + *code << literals[i] << labels[i]; + } + return *code << EndOp{}; +} + +void Module::OpReturn() { + code->Reserve(1); + *code << spv::Op::OpReturn << EndOp{}; +} + +void Module::OpUnreachable() { + code->Reserve(1); + *code << spv::Op::OpUnreachable << EndOp{}; +} + +Id Module::OpReturnValue(Id value) { + code->Reserve(2); + return *code << spv::Op::OpReturnValue << value << EndOp{}; +} + +void Module::OpKill() { + code->Reserve(1); + *code << spv::Op::OpKill << EndOp{}; +} + +void Module::OpDemoteToHelperInvocationEXT() { + code->Reserve(1); + *code << spv::Op::OpDemoteToHelperInvocationEXT << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/function.cpp b/gpu/third_party/sirit/src/instructions/function.cpp new file mode 100644 index 0000000..f84cd7f --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/function.cpp @@ -0,0 +1,34 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpFunction(Id result_type, spv::FunctionControlMask function_control, Id function_type) { + code->Reserve(5); + return *code << OpId{spv::Op::OpFunction, result_type} << function_control << function_type + << EndOp{}; +} + +void Module::OpFunctionEnd() { + code->Reserve(1); + *code << spv::Op::OpFunctionEnd << EndOp{}; +} + +Id Module::OpFunctionCall(Id result_type, Id function, std::span arguments) { + code->Reserve(4 + arguments.size()); + return *code << OpId{spv::Op::OpFunctionCall, result_type} << function << arguments << EndOp{}; +} + +Id Module::OpFunctionParameter(Id result_type) { + code->Reserve(3); + return *code << OpId{spv::Op::OpFunctionParameter, result_type} << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/group.cpp b/gpu/third_party/sirit/src/instructions/group.cpp new file mode 100644 index 0000000..dec6d4b --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/group.cpp @@ -0,0 +1,114 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpSubgroupBallotKHR(Id result_type, Id predicate) { + code->Reserve(4); + return *code << OpId{spv::Op::OpSubgroupBallotKHR, result_type} << predicate << EndOp{}; +} + +Id Module::OpSubgroupReadInvocationKHR(Id result_type, Id value, Id index) { + code->Reserve(5); + return *code << OpId{spv::Op::OpSubgroupReadInvocationKHR, result_type} << value << index + << EndOp{}; +} + +Id Module::OpSubgroupAllKHR(Id result_type, Id predicate) { + code->Reserve(4); + return *code << OpId{spv::Op::OpSubgroupAllKHR, result_type} << predicate << EndOp{}; +} + +Id Module::OpSubgroupAnyKHR(Id result_type, Id predicate) { + code->Reserve(4); + return *code << OpId{spv::Op::OpSubgroupAnyKHR, result_type} << predicate << EndOp{}; +} + +Id Module::OpSubgroupAllEqualKHR(Id result_type, Id predicate) { + code->Reserve(4); + return *code << OpId{spv::Op::OpSubgroupAllEqualKHR, result_type} << predicate << EndOp{}; +} + +Id Module::OpGroupNonUniformBroadcast(Id result_type, Id scope, Id value, Id id) { + code->Reserve(6); + return *code << OpId{spv::Op::OpGroupNonUniformBroadcast, result_type} << scope << value + << id << EndOp{}; +} + +Id Module::OpGroupNonUniformBroadcastFirst(Id result_type, Id scope, Id value) { + code->Reserve(5); + return *code << OpId{spv::Op::OpGroupNonUniformBroadcastFirst, result_type} << scope << value + << EndOp{}; +} + +Id Module::OpGroupNonUniformShuffle(Id result_type, Id scope, Id value, Id invocation_id) { + code->Reserve(6); + return *code << OpId{spv::Op::OpGroupNonUniformShuffle, result_type} << scope << value + << invocation_id << EndOp{}; +} + +Id Module::OpGroupNonUniformShuffleXor(Id result_type, Id scope, Id value, Id mask) { + code->Reserve(6); + return *code << OpId{spv::Op::OpGroupNonUniformShuffleXor, result_type} << scope << value + << mask << EndOp{}; +} + +Id Module::OpGroupNonUniformElect(Id result_type, Id scope) { + code->Reserve(4); + return *code << OpId{spv::Op::OpGroupNonUniformElect, result_type} << scope << EndOp{}; +} + +Id Module::OpGroupNonUniformAll(Id result_type, Id scope, Id predicate) { + code->Reserve(5); + return *code << OpId{spv::Op::OpGroupNonUniformAll, result_type} << scope << predicate << EndOp{}; +} + +Id Module::OpGroupNonUniformAny(Id result_type, Id scope, Id predicate) { + code->Reserve(5); + return *code << OpId{spv::Op::OpGroupNonUniformAny, result_type} << scope << predicate << EndOp{}; +} + +Id Module::OpGroupNonUniformAllEqual(Id result_type, Id scope, Id value) { + code->Reserve(5); + return *code << OpId{spv::Op::OpGroupNonUniformAllEqual, result_type} << scope << value << EndOp{}; +} + +Id Module::OpGroupNonUniformBallot(Id result_type, Id scope, Id predicate) { + code->Reserve(5); + return *code << OpId{spv::Op::OpGroupNonUniformBallot, result_type} << scope << predicate << EndOp{}; +} + +Id Module::OpGroupNonUniformInverseBallot(Id result_type, Id scope, Id value) { + code->Reserve(5); + return *code << OpId{spv::Op::OpGroupNonUniformInverseBallot, result_type} << scope << value << EndOp{}; +} + +Id Module::OpGroupNonUniformBallotBitCount(Id result_type, Id scope, spv::GroupOperation group_op, Id value) { + code->Reserve(6); + return *code << OpId{spv::Op::OpGroupNonUniformBallotBitCount, result_type} << scope << group_op << value << EndOp{}; +} + +Id Module::OpGroupNonUniformQuadBroadcast(Id result_type, Id scope, Id value, Id index) { + code->Reserve(6); + return *code << OpId{spv::Op::OpGroupNonUniformQuadBroadcast, result_type} << scope << value << index << EndOp{}; +} + +Id Module::OpGroupNonUniformBallotFindLSB(Id result_type, Id scope, Id value) { + code->Reserve(5); + return *code << OpId{spv::Op::OpGroupNonUniformBallotFindLSB, result_type} << scope << value + << EndOp{}; +} + +Id Module::OpGroupNonUniformIAdd(Id result_type, Id scope, spv::GroupOperation group_operation, Id value) { + code->Reserve(6); + return *code << OpId{spv::Op::OpGroupNonUniformIAdd, result_type} << scope << group_operation + << value << EndOp{}; +} +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/image.cpp b/gpu/third_party/sirit/src/instructions/image.cpp new file mode 100644 index 0000000..ef30e46 --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/image.cpp @@ -0,0 +1,168 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +#define DEFINE_IMAGE_OP(opcode) \ + Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \ + std::optional image_operands, \ + std::span operands) { \ + code->Reserve(6 + operands.size()); \ + return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate \ + << image_operands << operands << EndOp{}; \ + } + +#define DEFINE_IMAGE_EXP_OP(opcode) \ + Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \ + spv::ImageOperandsMask image_operands, std::span operands) { \ + code->Reserve(6 + operands.size()); \ + return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate \ + << image_operands << operands << EndOp{}; \ + } + +#define DEFINE_IMAGE_EXTRA_OP(opcode) \ + Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \ + std::optional image_operands, \ + std::span operands) { \ + code->Reserve(7 + operands.size()); \ + return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate << extra \ + << image_operands << operands << EndOp{}; \ + } + +#define DEFINE_IMAGE_EXTRA_EXP_OP(opcode) \ + Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \ + spv::ImageOperandsMask image_operands, std::span operands) { \ + code->Reserve(8 + operands.size()); \ + return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate << extra \ + << image_operands << operands << EndOp{}; \ + } + +#define DEFINE_IMAGE_QUERY_OP(opcode) \ + Id Module::opcode(Id result_type, Id image) { \ + code->Reserve(5); \ + return *code << OpId{spv::Op::opcode, result_type} << image << EndOp{}; \ + } + +#define DEFINE_IMAGE_QUERY_BIN_OP(opcode) \ + Id Module::opcode(Id result_type, Id image, Id extra) { \ + code->Reserve(5); \ + return *code << OpId{spv::Op::opcode, result_type} << image << extra << EndOp{}; \ + } + +DEFINE_IMAGE_OP(OpImageSampleImplicitLod) +DEFINE_IMAGE_EXP_OP(OpImageSampleExplicitLod) +DEFINE_IMAGE_EXTRA_OP(OpImageSampleDrefImplicitLod) +DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleDrefExplicitLod) +DEFINE_IMAGE_OP(OpImageSampleProjImplicitLod) +DEFINE_IMAGE_EXP_OP(OpImageSampleProjExplicitLod) +DEFINE_IMAGE_EXTRA_OP(OpImageSampleProjDrefImplicitLod) +DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleProjDrefExplicitLod) +DEFINE_IMAGE_OP(OpImageFetch) +DEFINE_IMAGE_EXTRA_OP(OpImageGather) +DEFINE_IMAGE_EXTRA_OP(OpImageDrefGather) +DEFINE_IMAGE_OP(OpImageRead) +DEFINE_IMAGE_QUERY_BIN_OP(OpImageQuerySizeLod) +DEFINE_IMAGE_QUERY_OP(OpImageQuerySize) +DEFINE_IMAGE_QUERY_BIN_OP(OpImageQueryLod) +DEFINE_IMAGE_QUERY_OP(OpImageQueryLevels) +DEFINE_IMAGE_QUERY_OP(OpImageQuerySamples) + +Id Module::OpSampledImage(Id result_type, Id image, Id sampler) { + code->Reserve(5); + return *code << OpId{spv::Op::OpSampledImage, result_type} << image << sampler << EndOp{}; +} + +Id Module::OpImageWrite(Id image, Id coordinate, Id texel, + std::optional image_operands, + std::span operands) { + code->Reserve(4 + (image_operands.has_value() ? 1 : 0) + operands.size()); + return *code << spv::Op::OpImageWrite << image << coordinate << texel << image_operands + << operands << EndOp{}; +} + +Id Module::OpImage(Id result_type, Id sampled_image) { + code->Reserve(4); + return *code << OpId{spv::Op::OpImage, result_type} << sampled_image << EndOp{}; +} + +Id Module::OpImageSparseSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands, + std::span operands) { + code->Reserve(5 + (image_operands.has_value() ? 1 : 0) + operands.size()); + return *code << OpId{spv::Op::OpImageSparseSampleImplicitLod, result_type} << sampled_image + << coordinate << image_operands << operands << EndOp{}; +} + +Id Module::OpImageSparseSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, + std::span operands) { + code->Reserve(6 + operands.size()); + return *code << OpId{spv::Op::OpImageSparseSampleExplicitLod, result_type} << sampled_image + << coordinate << image_operands << operands << EndOp{}; +} + +Id Module::OpImageSparseSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, + Id dref, + std::optional image_operands, + std::span operands) { + code->Reserve(6 + (image_operands.has_value() ? 1 : 0) + operands.size()); + return *code << OpId{spv::Op::OpImageSparseSampleDrefImplicitLod, result_type} << sampled_image + << coordinate << dref << image_operands << operands << EndOp{}; +} + +Id Module::OpImageSparseSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, + Id dref, spv::ImageOperandsMask image_operands, + std::span operands) { + code->Reserve(7 + operands.size()); + return *code << OpId{spv::Op::OpImageSparseSampleDrefExplicitLod, result_type} << sampled_image + << coordinate << dref << image_operands << operands << EndOp{}; +} + +Id Module::OpImageSparseFetch(Id result_type, Id image, Id coordinate, + std::optional image_operands, + std::span operands) { + code->Reserve(5 + (image_operands.has_value() ? 1 : 0) + operands.size()); + return *code << OpId{spv::Op::OpImageSparseFetch, result_type} << image << coordinate + << image_operands << operands << EndOp{}; +} + +Id Module::OpImageSparseGather(Id result_type, Id sampled_image, Id coordinate, Id component, + std::optional image_operands, + std::span operands) { + code->Reserve(6 + operands.size()); + return *code << OpId{spv::Op::OpImageSparseGather, result_type} << sampled_image << coordinate + << component << image_operands << operands << EndOp{}; +} + +Id Module::OpImageSparseDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands, + std::span operands) { + code->Reserve(6 + operands.size()); + return *code << OpId{spv::Op::OpImageSparseDrefGather, result_type} << sampled_image + << coordinate << dref << image_operands << operands << EndOp{}; +} + +Id Module::OpImageSparseTexelsResident(Id result_type, Id resident_code) { + code->Reserve(4); + return *code << OpId{spv::Op::OpImageSparseTexelsResident, result_type} << resident_code + << EndOp{}; +} + +Id Module::OpImageSparseRead(Id result_type, Id image, Id coordinate, + std::optional image_operands, + std::span operands) { + code->Reserve(5 + (image_operands.has_value() ? 1 : 0) + operands.size()); + return *code << OpId{spv::Op::OpImageSparseTexelsResident, result_type} << image << coordinate + << image_operands << operands << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/logical.cpp b/gpu/third_party/sirit/src/instructions/logical.cpp new file mode 100644 index 0000000..4d7292b --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/logical.cpp @@ -0,0 +1,65 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +#define DEFINE_UNARY(opcode) \ + Id Module::opcode(Id result_type, Id operand) { \ + code->Reserve(4); \ + return *code << OpId{spv::Op::opcode, result_type} << operand << EndOp{}; \ + } + +#define DEFINE_BINARY(opcode) \ + Id Module::opcode(Id result_type, Id operand_1, Id operand_2) { \ + code->Reserve(5); \ + return *code << OpId{spv::Op::opcode, result_type} << operand_1 << operand_2 << EndOp{}; \ + } + +#define DEFINE_TRINARY(opcode) \ + Id Module::opcode(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \ + code->Reserve(6); \ + return *code << OpId{spv::Op::opcode, result_type} << operand_1 << operand_2 << operand_3 \ + << EndOp{}; \ + } + +DEFINE_UNARY(OpAny) +DEFINE_UNARY(OpAll) +DEFINE_UNARY(OpIsNan) +DEFINE_UNARY(OpIsInf) +DEFINE_BINARY(OpLogicalEqual) +DEFINE_BINARY(OpLogicalNotEqual) +DEFINE_BINARY(OpLogicalOr) +DEFINE_BINARY(OpLogicalAnd) +DEFINE_UNARY(OpLogicalNot) +DEFINE_TRINARY(OpSelect) +DEFINE_BINARY(OpIEqual) +DEFINE_BINARY(OpINotEqual) +DEFINE_BINARY(OpUGreaterThan) +DEFINE_BINARY(OpSGreaterThan) +DEFINE_BINARY(OpUGreaterThanEqual) +DEFINE_BINARY(OpSGreaterThanEqual) +DEFINE_BINARY(OpULessThan) +DEFINE_BINARY(OpSLessThan) +DEFINE_BINARY(OpULessThanEqual) +DEFINE_BINARY(OpSLessThanEqual) +DEFINE_BINARY(OpFOrdEqual) +DEFINE_BINARY(OpFUnordEqual) +DEFINE_BINARY(OpFOrdNotEqual) +DEFINE_BINARY(OpFUnordNotEqual) +DEFINE_BINARY(OpFOrdLessThan) +DEFINE_BINARY(OpFUnordLessThan) +DEFINE_BINARY(OpFOrdGreaterThan) +DEFINE_BINARY(OpFUnordGreaterThan) +DEFINE_BINARY(OpFOrdLessThanEqual) +DEFINE_BINARY(OpFUnordLessThanEqual) +DEFINE_BINARY(OpFOrdGreaterThanEqual) +DEFINE_BINARY(OpFUnordGreaterThanEqual) + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/memory.cpp b/gpu/third_party/sirit/src/instructions/memory.cpp new file mode 100644 index 0000000..d6bdf0c --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/memory.cpp @@ -0,0 +1,74 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpImageTexelPointer(Id result_type, Id image, Id coordinate, Id sample) { + code->Reserve(6); + return *code << OpId{spv::Op::OpImageTexelPointer, result_type} << image << coordinate << sample + << EndOp{}; +} + +Id Module::OpLoad(Id result_type, Id pointer, std::span memory_access) { + code->Reserve(4 + memory_access.size()); + return *code << OpId{spv::Op::OpLoad, result_type} << pointer << memory_access << EndOp{}; +} + +Id Module::OpStore(Id pointer, Id object, std::span memory_access) { + code->Reserve(3 + memory_access.size()); + return *code << spv::Op::OpStore << pointer << object << memory_access << EndOp{}; +} + +Id Module::OpAccessChain(Id result_type, Id base, std::span indexes) { + assert(!indexes.empty()); + code->Reserve(4 + indexes.size()); + return *code << OpId{spv::Op::OpAccessChain, result_type} << base << indexes << EndOp{}; +} + +Id Module::OpVectorExtractDynamic(Id result_type, Id vector, Id index) { + code->Reserve(5); + return *code << OpId{spv::Op::OpVectorExtractDynamic, result_type} << vector << index + << EndOp{}; +} + +Id Module::OpVectorInsertDynamic(Id result_type, Id vector, Id component, Id index) { + code->Reserve(6); + return *code << OpId{spv::Op::OpVectorInsertDynamic, result_type} << vector << component + << index << EndOp{}; +} + +Id Module::OpVectorShuffle(Id result_type, Id vector_1, Id vector_2, std::span components) { + code->Reserve(5 + components.size()); + return *code << OpId{spv::Op::OpVectorShuffle, result_type} << vector_1 << vector_2 + << components << EndOp{}; +} + +Id Module::OpCompositeInsert(Id result_type, Id object, Id composite, + std::span indexes) { + code->Reserve(5 + indexes.size()); + return *code << OpId{spv::Op::OpCompositeInsert, result_type} << object << composite << indexes + << EndOp{}; +} + +Id Module::OpCompositeExtract(Id result_type, Id composite, std::span indexes) { + code->Reserve(4 + indexes.size()); + return *code << OpId{spv::Op::OpCompositeExtract, result_type} << composite << indexes + << EndOp{}; +} + +Id Module::OpCompositeConstruct(Id result_type, std::span ids) { + assert(ids.size() >= 1); + code->Reserve(3 + ids.size()); + return *code << OpId{spv::Op::OpCompositeConstruct, result_type} << ids << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/misc.cpp b/gpu/third_party/sirit/src/instructions/misc.cpp new file mode 100644 index 0000000..8cf77f1 --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/misc.cpp @@ -0,0 +1,43 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::OpUndef(Id result_type) { + code->Reserve(3); + return *code << OpId{spv::Op::OpUndef, result_type} << EndOp{}; +} + +void Module::OpEmitVertex() { + code->Reserve(1); + *code << spv::Op::OpEmitVertex << EndOp{}; +} + +void Module::OpEndPrimitive() { + code->Reserve(1); + *code << spv::Op::OpEndPrimitive << EndOp{}; +} + +void Module::OpEmitStreamVertex(Id stream) { + code->Reserve(2); + *code << spv::Op::OpEmitStreamVertex << stream << EndOp{}; +} + +void Module::OpEndStreamPrimitive(Id stream) { + code->Reserve(2); + *code << spv::Op::OpEndStreamPrimitive << stream << EndOp{}; +} + +Id Module::OpReadClockKHR(Id result_type, Id scope) { + code->Reserve(4); + return *code << OpId{spv::Op::OpReadClockKHR, result_type} << scope << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/instructions/type.cpp b/gpu/third_party/sirit/src/instructions/type.cpp new file mode 100644 index 0000000..3509d1f --- /dev/null +++ b/gpu/third_party/sirit/src/instructions/type.cpp @@ -0,0 +1,130 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include +#include + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +Id Module::TypeVoid() { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypeVoid} << EndOp{}; +} + +Id Module::TypeBool() { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypeBool} << EndOp{}; +} + +Id Module::TypeInt(int width, bool is_signed) { + declarations->Reserve(4); + return *declarations << OpId{spv::Op::OpTypeInt} << width << is_signed << EndOp{}; +} + +Id Module::TypeSInt(int width) { + return TypeInt(width, true); +} + +Id Module::TypeUInt(int width) { + return TypeInt(width, false); +} + +Id Module::TypeFloat(int width) { + declarations->Reserve(3); + return *declarations << OpId{spv::Op::OpTypeFloat} << width << EndOp{}; +} + +Id Module::TypeVector(Id component_type, int component_count) { + assert(component_count >= 2); + declarations->Reserve(4); + return *declarations << OpId{spv::Op::OpTypeVector} << component_type << component_count + << EndOp{}; +} + +Id Module::TypeMatrix(Id column_type, int column_count) { + assert(column_count >= 2); + declarations->Reserve(4); + return *declarations << OpId{spv::Op::OpTypeMatrix} << column_type << column_count << EndOp{}; +} + +Id Module::TypeImage(Id sampled_type, spv::Dim dim, int depth, bool arrayed, bool ms, int sampled, + spv::ImageFormat image_format, + std::optional access_qualifier) { + declarations->Reserve(10); + return *declarations << OpId{spv::Op::OpTypeImage} << sampled_type << dim << depth << arrayed + << ms << sampled << image_format << access_qualifier << EndOp{}; +} + +Id Module::TypeSampler() { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypeSampler} << EndOp{}; +} + +Id Module::TypeSampledImage(Id image_type) { + declarations->Reserve(3); + return *declarations << OpId{spv::Op::OpTypeSampledImage} << image_type << EndOp{}; +} + +Id Module::TypeArray(Id element_type, Id length) { + declarations->Reserve(4); + return *declarations << OpId{spv::Op::OpTypeArray} << element_type << length << EndOp{}; +} + +Id Module::TypeRuntimeArray(Id element_type) { + declarations->Reserve(3); + return *declarations << OpId{spv::Op::OpTypeRuntimeArray} << element_type << EndOp{}; +} + +Id Module::TypeStruct(std::span members) { + declarations->Reserve(2 + members.size()); + return *declarations << OpId{spv::Op::OpTypeStruct} << members << EndOp{}; +} + +Id Module::TypeOpaque(std::string_view name) { + declarations->Reserve(3 + WordsInString(name)); + return *declarations << OpId{spv::Op::OpTypeOpaque} << name << EndOp{}; +} + +Id Module::TypePointer(spv::StorageClass storage_class, Id type) { + declarations->Reserve(4); + return *declarations << OpId{spv::Op::OpTypePointer} << storage_class << type << EndOp{}; +} + +Id Module::TypeFunction(Id return_type, std::span arguments) { + declarations->Reserve(3 + arguments.size()); + return *declarations << OpId{spv::Op::OpTypeFunction} << return_type << arguments << EndOp{}; +} + +Id Module::TypeEvent() { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypeEvent} << EndOp{}; +} + +Id Module::TypeDeviceEvent() { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypeDeviceEvent} << EndOp{}; +} + +Id Module::TypeReserveId() { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypeReserveId} << EndOp{}; +} + +Id Module::TypeQueue() { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypeQueue} << EndOp{}; +} + +Id Module::TypePipe(spv::AccessQualifier access_qualifier) { + declarations->Reserve(2); + return *declarations << OpId{spv::Op::OpTypePipe} << access_qualifier << EndOp{}; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/sirit.cpp b/gpu/third_party/sirit/src/sirit.cpp new file mode 100644 index 0000000..59bd508 --- /dev/null +++ b/gpu/third_party/sirit/src/sirit.cpp @@ -0,0 +1,189 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include + +#include "sirit/sirit.h" + +#include "common_types.h" +#include "stream.h" + +namespace Sirit { + +constexpr u32 MakeWord0(spv::Op op, size_t word_count) { + return static_cast(op) | static_cast(word_count) << 16; +} + +Module::Module(u32 version_) + : version{version_}, ext_inst_imports{std::make_unique(&bound)}, + entry_points{std::make_unique(&bound)}, + execution_modes{std::make_unique(&bound)}, debug{std::make_unique(&bound)}, + debug_name{std::make_unique(&bound)}, annotations{std::make_unique(&bound)}, + declarations{std::make_unique(&bound)}, + global_variables{std::make_unique(&bound)}, code{std::make_unique(&bound)} {} + +Module::~Module() = default; + +std::vector Module::Assemble() const { + std::vector words = {spv::MagicNumber, version, GENERATOR_MAGIC_NUMBER, bound + 1, 0}; + const auto insert = [&words](std::span input) { + words.insert(words.end(), input.begin(), input.end()); + }; + + words.reserve(words.size() + capabilities.size() * 2); + for (const spv::Capability capability : capabilities) { + insert(std::array{ + MakeWord0(spv::Op::OpCapability, 2), + static_cast(capability), + }); + } + + for (const std::string_view extension_name : extensions) { + size_t string_words = WordsInString(extension_name); + words.push_back(MakeWord0(spv::Op::OpExtension, string_words + 1)); + size_t insert_index = words.size(); + words.resize(words.size() + string_words); + InsertStringView(words, insert_index, extension_name); + } + + insert(ext_inst_imports->Words()); + + insert(std::array{ + MakeWord0(spv::Op::OpMemoryModel, 3), + static_cast(addressing_model), + static_cast(memory_model), + }); + + insert(entry_points->Words()); + insert(execution_modes->Words()); + insert(debug->Words()); + insert(debug_name->Words()); + insert(annotations->Words()); + insert(declarations->Words()); + insert(global_variables->Words()); + insert(code->Words()); + + return words; +} + +void Module::PatchDeferredPhi(const std::function(std::size_t arg, Id parent)>& func) { + for (const u32 phi_index : deferred_phi_nodes) { + const u32 first_word = code->Value(phi_index); + [[maybe_unused]] const spv::Op op = static_cast(first_word & 0xffff); + assert(op == spv::Op::OpPhi); + const u32 num_words = first_word >> 16; + const u32 num_args = (num_words - 3) / 2; + u32 cursor = phi_index + 3; + for (u32 arg = 0; arg < num_args; ++arg, cursor += 2) { + const Id current_parent{code->Value(cursor + 1)}; + const auto [variable, parent] = func(arg, current_parent); + code->SetValue(cursor, variable.value); + code->SetValue(cursor + 1, parent.value); + } + } +} + +void Module::AddExtension(std::string extension_name) { + extensions.insert(std::move(extension_name)); +} + +void Module::AddCapability(spv::Capability capability) { + capabilities.insert(capability); +} + +void Module::SetMemoryModel(spv::AddressingModel addressing_model_, + spv::MemoryModel memory_model_) { + addressing_model = addressing_model_; + memory_model = memory_model_; +} + +void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, + std::string_view name, std::span interfaces) { + entry_points->Reserve(4 + WordsInString(name) + interfaces.size()); + *entry_points << spv::Op::OpEntryPoint << execution_model << entry_point << name << interfaces + << EndOp{}; +} + +void Module::AddExecutionMode(Id entry_point, spv::ExecutionMode mode, + std::span literals) { + execution_modes->Reserve(3 + literals.size()); + *execution_modes << spv::Op::OpExecutionMode << entry_point << mode << literals << EndOp{}; +} + +Id Module::AddLabel(Id label) { + assert(label.value != 0); + code->Reserve(2); + *code << MakeWord0(spv::Op::OpLabel, 2) << label.value; + return label; +} + +Id Module::AddLocalVariable(Id result_type, spv::StorageClass storage_class, + std::optional initializer) { + code->Reserve(5); + return *code << OpId{spv::Op::OpVariable, result_type} << storage_class << initializer + << EndOp{}; +} + +Id Module::AddGlobalVariable(Id result_type, spv::StorageClass storage_class, + std::optional initializer) { + global_variables->Reserve(5); + return *global_variables << OpId{spv::Op::OpVariable, result_type} << storage_class + << initializer << EndOp{}; +} + +Id Module::GetGLSLstd450() { + const char* extname = "GLSL.std.450"; + size_t len = WordsInString(extname); + if (!glsl_std_450) { + ext_inst_imports->Reserve(3 + len); + glsl_std_450 = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << extname << EndOp{}; + } + return *glsl_std_450; +} + +Id Module::GetNonSemanticDebugPrintf() { + const char* extname = "NonSemantic.DebugPrintf"; + size_t len = WordsInString(extname); + if (!non_semantic_debug_printf) { + ext_inst_imports->Reserve(3 + len); + non_semantic_debug_printf = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << extname + << EndOp{}; + } + return *non_semantic_debug_printf; +} + +Id Module::GetAmdGcnShader() { + const char* extname = "SPV_AMD_gcn_shader"; + size_t len = WordsInString(extname); + if (!amd_gcn_shader) { + ext_inst_imports->Reserve(3 + len); + amd_gcn_shader = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << extname << EndOp{}; + } + return *amd_gcn_shader; +} + +Id Module::GetAmdShaderTrinaryMinMax() { + const char* extname = "SPV_AMD_shader_trinary_minmax"; + size_t len = WordsInString(extname); + if (!amd_shader_trinary_minmax) { + ext_inst_imports->Reserve(3 + len); + amd_shader_trinary_minmax = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << extname << EndOp{}; + } + return *amd_shader_trinary_minmax; +} + + +Id Module::GetAmdExplicitVertexParameter() { + const char* extname = "SPV_AMD_shader_explicit_vertex_parameter"; + size_t len = WordsInString(extname); + if (!amd_explicit_vertex_parameter) { + ext_inst_imports->Reserve(3 + len); + amd_explicit_vertex_parameter = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << extname << EndOp{}; + } + return *amd_explicit_vertex_parameter; +} + +} // namespace Sirit diff --git a/gpu/third_party/sirit/src/stream.cpp b/gpu/third_party/sirit/src/stream.cpp new file mode 100644 index 0000000..e69de29 diff --git a/gpu/third_party/sirit/src/stream.h b/gpu/third_party/sirit/src/stream.h new file mode 100644 index 0000000..31c2680 --- /dev/null +++ b/gpu/third_party/sirit/src/stream.h @@ -0,0 +1,274 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __cpp_lib_bit_cast +#include +#endif + +#include + +#include "common_types.h" + +namespace Sirit { + +class Declarations; + +struct OpId { + OpId(spv::Op opcode_) : opcode{opcode_} {} + OpId(spv::Op opcode_, Id result_type_) : opcode{opcode_}, result_type{result_type_} { + assert(result_type.value != 0); + } + + spv::Op opcode{}; + Id result_type{}; +}; + +struct EndOp {}; + +inline size_t WordsInString(std::string_view string) { + return string.size() / sizeof(u32) + 1; +} + +inline void InsertStringView(std::vector& words, size_t& insert_index, + std::string_view string) { + const size_t size = string.size(); + const auto read = [string, size](size_t offset) { + return offset < size ? static_cast(string[offset]) : 0u; + }; + + for (size_t i = 0; i < size; i += sizeof(u32)) { + words[insert_index++] = read(i) | read(i + 1) << 8 | read(i + 2) << 16 | read(i + 3) << 24; + } + if (size % sizeof(u32) == 0) { + words[insert_index++] = 0; + } +} + +class Stream { + friend Declarations; + static constexpr std::size_t GROW_STEP = 1024; +public: + explicit Stream(u32* bound_) : bound{bound_} {} + + void Reserve(size_t num_words) { + if (insert_index + num_words <= words.size()) { + return; + } + words.resize(insert_index + num_words); + } + + std::span Words() const noexcept { + return std::span(words.data(), insert_index); + } + + u32 LocalAddress() const noexcept { + return static_cast(words.size()); + } + + u32 Value(u32 index) const noexcept { + return words[index]; + } + + void SetValue(u32 index, u32 value) noexcept { + words[index] = value; + } + + Stream& operator<<(spv::Op op) { + op_index = insert_index; + words[insert_index++] = static_cast(op); + return *this; + } + + Stream& operator<<(OpId op) { + op_index = insert_index; + words[insert_index++] = static_cast(op.opcode); + if (op.result_type.value != 0) { + words[insert_index++] = op.result_type.value; + } + words[insert_index++] = ++*bound; + return *this; + } + + Id operator<<(EndOp) { + const size_t num_words = insert_index - op_index; + words[op_index] |= static_cast(num_words) << 16; + return Id{*bound}; + } + + Stream& operator<<(u32 value) { + words[insert_index++] = value; + return *this; + } + + Stream& operator<<(s32 value) { + return *this << static_cast(value); + } + + Stream& operator<<(u64 value) { + return *this << static_cast(value) << static_cast(value >> 32); + } + + Stream& operator<<(s64 value) { + return *this << static_cast(value); + } + + Stream& operator<<(float value) { +#ifdef __cpp_lib_bit_cast + return *this << std::bit_cast(value); +#else + static_assert(sizeof(float) == sizeof(u32)); + u32 int_value; + std::memcpy(&int_value, &value, sizeof(int_value)); + return *this << int_value; +#endif + } + + Stream& operator<<(double value) { +#ifdef __cpp_lib_bit_cast + return *this << std::bit_cast(value); +#else + static_assert(sizeof(double) == sizeof(u64)); + u64 int_value; + std::memcpy(&int_value, &value, sizeof(int_value)); + return *this << int_value; +#endif + } + + Stream& operator<<(bool value) { + return *this << static_cast(value ? 1 : 0); + } + + Stream& operator<<(Id value) { + if (value.value == 0) { + std::abort(); + } + return *this << value.value; + } + + Stream& operator<<(const Literal& literal) { + std::visit([this](auto value) { *this << value; }, literal); + return *this; + } + + Stream& operator<<(const MemoryAccessLiteral& memory_access) { + std::visit([this](auto value) { *this << value; }, memory_access); + return *this; + } + + Stream& operator<<(std::string_view string) { + InsertStringView(words, insert_index, string); + return *this; + } + + Stream& operator<<(const char* string) { + return *this << std::string_view{string}; + } + + template + requires std::is_enum_v Stream& operator<<(T value) { + static_assert(sizeof(T) == sizeof(u32)); + return *this << static_cast(value); + } + + template + Stream& operator<<(std::optional value) { + if (value) { + *this << *value; + } + return *this; + } + + template + Stream& operator<<(std::span values) { + for (const auto& value : values) { + *this << value; + } + return *this; + } + +private: + u32* bound = nullptr; + std::vector words; + size_t insert_index = 0; + size_t op_index = 0; +}; + +class Declarations { +public: + explicit Declarations(u32* bound) : stream{bound} {} + + void Reserve(size_t num_words) { + return stream.Reserve(num_words); + } + + std::span Words() const noexcept { + return stream.Words(); + } + + template + Declarations& operator<<(const T& value) { + stream << value; + return *this; + } + + // Declarations without an id don't exist + Declarations& operator<<(spv::Op) = delete; + + Declarations& operator<<(OpId op) { + id_index = op.result_type.value != 0 ? 2 : 1; + stream << op; + return *this; + } + + Id operator<<(EndOp) { + const auto begin = stream.words.data(); + std::vector declarations(begin + stream.op_index, begin + stream.insert_index); + + // Normalize result id for lookups + const u32 id = std::exchange(declarations[id_index], 0); + + const auto [entry, inserted] = existing_declarations.emplace(declarations, id); + if (inserted) { + return stream << EndOp{}; + } + // If the declaration already exists, undo the operation + stream.insert_index = stream.op_index; + --*stream.bound; + + return Id{entry->second}; + } + +private: + struct HashVector { + size_t operator()(const std::vector& vector) const noexcept { + size_t hash = std::hash{}(vector.size()); + for (const u32 value : vector) { + hash ^= std::hash{}(value); + } + return hash; + } + }; + + Stream stream; + std::unordered_map, u32, HashVector> existing_declarations; + size_t id_index = 0; +}; + +} // namespace Sirit diff --git a/gpu/third_party/sirit/tests/CMakeLists.txt b/gpu/third_party/sirit/tests/CMakeLists.txt new file mode 100644 index 0000000..a3f9534 --- /dev/null +++ b/gpu/third_party/sirit/tests/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(sirit_tests + main.cpp) +target_link_libraries(sirit_tests PRIVATE sirit) +target_include_directories(sirit_tests PRIVATE . ../include) + +add_test(sirit_tests sirit_tests) diff --git a/gpu/third_party/sirit/tests/main.cpp b/gpu/third_party/sirit/tests/main.cpp new file mode 100644 index 0000000..d119c25 --- /dev/null +++ b/gpu/third_party/sirit/tests/main.cpp @@ -0,0 +1,139 @@ +/* This file is part of the sirit project. + * Copyright (c) 2019 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include +#include +#include + +#include + +class MyModule : public Sirit::Module { +public: + MyModule() : Sirit::Module{0x00010300} {} + ~MyModule() = default; + + void Generate() { + AddCapability(spv::Capability::Shader); + SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450); + + const auto t_void = Name(TypeVoid(), "void"); + const auto t_uint = Name(TypeInt(32, false), "uint"); + const auto t_float = Name(TypeFloat(32), "float"); + + const auto float4 = Name(TypeVector(t_float, 4), "float4"); + const auto in_float = Name(TypePointer(spv::StorageClass::Input, t_float), "in_float"); + const auto in_float4 = Name(TypePointer(spv::StorageClass::Input, float4), "in_float4"); + const auto out_float4 = Name(TypePointer(spv::StorageClass::Output, float4), "out_float4"); + + const auto gl_per_vertex = Name(TypeStruct(float4), "gl_PerVertex"); + const auto gl_per_vertex_ptr = + Name(TypePointer(spv::StorageClass::Output, gl_per_vertex), "out_gl_PerVertex"); + + const auto in_pos = Name(AddGlobalVariable(in_float4, spv::StorageClass::Input), "in_pos"); + const auto per_vertex = + Name(AddGlobalVariable(gl_per_vertex_ptr, spv::StorageClass::Output), "per_vertex"); + + Decorate(in_pos, spv::Decoration::Location, 0); + Decorate(gl_per_vertex, spv::Decoration::Block); + Decorate(gl_per_vertex, spv::Decoration::Block); + MemberDecorate(gl_per_vertex, 0, spv::Decoration::BuiltIn, + static_cast(spv::BuiltIn::Position)); + + const auto main_func = Name( + OpFunction(t_void, spv::FunctionControlMask::MaskNone, TypeFunction(t_void)), "main"); + AddLabel(); + + const auto ptr_pos_x = OpAccessChain(in_float, in_pos, Constant(t_uint, 0u)); + const auto ptr_pos_y = OpAccessChain(in_float, in_pos, Constant(t_uint, 1u)); + + const auto pos_x = OpLoad(t_float, ptr_pos_x); + const auto pos_y = OpLoad(t_float, ptr_pos_y); + + auto tmp_position = OpUndef(float4); + tmp_position = OpCompositeInsert(float4, pos_x, tmp_position, 0); + tmp_position = OpCompositeInsert(float4, pos_y, tmp_position, 1); + tmp_position = OpCompositeInsert(float4, Constant(t_float, 0.0f), tmp_position, 2); + tmp_position = OpCompositeInsert(float4, Constant(t_float, 1.0f), tmp_position, 3); + + const auto gl_position = OpAccessChain(out_float4, per_vertex, Constant(t_uint, 0u)); + OpStore(gl_position, tmp_position); + + OpReturn(); + OpFunctionEnd(); + + AddEntryPoint(spv::ExecutionModel::Vertex, main_func, "main", in_pos, per_vertex); + } +}; + +static constexpr std::uint8_t expected_binary[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x76, 0x6f, 0x69, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x75, 0x69, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x34, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x5f, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x69, 0x6e, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x00, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x6f, 0x75, 0x74, 0x5f, 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x5f, 0x70, + 0x6f, 0x73, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x65, 0x72, 0x5f, + 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x3b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, +}; + +int main(int argc, char** argv) { + MyModule module; + module.Generate(); + + std::vector code = module.Assemble(); + if (std::size(code) * sizeof(std::uint32_t) != std::size(expected_binary)) { + return EXIT_FAILURE; + } + if (std::memcmp(std::data(code), std::data(expected_binary), std::size(expected_binary)) != 0) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/import_names.inc b/import_names.inc new file mode 100644 index 0000000..55e9285 --- /dev/null +++ b/import_names.inc @@ -0,0 +1,750 @@ +/* NID -> symbol name for eboot and linked libc imports (diagnostics only). + * Names from public PS4 symbol lists (as collected in shadPS4 aerolib). */ +{"bzQExy189ZI#q#q","_init_env"}, +{"8G2LB+A3rzg#q#q","atexit"}, +{"XKRegsFpEpk#q#q","catchReturnFromMain"}, +{"uMei1W9uyNo#q#q","exit"}, +{"Ou3iL1abvng#p#J","__stack_chk_fail"}, +{"HUbZmOnT-Dg#q#q","atan2"}, +{"ZtjspkJQ+vw#q#q","_FSin"}, +{"pKwslsMUmSk#q#q","fmod"}, +{"3GPpjQdAMTw#q#q","__cxa_guard_acquire"}, +{"tsvEmnenz48#q#q","__cxa_atexit"}, +{"9rAeANT2tyE#q#q","__cxa_guard_release"}, +{"Ovb2dSJOAuE#q#q","strcmp"}, +{"Q3VBxCXhUHs#q#q","memcpy"}, +{"z+P+xCnWLBk#q#q","_ZdlPv"}, +{"7H0iTOciTLo#I#J","pthread_mutex_lock"}, +{"2Z+PpY6CaJg#I#J","pthread_mutex_unlock"}, +{"dQHWEsJtoE4#I#J","pthread_mutexattr_init"}, +{"mDmgMOGVUqg#I#J","pthread_mutexattr_settype"}, +{"ttHNfU+qDBU#I#J","pthread_mutex_init"}, +{"ltCfaGr2JGE#I#J","pthread_mutex_destroy"}, +{"9yDWMxEFdJU#q#q","strrchr"}, +{"j4ViWNHEgww#q#q","strlen"}, +{"Q2V+iqvjgC0#q#q","vsnprintf"}, +{"viiwFMaNamA#q#q","strstr"}, +{"DfivPArhucg#q#q","memcmp"}, +{"ZE6RNL+eLbk#q#q","tanf"}, +{"+P6FRGH4LfA#q#q","memmove"}, +{"88Vv-AzHVj8#q#q","fmodf"}, +{"q+9E0X3aWpU#q#q","_Stoull"}, +{"8zTFvBIAIN8#q#q","memset"}, +{"EH-x713A99c#q#q","atan2f"}, +{"zlfEH8FmyUA#q#q","_Stoul"}, +{"aesyjrHVWy4#q#q","strncmp"}, +{"sUP1hBaouOw#q#q","_Getpctype"}, +{"AV6ipCNa4Rw#q#q","strcasecmp"}, +{"pXvbDfchu6k#q#q","strncasecmp"}, +{"0hlfW1O4Aa4#q#q","localeconv"}, +{"kiZSXIWd9vg#q#q","strcpy"}, +{"c41UEHVtiEA#q#q","_Stod"}, +{"n88vx3C5nW8#I#J","gettimeofday"}, +{"xeYO4u7uyJ0#q#q","fopen"}, +{"3QIPIh-GDjw#q#q","rewind"}, +{"9BcDykPmo1I#p#J","__error"}, +{"Qazy8LmXTvw#q#q","ftell"}, +{"MUjC4lbHrK4#q#q","fflush"}, +{"MpxhMh8QFro#q#q","fwrite"}, +{"lbB+UlZqVG0#q#q","fread"}, +{"rQFVBXp-Cxg#q#q","fseek"}, +{"uodLYyUip20#q#q","fclose"}, +{"E6ao34wPw+U#I#J","stat"}, +{"EotR8a3ASf4#I#J","pthread_self"}, +{"K-jXhbt2gn4#I#J","pthread_mutex_trylock"}, +{"0TyVk4MSLt0#I#J","pthread_cond_init"}, +{"RXXqi4CtF8w#I#J","pthread_cond_destroy"}, +{"27bAgiJmOh0#I#J","pthread_cond_timedwait"}, +{"Op8TBGY5KHg#I#J","pthread_cond_wait"}, +{"2MOy+rUfuhQ#I#J","pthread_cond_signal"}, +{"mkx2fVhNMsg#I#J","pthread_cond_broadcast"}, +{"wtkt-teR1so#I#J","pthread_attr_init"}, +{"E+tyo3lp5Lw#I#J","pthread_attr_setdetachstate"}, +{"2Q0z6rnBrTE#I#J","pthread_attr_setstacksize"}, +{"euKRgm0Vn2M#I#J","pthread_attr_setschedparam"}, +{"OxhIB8LB-PQ#I#J","pthread_create"}, +{"zHchY8ft5pk#I#J","pthread_attr_destroy"}, +{"FJrT5LuUBAU#I#J","pthread_exit"}, +{"0wu33hunNdE#I#J","sleep"}, +{"QcteRwbsnV0#I#J","usleep"}, +{"GBUY7ywdULE#p#J","scePthreadRename"}, +{"gNQ1V2vfXDE#q#q","setjmp"}, +{"6sJWiWSRuqk#q#q","strncpy"}, +{"ob5xAW4ln-0#q#q","strchr"}, +{"hdm0YfMa7TQ#q#q","_Znam"}, +{"MLWl90SFWNE#q#q","_ZdaPv"}, +{"1D0H2KNjshE#q#q","powf"}, +{"QI-x0SL8jhw#q#q","acosf"}, +{"hcuQgD53UxM#q#q","printf"}, +{"lKEN2IebgJ0#q#q","longjmp"}, +{"JBcgYuW8lPU#q#q","acos"}, +{"T7uyNqP7vQA#q#q","tan"}, +{"fJnpuVVBbKk#q#q","_Znwm"}, +{"mXlxhmLNMPg#q#q","strtol"}, +{"cCXjU72Z0Ow#q#q","_Sin"}, +{"q0F6yS-rCms#q#q","strcspn"}, +{"-kU6bB4M-+k#q#q","strspn"}, +{"7Ly52zaL44Q#q#q","asin"}, +{"OXmauLdQ8kY#q#q","atan"}, +{"NVadfnzQhHQ#q#q","exp"}, +{"zXCi78bYrEI#q#q","_Log"}, +{"9LCjpWyQ5Zc#q#q","pow"}, +{"GZWjF-YIFFk#q#q","asinf"}, +{"fiiNDnNBKVY#q#q","localtime_s"}, +{"0WMHDb5Dt94#q#q","modf"}, +{"jjjRS7l1MPM#q#q","_FLog"}, +{"oVkZ8W8-Q8A#q#q","strtok"}, +{"4J2sUJmuHZQ#p#J","sceKernelGetProcessTime"}, +{"pO96TwzOm5E#p#J","sceKernelGetDirectMemorySize"}, +{"rTXw65xmLIA#p#J","sceKernelAllocateDirectMemory"}, +{"L-Q3LEjIbgA#p#J","sceKernelMapDirectMemory"}, +{"MBuItvba6z8#p#J","sceKernelReleaseDirectMemory"}, +{"gQX+4GDQjpM#q#q","malloc"}, +{"tIhsqj0qsFE#q#q","free"}, +{"fffwELXNVFA#q#q","fprintf"}, +{"tcVi5SivF7Q#q#q","sprintf"}, +{"kA-TdiOCsaY#q#q","frexp"}, +{"aZK8lNei-Qw#q#q","fputc"}, +{"L1SBTkC+Cvw#q#q","abort"}, +{"1mecP7RgI2A#q#q","gmtime"}, +{"wLlFkwG9UcQ#q#q","time"}, +{"VPbJwTCgME0#q#q","srand"}, +{"cpCOXWMgha0#q#q","rand"}, +{"vNe1w4diLCs#p#J","__tls_get_addr"}, +{"EMutwaQ34Jo#q#q","perror"}, +{"HF7lK46xzjY#I#J","pthread_mutexattr_destroy"}, +{"Ujf3KzMvRmI#q#q","memalign"}, +{"QZP6I9ZZxpE#q#q","clock"}, +{"h9CcP3J0oVM#I#J","pthread_join"}, +{"Jmi+9w9u0E4#I#J","pthread_create_name_np"}, +{"jbz9I9vkqkk#q#q","vsprintf"}, +{"Ls4tzzhimqQ#q#q","strcat"}, +{"kHg45qPC6f0#q#q","strncat"}, +{"7pNKcscKrf8#q#q","_Stoll"}, +{"1uJgoVq3bQU#q#q","_Getptolower"}, +{"188x57JYp0g#p#J","sceKernelCreateSema"}, +{"R1Jvn8bSCW8#p#J","sceKernelDeleteSema"}, +{"Zxa0VhQVTsk#p#J","sceKernelWaitSema"}, +{"4czppHBiriw#p#J","sceKernelSignalSema"}, +{"bDupEgbQ6Fk#F#G","sceFiosFileDeleteSync"}, +{"-ULUBK21QgE#F#G","sceFiosDirectoryCreate"}, +{"jayvY07C5dk#F#G","sceFiosStatSync"}, +{"uCkgJOrYUL4#F#G","sceFiosDHOpen"}, +{"SnoQQWnGK9I#F#G","sceFiosOpWait"}, +{"0-p4O8FINmU#F#G","sceFiosDHCloseSync"}, +{"+FRvKknUj1I#F#G","sceFiosOpGetActualCount"}, +{"5cyEcilO-J0#F#G","sceFiosOpDelete"}, +{"GGqucL9F+YI#F#G","sceFiosDHOpenSync"}, +{"odjOGg8harg#F#G","sceFiosDHReadSync"}, +{"Nlev7Lg8k3A#E#F","sceNetInit"}, +{"cTGkc6-TBlI#E#F","sceNetTerm"}, +{"SF47kB2MNTo#E#F","sceNetEpollCreate"}, +{"ZVw46bsasAk#E#F","sceNetEpollControl"}, +{"HQOwnfMGipQ#E#F","sceNetErrnoLoc"}, +{"Inp1lfL+Jdw#E#F","sceNetEpollDestroy"}, +{"Q4qBuN-c0ZM#E#F","sceNetSocket"}, +{"45ggEzakPJQ#E#F","sceNetSocketClose"}, +{"9wO9XrMsNhc#E#F","sceNetRecv"}, +{"beRjXBn-z+o#E#F","sceNetSend"}, +{"8Kcp5d-q1Uo#E#F","sceNetInetPton"}, +{"OXXX4mUk3uk#E#F","sceNetConnect"}, +{"iWQWrwiSt8A#E#F","sceNetHtons"}, +{"bErx49PgxyY#E#F","sceNetBind"}, +{"kOj1HiAGE54#E#F","sceNetListen"}, +{"drjIbDbA7UQ#E#F","sceNetEpollWait"}, +{"YQ0navp+YIc#q#q","puts"}, +{"PIWqhn9oSxc#E#F","sceNetAccept"}, +{"Rbvt+5Y2iEw#E#F","sceNetNtohs"}, +{"2mKX2Spso7I#E#F","sceNetSetsockopt"}, +{"b44anV2D7K0#F#G","sceFiosFHOpenSync"}, +{"AOujSGqU+ms#F#G","sceFiosFHCloseSync"}, +{"Kl-TbrDU9YM#F#G","sceFiosFHWriteSync"}, +{"EzzSJz6yuMc#F#G","sceFiosFHSyncSync"}, +{"xReSebwKApA#F#G","sceFiosFHSeek"}, +{"MrRFrdgpsx8#F#G","sceFiosFHTell"}, +{"Bn2ZF4ZjeuQ#F#G","sceFiosFHReadSync"}, +{"JGMio+21L4c#I#J","mkdir"}, +{"SHlt7EhOtqA#q#q","fgetpos"}, +{"TSM6whtekok#E#F","sceNetShutdown"}, +{"C4UgDHHPvdw#E#F","sceNetResolverCreate"}, +{"Nd91WaWmG2w#E#F","sceNetResolverStartNtoa"}, +{"kJlYH5uMAWI#E#F","sceNetResolverDestroy"}, +{"obuxdTiwkF8#J#K","sceNetCtlGetInfo"}, +{"uBPlr0lbuiI#J#K","sceNetCtlGetState"}, +{"pDBDcY6uLSA#q#q","vfprintf"}, +{"MZO7FXyAPU8#q#q","remove"}, +{"NN01qLRhiqU#I#J","rename"}, +{"c7ZnT7V1B98#I#J","rmdir"}, +{"LxcEU+ICu8U#q#q","feof"}, +{"St9nbxSoezk#q#q","clearerr"}, +{"AEuF3F2f8TA#q#q","fgetc"}, +{"-LFO7jhD5CE#q#q","ungetc"}, +{"KdP-nULpuGw#q#q","fgets"}, +{"npLpPTaSuHg#q#q","fscanf"}, +{"AHxyhN96dy4#q#q","ferror"}, +{"QMFyLoqNxIg#q#q","setvbuf"}, +{"gkWgn0p1AfU#q#q","freopen"}, +{"k+AXqu2-eBc#I#J","getpagesize"}, +{"gjbmYpP-XJQ#q#q","strcoll"}, +{"QNyUWGXmXNc#q#q","strtoumax"}, +{"AEJdIVZTEmo#q#q","qsort"}, +{"m5wN+SwZOR4#q#q","putchar"}, +{"aaDMGGkXFxo#q#q","frexpf"}, +{"kn0yiYeExgA#q#q","ldexpf"}, +{"3+UPM-9E6xY#q#q","modff"}, +{"RIa6GnWp+iU#q#q","strerror"}, +{"efhK-YSUYYQ#q#q","localtime"}, +{"Av3zjWi64Kw#q#q","strftime"}, +{"rcQCUr0EaRU#q#q","_Getptoupper"}, +{"n7AepwR0s34#q#q","mktime"}, +{"-VVn74ZyhEs#q#q","difftime"}, +{"PtsB1Q9wsFA#q#q","setlocale"}, +{"weDug8QD-lE#q#q","atanf"}, +{"PdnFCFqKGqA#q#q","_FCosh"}, +{"8zsu04XNsZ4#q#q","expf"}, +{"O4L+0oCN9zA#q#q","_FSinh"}, +{"SAd0Z3wKwLA#q#q","tanhf"}, +{"-QgqOT5u2Vk#q#q","_Assert"}, +{"eT2UsmTewbU#q#q","_ZSt11_Xbad_allocv"}, +{"wuAQt-j+p4o#q#q","exp2f"}, +{"ozMAr28BwSY#q#q","_ZSt14_Xout_of_rangePKc"}, +{"tQIo+GIPklo#q#q","_ZSt14_Xlength_errorPKc"}, +{"dnaeGXbjP6E#q#q","exp2"}, +{"JrwFIMzKNr0#q#q","ldexp"}, +{"QrZZdJ8XsX0#q#q","fputs"}, +{"PDX01ziUz+4#q#q","_ZSt13_Syserror_mapi"}, +{"fL3O02ypZFE#q#q","wmemcpy"}, +{"Noj9PsJrsa8#q#q","wmemmove"}, +{"WkkeywLJcgU#q#q","wcslen"}, +{"Al8MZJh-4hM#q#q","wmemset"}, +{"Ezzq78ZgHPs#q#q","wcschr"}, +{"g3ShSirD50I#q#q","wcsrchr"}, +{"QJ5xVfKkni0#q#q","wmemcmp"}, +{"fnUEjBCNRVU#q#q","wmemchr"}, +{"12wOHk8ywb0#p#J","sceKernelPollSema"}, +{"nsYoNRywwNg#p#J","scePthreadAttrInit"}, +{"UTXzJbWhhTE#p#J","scePthreadAttrSetstacksize"}, +{"-Wreprtu0Qs#p#J","scePthreadAttrSetdetachstate"}, +{"4+h9EzwKF4I#p#J","scePthreadAttrSetschedpolicy"}, +{"6UgtwV+0zb4#p#J","scePthreadCreate"}, +{"62KCwEMmzcM#p#J","scePthreadAttrDestroy"}, +{"bt3CTBKmGyI#p#J","scePthreadSetaffinity"}, +{"4qGrR6eoP9Y#p#J","scePthreadDetach"}, +{"1tKyG7RlMJo#p#J","scePthreadGetprio"}, +{"W0Hpm2X0uPE#p#J","scePthreadSetprio"}, +{"onNY9Byn-W8#p#J","scePthreadJoin"}, +{"sqWytnhYdEg#q#q","_ZNSt8ios_base4InitC1Ev"}, +{"-Bl9-SZ2noc#q#q","_ZNSt6_WinitC1Ev"}, +{"hqi8yMOCmG0#q#q","_ZNSt8_LocinfoC1EPKc"}, +{"DuW5ZqZv-70#q#q","_ZNKSt9exception6_RaiseEv"}, +{"N2f485TmJms#q#q","_ZNSt8ios_base7failureD1Ev"}, +{"iPBqs+YUUFw#q#q","_Atomic_fetch_add_4"}, +{"2HnmKiLmV6s#q#q","_Atomic_fetch_sub_4"}, +{"pNtJdE3x49E#q#q","wcscmp"}, +{"kALvdgEv5ME#q#q","_Locksyslock"}, +{"9nf8joUTSaQ#q#q","_Unlocksyslock"}, +{"E8wCoUEbfzk#q#q","wcsncmp"}, +{"1G3lF1Gg1k8#p#J","sceKernelOpen"}, +{"Cg4srZ6TKbU#p#J","sceKernelRead"}, +{"4wSze92BhLI#p#J","sceKernelWrite"}, +{"oib76F-12fk#p#J","sceKernelLseek"}, +{"UK2Tl2DWUns#p#J","sceKernelClose"}, +{"g8cM39EUZ6o#M#N","sceSysmoduleLoadModule"}, +{"Qs0wWulgl7U#U#V","sceMouseInit"}, +{"cAnT0Rw-IwU#U#V","sceMouseClose"}, +{"eR2bZFAAU0Q#M#N","sceSysmoduleUnloadModule"}, +{"CdWp0oHWGr0#D#E","sceUserServiceGetInitialUser"}, +{"RaqxZIf6DvE#U#V","sceMouseOpen"}, +{"x8qnXqh-tiM#U#V","sceMouseRead"}, +{"6ncge5+l5Qs#A#B","scePadClose"}, +{"xk0AcarP3V4#A#B","scePadOpen"}, +{"YndgXqQVV7c#A#B","scePadReadState"}, +{"gjP9-KQzoUk#A#B","scePadGetControllerInformation"}, +{"rIZnR6eSpvk#A#B","scePadResetOrientation"}, +{"r44mAxdSG+U#A#B","scePadSetAngularVelocityDeadbandState"}, +{"vDLMoJLde8I#A#B","scePadSetTiltCorrectionState"}, +{"yFVnOdGxvZY#A#B","scePadSetVibration"}, +{"WFcfL2lzido#p#J","sceKernelQueryMemoryProtection"}, +{"rVjRvHJ0X6c#p#J","sceKernelVirtualQuery"}, +{"BC+OG5m9+bw#p#J","sceKernelGetDirectMemoryType"}, +{"Up36PTk687E#C#D","sceVideoOutOpen"}, +{"CBiu4mCE1DA#C#D","sceVideoOutSetFlipRate"}, +{"D0OdFMjp46I#p#J","sceKernelCreateEqueue"}, +{"HXzjK9yI30k#C#D","sceVideoOutAddFlipEvent"}, +{"i6-sR91Wt-4#C#D","sceVideoOutSetBufferAttribute"}, +{"jpFjmgAC5AE#p#J","sceKernelDeleteEqueue"}, +{"uquVH4-Du78#C#D","sceVideoOutClose"}, +{"w3BY+tAEiQY#C#D","sceVideoOutRegisterBuffers"}, +{"SbU3dwp80lQ#C#D","sceVideoOutGetFlipStatus"}, +{"fzyMKs9kim0#p#J","sceKernelWaitEqueue"}, +{"FM5NPnLqBc8#q#q","wcscpy"}, +{"w21YgGGNtBk#E#F","sceNetEpollAbort"}, +{"gvD1greCu0A#E#F","sceNetSendto"}, +{"hoOAofhhRvE#E#F","sceNetGetsockname"}, +{"304ooNZxWDY#E#F","sceNetRecvfrom"}, +{"xphrZusl78E#E#F","sceNetGetsockopt"}, +{"zO9UL3qIINQ#H#I","sceRtcGetCurrentNetworkTick"}, +{"i8UmXTSq7N4#Q#R","sceNpCmpNpId"}, +{"XDncXQIJUSk#R#S","sceNpGetOnlineId"}, +{"dj+O5aD2a0Q#Q#R","sceNpCmpOnlineId"}, +{"CQtPRSF6Ds8#W#X","sceNpWebApiReadData"}, +{"G3AnLNdRBjE#W#X","sceNpWebApiInitialize"}, +{"x1Y7yiYSk7c#W#X","sceNpWebApiCreateContext"}, +{"y5Ta5JCzQHY#W#X","sceNpWebApiCreatePushEventFilter"}, +{"PfSTDCgNMgc#W#X","sceNpWebApiRegisterPushEventCallback"}, +{"JzhYTP2fG18#W#X","sceNpWebApiAbortRequest"}, +{"qK4o2656W4w#W#X","sceNpWebApiUnregisterPushEventCallback"}, +{"zE+R6Rcx3W0#W#X","sceNpWebApiDeletePushEventFilter"}, +{"XUjdsSTTZ3U#W#X","sceNpWebApiDeleteContext"}, +{"asz3TtIqGF8#W#X","sceNpWebApiTerminate"}, +{"noQgleu+KLE#W#X","sceNpWebApiDeleteRequest"}, +{"eLdDw6l0-bU#q#q","snprintf"}, +{"rdgs5Z1MyFw#W#X","sceNpWebApiCreateRequest"}, +{"kVbL4hL3K7w#W#X","sceNpWebApiSendRequest"}, +{"k210oKgP80Y#W#X","sceNpWebApiGetHttpStatusCode"}, +{"or0e885BlXo#W#X","sceNpWebApiUtilityParseNpId"}, +{"0nV21JjYCH8#q#q","wcsncpy"}, +{"743ZzEBzlV8#W#X","sceNpWebApiGetHttpResponseHeaderValueLength"}, +{"VwJ5L0Higg0#W#X","sceNpWebApiGetHttpResponseHeaderValue"}, +{"bDEVVP4bTjQ#H#I","sceRtcSetTime_t"}, +{"8w-H19ip48I#H#I","sceRtcGetTick"}, +{"jMNwqYr4R-k#H#I","sceRtcGetTickResolution"}, +{"UJ+Z7Q+4ck0#J#K","sceNetCtlRegisterCallback"}, +{"VfRSmPmj8Q8#R#S","sceNpRegisterStateCallback"}, +{"uFJpaKNBAj4#R#S","sceNpRegisterGamePresenceCallback"}, +{"eQH7nWPcAgc#R#S","sceNpGetState"}, +{"haVZE9FgKqE#h#i","sceNpProfileDialogUpdateStatus"}, +{"8rhLl1-0W-o#h#i","sceNpProfileDialogGetResult"}, +{"Lg+NCE6pTwQ#h#i","sceNpProfileDialogInitialize"}, +{"uj9Cz7Tk0cc#h#i","sceNpProfileDialogOpen"}, +{"0Sp9vJcB1-w#h#i","sceNpProfileDialogTerminate"}, +{"3Zl8BePTh9Y#R#S","sceNpCheckCallback"}, +{"iQw3iQPhvUQ#J#K","sceNetCtlCheckCallback"}, +{"IPb1hd1wAGc#R#S","sceNpGetGamePresenceStatus"}, +{"mjjTXh+NHWY#R#S","sceNpUnregisterStateCallback"}, +{"Rqm2OnZMCz0#J#K","sceNetCtlUnregisterCallback"}, +{"Ec63y59l9tw#R#S","sceNpSetNpTitleId"}, +{"j3YMu1MVNNo#D#E","sceUserServiceInitialize"}, +{"10t3e5+JPnU#P#Q","sceNpMatching2Initialize"}, +{"bwFjS+bX9mA#D#E","sceUserServiceTerminate"}, +{"Mqp3lJ+sjy4#P#Q","sceNpMatching2Terminate"}, +{"p-o74CnoNzY#R#S","sceNpGetNpId"}, +{"fQQfP87I7hs#P#Q","sceNpMatching2RegisterContextCallback"}, +{"YfmpW719rMo#P#Q","sceNpMatching2CreateContext"}, +{"7vjNQ6Z1op0#P#Q","sceNpMatching2ContextStart"}, +{"LhCPctIICxQ#P#Q","sceNpMatching2GetServerId"}, +{"+8e7wXLmjds#P#Q","sceNpMatching2SetDefaultRequestOptParam"}, +{"p+2EnxmaAMM#P#Q","sceNpMatching2RegisterRoomEventCallback"}, +{"0UMeWRGnZKA#P#Q","sceNpMatching2RegisterSignalingCallback"}, +{"4Nj7u5B5yCA#P#Q","sceNpMatching2RegisterLobbyEventCallback"}, +{"3KOuC4RmZZU#T#U","sceNpSignalingInitialize"}, +{"5yYjEdd4t8Y#T#U","sceNpSignalingCreateContext"}, +{"8533Q+LU7EQ#S#T","sceNpLookupCreateTitleCtx"}, +{"hx+LIg-1koI#T#U","sceNpSignalingDeleteContext"}, +{"NPhw0UXaNrk#T#U","sceNpSignalingTerminate"}, +{"mtqDK9zkoIE#S#T","sceNpLookupDeleteTitleCtx"}, +{"6UEembipgrM#T#U","sceNpSignalingDeactivateConnection"}, +{"n5JmImxTiZU#P#Q","sceNpMatching2JoinLobby"}, +{"BBbJ92uUdCg#P#Q","sceNpMatching2LeaveLobby"}, +{"-f6M4caNe8k#P#Q","sceNpMatching2ContextStop"}, +{"Nz-ZE7ur32I#P#Q","sceNpMatching2DestroyContext"}, +{"VqZX7POg2Mk#P#Q","sceNpMatching2SearchRoom"}, +{"wyvlEgZ-55w#P#Q","sceNpMatching2GetLobbyInfoList"}, +{"rJNPJqDCpiI#P#Q","sceNpMatching2GetWorldInfoList"}, +{"wUmwXZHaX1w#P#Q","sceNpMatching2SignalingGetPingInfo"}, +{"zCWZmXXN600#P#Q","sceNpMatching2CreateJoinRoom"}, +{"CSIMDsVjs-g#P#Q","sceNpMatching2JoinRoom"}, +{"BD6kfx442Do#P#Q","sceNpMatching2LeaveRoom"}, +{"AUVfU6byg3c#P#Q","sceNpMatching2KickoutRoomMember"}, +{"NCP3bLGPt+o#P#Q","sceNpMatching2GrantRoomOwner"}, +{"S9D8JSYIrjE#P#Q","sceNpMatching2SetRoomDataInternal"}, +{"q7GK98-nYSE#P#Q","sceNpMatching2SetRoomDataExternal"}, +{"HoqTrkS9c5Q#P#Q","sceNpMatching2SetRoomMemberDataInternal"}, +{"tHD5FPFXtu4#P#Q","sceNpMatching2SignalingGetConnectionStatus"}, +{"b7kJI+nx2hg#i#j","sceVoiceDeletePort"}, +{"Oo0S5PH7FIQ#i#j","sceVoiceEnd"}, +{"9TrhuGzberQ#i#j","sceVoiceInit"}, +{"nXpje5yNpaE#i#j","sceVoiceCreatePort"}, +{"oV9GAdJ23Gw#i#j","sceVoiceConnectIPortToOPort"}, +{"54phPH2LZls#i#j","sceVoiceStart"}, +{"Ao2YNSA7-Qo#i#j","sceVoiceStop"}, +{"ajVj3QG2um4#i#j","sceVoiceDisconnectIPortFromOPort"}, +{"CrLqDwWLoXM#i#j","sceVoiceGetPortInfo"}, +{"cQ6DGsQEjV4#i#j","sceVoiceReadFromOPort"}, +{"YeJl6yDlhW0#i#j","sceVoiceWriteToIPort"}, +{"KnNA1TEgtBI#o#p","sceNpScoreCreateNpTitleCtx"}, +{"G0pE+RNCwfk#o#p","sceNpScoreDeleteNpTitleCtx"}, +{"gW8qyjYrUbk#o#p","sceNpScoreCreateRequest"}, +{"ETS-uM-vH9Q#o#p","sceNpScoreGetRankingByNpIdPcId"}, +{"dK8-SgYf6r4#o#p","sceNpScoreDeleteRequest"}, +{"KBHxDjyk-jA#o#p","sceNpScoreGetRankingByRange"}, +{"bygbKdHmjn4#o#p","sceNpScoreSetPlayerCharacterId"}, +{"zKoVok6FFEI#o#p","sceNpScoreGetGameData"}, +{"zT0XBtgtOSI#o#p","sceNpScoreRecordScore"}, +{"LoVMVrijVOk#o#p","sceNpScoreGetBoardInfo"}, +{"1i7kmKbX6hk#o#p","sceNpScoreAbortRequest"}, +{"bcoVwcBjQ9E#o#p","sceNpScoreRecordGameData"}, +{"2b3TI0mDYiI#o#p","sceNpScoreCensorComment"}, +{"r4oAo9in0TA#o#p","sceNpScoreSanitizeComment"}, +{"eYz4v5Uek9U#S#T","sceNpLookupAbortRequest"}, +{"wLaxchvEEnk#S#T","sceNpLookupDeleteRequest"}, +{"0UvTFeomAUM#T#U","sceNpSignalingActivateConnection"}, +{"JA4+sS39GMs#S#T","sceNpLookupCreateAsyncRequest"}, +{"V4EVrruHuy8#S#T","sceNpLookupPollAsync"}, +{"T6tnM1Uti4g#S#T","sceNpLookupNpId"}, +{"bD-JizUb3JM#T#U","sceNpSignalingGetConnectionStatus"}, +{"WDpobjImAb4#q#q","wcsstr"}, +{"x9uumWcxhXU#q#q","wcsspn"}, +{"gfP0im5Z3g0#q#q","ldiv"}, +{"dl+4eHSzUu4#N#O","sceAjmInitialize"}, +{"Q3dyFuwGn64#N#O","sceAjmModuleRegister"}, +{"-qLsfDAywIY#N#O","sceAjmBatchWait"}, +{"Wi7DtlLV+KI#N#O","sceAjmModuleUnregister"}, +{"MHur6qCsUus#N#O","sceAjmFinalize"}, +{"AxoDrINp4J8#N#O","sceAjmInstanceCreate"}, +{"NVDXiUesSbA#N#O","sceAjmBatchCancel"}, +{"RbLbuKv8zho#N#O","sceAjmInstanceDestroy"}, +{"dmDybN--Fn8#N#O","sceAjmBatchJobControlBufferRa"}, +{"ElslOCpOIns#N#O","sceAjmBatchJobRunBufferRa"}, +{"fFFkk0xfGWs#N#O","sceAjmBatchStartBuffer"}, +{"WfAiBW8Wcek#N#O","sceAjmBatchErrorDump"}, +{"Y7aJ1uydPMo#q#q","realloc"}, +{"kBwCPsYX-m4#p#J","sceKernelFstat"}, +{"QBi7HCK03hw#p#J","sceKernelClockGettime"}, +{"1jfXLRVzisc#p#J","sceKernelUsleep"}, +{"aI+OeCz8xrQ#p#J","scePthreadSelf"}, +{"DzES9hQF4f4#p#J","scePthreadAttrSetschedparam"}, +{"3qxgM4ezETA#p#J","scePthreadAttrSetaffinity"}, +{"F8bUHwAG284#p#J","scePthreadMutexattrInit"}, +{"iMp8QpE+XO4#p#J","scePthreadMutexattrSettype"}, +{"cmo1RIYva9o#p#J","scePthreadMutexInit"}, +{"smWEktiyyG0#p#J","scePthreadMutexattrDestroy"}, +{"2Of0f+3mhhE#p#J","scePthreadMutexDestroy"}, +{"9UK1vLZQft4#p#J","scePthreadMutexLock"}, +{"tn3VlD0hG60#p#J","scePthreadMutexUnlock"}, +{"fPhymKNvK-A#D#E","sceUserServiceGetLoginUserIdList"}, +{"JfEPXVxhFqA#G#H","sceAudioOutInit"}, +{"ekNvsT22rsY#G#H","sceAudioOutOpen"}, +{"b+uAV89IlxE#G#H","sceAudioOutSetVolume"}, +{"QOQtbeDqsT4#G#H","sceAudioOutOutput"}, +{"s1--uE9mBFw#G#H","sceAudioOutClose"}, +{"GrQ9s4IrNaQ#G#H","sceAudioOutGetPortState"}, +{"1xxcMiGu2fo#D#E","sceUserServiceGetUserName"}, +{"LozEOU8+anM#Y#Z","sceAudioInInput"}, +{"5NE8Sjc7VC8#Y#Z","sceAudioInOpen"}, +{"Jh6WbHhnI68#Y#Z","sceAudioInClose"}, +{"1Pk0qZQGeWo#q#q","sscanf"}, +{"8u8lPzUEq+U#q#q","memchr"}, +{"ZkZhskCPXFw#O#P","sceSaveDataInitialize"}, +{"yKDy8S5yLA0#O#P","sceSaveDataTerminate"}, +{"dyIhnXq-0SM#O#P","sceSaveDataDirNameSearch"}, +{"S1GkePI17zQ#O#P","sceSaveDataDelete"}, +{"32HQAQdwM2o#O#P","sceSaveDataMount"}, +{"BMR4F-Uek3E#O#P","sceSaveDataUmount"}, +{"7Bt5pBC-Aco#O#P","sceSaveDataGetSaveDataMemory"}, +{"h3YURzXGSVQ#O#P","sceSaveDataSetSaveDataMemory"}, +{"s9e3+YpRnzw#d#e","sceSaveDataDialogInitialize"}, +{"85zul--eGXs#O#P","sceSaveDataSetParam"}, +{"c88Yy54Mx0w#O#P","sceSaveDataSaveIcon"}, +{"4tPhsP6FpDI#d#e","sceSaveDataDialogOpen"}, +{"KK3Bdg1RWK0#d#e","sceSaveDataDialogUpdateStatus"}, +{"YuH2FA7azqQ#d#e","sceSaveDataDialogTerminate"}, +{"v7AAAMo0Lz4#O#P","sceSaveDataSetupSaveDataMemory"}, +{"aS66RI0gGgo#m#n","sceAvPlayerInit"}, +{"HD1YKVU26-M#m#n","sceAvPlayerPostInit"}, +{"KMcEa+rHsIo#m#n","sceAvPlayerAddSource"}, +{"OVths0xGfho#m#n","sceAvPlayerSetLooping"}, +{"NkJwDzKmIlw#m#n","sceAvPlayerClose"}, +{"ET4Gr-Uu07s#m#n","sceAvPlayerStart"}, +{"ZC17w3vB5Lo#m#n","sceAvPlayerStop"}, +{"UbQoYawOsfY#m#n","sceAvPlayerIsActive"}, +{"9y5v+fGN4Wk#m#n","sceAvPlayerPause"}, +{"w5moABNwnRY#m#n","sceAvPlayerResume"}, +{"JdksQu8pNdQ#m#n","sceAvPlayerGetVideoDataEx"}, +{"wwM99gjFf1Y#m#n","sceAvPlayerCurrentTime"}, +{"hdTyRzCXQeQ#m#n","sceAvPlayerStreamCount"}, +{"d8FcbzfAdQw#m#n","sceAvPlayerGetStreamInfo"}, +{"ODJK2sn9w4A#m#n","sceAvPlayerEnableStream"}, +{"Wnp1OVcrZgk#m#n","sceAvPlayerGetAudioData"}, +{"2SKEx6bSq-4#p#J","sceKernelBatchMap"}, +{"cQke9UuBQOk#p#J","sceKernelMunmap"}, +{"7oxv3PPCumo#p#J","sceKernelReserveVirtualRange"}, +{"vSMAm3cxYTY#p#J","sceKernelMprotect"}, +{"fMP5NHUOaMk#M#N","sceSysmoduleIsLoaded"}, +{"IADmD4tScBY#b#c","sceImeDialogGetStatus"}, +{"x01jxu+vxlc#b#c","sceImeDialogGetResult"}, +{"gyTyVn+bXMw#b#c","sceImeDialogTerm"}, +{"NUeBrN7hzf0#b#c","sceImeDialogInit"}, +{"oBmw4xrmfKs#b#c","sceImeDialogAbort"}, +{"GUuiOcxL-r0#q#q","_WStof"}, +{"4nRn+exUJAM#q#q","_WStod"}, +{"34nH7v2xvNQ#q#q","wcstoll"}, +{"d3dMyWORw8A#q#q","wcstol"}, +{"Im55VJ-Bekc#q#q","swprintf_s"}, +{"qISjDHrxONc#K#L","sceHttpWaitRequest"}, +{"0gYjPTR-6cY#K#L","sceHttpCreateTemplate"}, +{"s2-NPIvz+iA#K#L","sceHttpSetNonblock"}, +{"6381dWF+xsQ#K#L","sceHttpCreateEpoll"}, +{"sWQiqKvYTVA#K#L","sceHttpAbortWaitRequest"}, +{"wYhXVfS2Et4#K#L","sceHttpDestroyEpoll"}, +{"4I8vEpuEhZ8#K#L","sceHttpDeleteTemplate"}, +{"f42K37mm5RM#K#L","sceHttpsEnableOption"}, +{"mSQCxzWTwVI#K#L","sceHttpsDisableOption"}, +{"EY28T2bkN7k#K#L","sceHttpAddRequestHeader"}, +{"dgJBaeJnGpo#E#F","sceNetPoolCreate"}, +{"hdpVEUDFW3s#L#M","sceSslInit"}, +{"A9cVMUtEp4Y#K#L","sceHttpInit"}, +{"Ik-KpLTlf7Q#K#L","sceHttpTerm"}, +{"0K1yQ6Lv-Yc#L#M","sceSslTerm"}, +{"K7RlrTkI-mw#E#F","sceNetPoolDestroy"}, +{"qgxDBjorUxs#K#L","sceHttpCreateConnectionWithURL"}, +{"Aeu5wVKkF9w#K#L","sceHttpCreateRequestWithURL"}, +{"PTiFIUxCpJc#K#L","sceHttpSetRequestContentLength"}, +{"0S9tTH0uqTU#K#L","sceHttpSetConnectTimeOut"}, +{"-xm7kZQNpHI#K#L","sceHttpSetEpoll"}, +{"59tL1AQBb8U#K#L","sceHttpUnsetEpoll"}, +{"qe7oZ+v4PWA#K#L","sceHttpDeleteRequest"}, +{"P6A3ytpsiYc#K#L","sceHttpDeleteConnection"}, +{"0a2TBNfE3BU#K#L","sceHttpGetStatusCode"}, +{"yuO2H2Uvnos#K#L","sceHttpGetResponseContentLength"}, +{"P5pdoykPYTk#K#L","sceHttpReadData"}, +{"1e2BNwI-XzE#K#L","sceHttpSendRequest"}, +{"nJz16JE1txM#q#q","swprintf"}, +{"OGVdXU3E-xg#q#q","wprintf"}, +{"0H2vBYbTLHI#B#C","sceGnmDrawInitDefaultHardwareState200"}, +{"bQVd5YzCal0#B#C","sceGnmSetPsShader"}, +{"4MgRw-bVNQU#B#C","sceGnmUpdatePsShader"}, +{"gAhCn6UiU4Y#B#C","sceGnmSetVsShader"}, +{"V31V01UiScY#B#C","sceGnmUpdateVsShader"}, +{"FUHG8sQ3R58#B#C","sceGnmSetEsShader"}, +{"VJNjFtqiF5w#B#C","sceGnmSetHsShader"}, +{"GNlx+y7xPdE#B#C","sceGnmUpdateHsShader"}, +{"vckdzbQ46SI#B#C","sceGnmSetLsShader"}, +{"KXltnCwEJHQ#B#C","sceGnmSetCsShader"}, +{"UJwNuMBcUAk#B#C","sceGnmSetGsShader"}, +{"nLM2i2+65hA#B#C","sceGnmUpdateGsShader"}, +{"jiItzS6+22g#B#C","sceGnmInsertSetMarker"}, +{"aj3L-iaFmyk#B#C","sceGnmInsertSetColorMarker"}, +{"W1Etj-jlW7Y#B#C","sceGnmInsertPushMarker"}, +{"aPIZJTXC+cU#B#C","sceGnmInsertPushColorMarker"}, +{"7qZVNgEu+SY#B#C","sceGnmInsertPopMarker"}, +{"1qXLHIpROPE#B#C","sceGnmInsertWaitFlipDone"}, +{"26PM5Mzl8zc#B#C","sceGnmLogicalCuIndexToPhysicalCuIndex"}, +{"RU74kek-N0c#B#C","sceGnmLogicalCuMaskToPhysicalCuMask"}, +{"zwY0YV91TTI#B#C","sceGnmSubmitCommandBuffers"}, +{"xbxNatawohc#B#C","sceGnmSubmitAndFlipCommandBuffers"}, +{"iCO804ZgzdA#B#C","sceGnmValidateCommandBuffers"}, +{"b0xyllnVY-I#B#C","sceGnmAddEqEvent"}, +{"PVT+fuoS9gU#B#C","sceGnmDeleteEqEvent"}, +{"UoYY0DWMC0U#B#C","sceGnmGetEqEventType"}, +{"H7-fgvEutM0#B#C","sceGnmGetEqTimeStamp"}, +{"29oKvKXzEZo#B#C","sceGnmMapComputeQueue"}, +{"A+uGq+3KFtQ#B#C","sceGnmMapComputeQueueWithPriority"}, +{"ArSg-TGinhk#B#C","sceGnmUnmapComputeQueue"}, +{"bX5IbRvECXk#B#C","sceGnmDingDong"}, +{"iBt3Oe00Kvc#B#C","sceGnmFlushGarlic"}, +{"qpGITzPE+Zc#B#C","sceGnmDebugHardwareStatus"}, +{"yvZ73uQUqrk#B#C","sceGnmSubmitDone"}, +{"b08AgtPlHPg#B#C","sceGnmAreSubmitsAllowed"}, +{"gObODli-OH8#B#C","sceGnmRequestFlipAndSubmitDone"}, +{"+xuDhxlWRPg#B#C","sceGnmSetupMipStatsReport"}, +{"f85orjx7qts#B#C","sceGnmRequestMipStatsReportAndReset"}, +{"HHo1BAljZO8#B#C","sceGnmDisableMipStatsReport"}, +{"jtkqXpAOY6w#B#C","sceGnmSetGsRingSizes"}, +{"ln33zjBrfjk#B#C","sceGnmGetTheTessellationFactorRingBufferBaseAddress"}, +{"f33OrruQYbM#B#C","sceRazorIsLoaded"}, +{"u9YKpRRHe-M#B#C","sceRazorCaptureImmediate"}, +{"4UFagYlfuAM#B#C","sceRazorCaptureSinceLastFlip"}, +{"xeTLfxVIQO4#B#C","sceRazorCaptureCommandBuffersOnlyImmediate"}, +{"9thMn+uB1is#B#C","sceRazorCaptureCommandBuffersOnlySinceLastFlip"}, +{"d88anrgNoKY#B#C","sceGnmDriverTriggerCapture"}, +{"TLV4mswiZ4A#B#C","sceGnmDriverCaptureInProgress"}, +{"jg33rEKLfVs#B#C","sceGnmIsUserPaEnabled"}, +{"nF6bFRUBRAU#B#C","sceGnmDispatchInitDefaultHardwareState"}, +{"T72hz6ffq08#p#J","scePthreadYield"}, +{"cfAXurvfl5o#q#q","__cxa_allocate_exception"}, +{"vkuuLfhnSZI#q#q","__cxa_throw"}, +{"usKbuvy2hQg#q#q","__cxa_call_unexpected"}, +{"f1zwJ3jAI2k#q#q","_Unwind_Resume"}, +{"3cUUypQzMiI#q#q","__cxa_begin_catch"}, +{"lX+4FNUklF0#q#q","__cxa_end_catch"}, +{"qYhnoevd9bI#q#q","_ZSt9terminatev"}, +{"ZL9FV4mJXxo#q#q","__cxa_rethrow"}, +{"zJGf8xjFnQE#E#F","sceNetSocketAbort"}, +{"9T2pDF2Ryqg#E#F","sceNetHtonl"}, +{"pQGpHYopAIY#E#F","sceNetNtohl"}, +{"U46NwOiJpys#C#D","sceVideoOutSubmitFlip"}, +{"xEszJVGpybs#q#q","sprintf_s"}, +{"GMpvxPFW924#q#q","vprintf"}, +{"ryUxD-60bKM#q#q","_ZnwmRKSt9nothrow_t"}, +{"Apb4YDxKsRI#E#F","sceNetResolverStartAton"}, +{"9vA2aW+CHuA#E#F","sceNetInetNtop"}, +{"MELi-cKqWq0#q#q","_ZSt19_Xbad_function_callv"}, +{"kDZvoVssCgQ#q#q","strpbrk"}, +{"ZPD1YOKI+Kw#H#I","sceRtcGetCurrentClockLocalTime"}, +{"JO4yuTuMoKI#J#K","sceNetCtlGetNatInfo"}, +{"fZo48un7LK4#V#W","sceSystemServiceParamGetInt"}, +{"M1TvFst-jrM#H#I","sceRtcConvertUtcToLocalTime"}, +{"8Yr143yEnRo#H#I","sceRtcConvertLocalTimeToUtc"}, +{"rPo6tV8D9bM#V#W","sceSystemServiceGetStatus"}, +{"656LMQSrg6U#V#W","sceSystemServiceReceiveEvent"}, +{"H4MCONF+Gps#q#q","wcspbrk"}, +{"Gaxrp3EWY-M#R#S","sceNpNotifyPlusFeature"}, +{"Vo5V8KAwCmk#V#W","sceSystemServiceHideSplashScreen"}, +{"-+3hY+y8bNo#V#W","sceSystemServiceLaunchWebBrowser"}, +{"6fIC3XKt2k0#j#k","sceMsgDialogUpdateStatus"}, +{"ePw-kqZmelo#j#k","sceMsgDialogTerminate"}, +{"lDqxaY1UbEo#j#k","sceMsgDialogInitialize"}, +{"uoUpLGNkygk#Z#a","sceCommonDialogInitialize"}, +{"b06Hh0DPEaE#j#k","sceMsgDialogOpen"}, +{"LR5cwFMMCVE#k#l","sceNpCommerceDialogUpdateStatus"}, +{"m-I92Ab50W8#k#l","sceNpCommerceDialogTerminate"}, +{"0aR2aWmQal4#k#l","sceNpCommerceDialogInitialize"}, +{"DfSCDRA3EjY#k#l","sceNpCommerceDialogOpen"}, +{"eiqMCt9UshI#R#S","sceNpCreateAsyncRequest"}, +{"gjSyfzSsDcE#X#Y","sceNpAuthPollAsync"}, +{"OzKvTvg3ZYU#R#S","sceNpAbortRequest"}, +{"N+mr7GjTvr8#X#Y","sceNpAuthCreateAsyncRequest"}, +{"KxGkOrQJTqY#X#Y","sceNpAuthGetAuthorizationCode"}, +{"2rsFmlGWleQ#R#S","sceNpCheckNpAvailability"}, +{"ilwLM4zOmu4#R#S","sceNpGetParentalControlInfo"}, +{"r6MyYJkryz8#R#S","sceNpCheckPlus"}, +{"uqcPJLWL08M#R#S","sceNpPollAsync"}, +{"GImICnh+boA#R#S","sceNpRegisterPlusEventCallback"}, +{"xViqJdDgKl0#R#S","sceNpUnregisterPlusEventCallback"}, +{"S7QTn72PrDw#R#S","sceNpDeleteRequest"}, +{"H8wG9Bk-nPc#X#Y","sceNpAuthDeleteRequest"}, +{"HNnWdT43ues#q#q","swscanf"}, +{"xnd8BJzAxmk#c#d","sceAppContentGetAddcontInfoList"}, +{"A2CQ3kgSopQ#R#S","sceNpSetContentRestriction"}, +{"ts6GlZOKRrE#n#o","scePlayGoInitialize"}, +{"uWIYLFkkwqk#n#o","scePlayGoGetLocus"}, +{"M1Gma1ocrGE#n#o","scePlayGoOpen"}, +{"73fF1MFU8hA#n#o","scePlayGoGetChunkId"}, +{"4AAcTU9R3XM#n#o","scePlayGoSetInstallSpeed"}, +{"AxHBk3eat04#H#I","sceRtcFormatRFC2822LocalTime"}, +{"XbkjbobZlCY#l#m","sceNpTrophyCreateContext"}, +{"q7U6tEAQf7c#l#m","sceNpTrophyCreateHandle"}, +{"TJCAxto9SEU#l#m","sceNpTrophyRegisterContext"}, +{"28xmRUFao68#l#m","sceNpTrophyUnlockTrophy"}, +{"YYP3f2W09og#l#m","sceNpTrophyGetGameInfo"}, +{"qqUVGDgQBm0#l#m","sceNpTrophyGetTrophyInfo"}, +{"R9lA82OraNs#c#d","sceAppContentInitialize"}, +{"99b82IKXpH4#c#d","sceAppContentAppParamGetInt"}, +{"taRWhTJFTgE#p#J","sceKernelGetdirentries"}, +{"eV9wAD2riIA#p#J","sceKernelStat"}, +{"VW3TVZiM4-E#p#J","sceKernelFtruncate"}, +{"WlyEA-sLDf0#p#J","sceKernelTruncate"}, +{"naInUjYt3so#p#J","sceKernelRmdir"}, +{"AUXVxWeJU-A#p#J","sceKernelUnlink"}, +{"52NcYU9+lEo#p#J","sceKernelRename"}, +{"1-LFLmRFxxM#p#J","sceKernelMkdir"}, +{"+L98PIbGttk#p#J","scePthreadRwlockUnlock"}, +{"upoVrzMHFeE#p#J","scePthreadMutexTrylock"}, +{"BB+kb08Tl9A#p#J","scePthreadRwlockDestroy"}, +{"6ULAa0fq4jA#p#J","scePthreadRwlockInit"}, +{"adh--6nIqTk#p#J","scePthreadRwlockTimedwrlock"}, +{"mqdNorrB+gI#p#J","scePthreadRwlockWrlock"}, +{"bIHoZCTomsI#p#J","scePthreadRwlockTrywrlock"}, +{"iPtZRWICjrM#p#J","scePthreadRwlockTimedrdlock"}, +{"Ox9i0c7L5w0#p#J","scePthreadRwlockRdlock"}, +{"3kg7rT0NQIs#p#J","scePthreadExit"}, +{"IWIBBdTHit4#p#J","sceKernelMapFlexibleMemory"}, +{"teiItL2boFw#p#J","sceKernelReleaseFlexibleMemory"}, +{"BmMjYxmew1w#p#J","scePthreadCondTimedwait"}, +{"WKAXJ4XBPQ4#p#J","scePthreadCondWait"}, +{"IafI2PxcPnQ#p#J","scePthreadMutexTimedlock"}, +{"b-xTWRgI1qw#q#q","_Dtest"}, +{"ueega6v3GUw#H#I","sceRtcSetTick"}, +{"CyIK-i4XdgQ#H#I","sceRtcGetDayOfWeek"}, +{"8Q60JLJ6Rv4#q#q","getc"}, +{"yH17Q6NWtVg#D#E","sceUserServiceGetEvent"}, +{"-2IRUCO--PM#p#J","sceKernelReadTsc"}, +{"hv1luiJrqQM#A#B","scePadInit"}, +{"P330P3dFF68#q#q","Need_sceLibc"}, +{"f7uOxY9mM1U#p#J","__stack_chk_guard"}, +{"zr094EQ39Ww#q#q","__cxa_pure_virtual"}, +{"H8AprKeZtNg#q#q","_Stderr"}, +{"2sWzhYqFH4E#q#q","_Stdout"}, +{"1TDo-ImqkJc#q#q","_Stdin"}, +{"kxXCvcat1cM#q#q","_ZNSt8ios_base4InitD1Ev"}, +{"Uw3OTZFPNt4#q#q","_ZNSt6_WinitD1Ev"}, +{"p6LrHjIQMdk#q#q","_ZNSt8_LocinfoD1Ev"}, +{"yLE5H3058Ao#q#q","_ZTVNSt8ios_base7failureE"}, +{"-L+-8F0+gBc#q#q","_ZTVSt13runtime_error"}, +{"Bq8m04PN1zw#q#q","_ZTVSt12system_error"}, +{"FQ9NFbBHb5Y#q#q","_ZSt7_BADOFF"}, +{"byV+FWlAnB4#q#q","_ZTVN10__cxxabiv117__class_type_infoE"}, +{"9ByRMdo7ywg#q#q","_ZTVN10__cxxabiv121__vmi_class_type_infoE"}, +{"pZ9WXcClPO8#q#q","_ZTVN10__cxxabiv120__si_class_type_infoE"}, +{"St4apgcBNfo#q#q","_ZTIi"}, +{"XwLA5cTHjt4#q#q","__gxx_personality_v0"}, +{"NLwJ3q+64bY#q#q","_ZSt7nothrow"}, +{"2WVBaSdGIds#q#q","_ZSt3cin"}, +{"TVfbf1sXt0A#q#q","_ZSt4cerr"}, +{"CvJ3HUPlMIY#q#q","_ZSt5wcerr"}, +{"2bASh0rEeXI#q#q","_ZSt4wcin"}, +{"5PfqUBaQf4g#q#q","_ZSt4cout"}, +{"d-YRIvO0jXI#q#q","_ZSt5wcout"}, +{"OMDRKKAZ8I4#p#J","sceKernelDebugRaiseException"}, +{"zE-wXIZjLoM#p#J","sceKernelDebugRaiseExceptionOnReleaseMode"}, +{"kOcnerypnQA#p#J","sceKernelGettimezone"}, +{"2Tb92quprl0#p#J","scePthreadCondInit"}, +{"g+PZd2hiacg#p#J","scePthreadCondDestroy"}, +{"kDh-NfxgMtE#p#J","scePthreadCondSignal"}, +{"JGgj7Uvrl+A#p#J","scePthreadCondBroadcast"}, +{"yS8U2TGCe1A#p#J","nanosleep"}, +{"3PtV6p3QNX4#p#J","scePthreadEqual"}, +{"14bOACANTBo#p#J","scePthreadOnce"}, +{"geDaqgH9lTg#p#J","scePthreadKeyCreate"}, +{"PrdHuuDekhY#p#J","scePthreadKeyDelete"}, +{"+BzXYkqYeLE#p#J","scePthreadSetspecific"}, +{"eoht7mQOCmo#p#J","scePthreadGetspecific"}, +{"n88vx3C5nW8#p#J","gettimeofday"}, +{"VADc3MNQ3cM#p#J","signal"}, +{"959qrazPIrg#p#J","sceKernelGetProcParam"}, +{"p5EcQeEeJAE#p#J","_sceKernelRtldSetApplicationHeapAPI"}, +{"Wl2o5hOVZdw#p#J","sceKernelPrintBacktraceWithModuleInfo"}, +{"mL8NDH86iQI#p#J","sceKernelMapNamedFlexibleMemory"}, +{"3k6kx-zOOSQ#p#J","sceKernelMlock"}, +{"8IGjwtnvYwI#F#G","sceFiosIsValidHandle"}, +{"DRuBt2pvICk#p#J","_read"}, +{"FxVZqBAA7ks#p#J","_write"}, +{"w13Ojm7ON9o#F#G","sceFiosFHOpenWithModeSync"}, +{"G-39lsdSgXo#F#G","sceFiosRenameSync"}, +{"KsVTc04kN9k#F#G","sceFiosDeleteSync"}, +{"hHlZQUnlxSM#p#J","getrusage"}, +{"lLMT9vJAck0#p#J","clock_gettime"}, +{"f7KBOafysXo#p#J","sceKernelGetModuleInfoFromAddr"}, +{"Fjc4-n1+y2g#p#J","__elf_phdr_match_addr"}, +{"kbw4UHHSYy0#p#J","__pthread_cxa_finalize"}, +{"6xVpy0Fdq+I#p#J","_sigprocmask"}, +{"6XG4B33N09g#p#J","sched_yield"}, +{"DFmMT80xcNI#p#J","sysctl"}, +{"BPE9s9vQQXo#p#J","mmap"}, +{"UqDGjXA5yUM#p#J","munmap"}, +{"mqQMh1zPPT8#p#J","fstat"}, +{"VkTAsrZDcJ0#p#J","sigfillset"}, +{"aPcyptbOiZs#p#J","sigprocmask"}, +{"tZY4+SZNFhA#p#J","msync"}, +{"HoLVWNanBBc#p#J","getpid"}, +{"crb5j7mkk1c#p#J","_is_signal_return"}, +{"mo0bFmWppIw#p#J","sigreturn"}, +{"OjWstbIRPUo#p#J","__Ux86_64_setcontext"}, +{"k+AXqu2-eBc#p#J","getpagesize"}, +{"x1X76arYMxU#p#J","scePthreadAttrGet"}, +{"8+s5BzZjxSg#p#J","scePthreadAttrGetaffinity"}, +{"6Z83sYWFlA8#p#J","_exit"}, +{"djxxOmW6-aw#p#J","__progname"}, +/* Imports of linked system modules (libSceFios2.prx) that the eboot does not import itself. */ +{"ejekcaNQNq0#p#J","sceKernelGettimeofday"}, +{"+r3rMFwItV4#p#J","sceKernelPread"}, +{"nKWi-N2HBV4#p#J","sceKernelPwrite"}, +{"fTx66l5iWIA#p#J","sceKernelFsync"}, +{"1FGvU0i9saQ#p#J","scePthreadMutexattrSetprotocol"}, +{"rcrVFJsQWRY#p#J","scePthreadGetaffinity"}, +{"XD3mDeybCnk#p#J","scePthreadRwlockTryrdlock"}, +{"eXbUSpEaTsA#p#J","scePthreadAttrSetinheritsched"}, +{"ZT4ODD2Ts9o#libSceLibcInternal","Need_sceLibcInternal"}, +{"lbQKqsERhtE#libSceDiscMap","sceDiscMapIsRequestOnHDD"}, +{"ioKMruft1ek#libSceDiscMap","sceDiscMap_8A828CAEE7EDD5E9"}, diff --git a/link_libc.py b/link_libc.py new file mode 100644 index 0000000..d70aa8d --- /dev/null +++ b/link_libc.py @@ -0,0 +1,212 @@ +"""Link the user's plaintext libc into a separate, reproducible probe image. + +The original boot.bin remains usable. Symbols are matched by library/module +identity, versions and NID, not by dump-local suffix or NID alone. +""" +import collections +import hashlib +import json +from pathlib import Path +import struct +from prepare import parse_self, span, unpack + + +def encode_id(value): + alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-' + result = alphabet[value & 63] + value >>= 6 + while value: + result = alphabet[value & 63] + result + value >>= 6 + return result + + +def module(path): + source = path.read_bytes() + elf, header, ph, _, missing = parse_self(source) + dp = next(p for p in ph if p['type'] == 2) + dynamic = [] + for pos in range(dp['offset'], dp['offset']+dp['filesz'], 16): + tag, value = unpack('> 48) + identity = (string(value & 0xffffffff), (value >> 32) & 65535) + if key in table and table[key] != identity: + raise ValueError('conflicting module/library IDs') + table[key] = identity + def identity(name): + parts = name.split('#') + if len(parts) != 3: + raise ValueError(f'unsupported symbol encoding {name!r}') + n, lib, mod = parts + return (n, libraries[lib], modules[mod]) + symbols = [] + table = span(blob, tags[0x61000039], tags[0x6100003f]) + for pos in range(0, len(table), 24): + n, info, other, section, value, size = unpack('> 4, section=section, + value=value, size=size, identity=identity(name) if name else None)) + relocations = [] + for ot, st in ((0x61000029, 0x6100002d), (0x6100002f, 0x61000031)): + table = span(blob, tags[ot], tags[st]) + for pos in range(0, len(table), 24): + target, info, addend = unpack('> 32, addend)) + return dict(elf=elf, header=header, ph=ph, tags=tags, symbols=symbols, + relocs=relocations, identity=identity, libraries=libraries, modules=modules, + sha256=hashlib.sha256(source).hexdigest(), missing=missing) + + +def link(game, out): + main = module(game/'eboot.bin') + libc = module(game/'sce_module/libc.prx') + raw = (out/'boot.bin').read_bytes() + magic, size, entry, ns, nr, ni, flags = unpack('<8s6Q', raw, 0) + if magic != b'BBPROBE2': + raise ValueError('linker expects freshly prepared BBPROBE2') + pos = 56 + segments = [unpack('<3Q', raw, pos+i*24) for i in range(ns)] + pos += ns*24 + names = [span(raw, pos+i*128, 128).split(b'\0',1)[0].decode() for i in range(ni)] + pos += ni*128 + relocs = [unpack(' 512*1024*1024: + raise ValueError('linked image exceeds probe limit') + image.extend(bytes(base+libsize-len(image))) + def mapped(address, size=8): + return any(p['vaddr'] <= address and address+size <= p['vaddr']+p['memsz'] for p in loads) + for p in loads: + if p['filesz'] > p['memsz']: + raise ValueError('invalid libc segment size') + image[base+p['vaddr']:base+p['vaddr']+p['filesz']] = span(libc['elf'],p['offset'],p['filesz']) + segments.append((base+p['vaddr'],p['memsz'],p['flags'])) + # Preserve main-program spelling for the existing host resolver. New kernel + # NIDs get the main module's spelling only if identity AND version match. + identities = {main['identity'](name):i for i,name in enumerate(names)} + main_libraries = {identity:key for key,identity in main['libraries'].items()} + main_modules = {identity:key for key,identity in main['modules'].items()} + def imported(symbol): + key = symbol['identity'] + if key not in identities: + n,lib,mod = key + name = (f'{n}#{main_libraries[lib]}#{main_modules[mod]}' + if lib in main_libraries and mod in main_modules else f'libc:{symbol["name"]}') + identities[key] = len(names) + names.append(name) + return identities[key] + tls_count = 0 + for target, kind, symid, addend in libc['relocs']: + if not mapped(target): + raise ValueError(f'libc relocation outside image {target:#x}') + target += base + if kind == 8: + relocs.append((target,0,base+addend,0)) + elif kind == 16: + # libc is module 2 in this probe. Descriptor offset is already stored + # in the adjacent word; __tls_get_addr will use a separate TLS block. + symbol = libc['symbols'][symid] + if symbol['name'] or symbol['type'] != 3 or addend: + raise ValueError('unsupported external TLS relocation') + struct.pack_into('= 0: + image[at] = 0x65 + patched += 1 + at = image.find(fs_load, at + len(fs_load), end) + main_tls = next((p for p in main['ph'] if p['type']==7), None) + main_tls_values = (main_tls['vaddr'], main_tls['filesz'], main_tls['memsz'], main_tls['align']) if main_tls else (0,0,0,0) + if main_tls and (main_tls['filesz'] > main_tls['memsz'] or main_tls['memsz'] > 1024*1024 + or main_tls['vaddr'] + main_tls['filesz'] > size): + raise ValueError('unsupported eboot TLS layout') + tls = next(p for p in libc['ph'] if p['type']==7) + if tls['filesz'] > tls['memsz'] or not mapped(tls['vaddr'],tls['memsz']): + raise ValueError('unsupported TLS layout') + procparam = next(p for p in main['ph'] if p['type']==0x61000001) + metadata = (base,libsize,base+libc['tags'][12],base+tls['vaddr'],tls['memsz'],tls['filesz'],len(bindings),procparam['vaddr']) + with (out/'boot-libc.bin').open('wb') as f: + f.write(struct.pack('<8s6Q',b'BBPROBE4',len(image),entry,len(segments),len(relocs),len(names),flags)) + f.write(struct.pack('<8Q',*metadata)) + f.write(struct.pack('<4Q',*main_tls_values)) + for binding in bindings: f.write(struct.pack('<3Q',*binding)) + for segment in segments: f.write(struct.pack('<3Q',*segment)) + for name in names: + if len(name.encode())>=128: raise ValueError('name too long') + f.write(name.encode().ljust(128,b'\0')) + for relocation in relocs: f.write(struct.pack('gs patched={patched}') + + +if __name__=='__main__': + import argparse + p=argparse.ArgumentParser(description=__doc__) + p.add_argument('game',type=Path);p.add_argument('--out',type=Path,default=Path(__file__).parent/'out') + a=p.parse_args() + link(a.game,a.out) diff --git a/link_modules.py b/link_modules.py new file mode 100644 index 0000000..3ef0600 --- /dev/null +++ b/link_modules.py @@ -0,0 +1,253 @@ +"""Link the eboot with the game's bundled system modules into one probe image. + +Successor of link_libc.py for several modules (default: libc.prx, then +libSceFios2.prx). Every module is placed after the previous one; imports of +all modules share one import table, so the C runtime can override any +function (host contracts first) and otherwise binds the native export. + +Exports are matched by (NID, library identity, module identity). Imports of +libSceLibcInternal are served by libc.prx's same-NID exports: the internal +library is not shipped with the game and exposes the same functions. +Output: out/boot-linked.bin (format BBPROBE5) and out/link.json. +""" +import collections +import hashlib +import json +from pathlib import Path +import struct +from prepare import parse_self, span, unpack +from link_libc import encode_id + +DEFAULT_MODULES = ('libc.prx', 'libSceFios2.prx') +FS_LOAD = bytes.fromhex('64488b042500000000') # mov rax, fs:[0] + + +def module(path): + source = path.read_bytes() + elf, header, ph, _, missing = parse_self(source) + dp = next(p for p in ph if p['type'] == 2) + dynamic = [] + for pos in range(dp['offset'], dp['offset'] + dp['filesz'], 16): + tag, value = unpack('> 48) + identity = (string(value & 0xffffffff), (value >> 32) & 65535) + if key in table and table[key] != identity: + raise ValueError('conflicting module/library IDs') + table[key] = identity + + def identity(name): + parts = name.split('#') + if len(parts) != 3: + return None # plain names such as module_start are not linkable + n, lib, mod = parts + return (n, libraries[lib], modules[mod]) + symbols = [] + table = span(blob, tags[0x61000039], tags[0x6100003f]) + for pos in range(0, len(table), 24): + n, info, other, section, value, size = unpack('> 4, section=section, + value=value, size=size, identity=identity(name) if name else None)) + relocations = [] + for ot, st in ((0x61000029, 0x6100002d), (0x6100002f, 0x61000031)): + table = span(blob, tags[ot], tags[st]) + for pos in range(0, len(table), 24): + target, info, addend = unpack('> 32, addend)) + return dict(elf=elf, header=header, ph=ph, tags=tags, symbols=symbols, relocs=relocations, + identity=identity, libraries=libraries, modules=modules, + sha256=hashlib.sha256(source).hexdigest(), missing=missing) + + +def patch_fs_loads(image, ph, base): + """Rewrite initial-exec `mov rax, fs:[0]` to GS: glibc owns FS on Linux.""" + patched = 0 + for p in ph: + if p['type'] != 1 or not p['flags'] & 1: + continue + start, end = base + p['vaddr'], base + p['vaddr'] + p['filesz'] + at = image.find(FS_LOAD, start, end) + while at >= 0: + image[at] = 0x65 + patched += 1 + at = image.find(FS_LOAD, at + len(FS_LOAD), end) + return patched + + +def link(game, out, module_names=DEFAULT_MODULES): + main = module(game / 'eboot.bin') + raw = (out / 'boot.bin').read_bytes() + magic, size, entry, ns, nr, ni, flags = unpack('<8s6Q', raw, 0) + if magic != b'BBPROBE2': + raise ValueError('linker expects freshly prepared BBPROBE2') + pos = 56 + segments = [unpack('<3Q', raw, pos + i * 24) for i in range(ns)] + pos += ns * 24 + names = [span(raw, pos + i * 128, 128).split(b'\0', 1)[0].decode() for i in range(ni)] + pos += ni * 128 + relocs = [unpack(' 512 * 1024 * 1024: + raise ValueError('linked image exceeds probe limit') + image.extend(bytes(base + modsize - len(image))) + + def mapped(address, length=8, loads=loads): + return any(p['vaddr'] <= address and address + length <= p['vaddr'] + p['memsz'] for p in loads) + for p in loads: + if p['filesz'] > p['memsz']: + raise ValueError(f'{filename}: invalid segment size') + image[base + p['vaddr']:base + p['vaddr'] + p['filesz']] = span(m['elf'], p['offset'], p['filesz']) + segments.append((base + p['vaddr'], p['memsz'], p['flags'])) + tls = next((p for p in m['ph'] if p['type'] == 7), None) + module_id = 0 + if tls: + if tls['filesz'] > tls['memsz'] or not mapped(tls['vaddr'], tls['memsz']): + raise ValueError(f'{filename}: unsupported TLS layout') + module_id = tls_module + tls_module += 1 + tls_relocations = 0 + for target, kind, symid, addend in m['relocs']: + if not mapped(target): + raise ValueError(f'{filename}: relocation outside image {target:#x}') + target += base + if kind == 8: + relocs.append((target, 0, base + addend, 0)) + elif kind == 16: + symbol = m['symbols'][symid] + if symbol['name'] or symbol['type'] != 3 or addend or not module_id: + raise ValueError(f'{filename}: unsupported external TLS relocation') + struct.pack_into(' main_tls['memsz'] or main_tls['memsz'] > 1024 * 1024 + or main_tls['vaddr'] + main_tls['filesz'] > size): + raise ValueError('unsupported eboot TLS layout') + procparam = next(p for p in main['ph'] if p['type'] == 0x61000001) + with (out / 'boot-linked.bin').open('wb') as f: + f.write(struct.pack('<8s6Q', b'BBPROBE5', len(image), entry, len(segments), len(relocs), len(names), flags)) + f.write(struct.pack('= 128: + raise ValueError('name too long') + f.write(name.encode().ljust(128, b'\0')) + for relocation in relocs: + f.write(struct.pack('gs patched={fs_patched}') + + +if __name__ == '__main__': + import argparse + p = argparse.ArgumentParser(description=__doc__) + p.add_argument('game', type=Path) + p.add_argument('--out', type=Path, default=Path(__file__).parent / 'out') + p.add_argument('--modules', nargs='*', default=list(DEFAULT_MODULES)) + a = p.parse_args() + link(a.game, a.out, a.modules) diff --git a/patches.py b/patches.py new file mode 100644 index 0000000..53195b3 --- /dev/null +++ b/patches.py @@ -0,0 +1,75 @@ +"""Compile selected shadPS4/GoldHEN XML patches into out/patches.bin for the loader. + +Patch addresses are PS4 virtual addresses (eboot base 0x400000); the loader's +image places eboot vaddr 0 at image offset 0. Only literal writes are supported +(bytes, bytes16/32/64, float32/64, utf8, utf16); pattern ("mask") patches are rejected. +""" +import argparse +import struct +import xml.etree.ElementTree as ET +from pathlib import Path + +EBOOT_BASE=0x400000 +# BB_FPS presets: patch names from patches/Bloodborne.xml (app version 01.09). +FPS_PRESETS={'30':[],'60':['60 FPS++'],'90':['90 FPS++'],'uncap':['Uncap FPS++']} + + +def eboot_segments(elf): + phoff,=struct.unpack_from(' + + + CUSA00207 + CUSA00208 + CUSA00299 + CUSA00900 + CUSA01363 + CUSA03014 + CUSA03023 + CUSA03173 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/prepare.py b/prepare.py new file mode 100644 index 0000000..adc7cfc --- /dev/null +++ b/prepare.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python3 +"""Inspect an already plaintext PS4 SELF; prepare a native entry-point probe. + +No decryption, patches to source files, third-party modules or Python dependencies. +Format references are linked in README.md. All offsets are checked before use. +""" +import argparse +import base64 +import collections +import hashlib +import json +from pathlib import Path +import struct + + +def span(data, offset, size): + if offset < 0 or size < 0 or offset + size > len(data): + raise ValueError(f"out of bounds: {offset:#x}+{size:#x} / {len(data):#x}") + return data[offset:offset + size] + + +def unpack(fmt, data, offset): + return struct.unpack(fmt, span(data, offset, struct.calcsize(fmt))) + + +def parse_self(data): + if span(data, 0, 4) != b'O\x15=\x1d': + raise ValueError("expected PS4 SELF") + count, = unpack(' 512 * 1024 * 1024: + raise ValueError("probe image exceeds 512 MiB limit") + elf = bytearray(end) + header_end = header[5] + header[10] * 56 + elf[:header_end] = span(data, base, header_end) + covered = [(0, header_end)] + segments = [] + for i in range(count): + flags, off, size, mem = unpack('> 20) & 4095 + if index >= len(ph): + raise ValueError("invalid segment index") + p = ph[index] + if size != p['filesz'] or size != mem: + raise ValueError("unsupported blocked segment layout") + elf[p['offset']:p['offset'] + size] = span(data, off, size) + covered.append((p['offset'], p['offset'] + size)) + missing = [] + for i, p in enumerate(ph): + if p['filesz'] and not any(a <= p['offset'] and p['offset'] + p['filesz'] <= z + for a, z in covered): + missing.append(i) + if p['type'] in (1, 2, 0x61000000, 0x61000010): + raise ValueError(f"required segment {i} is unavailable") + return elf, header, ph, segments, missing + + +def sfo(data): + magic, version, keys, values, count = unpack('<4sIIII', data, 0) + if magic != b'\0PSF': + raise ValueError('bad SFO signature') + result = {} + for i in range(count): + key, fmt, size, capacity, off = unpack(' 512 * 1024 * 1024 or not mapped(header[4], 1): + raise ValueError('invalid memory image') + image = bytearray(size) + for p in loads: + if p['filesz'] > p['memsz']: + raise ValueError('segment file size exceeds memory size') + image[p['vaddr']:p['vaddr'] + p['filesz']] = span(elf, p['offset'], p['filesz']) + dp = next(p for p in ph if p['type'] == 2) + dyn = [] + for pos in range(dp['offset'], dp['offset'] + dp['filesz'], 16): + tag, value = unpack('> 32 + counts[kind] += 1 + if not mapped(target): + raise ValueError(f'relocation outside mapped segments: {target:#x}') + if kind == 8: + relocs.append((target, 0, addend, 0)) # base-relative + elif kind in (1, 6, 7): + symbol = symbols[sym] + if symbol['section']: + if symbol['section'] == 0xfff1: + struct.pack_into('= 128: + raise ValueError('import name too long') + f.write(encoded.ljust(128, b'\0')) + for relocation in relocs: + f.write(struct.pack(' +#include +#include +#include +#include +#include "runtime.h" +#include "gpu/bbgpu.h" +#if !defined(__x86_64__) || !defined(__GNUC__) +#error This prototype requires x86-64 GCC or Clang (including MinGW). +#endif +#ifdef _WIN32 +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +typedef struct { uint64_t address, size, flags; } Segment; +typedef struct { uint64_t target, kind, value, addend; } Reloc; +static char (*names)[128]; +static uint64_t import_count; +static unsigned char *image; +static size_t page_size; +typedef struct { uint64_t base, size, init, tls_address, tls_memsz, tls_filesz, tls_module; } LinkedModule; +static LinkedModule modules[16]; +static uint64_t module_count; +static int entered_game; +static int gpu_enabled; +int vulkan_smoke(void); + +static void fail(const char *message) { fprintf(stderr, "ERROR: %s\n", message); exit(1); } +static uint64_t read64(FILE *f) { + unsigned char b[8]; + if (fread(b, 1, 8, f) != 8) fail("truncated boot file"); + uint64_t n = 0; + for (int i = 7; i >= 0; --i) n = (n << 8) | b[i]; + return n; +} +static size_t round_page(size_t size) { return (size + page_size - 1) & ~(page_size - 1); } +static void *allocate(size_t size) { +#ifndef _WIN32 + void *low=runtime_low_map(size,PROT_READ|PROT_WRITE); + if (low) return low; +#endif +#ifdef _WIN32 + void *p = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (!p) fail("VirtualAlloc failed"); +#else + void *p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (p == MAP_FAILED) fail("mmap failed"); +#endif + return p; +} +static void protect(void *p, size_t size, unsigned flags) { +#ifdef _WIN32 + DWORD old, mode = PAGE_NOACCESS; + if (flags & 1) mode = (flags & 2) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + else if (flags & 2) mode = PAGE_READWRITE; + else if (flags & 4) mode = PAGE_READONLY; + if (!VirtualProtect(p, size, mode, &old)) fail("VirtualProtect failed"); + FlushInstructionCache(GetCurrentProcess(), p, size); +#else + int mode = ((flags & 4) ? PROT_READ : 0) | ((flags & 2) ? PROT_WRITE : 0) | ((flags & 1) ? PROT_EXEC : 0); + if (mprotect(p, size, mode)) fail("mprotect failed"); +#endif +} +static ABI __attribute__((noreturn)) void unresolved(uint32_t id, uintptr_t argument) { + if (id >= import_count) fail("bad import trap index"); + printf("STOP: first unsupported PS4 import: %s (index %u)\n", names[id], id); + printf("API: %s\n", runtime_import_name(names[id])); + printf("Caller return offset: 0x%" PRIxPTR "; first argument: 0x%" PRIxPTR "\n", + (uintptr_t)__builtin_return_address(0) - (uintptr_t)image, argument); + uintptr_t caller=(uintptr_t)__builtin_return_address(0)-(uintptr_t)image; + for (uint64_t m=0;m=modules[m].base && caller-modules[m].basesi_addr)) return; + /* The process is terminating: dladdr/snprintf are acceptable here. */ + ucontext_t *uc = context; + uintptr_t rip = (uintptr_t)uc->uc_mcontext.gregs[REG_RIP]; + char line[512]; + Dl_info where; + if (rip - (uintptr_t)image < 0x10000000) + snprintf(line, sizeof(line), "Guest fault (signal %d) at guest offset 0x%lx, address %p\n", + sig, (unsigned long)(rip - (uintptr_t)image), info->si_addr); + else if (dladdr((void *)rip, &where) && where.dli_fname) + snprintf(line, sizeof(line), "Host fault (signal %d) in %s+0x%lx (%s), address %p\n", sig, where.dli_fname, + (unsigned long)(rip - (uintptr_t)where.dli_fbase), where.dli_sname ? where.dli_sname : "?", info->si_addr); + else + snprintf(line, sizeof(line), "Fault (signal %d) at RIP %p, address %p\n", sig, (void *)rip, info->si_addr); + { ssize_t written_=write(2, line, strlen(line)); (void)written_; } + /* Host call chain (frames with unwind info; guest frames end it). */ + void *frames[32]; + int depth = backtrace(frames, 32); + for (int i = 2; i < depth; ++i) { + if (dladdr(frames[i], &where) && where.dli_fname) + snprintf(line, sizeof(line), " #%d %s+0x%lx (%s)\n", i, where.dli_fname, + (unsigned long)((uintptr_t)frames[i] - (uintptr_t)where.dli_fbase), where.dli_sname ? where.dli_sname : "?"); + else + snprintf(line, sizeof(line), " #%d %p\n", i, frames[i]); + ssize_t written_=write(2, line, strlen(line)); (void)written_; + } + _exit(128 + sig); +} +#endif +/* Watchdog: dump RIP and the rbp frame chain of every thread (guest offsets + * when inside the image). Reads use process_vm_readv so bad frames cannot fault. */ +static uintptr_t exe_base; +static void write_hex(char *out, uint64_t v) { + const char digits[] = "0123456789abcdef"; + for (int i = 0; i < 16; ++i) out[i] = digits[(v >> (60 - i * 4)) & 15]; +} +static void dump_frames(ucontext_t *uc) { + char line[] = " tid=0000000000000000 rip=0000000000000000 image-relative=0000000000000000 host-relative=0000000000000000\n"; + uintptr_t rip=(uintptr_t)uc->uc_mcontext.gregs[REG_RIP], rbp=(uintptr_t)uc->uc_mcontext.gregs[REG_RBP]; + uint64_t tid=(uint64_t)gettid(); + /* First argument register: the lock address when a thread waits on a futex. */ + char arg[]=" tid=0000000000000000 rdi=0000000000000000\n"; + write_hex(arg+6,tid); write_hex(arg+27,(uint64_t)uc->uc_mcontext.gregs[REG_RDI]); + { ssize_t written_=write(2,arg,sizeof(arg)-1); (void)written_; } + for (int depth=0; depth<24; ++depth) { + write_hex(line+6,tid); write_hex(line+27,rip); write_hex(line+59,rip-(uintptr_t)image); write_hex(line+90,rip-exe_base); + { ssize_t written_=write(2,line,sizeof(line)-1); (void)written_; } + uintptr_t frame[2]; + struct iovec local={frame,sizeof(frame)}, remote={(void *)rbp,sizeof(frame)}; + if (!rbp || process_vm_readv(getpid(),&local,1,&remote,1,0)!=(ssize_t)sizeof(frame)) break; + if (frame[0]<=rbp) break; + rbp=frame[0]; rip=frame[1]; + } +} +static void thread_dump(int sig, siginfo_t *info, void *context) { (void)sig; (void)info; dump_frames(context); } +static void watchdog(int sig, siginfo_t *info, void *context) { + (void)info; + const char head[]="STOP: watchdog timeout; thread stacks:\n"; + { ssize_t written_=write(2,head,sizeof(head)-1); (void)written_; } + dump_frames(context); + int dir=open("/proc/self/task",O_RDONLY|O_DIRECTORY); + char buffer[4096]; + long n; + pid_t self=gettid(); + while (dir>=0 && (n=syscall(SYS_getdents64,dir,buffer,sizeof(buffer)))>0) + for (long at=0; atname,NULL,10); + if (tid>0 && tid!=self) { syscall(SYS_tgkill,getpid(),tid,SIGUSR2); usleep(20000); } + at+=d->reclen; + } + usleep(100000); + _exit(128 + sig); +} +/* param.sfo lookup: string or integer value of key, 0 when absent. */ +static int sfo_value(const char *path, const char *key, char *text, size_t text_size, uint32_t *number) { + FILE *f=fopen(path,"rb"); + if (!f) return 0; + unsigned char data[65536]; + size_t n=fread(data,1,sizeof(data),f); fclose(f); + if (n<20 || memcmp(data,"\0PSF",4)) return 0; + uint32_t keys, values, count; + memcpy(&keys,data+8,4); memcpy(&values,data+12,4); memcpy(&count,data+16,4); + for (uint32_t i=0;i=n || values+offset+length>n || strcmp((const char *)data+keys+key_offset,key)) continue; + if (format==0x0404 && number && length>=4) { memcpy(number,data+values+offset,4); return 1; } + if (text && text_size) { + size_t copy=length= segments[i].address && bytes <= segments[i].size && + address - segments[i].address <= segments[i].size - bytes) return 1; + return 0; +} +/* BBPATCH1 (patches.py): byte writes at image offsets, applied after relocation. */ +static void apply_patches(const char *path, Segment *segments, uint64_t ns, const Reloc *relocs, uint64_t nr) { + FILE *f=fopen(path,"rb"); + char magic[8]; + if (!f || fread(magic,1,8,f)!=8 || memcmp(magic,"BBPATCH1",8)) fail("invalid patch file"); + uint64_t count=read64(f), bytes=0; + unsigned char data[4096]; + for (uint64_t i=0;isizeof(data) || !mapped(segments,ns,offset,length) || fread(data,1,length,f)!=length) + fail("bad patch entry"); + for (uint64_t r=0;r 512*1024*1024 || entry >= size || !ns || ns > 64 || nr > 1000000 || import_count > 100000) + fail("boot file limits exceeded"); + int multi=!memcmp(magic,"BBPROBE5",8); + int linked=!memcmp(magic,"BBPROBE3",8) || !memcmp(magic,"BBPROBE4",8) || multi; + int native_libc=linked && !strict_imports && (capabilities&1); + uint64_t main_tls[4]={0}; + uint64_t nb=0,procparam=0; + uint64_t *bindings=calloc(import_count ? import_count : 1,sizeof(*bindings)); + uint64_t *binding_kinds=calloc(import_count ? import_count : 1,sizeof(*binding_kinds)); + if (!bindings || !binding_kinds) fail("allocation failed"); + if (multi) { + /* BBPROBE5: procparam, eboot TLS, module table, bindings (link_modules.py). */ + procparam=read64(f); + for (int i=0;i<4;++i) main_tls[i]=read64(f); + module_count=read64(f); + if (!module_count || module_count>sizeof(modules)/sizeof(*modules)) fail("invalid module count"); + for (uint64_t m=0;mbase=read64(f); x->size=read64(f); x->init=read64(f); x->tls_address=read64(f); + x->tls_memsz=read64(f); x->tls_filesz=read64(f); x->tls_module=read64(f); + } + nb=read64(f); + } else if (linked) { + LinkedModule *x=&modules[0]; + module_count=1; + x->base=read64(f); x->size=read64(f); x->init=read64(f); + x->tls_address=read64(f); x->tls_memsz=read64(f); x->tls_filesz=read64(f); x->tls_module=2; nb=read64(f); + procparam=read64(f); + if (!memcmp(magic,"BBPROBE4",8)) for (int i=0;i<4;++i) main_tls[i]=read64(f); + } + if (linked) { + if (main_tls[1]>main_tls[2] || main_tls[2]>1024*1024 || main_tls[0]>size || + main_tls[1]>size-main_tls[0] || (main_tls[3] & (main_tls[3]-1)) || main_tls[3]>4096) + fail("invalid eboot TLS metadata"); + for (uint64_t m=0;mbase>=size || !x->size || x->size>size-x->base || x->initbase || x->init-x->base>=x->size || + (x->tls_module && (x->tls_address>=size || x->tls_memsz>size-x->tls_address || x->tls_memsz>1024*1024 || + x->tls_filesz>x->tls_memsz || x->tls_module<2 || x->tls_module>7))) + fail("invalid linked module metadata"); + } + if (nb>import_count) fail("invalid binding count"); + for (uint64_t i=0;i=modules[m].base && address-modules[m].base=import_count || !inside || (kind!=1 && kind!=2) || bindings[index]) fail("invalid native binding"); + bindings[index]=address; binding_kinds[index]=kind; + } + } + Segment *segments = calloc(ns, sizeof(*segments)); + Reloc *relocs = calloc(nr ? nr : 1, sizeof(*relocs)); + names = calloc(import_count ? import_count : 1, sizeof(*names)); + if (!segments || !relocs || !names) fail("allocation failed"); + for (uint64_t i = 0; i < ns; ++i) { + segments[i].address = read64(f); + segments[i].size = read64(f); + segments[i].flags = read64(f); + if (segments[i].address > size || segments[i].size > size - segments[i].address || + segments[i].address % page_size || segments[i].flags > 7) fail("bad segment"); + } + if (fread(names, 128, import_count, f) != import_count) fail("truncated import names"); + for (uint64_t i = 0; i < import_count; ++i) + if (!memchr(names[i], 0, 128)) fail("unterminated import name"); + for (uint64_t i = 0; i < nr; ++i) { + relocs[i].target = read64(f); + relocs[i].kind = read64(f); + relocs[i].value = read64(f); + relocs[i].addend = read64(f); + if (!mapped(segments, ns, relocs[i].target, 8) || relocs[i].kind > 2 || + (relocs[i].kind && relocs[i].value >= import_count) || + (relocs[i].kind != 2 && relocs[i].addend) || relocs[i].addend >= page_size) fail("bad relocation"); + } + for (uint64_t m=0;m=segments[s].address && + bindings[i]-segments[s].address= segments[i].address && entry - segments[i].address < segments[i].size) + executable_entry = 1; + } + if (!executable_entry) fail("entry is not executable"); + printf("Mapped %" PRIu64 " bytes, %" PRIu64 " segments; applied %" PRIu64 " relocations\n", size, ns, nr); + if (native_libc) { + for (uint64_t m=0;m=segments[i].address && modules[m].init-segments[i].address&2; exit 1; fi + export VK_LOADER_LAYERS_DISABLE='~implicit~' +fi +if [[ -z ${BB_IN_NIX_SHELL:-} ]] && ! { command -v pkg-config >/dev/null && pkg-config --exists vulkan sdl3; } && command -v nix-shell >/dev/null; then + args=''; if (( $# )); then args=$(printf '%q ' "$@"); fi + exec env BB_IN_NIX_SHELL=1 nix-shell shell.nix --run "bash run.sh $args" +fi +if [[ -z ${PYTHON:-} ]]; then + PYTHON=$(command -v python3 || true) + if [[ -z $PYTHON ]]; then + for candidate in /nix/store/*-python3-*/bin/python3; do + if [[ -x $candidate ]]; then PYTHON=$candidate; break; fi + done + fi +fi +if [[ -z ${PYTHON:-} ]]; then echo 'Install Python 3 or set PYTHON.' >&2; exit 1; fi +"$PYTHON" prepare.py ../CUSA03173 +"$PYTHON" link_libc.py ../CUSA03173 +"$PYTHON" link_modules.py ../CUSA03173 +"$PYTHON" content_profile.py ../CUSA03173 --sku "${BB_CONTENT_SKU:-full}" +# Frame rate: BB_FPS=uncap (default; delta-time patch, vblank follows the display), +# 60/90 (fixed-timestep patches) or 30 (unpatched). BB_PATCHES adds patch names ("a;b"). +fps=${BB_FPS:-uncap} +"$PYTHON" patches.py --fps "$fps" --extra "${BB_PATCHES:-}" +if [[ -z ${BB_VBLANK_HZ:-} ]]; then + case $fps in uncap) export BB_VBLANK_HZ=0 ;; 90) export BB_VBLANK_HZ=90 ;; *) export BB_VBLANK_HZ=60 ;; esac +fi +bash build.sh +exec out/bb-probe out/boot-linked.bin --content-profile out/content.bin --patches out/patches.bin --app0 ../CUSA03173 --user "${BB_USER_DIR:-user}" --timeout "${BB_TIMEOUT:-0}" "$@" diff --git a/runtime.c b/runtime.c new file mode 100644 index 0000000..25865ae --- /dev/null +++ b/runtime.c @@ -0,0 +1,261 @@ +/* Narrow, explicit PS4 libc contracts. No automatic success stubs. */ +#define _CRT_RAND_S +#include "runtime.h" +#include "gpu/bbgpu.h" +#include +#include +#include +#include +#include +#include + +typedef struct { + union { GuestCallback plain; void (ABI *with_arg)(void *); } callback; + void *argument, *dso; + int with_arg, active; +} ExitHandler; +static ExitHandler *handlers; +static size_t handler_count, handler_capacity, calls_init, calls_atexit, calls_cxa; +static uint64_t capabilities; +static _Atomic size_t guards_acquired, guards_released; +static uint64_t stack_canary; +static _Atomic size_t memory_calls; +/* Dynamic TLS of linked modules: module IDs 2..7 (1 is the eboot's static TLS). */ +#define TLS_MODULES 8 +static struct { const void *data; uint64_t filesz, memsz; } tls_modules[TLS_MODULES]; +static _Thread_local unsigned char *tls_blocks[TLS_MODULES]; +static void *process_param; +void runtime_set_procparam(void *param) { process_param=param; } +static ABI void *guest_procparam(void) { return process_param; } +static void **application_heap_api; +static ABI void guest_set_heap_api(void **api) { + application_heap_api=api; + puts("Runtime: application heap API registered"); +} +void **runtime_application_heap_api(void) { return application_heap_api; } +void runtime_set_module_tls(uint64_t module, const void *data, uint64_t filesz, uint64_t memsz) { + if (module<2 || module>=TLS_MODULES) { fputs("STOP: unsupported TLS module id\n",stderr); exit(21); } + tls_modules[module].data=data; tls_modules[module].filesz=filesz; tls_modules[module].memsz=memsz; +} +void runtime_set_libc_tls(const void *data, uint64_t filesz, uint64_t memsz) { runtime_set_module_tls(2,data,filesz,memsz); } +static ABI void *guest_tls_get_addr(const uint64_t *index) { + if (!index || index[0]<2 || index[0]>=TLS_MODULES || !tls_modules[index[0]].data || index[1]>=tls_modules[index[0]].memsz) { + fputs("STOP: unsupported TLS module/offset\n",stderr); exit(21); + } + unsigned char **block=&tls_blocks[index[0]]; + if (!*block) { + *block=calloc(1,tls_modules[index[0]].memsz); + if (!*block) { fputs("Cannot allocate module TLS\n",stderr); exit(1); } + memcpy(*block,tls_modules[index[0]].data,tls_modules[index[0]].filesz); + } + return *block+index[1]; +} + +void runtime_start(uint64_t flags) { + capabilities = flags; + if (!(flags & 1)) return; +#ifdef _WIN32 + unsigned int halves[2]; + if (rand_s(&halves[0]) || rand_s(&halves[1])) { fputs("Cannot initialize stack canary\n", stderr); exit(1); } + memcpy(&stack_canary, halves, sizeof(stack_canary)); +#else + FILE *random = fopen("/dev/urandom", "rb"); + if (!random || fread(&stack_canary, sizeof(stack_canary), 1, random) != 1) { + fputs("Cannot initialize stack canary\n", stderr); exit(1); + } + fclose(random); +#endif + stack_canary &= ~UINT64_C(255); +} +void runtime_report(void) { + printf("Runtime: _init_env=%zu, atexit=%zu, __cxa_atexit=%zu, registered handlers=%zu\n", + calls_init, calls_atexit, calls_cxa, handler_count); + printf("Runtime: static guards acquired=%zu, released=%zu\n", (size_t)guards_acquired, (size_t)guards_released); + runtime_thread_report(); + runtime_mutex_report(); + runtime_rwlock_report(); + runtime_sema_report(); + runtime_content_report(); + runtime_memory_report(); + runtime_ajm_report(); + runtime_audio_report(); + runtime_pad_report(); + runtime_savedata_report(); + runtime_file_report(); + printf("Runtime: memory operations=%zu\n", (size_t)memory_calls); +} +static ABI void init_env(void) { + /* prepare.py verified the supplied libc export consists of exactly C3. */ + ++calls_init; + puts("Runtime: _init_env returned (verified libc implementation: RET)"); +} +static pthread_mutex_t handler_lock = PTHREAD_MUTEX_INITIALIZER; +static int register_handler(ExitHandler value) { + pthread_mutex_lock(&handler_lock); + if (handler_count == handler_capacity) { + size_t capacity = handler_capacity ? handler_capacity * 2 : 64; + ExitHandler *next = capacity > 1024 * 1024 ? NULL : realloc(handlers, capacity * sizeof(*handlers)); + if (!next) { pthread_mutex_unlock(&handler_lock); return -1; } + handlers = next; handler_capacity = capacity; + } + value.active = 1; handlers[handler_count++] = value; + pthread_mutex_unlock(&handler_lock); + return 0; +} +static ABI int guest_atexit(GuestCallback callback) { + if (!callback) return -1; + ++calls_atexit; + return register_handler((ExitHandler){.callback.plain=callback}); +} +static ABI int guest_cxa_atexit(void (ABI *callback)(void *), void *argument, void *dso) { + if (!callback) return -1; + ++calls_cxa; + return register_handler((ExitHandler){.callback.with_arg=callback, .argument=argument, .dso=dso, .with_arg=1}); +} +void runtime_finalize(void *dso) { + /* Mark before invoking: repeated or recursive finalization cannot run twice. + Restart at the end to include handlers registered by a destructor. */ + for (;;) { + pthread_mutex_lock(&handler_lock); + size_t i = handler_count; + while (i && (!handlers[i-1].active || (dso && handlers[i-1].dso != dso))) --i; + if (!i) { pthread_mutex_unlock(&handler_lock); return; } + ExitHandler handler = handlers[i-1]; handlers[i-1].active = 0; + pthread_mutex_unlock(&handler_lock); + if (handler.with_arg) handler.callback.with_arg(handler.argument); + else handler.callback.plain(); + } +} +static ABI void guest_finalize(void *dso) { runtime_finalize(dso); } +static _Atomic uint32_t next_guard_owner=1; +static _Thread_local uint32_t guard_owner; +static ABI int guard_acquire(uint64_t *guard) { + _Atomic uint64_t *state = (_Atomic uint64_t *)guard; + /* Dump libc uses the low byte for completion and the dword at +4 as lock. + The lock word holds a per-thread owner tag so recursion is detectable. */ + if (!guard_owner) guard_owner = atomic_fetch_add(&next_guard_owner, 1); + for (;;) { + uint64_t expected = 0; + if (atomic_load_explicit(state, memory_order_acquire) & 1) return 0; + if (atomic_compare_exchange_strong_explicit(state, &expected, (uint64_t)guard_owner << 32, + memory_order_acq_rel, memory_order_acquire)) break; + if (expected & 1) return 0; + if ((uint32_t)(expected >> 32) == guard_owner) { + fputs("STOP: recursive/concurrent static initialization is not supported yet\n", stderr); + exit(21); + } + sched_yield(); /* another thread is running the initializer */ + } + atomic_fetch_add(&guards_acquired, 1); + return 1; +} +static ABI void guard_release(uint64_t *guard) { + atomic_store_explicit((_Atomic uint64_t *)guard, 1, memory_order_release); + atomic_fetch_add(&guards_released, 1); +} +static ABI void guard_abort(uint64_t *guard) { + atomic_fetch_and_explicit((_Atomic uint64_t *)guard, UINT64_C(0xffffffff), memory_order_release); +} +static ABI __attribute__((noreturn)) void stack_fail(void) { + fputs("STOP: guest stack protector detected corruption\n", stderr); + exit(22); +} +static ABI void *guest_memset(void *dst, int value, size_t size) { + atomic_fetch_add_explicit(&memory_calls,1,memory_order_relaxed); return memset(dst, value, size); +} +static ABI void *guest_memcpy(void *dst, const void *src, size_t size) { + atomic_fetch_add_explicit(&memory_calls,1,memory_order_relaxed); return memcpy(dst, src, size); +} +static ABI void *guest_memmove(void *dst, const void *src, size_t size) { + atomic_fetch_add_explicit(&memory_calls,1,memory_order_relaxed); return memmove(dst, src, size); +} +static ABI int guest_memcmp(const void *a, const void *b, size_t size) { + atomic_fetch_add_explicit(&memory_calls,1,memory_order_relaxed); return memcmp(a, b, size); +} +static ABI size_t guest_strlen(const char *text) { return strlen(text); } +static ABI __attribute__((noreturn)) void guest_libc_exit(int status) { + printf("Runtime: guest requested exit(%d)\n", status); + runtime_finalize(NULL); + runtime_report(); + exit(status); +} +uintptr_t runtime_resolve(const char *name, int is_data) { + if (!(capabilities & 1)) return 0; + if (is_data) { + static int32_t need_libc_internal = 1; /* SDK marker variable referenced by Fios2 */ + if (!strcmp(name, "f7uOxY9mM1U#p#J")) return (uintptr_t)&stack_canary; + if (!strcmp(name, "ZT4ODD2Ts9o#libSceLibcInternal")) return (uintptr_t)&need_libc_internal; + return 0; + } + /* Exact scoped imports for CUSA03173; the suffix identifies library/module. */ + if (!strcmp(name, "bzQExy189ZI#q#q")) return (uintptr_t)init_env; + if (!strcmp(name, "8G2LB+A3rzg#q#q")) return (uintptr_t)guest_atexit; + if (!strcmp(name, "tsvEmnenz48#q#q")) return (uintptr_t)guest_cxa_atexit; + if (!strcmp(name, "uMei1W9uyNo#q#q")) return (uintptr_t)guest_libc_exit; + /* Not imported by the current eboot, exposed for ABI tests/future use. */ + if (!strcmp(name, "H2e8t5ScQGc#q#q")) return (uintptr_t)guest_finalize; + if (!strcmp(name, "3GPpjQdAMTw#q#q")) return (uintptr_t)guard_acquire; + if (!strcmp(name, "9rAeANT2tyE#q#q")) return (uintptr_t)guard_release; + if (!strcmp(name, "2emaaluWzUw#q#q")) return (uintptr_t)guard_abort; + if (!strcmp(name, "Ou3iL1abvng#p#J")) return (uintptr_t)stack_fail; + if (!strcmp(name, "8zTFvBIAIN8#q#q")) return (uintptr_t)guest_memset; + if (!strcmp(name, "Q3VBxCXhUHs#q#q")) return (uintptr_t)guest_memcpy; + if (!strcmp(name, "+P6FRGH4LfA#q#q")) return (uintptr_t)guest_memmove; + if (!strcmp(name, "DfivPArhucg#q#q")) return (uintptr_t)guest_memcmp; + if (!strcmp(name, "j4ViWNHEgww#q#q")) return (uintptr_t)guest_strlen; + if (!strcmp(name, "vNe1w4diLCs#p#J")) return (uintptr_t)guest_tls_get_addr; + if (!strcmp(name, "959qrazPIrg#p#J")) return (uintptr_t)guest_procparam; + if (!strcmp(name, "p5EcQeEeJAE#p#J")) return (uintptr_t)guest_set_heap_api; + uintptr_t mutex = runtime_mutex_resolve(name); + if (mutex) return mutex; + uintptr_t thread = runtime_thread_resolve(name); + if (thread) return thread; + uintptr_t content=runtime_content_resolve(name); + if (content) return content; + uintptr_t timer = runtime_time_resolve(name); + if (timer) return timer; + uintptr_t sema = runtime_sema_resolve(name); + if (sema) return sema; + uintptr_t rwlock = runtime_rwlock_resolve(name); + if (rwlock) return rwlock; + uintptr_t memory = runtime_memory_resolve(name); + if (memory) return memory; + uintptr_t kernel = runtime_kernel_resolve(name); + if (kernel) return kernel; + uintptr_t services = runtime_services_resolve(name); + if (services) return services; + uintptr_t ajm = runtime_ajm_resolve(name); + if (ajm) return ajm; + uintptr_t audio = runtime_audio_resolve(name); + if (audio) return audio; + uintptr_t pad = runtime_pad_resolve(name); + if (pad) return pad; + uintptr_t rtc = runtime_rtc_resolve(name); + if (rtc) return rtc; + uintptr_t save = runtime_savedata_resolve(name); + if (save) return save; + uintptr_t file = runtime_file_resolve(name); + if (file) return file; + return bbgpu_resolve(name); +} +static const struct { const char *nid, *symbol; } import_names[]={ +#include "import_names.inc" +}; +/* Symbol name for a scoped NID, or NULL when this eboot/libc never imports it. */ +const char *runtime_symbol(const char *nid) { + for (size_t i=0;i +#include +#define ABI __attribute__((sysv_abi)) +typedef void (ABI *GuestCallback)(void); +void runtime_start(uint64_t capabilities); +uintptr_t runtime_resolve(const char *name, int is_data); +void runtime_report(void); +void runtime_finalize(void *dso); +uintptr_t runtime_mutex_resolve(const char *name); +void runtime_mutex_report(void); +uintptr_t runtime_memory_resolve(const char *name); +void runtime_memory_report(void); +int runtime_memory_is_mapped(uintptr_t address, uint64_t size); +const char *runtime_import_name(const char *name); +uintptr_t runtime_rwlock_resolve(const char *name); +void runtime_rwlock_report(void); +void runtime_set_libc_tls(const void *data, uint64_t filesz, uint64_t memsz); +void runtime_set_module_tls(uint64_t module, const void *data, uint64_t filesz, uint64_t memsz); +void runtime_set_procparam(void *param); +void **runtime_application_heap_api(void); +uintptr_t runtime_thread_resolve(const char *name); +void runtime_thread_report(void); +void runtime_set_main_tls(const void *data, uint64_t filesz, uint64_t memsz, uint64_t align); +void runtime_thread_attach_main(void); +int32_t *runtime_errno(void); +uintptr_t runtime_sema_resolve(const char *name); +void runtime_sema_report(void); +unsigned runtime_sema_waiters(uint32_t id); +uintptr_t runtime_time_resolve(const char *name); +void runtime_content_configure(const uint32_t values[5]); +uintptr_t runtime_content_resolve(const char *name); +void runtime_content_report(void); +typedef struct { const char *name; void *function; } RuntimeExport; +#define RUNTIME_LOOKUP(table, nid) runtime_lookup(table, sizeof(table)/sizeof(*(table)), nid) +const char *runtime_symbol(const char *nid); +uintptr_t runtime_lookup(const RuntimeExport *table, size_t count, const char *nid); +uintptr_t runtime_kernel_resolve(const char *name); +uintptr_t runtime_file_resolve(const char *name); +uintptr_t runtime_services_resolve(const char *name); +void runtime_file_report(void); +void runtime_file_configure(const char *app0, const char *user); +int runtime_file_mount(const char *guest, const char *host); +void runtime_file_unmount(const char *guest); +int runtime_file_translate(const char *guest, char *out, size_t size); +int64_t runtime_file_open(const char *path, int flags, int mode); +int64_t runtime_file_close(int fd); +int64_t runtime_file_read(int fd, void *buffer, uint64_t size); +int64_t runtime_file_pread(int fd, void *buffer, uint64_t size, int64_t offset); +int64_t runtime_file_write(int fd, const void *buffer, uint64_t size); +int64_t runtime_file_lseek(int fd, int64_t offset, int whence); +int64_t runtime_file_stat(const char *path, void *guest_stat); +int64_t runtime_file_fstat(int fd, void *guest_stat); +int64_t runtime_file_getdents(int fd, char *buffer, uint64_t size, int64_t *base); +void runtime_thread_keys_cleanup(void); +/* Guest-visible errno values are FreeBSD's. */ +int32_t runtime_guest_errno(int host_errno); +void *runtime_low_map(size_t size, int prot); +uintptr_t runtime_ajm_resolve(const char *name); +void runtime_ajm_report(void); +uintptr_t runtime_audio_resolve(const char *name); +void runtime_audio_report(void); +uintptr_t runtime_pad_resolve(const char *name); +void runtime_pad_report(void); +uintptr_t runtime_rtc_resolve(const char *name); +const char *runtime_file_user_dir(void); +void runtime_savedata_configure(const char *title); +uintptr_t runtime_savedata_resolve(const char *name); +void runtime_savedata_report(void); +void runtime_thread_attach_host(const char *name); +#endif diff --git a/runtime_ajm.c b/runtime_ajm.c new file mode 100644 index 0000000..4d10937 --- /dev/null +++ b/runtime_ajm.c @@ -0,0 +1,481 @@ +/* libSceAjm: audio decoder batches. Batches use the SDK chunk format (the + * builder functions are imports, but games may also build chunks inline), and + * run synchronously at submission: decoding a batch takes well under a + * millisecond, so waiting always finds it complete. ATRAC9 is decoded by + * LibAtrac9 (MIT, third_party/LibAtrac9). MP3/AAC instances stop explicitly. */ +#define _GNU_SOURCE +#include "runtime.h" +#include +#include +#include +#include +#include "third_party/LibAtrac9/C/src/libatrac9.h" + +#define ERR_INVALID_CONTEXT ((int32_t)0x80930002) +#define ERR_INVALID_INSTANCE ((int32_t)0x80930003) +#define ERR_INVALID_BATCH ((int32_t)0x80930004) +#define ERR_INVALID_PARAMETER ((int32_t)0x80930005) +#define ERR_OUT_OF_RESOURCES ((int32_t)0x80930007) +#define ERR_ALREADY_REGISTERED ((int32_t)0x80930009) +#define ERR_NOT_REGISTERED ((int32_t)0x8093000A) +#define ERR_WRONG_REVISION ((int32_t)0x8093000B) +#define ERR_MALFORMED_BATCH ((int32_t)0x80930011) +#define ERR_CANCELLED ((int32_t)0x80930017) +#define RESULT_NOT_INITIALIZED 0x1 +#define RESULT_INVALID_PARAMETER 0x4 +#define RESULT_PARTIAL_INPUT 0x8 +#define RESULT_NOT_ENOUGH_ROOM 0x10 +#define RESULT_CODEC_ERROR 0x40000000u +#define RESULT_FATAL 0x80000000u +#define STATISTICS_INSTANCE 0x80000u +#define MAX_INSTANCES 0x3fff +#define MAX_CONTEXTS 8 +#define MAX_BATCHES 256 +enum { IDENT_JOB=0, IDENT_INPUT_RUN=1, IDENT_INPUT_CONTROL=2, IDENT_CONTROL_FLAGS=3, IDENT_RUN_FLAGS=4, + IDENT_RETURN_ADDRESS=6, IDENT_INLINE=7, IDENT_OUTPUT_RUN=17, IDENT_OUTPUT_CONTROL=18 }; +enum { FORMAT_S16=0, FORMAT_S32=1, FORMAT_FLOAT=2 }; +/* Job flags: version:3 codec:8 run:2 control:3 reserved:29 sideband:3 */ +#define RUN_CODEC_INFO(f) (((f)>>11)&1) +#define RUN_MULTIPLE_FRAMES(f) (((f)>>12)&1) +#define CONTROL_RESET(f) (((f)>>13)&1) +#define CONTROL_INITIALIZE(f) (((f)>>14)&1) +#define CONTROL_RESAMPLE(f) (((f)>>15)&1) +#define SIDEBAND_GAPLESS(f) (((f)>>45)&1) +#define SIDEBAND_FORMAT(f) (((f)>>46)&1) +#define SIDEBAND_STREAM(f) (((f)>>47)&1) + +typedef struct { uint32_t word; uint32_t size; } Chunk; /* ident:6 payload:20 reserved:6 */ +typedef struct { uint32_t word; uint32_t size; void *address; } ChunkBuffer; +typedef struct { int32_t result, internal_result; } SidebandResult; +typedef struct { int32_t input_consumed, output_written; uint64_t total_decoded_samples; } SidebandStream; +typedef struct { uint32_t channels, channel_mask, sample_rate, encoding, bitrate, reserved; } SidebandFormat; +typedef struct { uint32_t total_samples; uint16_t skip_samples, skipped_samples; } SidebandGapless; +typedef struct { uint32_t super_frame_size, frames_in_super_frame, next_frame_size, frame_samples; } At9Info; +typedef struct { int error_code; const void *job_address; uint32_t command_offset; const void *job_return_address; } BatchError; +_Static_assert(sizeof(ChunkBuffer)==16,"Ajm buffer chunk"); +_Static_assert(sizeof(SidebandFormat)==24 && sizeof(SidebandGapless)==8 && sizeof(SidebandStream)==16,"Ajm sideband layout"); + +typedef struct { + int used, codec, format, channels_hint, gapless_loop; + uint32_t codec_flags; + void *handle; + unsigned char config[4]; + int initialized; + Atrac9CodecInfo info; + uint32_t superframe_remain, frames; + SidebandGapless gapless_init, gapless; + uint64_t total_samples; +} Instance; +typedef struct { int used, registered[24]; Instance instances[MAX_INSTANCES+1]; } Context; +typedef struct { int used, context, canceled; } Batch; + +static pthread_mutex_t lock=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static Context *contexts[MAX_CONTEXTS+1]; +static Batch batches[MAX_BATCHES]; +static size_t jobs_run, frames_decoded, batches_run; + +static uint32_t ident(uint32_t word) { return word & 0x3f; } +static uint32_t payload(uint32_t word) { return (word>>6) & 0xfffff; } +static uint32_t header(uint32_t id, uint32_t value) { return (id & 0x3f) | ((value & 0xfffff)<<6); } +static uint32_t channel_mask(int channels) { + switch (channels) { case 1: return 4; case 2: return 3; case 4: return 0x33; case 6: return 0x60f; case 8: return 0x63f; default: return 0; } +} +static int pcm_size(int format) { return format==FORMAT_S16 ? 2 : 4; } + +/* ---- batch builders ---- */ +static unsigned char *put_buffer(unsigned char *p, uint32_t id, const void *address, uint64_t size) { + ChunkBuffer c={header(id,0),(uint32_t)size,(void *)address}; memcpy(p,&c,sizeof(c)); return p+sizeof(c); +} +static unsigned char *put_flags(unsigned char *p, uint32_t id, uint64_t flags) { + Chunk c={header(id,(uint32_t)(flags>>32)),(uint32_t)flags}; memcpy(p,&c,sizeof(c)); return p+sizeof(c); +} +static void *finish_job(unsigned char *start, unsigned char *end, uint32_t instance) { + Chunk job={header(IDENT_JOB,instance),(uint32_t)(end-start-sizeof(Chunk))}; + memcpy(start,&job,sizeof(job)); + return end; +} +static ABI void *job_control(void *buffer, uint32_t instance, uint64_t flags, void *in, uint64_t in_size, + void *out, uint64_t out_size, void *return_address) { + unsigned char *p=(unsigned char *)buffer+sizeof(Chunk); + if (return_address) p=put_buffer(p,IDENT_RETURN_ADDRESS,return_address,0); + p=put_buffer(p,IDENT_INPUT_CONTROL,in,in_size); + flags &= instance==STATISTICS_INSTANCE ? UINT64_C(0xC0018007) : UINT64_C(0x60000000E7FF); + p=put_flags(p,IDENT_CONTROL_FLAGS,flags); + p=put_buffer(p,IDENT_OUTPUT_CONTROL,out,out_size); + return finish_job(buffer,p,instance); +} +static ABI void *job_run(void *buffer, uint32_t instance, uint64_t flags, void *in, uint64_t in_size, + void *out, uint64_t out_size, void *sideband, uint64_t sideband_size, void *return_address) { + unsigned char *p=(unsigned char *)buffer+sizeof(Chunk); + if (return_address) p=put_buffer(p,IDENT_RETURN_ADDRESS,return_address,0); + p=put_buffer(p,IDENT_INPUT_RUN,in,in_size); + p=put_flags(p,IDENT_RUN_FLAGS,flags & UINT64_C(0xE00000001FFF)); + p=put_buffer(p,IDENT_OUTPUT_RUN,out,out_size); + p=put_buffer(p,IDENT_OUTPUT_CONTROL,sideband,sideband_size); + return finish_job(buffer,p,instance); +} +typedef struct { void *address; uint64_t size; } AjmBuffer; +static ABI void *job_run_split(void *buffer, uint32_t instance, uint64_t flags, const AjmBuffer *in, uint64_t in_count, + const AjmBuffer *out, uint64_t out_count, void *sideband, uint64_t sideband_size, + void *return_address) { + unsigned char *p=(unsigned char *)buffer+sizeof(Chunk); + if (return_address) p=put_buffer(p,IDENT_RETURN_ADDRESS,return_address,0); + for (uint64_t i=0;ihandle) Atrac9ReleaseHandle(in->handle); + in->handle=Atrac9GetHandle(); + in->initialized = Atrac9InitDecoder(in->handle,in->config)==0; + if (in->initialized) Atrac9GetCodecInfo(in->handle,&in->info); + in->frames=0; in->superframe_remain=(uint32_t)in->info.superframeSize; +} +static void gapless_reset(Instance *in) { + in->gapless.total_samples=in->gapless_init.total_samples; + in->gapless.skip_samples=in->gapless_init.skip_samples; + in->gapless.skipped_samples=0; +} +static int gapless_end(const Instance *in) { return in->gapless_init.total_samples && !in->gapless.total_samples; } +static uint32_t next_frame_bytes(const Instance *in) { + uint32_t frame=(uint32_t)in->info.frameSamples; + uint32_t skip=in->gapless.skip_samplesgapless.skip_samples : frame; + uint32_t samples=frame-skip; + if (in->gapless_init.total_samples && in->gapless.total_samplesgapless.total_samples; + return samples*(uint32_t)in->info.channels*(uint32_t)pcm_size(in->format); +} +typedef struct { ChunkBuffer *chunks; int count, current; uint32_t offset; } Output; +static uint64_t output_room(const Output *o) { + uint64_t room=0; + for (int i=o->current;icount;++i) room+=o->chunks[i].size-(i==o->current ? o->offset : 0); + return room; +} +static void output_write(Output *o, const unsigned char *data, uint64_t size) { + while (size && o->currentcount) { + ChunkBuffer *c=&o->chunks[o->current]; + uint64_t n=c->size-o->offset; if (n>size) n=size; + memcpy((unsigned char *)c->address+o->offset,data,n); + data+=n; size-=n; o->offset+=(uint32_t)n; + if (o->offset==c->size) { ++o->current; o->offset=0; } + } +} +/* One frame; returns result flags. */ +static uint32_t at9_frame(Instance *in, const unsigned char **input, uint64_t *input_size, Output *out, + uint32_t *samples_written, int32_t *internal) { + int channels=in->info.channels, frame=in->info.frameSamples, used=0; + int16_t pcm[256*8]; + if (frame*channels>(int)(sizeof(pcm)/sizeof(*pcm))) return RESULT_CODEC_ERROR|RESULT_FATAL; + int e=Atrac9Decode(in->handle,*input,pcm,&used); + if (e) { *internal=e; return RESULT_CODEC_ERROR|RESULT_FATAL; } + *input+=used; *input_size-=(uint64_t)used; in->superframe_remain-=(uint32_t)used; + ++frames_decoded; + uint32_t skip=0; + if (in->gapless.skip_samples) { + skip=in->gapless.skip_samples<(uint32_t)frame ? in->gapless.skip_samples : (uint32_t)frame; + in->gapless.skip_samples-=(uint16_t)skip; + } + uint32_t samples=(uint32_t)frame-skip; + if (in->gapless_init.total_samples && samples>in->gapless.total_samples) samples=in->gapless.total_samples; + uint64_t room=output_room(out)/(uint64_t)(channels*pcm_size(in->format)); + if (samples>room) samples=(uint32_t)room; + /* Convert (and optionally de-interleave) into the requested encoding. */ + unsigned char converted[256*8*4]; + int non_interleaved=(in->codec_flags>>8)&1; + for (uint32_t s=0;sformat==FORMAT_S16) memcpy(converted+index*2,&v,2); + else if (in->format==FORMAT_S32) { int32_t w=(int32_t)v<<16; memcpy(converted+index*4,&w,4); } + else { float f=(float)v/32768.0f; memcpy(converted+index*4,&f,4); } + } + output_write(out,converted,(uint64_t)samples*(uint64_t)channels*(uint64_t)pcm_size(in->format)); + *samples_written=samples; + in->gapless.skipped_samples+=(uint16_t)((uint32_t)frame-samples); + if (in->gapless_init.total_samples) in->gapless.total_samples-=samples; + if (++in->frames%(uint32_t)in->info.framesInSuperframe==0) { + uint64_t skip_bytes=in->superframe_remain<*input_size ? in->superframe_remain : *input_size; + *input+=skip_bytes; *input_size-=skip_bytes; + in->superframe_remain=(uint32_t)in->info.superframeSize; in->frames=0; + } else if (gapless_end(in)) { + /* Drain the rest of the superframe so the next stream starts aligned. */ + while (in->frames%(uint32_t)in->info.framesInSuperframe && *input_size) { + if (Atrac9Decode(in->handle,*input,pcm,&used)) break; + *input+=used; *input_size-=(uint64_t)used; in->superframe_remain-=(uint32_t)used; ++in->frames; + } + uint64_t skip_bytes=in->superframe_remain<*input_size ? in->superframe_remain : *input_size; + *input+=skip_bytes; *input_size-=skip_bytes; + in->superframe_remain=(uint32_t)in->info.superframeSize; in->frames=0; + } + return 0; +} +static void parse_riff(Instance *in, const unsigned char **input, uint64_t *size) { + const unsigned char *p=*input, *end=p+*size; + p+=12; + while (p+8<=end) { + uint32_t tag, length; memcpy(&tag,p,4); memcpy(&length,p+4,4); p+=8; + if (tag==0x61746164) break; /* "data" */ + if (tag==0x20746d66 && length>=52 && p+52<=end) { /* "fmt " */ + memcpy(in->config,p+44,4); at9_reset(in); + } else if (tag==0x74636166 && length>=12 && p+12<=end) { /* "fact" */ + uint32_t total, delay; memcpy(&total,p,4); memcpy(&delay,p+4,4); + in->gapless_init.total_samples=total; in->gapless_init.skip_samples=(uint16_t)delay; + gapless_reset(in); + } + p+=length; + } + *size-=(uint64_t)(p-*input); *input=p; +} + +/* ---- job execution ---- */ +typedef struct { + uint64_t flags; int have_flags; + ChunkBuffer inputs[16]; int input_count; + ChunkBuffer outputs[16]; int output_count; + ChunkBuffer input_control, output_control; +} Job; +static int parse_job(const unsigned char *p, uint32_t size, Job *job) { + memset(job,0,sizeof(*job)); + for (const unsigned char *end=p+size; pflags=((uint64_t)payload(c.word)<<32)|c.size; job->have_flags=1; p+=8; break; + } + case IDENT_INPUT_RUN: if (job->input_count==16) return -1; memcpy(&job->inputs[job->input_count++],p,16); p+=16; break; + case IDENT_OUTPUT_RUN: if (job->output_count==16) return -1; memcpy(&job->outputs[job->output_count++],p,16); p+=16; break; + case IDENT_INPUT_CONTROL: memcpy(&job->input_control,p,16); p+=16; break; + case IDENT_OUTPUT_CONTROL: memcpy(&job->output_control,p,16); p+=16; break; + case IDENT_RETURN_ADDRESS: p+=16; break; + default: return -1; + } + } + return job->have_flags ? 0 : -1; +} +static void run_job(Context *ctx, uint32_t id, Job *job) { + ++jobs_run; + unsigned char *side=job->output_control.size ? job->output_control.address : NULL; + unsigned char *side_end=side ? side+job->output_control.size : NULL; + SidebandResult *result=NULL; + if (side && side+sizeof(SidebandResult)<=side_end) { result=(void *)side; side+=sizeof(*result); memset(result,0,sizeof(*result)); } + if (id==STATISTICS_INSTANCE) { if (side) memset(side,0,(size_t)(side_end-side)); return; } + Instance *in=&ctx->instances[id & MAX_INSTANCES]; + if ((id & MAX_INSTANCES)==0 || !in->used) { if (result) result->result=(int32_t)(RESULT_FATAL|RESULT_INVALID_PARAMETER); return; } + uint64_t f=job->flags; + uint32_t flags_result=0; + const unsigned char *control=job->input_control.size ? job->input_control.address : NULL; + const unsigned char *control_end=control ? control+job->input_control.size : NULL; + if (CONTROL_RESET(f)) { in->total_samples=0; gapless_reset(in); if (in->initialized) at9_reset(in); } + if (control && SIDEBAND_FORMAT(f) && control+24<=control_end) control+=24; /* output format fixed per instance */ + if (control && SIDEBAND_GAPLESS(f) && control+8<=control_end) { + SidebandGapless g; memcpy(&g,control,8); control+=8; + uint32_t processed=in->gapless_init.total_samples-in->gapless.total_samples; + if (g.total_samples || !g.skip_samples) { + if (g.total_samples>=processed) { + int64_t diff=(int64_t)in->gapless_init.total_samples-g.total_samples; + in->gapless_init.total_samples=g.total_samples; in->gapless.total_samples=(uint32_t)(in->gapless.total_samples-diff); + } else flags_result|=RESULT_INVALID_PARAMETER; + } + uint32_t skipped=(uint32_t)in->gapless_init.skip_samples-in->gapless.skip_samples; + if (g.skip_samples || !g.total_samples) { + if (g.skip_samples>=skipped) { + int32_t diff=(int32_t)in->gapless_init.skip_samples-g.skip_samples; + in->gapless_init.skip_samples=g.skip_samples; in->gapless.skip_samples=(uint16_t)(in->gapless.skip_samples-diff); + } else flags_result|=RESULT_INVALID_PARAMETER; + } + } + if (control && CONTROL_RESAMPLE(f) && control+8<=control_end) control+=8; + if (control && CONTROL_INITIALIZE(f) && control+8<=control_end) { memcpy(in->config,control,4); at9_reset(in); } + uint64_t in_size=0; + for (int i=0;iinput_count;++i) in_size+=job->inputs[i].size; + unsigned char *joined=NULL; + const unsigned char *input=NULL; + if (job->input_count==1) input=job->inputs[0].address; + else if (job->input_count>1) { + joined=malloc(in_size ? in_size : 1); + uint64_t at=0; + for (int i=0;iinput_count;++i) { memcpy(joined+at,job->inputs[i].address,job->inputs[i].size); at+=job->inputs[i].size; } + input=joined; + } + Output out={job->outputs,job->output_count,0,0}; + uint64_t in_start=in_size, out_start=output_room(&out); + uint32_t frames=0; + int32_t internal=0; + if (in_size) for (;;) { + if (in->gapless_loop && gapless_end(in)) { gapless_reset(in); in->total_samples=0; } + if ((in->codec_flags & 1) && in_size>=4 && !memcmp(input,"RIFF",4)) { parse_riff(in,&input,&in_size); in->total_samples=0; } + if (!in->initialized) { flags_result|=RESULT_NOT_INITIALIZED; break; } + if (!gapless_end(in) && output_room(&out)superframe_remain) flags_result|=RESULT_PARTIAL_INPUT; + if (flags_result) break; + uint32_t written=0; + uint32_t r=at9_frame(in,&input,&in_size,&out,&written,&internal); + in->total_samples+=written; ++frames; + if (r) { flags_result|=r; break; } + if (!RUN_MULTIPLE_FRAMES(f)) break; + } + free(joined); + if (result) { result->result=(int32_t)flags_result; result->internal_result=internal; } + /* Output sideband order: stream, format, gapless, multi-frame, codec info. */ + if (side && SIDEBAND_STREAM(f) && side+16<=side_end) { + SidebandStream s={(int32_t)(in_start-in_size),(int32_t)(out_start-output_room(&out)),in->total_samples}; + memcpy(side,&s,16); side+=16; + } + if (side && SIDEBAND_FORMAT(f) && side+24<=side_end) { + SidebandFormat s={(uint32_t)in->info.channels,channel_mask(in->info.channels),(uint32_t)in->info.samplingRate, + (uint32_t)in->format,0,0}; + if (in->info.framesInSuperframe && in->info.frameSamples) + s.bitrate=(uint32_t)((uint64_t)in->info.samplingRate*(uint64_t)in->info.superframeSize*8/ + ((uint64_t)in->info.framesInSuperframe*(uint64_t)in->info.frameSamples)); + memcpy(side,&s,24); side+=24; + } + if (side && SIDEBAND_GAPLESS(f) && side+8<=side_end) { memcpy(side,&in->gapless,8); side+=8; } + if (side && RUN_MULTIPLE_FRAMES(f) && side+8<=side_end) { uint32_t m[2]={frames,0}; memcpy(side,m,8); side+=8; } + if (side && RUN_CODEC_INFO(f) && side+16<=side_end) { + At9Info info={(uint32_t)in->info.superframeSize,(uint32_t)in->info.framesInSuperframe,in->superframe_remain,(uint32_t)in->info.frameSamples}; + memcpy(side,&info,16); + } +} + +/* ---- API ---- */ +static Context *context(uint32_t id) { return id && id<=MAX_CONTEXTS ? contexts[id] : NULL; } +static ABI int32_t ajm_initialize(int64_t reserved, uint32_t *out) { + if (!out || reserved) return ERR_INVALID_PARAMETER; + pthread_mutex_lock(&lock); + for (uint32_t i=1;i<=MAX_CONTEXTS;++i) if (!contexts[i]) { + contexts[i]=calloc(1,sizeof(Context)); + pthread_mutex_unlock(&lock); + if (!contexts[i]) return ERR_OUT_OF_RESOURCES; + *out=i; puts("Runtime: Ajm context initialized (ATRAC9 via LibAtrac9)"); + return 0; + } + pthread_mutex_unlock(&lock); + return ERR_OUT_OF_RESOURCES; +} +static ABI int32_t ajm_finalize(uint32_t id) { + pthread_mutex_lock(&lock); + Context *c=context(id); + if (!c) { pthread_mutex_unlock(&lock); return ERR_INVALID_CONTEXT; } + for (int i=0;i<=MAX_INSTANCES;++i) if (c->instances[i].handle) Atrac9ReleaseHandle(c->instances[i].handle); + free(c); contexts[id]=NULL; + pthread_mutex_unlock(&lock); + return 0; +} +static ABI int32_t ajm_module_register(uint32_t id, uint32_t codec, int64_t reserved) { + if (reserved || codec>=24) return ERR_INVALID_PARAMETER; + pthread_mutex_lock(&lock); + Context *c=context(id); + int32_t r=!c ? ERR_INVALID_CONTEXT : c->registered[codec] ? ERR_ALREADY_REGISTERED : 0; + if (!r) c->registered[codec]=1; + pthread_mutex_unlock(&lock); + return r; +} +static ABI int32_t ajm_module_unregister(uint32_t id, uint32_t codec) { + pthread_mutex_lock(&lock); + Context *c=context(id); + int32_t r=!c ? ERR_INVALID_CONTEXT : codec>=24 ? ERR_INVALID_PARAMETER : !c->registered[codec] ? ERR_NOT_REGISTERED : 0; + if (!r) c->registered[codec]=0; + pthread_mutex_unlock(&lock); + return r; +} +static ABI int32_t ajm_instance_create(uint32_t id, uint32_t codec, uint64_t flags, uint32_t *out) { + if (!out || codec>=24) return ERR_INVALID_PARAMETER; + if (!(flags & 7)) return ERR_WRONG_REVISION; + if (codec!=1) { fprintf(stderr,"STOP: Ajm codec %u (0=MP3, 2=AAC) is not implemented\n",codec); exit(21); } + pthread_mutex_lock(&lock); + Context *c=context(id); + int32_t r=!c ? ERR_INVALID_CONTEXT : !c->registered[codec] ? ERR_NOT_REGISTERED : ERR_OUT_OF_RESOURCES; + if (c && c->registered[codec]) for (uint32_t i=1;i<=MAX_INSTANCES;++i) if (!c->instances[i].used) { + Instance *in=&c->instances[i]; + memset(in,0,sizeof(*in)); + in->used=1; in->codec=(int)codec; in->channels_hint=(int)((flags>>3)&15); in->format=(int)((flags>>7)&7); + in->gapless_loop=(int)((flags>>10)&1); in->codec_flags=(uint32_t)(flags>>32); + if (in->format>FORMAT_FLOAT) { in->used=0; r=ERR_INVALID_PARAMETER; break; } + *out=i|(codec<<14); r=0; break; + } + pthread_mutex_unlock(&lock); + return r; +} +static ABI int32_t ajm_instance_destroy(uint32_t id, uint32_t instance) { + pthread_mutex_lock(&lock); + Context *c=context(id); + Instance *in=c ? &c->instances[instance & MAX_INSTANCES] : NULL; + int32_t r=!c ? ERR_INVALID_CONTEXT : !(instance & MAX_INSTANCES) || !in->used ? ERR_INVALID_INSTANCE : 0; + if (!r) { if (in->handle) Atrac9ReleaseHandle(in->handle); memset(in,0,sizeof(*in)); } + pthread_mutex_unlock(&lock); + return r; +} +static ABI uint32_t ajm_instance_codec(uint32_t instance) { return (instance>>14)&0x1f; } +static ABI int32_t ajm_batch_start(uint32_t id, unsigned char *buffer, uint32_t size, int priority, + BatchError *error, uint32_t *out) { + (void)priority; + if (size & 7) return ERR_MALFORMED_BATCH; + pthread_mutex_lock(&lock); + Context *c=context(id); + if (!c) { pthread_mutex_unlock(&lock); return ERR_INVALID_CONTEXT; } + int slot=-1; + for (int i=0;iend || parse_job(body,chunk.size,&job)) { + if (error) { error->error_code=ERR_MALFORMED_BATCH; error->job_address=body-8; error->command_offset=(uint32_t)(body-8-buffer); error->job_return_address=NULL; } + pthread_mutex_unlock(&lock); + return ERR_MALFORMED_BATCH; + } + run_job(c,payload(chunk.word),&job); + } + batches[slot]=(Batch){1,(int)id,0}; + ++batches_run; + *out=(uint32_t)slot+1; + pthread_mutex_unlock(&lock); + return 0; +} +static ABI int32_t ajm_batch_wait(uint32_t id, uint32_t batch, uint32_t timeout, BatchError *error) { + (void)timeout; (void)error; + pthread_mutex_lock(&lock); + int32_t r=!context(id) ? ERR_INVALID_CONTEXT : !batch || batch>MAX_BATCHES || !batches[batch-1].used ? ERR_INVALID_BATCH : 0; + if (!r) { if (batches[batch-1].canceled) r=ERR_CANCELLED; batches[batch-1].used=0; } + pthread_mutex_unlock(&lock); + return r; +} +static ABI int32_t ajm_batch_cancel(uint32_t id, uint32_t batch) { + pthread_mutex_lock(&lock); + int32_t r=!context(id) ? ERR_INVALID_CONTEXT : !batch || batch>MAX_BATCHES || !batches[batch-1].used ? ERR_INVALID_BATCH : 0; + pthread_mutex_unlock(&lock); + return r; /* already processed at submission: nothing to cancel */ +} +static ABI int32_t ajm_error_dump(void) { return 0; } +static ABI int32_t ajm_memory_register(uint32_t id, void *p, uint64_t pages) { (void)p; (void)pages; return context(id) ? 0 : ERR_INVALID_CONTEXT; } + +static const RuntimeExport exports[]={ + {"sceAjmInitialize",ajm_initialize}, {"sceAjmFinalize",ajm_finalize}, + {"sceAjmModuleRegister",ajm_module_register}, {"sceAjmModuleUnregister",ajm_module_unregister}, + {"sceAjmInstanceCreate",ajm_instance_create}, {"sceAjmInstanceDestroy",ajm_instance_destroy}, + {"sceAjmInstanceCodecType",ajm_instance_codec}, + {"sceAjmBatchJobControlBufferRa",job_control}, {"sceAjmBatchJobRunBufferRa",job_run}, + {"sceAjmBatchJobRunSplitBufferRa",job_run_split}, {"sceAjmBatchJobInlineBuffer",job_inline}, + {"sceAjmBatchStartBuffer",ajm_batch_start}, {"sceAjmBatchWait",ajm_batch_wait}, + {"sceAjmBatchCancel",ajm_batch_cancel}, {"sceAjmBatchErrorDump",ajm_error_dump}, + {"sceAjmMemoryRegister",ajm_memory_register}, +}; +uintptr_t runtime_ajm_resolve(const char *name) { return RUNTIME_LOOKUP(exports,name); } +void runtime_ajm_report(void) { + printf("Runtime: Ajm batches=%zu, jobs=%zu, ATRAC9 frames decoded=%zu\n",batches_run,jobs_run,frames_decoded); +} diff --git a/runtime_audio.c b/runtime_audio.c new file mode 100644 index 0000000..591c62c --- /dev/null +++ b/runtime_audio.c @@ -0,0 +1,265 @@ +/* libSceAudioOut on SDL3 audio streams. sceAudioOutOutput returns once per + * buffer period on a steady clock, like PS4 hardware: FMOD's output thread + * reads 256-frame slots out of its mixer's 512-frame ring, and returning in + * bursts (whenever the device pulls a quantum) lets it overtake the mixer and + * play stale halves - a click every 10.7 ms. The lowest SDL queue level of + * each window is steered to two buffers (silence prefill on underrun, ±3% + * cadence corrections), which also absorbs device clock drift. Without an audio device (headless runs, BB_AUDIO=none) + * ports only follow the clock. */ +#define _GNU_SOURCE +#include "runtime.h" +#include +#include +#include +#include +#include +#include + +#define PORTS 25 +#define ERR_NOT_OPENED ((int32_t)0x80260001) +#define ERR_INVALID_PORT ((int32_t)0x80260003) +#define ERR_INVALID_POINTER ((int32_t)0x80260004) +#define ERR_PORT_FULL ((int32_t)0x80260005) +#define ERR_INVALID_SIZE ((int32_t)0x80260006) +#define ERR_INVALID_FORMAT ((int32_t)0x80260007) +#define ERR_INVALID_FREQ ((int32_t)0x80260008) +#define ERR_INVALID_VOLUME ((int32_t)0x80260009) +#define ERR_INVALID_TYPE ((int32_t)0x8026000A) +#define ERR_ALREADY_INIT ((int32_t)0x8026000E) +#define ERR_NOT_INIT ((int32_t)0x8026000F) +#define VOLUME_0DB 32768 + +typedef struct { + int used, type, channels, is_float, frames, sample_bytes, std_layout; + int32_t volume[8]; + SDL_AudioStream *stream; + uint64_t next_deadline_ns; /* next return of sceAudioOutOutput */ + int64_t adjust_ns; int window_min, window_count; /* queue level control */ + uint64_t last_output_us; + pthread_mutex_t lock; + FILE *dump; /* BB_AUDIO_DUMP: raw converted PCM per port */ + int stats; + uint64_t stat_start_ns, stat_last_ns, stat_max_gap_ns; /* BB_AUDIO_STATS */ + unsigned stat_starved, stat_buffers; int stat_min_queued; +} Port; +typedef struct { uint16_t output; uint8_t channel, reserved; int16_t volume; uint16_t reroute; uint64_t flag, reserved64[2]; } PortState; +_Static_assert(sizeof(PortState)==32,"AudioOut port state layout"); + +static pthread_mutex_t table_lock=PTHREAD_MUTEX_INITIALIZER; +static Port ports[PORTS]; +static int initialized, sdl_ready=-1; +static size_t buffers_out, ports_opened; + +static uint64_t now_ns(void) { struct timespec t; clock_gettime(CLOCK_MONOTONIC,&t); return (uint64_t)t.tv_sec*1000000000u+(uint64_t)t.tv_nsec; } +static void sleep_until(uint64_t deadline) { + struct timespec t={(time_t)(deadline/1000000000u),(long)(deadline%1000000000u)}; + while (clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&t,NULL)) {} +} +static int sdl_audio(void) { + if (sdl_ready<0) { + const char *mode=getenv("BB_AUDIO"); + sdl_ready = (!mode || strcmp(mode,"none")) && SDL_InitSubSystem(SDL_INIT_AUDIO); + printf("Runtime: audio backend %s\n", sdl_ready ? SDL_GetCurrentAudioDriver() : "timer (silent)"); + } + return sdl_ready; +} +static int port_range(int type, int *first, int *last) { + switch (type) { + case 0: *first=0; *last=7; return 1; /* main */ + case 1: *first=8; *last=8; return 1; /* bgm */ + case 2: *first=9; *last=12; return 1; /* voice */ + case 3: *first=13; *last=16; return 1; /* personal */ + case 4: *first=17; *last=20; return 1; /* pad speaker */ + case 126: *first=21; *last=22; return 1; /* audio3d */ + case 127: *first=23; *last=24; return 1; /* aux */ + default: return 0; + } +} +static Port *port_of(int32_t handle, int32_t *error) { + int id=handle & 0xff; + if ((handle & 0x3f000000)!=0x20000000 || id>=PORTS) { *error=ERR_INVALID_PORT; return NULL; } + if (!ports[id].used) { *error=ERR_NOT_OPENED; return NULL; } + return &ports[id]; +} + +static ABI int32_t audio_init(void) { + pthread_mutex_lock(&table_lock); + int32_t r=initialized ? ERR_ALREADY_INIT : 0; + initialized=1; + pthread_mutex_unlock(&table_lock); + return r; +} +static ABI int32_t audio_open(int32_t user, int32_t type, int32_t index, uint32_t length, uint32_t freq, uint32_t param) { + (void)user; (void)index; + if (!initialized) return ERR_NOT_INIT; + if (!length || length>2048 || (length & 0xff)) return ERR_INVALID_SIZE; + if (freq!=48000) return ERR_INVALID_FREQ; + uint32_t format=param & 0xff; + if (format>7) return ERR_INVALID_FORMAT; + int first, last; + if (!port_range(type,&first,&last)) return ERR_INVALID_TYPE; + static const int channels[8]={1,2,8,1,2,8,8,8}; + pthread_mutex_lock(&table_lock); + int id=-1; + for (int i=first;i<=last;++i) if (!ports[i].used) { id=i; break; } + if (id<0) { pthread_mutex_unlock(&table_lock); return ERR_PORT_FULL; } + Port *p=&ports[id]; + memset(p,0,sizeof(*p)); + pthread_mutex_init(&p->lock,NULL); + p->used=1; p->type=type; p->channels=channels[format]; p->is_float=format>=3 && format!=6; + p->sample_bytes=p->is_float ? 4 : 2; p->frames=(int)length; p->std_layout=format>=6; + for (int c=0;c<8;++c) p->volume[c]=VOLUME_0DB; + if (sdl_audio()) { + SDL_AudioSpec spec={p->is_float ? SDL_AUDIO_F32 : SDL_AUDIO_S16, p->channels, 48000}; + p->stream=SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK,&spec,NULL,NULL); + if (p->stream) SDL_ResumeAudioStreamDevice(p->stream); + else fprintf(stderr,"Runtime: SDL audio stream failed (%s); port %d uses the timer sink\n",SDL_GetError(),id); + } + p->stats=getenv("BB_AUDIO_STATS")!=NULL; + const char *dump=getenv("BB_AUDIO_DUMP"); + if (dump) { + char path[4096]; + snprintf(path,sizeof(path),"%s.port%d.%dch.%s",dump,id,p->channels,p->is_float ? "f32" : "s16"); + p->dump=fopen(path,"wb"); + } + ++ports_opened; + pthread_mutex_unlock(&table_lock); + printf("Runtime: audio port %d opened (type %d, %d ch, %s, %u frames)\n",id,type,p->channels,p->is_float ? "float" : "s16",length); + return (type<<16) | id | 0x20000000; +} +static ABI int32_t audio_close(int32_t handle) { + pthread_mutex_lock(&table_lock); + int32_t error=0; + Port *p=port_of(handle,&error); + if (p) { + pthread_mutex_lock(&p->lock); + if (p->stream) SDL_DestroyAudioStream(p->stream); + if (p->dump) fclose(p->dump); + p->dump=NULL; + p->stream=NULL; p->used=0; + pthread_mutex_unlock(&p->lock); + } + pthread_mutex_unlock(&table_lock); + return p ? 0 : error; +} +static ABI int32_t audio_output(int32_t handle, const void *data) { + int32_t error=0; + pthread_mutex_lock(&table_lock); + Port *p=port_of(handle,&error); + pthread_mutex_unlock(&table_lock); + if (!p) return error; + pthread_mutex_lock(&p->lock); + size_t samples=(size_t)p->frames*(size_t)p->channels, bytes=samples*(size_t)p->sample_bytes; + uint64_t period=(uint64_t)p->frames*1000000000u/48000u; + if (data) { + /* Apply per-channel volume and map PS4 8ch (L R C LFE SL SR BL BR) to SDL 7.1 order. */ + unsigned char converted[2048*8*4]; + static const int remap[8]={0,1,2,3,6,7,4,5}; + for (size_t f=0;f<(size_t)p->frames;++f) for (int c=0;cchannels;++c) { + int target=p->channels==8 && !p->std_layout ? remap[c] : c; + size_t from=f*(size_t)p->channels+(size_t)c, to=f*(size_t)p->channels+(size_t)target; + float gain=(float)p->volume[c]/VOLUME_0DB; + if (p->is_float) { float v; memcpy(&v,(const char *)data+from*4,4); v*=gain; memcpy(converted+to*4,&v,4); } + else { int16_t v; memcpy(&v,(const char *)data+from*2,2); v=(int16_t)((float)v*gain); memcpy(converted+to*2,&v,2); } + } + if (p->dump) fwrite(converted,1,bytes,p->dump); + if (p->stats) { + uint64_t now=now_ns(); + if (!p->stat_start_ns) { p->stat_start_ns=now; p->stat_min_queued=1<<30; } + else if (now-p->stat_last_ns>p->stat_max_gap_ns) p->stat_max_gap_ns=now-p->stat_last_ns; + p->stat_last_ns=now; ++p->stat_buffers; + if (p->stream) { + int queued=SDL_GetAudioStreamQueued(p->stream); + if (queuedstat_min_queued) p->stat_min_queued=queued; + if (queued==0) ++p->stat_starved; + } + if (now-p->stat_start_ns>=5000000000u) { + printf("Audio stats port %d: %u buffers/5s (expected %u), max gap %.2f ms, min queued %d bytes, starved %u\n", + (int)(p-ports),p->stat_buffers,(unsigned)(5u*48000u/(unsigned)p->frames),p->stat_max_gap_ns/1e6, + p->stat_min_queued,p->stat_starved); + p->stat_start_ns=now; p->stat_max_gap_ns=0; p->stat_starved=0; p->stat_buffers=0; p->stat_min_queued=1<<30; + } + } + uint64_t now=now_ns(); + if (!p->next_deadline_ns || now>p->next_deadline_ns+8*period) p->next_deadline_ns=now; /* start or stall: restart cadence */ + else sleep_until(p->next_deadline_ns); + p->next_deadline_ns+=period; + if (p->stream) { + /* The device drains the queue in quanta (21 ms on PipeWire), so the level + is a sawtooth: its minimum over ~32 buffers is what gets controlled. */ + int low=2*(int)bytes, queued=SDL_GetAudioStreamQueued(p->stream); + if (queued<(int)bytes) { + static const unsigned char silence[2048*8*4]; + SDL_PutAudioStreamData(p->stream,silence,low-queued<(int)bytes ? low-queued : (int)bytes); + queued=low; + } + if (!p->window_count || queuedwindow_min) p->window_min=queued; + if (++p->window_count==32) { + p->adjust_ns=p->window_min>low+2*(int)bytes ? (int64_t)(period/32) : p->window_minwindow_count=0; + } + p->next_deadline_ns+=(uint64_t)p->adjust_ns; + SDL_PutAudioStreamData(p->stream,converted,(int)bytes); + } + ++buffers_out; + } + p->last_output_us=now_ns()/1000; + pthread_mutex_unlock(&p->lock); + return data ? (int32_t)samples : 0; +} +typedef struct { int32_t handle; const void *data; } OutputParam; +static ABI int32_t audio_outputs(const OutputParam *params, uint32_t count) { + if (!params) return ERR_INVALID_POINTER; + if (!count || count>PORTS) return ERR_PORT_FULL; + int32_t result=0; + for (uint32_t i=0;ilock); + for (int c=0;c<8;++c) if (flags & (1<VOLUME_0DB) { pthread_mutex_unlock(&p->lock); return ERR_INVALID_VOLUME; } + p->volume[c]=volume[c]; + } + pthread_mutex_unlock(&p->lock); + return 0; +} +static ABI int32_t audio_state(int32_t handle, PortState *state) { + int32_t error=0; + pthread_mutex_lock(&table_lock); + Port *p=port_of(handle,&error); + pthread_mutex_unlock(&table_lock); + if (!p) return error; + if (!state) return ERR_INVALID_POINTER; + memset(state,0,sizeof(*state)); + switch (p->type) { + case 2: case 3: state->output=0x40; state->channel=1; break; /* headphone */ + case 4: state->output=0x04; state->channel=1; state->volume=127; break; /* pad speaker */ + default: state->output=0x01; state->channel=(uint8_t)(p->channels>2 ? 2 : p->channels); break; + } + return 0; +} +static ABI int32_t audio_last_time(int32_t handle, uint64_t *time) { + int32_t error=0; + pthread_mutex_lock(&table_lock); + Port *p=port_of(handle,&error); + pthread_mutex_unlock(&table_lock); + if (!p) return error; + if (!time) return ERR_INVALID_POINTER; + *time=p->last_output_us; return 0; +} + +static const RuntimeExport exports[]={ + {"sceAudioOutInit",audio_init}, {"sceAudioOutOpen",audio_open}, {"sceAudioOutClose",audio_close}, + {"sceAudioOutOutput",audio_output}, {"sceAudioOutOutputs",audio_outputs}, + {"sceAudioOutSetVolume",audio_volume}, {"sceAudioOutGetPortState",audio_state}, + {"sceAudioOutGetLastOutputTime",audio_last_time}, +}; +uintptr_t runtime_audio_resolve(const char *name) { return RUNTIME_LOOKUP(exports,name); } +void runtime_audio_report(void) { printf("Runtime: audio ports opened=%zu, buffers output=%zu\n",ports_opened,buffers_out); } diff --git a/runtime_content.c b/runtime_content.c new file mode 100644 index 0000000..59a683b --- /dev/null +++ b/runtime_content.c @@ -0,0 +1,91 @@ +/* Offline AppContent provider for the configured base-game profile. + * No package/DLC mounting, downloads, entitlement or license emulation. */ +#include "runtime.h" +#include +#include +#include +#define INVALID_ID ((int32_t)0x805a1000) +#define NOT_LOADED ((int32_t)0x805a1001) +#define PARAMETER ((int32_t)0x80d90002) +#define BUSY ((int32_t)0x80d90003) +static unsigned refs, initialized, configured; +static uint32_t parameters[5]; +static unsigned queries, lists; +void runtime_content_configure(const uint32_t values[5]) { + if (refs || initialized || (values[0]!=1 && values[0]!=3)) { + fputs("ERROR: invalid or late content profile\n",stderr); exit(1); + } + memcpy(parameters,values,sizeof(parameters)); configured=1; +} +static void require_provider(void) { + if (!configured) { fputs("STOP: AppContent needs --content-profile\n",stderr); exit(21); } +} +/* System modules: every library this eboot imports is provided by the host + * runtime, so loading one only tracks a reference count. AppContent (0xb4) + * additionally requires the configured content profile. */ +static unsigned module_refs[0x10000]; +static ABI int32_t module_load(uint16_t id) { + if (!id) return INVALID_ID; + if (id==0xb4) require_provider(); + if (module_refs[id]==UINT32_MAX) { fputs("STOP: module reference overflow\n",stderr); exit(21); } + ++module_refs[id]; + if (id==0xb4) { refs=module_refs[id]; printf("Runtime: AppContent host provider loaded; references=%u\n",refs); } + else printf("Runtime: system module 0x%x loaded (host implementation)\n",id); + return 0; +} +static ABI int32_t module_loaded(uint16_t id) { + if (!id) return INVALID_ID; + return module_refs[id] ? 0 : NOT_LOADED; +} +static ABI int32_t module_unload(uint16_t id) { + int32_t result=module_loaded(id); + if (result) return result; + --module_refs[id]; + if (id==0xb4) { refs=module_refs[id]; if (!refs) initialized=0; } + return 0; +} +static void require_loaded(void) { + require_provider(); + if (!refs) { fputs("STOP: AppContent called before module load\n",stderr); exit(21); } +} +static ABI int32_t content_init(const unsigned char *init,unsigned char *boot) { + require_loaded(); + if (!init || !boot) return PARAMETER; + if (initialized) return BUSY; + /* Only the reserved-zero init profile is implemented. */ + for (unsigned i=0;i<32;++i) if (init[i]) return PARAMETER; + memset(boot,0,40); initialized=1; + puts("Runtime: AppContent initialized; offline base-game profile, no mounted add-ons"); + return 0; +} +static void require_initialized(void) { + require_loaded(); + if (!initialized) { fputs("STOP: AppContent query before initialization\n",stderr); exit(21); } +} +static ABI int32_t param_int(uint32_t id,int32_t *out) { + require_initialized(); + if (id>4 || !out) return PARAMETER; + memcpy(out,¶meters[id],4); ++queries; + printf("Runtime: AppContent parameter %u = %d\n",id,*out); + return 0; +} +static ABI int32_t addon_list(uint32_t service,void *list,uint32_t capacity,uint32_t *hits) { + require_initialized(); + if (service) { fputs("STOP: nonzero AppContent service label unsupported\n",stderr); exit(21); } + if ((!capacity || !list) && !hits) return PARAMETER; + /* No add-ons are mounted by this provider. Never touch unused list slots. */ + if (hits) *hits=0; + ++lists; return 0; +} +uintptr_t runtime_content_resolve(const char *name) { + if (!strcmp(name,"g8cM39EUZ6o#M#N")) return (uintptr_t)module_load; + if (!strcmp(name,"fMP5NHUOaMk#M#N")) return (uintptr_t)module_loaded; + if (!strcmp(name,"eR2bZFAAU0Q#M#N")) return (uintptr_t)module_unload; + if (!strcmp(name,"R9lA82OraNs#c#d")) return (uintptr_t)content_init; + if (!strcmp(name,"99b82IKXpH4#c#d")) return (uintptr_t)param_int; + if (!strcmp(name,"xnd8BJzAxmk#c#d")) return (uintptr_t)addon_list; + return 0; +} +void runtime_content_report(void) { + printf("Runtime: AppContent references=%u, initialized=%u, parameter queries=%u, list queries=%u\n",refs,initialized,queries,lists); +} diff --git a/runtime_file.c b/runtime_file.c new file mode 100644 index 0000000..0c217da --- /dev/null +++ b/runtime_file.c @@ -0,0 +1,381 @@ +/* Guest file system: PS4 mount points mapped onto host directories. + * /app0, /hostapp -> game package root (read-only by convention) + * /temp0, /download0, /data, and mounts added by SaveData -> user directory + * Guest descriptors are small integers in our own table; stdio 0-2 pass through. + * Paths containing ".." components are rejected rather than normalized. */ +#define _GNU_SOURCE +#include "runtime.h" +#include +#include +#include +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#define ERR(n) ((int32_t)(UINT32_C(0x80020000)|(n))) +#define MAX_FILES 1024 +#define MAX_MOUNTS 16 + +typedef struct { int64_t sec, nsec; } GuestTimespec; +typedef struct { + uint32_t dev, ino; + uint16_t mode, nlink; + uint32_t uid, gid, rdev; + GuestTimespec atime, mtime, ctime; + int64_t size, blocks; + uint32_t blksize, flags, gen; + int32_t lspare; + GuestTimespec birthtime; +} GuestStat; +_Static_assert(sizeof(GuestStat)==120,"FreeBSD stat layout"); + +typedef struct { char *names; size_t count, *offsets; unsigned char *types; } Listing; +typedef struct { int used, host; Listing *dir; size_t position; char path[512]; } File; +typedef struct { char guest[64]; char host[512]; } Mount; +static File files[MAX_FILES]; +static Mount mounts[MAX_MOUNTS]; +static size_t mount_count, opens, reads, writes, missing; +static uint64_t bytes_read; +static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; + +int runtime_file_mount(const char *guest,const char *host) { + pthread_mutex_lock(&lock); + for (size_t i=0;i=64 || strlen(host)>=512) { pthread_mutex_unlock(&lock); return -1; } + snprintf(mounts[mount_count].guest,64,"%s",guest); + snprintf(mounts[mount_count].host,512,"%s",host); + ++mount_count; + pthread_mutex_unlock(&lock); + return 0; +} +void runtime_file_unmount(const char *guest) { + pthread_mutex_lock(&lock); + for (size_t i=0;ibest) { best=n; m=&mounts[i]; } + } + int result=0; + if (!m) result=ENOENT; + else if ((size_t)snprintf(out,size,"%s%s",m->host,buffer+best)>=size) result=ENAMETOOLONG; + pthread_mutex_unlock(&lock); + if (result==ENOENT) fprintf(stderr,"Runtime: no mount for guest path %s\n",guest); + return result; +} +static int host_flags(int flags) { + int r; + switch (flags&3) { case 0: r=O_RDONLY; break; case 1: r=O_WRONLY; break; default: r=O_RDWR; } + if (flags&0x4) r|=O_NONBLOCK; + if (flags&0x8) r|=O_APPEND; + if (flags&0x80) r|=O_SYNC; + if (flags&0x200) r|=O_CREAT; + if (flags&0x400) r|=O_TRUNC; + if (flags&0x800) r|=O_EXCL; + if (flags&0x20000) r|=O_DIRECTORY; + return r|O_CLOEXEC; +} +static void free_listing(Listing *l) { if (l) { free(l->names); free(l->offsets); free(l->types); free(l); } } +static Listing *list_directory(const char *path) { + DIR *d=opendir(path); + if (!d) return NULL; + Listing *l=calloc(1,sizeof(*l)); + size_t capacity=0,bytes=0,cap_names=0; + struct dirent *e; + while (l && (e=readdir(d))) { + size_t n=strlen(e->d_name)+1; + if (l->count==capacity) { + capacity=capacity ? capacity*2 : 64; + l->offsets=realloc(l->offsets,capacity*sizeof(size_t)); + l->types=realloc(l->types,capacity); + } + if (bytes+n>cap_names) { cap_names=(bytes+n)*2; l->names=realloc(l->names,cap_names); } + if (!l->offsets || !l->types || !l->names) { fputs("Out of memory listing directory\n",stderr); exit(1); } + memcpy(l->names+bytes,e->d_name,n); + l->offsets[l->count]=bytes; + l->types[l->count]=e->d_type==DT_DIR ? 4 : e->d_type==DT_REG ? 8 : e->d_type==DT_LNK ? 10 : 0; + ++l->count; bytes+=n; + } + closedir(d); + return l; +} +static void convert_stat(const struct stat *s,GuestStat *g) { + memset(g,0,sizeof(*g)); + g->dev=(uint32_t)s->st_dev; g->ino=(uint32_t)s->st_ino; + g->mode=(uint16_t)s->st_mode; g->nlink=(uint16_t)s->st_nlink; + g->size=s->st_size; g->blocks=s->st_blocks; g->blksize=(uint32_t)s->st_blksize; + g->atime=(GuestTimespec){s->st_atim.tv_sec,s->st_atim.tv_nsec}; + g->mtime=(GuestTimespec){s->st_mtim.tv_sec,s->st_mtim.tv_nsec}; + g->ctime=(GuestTimespec){s->st_ctim.tv_sec,s->st_ctim.tv_nsec}; + g->birthtime=g->ctime; +} +static File *get(int fd) { + if (fd<3 || fd>=MAX_FILES || !files[fd].used) return NULL; + return &files[fd]; +} +/* All operations return >=0 or -(host errno); wrappers adapt the convention. */ +static int64_t do_open(const char *guest,int flags,int mode) { + char path[1024]; + int e=translate(guest,path,sizeof(path)); + if (e) return -e; + int host=open(path,host_flags(flags),mode ? mode : 0644); + if (host<0) { + e=errno; + if (e==ENOENT) { ++missing; printf("Runtime: open(%s) -> not found\n",guest); } + return -e; + } + struct stat s; + Listing *dir=NULL; + if (!fstat(host,&s) && S_ISDIR(s.st_mode)) dir=list_directory(path); + pthread_mutex_lock(&lock); + int fd=-1; + for (int i=3;i=0 && fd<3) return 0; + pthread_mutex_lock(&lock); + File *f=get(fd); + if (!f) { pthread_mutex_unlock(&lock); return -EBADF; } + close(f->host); free_listing(f->dir); + *f=(File){0}; + pthread_mutex_unlock(&lock); + return 0; +} +static int host_fd(int fd) { + if (fd>=0 && fd<3) return fd; + File *f=get(fd); + return f ? f->host : -1; +} +static int64_t do_read(int fd,void *buffer,uint64_t size) { + int h=host_fd(fd); + if (h<0) return -EBADF; + ssize_t n=read(h,buffer,size); + if (n<0) return -errno; + __atomic_add_fetch(&reads,1,__ATOMIC_RELAXED); __atomic_add_fetch(&bytes_read,(uint64_t)n,__ATOMIC_RELAXED); + return n; +} +static int64_t do_pread(int fd,void *buffer,uint64_t size,int64_t offset) { + int h=host_fd(fd); + if (h<0) return -EBADF; + ssize_t n=pread(h,buffer,size,offset); + if (n<0) return -errno; + __atomic_add_fetch(&reads,1,__ATOMIC_RELAXED); __atomic_add_fetch(&bytes_read,(uint64_t)n,__ATOMIC_RELAXED); + return n; +} +static int64_t do_write(int fd,const void *buffer,uint64_t size) { + int h=host_fd(fd); + if (h<0) return -EBADF; + ssize_t n=write(h,buffer,size); + if (n<0) return -errno; + __atomic_add_fetch(&writes,1,__ATOMIC_RELAXED); + return n; +} +static int64_t do_pwrite(int fd,const void *buffer,uint64_t size,int64_t offset) { + int h=host_fd(fd); + if (h<0) return -EBADF; + ssize_t n=pwrite(h,buffer,size,offset); + return n<0 ? -errno : n; +} +static int64_t do_lseek(int fd,int64_t offset,int whence) { + File *f=get(fd); + if (!f) return -EBADF; + if (whence<0 || whence>2) return -EINVAL; + if (f->dir) { + /* Directory offsets are entry indices for getdirentries. */ + if (whence==0 && offset>=0) { f->position=(size_t)offset; return offset; } + return -EINVAL; + } + off_t r=lseek(f->host,offset,whence); + return r<0 ? -errno : r; +} +static int64_t do_fstat(int fd,GuestStat *out) { + int h=host_fd(fd); + if (h<0) return -EBADF; + if (!out) return -EFAULT; + struct stat s; + if (fstat(h,&s)) return -errno; + convert_stat(&s,out); return 0; +} +static int64_t do_stat(const char *guest,GuestStat *out) { + char path[1024]; struct stat s; + int e=translate(guest,path,sizeof(path)); + if (e) return -e; + if (!out) return -EFAULT; + if (stat(path,&s)) return -errno; + convert_stat(&s,out); return 0; +} +static int64_t do_getdents(int fd,char *buffer,uint64_t size,int64_t *basep) { + pthread_mutex_lock(&lock); + File *f=get(fd); + int64_t result=0; + if (!f) result=-EBADF; + else if (!f->dir) result=-EINVAL; + else if (!buffer) result=-EFAULT; + else if (size<512) result=-EINVAL; + else { + if (basep) *basep=(int64_t)f->position; + uint64_t written=0; + while (f->positiondir->count) { + const char *name=f->dir->names+f->dir->offsets[f->position]; + size_t n=strlen(name); if (n>255) n=255; + uint16_t reclen=(uint16_t)((8+n+1+7)&~(size_t)7); + if (written+reclen>size) break; + char *p=buffer+written; + memset(p,0,reclen); + uint32_t ino=(uint32_t)f->position+1; + memcpy(p,&ino,4); memcpy(p+4,&reclen,2); + p[6]=(char)f->dir->types[f->position]; p[7]=(char)n; + memcpy(p+8,name,n); + written+=reclen; ++f->position; + } + result=(int64_t)written; + } + pthread_mutex_unlock(&lock); + return result; +} +static int64_t path_op(const char *guest,int op,int mode) { + char path[1024]; + int e=translate(guest,path,sizeof(path)); + if (e) return -e; + int r= op==0 ? mkdir(path,mode ? mode : 0755) : op==1 ? rmdir(path) : unlink(path); + return r ? -errno : 0; +} +static int64_t do_rename(const char *from,const char *to) { + char a[1024],b[1024]; + int e=translate(from,a,sizeof(a)); + if (!e) e=translate(to,b,sizeof(b)); + if (e) return -e; + return rename(a,b) ? -errno : 0; +} +static int64_t do_ftruncate(int fd,int64_t length) { + int h=host_fd(fd); + if (h<0) return -EBADF; + return ftruncate(h,length) ? -errno : 0; +} +static int64_t do_truncate(const char *guest,int64_t length) { + char path[1024]; + int e=translate(guest,path,sizeof(path)); + if (e) return -e; + return truncate(path,length) ? -errno : 0; +} +static int64_t do_fsync(int fd) { int h=host_fd(fd); if (h<0) return -EBADF; return fsync(h) ? -errno : 0; } +static int64_t do_access(const char *guest,int mode) { + char path[1024]; + int e=translate(guest,path,sizeof(path)); + if (e) return -e; + return access(path,mode&7) ? -errno : 0; +} + +/* Convention adapters: sceKernel* -> Orbis error codes, POSIX -> -1 + errno. */ +static int64_t sce(int64_t r) { return r<0 ? ERR(runtime_guest_errno((int)-r)) : r; } +static int64_t posix(int64_t r) { if (r<0) { *runtime_errno()=runtime_guest_errno((int)-r); return -1; } return r; } +#define PAIR(name,params,args) \ + static ABI int64_t sce_##name params { return sce(do_##name args); } \ + static ABI int64_t posix_##name params { return posix(do_##name args); } +PAIR(open,(const char *p,int f,int m),(p,f,m)) +PAIR(close,(int fd),(fd)) +PAIR(read,(int fd,void *b,uint64_t n),(fd,b,n)) +PAIR(pread,(int fd,void *b,uint64_t n,int64_t o),(fd,b,n,o)) +PAIR(write,(int fd,const void *b,uint64_t n),(fd,b,n)) +PAIR(pwrite,(int fd,const void *b,uint64_t n,int64_t o),(fd,b,n,o)) +PAIR(lseek,(int fd,int64_t o,int w),(fd,o,w)) +PAIR(fstat,(int fd,GuestStat *s),(fd,s)) +PAIR(stat,(const char *p,GuestStat *s),(p,s)) +PAIR(getdents,(int fd,char *b,uint64_t n,int64_t *base),(fd,b,n,base)) +PAIR(rename,(const char *a,const char *b),(a,b)) +PAIR(ftruncate,(int fd,int64_t l),(fd,l)) +PAIR(truncate,(const char *p,int64_t l),(p,l)) +PAIR(fsync,(int fd),(fd)) +static ABI int64_t posix_access(const char *p,int m) { return posix(do_access(p,m)); } +static ABI int64_t sce_mkdir(const char *p,int m) { return sce(path_op(p,0,m)); } +static ABI int64_t posix_mkdir(const char *p,int m) { return posix(path_op(p,0,m)); } +static ABI int64_t sce_rmdir(const char *p) { return sce(path_op(p,1,0)); } +static ABI int64_t posix_rmdir(const char *p) { return posix(path_op(p,1,0)); } +static ABI int64_t sce_unlink(const char *p) { return sce(path_op(p,2,0)); } +static ABI int64_t posix_unlink(const char *p) { return posix(path_op(p,2,0)); } +static ABI int32_t sce_check_reachability(const char *p) { + GuestStat s; return (int32_t)sce(do_stat(p,&s)); +} + +static const RuntimeExport exports[]={ + {"sceKernelOpen",sce_open}, {"open",posix_open}, {"_open",posix_open}, + {"sceKernelClose",sce_close}, {"close",posix_close}, {"_close",posix_close}, + {"sceKernelRead",sce_read}, {"read",posix_read}, {"_read",posix_read}, + {"sceKernelPread",sce_pread}, {"pread",posix_pread}, + {"sceKernelWrite",sce_write}, {"write",posix_write}, {"_write",posix_write}, + {"sceKernelPwrite",sce_pwrite}, {"pwrite",posix_pwrite}, + {"sceKernelLseek",sce_lseek}, {"lseek",posix_lseek}, + {"sceKernelFstat",sce_fstat}, {"fstat",posix_fstat}, + {"sceKernelStat",sce_stat}, {"stat",posix_stat}, + {"sceKernelGetdirentries",sce_getdents}, {"getdirentries",posix_getdents}, + {"sceKernelRename",sce_rename}, {"rename",posix_rename}, + {"sceKernelFtruncate",sce_ftruncate}, {"ftruncate",posix_ftruncate}, + {"sceKernelTruncate",sce_truncate}, {"truncate",posix_truncate}, + {"sceKernelFsync",sce_fsync}, {"fsync",posix_fsync}, + {"access",posix_access}, {"sceKernelCheckReachability",sce_check_reachability}, + {"sceKernelMkdir",sce_mkdir}, {"mkdir",posix_mkdir}, + {"sceKernelRmdir",sce_rmdir}, {"rmdir",posix_rmdir}, + {"sceKernelUnlink",sce_unlink}, {"unlink",posix_unlink}, +}; +uintptr_t runtime_file_resolve(const char *name) { return RUNTIME_LOOKUP(exports,name); } +/* Host-side helpers for other modules (e.g. SaveData, Fios). */ +int64_t runtime_file_open(const char *p,int f,int m) { return do_open(p,f,m); } +int64_t runtime_file_close(int fd) { return do_close(fd); } +int64_t runtime_file_read(int fd,void *b,uint64_t n) { return do_read(fd,b,n); } +int64_t runtime_file_pread(int fd,void *b,uint64_t n,int64_t o) { return do_pread(fd,b,n,o); } +int64_t runtime_file_write(int fd,const void *b,uint64_t n) { return do_write(fd,b,n); } +int64_t runtime_file_lseek(int fd,int64_t o,int w) { return do_lseek(fd,o,w); } +int64_t runtime_file_stat(const char *p,void *s) { return do_stat(p,s); } +int64_t runtime_file_fstat(int fd,void *s) { return do_fstat(fd,s); } +int64_t runtime_file_getdents(int fd,char *b,uint64_t n,int64_t *base) { return do_getdents(fd,b,n,base); } +int runtime_file_translate(const char *guest,char *out,size_t size) { return translate(guest,out,size); } +void runtime_file_report(void) { + printf("Runtime: files opened=%zu, reads=%zu (%llu bytes), writes=%zu, not found=%zu\n", + opens,reads,(unsigned long long)bytes_read,writes,missing); +} +#else +uintptr_t runtime_file_resolve(const char *name) { (void)name; return 0; } +void runtime_file_report(void) {} +void runtime_file_configure(const char *a,const char *u) { (void)a; (void)u; } +#endif diff --git a/runtime_kernel.c b/runtime_kernel.c new file mode 100644 index 0000000..f95414d --- /dev/null +++ b/runtime_kernel.c @@ -0,0 +1,302 @@ +/* libkernel/libScePosix process services: clocks, sleeping, errno mapping, + * pthread once/keys, signal bookkeeping and a narrow sysctl. Guest values + * use FreeBSD numbering; host errno values never reach the guest directly. */ +#define _GNU_SOURCE +#include "runtime.h" +#include +#include +#include +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define ERR(n) ((int32_t)(UINT32_C(0x80020000)|(n))) +#define PAGE 16384 + +typedef struct { int64_t sec, nsec; } GuestTimespec; +typedef struct { int64_t sec, usec; } GuestTimeval; + +int32_t runtime_guest_errno(int e) { + switch (e) { + case 0: return 0; + case EPERM: return 1; case ENOENT: return 2; case ESRCH: return 3; case EINTR: return 4; + case EIO: return 5; case ENXIO: return 6; case E2BIG: return 7; case ENOEXEC: return 8; + case EBADF: return 9; case ECHILD: return 10; case EDEADLK: return 11; case ENOMEM: return 12; + case EACCES: return 13; case EFAULT: return 14; case EBUSY: return 16; case EEXIST: return 17; + case EXDEV: return 18; case ENODEV: return 19; case ENOTDIR: return 20; case EISDIR: return 21; + case EINVAL: return 22; case ENFILE: return 23; case EMFILE: return 24; case ENOTTY: return 25; + case EFBIG: return 27; case ENOSPC: return 28; case ESPIPE: return 29; case EROFS: return 30; + case EMLINK: return 31; case EPIPE: return 32; case ERANGE: return 34; case EAGAIN: return 35; + case ENAMETOOLONG: return 63; case ENOTEMPTY: return 66; case ETIMEDOUT: return 60; + case ELOOP: return 62; case ENOSYS: return 78; case EOVERFLOW: return 84; case ECANCELED: return 85; + default: return 5; /* EIO: unmapped host error */ + } +} +static int32_t fail_posix(int e) { *runtime_errno()=runtime_guest_errno(e); return -1; } + +/* ---- clocks and sleeping ---- */ +static struct timespec process_start; +__attribute__((constructor)) static void remember_start(void) { clock_gettime(CLOCK_MONOTONIC,&process_start); } +static int host_clock(uint32_t id,clockid_t *out) { + switch (id) { + case 0: case 9: case 10: *out=CLOCK_REALTIME; return 1; /* REALTIME(_PRECISE/_FAST) */ + case 4: case 11: case 12: case 5: case 7: case 8: *out=CLOCK_MONOTONIC; return 1; /* MONOTONIC/UPTIME */ + case 13: *out=CLOCK_REALTIME_COARSE; return 1; /* SECOND */ + case 14: *out=CLOCK_THREAD_CPUTIME_ID; return 1; + case 2: case 15: *out=CLOCK_PROCESS_CPUTIME_ID; return 1; /* PROF/PROCTIME */ + case 16: case 17: case 18: case 19: *out=CLOCK_MONOTONIC; return 1; /* PS4 network clocks */ + default: return 0; + } +} +static int clock_read(uint32_t id,GuestTimespec *ts) { + clockid_t host; + if (!ts || !host_clock(id,&host)) return EINVAL; + struct timespec t; + if (clock_gettime(host,&t)) return errno; + if (id==13) t.tv_nsec=0; + ts->sec=t.tv_sec; ts->nsec=t.tv_nsec; return 0; +} +static ABI int32_t kernel_clock_gettime(uint32_t id,GuestTimespec *ts) { + int e=clock_read(id,ts); return e ? ERR(runtime_guest_errno(e)) : 0; +} +static ABI int32_t posix_clock_gettime(uint32_t id,GuestTimespec *ts) { + int e=clock_read(id,ts); return e ? fail_posix(e) : 0; +} +static ABI int32_t posix_clock_getres(uint32_t id,GuestTimespec *ts) { + clockid_t host; struct timespec t; + if (!host_clock(id,&host)) return fail_posix(EINVAL); + if (clock_getres(host,&t)) return fail_posix(errno); + if (ts) { ts->sec=t.tv_sec; ts->nsec=t.tv_nsec; } + return 0; +} +static ABI uint64_t process_time(void) { + struct timespec t; clock_gettime(CLOCK_MONOTONIC,&t); + return (uint64_t)(t.tv_sec-process_start.tv_sec)*1000000+(uint64_t)((t.tv_nsec-process_start.tv_nsec)/1000); +} +static ABI uint64_t process_time_counter(void) { + struct timespec t; clock_gettime(CLOCK_MONOTONIC,&t); + return (uint64_t)(t.tv_sec-process_start.tv_sec)*1000000000+(uint64_t)(t.tv_nsec-process_start.tv_nsec); +} +static ABI uint64_t process_time_frequency(void) { return 1000000000; } +static ABI uint64_t read_tsc(void) { return __rdtsc(); } +static uint64_t tsc_hz; +static ABI uint64_t tsc_frequency(void) { + if (!tsc_hz) { + struct timespec a,b,nap={0,20000000}; + clock_gettime(CLOCK_MONOTONIC,&a); uint64_t t0=__rdtsc(); + nanosleep(&nap,NULL); + clock_gettime(CLOCK_MONOTONIC,&b); uint64_t t1=__rdtsc(); + uint64_t ns=(uint64_t)(b.tv_sec-a.tv_sec)*1000000000+(uint64_t)(b.tv_nsec-a.tv_nsec); + tsc_hz=(t1-t0)*1000000000/(ns ? ns : 1); + } + return tsc_hz; +} +/* Shared with the GPU library so flip/label timestamps use the guest's clock. */ +uint64_t runtime_process_time_us(void) { return process_time(); } +uint64_t runtime_process_time_counter(void) { return process_time_counter(); } +uint64_t runtime_tsc_frequency(void) { return tsc_frequency(); } +static int sleep_ns(uint64_t ns) { + struct timespec t={.tv_sec=(time_t)(ns/1000000000),.tv_nsec=(long)(ns%1000000000)}; + while (nanosleep(&t,&t)) if (errno!=EINTR) return errno; + return 0; +} +static ABI int32_t kernel_usleep(uint32_t usec) { sleep_ns((uint64_t)usec*1000); return 0; } +static ABI int32_t posix_usleep(uint32_t usec) { sleep_ns((uint64_t)usec*1000); return 0; } +static ABI uint32_t posix_sleep(uint32_t seconds) { sleep_ns((uint64_t)seconds*1000000000); return 0; } +static ABI int32_t posix_nanosleep(const GuestTimespec *rq,GuestTimespec *rem) { + if (!rq || rq->nsec<0 || rq->nsec>=1000000000 || rq->sec<0) return fail_posix(EINVAL); + sleep_ns((uint64_t)rq->sec*1000000000+(uint64_t)rq->nsec); + if (rem) { rem->sec=0; rem->nsec=0; } + return 0; +} +static ABI int32_t kernel_nanosleep(const GuestTimespec *rq,GuestTimespec *rem) { + return posix_nanosleep(rq,rem) ? ERR(*runtime_errno()) : 0; +} +typedef struct { int32_t minuteswest, dsttime; } GuestTimezone; +static ABI int32_t kernel_gettimezone(GuestTimezone *tz) { + if (!tz) return ERR(22); + time_t now=time(NULL); struct tm local; localtime_r(&now,&local); + tz->minuteswest=(int32_t)(-local.tm_gmtoff/60); tz->dsttime=0; + return 0; +} +static ABI int32_t posix_gettimeofday(GuestTimeval *tv,GuestTimezone *tz) { + struct timeval t; + gettimeofday(&t,NULL); + if (tv) { tv->sec=t.tv_sec; tv->usec=t.tv_usec; } + if (tz) kernel_gettimezone(tz); + return 0; +} +static ABI int32_t kernel_gettimeofday(GuestTimeval *tv) { + if (!tv) return ERR(22); + return posix_gettimeofday(tv,NULL); +} +static ABI int64_t posix_time(int64_t *out) { int64_t t=(int64_t)time(NULL); if (out) *out=t; return t; } + +/* ---- process ---- */ +static ABI int32_t get_pagesize(void) { return PAGE; } +static ABI int32_t get_pid(void) { return 1000; } +static ABI int32_t yield(void) { sched_yield(); return 0; } +static ABI __attribute__((noreturn)) void hard_exit(int status) { + printf("Runtime: guest requested _exit(%d)\n",status); + runtime_report(); + fflush(stdout); + _exit(status); +} +static ABI __attribute__((noreturn)) void raise_exception(uint32_t code,uint64_t argument) { + fprintf(stderr,"STOP: guest raised debug exception code=0x%x argument=0x%llx\n",code,(unsigned long long)argument); + runtime_report(); + exit(23); +} +static ABI int32_t print_backtrace(void) { + fputs("Runtime: guest requested a backtrace (not available)\n",stderr); + return 0; +} +typedef struct { uint32_t bits[4]; } GuestSigset; +static _Thread_local GuestSigset signal_mask; +static uintptr_t handlers[128]; +static ABI uintptr_t guest_signal(int sig,uintptr_t handler) { + if (sig<=0 || sig>=128) { *runtime_errno()=22; return (uintptr_t)-1; } /* SIG_ERR */ + uintptr_t old=handlers[sig]; handlers[sig]=handler; + printf("Runtime: guest signal(%d) handler recorded (host signals are not forwarded)\n",sig); + return old; +} +static ABI int32_t guest_sigprocmask(int how,const GuestSigset *set,GuestSigset *old) { + if (old) *old=signal_mask; + if (!set) return 0; + for (int i=0;i<4;++i) { + if (how==1) signal_mask.bits[i]|=set->bits[i]; /* SIG_BLOCK */ + else if (how==2) signal_mask.bits[i]&=~set->bits[i]; /* SIG_UNBLOCK */ + else if (how==3) signal_mask.bits[i]=set->bits[i]; /* SIG_SETMASK */ + else return fail_posix(EINVAL); + } + return 0; +} +static ABI int32_t guest_sigfillset(GuestSigset *set) { if (!set) return fail_posix(EINVAL); memset(set,0xff,sizeof(*set)); return 0; } +static ABI int32_t guest_sigemptyset(GuestSigset *set) { if (!set) return fail_posix(EINVAL); memset(set,0,sizeof(*set)); return 0; } +typedef struct { GuestTimeval utime, stime; int64_t rest[14]; } GuestRusage; +static ABI int32_t guest_getrusage(int who,GuestRusage *out) { + struct rusage r; + if (!out || (who!=0 && who!=1)) return fail_posix(EINVAL); + getrusage(who==0 ? RUSAGE_SELF : RUSAGE_THREAD,&r); + memset(out,0,sizeof(*out)); + out->utime=(GuestTimeval){r.ru_utime.tv_sec,r.ru_utime.tv_usec}; + out->stime=(GuestTimeval){r.ru_stime.tv_sec,r.ru_stime.tv_usec}; + return 0; +} +static ABI int32_t guest_sysctl(const int32_t *name,uint32_t namelen,void *old,uint64_t *oldlen,const void *new_value,uint64_t newlen) { + (void)newlen; + if (!name || namelen<2 || new_value) return fail_posix(EINVAL); + if (name[0]==1 && name[1]==37) { /* kern.arandom */ + if (!old || !oldlen) return fail_posix(EINVAL); + if (getrandom(old,(size_t)*oldlen,0)<0) return fail_posix(errno); + return 0; + } + if (name[0]==6 && (name[1]==7 || name[1]==3)) { /* hw.pagesize / hw.ncpu */ + if (!oldlen) return fail_posix(EINVAL); + int32_t value=name[1]==7 ? PAGE : 7; + if (old) { if (*oldlen<4) return fail_posix(ENOMEM); memcpy(old,&value,4); } + *oldlen=4; return 0; + } + fprintf(stderr,"STOP: unsupported sysctl mib"); + for (uint32_t i=0;i=KEYS) return ERR(22); + pthread_mutex_lock(&key_lock); + int32_t r=keys[key].used ? 0 : ERR(22); + keys[key].used=0; keys[key].destructor=NULL; + pthread_mutex_unlock(&key_lock); + return r; +} +static ABI int32_t key_set(uint32_t key,void *value) { + if (!key || key>=KEYS || !keys[key].used) return ERR(22); + key_values[key]=value; return 0; +} +static ABI void *key_get(uint32_t key) { return key && key +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#include +#include +#include +#define POOL_SIZE (UINT64_C(5056) * 1024 * 1024) /* sceKernelGetDirectMemorySize on retail PS4 */ +#define FLEXIBLE_SIZE (UINT64_C(448) * 1024 * 1024) +#define PAGE UINT64_C(16384) +#define USER_MIN UINT64_C(0x1000000000) +#define USER_MAX UINT64_C(0xfc00000000) +#define LIMIT 4096 +#define INVALID ((int32_t)UINT32_C(0x80020016)) +#define NO_MEMORY ((int32_t)UINT32_C(0x8002000c)) +#define ACCESS ((int32_t)UINT32_C(0x8002000d)) +#define NO_SPACE ((int32_t)UINT32_C(0x80020023)) +#define MAP_FIXED_FLAG 0x10 +#define MAP_NO_OVERWRITE 0x80 +enum { KIND_RESERVED=1, KIND_DIRECT, KIND_FLEXIBLE }; +typedef struct { uint64_t start, size; int type, used; } Block; +typedef struct { uintptr_t start, end; int kind, prot, type; uint64_t phys; } Vma; +typedef struct { + uintptr_t start, end; uint64_t offset; int32_t protection, memory_type; + uint32_t flags; char name[32]; +} VirtualQueryInfo; /* flags: flexible, direct, stack, pooled, committed */ +typedef struct { void *start; uint64_t offset, length; int8_t prot, type; int16_t reserved; int32_t operation; } BatchEntry; +_Static_assert(sizeof(VirtualQueryInfo)==72,"PS4 virtual query info layout"); +_Static_assert(sizeof(BatchEntry)==32,"PS4 batch map entry layout"); + +/* Region table lock. Lookups (GPU per-draw queries, VirtualQuery, GPU page + * protection) share it; map/unmap/protect take it exclusively. Both nest: code + * under the lock may write guest memory, and a GPU-tracked page then faults into + * runtime_memory_gpu_protect on the same thread. Readers nest because glibc's + * default rwlock prefers readers; a thread holding it exclusively skips relocking. */ +static pthread_rwlock_t lock=PTHREAD_RWLOCK_INITIALIZER; +static __thread unsigned exclusive_depth; +/* Odd while a writer holds the lock; readers' region caches are valid for one even value. */ +static uint64_t table_generation; +static void write_lock(void) { + if (!exclusive_depth++) { pthread_rwlock_wrlock(&lock); __atomic_add_fetch(&table_generation,1,__ATOMIC_ACQ_REL); } +} +static void write_unlock(void) { + if (!--exclusive_depth) { __atomic_add_fetch(&table_generation,1,__ATOMIC_RELEASE); pthread_rwlock_unlock(&lock); } +} +static void read_lock(void) { if (!exclusive_depth) pthread_rwlock_rdlock(&lock); } +static void read_unlock(void) { if (!exclusive_depth) pthread_rwlock_unlock(&lock); } +static Block blocks[LIMIT]; +static Vma *vmas; static size_t vma_count, vma_capacity; +static int pool_fd=-1; +static unsigned char *backing_base; /* second view of the pool: host writes bypass guest/GPU page protection */ +#define FLEX_SPAN (UINT64_C(1024) * 1024 * 1024) +static uint64_t flex_bitmap[FLEX_SPAN/PAGE/64]; +/* GPU hooks (bbgpu): notified outside the lock, in order, after each operation. */ +typedef void (*GpuRange)(uintptr_t address, uint64_t size); +static GpuRange hook_map, hook_unmap, hook_invalidate; +enum { HOOK_MAP, HOOK_UNMAP, HOOK_INVALIDATE }; +typedef struct { int kind; uintptr_t address; uint64_t size; } PendingHook; +static PendingHook pending[64]; static size_t pending_count; +static size_t allocations, maps, flexible_maps, protects, queries; +static uint64_t live_bytes, flexible_bytes; + +static int valid_alignment(uint64_t a) { return a >= PAGE && a <= POOL_SIZE && !(a & (a-1)); } +static uint64_t align_up(uint64_t n, uint64_t a) { return (n+a-1) & ~(a-1); } +static int host_prot(int prot) { + /* GPU read/write bits (0x10/0x20) need host access for the future GPU backend. */ + return ((prot & 0x11) ? PROT_READ : 0) | ((prot & 0x22) ? PROT_WRITE|PROT_READ : 0) | ((prot & 4) ? PROT_EXEC|PROT_READ : 0); +} +/* Direct memory occupies [0,POOL_SIZE) of the memfd, flexible memory [POOL_SIZE,+FLEX_SPAN). */ +static int pool(void) { + if (pool_fd>=0) return 0; + pool_fd=memfd_create("bb-guest-memory", MFD_CLOEXEC); + if (pool_fd<0 || ftruncate(pool_fd,(off_t)(POOL_SIZE+FLEX_SPAN))) return -1; + void *view=mmap(NULL,POOL_SIZE+FLEX_SPAN,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_NORESERVE,pool_fd,0); + if (view==MAP_FAILED) return -1; + backing_base=view; + return 0; +} +static void queue_hook(int kind, uintptr_t address, uint64_t size) { + GpuRange hook = kind==HOOK_MAP ? hook_map : kind==HOOK_UNMAP ? hook_unmap : hook_invalidate; + if (!hook) return; + if (pending_count==sizeof(pending)/sizeof(*pending)) { fputs("STOP: GPU hook queue overflow\n",stderr); exit(21); } + pending[pending_count++]=(PendingHook){kind,address,size}; +} +/* Runs queued GPU notifications; callers invoke it after dropping the lock. */ +static void flush_hooks(void) { + for (;;) { + write_lock(); + if (!pending_count) { write_unlock(); return; } + PendingHook h=pending[0]; + memmove(pending,pending+1,--pending_count*sizeof(*pending)); + GpuRange hook = h.kind==HOOK_MAP ? hook_map : h.kind==HOOK_UNMAP ? hook_unmap : hook_invalidate; + write_unlock(); + if (hook) hook(h.address,h.size); + } +} +static int flex_test(uint64_t page) { return (int)((flex_bitmap[page/64]>>(page%64))&1); } +static void flex_set(uint64_t first, uint64_t count, int used) { + for (uint64_t p=first;p a */ + size_t lo=0, hi=vma_count; + while (lo=a) return 0; + Vma right=vmas[i]; + right.start=a; + if (right.kind==KIND_DIRECT) right.phys+=a-vmas[i].start; + vmas[i].end=a; + return vma_insert(i+1,right); +} +/* Range [start,end) split on its edges; returns the first index inside it. */ +static size_t carve(uintptr_t start, uintptr_t end, int *error) { + *error = split_at(start) || split_at(end); + return vma_index(start); +} +static int covered(uintptr_t start, uintptr_t end, int allow_reserved) { + size_t i=vma_index(start); uintptr_t at=start; + for (; atat || (!allow_reserved && vmas[i].kind==KIND_RESERVED)) return 0; + at=vmas[i].end; + } + return 1; +} +static int overlaps(uintptr_t start, uintptr_t end, int ignore_reserved) { + for (size_t i=vma_index(start); i=at+size) return at; + at=align_up(vmas[i].end,alignment); + } + return 0; +} +static void drop_range(uintptr_t start, uintptr_t end) { + int error; size_t i=carve(start,end,&error), n=0; + while (i+n=start) { + if (vmas[i+n].kind==KIND_FLEXIBLE) { + flexible_bytes-=vmas[i+n].end-vmas[i+n].start; + flex_free(vmas[i+n].phys,vmas[i+n].end-vmas[i+n].start); + } + ++n; + } + vma_erase(i,n); +} +/* Places a host mapping; with MAP_FIXED it replaces what the guest had there. */ +static int32_t place(void **inout, uint64_t size, int prot, int flags, uint64_t alignment, + int kind, int type, uint64_t phys) { + uintptr_t address=(uintptr_t)*inout; + if (flags & MAP_FIXED_FLAG) { + if (!address || address%PAGE) return INVALID; + if ((flags & MAP_NO_OVERWRITE) && overlaps(address,address+size,1)) return NO_MEMORY; + } else { + address=find_free(address,size,alignment); + if (!address) return NO_MEMORY; + } + void *mapped = kind!=KIND_RESERVED + ? mmap((void *)address,size,host_prot(prot),MAP_SHARED|MAP_FIXED,pool_fd,(off_t)phys) + : mmap((void *)address,size,PROT_NONE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE|MAP_FIXED,-1,0); + if (mapped==MAP_FAILED) return NO_MEMORY; + drop_range(address,address+size); + if (vma_insert(vma_index(address),(Vma){address,address+size,kind,prot,type,phys})) return NO_MEMORY; + if (kind==KIND_FLEXIBLE) flexible_bytes+=size; + if (kind!=KIND_RESERVED) queue_hook(HOOK_MAP,address,size); + *inout=mapped; + return 0; +} +static int block_type(uint64_t phys) { + for (int i=0;i=blocks[i].start && phys-blocks[i].start=blocks[i].start && at-blocks[i].start 10) + return INVALID; + uint64_t end = (uint64_t)high < POOL_SIZE ? (uint64_t)high : POOL_SIZE; + if ((uint64_t)low >= end || size > end - (uint64_t)low) return NO_SPACE; + write_lock(); + if (pool()) { write_unlock(); return NO_MEMORY; } + uint64_t start = align_up((uint64_t)low, alignment); + int slot = -1; + for (int i=0; i end || size > end-start) { write_unlock(); return NO_SPACE; } + int overlap = 0; + for (int i=0; istart ? vmas[i].start : start, b=vmas[i].endstart ? vmas[i].start : start, b=vmas[i].endstart ? v.phys : start, b=v.phys+lengthused || b->start>=start+size || start>=b->start+b->size) continue; + uint64_t a=b->start>start ? b->start : start, e=b->start+b->sizestart+b->size : start+size; + Block left=*b, right=*b; + left.size=a-b->start; right.start=e; right.size=b->start+b->size-e; + b->used=0; + if (left.size) *b=left; + if (right.size) for (int j=0;jFLEXIBLE_SIZE || pool()) return NO_MEMORY; + uint64_t phys=flex_alloc(size); + if (phys==UINT64_MAX) return NO_MEMORY; + int32_t result=place(inout,size,prot,flags,PAGE,KIND_FLEXIBLE,0,phys); + if (result) flex_free(phys,size); else ++flexible_maps; + return result; +} +static ABI int32_t map_flexible(void **inout, uint64_t size, int prot, int flags) { + write_lock(); + int32_t result=map_flexible_locked(inout,size,prot,flags); + write_unlock(); + flush_hooks(); + if (!result) printf("Runtime: mapped flexible memory %p, size=%" PRIu64 ", prot=0x%x\n", *inout, size, prot); + else fprintf(stderr,"Runtime: flexible map of %" PRIu64 " bytes failed (0x%x), in use=%" PRIu64 "\n", + size, (unsigned)result, flexible_bytes); + return result; +} +static ABI int32_t map_flexible_named(void **inout, uint64_t size, int prot, int flags, const char *name) { + (void)name; return map_flexible(inout,size,prot,flags); +} +static ABI int32_t release_flexible(void *address, uint64_t size) { return direct_unmap(address,size); } +static ABI int32_t reserve_range(void **inout, uint64_t size, int flags, uint64_t alignment) { + if (!alignment) alignment=PAGE; + if (!inout || !size || size%PAGE || !valid_alignment(alignment)) return INVALID; + write_lock(); + if ((flags & MAP_FIXED_FLAG) && overlaps((uintptr_t)*inout,(uintptr_t)*inout+size,0)) { + write_unlock(); return NO_MEMORY; + } + int32_t result=place(inout,size,0,flags,alignment,KIND_RESERVED,0,0); + write_unlock(); + if (!result) printf("Runtime: reserved virtual range %p, size=%" PRIu64 "\n", *inout, size); + return result; +} +static int32_t protect_locked(uintptr_t start, uint64_t size, int prot, int type) { + uintptr_t end=start+align_up(size,PAGE); + start&=~(uintptr_t)(PAGE-1); + if ((prot & ~0x37) || !covered(start,end,0)) return INVALID; + if (mprotect((void *)start,end-start,host_prot(prot))) return INVALID; + int error; size_t i=carve(start,end,&error); + if (error) return NO_MEMORY; + for (; i=0) vmas[i].type=type; } + queue_hook(HOOK_INVALIDATE,start,end-start); + ++protects; + return 0; +} +static ABI int32_t kernel_mprotect(const void *address, uint64_t size, int prot) { + write_lock(); + int32_t result=protect_locked((uintptr_t)address,size,prot,-1); + write_unlock(); + flush_hooks(); + return result; +} +static ABI int32_t query_protection(void *address, void **start, void **end, uint32_t *prot) { + read_lock(); + size_t i=vma_index((uintptr_t)address); + if (i==vma_count || vmas[i].start>(uintptr_t)address || vmas[i].kind==KIND_RESERVED) { + read_unlock(); return ACCESS; + } + /* Report the whole contiguous run with identical protection. */ + size_t first=i, last=i; + while (first && vmas[first-1].end==vmas[first].start && vmas[first-1].kind!=KIND_RESERVED && vmas[first-1].prot==vmas[i].prot) --first; + while (last+1(uintptr_t)address && !(flags & 1))) { read_unlock(); return ACCESS; } + Vma v=vmas[i]; + memset(info,0,sizeof(*info)); + info->start=v.start; info->end=v.end; + info->offset=v.kind==KIND_DIRECT ? v.phys : 0; + info->protection=v.prot; info->memory_type=v.type; + info->flags=(v.kind==KIND_FLEXIBLE ? 1u : 0) | (v.kind==KIND_DIRECT ? 2u : 0) | (v.kind!=KIND_RESERVED ? 16u : 0); + strcpy(info->name, v.kind==KIND_RESERVED ? "reserved" : v.kind==KIND_DIRECT ? "direct" : "flexible"); + __atomic_add_fetch(&queries,1,__ATOMIC_RELAXED); + read_unlock(); + return 0; +} +static ABI int32_t direct_memory_type(uint64_t phys, int *type, void **start, void **end) { + read_lock(); + for (int i=0;i=blocks[i].start && phys-blocks[i].startoperation) { + case 0: result=map_direct_locked(&e->start,e->length,(uint8_t)e->prot,flags,(int64_t)e->offset,0); break; + case 1: result=unmap_locked((uintptr_t)e->start,e->length); break; + case 2: result=protect_locked((uintptr_t)e->start,e->length,(uint8_t)e->prot,-1); break; + case 3: result=map_flexible_locked(&e->start,e->length,(uint8_t)e->prot,flags); break; + case 4: result=protect_locked((uintptr_t)e->start,e->length,(uint8_t)e->prot,e->type); break; + default: result=INVALID; + } + if (result) break; + } + write_unlock(); + flush_hooks(); + if (processed) *processed=done; + return result; +} +static ABI int32_t batch_map(BatchEntry *entries, int count, int *processed) { + return batch_map2(entries,count,processed,MAP_FIXED_FLAG); +} +static const RuntimeExport exports[]={ + {"sceKernelGetDirectMemorySize",direct_size}, {"sceKernelAllocateDirectMemory",direct_allocate}, + {"sceKernelMapDirectMemory",direct_map}, {"sceKernelMapNamedDirectMemory",direct_map_named}, + {"sceKernelReleaseDirectMemory",direct_release}, {"sceKernelMunmap",direct_unmap}, {"munmap",direct_unmap}, + {"sceKernelMapFlexibleMemory",map_flexible}, {"sceKernelMapNamedFlexibleMemory",map_flexible_named}, + {"sceKernelReleaseFlexibleMemory",release_flexible}, {"sceKernelReserveVirtualRange",reserve_range}, + {"sceKernelMprotect",kernel_mprotect}, {"sceKernelQueryMemoryProtection",query_protection}, + {"sceKernelVirtualQuery",virtual_query}, {"sceKernelGetDirectMemoryType",direct_memory_type}, + {"sceKernelBatchMap",batch_map}, {"sceKernelBatchMap2",batch_map2}, +}; +uintptr_t runtime_memory_resolve(const char *name) { + /* Direct-memory NIDs are exercised by test_runtime.c before names are loaded. */ + if (!strcmp(name, "pO96TwzOm5E#p#J")) return (uintptr_t)direct_size; + if (!strcmp(name, "rTXw65xmLIA#p#J")) return (uintptr_t)direct_allocate; + if (!strcmp(name, "L-Q3LEjIbgA#p#J")) return (uintptr_t)direct_map; + if (!strcmp(name, "MBuItvba6z8#p#J")) return (uintptr_t)direct_release; + if (!strcmp(name, "cQke9UuBQOk#p#J")) return (uintptr_t)direct_unmap; + return RUNTIME_LOOKUP(exports,name); +} +/* Host-owned memory the guest can see (image, stacks, trampolines) lives in + * [LOW_MIN, USER_MIN): PS4 code packs pointers into 40-bit fields. */ +#define LOW_MIN UINT64_C(0x0800000000) +static uintptr_t low_next=LOW_MIN; +void *runtime_low_map(size_t size, int prot) { + size=align_up(size,PAGE); + write_lock(); + void *p=MAP_FAILED; + while (low_next+size<=USER_MIN) { + p=mmap((void *)low_next,size,prot,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED_NOREPLACE,-1,0); + low_next+=size+PAGE; /* unmapped gap catches overruns */ + if (p!=MAP_FAILED) break; + } + write_unlock(); + return p==MAP_FAILED ? NULL : p; +} +/* ---- GPU library interface (gpu/shim/bbgpu.cpp) ---- */ +/* Optimizations switched off at run time (diagnostics): the number in the file named by + * BB_TOGGLE_FILE, re-read every 250 ms. Bits: 1 region cache, 2 fetch shader cache, + * 4 page tracking early exit, 8 pending-op poll limit, 16 threaded Vulkan recording, + * 32 texture descriptor cache. */ +uint32_t runtime_disabled_optimizations; +static void *toggle_watcher(void *path) { + for (uint32_t last=UINT32_MAX;;) { + FILE *f=fopen(path,"r"); + unsigned value=0; + if (f) { if (fscanf(f,"%u",&value)!=1) value=0; fclose(f); } + if (value!=last) { + __atomic_store_n(&runtime_disabled_optimizations,value,__ATOMIC_RELEASE); + printf("Runtime: disabled optimizations mask=%u\n",value); + last=value; + } + struct timespec t={0,250000000}; nanosleep(&t,NULL); + } + return NULL; +} +void runtime_memory_set_gpu_hooks(GpuRange map, GpuRange unmap, GpuRange invalidate) { + const char *toggles=getenv("BB_TOGGLE_FILE"); + static pthread_t watcher; + if (toggles && !watcher) pthread_create(&watcher,NULL,toggle_watcher,(void *)toggles); + write_lock(); + hook_map=map; hook_unmap=unmap; hook_invalidate=invalidate; + for (size_t i=0;iat || vmas[i].kind==KIND_RESERVED) { ok=0; break; } + uint64_t n=(vmas[i].endgeneration==generation && c->end && c->start<=address && addressend) return c; + } + return NULL; +} +/* Called under the read lock after a lookup of address. */ +static void cache_region(size_t i) { + uint64_t generation=__atomic_load_n(&table_generation,__ATOMIC_ACQUIRE); + if (i==vma_count || (generation & 1)) return; + region_cache[region_cache_next++ % 8]=(CachedRegion){generation,vmas[i].start,vmas[i].end,vmas[i].kind}; +} +/* Mapped length from address, up to size, across adjacent mappings. */ +uint64_t runtime_memory_clamp(uintptr_t address, uint64_t size) { + const CachedRegion *c=(runtime_disabled_optimizations & 1) ? NULL : cached_region(address); + if (c && c->kind!=KIND_RESERVED && size<=c->end-address) return size; + read_lock(); + { size_t i=vma_index(address); if (iaddress+length || vmas[i].kind==KIND_RESERVED) break; + length=vmas[i].end-address; + } + read_unlock(); + return lengthstart; *end=c->end; *mapped=c->kind!=KIND_RESERVED; return 1; } + read_lock(); + size_t i=vma_index(address); + int found=iaddress ? vmas[i].start : address; + uintptr_t b=vmas[i].endkind!=KIND_RESERVED && size<=c->end-address) return 1; + read_lock(); + int result=covered(address,address+size,0); + read_unlock(); + return result; +} +void runtime_memory_report(void) { + printf("Runtime: direct memory allocations=%zu, maps=%zu, live=%" PRIu64 ", budget=%" PRIu64 "\n", + allocations, maps, live_bytes, POOL_SIZE); + printf("Runtime: flexible maps=%zu, in use=%" PRIu64 ", protects=%zu, queries=%zu, regions=%zu\n", + flexible_maps, flexible_bytes, protects, queries, vma_count); +} +#else +void *runtime_low_map(size_t size, int prot) { (void)size; (void)prot; return NULL; } +uintptr_t runtime_memory_resolve(const char *name) { (void)name; return 0; } +int runtime_memory_is_mapped(uintptr_t address, uint64_t size) { (void)address; (void)size; return 0; } +void runtime_memory_report(void) { puts("Runtime: Windows direct-memory backend not implemented"); } +#endif diff --git a/runtime_mutex.c b/runtime_mutex.c new file mode 100644 index 0000000..5e05875 --- /dev/null +++ b/runtime_mutex.c @@ -0,0 +1,270 @@ +/* Linux pthread-backed opaque PS4 mutex handles. No guest threads yet. */ +#define _GNU_SOURCE +#include "runtime.h" +#include +#include +#include +#ifndef _WIN32 +#include +#include +#include +typedef struct { int type; } GuestAttr; +typedef struct { pthread_mutex_t native; } GuestMutex; +static size_t created, locks, unlocks; +static int32_t orbis_error(int e) { + if (!e) return 0; + unsigned code; + switch (e) { + case EPERM: code=1; break; + case ENOMEM: code=12; break; + case EBUSY: code=16; break; + case EINVAL: code=22; break; + case EAGAIN: code=35; break; + case EDEADLK: code=11; break; + default: fprintf(stderr, "STOP: unmapped host pthread error %d\n", e); exit(21); + } + return (int32_t)(UINT32_C(0x80020000) | code); +} +static ABI int32_t attr_init(GuestAttr **out) { + if (!out) return orbis_error(EINVAL); + GuestAttr *attr = malloc(sizeof(*attr)); + if (!attr) return orbis_error(ENOMEM); + attr->type = 1; *out = attr; return 0; +} +static ABI int32_t attr_type(GuestAttr **attr, int type) { + if (!attr || !*attr || type < 1 || type > 4) return orbis_error(EINVAL); + (*attr)->type = type; return 0; +} +/* Priority protocols need a PS4 scheduler; the value is validated and recorded only. */ +static ABI int32_t attr_protocol(GuestAttr **attr, int protocol) { + if (!attr || !*attr || protocol < 0 || protocol > 2) return orbis_error(EINVAL); + return 0; +} +static ABI int32_t attr_destroy(GuestAttr **attr) { + if (!attr || !*attr) return orbis_error(EINVAL); + free(*attr); *attr = NULL; return 0; +} +static ABI int32_t mutex_init(GuestMutex **out, GuestAttr **attr, const char *name) { + (void)name; + if (!out || (attr && !*attr)) return orbis_error(EINVAL); + int type = attr ? (*attr)->type : 1; + if (type < 1 || type > 4) return orbis_error(EINVAL); + GuestMutex *mutex = malloc(sizeof(*mutex)); + if (!mutex) return orbis_error(ENOMEM); + pthread_mutexattr_t native_attr; + int e = pthread_mutexattr_init(&native_attr); + if (e) { free(mutex); return orbis_error(e); } + int native_type = type == 2 ? PTHREAD_MUTEX_RECURSIVE : type == 3 ? PTHREAD_MUTEX_NORMAL : PTHREAD_MUTEX_ERRORCHECK; + e = pthread_mutexattr_settype(&native_attr, native_type); + if (!e) e = pthread_mutex_init(&mutex->native, &native_attr); + pthread_mutexattr_destroy(&native_attr); + if (e) { free(mutex); return orbis_error(e); } + *out = mutex; ++created; return 0; +} +static pthread_mutex_t static_init = PTHREAD_MUTEX_INITIALIZER; +/* Statically initialized handles (0/1) are created once, even under contention. */ +static int32_t ensure_mutex(GuestMutex **mutex) { + if (!mutex) return orbis_error(EINVAL); + uintptr_t value = __atomic_load_n((uintptr_t *)mutex, __ATOMIC_ACQUIRE); + if (value == 2) return orbis_error(EINVAL); + if (value >= 2) return 0; + pthread_mutex_lock(&static_init); + int32_t e = 0; + if ((uintptr_t)*mutex < 2) { + GuestMutex *created_mutex = NULL; + e = mutex_init(&created_mutex, NULL, NULL); + if (!e) __atomic_store_n(mutex, created_mutex, __ATOMIC_RELEASE); + } + pthread_mutex_unlock(&static_init); + return e; +} +static ABI int32_t mutex_lock(GuestMutex **mutex) { + int32_t e = ensure_mutex(mutex); + if (e) return e; + e = orbis_error(pthread_mutex_lock(&(*mutex)->native)); + if (!e) ++locks; + return e; +} +static ABI int32_t mutex_trylock(GuestMutex **mutex) { + int32_t e = ensure_mutex(mutex); + if (e) return e; + e = orbis_error(pthread_mutex_trylock(&(*mutex)->native)); + if (!e) ++locks; + return e; +} +static ABI int32_t mutex_unlock(GuestMutex **mutex) { + if (!mutex || (uintptr_t)*mutex == 2) return orbis_error(EINVAL); + if ((uintptr_t)*mutex < 2) return orbis_error(EPERM); + int32_t e = orbis_error(pthread_mutex_unlock(&(*mutex)->native)); + if (!e) ++unlocks; + return e; +} +static ABI int32_t mutex_destroy(GuestMutex **mutex) { + if (!mutex || (uintptr_t)*mutex == 2) return orbis_error(EINVAL); + if ((uintptr_t)*mutex < 2) return 0; + int e = pthread_mutex_destroy(&(*mutex)->native); + if (!e) { free(*mutex); *mutex = (GuestMutex *)(uintptr_t)2; } + return orbis_error(e); +} +static int deadline_after(struct timespec *end, uint64_t usec) { + if (clock_gettime(CLOCK_REALTIME, end)) return errno; + uint64_t ns = (uint64_t)end->tv_nsec + (usec % 1000000) * 1000; + end->tv_sec += (time_t)(usec / 1000000 + ns / 1000000000); + end->tv_nsec = (long)(ns % 1000000000); + return 0; +} +static int32_t timed_error(int e) { return e == ETIMEDOUT ? (int32_t)UINT32_C(0x8002003c) : orbis_error(e); } +static ABI int32_t mutex_timedlock(GuestMutex **mutex, uint32_t usec) { + int32_t e = ensure_mutex(mutex); + if (e) return e; + struct timespec end; + if (deadline_after(&end, usec)) return orbis_error(EINVAL); + e = timed_error(pthread_mutex_timedlock(&(*mutex)->native, &end)); + if (!e) ++locks; + return e; +} +/* Condition variables: opaque handles over host pthread_cond (CLOCK_REALTIME, + * like FreeBSD's default), sharing the host mutex behind GuestMutex. */ +typedef struct { pthread_cond_t native; } GuestCond; +static size_t conds, waits, wakeups; +static ABI int32_t cond_init(GuestCond **out, void **attr, const char *name) { + (void)attr; (void)name; + if (!out) return orbis_error(EINVAL); + GuestCond *c = malloc(sizeof(*c)); + if (!c) return orbis_error(ENOMEM); + int e = pthread_cond_init(&c->native, NULL); + if (e) { free(c); return orbis_error(e); } + *out = c; ++conds; return 0; +} +static int32_t ensure_cond(GuestCond **cond) { + if (!cond) return orbis_error(EINVAL); + if (__atomic_load_n((uintptr_t *)cond, __ATOMIC_ACQUIRE) >= 2) return 0; + pthread_mutex_lock(&static_init); + int32_t e = 0; + if ((uintptr_t)*cond < 2) { + GuestCond *c = NULL; + e = cond_init(&c, NULL, NULL); + if (!e) __atomic_store_n(cond, c, __ATOMIC_RELEASE); + } + pthread_mutex_unlock(&static_init); + return e; +} +static ABI int32_t cond_destroy(GuestCond **cond) { + if (!cond) return orbis_error(EINVAL); + if ((uintptr_t)*cond < 2) return 0; + int e = pthread_cond_destroy(&(*cond)->native); + if (!e) { free(*cond); *cond = NULL; } + return orbis_error(e); +} +static ABI int32_t cond_wait(GuestCond **cond, GuestMutex **mutex) { + int32_t e = ensure_cond(cond); + if (e) return e; + if (!mutex || (uintptr_t)*mutex < 3) return orbis_error(EINVAL); + ++waits; + return orbis_error(pthread_cond_wait(&(*cond)->native, &(*mutex)->native)); +} +static int32_t cond_wait_until(GuestCond **cond, GuestMutex **mutex, const struct timespec *end) { + int32_t e = ensure_cond(cond); + if (e) return e; + if (!mutex || (uintptr_t)*mutex < 3 || !end) return orbis_error(EINVAL); + ++waits; + return timed_error(pthread_cond_timedwait(&(*cond)->native, &(*mutex)->native, end)); +} +static ABI int32_t cond_timedwait(GuestCond **cond, GuestMutex **mutex, uint32_t usec) { + struct timespec end; + if (deadline_after(&end, usec)) return orbis_error(EINVAL); + return cond_wait_until(cond, mutex, &end); +} +static ABI int32_t cond_signal(GuestCond **cond) { + int32_t e = ensure_cond(cond); + if (e) return e; + ++wakeups; return orbis_error(pthread_cond_signal(&(*cond)->native)); +} +static ABI int32_t cond_broadcast(GuestCond **cond) { + int32_t e = ensure_cond(cond); + if (e) return e; + ++wakeups; return orbis_error(pthread_cond_broadcast(&(*cond)->native)); +} +/* PS4 struct timespec is {int64 sec, int64 nsec}, identical to Linux x86-64. */ +typedef struct { int64_t sec, nsec; } GuestTimespec; +static ABI int32_t cond_abs_timedwait(GuestCond **cond, GuestMutex **mutex, const GuestTimespec *abs) { + if (!abs || abs->nsec < 0 || abs->nsec >= 1000000000) return orbis_error(EINVAL); + struct timespec end = {.tv_sec = (time_t)abs->sec, .tv_nsec = (long)abs->nsec}; + return cond_wait_until(cond, mutex, &end); +} +/* POSIX pthread APIs return positive guest errno values, unlike scePthread. */ +static int32_t posix_result(int32_t result) { return result ? (int32_t)((uint32_t)result & 0xffff) : 0; } +static ABI int32_t posix_attr_init(GuestAttr **out) { return posix_result(attr_init(out)); } +static ABI int32_t posix_attr_type(GuestAttr **attr,int type) { return posix_result(attr_type(attr,type)); } +static ABI int32_t posix_attr_destroy(GuestAttr **attr) { return posix_result(attr_destroy(attr)); } +static ABI int32_t posix_mutex_init(GuestMutex **out,GuestAttr **attr) { return posix_result(mutex_init(out,attr,NULL)); } +static ABI int32_t posix_mutex_destroy(GuestMutex **m) { return posix_result(mutex_destroy(m)); } +static ABI int32_t posix_mutex_lock(GuestMutex **m) { return posix_result(mutex_lock(m)); } +static ABI int32_t posix_mutex_trylock(GuestMutex **m) { return posix_result(mutex_trylock(m)); } +static ABI int32_t posix_mutex_unlock(GuestMutex **m) { return posix_result(mutex_unlock(m)); } +static ABI int32_t posix_cond_init(GuestCond **c, void **a) { return posix_result(cond_init(c, a, NULL)); } +static ABI int32_t posix_cond_destroy(GuestCond **c) { return posix_result(cond_destroy(c)); } +static ABI int32_t posix_cond_wait(GuestCond **c, GuestMutex **m) { return posix_result(cond_wait(c, m)); } +static ABI int32_t posix_cond_timedwait(GuestCond **c, GuestMutex **m, const GuestTimespec *t) { return posix_result(cond_abs_timedwait(c, m, t)); } +static ABI int32_t posix_cond_signal(GuestCond **c) { return posix_result(cond_signal(c)); } +static ABI int32_t posix_cond_broadcast(GuestCond **c) { return posix_result(cond_broadcast(c)); } +uintptr_t runtime_mutex_resolve(const char *name) { + if (!strcmp(name,"0TyVk4MSLt0#I#J")) return (uintptr_t)posix_cond_init; + if (!strcmp(name,"RXXqi4CtF8w#I#J")) return (uintptr_t)posix_cond_destroy; + if (!strcmp(name,"Op8TBGY5KHg#I#J")) return (uintptr_t)posix_cond_wait; + if (!strcmp(name,"27bAgiJmOh0#I#J")) return (uintptr_t)posix_cond_timedwait; + if (!strcmp(name,"2MOy+rUfuhQ#I#J")) return (uintptr_t)posix_cond_signal; + if (!strcmp(name,"mkx2fVhNMsg#I#J")) return (uintptr_t)posix_cond_broadcast; + if (!strcmp(name,"2Tb92quprl0#p#J")) return (uintptr_t)cond_init; + if (!strcmp(name,"g+PZd2hiacg#p#J")) return (uintptr_t)cond_destroy; + if (!strcmp(name,"WKAXJ4XBPQ4#p#J")) return (uintptr_t)cond_wait; + if (!strcmp(name,"BmMjYxmew1w#p#J")) return (uintptr_t)cond_timedwait; + if (!strcmp(name,"kDh-NfxgMtE#p#J")) return (uintptr_t)cond_signal; + if (!strcmp(name,"JGgj7Uvrl+A#p#J")) return (uintptr_t)cond_broadcast; + if (!strcmp(name,"IafI2PxcPnQ#p#J")) return (uintptr_t)mutex_timedlock; + if (!strcmp(name,"dQHWEsJtoE4#I#J")) return (uintptr_t)posix_attr_init; + if (!strcmp(name,"mDmgMOGVUqg#I#J")) return (uintptr_t)posix_attr_type; + if (!strcmp(name,"HF7lK46xzjY#I#J")) return (uintptr_t)posix_attr_destroy; + if (!strcmp(name,"ttHNfU+qDBU#I#J")) return (uintptr_t)posix_mutex_init; + if (!strcmp(name,"ltCfaGr2JGE#I#J")) return (uintptr_t)posix_mutex_destroy; + if (!strcmp(name,"7H0iTOciTLo#I#J")) return (uintptr_t)posix_mutex_lock; + if (!strcmp(name,"K-jXhbt2gn4#I#J")) return (uintptr_t)posix_mutex_trylock; + if (!strcmp(name,"2Z+PpY6CaJg#I#J")) return (uintptr_t)posix_mutex_unlock; + if (!strcmp(name, "F8bUHwAG284#p#J")) return (uintptr_t)attr_init; + if (!strcmp(name, "iMp8QpE+XO4#p#J")) return (uintptr_t)attr_type; + if (!strcmp(name, "smWEktiyyG0#p#J")) return (uintptr_t)attr_destroy; + if (!strcmp(name, "1FGvU0i9saQ#p#J")) return (uintptr_t)attr_protocol; + if (!strcmp(name, "cmo1RIYva9o#p#J")) return (uintptr_t)mutex_init; + if (!strcmp(name, "9UK1vLZQft4#p#J")) return (uintptr_t)mutex_lock; + if (!strcmp(name, "upoVrzMHFeE#p#J")) return (uintptr_t)mutex_trylock; + if (!strcmp(name, "tn3VlD0hG60#p#J")) return (uintptr_t)mutex_unlock; + if (!strcmp(name, "2Of0f+3mhhE#p#J")) return (uintptr_t)mutex_destroy; + return 0; +} +void runtime_mutex_report(void) { + printf("Runtime: mutexes created=%zu, locks=%zu, unlocks=%zu\n", created, locks, unlocks); + printf("Runtime: condition variables created=%zu, waits=%zu, wakeups=%zu\n", conds, waits, wakeups); +} +#else +static ABI int32_t posix_cond_init(GuestCond **c, void **a) { return posix_result(cond_init(c, a, NULL)); } +static ABI int32_t posix_cond_destroy(GuestCond **c) { return posix_result(cond_destroy(c)); } +static ABI int32_t posix_cond_wait(GuestCond **c, GuestMutex **m) { return posix_result(cond_wait(c, m)); } +static ABI int32_t posix_cond_timedwait(GuestCond **c, GuestMutex **m, const GuestTimespec *t) { return posix_result(cond_abs_timedwait(c, m, t)); } +static ABI int32_t posix_cond_signal(GuestCond **c) { return posix_result(cond_signal(c)); } +static ABI int32_t posix_cond_broadcast(GuestCond **c) { return posix_result(cond_broadcast(c)); } +uintptr_t runtime_mutex_resolve(const char *name) { + if (!strcmp(name,"0TyVk4MSLt0#I#J")) return (uintptr_t)posix_cond_init; + if (!strcmp(name,"RXXqi4CtF8w#I#J")) return (uintptr_t)posix_cond_destroy; + if (!strcmp(name,"Op8TBGY5KHg#I#J")) return (uintptr_t)posix_cond_wait; + if (!strcmp(name,"27bAgiJmOh0#I#J")) return (uintptr_t)posix_cond_timedwait; + if (!strcmp(name,"2MOy+rUfuhQ#I#J")) return (uintptr_t)posix_cond_signal; + if (!strcmp(name,"mkx2fVhNMsg#I#J")) return (uintptr_t)posix_cond_broadcast; + if (!strcmp(name,"2Tb92quprl0#p#J")) return (uintptr_t)cond_init; + if (!strcmp(name,"g+PZd2hiacg#p#J")) return (uintptr_t)cond_destroy; + if (!strcmp(name,"WKAXJ4XBPQ4#p#J")) return (uintptr_t)cond_wait; + if (!strcmp(name,"BmMjYxmew1w#p#J")) return (uintptr_t)cond_timedwait; + if (!strcmp(name,"kDh-NfxgMtE#p#J")) return (uintptr_t)cond_signal; + if (!strcmp(name,"JGgj7Uvrl+A#p#J")) return (uintptr_t)cond_broadcast; + if (!strcmp(name,"IafI2PxcPnQ#p#J")) return (uintptr_t)mutex_timedlock; (void)name; return 0; } +void runtime_mutex_report(void) { puts("Runtime: Windows mutex backend not implemented"); } +#endif diff --git a/runtime_pad.c b/runtime_pad.c new file mode 100644 index 0000000..d75f455 --- /dev/null +++ b/runtime_pad.c @@ -0,0 +1,190 @@ +/* libScePad on SDL3 gamepads, with a keyboard fallback. SDL events are pumped + * by the window thread (gpu/shim/window.cpp); here state is only sampled. + * + * Keyboard layout (when no gamepad is connected): + * WASD left stick, arrow keys right stick, Space Cross, LShift Circle, + * E Square, Q Triangle, 1 L1, 3 R1, R L2, F R2, Z L3, C R3, + * Enter Options, Tab touchpad, IJKL d-pad (I up, K down, J left, L right). */ +#define _GNU_SOURCE +#include "runtime.h" +#include +#include +#include +#include +#include +#include + +#define ERR_INVALID_ARG ((int32_t)0x80920001) +#define ERR_INVALID_HANDLE ((int32_t)0x80920003) +#define ERR_ALREADY_OPENED ((int32_t)0x80920004) +#define ERR_NOT_INITIALIZED ((int32_t)0x80920005) +#define PAD_HANDLE 1 + +enum { + BTN_L3=0x2, BTN_R3=0x4, BTN_OPTIONS=0x8, BTN_UP=0x10, BTN_RIGHT=0x20, BTN_DOWN=0x40, BTN_LEFT=0x80, + BTN_L2=0x100, BTN_R2=0x200, BTN_L1=0x400, BTN_R1=0x800, BTN_TRIANGLE=0x1000, BTN_CIRCLE=0x2000, + BTN_CROSS=0x4000, BTN_SQUARE=0x8000, BTN_TOUCHPAD=0x100000, +}; +typedef struct { + uint32_t buttons; + uint8_t left_x, left_y, right_x, right_y; + uint8_t l2, r2, analog_padding[2]; + float orientation[4], acceleration[3], angular_velocity[3]; + uint8_t touch_count, touch_reserve[3]; + uint32_t touch_held_time; + uint8_t touches[2][8]; + uint8_t connected, pad0[3]; + uint64_t timestamp; + uint8_t extension[16]; + uint8_t connected_count, reserve[2], unique_length, unique[12]; +} PadData; +typedef struct { + float pixel_density; uint16_t resolution_x, resolution_y; + uint8_t dead_zone_left, dead_zone_right, connection_type, connected_count; + uint8_t connected, pad[3]; + int32_t device_class; + uint8_t reserve[8]; +} ControllerInfo; +_Static_assert(sizeof(PadData)==120,"OrbisPadData layout"); +_Static_assert(__builtin_offsetof(PadData,timestamp)==80,"OrbisPadData timestamp offset"); +_Static_assert(sizeof(ControllerInfo)==28,"OrbisPadControllerInformation layout"); + +static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; +static int initialized, opened, sdl_ready; +static SDL_Gamepad *gamepad; +static size_t reads; +static uint8_t connected_count; + +static uint64_t now_us(void) { struct timespec t; clock_gettime(CLOCK_MONOTONIC,&t); return (uint64_t)t.tv_sec*1000000u+(uint64_t)t.tv_nsec/1000u; } +static uint8_t axis(int16_t v) { int x=(v+32768)>>8; return (uint8_t)(x<0 ? 0 : x>255 ? 255 : x); } +static uint8_t trigger(int16_t v) { int x=v>>7; return (uint8_t)(x<0 ? 0 : x>255 ? 255 : x); } + +/* Opens the first gamepad SDL knows about; called under lock. */ +static SDL_Gamepad *current_gamepad(void) { + if (!sdl_ready) sdl_ready = SDL_WasInit(SDL_INIT_GAMEPAD) ? 1 : SDL_InitSubSystem(SDL_INIT_GAMEPAD) ? 1 : -1; + if (sdl_ready<0) return NULL; + if (gamepad && !SDL_GamepadConnected(gamepad)) { SDL_CloseGamepad(gamepad); gamepad=NULL; } + if (!gamepad) { + int count=0; + SDL_JoystickID *ids=SDL_GetGamepads(&count); + if (ids && count>0) { + gamepad=SDL_OpenGamepad(ids[0]); + if (gamepad) { ++connected_count; printf("Runtime: gamepad connected: %s\n",SDL_GetGamepadName(gamepad)); } + } + SDL_free(ids); + } + return gamepad; +} +static void sample(PadData *d) { + memset(d,0,sizeof(*d)); + d->left_x=d->left_y=d->right_x=d->right_y=128; + d->orientation[3]=1.0f; + d->connected=1; d->connected_count=connected_count ? connected_count : 1; + d->timestamp=now_us(); + SDL_Gamepad *g=current_gamepad(); + if (g) { + static const struct { SDL_GamepadButton sdl; uint32_t ps; } map[]={ + {SDL_GAMEPAD_BUTTON_SOUTH,BTN_CROSS}, {SDL_GAMEPAD_BUTTON_EAST,BTN_CIRCLE}, + {SDL_GAMEPAD_BUTTON_WEST,BTN_SQUARE}, {SDL_GAMEPAD_BUTTON_NORTH,BTN_TRIANGLE}, + {SDL_GAMEPAD_BUTTON_LEFT_SHOULDER,BTN_L1}, {SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER,BTN_R1}, + {SDL_GAMEPAD_BUTTON_LEFT_STICK,BTN_L3}, {SDL_GAMEPAD_BUTTON_RIGHT_STICK,BTN_R3}, + {SDL_GAMEPAD_BUTTON_START,BTN_OPTIONS}, {SDL_GAMEPAD_BUTTON_BACK,BTN_TOUCHPAD}, + {SDL_GAMEPAD_BUTTON_TOUCHPAD,BTN_TOUCHPAD}, + {SDL_GAMEPAD_BUTTON_DPAD_UP,BTN_UP}, {SDL_GAMEPAD_BUTTON_DPAD_DOWN,BTN_DOWN}, + {SDL_GAMEPAD_BUTTON_DPAD_LEFT,BTN_LEFT}, {SDL_GAMEPAD_BUTTON_DPAD_RIGHT,BTN_RIGHT}, + }; + for (size_t i=0;ibuttons|=map[i].ps; + d->left_x=axis(SDL_GetGamepadAxis(g,SDL_GAMEPAD_AXIS_LEFTX)); d->left_y=axis(SDL_GetGamepadAxis(g,SDL_GAMEPAD_AXIS_LEFTY)); + d->right_x=axis(SDL_GetGamepadAxis(g,SDL_GAMEPAD_AXIS_RIGHTX)); d->right_y=axis(SDL_GetGamepadAxis(g,SDL_GAMEPAD_AXIS_RIGHTY)); + d->l2=trigger(SDL_GetGamepadAxis(g,SDL_GAMEPAD_AXIS_LEFT_TRIGGER)); d->r2=trigger(SDL_GetGamepadAxis(g,SDL_GAMEPAD_AXIS_RIGHT_TRIGGER)); + if (d->l2>30) d->buttons|=BTN_L2; + if (d->r2>30) d->buttons|=BTN_R2; + return; + } + if (!SDL_WasInit(SDL_INIT_VIDEO)) return; + const bool *k=SDL_GetKeyboardState(NULL); + if (!k) return; + static const struct { SDL_Scancode key; uint32_t ps; } keys[]={ + {SDL_SCANCODE_SPACE,BTN_CROSS}, {SDL_SCANCODE_LSHIFT,BTN_CIRCLE}, {SDL_SCANCODE_E,BTN_SQUARE}, + {SDL_SCANCODE_Q,BTN_TRIANGLE}, {SDL_SCANCODE_1,BTN_L1}, {SDL_SCANCODE_3,BTN_R1}, + {SDL_SCANCODE_R,BTN_L2}, {SDL_SCANCODE_F,BTN_R2}, {SDL_SCANCODE_Z,BTN_L3}, {SDL_SCANCODE_C,BTN_R3}, + {SDL_SCANCODE_RETURN,BTN_OPTIONS}, {SDL_SCANCODE_TAB,BTN_TOUCHPAD}, + {SDL_SCANCODE_I,BTN_UP}, {SDL_SCANCODE_K,BTN_DOWN}, {SDL_SCANCODE_J,BTN_LEFT}, {SDL_SCANCODE_L,BTN_RIGHT}, + }; + for (size_t i=0;ibuttons|=keys[i].ps; + if (d->buttons & BTN_L2) d->l2=255; + if (d->buttons & BTN_R2) d->r2=255; + d->left_x=(uint8_t)(128-(k[SDL_SCANCODE_A] ? 128 : 0)+(k[SDL_SCANCODE_D] ? 127 : 0)); + d->left_y=(uint8_t)(128-(k[SDL_SCANCODE_W] ? 128 : 0)+(k[SDL_SCANCODE_S] ? 127 : 0)); + d->right_x=(uint8_t)(128-(k[SDL_SCANCODE_LEFT] ? 128 : 0)+(k[SDL_SCANCODE_RIGHT] ? 127 : 0)); + d->right_y=(uint8_t)(128-(k[SDL_SCANCODE_UP] ? 128 : 0)+(k[SDL_SCANCODE_DOWN] ? 127 : 0)); +} + +static ABI int32_t pad_init(void) { pthread_mutex_lock(&lock); initialized=1; pthread_mutex_unlock(&lock); return 0; } +static ABI int32_t pad_open(int32_t user, int32_t type, int32_t index, const void *param) { + (void)param; + if (!initialized) return ERR_NOT_INITIALIZED; + if (user!=1) return ERR_INVALID_ARG; + if (type!=0 && type!=2) return ERR_INVALID_ARG; /* standard / special port */ + if (index) return ERR_INVALID_ARG; + pthread_mutex_lock(&lock); + int already=opened; opened=1; + pthread_mutex_unlock(&lock); + if (already) return ERR_ALREADY_OPENED; + puts("Runtime: pad opened for user 1 (SDL gamepad or keyboard)"); + return PAD_HANDLE; +} +static ABI int32_t pad_close(int32_t handle) { + if (handle!=PAD_HANDLE || !opened) return ERR_INVALID_HANDLE; + opened=0; return 0; +} +static ABI int32_t pad_read_state(int32_t handle, PadData *data) { + if (handle!=PAD_HANDLE || !opened) return ERR_INVALID_HANDLE; + if (!data) return ERR_INVALID_ARG; + pthread_mutex_lock(&lock); + sample(data); ++reads; + pthread_mutex_unlock(&lock); + return 0; +} +/* Buffered read: the port samples once per call, so one entry is returned. */ +static ABI int32_t pad_read(int32_t handle, PadData *data, int32_t count) { + if (handle!=PAD_HANDLE || !opened) return ERR_INVALID_HANDLE; + if (!data || count<1 || count>64) return ERR_INVALID_ARG; + pad_read_state(handle,data); + return 1; +} +static ABI int32_t pad_info(int32_t handle, ControllerInfo *info) { + if (handle!=PAD_HANDLE || !opened) return ERR_INVALID_HANDLE; + if (!info) return ERR_INVALID_ARG; + memset(info,0,sizeof(*info)); + info->pixel_density=44.86f; info->resolution_x=1920; info->resolution_y=943; + info->dead_zone_left=info->dead_zone_right=2; + info->connection_type=0; info->connected=1; info->device_class=0; + pthread_mutex_lock(&lock); + current_gamepad(); + info->connected_count=connected_count ? connected_count : 1; + pthread_mutex_unlock(&lock); + return 0; +} +static ABI int32_t pad_vibration(int32_t handle, const uint8_t *param) { + if (handle!=PAD_HANDLE || !opened) return ERR_INVALID_HANDLE; + if (!param) return ERR_INVALID_ARG; + pthread_mutex_lock(&lock); + SDL_Gamepad *g=current_gamepad(); + if (g) SDL_RumbleGamepad(g,(uint16_t)(param[0]*257),(uint16_t)(param[1]*257),1000); + pthread_mutex_unlock(&lock); + return 0; +} +static ABI int32_t pad_ok_handle(int32_t handle) { return handle==PAD_HANDLE && opened ? 0 : ERR_INVALID_HANDLE; } +static ABI int32_t pad_ok_handle_flag(int32_t handle, uint8_t flag) { (void)flag; return pad_ok_handle(handle); } + +static const RuntimeExport exports[]={ + {"scePadInit",pad_init}, {"scePadOpen",pad_open}, {"scePadClose",pad_close}, + {"scePadReadState",pad_read_state}, {"scePadRead",pad_read}, + {"scePadGetControllerInformation",pad_info}, {"scePadSetVibration",pad_vibration}, + {"scePadResetOrientation",pad_ok_handle}, + {"scePadSetAngularVelocityDeadbandState",pad_ok_handle_flag}, {"scePadSetTiltCorrectionState",pad_ok_handle_flag}, + {"scePadSetMotionSensorState",pad_ok_handle_flag}, +}; +uintptr_t runtime_pad_resolve(const char *name) { return RUNTIME_LOOKUP(exports,name); } +void runtime_pad_report(void) { printf("Runtime: pad reads=%zu, gamepad=%s\n",reads,gamepad ? SDL_GetGamepadName(gamepad) : "none"); } diff --git a/runtime_rtc.c b/runtime_rtc.c new file mode 100644 index 0000000..055b037 --- /dev/null +++ b/runtime_rtc.c @@ -0,0 +1,151 @@ +/* libSceRtc: calendar time. A tick is one microsecond since 0001-01-01 00:00 + * (proleptic Gregorian), the PS4 convention; the host clock supplies "now" + * and the host time zone supplies local time. */ +#define _GNU_SOURCE +#include "runtime.h" +#include +#include +#include + +#define ERR_INVALID_POINTER ((int32_t)0x80B50002) +#define ERR_INVALID_YEAR ((int32_t)0x80B50008) +#define ERR_INVALID_MONTH ((int32_t)0x80B50009) +#define ERR_INVALID_DAY ((int32_t)0x80B5000A) +#define ERR_INVALID_HOUR ((int32_t)0x80B5000B) +#define ERR_INVALID_MINUTE ((int32_t)0x80B5000C) +#define ERR_INVALID_SECOND ((int32_t)0x80B5000D) +#define ERR_INVALID_MICROSECOND ((int32_t)0x80B5000E) +#define UNIX_EPOCH_TICKS UINT64_C(0xdcbffeff2bc000) +#define TICKS_PER_DAY UINT64_C(86400000000) + +typedef struct { uint16_t year, month, day, hour, minute, second; uint32_t microsecond; } DateTime; +_Static_assert(sizeof(DateTime)==16,"OrbisRtcDateTime layout"); + +static int leap(int y) { return (y%4==0 && y%100!=0) || y%400==0; } +static int days_in_month(int y, int m) { + static const int d[12]={31,28,31,30,31,30,31,31,30,31,30,31}; + return m==2 && leap(y) ? 29 : d[m-1]; +} +/* Days since 0001-01-01 (H. Hinnant's days_from_civil, shifted epoch). */ +static int64_t days_from_civil(int64_t y, int64_t m, int64_t d) { + y -= m<=2; + int64_t era=(y>=0 ? y : y-399)/400; + int64_t yoe=y-era*400, doy=(153*(m+(m>2 ? -3 : 9))+2)/5+d-1, doe=yoe*365+yoe/4-yoe/100+doy; + return era*146097+doe-306; /* 0001-01-01 == 0 */ +} +static void civil_from_days(int64_t z, int *y, int *m, int *d) { + z+=306; + int64_t era=(z>=0 ? z : z-146096)/146097, doe=z-era*146097; + int64_t yoe=(doe-doe/1460+doe/36524-doe/146096)/365, doy=doe-(365*yoe+yoe/4-yoe/100); + int64_t mp=(5*doy+2)/153; + *d=(int)(doy-(153*mp+2)/5+1); *m=(int)(mp<10 ? mp+3 : mp-9); *y=(int)(yoe+era*400+(*m<=2)); +} +static int32_t validate(const DateTime *t) { + if (t->year<1 || t->year>9999) return ERR_INVALID_YEAR; + if (t->month<1 || t->month>12) return ERR_INVALID_MONTH; + if (t->day<1 || t->day>days_in_month(t->year,t->month)) return ERR_INVALID_DAY; + if (t->hour>23) return ERR_INVALID_HOUR; + if (t->minute>59) return ERR_INVALID_MINUTE; + if (t->second>59) return ERR_INVALID_SECOND; + if (t->microsecond>999999) return ERR_INVALID_MICROSECOND; + return 0; +} +static uint64_t to_tick(const DateTime *t) { + return (uint64_t)days_from_civil(t->year,t->month,t->day)*TICKS_PER_DAY+ + ((uint64_t)t->hour*3600+(uint64_t)t->minute*60+t->second)*1000000+t->microsecond; +} +static void from_tick(uint64_t tick, DateTime *t) { + int y,m,d; + civil_from_days((int64_t)(tick/TICKS_PER_DAY),&y,&m,&d); + uint64_t us=tick%TICKS_PER_DAY; + t->year=(uint16_t)y; t->month=(uint16_t)m; t->day=(uint16_t)d; + t->hour=(uint16_t)(us/3600000000u); t->minute=(uint16_t)(us/60000000u%60); t->second=(uint16_t)(us/1000000u%60); + t->microsecond=(uint32_t)(us%1000000u); +} +static uint64_t now_utc(void) { + struct timespec ts; clock_gettime(CLOCK_REALTIME,&ts); + return UNIX_EPOCH_TICKS+(uint64_t)ts.tv_sec*1000000u+(uint64_t)ts.tv_nsec/1000u; +} +/* Offset of local time from UTC at the given UTC tick, in microseconds. */ +static int64_t local_offset(uint64_t utc) { + time_t seconds=(time_t)((int64_t)(utc-UNIX_EPOCH_TICKS)/1000000); + struct tm local; + localtime_r(&seconds,&local); + return (int64_t)local.tm_gmtoff*1000000; +} + +static ABI int32_t rtc_current_local(DateTime *t) { + if (!t) return ERR_INVALID_POINTER; + uint64_t utc=now_utc(); + from_tick((uint64_t)((int64_t)utc+local_offset(utc)),t); + return 0; +} +static ABI int32_t rtc_current_clock(DateTime *t, int32_t minutes) { + if (!t) return ERR_INVALID_POINTER; + from_tick((uint64_t)((int64_t)now_utc()+(int64_t)minutes*60000000),t); + return 0; +} +static ABI int32_t rtc_current_tick(uint64_t *tick) { if (!tick) return ERR_INVALID_POINTER; *tick=now_utc(); return 0; } +static ABI int32_t rtc_utc_to_local(const uint64_t *utc, uint64_t *local) { + if (!utc || !local) return ERR_INVALID_POINTER; + *local=(uint64_t)((int64_t)*utc+local_offset(*utc)); return 0; +} +static ABI int32_t rtc_local_to_utc(const uint64_t *local, uint64_t *utc) { + if (!local || !utc) return ERR_INVALID_POINTER; + *utc=(uint64_t)((int64_t)*local-local_offset(*local)); return 0; +} +static ABI int32_t rtc_day_of_week(int32_t year, int32_t month, int32_t day) { + if (year<1 || year>9999) return ERR_INVALID_YEAR; + if (month<1 || month>12) return ERR_INVALID_MONTH; + if (day<1 || day>days_in_month(year,month)) return ERR_INVALID_DAY; + return (int32_t)((days_from_civil(year,month,day)+1)%7); /* 0001-01-01 was a Monday */ +} +static ABI int32_t rtc_get_tick(const DateTime *t, uint64_t *tick) { + if (!t || !tick) return ERR_INVALID_POINTER; + int32_t e=validate(t); + if (e) return e; + *tick=to_tick(t); return 0; +} +static ABI int32_t rtc_set_tick(DateTime *t, const uint64_t *tick) { + if (!t || !tick) return ERR_INVALID_POINTER; + from_tick(*tick,t); return 0; +} +static ABI uint32_t rtc_tick_resolution(void) { return 1000000; } +static ABI int32_t rtc_set_time_t(DateTime *t, int64_t seconds) { + if (!t) return ERR_INVALID_POINTER; + if (seconds<0) return (int32_t)0x80B50003; /* INVALID_VALUE */ + from_tick(UNIX_EPOCH_TICKS+(uint64_t)seconds*1000000u,t); return 0; +} +static ABI int32_t rtc_get_time_t(const DateTime *t, int64_t *seconds) { + if (!t || !seconds) return ERR_INVALID_POINTER; + int32_t e=validate(t); + if (e) return e; + uint64_t tick=to_tick(t); + *seconds=tick +#include +#include +#ifndef _WIN32 +#include +#include +#include +typedef struct Holder { + pthread_t thread; + unsigned readers, writer, pending; + struct Holder *next; +} Holder; +typedef struct Rwlock { + pthread_rwlock_t native; + Holder *holders; + unsigned inflight; + struct Rwlock *next; +} Rwlock; +typedef struct { int64_t seconds, nanoseconds; } GuestTime; +static pthread_mutex_t registry_lock = PTHREAD_MUTEX_INITIALIZER; +static Rwlock *registry; +static size_t created, reads, writes, unlocks; +static int32_t error(int e) { + if (!e) return 0; + unsigned code; + switch(e) { + case EPERM: code=1; break; + case EDEADLK: code=11; break; + case ENOMEM: code=12; break; + case EBUSY: code=16; break; + case EINVAL: code=22; break; + case EAGAIN: code=35; break; + case ETIMEDOUT: code=60; break; + default: fprintf(stderr,"STOP: unmapped rwlock error %d\n",e); exit(21); + } + return (int32_t)(UINT32_C(0x80020000)|code); +} +/* All helpers ending in _locked require registry_lock. */ +static Rwlock *find_locked(Rwlock *handle) { + for (Rwlock *r=registry; r; r=r->next) if (r==handle) return r; + return NULL; +} +static int create_locked(Rwlock **out) { + Rwlock *r=calloc(1,sizeof(*r)); + if (!r) return ENOMEM; + int e=pthread_rwlock_init(&r->native,NULL); + if (e) { free(r); return e; } + r->next=registry; registry=r; *out=r; ++created; return 0; +} +static ABI int32_t rw_init(Rwlock **out, void *const *attr, const char *name) { + (void)name; + if (!out || (attr && !*attr)) return error(EINVAL); + if (attr) { fputs("STOP: non-default PS4 rwlock attributes are not implemented\n",stderr); exit(21); } + pthread_mutex_lock(®istry_lock); + /* POSIX allows uninitialized storage, so never read *out during init. */ + int e=create_locked(out); + pthread_mutex_unlock(®istry_lock); return error(e); +} +static void prune_locked(Rwlock *r, Holder *h) { + if (h->readers || h->writer || h->pending) return; + Holder **link=&r->holders; + while (*link!=h) link=&(*link)->next; + *link=h->next; free(h); +} +enum Operation { READ, WRITE, TRY_READ, TRY_WRITE, TIMED_READ, TIMED_WRITE }; +static int32_t acquire(Rwlock **handle, enum Operation op, const GuestTime *time) { + if (!handle) return error(EINVAL); + int writer=op==WRITE || op==TRY_WRITE || op==TIMED_WRITE; + int attempt=op==TRY_READ || op==TRY_WRITE; + int timed=op==TIMED_READ || op==TIMED_WRITE; + pthread_mutex_lock(®istry_lock); + int e=0; + if (!*handle) e=create_locked(handle); + Rwlock *r=e ? NULL : find_locked(*handle); + if (!r) { pthread_mutex_unlock(®istry_lock); return error(e ? e : EINVAL); } + Holder *h=r->holders; + while (h && !pthread_equal(h->thread,pthread_self())) h=h->next; + if (h && (h->writer || (writer && h->readers))) { + pthread_mutex_unlock(®istry_lock); return error(attempt ? EBUSY : EDEADLK); + } + if (h && h->readers==UINT_MAX) { pthread_mutex_unlock(®istry_lock); return error(EAGAIN); } + if (!h) { + h=calloc(1,sizeof(*h)); + if (!h) { pthread_mutex_unlock(®istry_lock); return error(ENOMEM); } + h->thread=pthread_self(); h->next=r->holders; r->holders=h; + } + ++r->inflight; ++h->pending; + pthread_mutex_unlock(®istry_lock); + /* Timed operations first try the lock, matching POSIX timeout validation. */ + if (attempt || timed) e=writer ? pthread_rwlock_trywrlock(&r->native) : pthread_rwlock_tryrdlock(&r->native); + else e=writer ? pthread_rwlock_wrlock(&r->native) : pthread_rwlock_rdlock(&r->native); + if (timed && e==EBUSY) { + if (!time || time->nanoseconds<0 || time->nanoseconds>=1000000000) e=EINVAL; + else { + struct timespec deadline={.tv_sec=(time_t)time->seconds,.tv_nsec=(long)time->nanoseconds}; + e=writer ? pthread_rwlock_timedwrlock(&r->native,&deadline) : pthread_rwlock_timedrdlock(&r->native,&deadline); + } + } + pthread_mutex_lock(®istry_lock); + --r->inflight; --h->pending; + if (!e) { + if (writer) { h->writer=1; ++writes; } + else { ++h->readers; ++reads; } + } + prune_locked(r,h); + pthread_mutex_unlock(®istry_lock); return error(e); +} +static ABI int32_t rw_read(Rwlock **r) { return acquire(r,READ,NULL); } +static ABI int32_t rw_write(Rwlock **r) { return acquire(r,WRITE,NULL); } +static ABI int32_t rw_tryread(Rwlock **r) { return acquire(r,TRY_READ,NULL); } +static ABI int32_t rw_trywrite(Rwlock **r) { return acquire(r,TRY_WRITE,NULL); } +static ABI int32_t rw_timedread(Rwlock **r,const GuestTime *t) { return acquire(r,TIMED_READ,t); } +static ABI int32_t rw_timedwrite(Rwlock **r,const GuestTime *t) { return acquire(r,TIMED_WRITE,t); } +static ABI int32_t rw_unlock(Rwlock **handle) { + if (!handle) return error(EINVAL); + pthread_mutex_lock(®istry_lock); + Rwlock *r=find_locked(*handle); + if (!r) { pthread_mutex_unlock(®istry_lock); return error(EINVAL); } + Holder *h=r->holders; + while (h && !pthread_equal(h->thread,pthread_self())) h=h->next; + if (!h || (!h->readers && !h->writer)) { pthread_mutex_unlock(®istry_lock); return error(EPERM); } + int e=pthread_rwlock_unlock(&r->native); + if (!e) { if (h->writer) h->writer=0; else --h->readers; ++unlocks; } + prune_locked(r,h); + pthread_mutex_unlock(®istry_lock); return error(e); +} +static ABI int32_t rw_destroy(Rwlock **handle) { + if (!handle) return error(EINVAL); + pthread_mutex_lock(®istry_lock); + if (!*handle) { pthread_mutex_unlock(®istry_lock); return 0; } + Rwlock *r=find_locked(*handle); + if (!r) { pthread_mutex_unlock(®istry_lock); return error(EINVAL); } + if (r->inflight || r->holders) { pthread_mutex_unlock(®istry_lock); return error(EBUSY); } + int e=pthread_rwlock_destroy(&r->native); + if (!e) { + Rwlock **link=®istry; + while (*link!=r) link=&(*link)->next; + *link=r->next; free(r); *handle=(Rwlock *)(uintptr_t)1; + } + pthread_mutex_unlock(®istry_lock); return error(e); +} +uintptr_t runtime_rwlock_resolve(const char *name) { + if (!strcmp(name,"6ULAa0fq4jA#p#J")) return (uintptr_t)rw_init; + if (!strcmp(name,"BB+kb08Tl9A#p#J")) return (uintptr_t)rw_destroy; + if (!strcmp(name,"Ox9i0c7L5w0#p#J")) return (uintptr_t)rw_read; + if (!strcmp(name,"mqdNorrB+gI#p#J")) return (uintptr_t)rw_write; + if (!strcmp(name,"XD3mDeybCnk#p#J")) return (uintptr_t)rw_tryread; + if (!strcmp(name,"bIHoZCTomsI#p#J")) return (uintptr_t)rw_trywrite; + if (!strcmp(name,"+L98PIbGttk#p#J")) return (uintptr_t)rw_unlock; + if (!strcmp(name,"iPtZRWICjrM#p#J")) return (uintptr_t)rw_timedread; + if (!strcmp(name,"adh--6nIqTk#p#J")) return (uintptr_t)rw_timedwrite; + return 0; +} +void runtime_rwlock_report(void) { + pthread_mutex_lock(®istry_lock); + printf("Runtime: rwlocks created=%zu, reads=%zu, writes=%zu, unlocks=%zu\n",created,reads,writes,unlocks); + pthread_mutex_unlock(®istry_lock); +} +#else +uintptr_t runtime_rwlock_resolve(const char *name) { (void)name; return 0; } +void runtime_rwlock_report(void) { puts("Runtime: Windows rwlock backend not implemented"); } +#endif diff --git a/runtime_savedata.c b/runtime_savedata.c new file mode 100644 index 0000000..7a5fc57 --- /dev/null +++ b/runtime_savedata.c @@ -0,0 +1,325 @@ +/* libSceSaveData on host directories: + * /savedata///<dir name>/ files the game writes + * <user>/savedata/<user id>/<title id>/<dir name>.sce_sys/ param.bin, icon0.png + * <user>/savedata/<user id>/<title id>.memory/memory.dat SaveDataMemory + * A mounted directory appears to the guest as /savedata0../savedata15. + * Metadata lives beside the directory so the guest's own files are untouched. */ +#define _GNU_SOURCE +#include "runtime.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include <time.h> +#ifndef _WIN32 +#include <dirent.h> +#include <errno.h> +#include <ftw.h> +#include <sys/stat.h> +#include <unistd.h> + +#define ERR_PARAMETER ((int32_t)0x809F0000) +#define ERR_NOT_INITIALIZED ((int32_t)0x809F0001) +#define ERR_NOT_MOUNTED ((int32_t)0x809F0004) +#define ERR_EXISTS ((int32_t)0x809F0007) +#define ERR_NOT_FOUND ((int32_t)0x809F0008) +#define ERR_INTERNAL ((int32_t)0x809F000B) +#define ERR_MOUNT_FULL ((int32_t)0x809F000C) +#define ERR_BAD_MOUNTED ((int32_t)0x809F000D) +#define ERR_INVALID_USER ((int32_t)0x809F0011) +#define ERR_MEMORY_NOT_READY ((int32_t)0x809F0012) +#define MODE_RDONLY 1 +#define MODE_CREATE 4 +#define MODE_COPY_ICON 16 +#define MODE_CREATE2 32 +#define SLOTS 16 + +typedef struct { char data[10]; char pad[6]; } TitleId; +typedef struct { char data[32]; } DirName; +typedef struct { char data[16]; } MountPoint; +typedef struct { + char title[128], subtitle[128], detail[1024]; + uint32_t user_param; int32_t pad; + int64_t mtime; + uint8_t reserved[32]; +} Param; +typedef struct { int32_t user; int32_t pad; const TitleId *title; const DirName *dir; const void *fingerprint; + uint64_t blocks; uint32_t mode; uint8_t reserved[32]; } Mount1; +typedef struct { int32_t user; int32_t pad; const DirName *dir; uint64_t blocks; uint32_t mode; + uint8_t reserved[32]; int32_t pad2; } Mount2; +typedef struct { MountPoint point; uint64_t required_blocks; uint32_t unused, status; uint8_t reserved[28]; int32_t pad; } MountResult; +typedef struct { int32_t user; int32_t pad; const TitleId *title; const DirName *dir; uint32_t unused; + uint8_t reserved[32]; int32_t pad2; } Delete; +typedef struct { int32_t user; int32_t pad; const TitleId *title; const DirName *dir; uint32_t key, order; + uint8_t reserved[32]; } SearchCond; +typedef struct { uint64_t blocks, free_blocks; uint8_t reserved[32]; } SearchInfo; +typedef struct { uint32_t hits; int32_t pad; DirName *names; uint32_t names_capacity, set_count; + Param *params; SearchInfo *infos; uint8_t reserved[12]; int32_t pad2; } SearchResult; +typedef struct { const void *buffer; uint64_t buffer_size, data_size; uint8_t reserved[32]; } Icon; +_Static_assert(sizeof(Param)==1328,"OrbisSaveDataParam layout"); +_Static_assert(sizeof(Mount1)==80 && sizeof(Mount2)==64,"OrbisSaveDataMount layouts"); +_Static_assert(sizeof(MountResult)==64,"OrbisSaveDataMountResult layout"); +_Static_assert(sizeof(SearchCond)==64 && sizeof(SearchResult)==56,"dir name search layouts"); + +static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; +static int initialized; +static char title_id[16]="UNKNOWN"; +static struct { int used; char host[700], meta[700]; } slots[SLOTS]; +static char memory_path[720]; +static uint64_t memory_size; +static size_t mounts_done, memory_writes; + +void runtime_savedata_configure(const char *title) { if (title && *title) snprintf(title_id,sizeof(title_id),"%s",title); } + +static int make_dirs(const char *path) { + char buffer[700]; + snprintf(buffer,sizeof(buffer),"%s",path); + for (char *p=buffer+1;*p;++p) if (*p=='/') { *p=0; mkdir(buffer,0755); *p='/'; } + return mkdir(buffer,0755) && errno!=EEXIST ? -1 : 0; +} +static void root(int32_t user, const char *title, char *out, size_t size) { + snprintf(out,size,"%s/savedata/%d/%s",runtime_file_user_dir(),user,title && *title ? title : title_id); +} +static int valid_name(const char *name, size_t max) { + size_t n=strnlen(name,max); + if (!n || n==max) return 0; + for (size_t i=0;i<n;++i) if (name[i]=='/' || name[i]=='\\' || (name[i]=='.' && (i==0 || name[i-1]=='.'))) return 0; + return 1; +} +static void write_param(const char *meta, const Param *p) { + char path[700]; snprintf(path,sizeof(path),"%s/param.bin",meta); + FILE *f=fopen(path,"wb"); + if (f) { Param copy=*p; copy.mtime=time(NULL); fwrite(©,sizeof(copy),1,f); fclose(f); } +} +static int read_param(const char *meta, Param *p) { + char path[700]; snprintf(path,sizeof(path),"%s/param.bin",meta); + memset(p,0,sizeof(*p)); + FILE *f=fopen(path,"rb"); + if (!f) return -1; + size_t n=fread(p,sizeof(*p),1,f); fclose(f); + struct stat st; + if (!stat(path,&st)) p->mtime=st.st_mtime; + return n==1 ? 0 : -1; +} +static int remove_entry(const char *path, const struct stat *st, int flag, struct FTW *ftw) { + (void)st; (void)flag; (void)ftw; return remove(path); +} + +static ABI int32_t save_initialize(const void *param) { (void)param; initialized=1; return 0; } +static ABI int32_t save_terminate(void) { + if (!initialized) return ERR_NOT_INITIALIZED; + initialized=0; return 0; +} +static int32_t mount(int32_t user, const char *title, const DirName *dir, uint32_t mode, MountResult *result) { + if (!initialized) return ERR_NOT_INITIALIZED; + if (user<0) return ERR_INVALID_USER; + if (!dir || !result || !valid_name(dir->data,sizeof(dir->data))) return ERR_PARAMETER; + char base[600], host[640], meta[680]; + root(user,title,base,sizeof(base)); + snprintf(host,sizeof(host),"%s/%s",base,dir->data); + snprintf(meta,sizeof(meta),"%s/%s.sce_sys",base,dir->data); + struct stat st; + int exists=!stat(host,&st) && S_ISDIR(st.st_mode); + if ((mode & MODE_CREATE) && exists) return ERR_EXISTS; + if (!(mode & (MODE_CREATE|MODE_CREATE2)) && !exists) return ERR_NOT_FOUND; + pthread_mutex_lock(&lock); + int slot=-1; + for (int i=0;i<SLOTS;++i) { + if (slots[i].used && !strcmp(slots[i].host,host)) { pthread_mutex_unlock(&lock); return ERR_BAD_MOUNTED; } + if (!slots[i].used && slot<0) slot=i; + } + if (slot<0) { pthread_mutex_unlock(&lock); return ERR_MOUNT_FULL; } + if (!exists && (make_dirs(host) || make_dirs(meta))) { pthread_mutex_unlock(&lock); return ERR_INTERNAL; } + if (!exists) { Param empty={0}; write_param(meta,&empty); } + slots[slot].used=1; + snprintf(slots[slot].host,sizeof(slots[slot].host),"%s",host); + snprintf(slots[slot].meta,sizeof(slots[slot].meta),"%s",meta); + memset(result,0,sizeof(*result)); + char point[32]; + snprintf(point,sizeof(point),"/savedata%d",slot&15); + memcpy(result->point.data,point,strlen(point)+1); + result->status=exists ? 0 : 1; /* CREATED */ + runtime_file_mount(result->point.data,host); + ++mounts_done; + pthread_mutex_unlock(&lock); + printf("Runtime: save data '%s' mounted at %s (%s%s)\n",dir->data,result->point.data, + exists ? "existing" : "created",(mode & MODE_RDONLY) ? ", read-only" : ""); + return 0; +} +static ABI int32_t save_mount(const Mount1 *m, MountResult *result) { + if (!m) return ERR_PARAMETER; + return mount(m->user,m->title ? m->title->data : NULL,m->dir,m->mode,result); +} +static ABI int32_t save_mount2(const Mount2 *m, MountResult *result) { + if (!m) return ERR_PARAMETER; + return mount(m->user,NULL,m->dir,m->mode,result); +} +static int slot_of(const MountPoint *point) { + if (!point || strncmp(point->data,"/savedata",9)) return -1; + int slot=atoi(point->data+9); + return slot>=0 && slot<SLOTS && slots[slot].used ? slot : -1; +} +static ABI int32_t save_umount(const MountPoint *point) { + if (!initialized) return ERR_NOT_INITIALIZED; + pthread_mutex_lock(&lock); + int slot=slot_of(point); + if (slot>=0) { runtime_file_unmount(point->data); slots[slot].used=0; } + pthread_mutex_unlock(&lock); + return slot>=0 ? 0 : ERR_NOT_FOUND; +} +static ABI int32_t save_set_param(const MountPoint *point, uint32_t type, const void *buffer, uint64_t size) { + if (!initialized) return ERR_NOT_INITIALIZED; + if (!buffer) return ERR_PARAMETER; + pthread_mutex_lock(&lock); + int slot=slot_of(point); + if (slot<0) { pthread_mutex_unlock(&lock); return ERR_NOT_MOUNTED; } + Param p; read_param(slots[slot].meta,&p); + switch (type) { + case 0: if (size<sizeof(Param)) goto bad; memcpy(&p,buffer,sizeof(p)); break; /* ALL */ + case 1: snprintf(p.title,sizeof(p.title),"%.*s",(int)size,(const char *)buffer); break; + case 2: snprintf(p.subtitle,sizeof(p.subtitle),"%.*s",(int)size,(const char *)buffer); break; + case 3: snprintf(p.detail,sizeof(p.detail),"%.*s",(int)size,(const char *)buffer); break; + case 4: if (size<4) goto bad; memcpy(&p.user_param,buffer,4); break; + default: goto bad; + } + write_param(slots[slot].meta,&p); + pthread_mutex_unlock(&lock); + return 0; +bad: + pthread_mutex_unlock(&lock); + return ERR_PARAMETER; +} +static ABI int32_t save_icon(const MountPoint *point, const Icon *icon) { + if (!initialized) return ERR_NOT_INITIALIZED; + if (!icon || !icon->buffer) return ERR_PARAMETER; + pthread_mutex_lock(&lock); + int slot=slot_of(point); + int32_t r=ERR_NOT_MOUNTED; + if (slot>=0) { + char path[700]; snprintf(path,sizeof(path),"%s/icon0.png",slots[slot].meta); + FILE *f=fopen(path,"wb"); + r=f && fwrite(icon->buffer,1,icon->data_size,f)==icon->data_size ? 0 : ERR_INTERNAL; + if (f) fclose(f); + } + pthread_mutex_unlock(&lock); + return r; +} +static ABI int32_t save_delete(const Delete *d) { + if (!initialized) return ERR_NOT_INITIALIZED; + if (!d || !d->dir || !valid_name(d->dir->data,sizeof(d->dir->data))) return ERR_PARAMETER; + char base[600], host[640], meta[680]; + root(d->user,d->title ? d->title->data : NULL,base,sizeof(base)); + snprintf(host,sizeof(host),"%s/%s",base,d->dir->data); + snprintf(meta,sizeof(meta),"%s/%s.sce_sys",base,d->dir->data); + struct stat st; + if (stat(host,&st)) return ERR_NOT_FOUND; + nftw(host,remove_entry,16,FTW_DEPTH|FTW_PHYS); + nftw(meta,remove_entry,16,FTW_DEPTH|FTW_PHYS); + printf("Runtime: save data '%s' deleted\n",d->dir->data); + return 0; +} +/* SQL-LIKE pattern: % any run, _ one character. */ +static int like(const char *s, const char *p) { + if (!*p) return !*s; + if (*p=='%') { for (;;++s) { if (like(s,p+1)) return 1; if (!*s) return 0; } } + return *s && (*p=='_' || *p==*s) && like(s+1,p+1); +} +typedef struct { char name[32]; Param param; } Entry; +static uint32_t sort_key, sort_order; +static int compare(const void *a, const void *b) { + const Entry *x=a, *y=b; + int c = sort_key==1 ? (x->param.user_param>y->param.user_param)-(x->param.user_param<y->param.user_param) + : sort_key==3 ? (x->param.mtime>y->param.mtime)-(x->param.mtime<y->param.mtime) + : strcmp(x->name,y->name); + return sort_order ? -c : c; +} +static ABI int32_t save_search(const SearchCond *cond, SearchResult *result) { + if (!initialized) return ERR_NOT_INITIALIZED; + if (!cond || !result) return ERR_PARAMETER; + char base[600]; + root(cond->user,cond->title ? cond->title->data : NULL,base,sizeof(base)); + Entry *entries=NULL; size_t count=0, capacity=0; + DIR *d=opendir(base); + for (struct dirent *e; d && (e=readdir(d));) { + size_t n=strlen(e->d_name); + if (e->d_name[0]=='.' || n>=32 || (n>8 && !strcmp(e->d_name+n-8,".sce_sys"))) continue; + if (cond->dir && cond->dir->data[0] && !like(e->d_name,cond->dir->data)) continue; + if (count==capacity) { capacity=capacity ? capacity*2 : 16; entries=realloc(entries,capacity*sizeof(*entries)); } + snprintf(entries[count].name,32,"%s",e->d_name); + char meta[680]; snprintf(meta,sizeof(meta),"%s/%s.sce_sys",base,e->d_name); + read_param(meta,&entries[count].param); + ++count; + } + if (d) closedir(d); + sort_key=cond->key; sort_order=cond->order; + if (count) qsort(entries,count,sizeof(*entries),compare); + result->hits=(uint32_t)count; + uint32_t set=count<result->names_capacity ? (uint32_t)count : result->names_capacity; + for (uint32_t i=0;i<set;++i) { + if (result->names) memcpy(result->names[i].data,entries[i].name,32); + if (result->params) result->params[i]=entries[i].param; + if (result->infos) { memset(&result->infos[i],0,sizeof(SearchInfo)); result->infos[i].blocks=32768; result->infos[i].free_blocks=16384; } + } + result->set_count=set; + free(entries); + return 0; +} +/* SaveDataMemory: one fixed-size blob per user/title. */ +static ABI int32_t memory_setup(int32_t user, uint64_t size, const Param *param) { + if (!initialized) return ERR_NOT_INITIALIZED; + if (!size) return ERR_PARAMETER; + char base[600], dir[640]; + root(user,NULL,base,sizeof(base)); + snprintf(dir,sizeof(dir),"%s.memory",base); + if (make_dirs(dir)) return ERR_INTERNAL; + pthread_mutex_lock(&lock); + snprintf(memory_path,sizeof(memory_path),"%s/memory.dat",dir); + FILE *f=fopen(memory_path,"r+b"); + if (!f) f=fopen(memory_path,"w+b"); + int32_t r=ERR_INTERNAL; + if (f) { + fseek(f,0,SEEK_END); + if ((uint64_t)ftell(f)<size && ftruncate(fileno(f),(off_t)size)) goto done; + memory_size=size; r=0; + done: + fclose(f); + } + if (!r && param) write_param(dir,param); + pthread_mutex_unlock(&lock); + if (!r) printf("Runtime: save data memory ready (%llu bytes)\n",(unsigned long long)size); + return r; +} +static int32_t memory_io(void *buffer, uint64_t size, int64_t offset, int write) { + if (!initialized) return ERR_NOT_INITIALIZED; + if (!buffer || offset<0) return ERR_PARAMETER; + pthread_mutex_lock(&lock); + if (!memory_size) { pthread_mutex_unlock(&lock); return ERR_MEMORY_NOT_READY; } + if ((uint64_t)offset+size>memory_size) { pthread_mutex_unlock(&lock); return ERR_PARAMETER; } + FILE *f=fopen(memory_path,"r+b"); + int32_t r=ERR_INTERNAL; + if (f && !fseek(f,offset,SEEK_SET) && + (write ? fwrite(buffer,1,size,f) : fread(buffer,1,size,f))==size) r=0; + if (f) fclose(f); + if (!r && write) ++memory_writes; + pthread_mutex_unlock(&lock); + return r; +} +static ABI int32_t memory_get(int32_t user, void *buffer, uint64_t size, int64_t offset) { (void)user; return memory_io(buffer,size,offset,0); } +static ABI int32_t memory_set(int32_t user, void *buffer, uint64_t size, int64_t offset) { (void)user; return memory_io(buffer,size,offset,1); } + +static const RuntimeExport exports[]={ + {"sceSaveDataInitialize",save_initialize}, {"sceSaveDataInitialize2",save_initialize}, + {"sceSaveDataInitialize3",save_initialize}, {"sceSaveDataTerminate",save_terminate}, + {"sceSaveDataMount",save_mount}, {"sceSaveDataMount2",save_mount2}, {"sceSaveDataUmount",save_umount}, + {"sceSaveDataSetParam",save_set_param}, {"sceSaveDataSaveIcon",save_icon}, {"sceSaveDataDelete",save_delete}, + {"sceSaveDataDirNameSearch",save_search}, + {"sceSaveDataSetupSaveDataMemory",memory_setup}, {"sceSaveDataGetSaveDataMemory",memory_get}, + {"sceSaveDataSetSaveDataMemory",memory_set}, +}; +uintptr_t runtime_savedata_resolve(const char *name) { return RUNTIME_LOOKUP(exports,name); } +void runtime_savedata_report(void) { printf("Runtime: save data mounts=%zu, memory writes=%zu\n",mounts_done,memory_writes); } +#else +void runtime_savedata_configure(const char *title) { (void)title; } +uintptr_t runtime_savedata_resolve(const char *name) { (void)name; return 0; } +void runtime_savedata_report(void) {} +#endif diff --git a/runtime_sema.c b/runtime_sema.c new file mode 100644 index 0000000..0ec6df3 --- /dev/null +++ b/runtime_sema.c @@ -0,0 +1,183 @@ +/* Kernel semaphores: 32-bit IDs, counted tokens and FIFO waiters. + * Priority-ordered semaphores are approximated by FIFO order. */ +#define _GNU_SOURCE +#include "runtime.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef _WIN32 +#include <pthread.h> +#include <errno.h> +#include <time.h> +#define ERR(n) ((int32_t)(UINT32_C(0x80020000)|(n))) +typedef struct Waiter { + int32_t need, result; + int done; + pthread_cond_t event; + struct Waiter *next; +} Waiter; +typedef struct Sema { + uint32_t id, attr; + int32_t count, initial, maximum; + unsigned active; + int deleted; + Waiter *first; + struct Sema *next; +} Sema; +static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; +static Sema *registry; +static uint32_t next_id=1; +static size_t created, deleted, acquired, signaled, timed_out; +static Sema *find(uint32_t id) { + for (Sema *s=registry;s;s=s->next) if (s->id==id) return s; + return NULL; +} +static void host_check(int e) { + if (e) { fprintf(stderr,"STOP: semaphore host error %d\n",e); exit(21); } +} +static uint64_t now_ns(void) { + struct timespec t; + if (clock_gettime(CLOCK_MONOTONIC,&t)) { perror("clock_gettime"); exit(1); } + return (uint64_t)t.tv_sec*1000000000+(uint64_t)t.tv_nsec; +} +static ABI int32_t sem_create(uint32_t *out,const char *name,uint32_t attr, + int32_t initial,int32_t maximum,const void *options) { + if (!out || !name || attr>2 || initial<0 || maximum<=0 || initial>maximum) return ERR(22); + if (options) { fputs("STOP: semaphore options are not implemented\n",stderr); exit(21); } + Sema *s=calloc(1,sizeof(*s)); + if (!s) return ERR(12); + pthread_mutex_lock(&lock); + if (next_id==UINT32_MAX) { pthread_mutex_unlock(&lock); free(s); return ERR(28); } + s->id=next_id++; s->attr=attr; s->count=s->initial=initial; s->maximum=maximum; + s->next=registry; registry=s; *out=s->id; ++created; + printf("Runtime: semaphore id=%u, attr=%u, initial=%d, max=%d\n",s->id,attr,initial,maximum); + pthread_mutex_unlock(&lock); + return 0; +} +static int32_t wait_count(uint32_t id,int32_t need,uint32_t *timeout,int block) { + pthread_mutex_lock(&lock); + Sema *s=find(id); + int32_t result=0; + if (!s) result=ERR(3); + else if (need<=0 || need>s->maximum) result=ERR(22); + else if (s->count>=need) { s->count-=need; ++acquired; } + else if (!block) result=ERR(16); + else if (timeout && !*timeout) { result=ERR(60); ++timed_out; } + else { + /* Priority-ordered semaphores (attr 2) are served FIFO: there is no + PS4 priority scheduler, host threads run at equal priority. */ + if (getenv("BB_TRACE_SEMA")) fprintf(stderr,"Runtime: blocking wait on semaphore %u (need %d, count %d)\n",id,need,s->count); /* deadlock diagnosis */ + Waiter w={.need=need}; + pthread_condattr_t attr; + host_check(pthread_condattr_init(&attr)); + host_check(pthread_condattr_setclock(&attr,CLOCK_MONOTONIC)); + host_check(pthread_cond_init(&w.event,&attr)); + host_check(pthread_condattr_destroy(&attr)); + Waiter **tail=&s->first; + while (*tail) tail=&(*tail)->next; + *tail=&w; ++s->active; + uint64_t deadline=timeout ? now_ns()+(uint64_t)*timeout*1000 : 0; + struct timespec end={.tv_sec=(time_t)(deadline/1000000000),.tv_nsec=(long)(deadline%1000000000)}; + while (!w.done) { + int e=timeout ? pthread_cond_timedwait(&w.event,&lock,&end) : pthread_cond_wait(&w.event,&lock); + if (e==ETIMEDOUT && !w.done) { + Waiter **p=&s->first; + while (*p!=&w) p=&(*p)->next; + *p=w.next; w.result=ERR(60); w.done=1; ++timed_out; + } else if (e!=ETIMEDOUT) host_check(e); + } + result=w.result; + if (!result) ++acquired; + if (timeout) { + uint64_t now=now_ns(); + *timeout=result ? 0 : (uint32_t)(now>=deadline ? 0 : (deadline-now)/1000); + } + host_check(pthread_cond_destroy(&w.event)); + if (!--s->active && s->deleted) free(s); + } + pthread_mutex_unlock(&lock); + return result; +} +static ABI int32_t sem_wait(uint32_t id,int32_t need,uint32_t *timeout) { return wait_count(id,need,timeout,1); } +static ABI int32_t sem_poll(uint32_t id,int32_t need) { return wait_count(id,need,NULL,0); } +static ABI int32_t sem_signal(uint32_t id,int32_t count) { + pthread_mutex_lock(&lock); + Sema *s=find(id); + int32_t result=0; + if (!s) result=ERR(3); + else if (count<=0 || count>s->maximum-s->count) result=ERR(22); + else { + s->count+=count; ++signaled; + Waiter **p=&s->first; + while (*p) { + Waiter *w=*p; + if (w->need>s->count) { p=&w->next; continue; } + s->count-=w->need; *p=w->next; w->done=1; + host_check(pthread_cond_signal(&w->event)); + } + } + pthread_mutex_unlock(&lock); + return result; +} +static int32_t wake_all(Sema *s,int32_t result) { + int32_t count=0; + while (s->first) { + Waiter *w=s->first; s->first=w->next; + w->result=result; w->done=1; ++count; + host_check(pthread_cond_signal(&w->event)); + } + return count; +} +static ABI int32_t sem_cancel(uint32_t id,int32_t count,int32_t *waiters) { + pthread_mutex_lock(&lock); + Sema *s=find(id); + int32_t result=0; + if (!s) result=ERR(3); + else if (count>s->maximum) result=ERR(22); + else { + int32_t n=wake_all(s,ERR(85)); + if (waiters) *waiters=n; + s->count=count<0 ? s->initial : count; + } + pthread_mutex_unlock(&lock); + return result; +} +static ABI int32_t sem_delete(uint32_t id) { + pthread_mutex_lock(&lock); + Sema **p=®istry; + while (*p && (*p)->id!=id) p=&(*p)->next; + if (!*p) { pthread_mutex_unlock(&lock); return ERR(3); } + Sema *s=*p; *p=s->next; s->deleted=1; ++deleted; + wake_all(s,ERR(13)); + if (!s->active) free(s); + pthread_mutex_unlock(&lock); + return 0; +} +/* Read-only test/diagnostic snapshot, not exposed to guest code. */ +unsigned runtime_sema_waiters(uint32_t id) { + pthread_mutex_lock(&lock); + Sema *s=find(id); unsigned n=0; + if (s) for (Waiter *w=s->first;w;w=w->next) ++n; + pthread_mutex_unlock(&lock); + return n; +} +uintptr_t runtime_sema_resolve(const char *name) { + if (!strcmp(name,"188x57JYp0g#p#J")) return (uintptr_t)sem_create; + if (!strcmp(name,"Zxa0VhQVTsk#p#J")) return (uintptr_t)sem_wait; + if (!strcmp(name,"4czppHBiriw#p#J")) return (uintptr_t)sem_signal; + if (!strcmp(name,"12wOHk8ywb0#p#J")) return (uintptr_t)sem_poll; + if (!strcmp(name,"4DM06U2BNEY#p#J")) return (uintptr_t)sem_cancel; + if (!strcmp(name,"R1Jvn8bSCW8#p#J")) return (uintptr_t)sem_delete; + return 0; +} +void runtime_sema_report(void) { + pthread_mutex_lock(&lock); + printf("Runtime: semaphores created=%zu, deleted=%zu, acquired=%zu, signals=%zu, timeouts=%zu\n", + created,deleted,acquired,signaled,timed_out); + pthread_mutex_unlock(&lock); +} +#else +uintptr_t runtime_sema_resolve(const char *name) { (void)name; return 0; } +void runtime_sema_report(void) { puts("Runtime: Windows semaphore backend not implemented"); } +unsigned runtime_sema_waiters(uint32_t id) { (void)id; return 0; } +#endif diff --git a/runtime_services.c b/runtime_services.c new file mode 100644 index 0000000..8b233e9 --- /dev/null +++ b/runtime_services.c @@ -0,0 +1,473 @@ +/* System services for an offline, single-user console: + * - one local user (id 1) who is logged in but not signed in to PSN; + * - network cable unplugged: NetCtl disconnected, sockets unavailable; + * - common dialogs complete immediately (no UI is drawn yet); + * - the whole package is installed (PlayGo reports every chunk local). + * Every entry here is an explicit contract; unknown functions still stop. */ +#define _GNU_SOURCE +#include "runtime.h" +#include "gpu/bbgpu.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef _WIN32 +#include <pthread.h> +#include <time.h> +#include <arpa/inet.h> + +#define USER_ID 1 +#define ORBIS_OK 0 +#define USER_INVALID_ARGUMENT ((int32_t)0x80960005) +#define USER_NO_EVENT ((int32_t)0x80960007) +#define SYSTEM_NO_EVENT ((int32_t)0x80A10004) +#define SYSTEM_PARAMETER ((int32_t)0x80A10003) +#define NET_CTL_NOT_CONNECTED ((int32_t)0x80412108) +#define NET_CTL_INVALID_ADDR ((int32_t)0x80412107) +#define NP_SIGNED_OUT ((int32_t)0x80550006) +#define NP_INVALID_ARGUMENT ((int32_t)0x80550003) +#define NET_ENETUNREACH ((int32_t)0x80410133) +#define NET_EINVAL ((int32_t)0x80410116) +#define HTTP_NETWORK ((int32_t)0x80431063) +#define DIALOG_NOT_INITIALIZED ((int32_t)0x80B80003) +#define PLAYGO_BAD_HANDLE ((int32_t)0x80B20009) +#define PLAYGO_BAD_POINTER ((int32_t)0x80B2000A) +#define PLAYGO_BAD_SIZE ((int32_t)0x80B2000B) +#define PLAYGO_BAD_CHUNK ((int32_t)0x80B2000C) +#define AUDIO_IN_NOT_OPENED ((int32_t)0x80260109) +#define TROPHY_INVALID ((int32_t)0x80551604) + +static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; +static int next_id=1; +static int new_id(void) { pthread_mutex_lock(&lock); int id=next_id++; pthread_mutex_unlock(&lock); return id; } +static void note(const char *what) { printf("Runtime: %s\n",what); } + +/* ---- UserService ---- */ +static int login_event_pending=1; +static ABI int32_t user_initialize(const void *params) { (void)params; note("UserService initialized (user 1 logged in)"); return 0; } +static ABI int32_t user_terminate(void) { return 0; } +static ABI int32_t user_initial(int32_t *id) { if (!id) return USER_INVALID_ARGUMENT; *id=USER_ID; return 0; } +static ABI int32_t user_list(int32_t *ids) { + if (!ids) return USER_INVALID_ARGUMENT; + ids[0]=USER_ID; ids[1]=ids[2]=ids[3]=-1; return 0; +} +static ABI int32_t user_name(int32_t id,char *name,uint64_t size) { + if (id!=USER_ID || !name) return USER_INVALID_ARGUMENT; + const char *value=getenv("BB_USER_NAME") ? getenv("BB_USER_NAME") : "Hunter"; + if (strlen(value)+1>size) return (int32_t)0x8096000a; /* BUFFER_TOO_SHORT */ + strcpy(name,value); return 0; +} +static ABI int32_t user_event(int32_t *event) { + if (!event) return USER_INVALID_ARGUMENT; + pthread_mutex_lock(&lock); + int pending=login_event_pending; login_event_pending=0; + pthread_mutex_unlock(&lock); + if (!pending) return USER_NO_EVENT; + event[0]=0; event[1]=USER_ID; /* LOGIN */ + return 0; +} + +/* ---- SystemService ---- */ +static int language(void) { const char *v=getenv("BB_LANGUAGE"); return v ? atoi(v) : 1; } +static ABI int32_t system_param(int32_t id,int32_t *value) { + if (!value) return SYSTEM_PARAMETER; + switch (id) { + case 1: *value=language(); break; /* language (1 = English US, 8 = Russian) */ + case 2: *value=1; break; /* date format DD/MM/YYYY */ + case 3: *value=1; break; /* 24-hour clock */ + case 4: { time_t now=time(NULL); struct tm t; localtime_r(&now,&t); *value=(int32_t)(t.tm_gmtoff/60); break; } + case 5: *value=0; break; /* summer time */ + case 7: *value=0; break; /* parental level off */ + case 1000: *value=1; break; /* enter button = cross */ + default: fprintf(stderr,"STOP: unsupported system parameter %d\n",id); exit(21); + } + return 0; +} +static ABI int32_t system_status(unsigned char *status) { + if (!status) return SYSTEM_PARAMETER; + memset(status,0,12); /* event_num=0, no overlay, foreground, normal CPU mode */ + return 0; +} +static ABI int32_t system_event(void *event) { (void)event; return SYSTEM_NO_EVENT; } +static ABI int32_t hide_splash(void) { note("SystemService: splash screen hidden"); return 0; } +static ABI int32_t launch_browser(void) { note("SystemService: web browser request ignored (offline)"); return 0; } + +/* ---- NetCtl / Net / Http / Ssl: no network ---- */ +static int32_t net_errno; +static ABI int32_t net_init(void) { return 0; } +static ABI int32_t net_term(void) { return 0; } +static ABI int32_t *net_errno_loc(void) { return &net_errno; } +static ABI int32_t net_pool_create(const char *name,int size,int flags) { (void)name; (void)size; (void)flags; return new_id(); } +static ABI int32_t net_pool_destroy(int id) { (void)id; return 0; } +static ABI int32_t net_unreachable(void) { net_errno=51; return NET_ENETUNREACH; } +static ABI int32_t net_epoll_create(const char *name,int flags) { (void)name; (void)flags; return new_id(); } +static ABI int32_t net_epoll_destroy(int id) { (void)id; return 0; } +static ABI int32_t net_resolver_create(const char *name,int pool,int flags) { (void)name; (void)pool; (void)flags; return new_id(); } +static ABI int32_t net_resolver_destroy(int id) { (void)id; return 0; } +static ABI uint16_t net_htons(uint16_t v) { return htons(v); } +static ABI uint16_t net_ntohs(uint16_t v) { return ntohs(v); } +static ABI uint32_t net_htonl(uint32_t v) { return htonl(v); } +static ABI uint32_t net_ntohl(uint32_t v) { return ntohl(v); } +static ABI int32_t net_pton(int af,const char *src,void *dst) { + if (af!=2) { net_errno=47; return NET_EINVAL; } + return inet_pton(AF_INET,src,dst); +} +static ABI const char *net_ntop(int af,const void *src,char *dst,uint32_t size) { + if (af!=2) { net_errno=47; return NULL; } + return inet_ntop(AF_INET,src,dst,size); +} +static ABI int32_t netctl_state(int32_t *state) { if (!state) return NET_CTL_INVALID_ADDR; *state=0; return 0; } +static ABI int32_t netctl_info(int code,void *info) { (void)code; (void)info; return NET_CTL_NOT_CONNECTED; } +static ABI int32_t netctl_register(void *cb,void *arg,int32_t *cid) { (void)cb; (void)arg; if (!cid) return NET_CTL_INVALID_ADDR; *cid=new_id(); return 0; } +static ABI int32_t netctl_check(void) { return 0; } +static ABI int32_t netctl_unregister(int cid) { (void)cid; return 0; } +static ABI int32_t netctl_nat(uint32_t *info) { + if (!info) return NET_CTL_INVALID_ADDR; + info[1]=0; info[2]=3; info[3]=0; /* stun failed, NAT type 3, no mapped address */ + return 0; +} +static ABI int32_t lib_init_id(void) { return new_id(); } +static ABI int32_t ok_void(void) { return 0; } +static ABI int32_t http_fail(void) { return HTTP_NETWORK; } +/* Objects are created so setup code proceeds; any transfer fails as unplugged. */ +static ABI int32_t http_object(void) { return new_id(); } +static ABI int32_t http_epoll(int32_t ctx,void **handle) { + (void)ctx; + if (!handle) return (int32_t)0x80431077; /* HTTP INVALID_VALUE */ + *handle=(void *)(uintptr_t)(0x100+new_id()); return 0; +} +static ABI int32_t http_wait(void *handle,void *events,int32_t max,int64_t timeout) { + (void)handle; (void)events; (void)max; + if (timeout>0) { struct timespec t={timeout/1000000,(timeout%1000000)*1000}; nanosleep(&t,NULL); } + return 0; /* no events: nothing is in flight */ +} + +/* ---- NP (PSN): signed out ---- */ +static ABI int32_t np_state(int32_t user,int32_t *state) { + if (!state) return NP_INVALID_ARGUMENT; + (void)user; *state=1; /* SIGNED_OUT */ + return 0; +} +static ABI int32_t np_signed_out(void) { return NP_SIGNED_OUT; } +static ABI int32_t np_register(void *cb,void *arg) { (void)cb; (void)arg; return new_id(); } +static ABI void np_register_void(void *cb,void *arg) { (void)cb; (void)arg; } +static ABI int32_t np_request(const void *param) { (void)param; return new_id(); } +static ABI int32_t np_request_ctx(int32_t ctx,const void *param) { (void)ctx; (void)param; return new_id(); } +static ABI int32_t np_poll(int32_t request,int32_t *result) { (void)request; if (result) *result=NP_SIGNED_OUT; return 0; } +static ABI int32_t np_compare(const void *a,const void *b) { + if (!a || !b) return NP_INVALID_ARGUMENT; + return memcmp(a,b,16) ? (int32_t)0x80550609 : 0; /* NP_UTIL NOT_MATCH */ +} + +/* ---- Voice chat: ports exist, carry no audio ---- */ +static ABI int32_t voice_port(void *param,uint32_t *port) { (void)param; if (!port) return (int32_t)0x8029000b; *port=(uint32_t)new_id(); return 0; } +static ABI int32_t voice_read(uint32_t port,void *data,uint32_t *size) { (void)port; (void)data; if (size) *size=0; return 0; } +static ABI int32_t voice_write(uint32_t port,const void *data,uint32_t *size) { (void)port; (void)data; (void)size; return 0; } +static ABI int32_t voice_info(uint32_t port,uint32_t *info) { + (void)port; + if (!info) return (int32_t)0x8029000b; + memset(info,0,40); /* type, state=unconnected, no bytes available */ + return 0; +} + +/* ---- Common dialogs: nothing is displayed; an opened dialog finishes. ---- */ +typedef struct { const char *name; int initialized, status; } Dialog; +static Dialog dialogs[]={{"CommonDialog",0,0},{"MsgDialog",0,0},{"SaveDataDialog",0,0}, + {"NpProfileDialog",0,0},{"NpCommerceDialog",0,0},{"ImeDialog",0,0}}; +static int common_initialized; +static ABI int32_t common_init(void) { common_initialized=1; return 0; } +static int32_t dialog_init(int i) { + if (dialogs[i].initialized) return (int32_t)0x80B80004; + dialogs[i].initialized=1; dialogs[i].status=1; return 0; +} +static int32_t dialog_open(int i) { + if (!dialogs[i].initialized) return DIALOG_NOT_INITIALIZED; + printf("Runtime: %s opened; completed immediately (no dialog UI yet)\n",dialogs[i].name); + dialogs[i].status=3; return 0; +} +static int32_t dialog_status(int i) { return dialogs[i].status; } +static int32_t dialog_term(int i) { + if (!dialogs[i].initialized) return DIALOG_NOT_INITIALIZED; + dialogs[i].initialized=0; dialogs[i].status=0; return 0; +} +#define DIALOG(tag,i) \ + static ABI int32_t tag##_init(void) { return dialog_init(i); } \ + static ABI int32_t tag##_open(const void *p) { (void)p; return dialog_open(i); } \ + static ABI int32_t tag##_status(void) { return dialog_status(i); } \ + static ABI int32_t tag##_term(void) { return dialog_term(i); } +DIALOG(msg,1) DIALOG(save,2) DIALOG(profile,3) DIALOG(commerce,4) +static ABI int32_t profile_result(void *result) { if (result) memset(result,0,4); return 0; } +/* ImeDialog: text typed on the keyboard into the game window (title bar shows it). + * OrbisImeDialogParam: user, type, languages(8), enter label, method, filter, + * option, max length, char16 buffer, position, alignment, placeholder, title. */ +typedef struct { + int32_t user; uint32_t type; uint64_t languages; uint32_t enter_label, input_method; + void *filter; uint32_t option, max_length; uint16_t *buffer; + float x, y; uint32_t halign, valign; const uint16_t *placeholder, *title; int8_t reserved[16]; +} ImeParam; +static struct { int running, finished, end_status; uint16_t *buffer; uint32_t max_length; } ime; +static size_t utf16_to_utf8(const uint16_t *in, size_t limit, char *out, size_t size) { + size_t n=0; + for (size_t i=0; in && i<limit && in[i] && n+4<size; ++i) { + uint32_t c=in[i]; + if (c>=0xD800 && c<0xDC00 && i+1<limit && in[i+1]>=0xDC00 && in[i+1]<0xE000) { c=0x10000+((c-0xD800)<<10)+(in[i+1]-0xDC00); ++i; } + if (c<0x80) out[n++]=(char)c; + else if (c<0x800) { out[n++]=(char)(0xC0|c>>6); out[n++]=(char)(0x80|(c&63)); } + else if (c<0x10000) { out[n++]=(char)(0xE0|c>>12); out[n++]=(char)(0x80|((c>>6)&63)); out[n++]=(char)(0x80|(c&63)); } + else { out[n++]=(char)(0xF0|c>>18); out[n++]=(char)(0x80|((c>>12)&63)); out[n++]=(char)(0x80|((c>>6)&63)); out[n++]=(char)(0x80|(c&63)); } + } + out[n]=0; return n; +} +static void utf8_to_utf16(const char *in, uint16_t *out, uint32_t max) { + uint32_t n=0; + for (const unsigned char *p=(const unsigned char *)in; *p && n<max;) { + uint32_t c; int extra; + if (*p<0x80) { c=*p; extra=0; } else if ((*p&0xE0)==0xC0) { c=*p&31; extra=1; } + else if ((*p&0xF0)==0xE0) { c=*p&15; extra=2; } else { c=*p&7; extra=3; } + ++p; + for (int k=0;k<extra && (*p&0xC0)==0x80;++k) c=(c<<6)|(*p++&63); + if (c>=0x10000) { if (n+2>max) break; c-=0x10000; out[n++]=(uint16_t)(0xD800+(c>>10)); out[n++]=(uint16_t)(0xDC00+(c&1023)); } + else out[n++]=(uint16_t)c; + } + out[n<max ? n : max]=0; +} +static void ime_complete(int end_status, const char *text) { + if (!end_status && ime.buffer && ime.max_length) utf8_to_utf16(text,ime.buffer,ime.max_length); + ime.end_status=end_status; ime.finished=1; ime.running=0; + printf("Runtime: ImeDialog %s%s%s\n",end_status ? "cancelled" : "text: ",end_status ? "" : text,""); +} +static ABI int32_t ime_init(const ImeParam *param, const void *extended) { + (void)extended; + if (!param || !param->buffer || !param->max_length) return (int32_t)0x80BC0004; /* IME INVALID_ADDRESS */ + if (ime.running) return (int32_t)0x80BC0003; /* BUSY */ + memset(&ime,0,sizeof(ime)); + ime.buffer=param->buffer; ime.max_length=param->max_length; ime.running=1; + char initial[512], prompt[256]; + utf16_to_utf8(param->buffer,param->max_length,initial,sizeof(initial)); + utf16_to_utf8(param->title,128,prompt,sizeof(prompt)); + const char *preset=getenv("BB_IME_TEXT"); + if (preset) { ime_complete(0,preset); return 0; } + if (!bbgpu_text_input_begin(initial,prompt[0] ? prompt : "Text")) { + const char *name=getenv("BB_USER_NAME"); + ime_complete(0,name ? name : initial[0] ? initial : "Hunter"); + } else printf("Runtime: ImeDialog opened: type in the game window, Enter to confirm, Esc to cancel\n"); + return 0; +} +static ABI int32_t ime_status(void) { + if (ime.running) { + char text[512]; + int state=bbgpu_text_input_poll(text,sizeof(text)); + if (state) ime_complete(state==1 ? 0 : 1,text); + } + return ime.running ? 1 : ime.finished ? 2 : 0; /* Running / Finished / None */ +} +static ABI int32_t ime_result(uint32_t *result) { + if (!ime.finished) return (int32_t)0x80BC0101; /* DIALOG NOT_FINISHED */ + if (result) *result=(uint32_t)ime.end_status; + return 0; +} +static ABI int32_t ime_term(void) { memset(&ime,0,sizeof(ime)); return 0; } + +/* ---- Trophies: accepted locally, recorded in the log ---- */ +static ABI int32_t trophy_context(int32_t *ctx,int32_t user,uint32_t label,uint64_t options) { + (void)user; (void)label; (void)options; + if (!ctx) return TROPHY_INVALID; + *ctx=new_id(); return 0; +} +static ABI int32_t trophy_handle(int32_t *handle) { if (!handle) return TROPHY_INVALID; *handle=new_id(); return 0; } +static ABI int32_t trophy_register(int32_t ctx,int32_t handle,uint64_t options) { (void)ctx; (void)handle; (void)options; return 0; } +static ABI int32_t trophy_unlock(int32_t ctx,int32_t handle,int32_t id,int32_t *platinum) { + (void)ctx; (void)handle; + printf("Runtime: trophy %d unlocked\n",id); + if (platinum) *platinum=-1; + return 0; +} +static ABI int32_t trophy_game_info(int32_t ctx,int32_t handle,void *details,void *data) { + (void)ctx; (void)handle; + if (details) { uint64_t size; memcpy(&size,details,8); memset((char *)details+8,0,size>8 && size<4096 ? size-8 : 0); } + if (data) { uint64_t size; memcpy(&size,data,8); memset((char *)data+8,0,size>8 && size<4096 ? size-8 : 0); } + return 0; +} +static ABI int32_t trophy_info(int32_t ctx,int32_t handle,int32_t id,void *details,void *data) { + (void)id; return trophy_game_info(ctx,handle,details,data); +} + +/* ---- PlayGo: fully installed package ---- */ +static int playgo_handle, playgo_chunks=-1; +static ABI int32_t playgo_init(const void *params) { + (void)params; + int fd=(int)runtime_file_open("/app0/sce_sys/playgo-chunk.dat",0,0); + unsigned char header[12]; + playgo_chunks=1; + if (fd>=0) { + if (runtime_file_read(fd,header,sizeof(header))==sizeof(header)) playgo_chunks=header[10]|header[11]<<8; + runtime_file_close(fd); + } + printf("Runtime: PlayGo initialized; %d chunks, all installed locally\n",playgo_chunks); + return 0; +} +static ABI int32_t playgo_open(int32_t *handle,const void *param) { + (void)param; + if (!handle) return PLAYGO_BAD_POINTER; + playgo_handle=1; *handle=1; return 0; +} +static ABI int32_t playgo_chunk_ids(int32_t handle,uint16_t *ids,uint32_t count,uint32_t *out) { + if (handle!=playgo_handle || !handle) return PLAYGO_BAD_HANDLE; + if (!out) return PLAYGO_BAD_POINTER; + if (ids && !count) return PLAYGO_BAD_SIZE; + if (!ids) { *out=(uint32_t)playgo_chunks; return 0; } + uint32_t n=count<(uint32_t)playgo_chunks ? count : (uint32_t)playgo_chunks; + for (uint32_t i=0;i<n;++i) ids[i]=(uint16_t)i; + *out=n; return 0; +} +static ABI int32_t playgo_locus(int32_t handle,const uint16_t *ids,uint32_t count,int8_t *loci) { + if (handle!=playgo_handle || !handle) return PLAYGO_BAD_HANDLE; + if (!ids || !loci) return PLAYGO_BAD_POINTER; + if (!count) return PLAYGO_BAD_SIZE; + for (uint32_t i=0;i<count;++i) { + if (ids[i]>=playgo_chunks) return PLAYGO_BAD_CHUNK; + loci[i]=3; /* LocalFast */ + } + return 0; +} +static ABI int32_t playgo_speed(int32_t handle,int32_t speed) { (void)speed; return handle==playgo_handle && handle ? 0 : PLAYGO_BAD_HANDLE; } + +/* ---- DiscMap: the game is fully installed, no disc bitmap exists ---- */ +#define DISC_MAP_NO_BITMAP ((int32_t)0x81100004) +static ABI int32_t discmap_on_hdd(const char *path,int64_t offset,int64_t size,int32_t *result) { + (void)path; (void)offset; (void)size; (void)result; return DISC_MAP_NO_BITMAP; +} +static ABI int32_t discmap_8a82(const char *path,int64_t offset,int64_t size,int32_t *flags,int32_t *r1,int32_t *r2) { + (void)path; (void)offset; (void)size; (void)flags; (void)r1; (void)r2; return DISC_MAP_NO_BITMAP; +} + +/* ---- Devices that are absent: mouse, microphone, voice chat ---- */ +/* A mouse port opens but never reports a connected device. */ +static ABI int32_t mouse_open(int32_t user,int32_t type,int32_t index,const void *param) { (void)user; (void)type; (void)index; (void)param; return new_id(); } +static ABI int32_t mouse_read(int32_t handle,unsigned char *data,int32_t count) { + (void)handle; + if (!data || count<1) return (int32_t)0x80DF0001; + memset(data,0,40); return 1; /* timestamp 0, connected=false */ +} +static ABI int32_t mouse_close(int32_t handle) { (void)handle; return 0; } +static ABI int32_t audio_in_open(void) { return AUDIO_IN_NOT_OPENED; } + + +static const RuntimeExport exports[]={ + {"sceUserServiceInitialize",user_initialize}, {"sceUserServiceTerminate",user_terminate}, + {"sceUserServiceGetInitialUser",user_initial}, {"sceUserServiceGetLoginUserIdList",user_list}, + {"sceUserServiceGetUserName",user_name}, {"sceUserServiceGetEvent",user_event}, + {"sceSystemServiceParamGetInt",system_param}, {"sceSystemServiceGetStatus",system_status}, + {"sceSystemServiceReceiveEvent",system_event}, {"sceSystemServiceHideSplashScreen",hide_splash}, + {"sceSystemServiceLaunchWebBrowser",launch_browser}, + {"sceNetInit",net_init}, {"sceNetTerm",net_term}, {"sceNetErrnoLoc",net_errno_loc}, + {"sceNetPoolCreate",net_pool_create}, {"sceNetPoolDestroy",net_pool_destroy}, + {"sceNetEpollCreate",net_epoll_create}, {"sceNetEpollDestroy",net_epoll_destroy}, + {"sceNetResolverCreate",net_resolver_create}, {"sceNetResolverDestroy",net_resolver_destroy}, + {"sceNetHtons",net_htons}, {"sceNetNtohs",net_ntohs}, {"sceNetHtonl",net_htonl}, {"sceNetNtohl",net_ntohl}, + {"sceNetInetPton",net_pton}, {"sceNetInetNtop",net_ntop}, + {"sceNetSocket",net_unreachable}, {"sceNetConnect",net_unreachable}, {"sceNetBind",net_unreachable}, + {"sceNetListen",net_unreachable}, {"sceNetAccept",net_unreachable}, {"sceNetSend",net_unreachable}, + {"sceNetSendto",net_unreachable}, {"sceNetRecv",net_unreachable}, {"sceNetRecvfrom",net_unreachable}, + {"sceNetSetsockopt",net_unreachable}, {"sceNetGetsockopt",net_unreachable}, + {"sceNetGetsockname",net_unreachable}, {"sceNetShutdown",net_unreachable}, + {"sceNetSocketClose",net_unreachable}, {"sceNetSocketAbort",net_unreachable}, + {"sceNetEpollControl",net_unreachable}, {"sceNetEpollWait",net_unreachable}, {"sceNetEpollAbort",net_unreachable}, + {"sceNetResolverStartNtoa",net_unreachable}, {"sceNetResolverStartAton",net_unreachable}, + {"sceNetCtlGetState",netctl_state}, {"sceNetCtlGetInfo",netctl_info}, + {"sceNetCtlRegisterCallback",netctl_register}, {"sceNetCtlCheckCallback",netctl_check}, + {"sceNetCtlUnregisterCallback",netctl_unregister}, {"sceNetCtlGetNatInfo",netctl_nat}, + {"sceSslInit",lib_init_id}, {"sceSslTerm",ok_void}, + {"sceHttpInit",lib_init_id}, {"sceHttpTerm",ok_void}, + {"sceHttpCreateTemplate",http_object}, {"sceHttpDeleteTemplate",ok_void}, + {"sceHttpCreateConnectionWithURL",http_object}, {"sceHttpCreateRequestWithURL",http_object}, + {"sceHttpSendRequest",http_fail}, {"sceHttpCreateEpoll",http_epoll}, + {"sceHttpSetNonblock",ok_void}, {"sceHttpSetConnectTimeOut",ok_void}, + {"sceHttpsEnableOption",ok_void}, {"sceHttpsDisableOption",ok_void}, + {"sceHttpAddRequestHeader",ok_void}, {"sceHttpSetRequestContentLength",ok_void}, + {"sceHttpDeleteConnection",ok_void}, {"sceHttpDeleteRequest",ok_void}, + {"sceHttpAbortWaitRequest",ok_void}, {"sceHttpDestroyEpoll",ok_void}, + {"sceHttpSetEpoll",ok_void}, {"sceHttpUnsetEpoll",ok_void}, {"sceHttpWaitRequest",http_wait}, + {"sceHttpGetStatusCode",http_fail}, {"sceHttpGetResponseContentLength",http_fail}, + {"sceHttpReadData",http_fail}, + {"sceNpGetState",np_state}, {"sceNpGetOnlineId",np_signed_out}, {"sceNpGetNpId",np_signed_out}, + {"sceNpRegisterStateCallback",np_register}, {"sceNpUnregisterStateCallback",ok_void}, + {"sceNpRegisterGamePresenceCallback",np_register_void}, {"sceNpRegisterPlusEventCallback",np_register}, + {"sceNpUnregisterPlusEventCallback",ok_void}, {"sceNpCheckCallback",ok_void}, + {"sceNpSetNpTitleId",ok_void}, {"sceNpNotifyPlusFeature",ok_void}, {"sceNpSetContentRestriction",ok_void}, + {"sceNpCreateAsyncRequest",np_request}, {"sceNpDeleteRequest",ok_void}, {"sceNpAbortRequest",ok_void}, + {"sceNpPollAsync",np_poll}, {"sceNpCheckNpAvailability",np_signed_out}, + {"sceNpGetParentalControlInfo",np_signed_out}, {"sceNpCheckPlus",np_signed_out}, + {"sceNpGetGamePresenceStatus",np_signed_out}, + {"sceNpCmpNpId",np_compare}, {"sceNpCmpOnlineId",np_compare}, + {"sceNpAuthCreateAsyncRequest",np_request}, {"sceNpAuthDeleteRequest",ok_void}, + {"sceNpAuthPollAsync",np_poll}, {"sceNpAuthGetAuthorizationCode",np_signed_out}, + {"sceNpLookupCreateTitleCtx",np_request}, {"sceNpLookupDeleteTitleCtx",ok_void}, + {"sceNpLookupCreateAsyncRequest",np_request_ctx}, {"sceNpLookupDeleteRequest",ok_void}, + {"sceNpLookupAbortRequest",ok_void}, {"sceNpLookupPollAsync",np_poll}, {"sceNpLookupNpId",np_signed_out}, + {"sceNpScoreCreateNpTitleCtx",np_request_ctx}, {"sceNpScoreDeleteNpTitleCtx",ok_void}, + {"sceNpScoreCreateRequest",np_request}, {"sceNpScoreDeleteRequest",ok_void}, {"sceNpScoreAbortRequest",ok_void}, + {"sceNpWebApiInitialize",lib_init_id}, {"sceNpWebApiTerminate",ok_void}, + {"sceNpWebApiCreateContext",np_signed_out}, + {"sceNpWebApiCreateRequest",np_signed_out}, {"sceNpWebApiSendRequest",np_signed_out}, + {"sceNpWebApiDeleteRequest",ok_void}, {"sceNpWebApiAbortRequest",ok_void}, + {"sceNpWebApiDeleteContext",ok_void}, {"sceNpWebApiReadData",np_signed_out}, + {"sceNpWebApiGetHttpStatusCode",np_signed_out}, {"sceNpWebApiGetHttpResponseHeaderValue",np_signed_out}, + {"sceNpWebApiGetHttpResponseHeaderValueLength",np_signed_out}, + {"sceNpWebApiCreatePushEventFilter",np_signed_out}, {"sceNpWebApiDeletePushEventFilter",ok_void}, + {"sceNpWebApiRegisterPushEventCallback",np_signed_out}, {"sceNpWebApiUnregisterPushEventCallback",ok_void}, + {"sceNpWebApiUtilityParseNpId",np_signed_out}, + {"sceNpMatching2ContextStart",np_signed_out}, {"sceNpMatching2ContextStop",ok_void}, + {"sceNpMatching2DestroyContext",ok_void}, + {"sceNpMatching2RegisterContextCallback",ok_void}, {"sceNpMatching2RegisterLobbyEventCallback",ok_void}, + {"sceNpMatching2RegisterRoomEventCallback",ok_void}, {"sceNpMatching2RegisterSignalingCallback",ok_void}, + {"sceNpMatching2SetDefaultRequestOptParam",ok_void}, + {"sceNpMatching2CreateJoinRoom",np_signed_out}, {"sceNpMatching2JoinRoom",np_signed_out}, + {"sceNpMatching2LeaveRoom",np_signed_out}, {"sceNpMatching2SearchRoom",np_signed_out}, + {"sceNpMatching2GetServerId",np_signed_out}, {"sceNpMatching2GetWorldInfoList",np_signed_out}, + {"sceNpMatching2GetLobbyInfoList",np_signed_out}, {"sceNpMatching2JoinLobby",np_signed_out}, + {"sceNpMatching2LeaveLobby",np_signed_out}, {"sceNpMatching2GrantRoomOwner",np_signed_out}, + {"sceNpMatching2KickoutRoomMember",np_signed_out}, {"sceNpMatching2SetRoomDataExternal",np_signed_out}, + {"sceNpMatching2SetRoomDataInternal",np_signed_out}, {"sceNpMatching2SetRoomMemberDataInternal",np_signed_out}, + {"sceNpMatching2SignalingGetConnectionStatus",np_signed_out}, {"sceNpMatching2SignalingGetPingInfo",np_signed_out}, + {"sceNpSignalingDeleteContext",ok_void}, {"sceNpSignalingActivateConnection",np_signed_out}, + {"sceNpSignalingDeactivateConnection",ok_void}, {"sceNpSignalingGetConnectionStatus",np_signed_out}, + {"sceNpScoreCensorComment",np_signed_out}, {"sceNpScoreSanitizeComment",np_signed_out}, + {"sceNpScoreGetBoardInfo",np_signed_out}, {"sceNpScoreGetGameData",np_signed_out}, + {"sceNpScoreGetRankingByNpIdPcId",np_signed_out}, {"sceNpScoreGetRankingByRange",np_signed_out}, + {"sceNpScoreRecordGameData",np_signed_out}, {"sceNpScoreRecordScore",np_signed_out}, + {"sceNpScoreSetPlayerCharacterId",ok_void}, + {"sceVoiceCreatePort",voice_port}, {"sceVoiceDeletePort",ok_void}, + {"sceVoiceConnectIPortToOPort",ok_void}, {"sceVoiceDisconnectIPortFromOPort",ok_void}, + {"sceVoiceStart",ok_void}, {"sceVoiceStop",ok_void}, {"sceVoiceGetPortInfo",voice_info}, + {"sceVoiceReadFromOPort",voice_read}, {"sceVoiceWriteToIPort",voice_write}, + {"sceAudioInInput",audio_in_open}, {"sceAudioInClose",audio_in_open}, + {"sceNpMatching2Initialize",ok_void}, {"sceNpMatching2Terminate",ok_void}, + {"sceNpMatching2CreateContext",np_signed_out}, + {"sceNpSignalingInitialize",ok_void}, {"sceNpSignalingTerminate",ok_void}, + {"sceNpSignalingCreateContext",np_signed_out}, + {"sceCommonDialogInitialize",common_init}, + {"sceMsgDialogInitialize",msg_init}, {"sceMsgDialogOpen",msg_open}, + {"sceMsgDialogUpdateStatus",msg_status}, {"sceMsgDialogTerminate",msg_term}, + {"sceSaveDataDialogInitialize",save_init}, {"sceSaveDataDialogOpen",save_open}, + {"sceSaveDataDialogUpdateStatus",save_status}, {"sceSaveDataDialogTerminate",save_term}, + {"sceNpProfileDialogInitialize",profile_init}, {"sceNpProfileDialogOpen",profile_open}, + {"sceNpProfileDialogUpdateStatus",profile_status}, {"sceNpProfileDialogTerminate",profile_term}, + {"sceNpProfileDialogGetResult",profile_result}, + {"sceNpCommerceDialogInitialize",commerce_init}, {"sceNpCommerceDialogOpen",commerce_open}, + {"sceNpCommerceDialogUpdateStatus",commerce_status}, {"sceNpCommerceDialogTerminate",commerce_term}, + {"sceImeDialogInit",ime_init}, {"sceImeDialogGetStatus",ime_status}, {"sceImeDialogGetResult",ime_result}, + {"sceImeDialogTerm",ime_term}, {"sceImeDialogAbort",ime_term}, + {"sceNpTrophyCreateContext",trophy_context}, {"sceNpTrophyCreateHandle",trophy_handle}, + {"sceNpTrophyRegisterContext",trophy_register}, {"sceNpTrophyUnlockTrophy",trophy_unlock}, + {"sceNpTrophyGetGameInfo",trophy_game_info}, {"sceNpTrophyGetTrophyInfo",trophy_info}, + {"scePlayGoInitialize",playgo_init}, {"scePlayGoOpen",playgo_open}, {"scePlayGoGetChunkId",playgo_chunk_ids}, + {"scePlayGoGetLocus",playgo_locus}, {"scePlayGoSetInstallSpeed",playgo_speed}, + {"sceMouseInit",ok_void}, {"sceMouseOpen",mouse_open}, {"sceMouseRead",mouse_read}, {"sceMouseClose",mouse_close}, + {"sceAudioInOpen",audio_in_open}, + {"sceDiscMapIsRequestOnHDD",discmap_on_hdd}, {"sceDiscMap_8A828CAEE7EDD5E9",discmap_8a82}, + {"sceVoiceInit",ok_void}, {"sceVoiceEnd",ok_void}, +}; +uintptr_t runtime_services_resolve(const char *name) { return RUNTIME_LOOKUP(exports,name); } +#else +uintptr_t runtime_services_resolve(const char *name) { (void)name; return 0; } +#endif diff --git a/runtime_thread.c b/runtime_thread.c new file mode 100644 index 0000000..74a6af7 --- /dev/null +++ b/runtime_thread.c @@ -0,0 +1,361 @@ +/* Guest threads on host pthreads. Each guest thread owns a FreeBSD-style TCB + * (variant II: static TLS below the TCB). The loader rewrites the eboot's + * `mov rax, fs:[0]` into `mov rax, gs:[0]`, so GS base = guest TCB while glibc + * keeps FS. Priorities/affinity are recorded, not enforced by a PS4 scheduler. */ +#define _GNU_SOURCE +#include "runtime.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef _WIN32 +#include <pthread.h> +#include <sched.h> +#include <setjmp.h> +#include <errno.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/mman.h> +#include <asm/prctl.h> +#define ERR(n) ((int32_t)(UINT32_C(0x80020000)|(n))) +#define ATTR_MAGIC UINT32_C(0x41545452) +#define STACK_MARGIN (256*1024) +#define MIN_STACK (64*1024) +#define DEFAULT_STACK (1024*1024) +#define DEFAULT_PRIO 700 + +typedef void *(ABI *GuestEntry)(void *); +typedef struct ThreadAttr { + uint32_t magic; + int detached, policy, prio, inherit; + uint64_t stack, guard, affinity; + struct ThreadAttr *next; +} ThreadAttr; +typedef struct GuestThread { + /* Guest-visible TCB is allocated separately; this is the ScePthread handle. */ + uint64_t *tcb; + unsigned char *tls_block; + pthread_t host; + GuestEntry entry; + void *argument, *result; + ThreadAttr attr; + char name[32]; + int detached, finished, joined, host_owned; + jmp_buf exit_jump; + struct GuestThread *next; +} GuestThread; + +static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; +static ThreadAttr *attributes; +static GuestThread *threads; +static _Thread_local GuestThread *current; +static _Thread_local int32_t guest_errno; +static const unsigned char *tls_template; +static uint64_t tls_filesz, tls_memsz, tls_align=16; +static size_t created, joined_count, exited; + +void runtime_set_main_tls(const void *data,uint64_t filesz,uint64_t memsz,uint64_t align) { + tls_template=data; tls_filesz=filesz; tls_memsz=memsz; tls_align=align ? align : 16; +} +static uint64_t tls_offset(void) { return (tls_memsz+tls_align-1)&~(tls_align-1); } +static void set_gs(void *base) { + if (syscall(SYS_arch_prctl,ARCH_SET_GS,(unsigned long)base)) { perror("STOP: arch_prctl(ARCH_SET_GS)"); exit(21); } +} +/* Build TCB/static TLS for the calling host thread and point GS at it. */ +static void attach(GuestThread *t) { + uint64_t offset=tls_offset(); + size_t total=offset+256; + unsigned char *block=aligned_alloc(64,(total+63)&~(size_t)63); + if (!block) { fputs("Cannot allocate guest TLS\n",stderr); exit(1); } + memset(block,0,total); + if (tls_filesz) memcpy(block,tls_template,tls_filesz); + uint64_t *tcb=(uint64_t *)(block+offset); + static uint64_t dtv[3]; + tcb[0]=(uint64_t)(uintptr_t)tcb; /* tcb_self */ + tcb[1]=(uint64_t)(uintptr_t)dtv; /* tcb_dtv (static module only) */ + tcb[2]=(uint64_t)(uintptr_t)t; /* tcb_thread */ + t->tls_block=block; t->tcb=tcb; + set_gs(tcb); + current=t; +} +static GuestThread *new_thread(void) { + GuestThread *t=calloc(1,sizeof(*t)); + if (!t) return NULL; + t->attr=(ThreadAttr){.magic=ATTR_MAGIC,.policy=1,.prio=DEFAULT_PRIO,.stack=DEFAULT_STACK,.affinity=0x7f}; + return t; +} +static void publish(GuestThread *t) { + pthread_mutex_lock(&lock); t->next=threads; threads=t; pthread_mutex_unlock(&lock); +} +/* Host threads that call into guest code without being created by the guest + * (the main thread, test threads) get a record on first use. */ +GuestThread *runtime_thread_current(void) { + if (current) return current; + GuestThread *t=new_thread(); + if (!t) { fputs("Cannot allocate guest thread\n",stderr); exit(1); } + t->host=pthread_self(); t->host_owned=1; + snprintf(t->name,sizeof(t->name),"host"); + attach(t); publish(t); + return t; +} +/* Host threads that call guest code (HLE decoders invoking guest callbacks) need + * a TCB/TLS like guest threads; the record lives until process exit. */ +void runtime_thread_attach_host(const char *name) { + GuestThread *t=runtime_thread_current(); + snprintf(t->name,sizeof(t->name),"%s",name ? name : "host"); +} +void runtime_thread_attach_main(void) { + GuestThread *t=runtime_thread_current(); + snprintf(t->name,sizeof(t->name),"main"); +} +static GuestThread *find_thread(void *handle) { + GuestThread *found=NULL; + pthread_mutex_lock(&lock); + for (GuestThread *t=threads;t;t=t->next) if (t==handle) { found=t; break; } + pthread_mutex_unlock(&lock); + return found; +} +static ThreadAttr *find_attr(ThreadAttr **slot) { + if (!slot || !*slot) return NULL; + ThreadAttr *found=NULL; + pthread_mutex_lock(&lock); + for (ThreadAttr *a=attributes;a;a=a->next) if (a==*slot && a->magic==ATTR_MAGIC) { found=a; break; } + pthread_mutex_unlock(&lock); + return found; +} + +static ABI void *thread_self(void) { return runtime_thread_current(); } +static ABI int32_t *guest_error(void) { return &guest_errno; } +int32_t *runtime_errno(void) { return &guest_errno; } + +static ABI int32_t attr_init(ThreadAttr **out) { + if (!out) return ERR(22); + ThreadAttr *a=calloc(1,sizeof(*a)); + if (!a) return ERR(12); + *a=(ThreadAttr){.magic=ATTR_MAGIC,.policy=1,.prio=DEFAULT_PRIO,.inherit=4,.stack=DEFAULT_STACK,.guard=4096,.affinity=0x7f}; + pthread_mutex_lock(&lock); a->next=attributes; attributes=a; pthread_mutex_unlock(&lock); + *out=a; return 0; +} +static ABI int32_t attr_destroy(ThreadAttr **slot) { + ThreadAttr *a=find_attr(slot); + if (!a) return ERR(22); + pthread_mutex_lock(&lock); + ThreadAttr **link=&attributes; + while (*link!=a) link=&(*link)->next; + *link=a->next; a->magic=0; + pthread_mutex_unlock(&lock); + free(a); *slot=NULL; return 0; +} +static ABI int32_t attr_get(void *thread,ThreadAttr **out) { + ThreadAttr *a=find_attr(out); + if (!a || !thread) return ERR(22); + GuestThread *t=find_thread(thread); + if (!t) return ERR(3); + ThreadAttr *next=a->next; + *a=t->attr; a->magic=ATTR_MAGIC; a->next=next; + a->detached=t->detached; + return 0; +} +static ABI int32_t attr_set_stack(ThreadAttr **slot,uint64_t size) { + ThreadAttr *a=find_attr(slot); + if (!a || size<16384) return ERR(22); + a->stack=size; return 0; +} +static ABI int32_t attr_get_stack(ThreadAttr **slot,uint64_t *size) { + ThreadAttr *a=find_attr(slot); + if (!a || !size) return ERR(22); + *size=a->stack; return 0; +} +static ABI int32_t attr_set_detach(ThreadAttr **slot,int state) { + ThreadAttr *a=find_attr(slot); + if (!a || (state!=0 && state!=1)) return ERR(22); + a->detached=state; return 0; +} +static ABI int32_t attr_get_detach(ThreadAttr **slot,int *state) { + ThreadAttr *a=find_attr(slot); + if (!a || !state) return ERR(22); + *state=a->detached; return 0; +} +static ABI int32_t attr_set_policy(ThreadAttr **slot,int policy) { + ThreadAttr *a=find_attr(slot); + if (!a || policy<1 || policy>3) return ERR(22); + a->policy=policy; return 0; +} +static ABI int32_t attr_set_inherit(ThreadAttr **slot,int inherit) { + ThreadAttr *a=find_attr(slot); + if (!a || (inherit!=0 && inherit!=4)) return ERR(22); + a->inherit=inherit; return 0; +} +static ABI int32_t attr_set_param(ThreadAttr **slot,const int *param) { + ThreadAttr *a=find_attr(slot); + if (!a || !param) return ERR(22); + a->prio=*param; return 0; +} +static ABI int32_t attr_get_param(ThreadAttr **slot,int *param) { + ThreadAttr *a=find_attr(slot); + if (!a || !param) return ERR(22); + *param=a->prio; return 0; +} +static ABI int32_t attr_set_affinity(ThreadAttr **slot,uint64_t mask) { + ThreadAttr *a=find_attr(slot); + if (!a) return ERR(22); + a->affinity=mask; return 0; +} +static ABI int32_t attr_affinity(ThreadAttr **slot,uint64_t *mask) { + ThreadAttr *a=find_attr(slot); + if (!a || !mask) return ERR(22); + *mask=a->affinity; return 0; +} +static ABI int32_t attr_set_guard(ThreadAttr **slot,uint64_t size) { + ThreadAttr *a=find_attr(slot); + if (!a) return ERR(22); + a->guard=size; return 0; +} + +/* Linux thread names hold 15 characters; longer ones would be rejected. */ +static void set_host_name(const char *name) { + char host[16]={0}; + memcpy(host,name,strnlen(name,sizeof(host)-1)); + pthread_setname_np(pthread_self(),host); +} +static void *host_start(void *p) { + GuestThread *t=p; + attach(t); + set_host_name(t->name); + if (!setjmp(t->exit_jump)) t->result=t->entry(t->argument); + runtime_thread_keys_cleanup(); + pthread_mutex_lock(&lock); t->finished=1; ++exited; pthread_mutex_unlock(&lock); + return t->result; +} +static int32_t create(GuestThread **out,ThreadAttr **attr_slot,GuestEntry entry,void *argument,const char *name) { + if (!out || !entry) return ERR(22); + ThreadAttr *a=NULL; + if (attr_slot && !(a=find_attr(attr_slot))) return ERR(22); + GuestThread *t=new_thread(); + if (!t) return ERR(12); + if (a) { t->attr=*a; t->attr.next=NULL; } + t->entry=entry; t->argument=argument; t->detached=t->attr.detached; + snprintf(t->name,sizeof(t->name),"%s",name ? name : "guest"); + pthread_attr_t host; + pthread_attr_init(&host); + uint64_t stack=t->attr.stack<MIN_STACK ? MIN_STACK : t->attr.stack; + /* Stacks below 1 TiB as on PS4; guest code may pack stack addresses. */ + size_t stack_bytes=(size_t)stack+STACK_MARGIN; + void *stack_memory=runtime_low_map(stack_bytes,PROT_READ|PROT_WRITE); + if (stack_memory) pthread_attr_setstack(&host,stack_memory,stack_bytes); + else pthread_attr_setstacksize(&host,stack_bytes); + publish(t); + /* Publish the handle before the thread can run and inspect itself. */ + *out=t; + int e=pthread_create(&t->host,&host,host_start,t); + pthread_attr_destroy(&host); + if (e) { fprintf(stderr,"STOP: host pthread_create failed: %d\n",e); exit(21); } + if (t->detached) pthread_detach(t->host); + pthread_mutex_lock(&lock); ++created; pthread_mutex_unlock(&lock); + printf("Runtime: guest thread '%s' created (stack=%llu, prio=%d)\n",t->name,(unsigned long long)stack,t->attr.prio); + return 0; +} +static ABI int32_t thread_create(GuestThread **out,ThreadAttr **attr,GuestEntry entry,void *argument,const char *name) { + return create(out,attr,entry,argument,name); +} +static ABI int32_t thread_join(GuestThread *t,void **result) { + if (!find_thread(t) || t->host_owned) return ERR(3); + if (t==current) return ERR(11); + if (t->detached || t->joined) return ERR(22); + t->joined=1; + void *value=NULL; + int e=pthread_join(t->host,&value); + if (e) { fprintf(stderr,"STOP: host pthread_join failed: %d\n",e); exit(21); } + if (result) *result=t->result; + pthread_mutex_lock(&lock); ++joined_count; pthread_mutex_unlock(&lock); + return 0; +} +static ABI int32_t thread_detach(GuestThread *t) { + if (!find_thread(t)) return ERR(3); + if (t->detached) return ERR(22); + t->detached=1; + if (!t->host_owned) pthread_detach(t->host); + return 0; +} +static ABI __attribute__((noreturn)) void thread_exit(void *value) { + GuestThread *t=runtime_thread_current(); + if (t->host_owned) { fputs("STOP: pthread_exit on host-owned/main thread\n",stderr); exit(21); } + t->result=value; + /* No host unwinder: guest frames have no registered FDEs. */ + longjmp(t->exit_jump,1); +} +static ABI int32_t thread_yield(void) { sched_yield(); return 0; } +static ABI int32_t thread_get_prio(GuestThread *t,int *prio) { + if (!find_thread(t)) return ERR(3); + if (!prio) return ERR(22); + *prio=t->attr.prio; return 0; +} +static ABI int32_t thread_set_prio(GuestThread *t,int prio) { + if (!find_thread(t)) return ERR(3); + t->attr.prio=prio; return 0; +} +static ABI int32_t thread_set_affinity(GuestThread *t,uint64_t mask) { + if (!find_thread(t)) return ERR(3); + t->attr.affinity=mask; return 0; +} +static ABI int32_t thread_get_affinity(GuestThread *t,uint64_t *mask) { + if (!find_thread(t)) return ERR(3); + if (!mask) return ERR(22); + *mask=t->attr.affinity; return 0; +} +static ABI int32_t thread_rename(GuestThread *t,const char *name) { + if (!find_thread(t)) return ERR(3); + if (!name) return ERR(22); + snprintf(t->name,sizeof(t->name),"%s",name); + if (t==current) set_host_name(t->name); + return 0; +} +static ABI int32_t thread_equal(GuestThread *a,GuestThread *b) { return a==b; } + +/* POSIX (libScePosix) variants return positive errno values. */ +static int32_t posix(int32_t r) { return r ? (int32_t)((uint32_t)r&0xffff) : 0; } +static ABI int32_t posix_attr_init(ThreadAttr **a) { return posix(attr_init(a)); } +static ABI int32_t posix_attr_destroy(ThreadAttr **a) { return posix(attr_destroy(a)); } +static ABI int32_t posix_attr_set_detach(ThreadAttr **a,int s) { return posix(attr_set_detach(a,s)); } +static ABI int32_t posix_attr_set_stack(ThreadAttr **a,uint64_t s) { return posix(attr_set_stack(a,s)); } +static ABI int32_t posix_attr_set_param(ThreadAttr **a,const int *p) { return posix(attr_set_param(a,p)); } +static ABI int32_t posix_create(GuestThread **t,ThreadAttr **a,GuestEntry e,void *arg) { return posix(create(t,a,e,arg,"posix")); } +static ABI int32_t posix_create_name(GuestThread **t,ThreadAttr **a,GuestEntry e,void *arg,const char *name) { return posix(create(t,a,e,arg,name)); } +static ABI int32_t posix_join(GuestThread *t,void **r) { return posix(thread_join(t,r)); } + +uintptr_t runtime_thread_resolve(const char *name) { + static const struct { const char *nid; void *fn; } table[]={ + {"aI+OeCz8xrQ#p#J",thread_self}, {"EotR8a3ASf4#I#J",thread_self}, + {"9BcDykPmo1I#p#J",guest_error}, + {"nsYoNRywwNg#p#J",attr_init}, {"62KCwEMmzcM#p#J",attr_destroy}, + {"x1X76arYMxU#p#J",attr_get}, {"8+s5BzZjxSg#p#J",attr_affinity}, + {"UTXzJbWhhTE#p#J",attr_set_stack}, {"-Wreprtu0Qs#p#J",attr_set_detach}, + {"4+h9EzwKF4I#p#J",attr_set_policy}, {"DzES9hQF4f4#p#J",attr_set_param}, + {"3qxgM4ezETA#p#J",attr_set_affinity}, {"eXbUSpEaTsA#p#J",attr_set_inherit}, + {"JaRMy+QcpeU#p#J",attr_get_detach}, {"-fA+7ZlGDQs#p#J",attr_get_stack}, + {"FXPWHNk8Of0#p#J",attr_get_param}, {"El+cQ20DynU#p#J",attr_set_guard}, + {"6UgtwV+0zb4#p#J",thread_create}, {"onNY9Byn-W8#p#J",thread_join}, + {"4qGrR6eoP9Y#p#J",thread_detach}, {"3kg7rT0NQIs#p#J",thread_exit}, + {"T72hz6ffq08#p#J",thread_yield}, {"1tKyG7RlMJo#p#J",thread_get_prio}, + {"W0Hpm2X0uPE#p#J",thread_set_prio}, {"bt3CTBKmGyI#p#J",thread_set_affinity}, {"rcrVFJsQWRY#p#J",thread_get_affinity}, + {"GBUY7ywdULE#p#J",thread_rename}, {"3PtV6p3QNX4#p#J",thread_equal}, + {"wtkt-teR1so#I#J",posix_attr_init}, {"zHchY8ft5pk#I#J",posix_attr_destroy}, + {"E+tyo3lp5Lw#I#J",posix_attr_set_detach}, {"2Q0z6rnBrTE#I#J",posix_attr_set_stack}, + {"euKRgm0Vn2M#I#J",posix_attr_set_param}, {"OxhIB8LB-PQ#I#J",posix_create}, + {"Jmi+9w9u0E4#I#J",posix_create_name}, {"h9CcP3J0oVM#I#J",posix_join}, + {"FJrT5LuUBAU#I#J",thread_exit}, + }; + for (size_t i=0;i<sizeof(table)/sizeof(*table);++i) + if (!strcmp(name,table[i].nid)) return (uintptr_t)table[i].fn; + return 0; +} +void runtime_thread_report(void) { + pthread_mutex_lock(&lock); + printf("Runtime: guest threads created=%zu, exited=%zu, joined=%zu\n",created,exited,joined_count); + pthread_mutex_unlock(&lock); +} +#else +uintptr_t runtime_thread_resolve(const char *name) { (void)name; return 0; } +void runtime_thread_report(void) {} +void runtime_thread_attach_main(void) {} +void runtime_set_main_tls(const void *d,uint64_t f,uint64_t m,uint64_t a) { (void)d;(void)f;(void)m;(void)a; } +#endif diff --git a/runtime_time.c b/runtime_time.c new file mode 100644 index 0000000..c5470c1 --- /dev/null +++ b/runtime_time.c @@ -0,0 +1,28 @@ +/* Explicit guest timeval layout; host pointers never escape this boundary. */ +#define _DEFAULT_SOURCE +#include "runtime.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef _WIN32 +#include <sys/time.h> +typedef struct { int64_t seconds, microseconds; } GuestTimeval; +typedef struct { int32_t minuteswest, dsttime; } GuestTimezone; +static ABI int guest_gettimeofday(GuestTimeval *value,GuestTimezone *zone) { + struct timeval t; + struct timezone z; + if (gettimeofday(&t,&z)) { + /* Guest errno/TLS failure path is not implemented yet. */ + perror("STOP: host gettimeofday failed"); exit(21); + } + if (value) { value->seconds=t.tv_sec; value->microseconds=t.tv_usec; } + if (zone) { zone->minuteswest=z.tz_minuteswest; zone->dsttime=z.tz_dsttime; } + return 0; +} +uintptr_t runtime_time_resolve(const char *name) { + if (!strcmp(name,"n88vx3C5nW8#I#J")) return (uintptr_t)guest_gettimeofday; + return 0; +} +#else +uintptr_t runtime_time_resolve(const char *name) { (void)name; return 0; } +#endif diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..d9f6d79 --- /dev/null +++ b/shell.nix @@ -0,0 +1,10 @@ +# Build environment: `nix-shell native_probe/shell.nix --run 'bash native_probe/run.sh'` +{ pkgs ? import <nixpkgs> {} }: +pkgs.mkShell { + packages = with pkgs; [ + gcc gnumake cmake ninja pkg-config python3 binutils + vulkan-headers vulkan-loader sdl3 + # GPU library (gpu/): shadPS4 video core dependencies + ffmpeg-headless boost fmt magic-enum robin-map xxhash vulkan-memory-allocator glslang xbyak zydis spirv-headers miniz libx11 libxcb xorgproto wayland + ]; +} diff --git a/test_content.c b/test_content.c new file mode 100644 index 0000000..a2136ca --- /dev/null +++ b/test_content.c @@ -0,0 +1,63 @@ +#include "runtime.h" +#include <assert.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +typedef int32_t (ABI *Module)(uint16_t); +typedef int32_t (ABI *Init)(const void *,void *); +typedef int32_t (ABI *Param)(uint32_t,int32_t *); +typedef int32_t (ABI *List)(uint32_t,void *,uint32_t,uint32_t *); +#define GET(t,n) ((t)runtime_content_resolve(n)) +int main(int argc,char **argv) { + Module load=GET(Module,"g8cM39EUZ6o#M#N"); + Module loaded=GET(Module,"fMP5NHUOaMk#M#N"); + Module unload=GET(Module,"eR2bZFAAU0Q#M#N"); + Init init=GET(Init,"R9lA82OraNs#c#d"); + Param param=GET(Param,"99b82IKXpH4#c#d"); + List list=GET(List,"xnd8BJzAxmk#c#d"); + assert(load && loaded && unload && init && param && list); + assert(!runtime_content_resolve("g8cM39EUZ6o#I#J")); + if (argc>1 && !strcmp(argv[1],"--missing")) { load(0xb4); return 99; } + const uint32_t profile[]={1,13,0x80000000,0,7}; + runtime_content_configure(profile); + if (argc>1 && !strcmp(argv[1],"--unknown")) { + /* Other system modules are host-provided: reference counted, independent. */ + assert((uint32_t)loaded(0xb5)==0x805a1001); + assert(load(0xb5)==0 && loaded(0xb5)==0 && (uint32_t)loaded(0xb4)==0x805a1001); + assert(unload(0xb5)==0 && (uint32_t)loaded(0xb5)==0x805a1001); + puts("PASS: independent module references"); return 0; + } + assert((uint32_t)loaded(0)==0x805a1000); + assert((uint32_t)loaded(0xb4)==0x805a1001); + assert((uint32_t)unload(0xb4)==0x805a1001); + assert(load(0xb4)==0 && load(0xb4)==0 && loaded(0xb4)==0); + unsigned char initial[32]={0}; + struct { unsigned char boot[40]; uint32_t canary; } b; + memset(&b,0xa5,sizeof(b)); + assert((uint32_t)init(NULL,b.boot)==0x80d90002); + initial[31]=1; assert((uint32_t)init(initial,b.boot)==0x80d90002); initial[31]=0; + assert(b.boot[0]==0xa5 && init(initial,b.boot)==0); + for (unsigned i=0;i<40;++i) assert(b.boot[i]==0); + assert(b.canary==0xa5a5a5a5); + b.boot[0]=0xcc; assert((uint32_t)init(initial,b.boot)==0x80d90003 && b.boot[0]==0xcc); + struct { int32_t value; uint32_t canary; } result={-1,0x1234}; + for (unsigned i=0;i<5;++i) { + assert(param(i,&result.value)==0 && (uint32_t)result.value==profile[i]); + assert(result.canary==0x1234); + } + result.value=77; + assert((uint32_t)param(5,&result.value)==0x80d90002 && result.value==77); + assert((uint32_t)param(0,NULL)==0x80d90002); + unsigned char entries[48]; memset(entries,0xaa,sizeof(entries)); + struct { uint32_t hits,canary; } h={99,0xabcdef}; + assert(list(0,NULL,0,&h.hits)==0 && h.hits==0 && h.canary==0xabcdef); + assert(list(0,entries,2,&h.hits)==0 && h.hits==0); + for (unsigned i=0;i<sizeof(entries);++i) assert(entries[i]==0xaa); + assert((uint32_t)list(0,NULL,0,NULL)==0x80d90002); + assert(unload(0xb4)==0 && loaded(0xb4)==0); + assert((uint32_t)init(initial,b.boot)==0x80d90003); + assert(unload(0xb4)==0 && (uint32_t)loaded(0xb4)==0x805a1001); + assert(load(0xb4)==0 && init(initial,b.boot)==0 && unload(0xb4)==0); + puts("PASS: AppContent lifecycle, profile and output boundaries"); + return 0; +} diff --git a/test_content.py b/test_content.py new file mode 100644 index 0000000..f3eca74 --- /dev/null +++ b/test_content.py @@ -0,0 +1,39 @@ +from pathlib import Path +import struct +import subprocess +import tempfile +import unittest +from unittest.mock import patch +import content_profile + +EXE=Path(__file__).parent/'out/content-test' + +class ProfileTests(unittest.TestCase): + def test_sfo_parameters_and_explicit_trial_profile(self): + with tempfile.TemporaryDirectory() as tmp: + p=Path(tmp);(p/'sce_sys').mkdir();(p/'sce_sys/param.sfo').write_bytes(b'fixture') + with patch.object(content_profile,'sfo',return_value={'USER_DEFINED_PARAM_1':13,'USER_DEFINED_PARAM_4':0xffffffff}): + content_profile.prepare(p,p,'trial') + self.assertEqual(struct.unpack('<8s5I',(p/'content.bin').read_bytes()),(b'BBCONT01',1,13,0,0,0xffffffff)) + + def test_invalid_sfo_parameter_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + p=Path(tmp);(p/'sce_sys').mkdir();(p/'sce_sys/param.sfo').write_bytes(b'fixture') + with patch.object(content_profile,'sfo',return_value={'USER_DEFINED_PARAM_1':'13'}): + with self.assertRaisesRegex(ValueError,'invalid user-defined'): + content_profile.prepare(p,p) + +@unittest.skipUnless(EXE.exists(),'run bash build.sh --test first') +class ContentTests(unittest.TestCase): + def run_case(self,*args): + return subprocess.run([str(EXE.resolve()),*args],capture_output=True,text=True,timeout=5) + + def test_lifecycle_and_output_boundaries(self): + r=self.run_case();self.assertEqual(r.returncode,0,r.stdout+r.stderr) + + def test_missing_profile_does_not_report_loaded(self): + r=self.run_case('--missing');self.assertEqual(r.returncode,21) + self.assertIn('needs --content-profile',r.stderr) + + def test_other_modules_are_counted_independently(self): + r=self.run_case('--unknown');self.assertEqual(r.returncode,0,r.stdout+r.stderr) diff --git a/test_link_libc.py b/test_link_libc.py new file mode 100644 index 0000000..bc7b4b1 --- /dev/null +++ b/test_link_libc.py @@ -0,0 +1,81 @@ +"""Cross-module identity and TLS relocation tests without game binaries.""" +import json +from pathlib import Path +import struct +import tempfile +import unittest +from unittest.mock import patch +import link_libc +from test_probe import package + + +class LinkTests(unittest.TestCase): + def fixture(self, version=1, relocs=()): + main_key=('fixture',('libc',1),('libc',1)) + lib_key=('fixture',('libc',version),('libc',1)) + main=dict(identity=lambda name:main_key,libraries={'q':('libc',1)}, + modules={'q':('libc',1)},ph=[dict(type=0x61000001,vaddr=256)]) + symbols=[dict(name='',type=3,binding=0,section=1,value=0,size=0,identity=None), + dict(name='fixture#C#A',type=2,binding=1,section=1,value=16,size=1,identity=lib_key)] + elf=b'\x31\xc0\xc3'+bytes(13)+b'\xc3'+bytes(111) + libc=dict(elf=elf,ph=[dict(type=1,vaddr=0,memsz=4096,filesz=len(elf),offset=0,flags=5), + dict(type=7,vaddr=128,memsz=32,filesz=4)], + tags={12:0},symbols=symbols,relocs=list(relocs),sha256='fixture') + return main,libc + + def run_link(self,main,libc,code=b'\xc3'): + with tempfile.TemporaryDirectory() as tmp: + out=Path(tmp) + (out/'boot.bin').write_bytes(package(code,names=['fixture#q#q'],capabilities=1)) + with patch.object(link_libc,'module',side_effect=[main,libc]): + link_libc.link(Path('fixture-game'),out) + return (out/'boot-libc.bin').read_bytes(),json.loads((out/'libc-link.json').read_text()) + + def test_different_local_ids_bind_same_identity(self): + data,report=self.run_link(*self.fixture()) + self.assertEqual(data[:8],b'BBPROBE4') + self.assertEqual(report['symbol_bindings'],[ + dict(import_name='fixture#q#q',address='0x10010',kind=1)]) + + def test_same_nid_wrong_library_version_does_not_bind(self): + _,report=self.run_link(*self.fixture(version=2)) + self.assertEqual(report['bindings'],0) + + def test_tls_module_id_is_literal_not_image_pointer(self): + data,report=self.run_link(*self.fixture(relocs=[(64,16,0,0)])) + size=struct.unpack_from('<Q',data,8)[0] + image=data[-size:] + self.assertEqual(struct.unpack_from('<Q',image,65536+64)[0],2) + self.assertEqual(report['tls_relocations'],1) + + def test_unsupported_tls_symbol_rejected(self): + with self.assertRaisesRegex(ValueError,'unsupported external TLS'): + self.run_link(*self.fixture(relocs=[(64,16,1,0)])) + + def test_relocation_outside_segments_rejected(self): + with self.assertRaisesRegex(ValueError,'relocation outside image'): + self.run_link(*self.fixture(relocs=[(4092,8,0,0)])) + + def test_fs_thread_pointer_loads_are_rewritten_to_gs(self): + main,libc=self.fixture() + load=bytes.fromhex('64488b042500000000') + code=load+b'\x90'+load+b'\xc3' + main['ph']=main['ph']+[dict(type=1,vaddr=0,filesz=64,memsz=64,flags=5), + dict(type=7,vaddr=2048,filesz=0,memsz=48,align=16)] + data,report=self.run_link(main,libc,code) + size=struct.unpack_from('<Q',data,8)[0] + image=data[-size:] + self.assertEqual(image[0],0x65) + self.assertEqual(image[10],0x65) + self.assertEqual(report['fs_loads_patched'],2) + self.assertEqual(report['main_tls'],dict(vaddr=2048,filesz=0,memsz=48,align=16)) + self.assertEqual(struct.unpack_from('<4Q',data,56+64),(2048,0,48,16)) + + def test_fs_loads_outside_executable_segments_are_kept(self): + main,libc=self.fixture() + load=bytes.fromhex('64488b042500000000') + main['ph']=main['ph']+[dict(type=1,vaddr=0,filesz=64,memsz=64,flags=6)] + data,report=self.run_link(main,libc,load) + image=data[-struct.unpack_from('<Q',data,8)[0]:] + self.assertEqual(image[0],0x64) + self.assertEqual(report['fs_loads_patched'],0) diff --git a/test_prepare.py b/test_prepare.py new file mode 100644 index 0000000..3d4e4de --- /dev/null +++ b/test_prepare.py @@ -0,0 +1,80 @@ +import struct +import unittest +import tempfile +from pathlib import Path +from prepare import parse_self, inspect_libc, nid + + +def fixture(): + data = bytearray(0x210) + data[:4] = b'O\x15=\x1d' + struct.pack_into('<H', data, 24, 1) + struct.pack_into('<QQQQ', data, 32, 0x800, 0x200, 16, 16) + struct.pack_into('<16sHHIQQQIHHHHHH', data, 64, + b'\x7fELF\x02\x01\x01\x09', 0xfe10, 62, 1, 0, 64, 0, 0, 64, 56, 1, 0, 0, 0) + struct.pack_into('<IIQQQQQQ', data, 128, 1, 5, 0x1000, 0, 0, 16, 32, 0x1000) + data[0x200:] = bytes(range(16)) + return data + + +class SelfTests(unittest.TestCase): + def test_libc_ret_contract_is_verified_from_symbol_and_code(self): + def libc(instruction): + data=bytearray(0x320) + data[:4]=b'O\x15=\x1d' + struct.pack_into('<H',data,24,2) + struct.pack_into('<QQQQ',data,32,0x800,0x200,16,16) + struct.pack_into('<QQQQ',data,64,0x100800,0x220,256,256) + struct.pack_into('<16sHHIQQQIHHHHHH',data,96,b'\x7fELF\x02\x01\x01\x09',0xfe18,62,1,0,64,0,0,64,56,3,0,0,0) + struct.pack_into('<IIQQQQQQ',data,160,1,5,0x1000,0,0,16,16,0x1000) + struct.pack_into('<IIQQQQQQ',data,216,0x61000000,4,0x2000,0,0,256,0,16) + struct.pack_into('<IIQQQQQQ',data,272,2,4,0x20b0,0,0,80,80,8) + data[0x200]=instruction + name=b'bzQExy189ZI#C#A\0' + data[0x220:0x220+len(name)]=name + struct.pack_into('<IBBHQQ',data,0x260,0,0x12,0,1,0,1) + for i,(tag,value) in enumerate([(0x61000035,0),(0x61000037,32),(0x61000039,64),(0x6100003f,24),(0,0)]): + struct.pack_into('<QQ',data,0x2d0+16*i,tag,value) + return data + with tempfile.TemporaryDirectory() as tmp: + path=Path(tmp)/'libc.prx' + path.write_bytes(libc(0xc3)) + proof=inspect_libc(path) + self.assertTrue(proof['init_env_is_ret']) + self.assertEqual(proof['bytes'],'c3') + path.write_bytes(libc(0x90)) + self.assertFalse(inspect_libc(path)['init_env_is_ret']) + self.assertEqual(nid('_init_env'),'bzQExy189ZI') + + def test_file_offset_is_not_virtual_address(self): + elf, header, ph, segments, missing = parse_self(fixture()) + self.assertEqual(elf[0x1000:0x1010], bytes(range(16))) + self.assertEqual(ph[0]['vaddr'], 0) + self.assertEqual(missing, []) + + def test_truncated_payload_rejected(self): + with self.assertRaisesRegex(ValueError, 'out of bounds'): + parse_self(fixture()[:-1]) + + def test_encrypted_or_compressed_payload_rejected(self): + for flag in (2, 8): + data = fixture() + struct.pack_into('<Q', data, 32, 0x800 | flag) + with self.assertRaisesRegex(ValueError, 'encrypted/compressed'): + parse_self(data) + + def test_missing_required_segment_rejected(self): + data = fixture() + struct.pack_into('<Q', data, 32, 0) + with self.assertRaisesRegex(ValueError, 'required segment'): + parse_self(data) + + def test_bad_program_header_index_rejected(self): + data = fixture() + struct.pack_into('<Q', data, 32, 0x100800) + with self.assertRaisesRegex(ValueError, 'segment index'): + parse_self(data) + + +if __name__ == '__main__': + unittest.main() diff --git a/test_probe.py b/test_probe.py new file mode 100644 index 0000000..7d04645 --- /dev/null +++ b/test_probe.py @@ -0,0 +1,144 @@ +"""Boundary tests for the native loader; uses tiny synthetic x86-64 images.""" +from pathlib import Path +import struct +import subprocess +import tempfile +import unittest + +EXE = Path(__file__).parent / 'out/bb-probe' + + +def package(code, relocs=(), names=(), capabilities=None): + image = code.ljust(4096, b'\0') + header = struct.pack('<8sQQQQQ', b'BBPROBE1' if capabilities is None else b'BBPROBE2', len(image), 0, 1, len(relocs), len(names)) + if capabilities is not None: + header += struct.pack('<Q', capabilities) + segment = struct.pack('<QQQ', 0, len(image), 5) + return (header + segment + b''.join(n.encode().ljust(128, b'\0') for n in names) + + b''.join(struct.pack('<QQqq', *r) for r in relocs) + image) + + +def native_package(name='fixture-native', binding_address=4112, binding_kind=1, + lib_flags=5, init=b'\x31\xc0\xc3', native=b'\xc3', metadata=None): + # Main calls an import then tail-jumps to the terminal diagnostic import. + code = b'\x48\x83\xec\x08\xff\x15\x16\0\0\0\x48\x83\xc4\x08\xff\x25\x14\0\0\0' + image = code.ljust(4096,b'\0') + init.ljust(16,b'\0') + native + image = image.ljust(12288,b'\0') + header=struct.pack('<8s6Q',b'BBPROBE3',len(image),0,3,2,2,1) + meta=metadata or (4096,8192,4096,8192,32,4,1,256) + return (header + struct.pack('<8Q',*meta) + struct.pack('<3Q',0,binding_address,binding_kind) + + struct.pack('<9Q',0,4096,5,4096,4096,lib_flags,8192,4096,6) + + name.encode().ljust(128,b'\0') + b'after-native'.ljust(128,b'\0') + + struct.pack('<8Q',32,1,0,0,40,1,1,0) + image) + + +@unittest.skipUnless(EXE.exists(), 'build native probe first') +class LoaderTests(unittest.TestCase): + def test_invalid_content_profile_is_rejected(self): + with tempfile.TemporaryDirectory() as tmp: + path=Path(tmp)/'content.bin' + for data in (b'BBCONT01',struct.pack('<8s5I',b'BBCONT01',2,0,0,0,0), + struct.pack('<8s5I',b'BBCONT01',3,0,0,0,0)+b'extra'): + with self.subTest(data=data): + path.write_bytes(data) + r=self.run_image(package(b'\xc3'),'--content-profile',str(path)) + self.assertEqual(r.returncode,1,r.stdout+r.stderr) + self.assertIn('content profile',r.stderr) + + def run_image(self, data, *options): + with tempfile.TemporaryDirectory() as tmp: + path = Path(tmp) / 'boot.bin' + path.write_bytes(data) + return subprocess.run([str(EXE.resolve()), str(path), '--cpu-only', *options], + capture_output=True, text=True, timeout=5) + + def test_original_instruction_reaches_named_import(self): + # jmp [rip+2]; two padding bytes; relocated function pointer at +8 + r = self.run_image(package(b'\xff\x25\x02\0\0\0\x90\x90', [(8, 1, 0, 0)], ['fixture-import'])) + self.assertEqual(r.returncode, 20, r.stderr) + self.assertIn('first unsupported PS4 import: fixture-import', r.stdout) + + def test_native_initializer_and_export_return(self): + r=self.run_image(native_package()) + self.assertEqual(r.returncode,20,r.stdout+r.stderr) + self.assertIn('Native libc module initializer returned 0',r.stdout) + self.assertIn('first unsupported PS4 import: after-native',r.stdout) + + def test_host_contract_takes_priority_over_native_export(self): + r=self.run_image(native_package(name='bzQExy189ZI#q#q',native=b'\x0f\x0b')) + self.assertEqual(r.returncode,20,r.stdout+r.stderr) + self.assertIn('_init_env returned',r.stdout) + self.assertIn('first unsupported PS4 import: after-native',r.stdout) + + def test_strict_mode_skips_native_initialization_and_binding(self): + r=self.run_image(native_package(init=b'\x0f\x0b'), '--strict-imports') + self.assertEqual(r.returncode,20,r.stdout+r.stderr) + self.assertIn('first unsupported PS4 import: fixture-native',r.stdout) + self.assertNotIn('Starting native libc',r.stdout) + + def test_native_metadata_and_bindings_are_validated(self): + for kwargs,message in [ + ({'binding_address':12288},'invalid native binding'), + ({'binding_kind':2},'native export kind/range mismatch'), + ({'lib_flags':4},'native function is not executable'), + ({'metadata':(4096,8192,4096,8192,32,33,1,256)},'invalid libc metadata'), + ({'metadata':(4096,8192,4096,8192,32,4,1,12280)},'unmapped libc metadata'), + ]: + with self.subTest(kwargs=kwargs): + r=self.run_image(native_package(**kwargs)) + self.assertEqual(r.returncode,1,r.stdout+r.stderr) + self.assertIn(message,r.stderr) + + def test_failed_native_initializer_does_not_enter_game(self): + r=self.run_image(native_package(init=b'\xb8\x01\0\0\0\xc3')) + self.assertEqual(r.returncode,1,r.stdout+r.stderr) + self.assertIn('libc initializer failed',r.stderr) + self.assertNotIn('Entering original',r.stdout) + + def test_base_relative_address_is_relocated(self): + # jump via a relative relocation to code at +16, then to an import at +24 + code = b'\xff\x25\x02\0\0\0\x90\x90' + b'\0'*8 + b'\xff\x25\x02\0\0\0\x90\x90' + r = self.run_image(package(code, [(8, 0, 16, 0), (24, 1, 0, 0)], ['after-relative-jump'])) + self.assertEqual(r.returncode, 20, r.stderr) + self.assertIn('after-relative-jump', r.stdout) + + def test_out_of_bounds_relocation_is_rejected(self): + r = self.run_image(package(b'\xc3', [(4092, 0, 0, 0)])) + self.assertEqual(r.returncode, 1) + self.assertIn('bad relocation', r.stderr) + + def test_truncated_image_is_rejected(self): + r = self.run_image(package(b'\xc3')[:-1]) + self.assertEqual(r.returncode, 1) + self.assertIn('incorrect memory image size', r.stderr) + + def test_illegal_instruction_reports_guest_offset(self): + r = self.run_image(package(b'\x0f\x0b')) + self.assertEqual(r.returncode, 132) + self.assertIn('0x0000000000000000', r.stderr) + + def test_runtime_returns_from_verified_init_env(self): + # Align stack, call _init_env through +32, then tail-jump to unknown +40. + code = b'\x48\x83\xec\x08\xff\x15\x16\0\0\0\x48\x83\xc4\x08\xff\x25\x14\0\0\0' + data = package(code, [(32,1,0,0),(40,1,1,0)], ['bzQExy189ZI#q#q','after-init'], 1) + r = self.run_image(data) + self.assertEqual(r.returncode,20,r.stderr) + self.assertIn('first unsupported PS4 import: after-init',r.stdout) + self.assertIn('_init_env=1',r.stdout) + strict = self.run_image(data,'--strict-imports') + self.assertEqual(strict.returncode,20,strict.stderr) + self.assertIn('first unsupported PS4 import: bzQExy189ZI#q#q',strict.stdout) + + def test_unverified_runtime_stays_disabled(self): + r = self.run_image(package(b'\xff\x25\x02\0\0\0\x90\x90',[(8,1,0,0)],['bzQExy189ZI#q#q'],0)) + self.assertEqual(r.returncode,20,r.stderr) + self.assertIn('_init_env=0',r.stdout) + + def test_unknown_capabilities_rejected(self): + r = self.run_image(package(b'\xc3',capabilities=2)) + self.assertEqual(r.returncode,1) + self.assertIn('unknown runtime capabilities',r.stderr) + + +if __name__ == '__main__': + unittest.main() diff --git a/test_runtime.c b/test_runtime.c new file mode 100644 index 0000000..e73e9a6 --- /dev/null +++ b/test_runtime.c @@ -0,0 +1,353 @@ +#define _GNU_SOURCE +#include "runtime.h" +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <pthread.h> +#include <stdatomic.h> +#include <time.h> + +typedef int (ABI *Register)(GuestCallback); +typedef int (ABI *RegisterCxa)(void (ABI *)(void *), void *, void *); +typedef int (ABI *Acquire)(uint64_t *); +typedef void (ABI *Guard)(uint64_t *); +typedef int32_t (ABI *AttrInit)(void **); +typedef int32_t (ABI *AttrType)(void **, int); +typedef int32_t (ABI *MutexInit)(void **, void **, const char *); +typedef int32_t (ABI *HandleOp)(void **); +typedef int32_t (ABI *Allocate)(int64_t, int64_t, uint64_t, uint64_t, int, int64_t *); +typedef int32_t (ABI *Map)(void **, uint64_t, int, int, int64_t, uint64_t); +typedef int32_t (ABI *Unmap)(void *, uint64_t); +typedef int32_t (ABI *Release)(uint64_t, uint64_t); +#define GET(type, name) ((type)runtime_resolve(name, 0)) +typedef void *(ABI *TlsAddress)(const uint64_t *); +typedef void *(ABI *ThreadSelf)(void); +typedef int32_t (ABI *ThreadGetAttr)(void *,void **); +typedef int32_t (ABI *ThreadAffinity)(void **,uint64_t *); +static void *main_identity; +static void *tls_worker(void *unused) { + (void)unused; + const uint64_t index[]={2,0}; + unsigned char *p=GET(TlsAddress,"vNe1w4diLCs#p#J")(index); + assert(p[0]==42 && p[1]==17 && p[31]==0); + p[0]=99; + assert(GET(ThreadSelf,"aI+OeCz8xrQ#p#J")()!=main_identity); + return NULL; +} +static void libc_support(void) { + static const unsigned char initial[]={42,17}; + runtime_set_libc_tls(initial,sizeof(initial),32); + const uint64_t index[]={2,0}, last[]={2,31}; + TlsAddress tls=GET(TlsAddress,"vNe1w4diLCs#p#J"); + unsigned char *p=tls(index); + assert(p[0]==42 && p[1]==17 && p[2]==0 && p[31]==0); + assert(tls(last)==p+31 && tls(index)==p); + p[0]=23; + main_identity=GET(ThreadSelf,"aI+OeCz8xrQ#p#J")(); + pthread_t worker; + assert(pthread_create(&worker,NULL,tls_worker,NULL)==0); + assert(pthread_join(worker,NULL)==0); + assert(p[0]==23 && initial[0]==42); + void *attr=NULL; + AttrInit init=GET(AttrInit,"nsYoNRywwNg#p#J"); + ThreadGetAttr get=GET(ThreadGetAttr,"x1X76arYMxU#p#J"); + ThreadAffinity affinity=GET(ThreadAffinity,"8+s5BzZjxSg#p#J"); + HandleOp destroy=GET(HandleOp,"62KCwEMmzcM#p#J"); + uint64_t mask=0; + assert((uint32_t)init(NULL)==0x80020016); + assert(init(&attr)==0 && get(main_identity,&attr)==0); + assert(affinity(&attr,&mask)==0 && mask==0x7f); + assert((uint32_t)get(&mask,&attr)==0x80020003); + assert((uint32_t)affinity(&attr,NULL)==0x80020016); + assert(destroy(&attr)==0 && !attr); + assert((uint32_t)affinity(&attr,&mask)==0x80020016); + uint64_t param[8]={64}; + runtime_set_procparam(param); + assert(GET(ThreadSelf,"959qrazPIrg#p#J")()==param); + typedef void (ABI *SetHeap)(void **); + void *heap[10]={0}; + GET(SetHeap,"p5EcQeEeJAE#p#J")(heap); + assert(runtime_application_heap_api()==heap); + GET(SetHeap,"p5EcQeEeJAE#p#J")(NULL); + assert(runtime_application_heap_api()==NULL); + runtime_set_procparam(NULL); +} +static int order[512], count; +static Register register_plain; +static ABI void first(void) { order[count++]=1; } +static ABI void second(void) { order[count++]=2; } +static ABI void with_arg(void *p) { order[count++]=(int)(uintptr_t)p; } +static ABI void add_handler(void) { order[count++]=4; assert(register_plain(first)==0); } + +static void exit_handlers(void) { + register_plain=GET(Register,"8G2LB+A3rzg#q#q"); + RegisterCxa cxa=GET(RegisterCxa,"tsvEmnenz48#q#q"); + assert(register_plain && cxa); + assert(register_plain(first)==0); + assert(cxa(with_arg,(void *)3,(void *)11)==0); + assert(register_plain(second)==0); + runtime_finalize((void *)11); + assert(count==1 && order[0]==3); + runtime_finalize((void *)11); assert(count==1); + runtime_finalize(NULL); + assert(count==3 && order[1]==2 && order[2]==1); + runtime_finalize(NULL); assert(count==3); + assert(register_plain(add_handler)==0); + runtime_finalize(NULL); + assert(count==5 && order[3]==4 && order[4]==1); + /* Exercise reallocating the registry and strict LIFO ordering. */ + count=0; + for (uintptr_t i=0; i<200; ++i) assert(cxa(with_arg,(void *)i,(void *)12)==0); + runtime_finalize((void *)12); + assert(count==200); + for (int i=0; i<200; ++i) assert(order[i]==199-i); +} +static void guards(void) { + uint64_t state=0; + Acquire acquire=GET(Acquire,"3GPpjQdAMTw#q#q"); + Guard release=GET(Guard,"9rAeANT2tyE#q#q"), abort_guard=GET(Guard,"2emaaluWzUw#q#q"); + assert(acquire(&state)==1 && state==(UINT64_C(1)<<32)); + abort_guard(&state); assert(state==0); + assert(acquire(&state)==1); + release(&state); assert(state==1); + assert(acquire(&state)==0); +} +static void mutexes(void) { + AttrInit attr_init=GET(AttrInit,"F8bUHwAG284#p#J"); + AttrType type=GET(AttrType,"iMp8QpE+XO4#p#J"); + HandleOp attr_destroy=GET(HandleOp,"smWEktiyyG0#p#J"); + MutexInit init=GET(MutexInit,"cmo1RIYva9o#p#J"); + HandleOp lock=GET(HandleOp,"9UK1vLZQft4#p#J"), unlock=GET(HandleOp,"tn3VlD0hG60#p#J"); + HandleOp trylock=GET(HandleOp,"upoVrzMHFeE#p#J"), destroy=GET(HandleOp,"2Of0f+3mhhE#p#J"); + void *attr=NULL, *mutex=NULL; + assert((uint32_t)attr_init(NULL)==0x80020016); + assert(attr_init(&attr)==0); + assert((uint32_t)type(&attr,99)==0x80020016); + assert(type(&attr,2)==0 && init(&mutex,&attr,"recursive-test")==0); + assert(attr_destroy(&attr)==0 && attr==NULL); + assert(lock(&mutex)==0 && trylock(&mutex)==0); + assert((uint32_t)destroy(&mutex)==0x80020010); + assert(unlock(&mutex)==0 && unlock(&mutex)==0 && destroy(&mutex)==0); + assert((uint32_t)lock(&mutex)==0x80020016); + mutex=NULL; + assert(lock(&mutex)==0); /* static initialization */ + assert((uint32_t)lock(&mutex)==0x8002000b); + assert((uint32_t)trylock(&mutex)==0x80020010); + assert(unlock(&mutex)==0 && destroy(&mutex)==0); +} +static void posix_mutexes(void) { + AttrInit init=GET(AttrInit,"dQHWEsJtoE4#I#J"); + AttrType type=GET(AttrType,"mDmgMOGVUqg#I#J"); + HandleOp destroy_attr=GET(HandleOp,"HF7lK46xzjY#I#J"); + typedef int32_t (ABI *PosixInit)(void **,void **); + PosixInit mutex_init=GET(PosixInit,"ttHNfU+qDBU#I#J"); + HandleOp lock=GET(HandleOp,"7H0iTOciTLo#I#J"); + HandleOp unlock=GET(HandleOp,"2Z+PpY6CaJg#I#J"); + HandleOp trylock=GET(HandleOp,"K-jXhbt2gn4#I#J"); + HandleOp destroy=GET(HandleOp,"ltCfaGr2JGE#I#J"); + void *a=NULL,*m=NULL; + assert(init(NULL)==22 && init(&a)==0); + assert(type(&a,99)==22 && type(&a,2)==0); + assert(mutex_init(&m,&a)==0 && destroy_attr(&a)==0); + assert(lock(&m)==0 && trylock(&m)==0 && destroy(&m)==16); + assert(unlock(&m)==0 && unlock(&m)==0 && destroy(&m)==0); + m=NULL; + assert(lock(&m)==0 && lock(&m)==11 && trylock(&m)==16); + assert(unlock(&m)==0 && destroy(&m)==0); + assert(!runtime_resolve("dQHWEsJtoE4#q#q",0)); +} +static void wall_time(void) { + typedef int (ABI *GetTime)(int64_t *,int32_t *); + GetTime get=GET(GetTime,"n88vx3C5nW8#I#J"); + struct { int64_t value[2]; uint64_t canary; } t={{0,0},0xabcdef}; + struct { int32_t value[2]; uint32_t canary; } z={{0,0},0x123456}; + time_t before=time(NULL); + assert(get(t.value,z.value)==0); + time_t after=time(NULL); + assert(t.value[0]>=before && t.value[0]<=after); + assert(t.value[1]>=0 && t.value[1]<1000000); + assert(t.canary==0xabcdef && z.canary==0x123456); + assert(get(NULL,NULL)==0 && get(NULL,z.value)==0); + assert(!runtime_resolve("n88vx3C5nW8#q#q",0)); +} +static void direct_memory(void) { + Allocate alloc=GET(Allocate,"rTXw65xmLIA#p#J"); + Map map=GET(Map,"L-Q3LEjIbgA#p#J"); + Unmap unmap=GET(Unmap,"cQke9UuBQOk#p#J"); + Release release=GET(Release,"MBuItvba6z8#p#J"); + int64_t a=-1,b=-1,c=-1; + const uint64_t pool=536870912, length=16384; + assert((uint32_t)alloc(0,pool,1,0,0,&a)==0x80020016 && a==-1); + assert((uint32_t)alloc(0,8192,length,0,0,&a)==0x80020023); + assert(alloc(0,pool,length,2097152,0,&a)==0 && a==0); + assert(alloc(0,pool,length,2097152,0,&b)==0 && b==2097152); + assert(alloc(0,pool,length,16384,0,&c)==0 && c==16384); + void *x=NULL,*y=NULL,*invalid=NULL; + assert((uint32_t)map(&invalid,length*2,3,0,b,0)==0x80020016); + assert(map(&x,length,3,0,a,2097152)==0 && !((uintptr_t)x%2097152)); + assert(map(&y,length,3,0,a,0)==0); + assert(*(uint64_t *)x==0); + *(uint64_t *)x=UINT64_C(0xabcdef0123456789); + assert(*(uint64_t *)y==UINT64_C(0xabcdef0123456789)); /* real shared backing */ + assert((uint32_t)unmap((char *)x+4096,length)==0x80020016); /* unaligned */ + assert(unmap(x,length)==0 && unmap(y,length)==0); + assert(release(a,length)==0 && release(b,length)==0 && release(c,length)==0); + assert(alloc(0,pool,length,0,0,&a)==0 && a==0); + x=NULL; assert(map(&x,length,3,0,a,0)==0); + assert(*(uint64_t *)x==0); /* released allocation does not leak previous data */ + assert(release(a,length)==0); /* release also unmaps owned mapping */ +} +static void memory_primitives(void) { + typedef void *(ABI *Set)(void *,int,size_t); + typedef void *(ABI *Copy)(void *,const void *,size_t); + typedef int (ABI *Compare)(const void *,const void *,size_t); + char a[16],b[16]; + assert(GET(Set,"8zTFvBIAIN8#q#q")(a,0x5a,sizeof(a))==a); + assert(GET(Copy,"Q3VBxCXhUHs#q#q")(b,a,sizeof(a))==b); + assert(GET(Compare,"DfivPArhucg#q#q")(a,b,sizeof(a))==0); + memcpy(a,"abcdef",7); + GET(Copy,"+P6FRGH4LfA#q#q")(a+1,a,6); + assert(memcmp(a,"aabcdef",7)==0); + typedef size_t (ABI *Length)(const char *); + Length length=GET(Length,"j4ViWNHEgww#q#q"); + assert(length("")==0 && length("abc\0def")==3 && length("\xff\x80")==2); +} + +static HandleOp rw_read, rw_write, rw_tryread, rw_trywrite, rw_unlock, rw_destroy; +typedef struct { int64_t seconds, nanoseconds; } TestTime; +typedef int32_t (ABI *TimedLock)(void **, const TestTime *); +static void rw_setup(void) { + rw_read=GET(HandleOp,"Ox9i0c7L5w0#p#J"); rw_write=GET(HandleOp,"mqdNorrB+gI#p#J"); + rw_tryread=GET(HandleOp,"XD3mDeybCnk#p#J"); rw_trywrite=GET(HandleOp,"bIHoZCTomsI#p#J"); + rw_unlock=GET(HandleOp,"+L98PIbGttk#p#J"); rw_destroy=GET(HandleOp,"BB+kb08Tl9A#p#J"); + assert(rw_read && rw_write && rw_tryread && rw_trywrite && rw_unlock && rw_destroy); +} +static void rw_lifecycle(void) { + rw_setup(); + MutexInit init=GET(MutexInit,"6ULAa0fq4jA#p#J"); + void *lock; + assert((uint32_t)init(NULL,NULL,NULL)==0x80020016); + assert(init(&lock,NULL,"rw-test")==0); + assert(rw_read(&lock)==0 && rw_read(&lock)==0); + assert((uint32_t)rw_trywrite(&lock)==0x80020010); + assert((uint32_t)rw_write(&lock)==0x8002000b); + assert((uint32_t)rw_destroy(&lock)==0x80020010); + assert(rw_unlock(&lock)==0 && rw_unlock(&lock)==0); + assert((uint32_t)rw_unlock(&lock)==0x80020001); + assert(rw_write(&lock)==0); + assert((uint32_t)rw_tryread(&lock)==0x80020010); + assert((uint32_t)rw_read(&lock)==0x8002000b); + assert(rw_unlock(&lock)==0 && rw_destroy(&lock)==0); + assert((uintptr_t)lock==1); + assert((uint32_t)rw_read(&lock)==0x80020016); + assert((uint32_t)rw_destroy(&lock)==0x80020016); + lock=NULL; + assert(rw_destroy(&lock)==0); + assert(rw_read(&lock)==0 && rw_unlock(&lock)==0 && rw_destroy(&lock)==0); + lock=(void *)(uintptr_t)0xdead; + assert((uint32_t)rw_tryread(&lock)==0x80020016); +} +typedef struct { + void *lock; + pthread_barrier_t ready, release, writer_ready; + _Atomic int value; +} RwFixture; +static void barrier(pthread_barrier_t *b) { + int e=pthread_barrier_wait(b); assert(e==0 || e==PTHREAD_BARRIER_SERIAL_THREAD); +} +static void *reader_worker(void *context) { + RwFixture *f=context; + assert(rw_read(&f->lock)==0); + barrier(&f->ready); barrier(&f->release); + assert(atomic_load(&f->value)==0); + assert(rw_unlock(&f->lock)==0); return NULL; +} +static void *writer_worker(void *context) { + RwFixture *f=context; + assert((uint32_t)rw_trywrite(&f->lock)==0x80020010); + barrier(&f->writer_ready); + assert(rw_write(&f->lock)==0); + atomic_store(&f->value,1); + assert(rw_unlock(&f->lock)==0); return NULL; +} +static void *holding_writer(void *context) { + RwFixture *f=context; + assert(rw_write(&f->lock)==0); + barrier(&f->ready); barrier(&f->release); + assert(rw_unlock(&f->lock)==0); return NULL; +} +static void fixture_init(RwFixture *f) { + assert(pthread_barrier_init(&f->ready,NULL,2)==0); + assert(pthread_barrier_init(&f->release,NULL,2)==0); + assert(pthread_barrier_init(&f->writer_ready,NULL,2)==0); +} +static void fixture_destroy(RwFixture *f) { + assert(rw_destroy(&f->lock)==0); + assert(pthread_barrier_destroy(&f->ready)==0); + assert(pthread_barrier_destroy(&f->release)==0); + assert(pthread_barrier_destroy(&f->writer_ready)==0); +} +static void rw_concurrency(void) { + rw_setup(); + RwFixture f={0}; fixture_init(&f); + pthread_t reader,writer; + assert(rw_read(&f.lock)==0); + assert(pthread_create(&reader,NULL,reader_worker,&f)==0); + barrier(&f.ready); /* two threads now hold read locks at once */ + assert(rw_unlock(&f.lock)==0); + assert(pthread_create(&writer,NULL,writer_worker,&f)==0); + barrier(&f.writer_ready); + assert((uint32_t)rw_destroy(&f.lock)==0x80020010); + assert(atomic_load(&f.value)==0); + barrier(&f.release); + assert(pthread_join(reader,NULL)==0 && pthread_join(writer,NULL)==0); + assert(atomic_load(&f.value)==1); + fixture_destroy(&f); +} +static void rw_timeouts(void) { + rw_setup(); + TimedLock read_timed=GET(TimedLock,"iPtZRWICjrM#p#J"), write_timed=GET(TimedLock,"adh--6nIqTk#p#J"); + RwFixture f={0}; fixture_init(&f); + pthread_t writer; assert(pthread_create(&writer,NULL,holding_writer,&f)==0); + barrier(&f.ready); + TestTime expired={0,0},invalid={0,1000000000}; + assert((uint32_t)read_timed(&f.lock,&expired)==0x8002003c); + assert((uint32_t)write_timed(&f.lock,&expired)==0x8002003c); + assert((uint32_t)read_timed(&f.lock,&invalid)==0x80020016); + assert((uint32_t)rw_unlock(&f.lock)==0x80020001); + barrier(&f.release); assert(pthread_join(writer,NULL)==0); + assert(read_timed(&f.lock,&invalid)==0); /* available lock ignores deadline */ + assert(rw_unlock(&f.lock)==0); + fixture_destroy(&f); +} +int main(int argc,char **argv) { + runtime_start(0); assert(runtime_resolve("bzQExy189ZI#q#q",0)==0); + runtime_start(1); + assert(runtime_resolve("bzQExy189ZI#wrong#module",0)==0); + assert(runtime_resolve("unknown",0)==0); + assert(runtime_resolve("8zTFvBIAIN8#q#q",1)==0); + assert(runtime_resolve("f7uOxY9mM1U#p#J",0)==0); + uint64_t *canary=(uint64_t *)runtime_resolve("f7uOxY9mM1U#p#J",1); + assert(canary && *canary && !(*canary & 255)); + if (argc>1 && !strcmp(argv[1],"--guard-recursion")) { + uint64_t guard=0; Acquire acquire=GET(Acquire,"3GPpjQdAMTw#q#q"); + acquire(&guard); acquire(&guard); return 99; + } + if (argc>1 && !strcmp(argv[1],"--bad-tls")) { + static const char data[4]={0}; + runtime_set_libc_tls(data,4,8); + const uint64_t index[]={2,8}; + GET(TlsAddress,"vNe1w4diLCs#p#J")(index); return 99; + } + if (argc>1 && !strcmp(argv[1],"--stack-failure")) { + GET(GuestCallback,"Ou3iL1abvng#p#J")(); return 99; + } + if (argc>1 && !strcmp(argv[1],"--rwlock-lifecycle")) { rw_lifecycle(); return 0; } + if (argc>1 && !strcmp(argv[1],"--rwlock-concurrency")) { rw_concurrency(); return 0; } + if (argc>1 && !strcmp(argv[1],"--rwlock-timeouts")) { rw_timeouts(); return 0; } + libc_support(); posix_mutexes(); wall_time(); exit_handlers(); guards(); mutexes(); direct_memory(); memory_primitives(); + rw_lifecycle(); rw_concurrency(); rw_timeouts(); + puts("PASS: callback lifecycle, guard ABI, mutex errors, shared direct memory, memory primitives, resolver scope"); + return 0; +} diff --git a/test_runtime.py b/test_runtime.py new file mode 100644 index 0000000..916a176 --- /dev/null +++ b/test_runtime.py @@ -0,0 +1,43 @@ +from pathlib import Path +import subprocess +import unittest + +EXE = Path(__file__).parent / 'out/runtime-test' + + +@unittest.skipUnless(EXE.exists(), 'run bash build.sh --test first') +class RuntimeTests(unittest.TestCase): + def run_case(self, *args): + return subprocess.run([str(EXE.resolve()), *args], capture_output=True, text=True, timeout=10) + + def test_runtime_contracts(self): + r=self.run_case() + self.assertEqual(r.returncode,0,r.stdout+r.stderr) + self.assertIn('PASS: callback lifecycle',r.stdout) + + def test_recursive_guard_fails_explicitly(self): + r=self.run_case('--guard-recursion') + self.assertEqual(r.returncode,21) + self.assertIn('recursive/concurrent static initialization',r.stderr) + + def test_stack_corruption_is_not_ignored(self): + r=self.run_case('--stack-failure') + self.assertEqual(r.returncode,22) + self.assertIn('stack protector detected corruption',r.stderr) + + def test_tls_bounds_are_checked(self): + r=self.run_case('--bad-tls') + self.assertEqual(r.returncode,21) + self.assertIn('unsupported TLS module/offset',r.stderr) + + def test_rwlock_lifecycle_and_ownership(self): + r=self.run_case('--rwlock-lifecycle') + self.assertEqual(r.returncode,0,r.stdout+r.stderr) + + def test_rwlock_multiple_readers_exclude_writer(self): + r=self.run_case('--rwlock-concurrency') + self.assertEqual(r.returncode,0,r.stdout+r.stderr) + + def test_rwlock_timeouts_use_orbis_errors(self): + r=self.run_case('--rwlock-timeouts') + self.assertEqual(r.returncode,0,r.stdout+r.stderr) diff --git a/test_sema.c b/test_sema.c new file mode 100644 index 0000000..158c629 --- /dev/null +++ b/test_sema.c @@ -0,0 +1,133 @@ +#define _GNU_SOURCE +#include "runtime.h" +#include <assert.h> +#include <pthread.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <limits.h> +typedef int32_t (ABI *Create)(uint32_t *,const char *,uint32_t,int32_t,int32_t,const void *); +typedef int32_t (ABI *CountOp)(uint32_t,int32_t); +typedef int32_t (ABI *Wait)(uint32_t,int32_t,uint32_t *); +typedef int32_t (ABI *Delete)(uint32_t); +typedef int32_t (ABI *Cancel)(uint32_t,int32_t,int32_t *); +#define GET(t,n) ((t)runtime_resolve(n,0)) +static Create create; +static CountOp poll_sem,signal_sem; +static Wait wait_sem; +static Delete delete_sem; +static Cancel cancel_sem; +static void setup(void) { + runtime_start(1); + create=GET(Create,"188x57JYp0g#p#J"); + poll_sem=GET(CountOp,"12wOHk8ywb0#p#J"); + signal_sem=GET(CountOp,"4czppHBiriw#p#J"); + wait_sem=GET(Wait,"Zxa0VhQVTsk#p#J"); + delete_sem=GET(Delete,"R1Jvn8bSCW8#p#J"); + cancel_sem=GET(Cancel,"4DM06U2BNEY#p#J"); + assert(create && poll_sem && signal_sem && wait_sem && delete_sem && cancel_sem); + assert(!runtime_resolve("188x57JYp0g#I#J",0)); + assert(!runtime_resolve("188x57JYp0g#p#J",1)); +} +static void lifecycle(void) { + struct { uint32_t handle,canary; } s={0,0xdeadbeef}; + assert((uint32_t)create(NULL,"test",1,0,1,NULL)==0x80020016); + assert((uint32_t)create(&s.handle,"test",1,2,1,NULL)==0x80020016); + assert(create(&s.handle,"test",2,2,3,NULL)==0 && s.canary==0xdeadbeef); + uint32_t old=s.handle,timeout=1000000; + assert(wait_sem(s.handle,2,&timeout)==0 && timeout==1000000); + assert((uint32_t)poll_sem(s.handle,1)==0x80020010); + timeout=0; + assert((uint32_t)wait_sem(s.handle,1,&timeout)==0x8002003c); + assert((uint32_t)signal_sem(s.handle,4)==0x80020016); + assert((uint32_t)poll_sem(s.handle,0)==0x80020016); + assert((uint32_t)signal_sem(s.handle,-1)==0x80020016); + assert(signal_sem(s.handle,3)==0); + assert((uint32_t)signal_sem(s.handle,INT_MAX)==0x80020016); + assert(poll_sem(s.handle,3)==0); + int32_t n=-1; + assert(cancel_sem(s.handle,-1,&n)==0 && n==0); + assert(poll_sem(s.handle,2)==0); + assert(delete_sem(s.handle)==0); + assert((uint32_t)delete_sem(s.handle)==0x80020003); + assert((uint32_t)signal_sem(s.handle,1)==0x80020003); + assert(create(&s.handle,"test",1,0,1,NULL)==0 && s.handle!=old); + assert((uint32_t)poll_sem(old,1)==0x80020003); + timeout=1000; + assert((uint32_t)wait_sem(s.handle,1,&timeout)==0x8002003c && timeout==0); + assert(runtime_sema_waiters(s.handle)==0); + assert(signal_sem(s.handle,1)==0 && poll_sem(s.handle,1)==0); + assert(delete_sem(s.handle)==0); +} +typedef struct { uint32_t id; int32_t need,result; uint32_t timeout; } Task; +static void *waiter(void *p) { Task *t=p; t->result=wait_sem(t->id,t->need,&t->timeout); return NULL; } +static void enrolled(uint32_t id,unsigned count) { + const struct timespec nap={0,1000000}; + for (int i=0;i<2000;++i) { + if (runtime_sema_waiters(id)==count) return; + nanosleep(&nap,NULL); + } + assert(!"waiter enrollment timed out"); +} +static void concurrency(void) { + uint32_t id; + assert(create(&id,"fifo",1,0,3,NULL)==0); + Task a={id,1,99,5000000},b={id,1,99,5000000}; + pthread_t first,second; + assert(pthread_create(&first,NULL,waiter,&a)==0); enrolled(id,1); + assert(pthread_create(&second,NULL,waiter,&b)==0); enrolled(id,2); + assert(signal_sem(id,1)==0); + assert(pthread_join(first,NULL)==0 && a.result==0 && a.timeout<=5000000); + assert(runtime_sema_waiters(id)==1 && (uint32_t)poll_sem(id,1)==0x80020010); + assert(signal_sem(id,1)==0); + assert(pthread_join(second,NULL)==0 && b.result==0); + /* A request that fits can pass an earlier larger request, matching the + researched kernel semaphore model. No tokens are partially consumed. */ + a=(Task){id,2,99,5000000}; b=(Task){id,1,99,5000000}; + assert(pthread_create(&first,NULL,waiter,&a)==0); enrolled(id,1); + assert(pthread_create(&second,NULL,waiter,&b)==0); enrolled(id,2); + assert(signal_sem(id,1)==0); + assert(pthread_join(second,NULL)==0 && b.result==0); + assert(runtime_sema_waiters(id)==1); + assert(signal_sem(id,2)==0); + assert(pthread_join(first,NULL)==0 && a.result==0); + assert(delete_sem(id)==0); +} +static void cancellation(void) { + uint32_t id; + assert(create(&id,"cancel",1,0,2,NULL)==0); + Task a={id,1,99,5000000},b={id,1,99,5000000}; + pthread_t first,second; + assert(pthread_create(&first,NULL,waiter,&a)==0); enrolled(id,1); + assert(pthread_create(&second,NULL,waiter,&b)==0); enrolled(id,2); + int32_t n=-1; + assert(cancel_sem(id,1,&n)==0 && n==2); + assert(pthread_join(first,NULL)==0 && (uint32_t)a.result==0x80020055); + assert(pthread_join(second,NULL)==0 && (uint32_t)b.result==0x80020055); + assert(a.timeout==0 && b.timeout==0 && poll_sem(id,1)==0); + a=(Task){id,1,99,5000000}; b=(Task){id,1,99,5000000}; + assert(pthread_create(&first,NULL,waiter,&a)==0); enrolled(id,1); + assert(pthread_create(&second,NULL,waiter,&b)==0); enrolled(id,2); + assert(delete_sem(id)==0); + assert(pthread_join(first,NULL)==0 && (uint32_t)a.result==0x8002000d); + assert(pthread_join(second,NULL)==0 && (uint32_t)b.result==0x8002000d); + assert((uint32_t)poll_sem(id,1)==0x80020003); +} +int main(int argc,char **argv) { + setup(); + if (argc>1 && !strcmp(argv[1],"--priority")) { + /* Priority semaphores block and are woken in FIFO order. */ + uint32_t id; assert(create(&id,"priority",2,0,1,NULL)==0); + Task a={id,1,99,5000000}; pthread_t t; + assert(pthread_create(&t,NULL,waiter,&a)==0); enrolled(id,1); + assert(signal_sem(id,1)==0); + assert(pthread_join(t,NULL)==0 && a.result==0); + puts("PASS: priority semaphore wait"); return 0; + } + if (argc>1 && !strcmp(argv[1],"--concurrency")) concurrency(); + else if (argc>1 && !strcmp(argv[1],"--cancel-delete")) cancellation(); + else lifecycle(); + puts("PASS: semaphore contracts"); + return 0; +} diff --git a/test_sema.py b/test_sema.py new file mode 100644 index 0000000..a8aa066 --- /dev/null +++ b/test_sema.py @@ -0,0 +1,26 @@ +from pathlib import Path +import subprocess +import unittest + +EXE=Path(__file__).parent/'out/sema-test' + +@unittest.skipUnless(EXE.exists(),'run bash build.sh --test first') +class SemaphoreTests(unittest.TestCase): + def run_case(self,*args): + return subprocess.run([str(EXE.resolve()),*args],capture_output=True,text=True,timeout=10) + + def test_counts_errors_timeout_and_stale_ids(self): + r=self.run_case() + self.assertEqual(r.returncode,0,r.stdout+r.stderr) + + def test_fifo_wakeup_and_token_reservation(self): + r=self.run_case('--concurrency') + self.assertEqual(r.returncode,0,r.stdout+r.stderr) + + def test_cancel_and_delete_wake_all_waiters(self): + r=self.run_case('--cancel-delete') + self.assertEqual(r.returncode,0,r.stdout+r.stderr) + + def test_priority_wait_blocks_until_signal(self): + r=self.run_case('--priority') + self.assertEqual(r.returncode,0,r.stdout+r.stderr) diff --git a/third_party/LibAtrac9 b/third_party/LibAtrac9 new file mode 160000 index 0000000..efca2e3 --- /dev/null +++ b/third_party/LibAtrac9 @@ -0,0 +1 @@ +Subproject commit efca2e3af35562a09a9bb6deed90e45b4b824dc4 diff --git a/vulkan_smoke.c b/vulkan_smoke.c new file mode 100644 index 0000000..3318fc8 --- /dev/null +++ b/vulkan_smoke.c @@ -0,0 +1,62 @@ +/* Independent backend smoke test: command submission and readback, no game graphics. */ +#include <vulkan/vulkan.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#define CHECK(call) do { VkResult r = (call); if (r != VK_SUCCESS) { \ + fprintf(stderr, "Vulkan: %s returned %d\n", #call, r); exit(1); } } while (0) + +int vulkan_smoke(void) { + VkApplicationInfo app = {.sType=VK_STRUCTURE_TYPE_APPLICATION_INFO, .pApplicationName="Bloodborne native probe", .apiVersion=VK_API_VERSION_1_0}; + VkInstanceCreateInfo ici = {.sType=VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pApplicationInfo=&app}; + VkInstance instance; CHECK(vkCreateInstance(&ici, NULL, &instance)); + uint32_t count = 0; CHECK(vkEnumeratePhysicalDevices(instance, &count, NULL)); + if (!count) { fprintf(stderr, "Vulkan: no physical devices\n"); vkDestroyInstance(instance, NULL); return 1; } + VkPhysicalDevice *devices = calloc(count, sizeof(*devices)); + if (!devices) exit(1); + CHECK(vkEnumeratePhysicalDevices(instance, &count, devices)); + VkPhysicalDevice physical = devices[0]; free(devices); + VkPhysicalDeviceProperties properties; vkGetPhysicalDeviceProperties(physical, &properties); + uint32_t nq = 0; vkGetPhysicalDeviceQueueFamilyProperties(physical, &nq, NULL); + VkQueueFamilyProperties *families = calloc(nq, sizeof(*families)); + if (!families) exit(1); + vkGetPhysicalDeviceQueueFamilyProperties(physical, &nq, families); + uint32_t family = 0; + while (family < nq && !(families[family].queueCount && (families[family].queueFlags & VK_QUEUE_GRAPHICS_BIT))) ++family; + free(families); + if (family == nq) { fprintf(stderr, "Vulkan: no graphics queue\n"); vkDestroyInstance(instance, NULL); return 1; } + float priority = 1; + VkDeviceQueueCreateInfo qci = {.sType=VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .queueFamilyIndex=family, .queueCount=1, .pQueuePriorities=&priority}; + VkDeviceCreateInfo dci = {.sType=VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .queueCreateInfoCount=1, .pQueueCreateInfos=&qci}; + VkDevice device; CHECK(vkCreateDevice(physical, &dci, NULL, &device)); + VkQueue queue; vkGetDeviceQueue(device, family, 0, &queue); + VkBufferCreateInfo bci = {.sType=VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .size=4096, .usage=VK_BUFFER_USAGE_TRANSFER_DST_BIT, .sharingMode=VK_SHARING_MODE_EXCLUSIVE}; + VkBuffer buffer; CHECK(vkCreateBuffer(device, &bci, NULL, &buffer)); + VkMemoryRequirements requirements; vkGetBufferMemoryRequirements(device, buffer, &requirements); + VkPhysicalDeviceMemoryProperties memory; vkGetPhysicalDeviceMemoryProperties(physical, &memory); + uint32_t type = 0, wanted = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + while (type < memory.memoryTypeCount && !((requirements.memoryTypeBits & (1u << type)) && (memory.memoryTypes[type].propertyFlags & wanted) == wanted)) ++type; + if (type == memory.memoryTypeCount) { fprintf(stderr, "Vulkan: no coherent host memory\n"); exit(1); } + VkMemoryAllocateInfo mai = {.sType=VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize=requirements.size, .memoryTypeIndex=type}; + VkDeviceMemory allocation; CHECK(vkAllocateMemory(device, &mai, NULL, &allocation)); + CHECK(vkBindBufferMemory(device, buffer, allocation, 0)); + VkCommandPoolCreateInfo pci = {.sType=VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .queueFamilyIndex=family}; + VkCommandPool pool; CHECK(vkCreateCommandPool(device, &pci, NULL, &pool)); + VkCommandBufferAllocateInfo cai = {.sType=VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .commandPool=pool, .level=VK_COMMAND_BUFFER_LEVEL_PRIMARY, .commandBufferCount=1}; + VkCommandBuffer command; CHECK(vkAllocateCommandBuffers(device, &cai, &command)); + VkCommandBufferBeginInfo begin = {.sType=VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO}; + CHECK(vkBeginCommandBuffer(command, &begin)); + vkCmdFillBuffer(command, buffer, 0, 4096, 0xb100db0e); + VkMemoryBarrier barrier = {.sType=VK_STRUCTURE_TYPE_MEMORY_BARRIER, .srcAccessMask=VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask=VK_ACCESS_HOST_READ_BIT}; + vkCmdPipelineBarrier(command, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 1, &barrier, 0, NULL, 0, NULL); + CHECK(vkEndCommandBuffer(command)); + VkSubmitInfo submit = {.sType=VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount=1, .pCommandBuffers=&command}; + CHECK(vkQueueSubmit(queue, 1, &submit, VK_NULL_HANDLE)); CHECK(vkQueueWaitIdle(queue)); + uint32_t *pixels; CHECK(vkMapMemory(device, allocation, 0, 4096, 0, (void **)&pixels)); + int ok = 1; for (int i=0; i<1024; ++i) if (pixels[i] != 0xb100db0e) ok = 0; + vkUnmapMemory(device, allocation); + printf("Vulkan: %s; command submission + 4096-byte readback %s\n", properties.deviceName, ok ? "PASS" : "FAIL"); + vkDestroyCommandPool(device, pool, NULL); vkDestroyBuffer(device, buffer, NULL); + vkFreeMemory(device, allocation, NULL); vkDestroyDevice(device, NULL); vkDestroyInstance(instance, NULL); + return ok ? 0 : 1; +}