Это классический механизм снятия противоречия по Гегелю. То же самое можно сказать и про архитектуру Intel/AMD. И всё же для меня OpenGL останется таким: Кстати, в Windows 95 была пасхалка volcano. Возможно, они уже тогда что-то знали:
Итак, я запутался, психанул и написал логгер. И подключил его как вывод к мессенджеру. Теперь лог здорового человека выглядит так: Лог курильщика выглядит так:
...А когда сделал свой логгер, понял, что штатный мессенджер Vulkan мне больше не нужен. Почему? Потому что он добавляет лишний слой LayerValidation и лишнее расширение ExtDebugUtils, которые не всеми системами поддерживаются. А из этого следует, что Туториал построен по соображениям наглядности, а у нас цель - минимальный фрейм на ассемблере при максимуме совместимости. Поэтому дальше смотрим в Туториал, но думаем самостоятельно. И, следовательно, шаг 3 – vkSurface (поверхность) создаётся по аналогии с vkInstance: заполняется соответствующая структура, вызывается соответствующая функция. При закрытии приложения всё это подчищается --- Сообщение объединено, 8 июн 2026 --- Шаг 4 - смотрим, какая у нас видеокарта. И плачем Хотя моя малышка - просто Золушка. Она у меня и в TwinMotion рендерит иногда. --- Сообщение объединено, 8 июн 2026 --- Стандартный подход в Вулкане: два прохода одной и той же функции - в данном случае vkEnumeratePhysicalDevices. Один проход считает количество элементов, второй - загружает их для работы.
Шаг 5 – Выбор семейств очередей (Queue families) Та же схема: первый прогон функции считает доступные семейства, второй - подгружает. После первого прогона, получив число семейств, выделяем память под структуры queueFamilyProperties. После второго прогона переходим к выбору семейств. Перед началом перебора выделяем память под массив pSupport. Ищем семейства, поддерживающие графику и презентацию. Два последовательных цикла перебора: в первом ищем графику и/или презентацию, во втором - хотя бы презентацию. Оффтоп: семейства любят и ревитчики, и вулканщики. --- Сообщение объединено, 8 июн 2026 --- Прошёл месяц после старта - мы здесь: 1. Frame Window app 2. Vulkan Instance 3. Validation Layers, Extensions, and Debug Messenger 4. Physical devices and Queue families Спойлер: 5. Create Logical Device (vkCreateDevice) Specify which queues to create (graphics + present) Enable any device extensions (e.g., VK_KHR_swapchain) Create the device and retrieve queue handles Спойлер: 6. Create Swapchain (vkCreateSwapchainKHR) Choose surface capabilities (format, present mode, extent) Create swapchain images and image views Спойлер: 7. Create Render Pass (vkCreateRenderPass) Define attachments (color, depth) Define subpasses and dependencies Спойлер: 8. Create Graphics Pipeline (vkCreateGraphicsPipelines) Shader modules (vertex, fragment) Pipeline layout, viewport, rasterizer, multisampling, color blending Спойлер: 9. Create Framebuffers (vkCreateFramebuffer) One per swapchain image, attaching the corresponding image view Спойлер: 10. Create Command Buffers (vkAllocateCommandBuffers) Record draw commands for each framebuffer Спойлер: 11. Create Synchronization Objects (vkCreateSemaphore, vkCreateFence) For presentation and rendering 12. Main Loop – Render (vkAcquireNextImageKHR, vkQueueSubmit, vkQueuePresentKHR) --- Сообщение объединено, 9 июн 2026 в 00:46 --- Шаг 5 - или какой он там уже? - Без комментариев. Три записи в логе: vkCreateDevice: OK vkGetDeviceQueue (Graphics Queue): OK vkGetDeviceQueue (Present Queue): OK --- Сообщение объединено, 9 июн 2026 в 00:53 --- Не знаю, что там дальше, но до середины мы добрались. А учитывая, что мы перелопатили всю рамку, чтобы уйти от GLFW, написали свой дампер и логгер, - большая часть пройдена. Хотя, вообще-то, я знаю, что там дальше: новые глюки и новые решения. Паровоз идёт вперёд, следующая станция - Swapchain
Шаг i-й (я уже сбился) – Swapchain Ничего нового. Всё по той же схеме: первый прогон – получаем количество элементов; выделяем память под известное количество элементов; второй прогон – подгружаем в работу. После пятой итерации этот подход уже не напрягает. Рутина. Лог пишется. Но как это работает (или не работает) узнаем, когда будем (или не будем) рисовать треугольник. А пока - мы в середине пути по склону Фудзи. На данном шаге больше всего записей в логе: --- Сообщение объединено, 10 июн 2026 в 19:28 --- Попёрло, попёрло Шаг Render Pass Здесь нет сложного кода. Главное - настроить структуры: VkAttachmentDescription VkAttachmentReference VkSubpassDescription VkSubpassDependency VkRenderPassCreateInfo Поскольку мой логгер хоть и пошаговый, но примитивный (он реагирует только на нулевые значения), всё идёт гладко. Везде OK и Success: --- Сообщение объединено, 10 июн 2026 в 19:31 --- Осталось примерно 40% (в идеале, без учёта судорожного поиска ошибок в готовом коде). Так хочется уже увидеть треугольник
Шаг createPipelineLayout Вообще комментировать нечего. Близнец предыдущего createRenderPass Также создаём структуру, проверяем размеры и выравнивание, заполняем, создаём процедуры create и destroy. Достаточно автозамены имени процедуры с предыдушего шага - настолько всё идентично. Результат лаконичен: vkCreatePipelineLayout: OK vkDestroyPipelineLayout: OK --- Сообщение объединено, 11 июн 2026 в 02:28 --- Шаг Shader Modules Подгружаем вершинный и фрагментный шейдеры Создаём структуры, вызываем функции. Шейдеры (чтобы не заморачиваться чтением файлов) включил как include. Ну и лог обогатился строками: vkCreateShaderModule (Vertex): OK vkCreateShaderModule (Fragment): OK --- Сообщение объединено, 11 июн 2026 в 02:30 --- Осталось 30%. Дожимаем --- Сообщение объединено, 11 июн 2026 в 05:55 --- И тут я увяз. Чувствую, что надолго. Придётся возвращать слой валидации и штатный дебаггер Вулкана. А так не хотелось
Шаг Graphics Pipeline Сегодня бухаем идём в филармонию. Загрузка откомпилированных шейдеров в память не прокатила, поэтому пришлось написать загрузчик для файлов .spv Спойлер: Загрузчик Код (ASM): LoadShader proc pszFileName:QWORD, pdwSize:QWORD, pszLog:QWORD, pgpBuffer:QWORD local hFile:QWORD, dwRead:QWORD ;Prologue push rbp mov rbp,rsp and rsp,-16 ;Align the Stack sub rsp,100h ;Create the Buffer mov pszFileName,rcx mov pdwSize,rdx mov pszLog,r8 mov pgpBuffer,r9 ;LOG_TEXT szLog mov rcx,r8 call WriteLog ;Open file mov rcx,pszFileName mov rdx,80000000h ;GENERIC_READ mov r8,1 ;FILE_SHARE_READ xor r9,r9 ;lpSecurityAttributes mov qword ptr [rsp+20h],3 ;OPEN_EXISTING mov qword ptr [rsp+28h],0 ;dwFlagsAndAttributes mov qword ptr [rsp+30h],0; hTemplateFile call CreateFileA cmp rax,-1 je lbl_LoadShader_WinError mov hFile,rax ;Get file size mov rcx,hFile xor rdx,rdx xor r8,r8 call GetFileSize test rax,rax jz lbl_LoadShader_Error_Close mov rdi,pdwSize mov qword ptr[rdi],rax ;Allocate heap memory call GetProcessHeap test rax,rax jz lbl_LoadShader_Error_Close mov rcx,rax mov rdx,8 ;HEAP_ZERO_MEMORY mov rsi,pdwSize mov r8,qword ptr[rsi] call HeapAlloc test rax,rax jz lbl_LoadShader_Error_Close mov rdi,pgpBuffer mov qword ptr[rdi],rax ;Read file mov rcx,hFile mov rdi,pgpBuffer mov rdx,qword ptr[rdi] mov rsi,pdwSize mov r8,qword ptr[rsi] lea r9,dwRead mov qword ptr[rsp+20h],0 call ReadFile test rax,rax jz lbl_LoadShader_Error_Free_Close ;Close file mov rcx,hFile call CloseHandle ;Success LOG_TEXT szOK jmp lbl_LoadShader_End lbl_LoadShader_Error_Free_Close: mov rsi,pgpBuffer mov rcx,qword ptr[rsi] call HeapFree jmp lbl_LoadShader_WinError lbl_LoadShader_Error_Close: mov rcx,hFile call CloseHandle lbl_LoadShader_WinError: call SpellWinError lbl_LoadShader_End: ;Epilogue leave ret LoadShader endp Ну и собственно шейдеры: Спойлер: Фрагментный #version 450 layout(location = 0) out vec4 outColor; void main() { outColor = vec4(1.0, 0.0, 0.0, 1.0); } Спойлер: Вершинный #version 450 void main() { const vec2 positions[3] = vec2[]( vec2(-1.0, -1.0), vec2( 3.0, -1.0), vec2(-1.0, 3.0) ); gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); } И вот награда: Спойлер: Лог Application Started Entering WinMain RegisterClass: OK CreateMenu: OK CreateAcceleratorTable: OK CreateWindow: OK CreateStatusBar: OK vkCreateInstance: OK vkEnumeratePhysicalDevices - First Pass: OK vkEnumeratePhysicalDevices - Second Pass: OK GetPhysicalDeviceProperties: NVIDIA GeForce GTX 1650 GetPhysicalDeviceProperties: Intel(R) UHD Graphics 630 vkCreateWin32SurfaceKHR: OK vkGetPhysicalDeviceQueueFamilyProperties - First Pass: OK Memory Allocating: OK vkGetPhysicalDeviceQueueFamilyProperties - Second Pass: OK Memory Allocating: OK vkGetPhysicalDeviceSurfaceSupportKHR: OK Queue Family Selected Successfully vkCreateDevice: OK vkGetDeviceQueue (Graphics Queue): OK vkGetDeviceQueue (Present Queue): OK vkGetPhysicalDeviceSurfaceCapabilitiesKHR: OK Extent Chosen Successfully vkGetPhysicalDeviceSurfaceFormatsKHR - First Pass: OK Memory Allocating: OK vkGetPhysicalDeviceSurfaceFormatsKHR - Second Pass: OK Format Chosen Successfully vkGetPhysicalDeviceSurfacePresentModesKHR - First Pass: OK Memory Allocating: OK vkGetPhysicalDeviceSurfacePresentModesKHR - Second Pass: OK Present Mode Chosen Successfully vkCreateSwapchainKHR: OK vkGetSwapchainImagesKHR - First Pass: OK Memory Allocating: OK vkGetSwapchainImagesKHR - Second Pass: OK Memory Allocating: OK vkCreateImageView: OK vkCreateImageView: OK vkCreateRenderPass: OK vkCreatePipelineLayout: OK Loading Vertex Shader: OK vkCreateShaderModule (Vertex): OK Loading Fragment Shader: OK vkCreateShaderModule (Fragment): OK vkCreateGraphicsPipelines: OK UpdateWindow: OK Entering Message Loop DrawScene called WM_CLOSE received vkDestroyPipeline: OK vkDestroyShaderModule (Fragment): OK vkDestroyShaderModule (Vertex): OK vkDestroyPipelineLayout: OK vkDestroyRenderPass: OK vkDestroySwapchainKHR: OK vkDestroyDevice: OK vkDestroySurfaceKHR: OK vkDestroyInstance: OK WM_DESTROY received Calling ExitProcess Я окончательно запутался в 10 процедурах. Нет, в целом, я в коде пока ориентируюсь, но на каком этапе появилась та или иная переменная, уже начинаю забывать. Чтобы и читатель не запутался, я растащил по папкам не только код процедур, но и данные. Сделано 75%, осталось 25% (около 5 шагов) А потом увидим, работает это или нет --- Сообщение объединено, 12 июн 2026 в 19:50 --- Шаг предпоследний - пул команд, семафоры, заборы Здесь ничего интересного - несколько типовых структур, однократные вызовы, и дестрой. 85% Спойлер: Лог vkCreateCommandPool: OK vkCreateSemaphoreImageAvailable: OK vkCreateSemaphoreRenderFinished: OK vkCreateFence: OK vkAllocateCommandBuffers: OK ... vkDestroyFence: OK vkDestroySemaphoreRenderFinished: OK vkDestroySemaphoreImageAvailable: OK vkDestroyCommandPool: OK
Шаг последний (а за ним будет ещё год отладки) Получена первая графика от Вулкана! После ровно десяти предупреждений об ошибках Вулкан рисует замечательный красный прямоугольник. Почему не треугольник - пока не знаю. Ошибки вылезают только в процедуре отрисовки, т.е. всю рутину настройки мы прошли, дальше будет тонкая доводка Весь код (не считая шейдеров) занимает 4059 строк Спойлер: Немного статистики Processing: C:\b11\000_CreateInstance.asm Lines: 32 Processing: C:\b11\001_DestroyInstance.asm Lines: 30 Processing: C:\b11\00_WinMain.asm Lines: 163 Processing: C:\b11\010_CreateDebugMessenger.asm Lines: 45 Processing: C:\b11\011_DebugCallback.asm Lines: 42 Processing: C:\b11\012_DestroyDebugMessenger.asm Lines: 40 Processing: C:\b11\01_CreateMenu.asm Lines: 56 Processing: C:\b11\020_EnumeratePhysical.asm Lines: 90 Processing: C:\b11\02_CreateAccel.asm Lines: 13 Processing: C:\b11\030_CreateSurface.asm Lines: 39 Processing: C:\b11\031_DestroySurface.asm Lines: 30 Processing: C:\b11\03_CreateStatusBar.asm Lines: 35 Processing: C:\b11\040_GetQueueFamilyProps.asm Lines: 84 Processing: C:\b11\041_SelectQueueFamily.asm Lines: 113 Processing: C:\b11\042_SelectQueueFamily_5passes.asm Lines: 88 Processing: C:\b11\050_CreateDevice.asm Lines: 91 Processing: C:\b11\051_DestroyDevice.asm Lines: 26 Processing: C:\b11\060_GetCapabilities.asm Lines: 57 Processing: C:\b11\061_GetFormats.asm Lines: 92 Processing: C:\b11\062_ChoosePresentMode.asm Lines: 89 Processing: C:\b11\063_CreateSwapchain.asm Lines: 142 Processing: C:\b11\064_DestroySwapchain.asm Lines: 44 Processing: C:\b11\070_CreateRenderPass.asm Lines: 37 Processing: C:\b11\071_DestroyRenderPass.asm Lines: 27 Processing: C:\b11\080_CreatePipelineLayout.asm Lines: 33 Processing: C:\b11\081_DestroyPipelineLayout.asm Lines: 27 Processing: C:\b11\090_LoadShaders.asm Lines: 95 Processing: C:\b11\091_CreateShaderModules.asm Lines: 86 Processing: C:\b11\092_DestroyShaderModules.asm Lines: 39 Processing: C:\b11\100_CreateGrPipeline.asm Lines: 64 Processing: C:\b11\101_DestroyGrPipeline.asm Lines: 27 Processing: C:\b11\10_WndProc.asm Lines: 88 Processing: C:\b11\110_CreateCommandPool.asm Lines: 37 Processing: C:\b11\111_CreateSemaphores.asm Lines: 47 Processing: C:\b11\112_CreateFence.asm Lines: 33 Processing: C:\b11\113_AllocateCommandBuffers.asm Lines: 60 Processing: C:\b11\114_DestroyCommandObjects.asm Lines: 63 Processing: C:\b11\11_Size.asm Lines: 52 Processing: C:\b11\120_CreateFrameBuffers.asm Lines: 77 Processing: C:\b11\121_RecordCommandBuffers.asm Lines: 100 Processing: C:\b11\122_DestroyFrameBuffers.asm Lines: 37 Processing: C:\b11\130_DrawScene.asm Lines: 99 Processing: C:\b11\70_About.asm Lines: 21 Processing: C:\b11\80_Close.asm Lines: 39 Processing: C:\b11\90_Logger.asm Lines: 110 Processing: C:\b11\99_SpellError.asm Lines: 89 Processing: C:\b11\const.asm Lines: 4 Processing: C:\b11\extern.asm Lines: 135 Processing: C:\b11\macro.asm Lines: 5 Processing: C:\b11\struct.asm Lines: 637 Processing: C:\b11\sz.asm Lines: 178 Processing: C:\b11\var.asm Lines: 141 Processing: C:\b11\Vulkan.asm Lines: 131 Total lines in all .asm files: 4059 --- Сообщение объединено, 14 июн 2026 в 14:16 --- Вот и всё, а ты боялась! Ошибки устранены. Получено работающее рамочное приложение Vulkan на MASM для x64. Пока это ещё не микродвижок, как на OpenGL, но уже готовая рамка. Он рисует не треугольник, а красное поле - но это не вопрос рамки, а вопрос шейдеров. Это уже совсем другая история. Коллеги, буду признателен за обратную связь - у меня нет возможности протестировать на чём-либо, кроме моей основной машины. Напоминаю, что для работы этого приложения нужен установленный Vulkan SDK. Насчёт runtime, опять же, не знаю, т.к. с Вулканом у меня только одна машина. --- Сообщение объединено, 14 июн 2026 в 14:19 --- Чистый лог под катом: Спойлер: Полный лог рамки Vulkan Application Started Entering WinMain RegisterClass: OK CreateMenu: OK CreateAcceleratorTable: OK CreateWindow: OK CreateStatusBar: OK vkCreateInstance: OK vkGetInstanceProcAddr: OK vkCreateDebugUtilsMessengerEXT: OK vkEnumeratePhysicalDevices - First Pass: OK vkEnumeratePhysicalDevices - Second Pass: OK GetPhysicalDeviceProperties: NVIDIA GeForce GTX 1650 GetPhysicalDeviceProperties: Intel(R) UHD Graphics 630 vkCreateWin32SurfaceKHR: OK vkGetPhysicalDeviceQueueFamilyProperties - First Pass: OK Memory Allocating: OK vkGetPhysicalDeviceQueueFamilyProperties - Second Pass: OK Memory Allocating: OK vkGetPhysicalDeviceSurfaceSupportKHR: OK Queue Family Selected Successfully vkCreateDevice: OK vkGetDeviceQueue (Graphics Queue): OK vkGetDeviceQueue (Present Queue): OK vkGetPhysicalDeviceSurfaceCapabilitiesKHR: OK Extent Chosen Successfully vkGetPhysicalDeviceSurfaceFormatsKHR - First Pass: OK Memory Allocating: OK vkGetPhysicalDeviceSurfaceFormatsKHR - Second Pass: OK Format Chosen Successfully vkGetPhysicalDeviceSurfacePresentModesKHR - First Pass: OK Memory Allocating: OK vkGetPhysicalDeviceSurfacePresentModesKHR - Second Pass: OK Present Mode Chosen Successfully vkCreateSwapchainKHR: OK vkGetSwapchainImagesKHR - First Pass: OK Memory Allocating: OK vkGetSwapchainImagesKHR - Second Pass: OK Memory Allocating: OK vkCreateImageView: OK vkCreateImageView: OK vkCreateRenderPass: OK vkCreatePipelineLayout: OK Loading Vertex Shader: OK vkCreateShaderModule (Vertex): OK Loading Fragment Shader: OK vkCreateShaderModule (Fragment): OK vkCreateGraphicsPipelines: OK vkCreateCommandPool: OK vkCreateSemaphoreImageAvailable: OK vkCreateSemaphoreRenderFinished: OK vkCreateFence: OK Memory Allocating: OK vkAllocateCommandBuffers: OK Memory Allocating: OK vkCreateFramebuffer: OK vkCreateFramebuffer: OK Record Command BuffersvkBeginCommandBuffer: OK vkCmdBeginRenderPass: OK vkCmdSetViewport: OK vkCmdSetScissor: OK vkCmdBindPipeline: OK vkCmdDraw: OK vkCmdEndRenderPass: OK vkEndCommandBuffer: OK vkBeginCommandBuffer: OK vkCmdBeginRenderPass: OK vkCmdSetViewport: OK vkCmdSetScissor: OK vkCmdBindPipeline: OK vkCmdDraw: OK vkCmdEndRenderPass: OK vkEndCommandBuffer: OK UpdateWindow: OK Entering Message Loop DrawScene called vkAcquireNextImageKHR: OK vkResetFences: OK vkQueueSubmit: OK vkQueuePresentKHR: OK WM_CLOSE received vkDestroyFence: OK vkDestroySemaphoreRenderFinished: OK vkDestroySemaphoreImageAvailable: OK vkDestroyCommandPool: OK vkDestroyFramebuffer: OK vkDestroyFramebuffer: OK vkDestroyPipeline: OK vkDestroyShaderModule (Fragment): OK vkDestroyShaderModule (Vertex): OK vkDestroyPipelineLayout: OK vkDestroyRenderPass: OK vkDestroySwapchainKHR: OK vkDestroyDevice: OK vkDestroySurfaceKHR: OK vkGetInstanceProcAddr: OK vkDestroyDebugUtilsMessengerEXT: OK vkDestroyInstance: OK WM_DESTROY received Calling ExitProcess --- Сообщение объединено, 14 июн 2026 в 14:22 --- Upd: получено криво работающее приложение. Красный прямоугольник оно показывает хорошо, но после WM_SIZE сходит с ума. Но даже это - не повод для грусти. Поправим. Напильником доработаем
Во-первых, для тех кто не в курсе. Нужно скачать по этой ссылке библиотеку vulkan-1.dll https://sdk.lunarg.com/sdk/download/1.4.350.0/windows/VulkanRT-X64-1.4.350.0-Components.zip Во-вторых, у меня (Win 10 x64) никакой красный квадрат не отображается. Отображается обычное окно, которое было в самом начале и на фоне этого окна, что-то типа MessageBoxA - сообщает об ошибке.
Последний штрих Падение рамочного приложения Vulkan при изменении размеров окна - это не баг, а фича. Неслучайно в Мануале (там, где используется GLFW) изначально окно не имеет WS_MAXIMIZEBOX: Код (C): glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); Я это заметил, но не понял сразу, какая там подлянка. Чтобы Вулкан перерисовал окно с новыми размерами, надо перезадать почти всё: Код (C): static void frameBufferResizeCallback(GLFWwindow* window, int width, int height) { recreateSwapChain(); } int recreateSwapChain() { vkDeviceWaitIdle(s_logicalDevice); cleanUpSwapChain(); //r2 createSwapChain(); //s7 createDepthResources(); //s11 createRenderPass(); //s8 createGraphicsPipeline(); //s10 createFrameBuffers(); //s12 createCommandBuffers(); //s20 return EXIT_SUCCESS; } Поэтому, чтобы не переусложнять рамочное приложение, я тоже убрал всё, что связано с изменением размеров. Наслаждаемся видом красного вулкана на фоне зелёного луга: Смысл этого приложения в том, что можно менять шейдеры в папке SPIR-V, а рамочное приложение будет их загружать и отрисовывать. При этом перекомпилировать нужно только шейдеры, а не само приложение. Ну и для сведения: файл Vulkan.exe занимает 23 кб. --- Сообщение объединено, 15 июн 2026 в 02:25 --- Это Вулкан. Он такой. Пришлите, пожалуйста, лог. Лучше - в результате запуска самой новой редакции приложения (rev0). Посмотрю, на что он ругается
vk_log.txt : Application Started Entering WinMain RegisterClass: OK CreateMenu: OK CreateAcceleratorTable: OK CreateWindow: OK CreateStatusBar: OK vkCreateInstance Error: 0xFFFFFFFA vkGetInstanceProcAddr Error: 0xFFFFFFFA vkEnumeratePhysicalDevices
У меня точно такой же лог выдавало приложение на второй машине (это ноутбук 2023 года без дискретной видеокарты), на которой не был установлен Вулкан. Эти строки означают, что стандартные функции WinAPI отработали нормально, то есть каждая из функций WinAPI, отработав штатно, при выходе поместила в регистр RAX НЕнулевое значение: RegisterClass: OK CreateMenu: OK CreateAcceleratorTable: OK CreateWindow: OK CreateStatusBar: OK Дальше чуть-чуть здесь интереснее. Функции Vulkan, наоборот, при успехе обнуляют регистр RAX, т.е. возвращают значение VK_SUCCESS = 0. Но из Вашего лога видно, что обе функции возвратили значение 0xFFFFFFFA, т.е. VK_ERROR_LAYER_NOT_PRESENT = -6: vkCreateInstance Error: 0xFFFFFFFA vkGetInstanceProcAddr Error: 0xFFFFFFFA В данном приложении присутствует только один слой - VK_LAYER_KHRONOS_validation. Это очень важный слой, поэтому можно сказать, что, если система его не находит, то Вулкан или не установлен, или установлен неправильно. Точно такой же лог у меня был на ноутбуке, на котором не было Вулкана. Простое скачивание и помещение файла vulkan-1.dll в папку с данным приложением не решило вопроса. Лог оставался таким же. Тогда я скачал и установил vulkansdk-windows-X64-1.4.341.1.exe на ноутбук. Но на ноутбуке это пока не помогло. Если раньше мой ноутбук, так же, как и Ваша машина, возвращал VK_ERROR_LAYER_NOT_PRESENT: vkCreateInstance Error: 0xFFFFFFFA vkGetInstanceProcAddr Error: 0xFFFFFFFA потом почему-то пропускал vkCreateDebugUtilsMessengerEXT и перескакивал на vkEnumeratePhysicalDevices (где и рушился без ответа), то теперь (после нормальной установки Vulkan) у меня на ноутбуке приложение падает сразу после входа в vkCreateInstance Error. Буду разбираться, т.к. в утилите Vulkan Configurator я вижу слой VK_LAYER_KHRONOS_validation. Для инфо: на основном компьютере (где дискретная 1650) приложение работает стабильно. Остаётся ещё один вопрос: если Вулкана не было, то откуда взялись эти функции и как они возвратили эти значения: vkCreateInstance Error: 0xFFFFFFFA vkGetInstanceProcAddr Error: 0xFFFFFFFA ? --- Сообщение объединено, 15 июн 2026 в 15:43 --- И это как раз мой случай на ноутбуке. У меня Intel(R) Iris(R) Xe Graphics не работает с VK_LAYER_KHRONOS_validation, хотя видит его в тестах вулкана. После отключения дебаггера-мессенджера приложения работают стабильно. Здесь прилагаю ревизию 1 - с отключенным дебаггером. Теперь это точно минимальное Vulkan-приложение. Это квант Вулкана.
ml64, не обижайтесь, но я не виноват. У меня практически ничего не изменилось - ни тебе прямоугольника, ни тебе треугольника в нем. Application Started Entering WinMain RegisterClass: OK CreateMenu: OK CreateAcceleratorTable: OK CreateWindow: OK CreateStatusBar: OK vkCreateInstance Error: 0xFFFFFFF7 vkEnumeratePhysicalDevices
Продолжаю тестировать. Пока работает Внимание! Во вложении версия приложения со слоем валидации (дебаггером), который не везде запускается Но эти же изменения можно применить к минимальной версии (Ревизии 1 из поста выше) Сделал окно поменьше (для скриншотов): mov rcx,40100h ;dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE lea rdx,szMainWndClass lea r8,szMainWndTitle ;mov r9,16CF0000h ;dwStyle = WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS = 16CF.0000h mov r9,16C80000h ;~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX) mov qword ptr [rsp+20h],10h ;x = 16 mov qword ptr [rsp+28h],10h ;y = 16 mov qword ptr [rsp+30h],200h ;nWidth = 512 mov qword ptr [rsp+38h],200h ;nHeight = 512 mov qword ptr [rsp+40h],0 ;hWndParent mov rax,ghMenuMain mov qword ptr [rsp+48h],rax ;hMenu mov rax,ghInstance mov qword ptr [rsp+50h],rax mov qword ptr [rsp+58h],0 ;Don't Pass Anything To WM_CREATE call CreateWindowExA Поменял фон на серый: Код (ASM): ;VkClearValue (color) align 10h [COLOR=#808080]clearValue_red dd 3f000000h ;0.5f clearValue_green dd 3f000000h ;0.5f clearValue_blue dd 3f000000h ;0.5f[/COLOR] сlearValue_a dd 3f800000h ;1.0f Установил метод fan - "вентилятор": Код (ASM): ;VkPipelineInputAssemblyStateCreateInfo align 10h inputAssembly_sType dd 14h ;VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20 inputAssembly_dummy0 dd 0 inputAssembly_pNext dq 0 inputAssembly_flags dd 0 [COLOR=#00b300]inputAssembly_topology dd 5 ;VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN[/COLOR] inputAssembly_primitiveRestartEnable dd 0 Выставил 8 точек для отрисовки: 6 вершин, один центр (для fan) и 1 замыкающую: Код (ASM): ;Draw 8 vertices LOG_TEXT szLogVkCmdDraw mov rcx,qword ptr[rdi] mov rdx,8 ;vertexCount mov r8,1 ;instanceCount xor r9,r9 ;firstVertex = 0 mov qword ptr[rsp+20h],0 ;firstInstance = 0 call vkCmdDraw LOG_TEXT szOK И переписал шейдеры: Код (ASM): #version 450 layout(location = 0) in vec3 fragColor; layout(location = 0) out vec4 outColor; void main() { outColor = vec4(fragColor, 1.0); } Код (ASM): #version 450 layout(location = 0) out vec3 fragColor; const vec2 center = vec2(0.0, 0.0); const float radius = 0.5; const float angleStep = 2.0 * 3.141592653589793 / 6.0; // 60 degrees // Colors for center + 6 outer vertices + repeat of first outer vertex const vec3 colors[8] = vec3[]( vec3(1.0, 1.0, 1.0), // center vec3(1.0, 0.0, 0.0), // vertex 1 - red vec3(1.0, 0.5, 0.0), // vertex 2 - orange vec3(1.0, 1.0, 0.0), // vertex 3 - yellow vec3(0.0, 1.0, 0.0), // vertex 4 - green vec3(0.0, 0.0, 1.0), // vertex 5 - blue vec3(0.5, 0.0, 1.0), // vertex 6 - purple vec3(1.0, 0.0, 0.0) // vertex 7 - same as vertex 1 (red) ); void main() { int idx = int(gl_VertexIndex); vec2 pos; if (idx == 0) { pos = center; } else { // For idx 7, use the same angle as idx 1 int outerIdx = (idx == 7) ? 1 : idx; float angle = angleStep * float(outerIdx - 1) - 3.141592653589793 / 2.0; // start at top pos = center + radius * vec2(cos(angle), sin(angle)); } gl_Position = vec4(pos, 0.0, 1.0); fragColor = colors[idx]; } --- Сообщение объединено, 15 июн 2026 в 20:43 --- А это уже совсем другая ошибка: 0xFFFFFFF7 = -9 = VK_ERROR_INCOMPATIBLE_DRIVER Вулкану не нравится драйвер. А что говорит утилита vulkaninfoSDK.exe из пакета VulkanSDK?
WARNING: [Loader Message] Code 0 : windows_read_data_files_in_registry: Registry lookup failed to get layer manifest files. ERROR: [Loader Message] Code 0 : windows_read_data_files_in_registry: Registry lookup failed to get ICD manifest files. Possibly missing Vulkan driver? ERROR: [Loader Message] Code 0 : vkCreateInstance: Found no drivers! Cannot create Vulkan instance. This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU that does not support Vulkan. ERROR at C:\SDKBuild\build-X64-1.4.350.0\Vulkan-Tools\vulkaninfo\vulkaninfo.h:611:vkCreateInstance failed with ERROR_INCOMPATIBLE_DRIVER P.S. Наверно, не судьба мне, испытать минуты радости за ваше творчество. Или всё же есть надежда, что всё это можно как-то исправить ?