Vulkan 1.0 Release

Very very nice work, Spasi!
Those changes got rid of my manual function lookups, reduced the parameter list of many methods which took multiple dispatchables but only needed one, and I also found many many “PointerBuffer should be LongBuffer” errors along the way due to now having type-safety with the classes. :slight_smile:
These changes feel very nice and the whole binding feels very mature already, also when compared to C code!

I have but one tiny request: I think VkCommandBuffer’s are going to be created a huge huge number of times in an application, since from the Vulkan perspective they are very very lightweight.
Now it would be absolutely disastrous if it made LWJGL lookup the function pointers on each instantiation. :slight_smile:
Or just doing an instantiation of the VkCommandBuffer Java object itself is pretty bad in this case.
Since it seems that VkCommandBuffer’s only really dispatch based on their owned VkDevice, could we make the VkCommandBuffer handle inside the VkCommandBuffer class mutable?

Not sure about the frequency. I’m still reading the spec and writing the sample code and haven’t gotten to command buffers yet. But note:

  • There’s vkResetCommandBuffer, you can (should?) reuse command buffers.
  • Escape analysis applies to handle objects. Multiple threads building command buffers in tight loops might benefit from that.

In any case, I’ll wait for input when there are real/complete Vulkan applications. If garbage generation turns out to be a problem, the current handle classes can be made mutable without breaking anything.

Schedule a meeting (Skype…?) or something with Vulkan creators. I am sure you can hash some stuff out!

Has anyone gotten VK_EXT_debug_report working? It seems a lot less powerful compared to OpenGL’s system, and it doesn’t actually seem to catch anything.

I’ve got VK_LAYER_LUNARG_standard_validation added to the list of extensions and I’ve registered a callback with vkCreateDebugReportCallbackEXT():


			vkCreateDebugReportCallbackEXT(instance, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, new VkDebugReportCallbackEXT() {
				
				@Override
				public int invoke(int flags, int objectType, long object, long location, int messageCode, long pLayerPrefix, long pMessage, long pUserData) {
					System.err.println("ERROR OCCURED: " + MemoryUtil.memDecodeASCII(pMessage));
					return 0;
				}
			}, 0);

I can’t really get this to trigger at all. Any tiny error in the parameters to any Vulkan functions just causes a complete VM crash without any output. In addition, this can’t detect any problems with the instance creation in the first place.

Have you also added VK_EXT_DEBUG_REPORT_EXTENSION_NAME to the extensions list? It seems to be working fine for me, though it’s indeed easy to crash and some errors don’t trigger any output. This also triggers the callback for me:

vkDebugReportMessageEXT(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, NULL, NULL, 0, "prefix", "message");

Yeah, calling vkDebugReportMessageEXT() does trigger an error, but I have yet to see any real errors actually occurring.

I’ve seen various reports on reddit/IRC channels saying some of the debugging functionality is broken. (annoyingly, I can’t find any right now)

Did you also add the enabled layers to the enabledLayerNames array when creating the VkInstance and the VkDevice? https://github.com/SaschaWillems/Vulkan/blob/master/base/vulkandebug.cpp#L9-L17

for VkInstance creation:

for VkDevice creation:

There aren’t any setters in VkPhysicalDeviceFeatures. Although that struct is gettable from Vulkan, it’s also settable and passed into vkCreateDevice().

I think I’m doing everything right… I’ll look into it more.

EDIT: Woohoo! I got an error!

[quote]ERROR OCCURED: Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties().
[/quote]
I am surprised as hell that it detected that but not all the other obvious errors I tried to introduce…

[quote=“theagentd,post:90,topic:56271”]
Thanks, fixed in build #31.

Here is a “simple” but complete Vulkan demo rendering a cornflower blue image on a SWT Canvas with LWJGL 3:
the demo source.
EDIT: Changed URL to: this demo now
It is the very minimal code setup to do a simple glClear() with Vulkan. :slight_smile:

Is the present semaphore actually required? What purpose does it have?

EDIT: I can’t see what I’m doing wrong, but for some reason I get an error when I try to present my images.

I get the same errors for all the images given to me by the swapchain… I think I’ve had enough of Vulkan for today. x___x Time for some Insurgency.

EDIT2: I lied. I got it working by just adding a clear to the image. Now I just need to figure out why my test program gets slower and slower the longer it runs despite not having any memory leaks…

EDIT3: Well, the “performance leak” is caused by the validation layer… Sigh.

Hi KaiHH,
I was just wondering, do you use SWT here as a replacement for GLFW? If so, what are the advantages of SWT over GLFW in your opinion? I read your project info page on github but couldn’t glean the answer to this from it. Apologies if this is a silly question.
Cheers,
Keith

I think you are right. In this special case it might not be necessary. Having read over the WSI spec multiple times, it is really hard to get to the grips of what is necessary and what not regarding synchronization/barriers. :slight_smile:
What I found out so far, maybe you can comment/correct on it:

  • vkAcquireNextImageKHR is non-blocking by nature (even if the timeout expired, there is a sentence on it in the WSI spec about that this function was changed from queue’ing to non-queueing)
  • vkAcquireNextImageKHR is non-queued, which I guess means not automatically ordered within one queue
  • vkQueuePresentKHR on the other side IS queued and ordered, but it can overlap with the next vkAcquireNextImageKHR (if of course we don’t use a “drain queue” wait with vkQueueWaitIdle)
  • also it is possible (but not at the moment with that example) to have two different queues for graphics and present operations, which would make that semaphore mandatory (unless of course like in the example a “drain queue” wait is done)
  • so, if vkAcquireNextImageKHR returns non-blocking then the image we are trying to acquire might not be available for color attach writes

So, our submit of a render pass begin should wait on the signalling of the semaphore of vkAcquireNextImageKHR.
But to be frank, I did it because everyone else is doing it. :slight_smile:

Hi Keith,
yes, SWT is more like AWT/Swing than GLFW. You surely know this but SWT is the widget toolkit on which the Eclipse IDE is based. I was just trying to show that you could actually embed Vulkan in an Eclipse RCP/Plugin application.
For example if you wanted to do a level/asset/3D editor or a CAD application based on the tooling provided by the Eclipse platform.
I will definitely port that demo to GLFW as well.

Thanks for the answer. That’s a good idea to show how it can be used in SWT. I know that nsigma uses SWT and Eclipse RCP in his wares :slight_smile:
By the way, the verbosity of Vulkan is shocking. Don’t think I’ll even try it until it’s incorporated into LibGDX or something else.

There is now also a GLFW cross-platform Vulkan clear-screen demo: https://github.com/LWJGL/lwjgl3-demos/blob/master/src/org/lwjgl/demo/vulkan/ClearScreenDemo.java

Added a simple Vulkan demo that renders a shaded triangle with a bit of animation: HelloVulkan. It’s a port of GLFW’s Vulkan test (the code style is not very pretty), with some fixes and minor readability improvements. You’ll need a fresh LWJGL build (#34) and the LunarG Vulkan SDK to run it.

That hardcoded SPIR-V shader code… Regardless, that code will be a good reference when I try to implement some actual rendering. =P

Speaking of the SDK, I found a memory leak causing some functions to cause vkQueueSubmit() to become slower and slower the longer the program runs. I’ve reported it and a fix will be included in the next release.

I did some profiling on my tiny little screen clearing program. It seems like stack allocation indeed manages to get rid of all the structs and struct buffers as they don’t show up in VisualVM when sampling. Profiling “deoptimizes” everything and causes the structs to be allocated. However, I am seeing a small amount of int[]s being allocated each frame, and it’s not me allocating those. I’m having a hard time tracking them down as they seem to be extremely short-lived and if I try to profile memory to get a stack trace of the int[] allocations they don’t show up once stack allocation has been disabled… Anything obvious generating that garbage?

If you are looking for a GLSL -> SPIR-V compiler, use https://github.com/google/shaderc .
It contains a very very nice glslc cmd tool which inputs a GLSL file and outputs a SPIR-V bytecode file.
(there is also an “online” GLSL to SPIR-V compiler, which is crap and doesn’t work and generates way too much unnecessary statements and extension references in the SPIR-V code).
I managed to build the glslc tool for Windows, I can send you a pre-built if you want.

EDIT:
Here is a minimal size, no dependencies, Windows x64 release build of glslc: https://www.dropbox.com/s/83qw8cr7jk6mv3a/glslc.exe?dl=1
(it is UPX-packed, so Virus scanners might warn you - mine did)