w23 / xash3d-fwgs

Vulkan Ray Tracing fork of Xash3D FWGS engine. Intended to be merged into master at some point in the future.
163 stars 16 forks source link

Bring back ray tracing pipeline support #495

Open w23 opened 1 year ago

w23 commented 1 year ago

Currently we are focused on compute shaders + ray query rendering pipeline, as it gives us more control over vgpr occupancy and performance in general.

Unfortunately (and rather surprisingly), there are GPUs which don't support VK_KHR_ray_query, but do support VK_KHR_ray_tracing_pipeline. E.g. 1660 Ti is an example: https://vulkan.gpuinfo.org/displayreport.php?id=10764#extensions (even more surprisingly, some 1660s on some drivers did report ray query support: https://vulkan.gpuinfo.org/listdevicescoverage.php?extension=VK_KHR_ray_query&platform=all)

So it would make sense to still maintain the ray tracing pipeline path. The code is still there, but it hasn't been really tested for quite a few months, so some amount of bit rot is expected.

This is not high priority, though, and should be addressed after the main rendering path is in a better shape.

0x4E69676874466F78 commented 1 year ago

nilsoncore

Немного офф-топа: я с сожалением для себя узнал, что RTX мне не светит :( (нет расширения ray_query, карточка 1080 Ti). Я почему-то думал, что тут как-то Path Traycing`ом обойдется, но да ладно) Постараюсь пилить вспомогательные утилиты, чтобы ты меньше времени уделял на сторонние вещи, и больше на сам рендер. (надеюсь, хах)

w23

Немного офф-топа: я с сожалением для себя узнал, что RTX мне не светит :( (нет расширения ray_query, карточка 1080 Ti). Я почему-то думал, что тут как-то Path Traycing`ом обойдется, но да ладно) Постараюсь пилить вспомогательные утилиты, чтобы ты меньше времени уделял на сторонние вещи, и больше на сам рендер. (надеюсь, хах)

Если у тебя есть VK_KHR_ray_tracing_pipeline, то не всё потеряно -- #495

0x4E69676874466F78

@nilsoncore

нет расширения ray_query, карточка 1080 Ti

А почему тут пишет что есть: https://vulkan.gpuinfo.org/listdevicescoverage.php?extension=VK_KHR_ray_query&platform=all ? Альтернатива уже выше упомянутый https://vulkan.gpuinfo.org/listdevicescoverage.php?extension=VK_KHR_ray_tracing_pipeline&platform=all Возможно в новых драйверах остался только VK_KHR_ray_tracing_pipeline, где-то что-то такое уже слышал от одного парня на стриме.

nilsoncore

Если у тебя есть VK_KHR_ray_tracing_pipeline, то не всё потеряно -- #495

Сайт вулкана gpuinfo пишет, что у меня вроде как версия r.1 должна быть. Будем думать, что надежды есть.

А почему тут пишет что есть:

Там драйвер старый, 2020 года. Там да, пишет что есть. Но когда смотрю по новому драйверу (который у меня стоит), там такого нет, но есть VK_KHR_ray_tracing_pipeline и VK_NV_ray_tracing

nilsonragee commented 1 year ago

Добавлю немного информации. У меня видеокарта, как и говорил, GTX 1080 Ti. Версия драйвера Nvidia - '536.67' (так написано в NVIDIA Control Panel -> System Information). Запускаю с вот такой строкой: ./xash3d -ref vk -vkdebug -dev 2 -log -vk_rtx 1 -rtx +map c1a0d Немного информации из моего engine.log файла (префиксы времени убрал):

=================================================================================
     (build 3090) started at Sep17 2023 [17:54.11]
=================================================================================

...

Error: VK NOT_IMPLEMENTED(x0): R_SetDisplayTransform (0, 0, 0, 1.000000, 1.000000)
Vulkan version 1.3.241
Requesting instance extensions: 3
    0: VK_KHR_surface
    1: VK_KHR_win32_surface
    2: VK_EXT_debug_utils
Have 1 devices:
    0: 10de:1b06 2 NVIDIA GeForce GTX 1080 Ti 536.268.0 1.3.242
        Queue 0/4 present: 1 graphics: 1 compute: 1
        Supported device extensions: 168
            VK_KHR_swapchain: 0.0.70
            VK_KHR_acceleration_structure: 0.0.13
            VK_KHR_ray_tracing_pipeline: 0.0.1
            VK_KHR_deferred_host_operations: 0.0.4
            VK_KHR_ray_query: N/A
            VK_NV_device_diagnostic_checkpoints: 0.0.2
            VK_NV_device_diagnostics_config: 0.0.2
            VK_EXT_calibrated_timestamps: 0.0.2
        Anistoropy supported: 1
Error: Extension VK_KHR_ray_query is not supported
        Ray tracing supported: 0
        NV checkpoints supported: 1
Trying device #0: 10de:1b06 2 NVIDIA GeForce GTX 1080 Ti 536.268.0 1.3.242
Memory heaps: 3
  0: size=11120Mb used=0Mb avail=10352Mb device_local=1
  1: size=8174Mb used=0Mb avail=7509Mb device_local=0
  2: size=214Mb used=1Mb avail=212Mb device_local=1
Memory types: 11
  0: bit=0x1 heap=1 flags=.....
  1: bit=0x2 heap=1 flags=.....
  2: bit=0x4 heap=1 flags=.....
  3: bit=0x8 heap=1 flags=.....
  4: bit=0x10 heap=1 flags=.....
  5: bit=0x20 heap=1 flags=.....
  6: bit=0x40 heap=1 flags=.....
  7: bit=0x80 heap=0 flags=D....
  8: bit=0x100 heap=1 flags=.VC..
  9: bit=0x200 heap=1 flags=.VC$.
  10: bit=0x400 heap=2 flags=DVC..
Supported surface present modes: 4
    0: VK_PRESENT_MODE_FIFO_KHR (2)
    1: VK_PRESENT_MODE_FIFO_RELAXED_KHR (3)
    2: VK_PRESENT_MODE_MAILBOX_KHR (1)
    3: VK_PRESENT_MODE_IMMEDIATE_KHR (0)
Supported surface formats: 5
    0: VK_FORMAT_B8G8R8A8_UNORM(44) VK_COLOR_SPACE_SRGB_NONLINEAR_KHR(0)
    1: VK_FORMAT_B8G8R8A8_SRGB(50) VK_COLOR_SPACE_SRGB_NONLINEAR_KHR(0)
    2: VK_FORMAT_R16G16B16A16_SFLOAT(97) VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT(1000104002)
    3: VK_FORMAT_A2B10G10R10_UNORM_PACK32(64) VK_COLOR_SPACE_HDR10_ST2084_EXT(1000104008)
    4: VK_FORMAT_A2B10G10R10_UNORM_PACK32(64) VK_COLOR_SPACE_SRGB_NONLINEAR_KHR(0)
Creating swapchain 1920x1080 min_count=3 (extent 1920x1080)
Error: vk: Texture *cintexture layer 0 missing buffer
Renderer ref_vk.dll initialized

...

Из лога видно, что запрашиваемого расширения VK_KHR_ray_query нет, но есть то самое VK_KHR_ray_tracing_pipeline.

nilsonragee commented 1 year ago

нет расширения ray_query, карточка 1080 Ti

А почему тут пишет что есть: https://vulkan.gpuinfo.org/listdevicescoverage.php?extension=VK_KHR_ray_query&platform=all ?

Видимо, это какой-то баг, потому что если перейти по ссылке и посмотреть детальную информацию, то там нигде это расширение не упоминается.

0x4E69676874466F78 commented 1 year ago

@nilsoncore ты прав, я проверил JSON, причём с той версией (460.79.0.0) на 1080 ti там вообще только "VK_NV_ray_tracing": 3, хотя у такой же карточке на более старых драйверах (457.67.0.0) есть ещё "VK_KHR_ray_tracing_pipeline": 1,. Не знаю как теперь этим спискам можно верить.

0x4E69676874466F78 commented 1 year ago

Может ли VK_NV_ray_tracing быть по каким-то причинам синонимом VK_KHR_ray_query?

0x4E69676874466F78 commented 1 year ago

Проблема где-то на их бэкэнде. Я посмотрел в API, там есть эти карты, но внутри самого репорта нихера нет этого.

0x4E69676874466F78 commented 1 year ago

Создал репорт https://github.com/SaschaWillems/vulkan.gpuinfo.org/issues/78

nilsonragee commented 1 year ago

I decided to check all available extensions on my graphics card. Among all of them, I would highlight these ones as probably the most relatable extensions to ray tracing:

After that, I tried to find some info about these extensions in Vulkan 1.3 specification. Here is what I have found.

There is some interesting info on VK_KHR_ray_query page about how VK_KHR_acceleration_structure, VK_KHR_ray_tracing_pipeline, and VK_KHR_ray_query extensions once were a single one called VK_KHR_ray_tracing:


Issues

(1) What are the changes between the public provisional (VK_KHR_ray_tracing v8) release and the final (VK_KHR_acceleration_structure v11 / VK_KHR_ray_query v1) release?

"46.1. Feature Requirements" section describes which features would be available with corresponding extensions:


46.1. Feature Requirements

All Vulkan graphics implementations must support the following features:


There is also small section about ray traversal I want to point out:


39. Ray Traversal

The ray traversal process identifies and handles intersections between a ray and geometries in an acceleration structure.

Ray traversal cannot be started by a Vulkan API command directly - a shader must execute OpRayQueryProceedKHR or OpTraceRayKHR . When the rayTracingPipeline feature is enabled, OpTraceRayKHR can be used for ray tracing in a ray tracing pipeline. When the rayQuery feature is enabled, OpRayQueryProceedKHR can be used in any shader stage.


Section "40.2. Ray Tracing Commands" describes which commands may be used. Here is a quick snippet:


40.2. Ray Tracing Commands

To dispatch ray tracing use:

// Provided by VK_NV_ray_tracing
void vkCmdTraceRaysNV(
    VkCommandBuffer    commandBuffer,
    VkBuffer           raygenShaderBindingTableBuffer,
    VkDeviceSize       raygenShaderBindingOffset,
    VkBuffer           missShaderBindingTableBuffer,
    VkDeviceSize       missShaderBindingOffset,
    VkDeviceSize       missShaderBindingStride,
    VkBuffer           hitShaderBindingTableBuffer,
    VkDeviceSize       hitShaderBindingOffset,
    VkDeviceSize       hitShaderBindingStride,
    VkBuffer           callableShaderBindingTableBuffer,
    VkDeviceSize       callableShaderBindingOffset,
    VkDeviceSize       callableShaderBindingStride,
    uint32_t           width,
    uint32_t           height,
    uint32_t           depth);

To dispatch ray tracing use:

// Provided by VK_KHR_ray_tracing_pipeline
void vkCmdTraceRaysKHR(
    VkCommandBuffer                         commandBuffer,
    const VkStridedDeviceAddressRegionKHR*  pRaygenShaderBindingTable,
    const VkStridedDeviceAddressRegionKHR*  pMissShaderBindingTable,
    const VkStridedDeviceAddressRegionKHR*  pHitShaderBindingTable,
    const VkStridedDeviceAddressRegionKHR*  pCallableShaderBindingTable,
    uint32_t                                width,
    uint32_t                                height,
    uint32_t                                depth);

The VkStridedDeviceAddressRegionKHR structure is defined as:

// Provided by VK_KHR_ray_tracing_pipeline
typedef struct VkStridedDeviceAddressRegionKHR {
    VkDeviceAddress    deviceAddress;
    VkDeviceSize       stride;
    VkDeviceSize       size;
} VkStridedDeviceAddressRegionKHR;

To dispatch ray tracing, with some parameters sourced on the device, use:

// Provided by VK_KHR_ray_tracing_pipeline
void vkCmdTraceRaysIndirectKHR(
    VkCommandBuffer                         commandBuffer,
    const VkStridedDeviceAddressRegionKHR*  pRaygenShaderBindingTable,
    const VkStridedDeviceAddressRegionKHR*  pMissShaderBindingTable,
    const VkStridedDeviceAddressRegionKHR*  pHitShaderBindingTable,
    const VkStridedDeviceAddressRegionKHR*  pCallableShaderBindingTable,
    VkDeviceAddress                         indirectDeviceAddress);

The VkTraceRaysIndirectCommandKHR structure is defined as:

// Provided by VK_KHR_ray_tracing_pipeline
typedef struct VkTraceRaysIndirectCommandKHR {
    uint32_t    width;
    uint32_t    height;
    uint32_t    depth;
} VkTraceRaysIndirectCommandKHR;

To dispatch ray tracing, with some parameters sourced on the device, use:

// Provided by VK_KHR_ray_tracing_maintenance1 with VK_KHR_ray_tracing_pipeline
void vkCmdTraceRaysIndirect2KHR(
    VkCommandBuffer              commandBuffer,
    VkDeviceAddress              indirectDeviceAddress);

The VkTraceRaysIndirectCommand2KHR structure is defined as:

// Provided by VK_KHR_ray_tracing_maintenance1 with VK_KHR_ray_tracing_pipeline
typedef struct VkTraceRaysIndirectCommand2KHR {
    VkDeviceAddress    raygenShaderRecordAddress;
    VkDeviceSize       raygenShaderRecordSize;
    VkDeviceAddress    missShaderBindingTableAddress;
    VkDeviceSize       missShaderBindingTableSize;
    VkDeviceSize       missShaderBindingTableStride;
    VkDeviceAddress    hitShaderBindingTableAddress;
    VkDeviceSize       hitShaderBindingTableSize;
    VkDeviceSize       hitShaderBindingTableStride;
    VkDeviceAddress    callableShaderBindingTableAddress;
    VkDeviceSize       callableShaderBindingTableSize;
    VkDeviceSize       callableShaderBindingTableStride;
    uint32_t           width;
    uint32_t           height;
    uint32_t           depth;
} VkTraceRaysIndirectCommand2KHR;

Now that I think about it, pasting all of these structs might be too much, but whatever. I think it's good to have all the info gathered in a single place rather than always look for it everywhere.

nilsonragee commented 1 year ago

Может ли VK_NV_ray_tracing быть по каким-то причинам синонимом VK_KHR_ray_query?

Это скорее нвидевская альтернатива VK_KHR_ray_tracing_pipeline, как я написал выше, и потом еще дополню. Пишу на английском, чтобы инфа была доступна для большего круга людей, может кто-то шарит и подхватит.

nilsonragee commented 1 year ago

Это скорее нвидевская альтернатива VK_KHR_ray_tracing_pipeline, как я написал выше, и потом еще дополню. Пишу на английском, чтобы инфа была доступна для большего круга людей, может кто-то шарит и подхватит.

Как написано в спецификации на странице самого же VK_KHR_ray_query:

(перевод топорно дословный)

0x4E69676874466F78 commented 1 year ago

@nilsoncore ого, целое расследование!

nilsonragee commented 1 year ago

@nilsoncore ого, целое расследование!

Надо же как-то помогать, help wanted стоит. Да и сам я тогда без лучиков останусь! :D

w23 commented 1 year ago

Увы, VK_NV_ray_tracing это предшественник именно VK_KHR_ray_tracing_pipeline.

nilsonragee commented 1 year ago

Увы, VK_NV_ray_tracing это предшественник именно VK_KHR_ray_tracing_pipeline.

Да, это прям заметно - читаешь функции/структуры, все как у KHR с небольшими отличиями. А какие подводные камни при работе с VK_KHR_ray_tracing_pipeline вместо VK_KHR_ray_query? Я так понимаю это связано как раз с тем, что написано в 39 параграфе "Ray Traversal": трассировка через query может быть на любой стадии шейдера, а через pipeline только на пайплайне трассировки лучей - это?

w23 commented 1 year ago

Увы, VK_NV_ray_tracing это предшественник именно VK_KHR_ray_tracing_pipeline.

Да, это прям заметно - читаешь функции/структуры, все как у KHR с небольшими отличиями.

Йеп.

А какие подводные камни при работе с VK_KHR_ray_tracing_pipeline вместо VK_KHR_ray_query? Я так понимаю это связано как раз с тем, что написано в 39 параграфе "Ray Traversal": трассировка через query может быть на любой стадии шейдера, а через pipeline только на пайплайне трассировки лучей - это?

Это довольно разные вещи, как по сложности, так и концептуально.

Грубо говоря, ray query всего-лишь добавляет возможность в любом месте любого шейдера пульнуть лучём откуда и куда угодно и спросить "чё там?". Можно при традиционном рендере в пиксельном шейдере рисовать тени, спрашивая, не упёрлись ли мы во что-либо между пикселем и источником света. В нашем уютном проектике здесь ворох компьют шейдеров, где мы пуляемся лучами в соответствии с задачей (если лучи из камеры, есть -- из пикселей/точек в мире, и т.д.).

Тогда как ray tracing pipeline это вообще абсолютно новый тип vulkan pipeline, наряду с render и compute. У него жёстко специфицированная структура из наборов шейдерных модулей, которые могут логически вызывать друг друга. Грубо говоря, есть шейдеры, пуляющиеся лучами, есть шейдеры, отвечающие на пересечения луча с материалом с индексом mᵢ, есть шейдеры "луч в никуда", и т.д. Они все по сложным правилам ссылаются друг на друга.

Утверждается, что на нвидии конкретно такая структура может быть аппаратно оптимизирована на видюхе динамически, когда ядрышки оппортунистически исходя из райнтайм наблюдений могут собирать вот из этих специфицированных кирпичиков разные shader invocations в когерентные пучки. На AMD это всё конечно превращается тупо в один гигантский организм compute shader. И, кто бы мог подумать, там получается конечно никакой когерентности, vgpr регистров нужно сто миллионов сто сто, shader occupancy -3. Ну и строить такой пайплайн крайне болезненно, там индирекция на индирекцию на видеопамять индирекцией погоняет. Мы на это не один десяток стримов угрохали, и шишек набили красиво.

Поэтому мы решили побить всё голыми руками на логические стадии в разных compute шейдерах. Это подняло перф везде (в том числе и на нвидии бтв) в разы.

В теории из наших compute кирпичиков и какой-то матери можно собрать rt pipeline идентичный натуральному взад, чему и посвящена эта задача.

nilsonragee commented 1 year ago

Да уж, я тут со своими расследованиями решить учить учёного... Судя по всему, придется изрядно попотеть, и лучше всего это делать, когда хотя бы один бэк-энд уже будет работать стабильно. Главное, чтобы дата релиза была в обозримом будущем...

w23 commented 1 year ago

Да уж, я тут со своими расследованиями решить учить учёного... Судя по всему, придется изрядно попотеть, и лучше всего это делать, когда хотя бы один бэк-энд уже будет работать стабильно. Главное, чтобы дата релиза была в обозримом будущем...

Расследования норм -- сам разберёшься, и подытожишь по-своему с другого угла. Я дал TL;DR со своего угла, потеря, так сказать, с компрессией.

В принципе, впихивание RT pipeline довольно автономное:

  1. Надо убедиться, что sebastian.py и meatpipe.{c,h} в них умеют. Они и умели, в гитовой истории должно быть.
  2. Суметь из кирпичиков в ref/vk/shaders собрать RT pipeline. Можно бить на итерации, например:
    1. Прямой луч с просто с глубиной/координатами
    2. Прямой луч с текстурами без освещения
    3. Прямой луч с простым освещением без теней
    4. Прямой луч со светом и тенями
    5. Непрямые лучи-отскоки (дорисовать остаток совы)
  3. По ходу итераций выше понимать, что нужно поменять/добавить в то, как мы конструируем TLAS/BLAS, индексы "материалов", и пр.

Из сложностей:

0x4E69676874466F78 commented 1 year ago

Мне ответили: https://github.com/SaschaWillems/vulkan.gpuinfo.org/issues/78#issuecomment-1752043340 Если посмотреть вкладку Extensions то там действительно есть

VK_KHR_ray_query | r.1 VK_KHR_ray_tracing_pipeline | r.1