обработка шейдеров вулкана каждый раз когда я запускаю игру

ОБРАБОТКА ШЕЙДЕРОВ ВУЛКАНА КАЖДЫЙ РАЗ КОГДА Я ЗАПУСКАЮ ИГРУ Дота

Обработка шейдеров вулкан

10 Aug 2020 в 21:50

Что за фигня? почему у меня при каждом запуске доты уже как 2 недели начала вылазить табличка «Обработка шейдеров вулкан», т.е. из-за этого увеличивается время запуска доты, что не есть гут.  в общем зачем дота каждый раз это делает и как это вообще контрить?

зы раньше такое было только после обнов, теперь это кеширование каждый раз ;(

Модератор технического раздела

в настройках стима в разделе «кэш шейдеров» какие галки поставлены?

Поменяй не на вулкан в настройках

Richard Winters сказал(а):↑

в настройках ничего не менял, всё как раньше было

настройки вот такие


ОБРАБОТКА ШЕЙДЕРОВ ВУЛКАНА КАЖДЫЙ РАЗ КОГДА Я ЗАПУСКАЮ ИГРУ

мне нравится вулкан, так как на нём фпс прыгает/проседает по минимуму

перед заходом в доту проверь раскладку если русская то клавиши способностей нажиматься не будут

это фиксится параметром запуска: %command% -input_button_code_is_scan_code

ничего не помогает, кто то решил проблему?

переустановка стима и доты — это ж очевидно

не может быть, если в настройках доты — выбран дх11 и после переустановки стима и доты — не будет никакого вулкана

Do you use the game files with another OS, probably Windows or another Linux with slightly different drivers? I once had a similar issue, using the same game files with different drivers and different Linux distributions.

I have the same problem on my PC (100% Manjaro Linux) since at least 4-6 months which I especially noticed playing Rocket League. Sometimes it launches instantly (2/10) and the other times it displays the vulkan shader progress bar (even after I restart the game).

BUT when I skip it (I have done this for Halo and Rocket League) the games did both still run — I never had that a game after skipping wouldn’t load.

Multiple other titles do not have a problem with this (idk the names but I have played a lot of Windows titles using Proton and a lot of them do never ask this twice or do complete the progress bar so fast that I don’t really care 1-4s).

What ya gonna do.

I made the question because it happened two or three times with the same game («a hat in time»). Each time i allowed the extremely long process to end while doing something else, but for whatever reason i had to do it again (maybe related to the game crashing?). Hope the way steam is handling this process improves.

I dont use the same library files in different machines (yet), but i would try that sometime to see what happens. Im also using manjaro.

+1, I have the same issue on «a hat in time».

It takes forever, every time I launch the game. That by itself is a turn off.

Then it will crash when I am configuring my controller. I cant even play the game anymore.

is there any chance of exiting the game after the lengthy shader compilation and before the crash?

then running it again to confirm it doesn’t do it again unless it crashes or something gets updated (game/proton/related OS components)

Originally posted by Marlock:

Thanks for the recommendation, that did get ride of the «processing vulkan shaders» issue.

Same here — for same games I play several times without any updates. E.g. Shadow of the Tomb Raider. In addition, I often see dowanloads for it telling something about shaders. What’s the catch here? It’*s an «old» game — it should be enoug

Originally posted by Wurzelzweig Linux:

so even if the game itself gets no update at all, there may be need for shader updates

this is getting ridiculous Ubuntu 20.04 , Vega 64 , every-time I launch doom it sits their redoing all the caches for a good hr , and skip does jack

I know this is a older topic, here is my solution:I had enabled Experimental Proton and the game (in my case Rocket League) had to cache shaders for every startup. After changing to a specific Proton version (in my case 6.3-5) it happens very rarely

is there a way to make the process once, so i dont have to «skip» it (when i skip it, sometimes the game wont load).

hi. i have a same problem on linux. if you skipped it but game wont load, you can close steam window (but not in the tray). this must work, like in my case.


ОБРАБОТКА ШЕЙДЕРОВ ВУЛКАНА КАЖДЫЙ РАЗ КОГДА Я ЗАПУСКАЮ ИГРУ

Я переводчик в IT-компании CG Tribe, и я продолжаю выкладывать перевод руководства к Vulkan API (vulkan-tutorial.com).

Сегодня я хочу поделиться с вами переводом первых двух глав раздела, посвященного графическому конвейеру (Graphics pipeline basics), — Introduction и Shader modules.

Вступление

В течение следующих нескольких глав мы будем настраивать графический конвейер, который позволит нам нарисовать первый треугольник. Графический конвейер — это последовательность операций, которые преобразуют вершины и текстуры мешей в пиксели в render target-ах.

Ниже представлена упрощенная схема:


ОБРАБОТКА ШЕЙДЕРОВ ВУЛКАНА КАЖДЫЙ РАЗ КОГДА Я ЗАПУСКАЮ ИГРУ

Input assembler собирает сырые данные вершин из буферов. На этом этапе также может использоваться индексный буфер, который избавляет от необходимости дублировать данные вершин для повторяющихся элементов.

Вершинный шейдер (vertex shader) вызывается для каждой вершины и используется, в основном, для трансформации вершин из локальной системы координат в экранную. Также он передает данные каждой вершины далее по конвейеру.

Шейдеры тесселяции (tessellation shaders) позволяют увеличить количество мешей за счет дополнительного разбиения геометрии. Их часто используют, чтобы сделать близлежащие поверхности, например, кирпичные стены или лестницы, менее плоскими.

Геометрический шейдер (geometry shader) вызывается для каждого примитива (треугольник, линия, точка) и может отменить их отрисовку или сгенерировать новые примитивы. Геометрический шейдер похож на шейдер тесселяции, только, в отличие от него, более гибкий. Однако он не часто используется в современных приложениях из-за недостаточно высокой производительности большинства видеокарт, за исключением встроенных графических процессоров Intel.

На этапе растеризации (rasterization) каждый примитив раскладывается на множество фрагментов. Фрагменты — это пиксельные элементы, которые заполняют примитивы во фреймбуфере. Все фрагменты, которые выходят за пределы экрана, отсекаются, а атрибуты, переданные вершинным шейдером, интерполируются по фрагментам, как показано на рисунке. Фрагменты, находящиеся за другими фрагментами, как правило, тоже отсекаются из-за теста глубины (depth testing).

Фрагментный шейдер (fragment shader) вызывается для каждого фрагмента и определяет, в какие фреймбуферы и с каким значением цвета и глубины записываются фрагменты. Для этого он использует интерполированные данные из вершинного шейдера, такие как текстурные координаты и нормали для освещения.

На этапе смешивания цветов (color blending) происходит смешивание различных фрагментов, относящихся к одному и тому же пикселю во фреймбуфере. Фрагменты могут перекрывать друг друга или смешиваться в зависимости от прозрачности.

Этапы, выделенные зеленым цветом, называются непрограммируемыми (fixed-function). На этих этапах вы можете корректировать операции с помощью параметров, но принцип их работы определен заранее.

Этапы, выделенные оранжевым цветом, — программируемые этапы (programmable). Это значит, что вы можете загрузить свой собственный код на видеокарту, чтобы выполнить необходимые операции. Это позволяет вам использовать, например, фрагментные шейдеры для самых разных задач от текстурирования и освещения до трассировки лучей. Эти программы запускаются одновременно на множестве ядер GPU для параллельной обработки таких объектов как вершины и фрагменты.

Если ранее вы работали с OpenGL или Direct3D, вы, вероятно, привыкли, что можете изменять любые настройки конвейера, когда это нужно, с помощью таких вызовов, как glBlendFunc и OMSetBlendState. В Vulkan же почти все настройки графического конвейера задаются заранее, поэтому вам придется полностью пересоздать конвейер, если вы захотите, например, переключить шейдер, привязать другой фреймбуфер или изменить функцию смешивания. Недостаток Vulkan в том, что нужно создавать несколько конвейеров, чтобы описать все комбинации состояний, которые вы хотите использовать в операциях отрисовки. Однако, поскольку все операции, которые вы будете выполнять в конвейере, известны заранее, у драйвера появляется больше возможностей для оптимизации.

Некоторые программируемые этапы можно пропустить. Например, вы можете отключить тесселяцию и геометрический шейдер, если рисуете простую геометрию. Если вас интересуют только значения глубины (например, при создании карты теней), вы можете отключить фрагментный шейдер.

В следующей главе мы начнем с создания двух программируемых этапов, необходимых для отображения треугольника на экране: вершинного шейдера и фрагментного шейдера. Далее мы настроим непрограммируемые этапы, указав такие параметры, как режим смешивания и viewport. Заключительная часть создания графического конвейера включает настройку входных данных и выходных фреймбуферов.

Создайте функцию createGraphicsPipeline, которая вызывается сразу после createImageViews в initVulkan. Мы будем работать с ней в последующих главах.

Шейдерные модули

В отличие от более ранних API шейдеры должны быть переданы в Vulkan в виде байт-кода, который называется SPIR-V. Он разработан для работы как с Vulkan, так и с OpenCL (оба Khronos API). S PIR-V можно использовать для создания графических и вычислительных шейдеров, но мы сосредоточимся только на шейдерах, используемых в графическом конвейере Vulkan.

Преимущество использования байт-кода в том, что компиляторы, написанные производителями GPU и компилирующие шейдеры в нативный код, получаются значительно проще. К тому же прошлое показало, что при использовании человеко-ориентированного синтаксиса, как GLSL, некоторые вендоры интерпретировали стандарт весьма свободно. При написании нетривиальных шейдеров для GPU такого производителя был большой риск, что код окажется несовместим с драйверами других производителей или, еще хуже, из-за ошибок компилятора шейдер будет работать иначе. Простой формат байт-кода SPIR-V позволяет избежать этих проблем.

Нам не придется писать байт-код вручную. Khronos выпустил собственный компилятор, независимый от производителя, который компилирует GLSL в SPIR-V. Он проверяет, соответствует ли шейдерный код стандарту, и создает бинарный файл SPIR-V для использования в вашей программе. Также этот компилятор можно использовать в качестве библиотеки для создания SPIR-V в рантайме (во время исполнения), но в руководстве мы не будем этого делать. Вместо glslangValidator.exe мы будем использовать glslc.exe от Google. Преимущество glslc в том, что он использует тот же формат командной строки, что и компиляторы GCC или Clang, и включает некоторые дополнительные функции, например, includes. Обе программы уже включены в Vulkan SDK, поэтому не нужно скачивать ничего дополнительно.

GLSL — это язык для программирования шейдеров, синтаксис которого базируется на языке C. Вместо использования параметров для входных данных и возвращаемого значения для выходных, GLSL использует глобальные переменные. В GLSL есть много фич, полезных при работе с графикой, например, встроенные векторные и матричные типы. Также доступны такие операции, как векторное произведение, умножение вектора на матрицу или отражение вектора от плоскости. Векторный тип обозначается как vec с числом, указывающим количество элементов. Так, например, 3D позиция может быть сохранена в vec3. Вы можете получить доступ к отдельным компонентам через такие элементы, как .x, либо создать новый вектор из нескольких компонентов одновременно. Например, результатом выражения vec3 (1.0, 2.0, 3.0) .xy будет vec2. Конструкторы векторов также могут принимать комбинации векторных объектов и скалярных значений. Например, vec3 можно построить с помощью vec3 (vec2 (1.0, 2.0), 3.0).

Как уже было сказано, для отрисовки треугольника мы должны написать вершинный шейдер и фрагментный шейдер. В следующих двух пунктах мы рассмотрим код GLSL для каждого шейдера и покажем, как создать бинарные файлы SPIR-V и загрузить их в программу.

Вершинный шейдер

Вершинный шейдер обрабатывает каждую входящую вершину. В качестве входных данных он принимает вершинные атрибуты, такие как координаты в мировом пространстве, цвет, нормаль и текстурные координаты. Выходные данные — преобразованные координаты в пространстве отсечения (clip space) и атрибуты, которые передаются фрагментному шейдеру (например, цвет и текстурные координаты). Позже эти значения будут интерполированы по фрагментам для создания плавного градиента.


ОБРАБОТКА ШЕЙДЕРОВ ВУЛКАНА КАЖДЫЙ РАЗ КОГДА Я ЗАПУСКАЮ ИГРУ

Если до этого вы работали с OpenGL, вы можете заметить, что координата Y теперь зеркально отражена. А для координаты Z задан тот же диапазон, что и в Direct3D, от 0 до 1.

Для нашего первого треугольника мы не будем применять никаких преобразований, а просто укажем положения трех вершин в нормализованных координатах устройства для создания такой фигуры:

Мы можем отдавать непосредственно нормализованные координаты устройства, используя координаты пространства отсечения с единицей в качестве последнего компонента. Таким образом, деление на w не изменит значения координат при переходе от клип пространства к экранному.

Как правило, нормализированные координаты хранятся в вершинном буфере, но создание вершинного буфера в Vulkan и заполнение его данными — задача нетривиальная. Поэтому мы отложим это до тех пор, пока на экране не появится первый треугольник. А пока применим небольшую хитрость: вставим координаты непосредственно в вершинный шейдер. Код будет выглядеть так:

Функция main вызывается для каждой вершины. Встроенная переменная gl_VertexIndex содержит порядковый номер (index) текущей вершины. Обычно это номер вершины в вершинном буфере, но в нашем случае мы используем его для обращения во встроенный массив. Координаты x и y, полученные из массива, объединяются с константными z и w. В результате мы получаем координаты в пространстве отсечения. Встроенная переменная gl_Position используется в качестве выходной.

Фрагментный шейдер

Вершины, полученные из вершинного шейдера, образуют треугольник, который должен быть заполнен фрагментами (пикселами) на экране. Фрагментный шейдер вызывается для каждого фрагмента и определяет его цвет и значение глубины во фреймбуфере (или фреймбуферах). Чтобы окрасить весь треугольник в красный цвет, используется простой фрагментный шейдер:

Функция main вызывается для каждого фрагмента. Для указания цвета в GLSL используются четырехкомпонентные RGBA-векторы с диапазоном от 0 до 1 для каждого канала. В отличие от вершинного шейдера, во фрагментном шейдере нет встроенной переменной для вывода цвета фрагмента. Вам нужно указать свою собственную выходную переменную для каждого фреймбуфера, где модификатор layout (location = 0) указывает номер фреймбуфера. В нашем случае в переменную outColor, которая связана с первым (и единственным) фреймбуфером с номером 0, записывается красный цвет.

Цвет каждой вершины

Полностью красный треугольник выглядит слишком просто, может, сделаем его поинтереснее?

Для этого внесём кое-какие изменения в оба шейдера. Сначала укажем цвет для каждой из трех вершин. Вершинный шейдер должен включать в себя массив цветов:

Теперь нужно передать цвет каждой вершины во фрагментный шейдер, чтобы он мог вывести их интерполированные значения во фреймбуфер. Добавим выходную переменную для цвета в вершинный шейдер и заполним её в функции main:

Затем добавим соответствующую ему входную переменную во фрагментный шейдер:

Входная и выходная переменная могут иметь разные имена — соответствие устанавливается с помощью номера, указанного в location. Как показано на изображении выше, значения fragColor будут автоматически интерполироваться по фрагментам между тремя вершинами для создания плавного градиента.

Компиляция шейдеров

Создадим каталог с именем shaders в корневом каталоге проекта и сохраним вершинный шейдер в файл с именем shader.vert. Фрагментный шейдер сохраним в файл с именем shader.frag. Для шейдеров GLSL нет официального расширения, но чаще всего используются .vert и .frag.

Содержимое файла shader.vert должно быть следующим:

А содержимое файла shader.frag следующим:

Теперь скомпилируем этот код в байт-код SPIR-V с помощью glslc.

Создайте файл compile.bat, который будет содержать следующее:

C:/VulkanSDK/x.x.x.x/Bin32/glslc.exe shader.vert -o vert.spv
C:/VulkanSDK/x.x.x.x/Bin32/glslc.exe shader.frag -o frag.spv
pause

Замените путь к glslc.exe на путь установки Vulkan SDK. Дважды щелкните по файлу, чтобы запустить его.

Создайте файл compile.sh, который будет содержать следующее:

Замените путь к glslc на путь установки Vulkan SDK. Сделайте скрипт исполняемым с помощью команды chmod + x compile.sh и запустите его.

Эти две команды говорят компилятору прочитать исходный файл GLSL и вывести его в байт-код SPIR-V с помощью флага -o (output).

Если в вашем шейдере есть синтаксическая ошибка, компилятор сообщит вам номер строки и укажет на проблему. Чтобы в этом убедиться, попробуйте, например, убрать точку с запятой откуда-нибудь из текста шейдеров и по новой запустить скрипт. Также можете запустить компилятор без аргументов, чтобы узнать, какие типы флагов он поддерживает. Кроме того, компилятор может, например, вывести байт-код в формат удобный для чтения, чтобы вы могли посмотреть, что делает шейдер и какие оптимизации были выполнены на этом этапе.

Компиляция шейдеров в командной строке — один из самых простых способов, который мы будем использовать в руководстве, но вы можете скомпилировать шейдеры непосредственно из вашего кода. Для этого в Vulkan SDK есть libshaderc — библиотека для компиляции кода GLSL в SPIR-V.

Загрузка шейдера

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

Функция readFile будет считывать все байты из указанного файла и возвращать их в байтовом массиве, обернутом в std :: vector. При открытии файла используем два флага:

Смысл установки указателя чтения на конец файла в том, что таким образом мы можем вычислить размер файла и заранее выделить память под буфер.

Затем мы можем вернуть указатель в начало файла и считать все байты за один вызов:

И, наконец, закроем файл и возвратим буфер:

Теперь вызовем функцию readFile из createGraphicsPipeline, чтобы загрузить байт-код обоих шейдеров:

Вы можете проверить, правильно ли загрузились файлы. Для этого можно напечатать в лог размер загруженных данных и сравнить с тем, что лежит на диске. Обратите внимание, что мы загружаем бинарные данные, а не текст, поэтому размер нельзя вычислять по нулевому байту в конце. Позже нам потребуется явно указывать размер полученных данных, и мы будем использовать для этого метод size контейнера std::vector.

Создание шейдерных модулей

Прежде чем передать код конвейеру, мы должны обернуть его в VkShaderModule. Для этого создадим функцию createShaderModule.

Функция принимает буфер с байт-кодом в качестве параметра и создает из него VkShaderModule.

Создать шейдерный модуль несложно, для этого надо передать указатель на буфер с байт-кодом и размер этого буфера. Эта информация указывается в структуре VkShaderModuleCreateInfo. Единственная загвоздка в том, что размер байт-кода указывается в байтах, а тип указателя байт-кода — uint32_t, вместо char. Поэтому необходимо преобразовать указатель с помощью reinterpret_cast, как показано ниже. Когда вы делаете подобные преобразования, необходимо убедиться, что размещение данных удовлетворяет требованиям по выравниванию uint32_t. К счастью для нас, данные хранятся в std :: vector, в котором дефолтный аллокатор уже гарантирует, что данные так или иначе будут удовлетворять требованиям.

VkShaderModule можно создать с помощью вызова vkCreateShaderModule:

В функцию передаются уже знакомые нам параметры: логическое устройство, указатель на структуру с необходимой информацией, опциональный указатель на кастомный аллокатор и выходная переменная. Буфер с кодом можно освободить сразу после создания шейдерного модуля. Не забудьте вернуть созданный шейдерный модуль:

Шейдерный модуль всего лишь тонкая обертка для шейдерного байт-кода, загруженного из файла, и объявленных в нем функций. Компиляция и линковка байт-кода SPIR-V в машинный код не произойдет до тех пор, пока не будет создан графический конвейер. Это значит, что мы можем уничтожить шейдерные модули сразу после создания конвейера. Поэтому в функции createGraphicsPipeline сделаем их локальными переменными вместо членов класса:

Уничтожим их в конце функции с помощью двух вызовов vkDestroyShaderModule. Остальной код в этой главе будет вставлен перед следующими строками:

Связываем шейдеры и конвейер

Чтобы использовать шейдеры, нужно подключить их к конкретным стадиям конвейера. Для этого при создании конвейера будем использовать структуру VkPipelineShaderStageCreateInfo.

Заполним структуру для вершинного шейдера в функции createGraphicsPipeline.

Первым делом, помимо обязательного указания типа структуры в члене sType, сообщим Vulkan, на какой стадии конвейера будет использоваться шейдер. Для каждой программируемой стадии есть соответствующее значение из перечисления VkShaderStageFlagBits.

vertShaderStageInfo.module = vertShaderModule;
vertShaderStageInfo.pName = «main»;

Следующие два члена указывают шейдерный модуль с кодом и вызываемую функцию, известную как точка входа (entrypoint). Это значит, что можно использовать один шейдерный модуль для нескольких фрагментных шейдеров, меняя поведение с помощью разных точек входа. Но мы будем придерживаться стандартной функции main.

Есть еще один (опциональный) член pSpecializationInfo. Мы не будем его использовать, однако расскажем о нем подробнее. p SpecializationInfo позволяет указывать значения для шейдерных констант. Вы можете использовать один шейдерный модуль, а его поведение настроить при создании конвейера, указав различные значения для используемых констант. Этот способ более эффективный по сравнению с настройкой шейдера во время рендеринга, поскольку компилятор может выполнять оптимизацию, например, удалять операторы if, зависящие от этих значений. Если у вас нет таких констант, вы можете установить nullptr, в нашем случае инициализация структуры делает это автоматически.

А теперь сделаем практически то же самое для фрагментного шейдера:

Наконец создадим массив, содержащий подготовленные нами структуры. Это понадобится нам, чтобы ссылаться на них при создании конвейера.

В этой главе мы рассмотрели только программируемые этапы конвейера. В следующей главе мы перейдем к непрограммируемым этапам.

Поставил, вроде как работает так же, но при каждому запуске обработка шейдеров, так всегда будет? Какие у него плюсы вообще?

Если повезет — фпс будет вышестабильней, но это редкость, и чаще всего на амд картах

У меня амд конфигурация и вулканом пользоваться вообще ад, потому что он какой-то неоптимизированный, дх11 меньше проблем создаёт, поэтому на дх11 и сижу с железяками от амд

у меня также

Вулкан нужен только для слабых видеокарт с 2 Гб памяти

А да поэтому он везде в новых играх соседствует с дх12 чтобы чел с 750ti мог в 4к киберпанк запустить?

Причем тут Киберпанк, это рекомендация valve для доты в момент релиза вулкана для нее

В радуге осаде мне вулкан фреймтайм уменьшает до минимума и кадров на 10 больше

На 11 дота лагает, на вулкане нет.

вулкан типа амдшная тема. у меня видеокарта амд и на вулкане невозможно играть) каждые пару сек просадки с дефолтных 200-230 до 50-70

Вулкан это не амдшная тема, а просто основанная на их АПИ с поддержкой ассинхронных вычислений. Просто у фанатов Нвидии подгорало, когда Максвеллы и Паскали сосали бибу в Вулкане, и они кричали, что мол амуде в этом причастна. С 2000-й серии Turing всё стало нормально.

Если хоч фризов и жестких просадок на ровном месте(которые могут еще длится до конца игры) — то юзай

будет дико тормозить вот такой плюс

Processing Vulkan shaders at every start

I’m playing on Linux (Manjaro), and Dota2 has to process vulkan shaders every time I start the game (or at least every first time after a reboot).

As this always takes a lot of time and it uses all cores and my CPU heats up to 90 degrees, this is highly annoying. Is this normal that it has to process the shaders every time?

Showing — of comments

Yeah I use opengl aswell. I changed back to nvidia-450, with that driver the problem does not exist

come back to windows) it miss you

Originally posted by crysman:

You should stop using OpenGL anyways, as Valve is completely killing OpenGL support in Dota pretty soon. You’ll have to switch over to Vulkan or DX10 or above.

Originally posted by Mr._Cthulhu:

I have the same problem in Manjaro. 🙁

Originally posted by NurZ Nils:

Установил Ubuntu, драйвера на видеокарту тоже, но при каждом запуске доты ОЧЕНЬ ДОЛГО  идет обработка шейдеров vulcan.

Есть какие-то способы это побороть или запустить доту на убунту без существенных потерь по производительности?

Александр Чеботарь сказал(а):↑

Вулкан в целом криво работает в доте

поставь opengl. странно, но он лучше вулкана, правда у тебя будет пустота вместо земли на стартовом экране сил света, но это не критично

Новости:  ВЫРАВНИВАТЕЛЬ ДОТА
Оцените статью
Dota Help