Рамочное приложение Vulkan на MASM x64

Тема в разделе "Vulkan", создана пользователем ml64, 9 май 2026.

  1. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50
    Это классический механизм снятия противоречия по Гегелю.
    То же самое можно сказать и про архитектуру Intel/AMD.

    И всё же для меня OpenGL останется таким:
    Pipes.jpg

    Кстати, в Windows 95 была пасхалка volcano. Возможно, они уже тогда что-то знали:
    volcano.png
     
    Mikl___ и Research нравится это.
  2. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50
    Итак, я запутался, психанул и написал логгер.
    И подключил его как вывод к мессенджеру.
    Теперь лог здорового человека выглядит так:
    Лог курильщика выглядит так:
     

    Вложения:

    • Битый.7z
      Размер файла:
      9,5 КБ
      Просмотров:
      42
    • Рабочий.7z
      Размер файла:
      9,5 КБ
      Просмотров:
      43
    Mikl___ нравится это.
  3. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50
    ...А когда сделал свой логгер, понял, что штатный мессенджер Vulkan мне больше не нужен.
    Почему?
    Потому что он добавляет лишний слой LayerValidation и лишнее расширение ExtDebugUtils, которые не всеми системами поддерживаются.
    А из этого следует, что Туториал построен по соображениям наглядности, а у нас цель - минимальный фрейм на ассемблере при максимуме совместимости.
    Поэтому дальше смотрим в Туториал, но думаем самостоятельно.

    И, следовательно,

    шаг 3 – vkSurface (поверхность)


    создаётся по аналогии с vkInstance: заполняется соответствующая структура, вызывается соответствующая функция. При закрытии приложения всё это подчищается
    --- Сообщение объединено, 8 июн 2026 ---

    Шаг 4 - смотрим, какая у нас видеокарта. И плачем


    Хотя моя малышка - просто Золушка. Она у меня и в TwinMotion рендерит иногда.
    --- Сообщение объединено, 8 июн 2026 ---
    Стандартный подход в Вулкане: два прохода одной и той же функции - в данном случае vkEnumeratePhysicalDevices.
    Один проход считает количество элементов, второй - загружает их для работы.
     

    Вложения:

    Последнее редактирование: 7 июн 2026
    Mikl___ и Research нравится это.
  4. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50

    Шаг 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
    Specify which queues to create (graphics + present)
    Enable any device extensions (e.g., VK_KHR_swapchain)
    Create the device and retrieve queue handles
    Choose surface capabilities (format, present mode, extent)
    Create swapchain images and image views
    Define attachments (color, depth)
    Define subpasses and dependencies
    Shader modules (vertex, fragment)
    Pipeline layout, viewport, rasterizer, multisampling, color blending
    One per swapchain image, attaching the corresponding image view
    Record draw commands for each framebuffer
    For presentation and rendering
    12. Main Loop – Render (vkAcquireNextImageKHR, vkQueueSubmit, vkQueuePresentKHR)
    --- Сообщение объединено, 9 июн 2026 ---

    Шаг 5 - или какой он там уже? -


    Без комментариев. Три записи в логе:
    vkCreateDevice: OK
    vkGetDeviceQueue (Graphics Queue): OK
    vkGetDeviceQueue (Present Queue): OK
    --- Сообщение объединено, 9 июн 2026 ---
    Не знаю, что там дальше, но до середины мы добрались.
    А учитывая, что мы перелопатили всю рамку, чтобы уйти от GLFW, написали свой дампер и логгер, - большая часть пройдена.
    Хотя, вообще-то, я знаю, что там дальше: новые глюки и новые решения.
    Паровоз идёт вперёд, следующая станция - Swapchain
     

    Вложения:

    • Families.zip
      Размер файла:
      20 КБ
      Просмотров:
      40
    • LogicalDevice.zip
      Размер файла:
      22,1 КБ
      Просмотров:
      37
    Последнее редактирование: 8 июн 2026
    Mikl___ и Tech нравится это.
  5. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50

    Шаг i-й (я уже сбился) – Swapchain


    Ничего нового. Всё по той же схеме:
    первый прогон – получаем количество элементов;
    выделяем память под известное количество элементов;
    второй прогон – подгружаем в работу.
    После пятой итерации этот подход уже не напрягает. Рутина.

    Лог пишется.
    Но как это работает (или не работает) узнаем, когда будем (или не будем) рисовать треугольник.
    А пока - мы в середине пути по склону Фудзи. На данном шаге больше всего записей в логе:
    --- Сообщение объединено, 10 июн 2026 в 19:28 ---
    Попёрло, попёрло

    Шаг Render Pass


    Здесь нет сложного кода. Главное - настроить структуры:
    VkAttachmentDescription
    VkAttachmentReference
    VkSubpassDescription
    VkSubpassDependency
    VkRenderPassCreateInfo

    Поскольку мой логгер хоть и пошаговый, но примитивный (он реагирует только на нулевые значения), всё идёт гладко. Везде OK и Success:
    --- Сообщение объединено, 10 июн 2026 в 19:31 ---
    Осталось примерно 40% (в идеале, без учёта судорожного поиска ошибок в готовом коде).
    Так хочется уже увидеть треугольник
     

    Вложения:

    • Swapchain.zip
      Размер файла:
      28,4 КБ
      Просмотров:
      30
    • RenderPass.zip
      Размер файла:
      30,4 КБ
      Просмотров:
      32
    Последнее редактирование: 10 июн 2026 в 15:58
    Mikl___ и Tech нравится это.
  6. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50

    Шаг 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 ---
    И тут я увяз.
    Чувствую, что надолго. Придётся возвращать слой валидации и штатный дебаггер Вулкана. А так не хотелось
     

    Вложения:

    • PipelineLayout.zip
      Размер файла:
      31,8 КБ
      Просмотров:
      29
    • Shaders.zip
      Размер файла:
      35,4 КБ
      Просмотров:
      27
    • PipelineError.zip
      Размер файла:
      38,7 КБ
      Просмотров:
      25
    Mikl___ нравится это.
  7. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50

    Шаг Graphics Pipeline


    Сегодня бухаем идём в филармонию.
    Загрузка откомпилированных шейдеров в память не прокатила, поэтому пришлось написать загрузчик для файлов .spv
    Код (ASM):
    1.  
    2. LoadShader proc pszFileName:QWORD, pdwSize:QWORD, pszLog:QWORD, pgpBuffer:QWORD
    3. local hFile:QWORD, dwRead:QWORD
    4. ;Prologue
    5. push rbp
    6. mov rbp,rsp
    7. and rsp,-16 ;Align the Stack
    8. sub rsp,100h ;Create the Buffer
    9. mov pszFileName,rcx
    10. mov pdwSize,rdx
    11. mov pszLog,r8
    12. mov pgpBuffer,r9
    13. ;LOG_TEXT szLog
    14. mov rcx,r8
    15. call WriteLog
    16. ;Open file
    17. mov rcx,pszFileName
    18. mov rdx,80000000h ;GENERIC_READ
    19. mov r8,1 ;FILE_SHARE_READ
    20. xor r9,r9 ;lpSecurityAttributes
    21. mov qword ptr [rsp+20h],3 ;OPEN_EXISTING
    22. mov qword ptr [rsp+28h],0 ;dwFlagsAndAttributes
    23. mov qword ptr [rsp+30h],0; hTemplateFile
    24. call CreateFileA
    25. cmp rax,-1
    26. je lbl_LoadShader_WinError
    27. mov hFile,rax
    28. ;Get file size
    29. mov rcx,hFile
    30. xor rdx,rdx
    31. xor r8,r8
    32. call GetFileSize
    33. test rax,rax
    34. jz lbl_LoadShader_Error_Close
    35. mov rdi,pdwSize
    36. mov qword ptr[rdi],rax
    37. ;Allocate heap memory
    38. call GetProcessHeap
    39. test rax,rax
    40. jz lbl_LoadShader_Error_Close
    41. mov rcx,rax
    42. mov rdx,8 ;HEAP_ZERO_MEMORY
    43. mov rsi,pdwSize
    44. mov r8,qword ptr[rsi]
    45. call HeapAlloc
    46. test rax,rax
    47. jz lbl_LoadShader_Error_Close
    48. mov rdi,pgpBuffer
    49. mov qword ptr[rdi],rax
    50. ;Read file
    51. mov rcx,hFile
    52. mov rdi,pgpBuffer
    53. mov rdx,qword ptr[rdi]
    54. mov rsi,pdwSize
    55. mov r8,qword ptr[rsi]
    56. lea r9,dwRead
    57. mov qword ptr[rsp+20h],0
    58. call ReadFile
    59. test rax,rax
    60. jz lbl_LoadShader_Error_Free_Close
    61. ;Close file
    62. mov rcx,hFile
    63. call CloseHandle
    64. ;Success
    65. LOG_TEXT szOK
    66. jmp lbl_LoadShader_End
    67. lbl_LoadShader_Error_Free_Close:
    68. mov rsi,pgpBuffer
    69. mov rcx,qword ptr[rsi]
    70. call HeapFree
    71. jmp lbl_LoadShader_WinError
    72. lbl_LoadShader_Error_Close:
    73. mov rcx,hFile
    74. call CloseHandle
    75. lbl_LoadShader_WinError:
    76. call SpellWinError
    77. lbl_LoadShader_End:
    78. ;Epilogue
    79. leave
    80. ret
    81. LoadShader endp
    82.  

    Ну и собственно шейдеры:
    #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
     

    Вложения:

    Последнее редактирование: 12 июн 2026 в 18:37
    Mikl___ нравится это.
  8. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50

    Шаг последний (а за ним будет ещё год отладки)


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

    Весь код (не считая шейдеров) занимает 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 ---
    Чистый лог под катом:
    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 сходит с ума.
    Но даже это - не повод для грусти. Поправим. Напильником доработаем
     

    Вложения:

    • RedRect.zip
      Размер файла:
      55 КБ
      Просмотров:
      16
    • VulkanMASM.zip
      Размер файла:
      54,1 КБ
      Просмотров:
      12
    Последнее редактирование: 14 июн 2026 в 08:56
    MaKsIm нравится это.
  9. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    478
    Во-первых, для тех кто не в курсе. Нужно скачать по этой ссылке библиотеку 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-Red_.jpg
      Vulkan-Red_.jpg
      Размер файла:
      36,6 КБ
      Просмотров:
      13
  10. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50

    Последний штрих


    Падение рамочного приложения Vulkan при изменении размеров окна - это не баг, а фича.
    Неслучайно в Мануале (там, где используется GLFW) изначально окно не имеет WS_MAXIMIZEBOX:
    Код (C):
    1. glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
    Я это заметил, но не понял сразу, какая там подлянка.
    Чтобы Вулкан перерисовал окно с новыми размерами, надо перезадать почти всё:

    Код (C):
    1. static void frameBufferResizeCallback(GLFWwindow* window, int width, int height)
    2. {
    3.     recreateSwapChain();
    4. }
    5.  
    6. int recreateSwapChain()
    7. {
    8.     vkDeviceWaitIdle(s_logicalDevice);
    9.  
    10.     cleanUpSwapChain(); //r2
    11.     createSwapChain(); //s7
    12.     createDepthResources(); //s11
    13.     createRenderPass(); //s8
    14.     createGraphicsPipeline(); //s10
    15.     createFrameBuffers(); //s12
    16.     createCommandBuffers(); //s20
    17.  
    18.     return EXIT_SUCCESS;
    19. }
    Поэтому, чтобы не переусложнять рамочное приложение, я тоже убрал всё, что связано с изменением размеров.

    Наслаждаемся видом красного вулкана на фоне зелёного луга:

    RedVolcano.jpg

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

    При этом перекомпилировать нужно только шейдеры, а не само приложение.

    Ну и для сведения: файл Vulkan.exe занимает 23 кб.

    --- Сообщение объединено, 15 июн 2026 в 02:25 ---
    Это Вулкан. Он такой. Пришлите, пожалуйста, лог. Лучше - в результате запуска самой новой редакции приложения (rev0). Посмотрю, на что он ругается
     

    Вложения:

    • VkMASM_rev0.zip
      Размер файла:
      54,4 КБ
      Просмотров:
      10
    Последнее редактирование: 15 июн 2026 в 02:49
    Tech нравится это.
  11. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    478
    vk_log.txt :

    Application Started
    Entering WinMain
    RegisterClass: OK
    CreateMenu: OK
    CreateAcceleratorTable: OK
    CreateWindow: OK
    CreateStatusBar: OK
    vkCreateInstance Error: 0xFFFFFFFA
    vkGetInstanceProcAddr Error: 0xFFFFFFFA
    vkEnumeratePhysicalDevices
     
  12. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50
    У меня точно такой же лог выдавало приложение на второй машине (это ноутбук 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-приложение. Это квант Вулкана.
     

    Вложения:

  13. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    478
    ml64, не обижайтесь, но я не виноват. У меня практически ничего не изменилось - ни тебе прямоугольника, ни тебе треугольника в нем. :)

    Application Started
    Entering WinMain
    RegisterClass: OK
    CreateMenu: OK
    CreateAcceleratorTable: OK
    CreateWindow: OK
    CreateStatusBar: OK
    vkCreateInstance Error: 0xFFFFFFF7
    vkEnumeratePhysicalDevices
     
  14. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50

    Продолжаю тестировать. Пока работает


    Внимание! Во вложении версия приложения со слоем валидации (дебаггером), который не везде запускается
    Но эти же изменения можно применить к минимальной версии (Ревизии 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):
    1. ;VkClearValue (color)
    2. align 10h
    3. [COLOR=#808080]clearValue_red dd 3f000000h ;0.5f
    4. clearValue_green dd 3f000000h ;0.5f
    5. clearValue_blue dd 3f000000h ;0.5f[/COLOR]
    6. сlearValue_a dd 3f800000h ;1.0f
    Установил метод fan - "вентилятор":
    Код (ASM):
    1.  
    2. ;VkPipelineInputAssemblyStateCreateInfo
    3. align 10h
    4. inputAssembly_sType dd 14h ;VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20
    5. inputAssembly_dummy0 dd 0
    6. inputAssembly_pNext dq 0
    7. inputAssembly_flags dd 0
    8. [COLOR=#00b300]inputAssembly_topology dd 5 ;VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN[/COLOR]
    9. inputAssembly_primitiveRestartEnable dd 0
    10.  
    Выставил 8 точек для отрисовки: 6 вершин, один центр (для fan) и 1 замыкающую:
    Код (ASM):
    1.  
    2. ;Draw 8 vertices
    3. LOG_TEXT szLogVkCmdDraw
    4. mov rcx,qword ptr[rdi]
    5. mov rdx,8 ;vertexCount
    6. mov r8,1 ;instanceCount
    7. xor r9,r9 ;firstVertex = 0
    8. mov qword ptr[rsp+20h],0 ;firstInstance = 0
    9. call vkCmdDraw
    10. LOG_TEXT szOK
    11.  
    И переписал шейдеры:

    Код (ASM):
    1.  
    2. #version 450
    3. layout(location = 0) in vec3 fragColor;
    4. layout(location = 0) out vec4 outColor;
    5. void main() {
    6.     outColor = vec4(fragColor, 1.0);
    7. }
    8.  
    Код (ASM):
    1.  
    2. #version 450
    3. layout(location = 0) out vec3 fragColor;
    4. const vec2 center = vec2(0.0, 0.0);
    5. const float radius = 0.5;
    6. const float angleStep = 2.0 * 3.141592653589793 / 6.0; // 60 degrees
    7. // Colors for center + 6 outer vertices + repeat of first outer vertex
    8. const vec3 colors[8] = vec3[](
    9.     vec3(1.0, 1.0, 1.0),   // center
    10.     vec3(1.0, 0.0, 0.0),   // vertex 1 - red
    11.     vec3(1.0, 0.5, 0.0),   // vertex 2 - orange
    12.     vec3(1.0, 1.0, 0.0),   // vertex 3 - yellow
    13.     vec3(0.0, 1.0, 0.0),   // vertex 4 - green
    14.     vec3(0.0, 0.0, 1.0),   // vertex 5 - blue
    15.     vec3(0.5, 0.0, 1.0),   // vertex 6 - purple
    16.     vec3(1.0, 0.0, 0.0)    // vertex 7 - same as vertex 1 (red)
    17. );
    18. void main() {
    19.     int idx = int(gl_VertexIndex);
    20.     vec2 pos;
    21.     if (idx == 0) {
    22.         pos = center;
    23.     } else {
    24.         // For idx 7, use the same angle as idx 1
    25.         int outerIdx = (idx == 7) ? 1 : idx;
    26.         float angle = angleStep * float(outerIdx - 1) - 3.141592653589793 / 2.0; // start at top
    27.         pos = center + radius * vec2(cos(angle), sin(angle));
    28.     }
    29.     gl_Position = vec4(pos, 0.0, 1.0);
    30.     fragColor = colors[idx];
    31. }
    32.  
    Hexagon.jpg
    --- Сообщение объединено, 15 июн 2026 в 20:43 ---
    А это уже совсем другая ошибка:
    0xFFFFFFF7 = -9 = VK_ERROR_INCOMPATIBLE_DRIVER
    Вулкану не нравится драйвер.
    А что говорит утилита vulkaninfoSDK.exe из пакета VulkanSDK?
     

    Вложения:

    • vkHexagon.zip
      Размер файла:
      73,6 КБ
      Просмотров:
      1
    Последнее редактирование: 15 июн 2026 в 20:50
  15. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    478
    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. Наверно, не судьба мне, испытать минуты радости за ваше творчество. :) Или всё же есть надежда, что всё это можно как-то исправить ?
     
  16. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    360
    Лог говорит же, проверь поддержку Vulkan графическим адаптером, и если ок - переустанови драйвер.
     
  17. ml64

    ml64 Member

    Публикаций:
    0
    Регистрация:
    29 окт 2017
    Сообщения:
    50
    Ругается, что не нашёл драйверов.
    А железо какое? Видеокарта? Центральный процессор с интегрированным GPU?