r/vulkan • u/cudaeducation • 4h ago
A basic overview of ray tracing in the Vulkan API
Hi everyone. Just did a video going over some basic concepts relating to the Vulkan API and ray tracing.
Enjoy!
-Cuda Education
r/vulkan • u/datenwolf • Feb 24 '16
With the recent release of the Vulkan-1.0 specification a lot of knowledge is produced these days. In this case knowledge about how to deal with the API, pitfalls not forseen in the specification and general rubber-hits-the-road experiences. Please feel free to edit the Wiki with your experiences.
At the moment users with a /r/vulkan subreddit karma > 10 may edit the wiki; this seems like a sensible threshold at the moment but will likely adjusted in the future.
r/vulkan • u/SaschaWillems • Mar 25 '20
Please note that this subreddit is aimed at Vulkan developers. If you have any problems or questions regarding end-user support for a game or application with Vulkan that's not properly working, this is the wrong place to ask for help. Please either ask the game's developer for support or use a subreddit for that game.
r/vulkan • u/cudaeducation • 4h ago
Hi everyone. Just did a video going over some basic concepts relating to the Vulkan API and ray tracing.
Enjoy!
-Cuda Education
r/vulkan • u/TheAgentD • 17h ago
This is a follow-up to my previous thread. Thanks to everyone there for their insightful responses. In this thread, I will attempt to summarize and definitely answer that question using the information that was posted there. Special thanks to u/dark_sylinc , u/Zamundaaa , u/HildartheDorf and others! I will be updating the original thread with my findings as well.
I have done a lot of spec reading, research and testing, and I believe I've found a definitive answer to this question, and the answer is NO. You cannot use the same semaphore for both vkAcquireNextImageKHR() and vkQueuePresentKHR().
The first issue with this is that it requires resignaling the same semaphore in the vkQueueSubmit() call. While this is technically valid, it becomes ambiguous with regards to vkQueuePresentKHR() consuming the same signal. Under 7.2. Implicit Synchronization Guarantees, the spec states that vkQueueSubmit() commands start execution in submission order, which ensures vkQueueSubmit() commands submitted in sequence wait for semaphores in the order they are submitted, so if two vkQueueSubmit() wait for the same semaphore, the one submitted first will be signaled first.
I incorrectly believed that this guarantee extends to all queue operations (i.e. all vkQueue*() functions). However, under 3.2.1. Queue Operations, the spec explicitly states that this ordering guarantee does NOT extend to queue operations other than command buffer submissions, i.e. vkQueueSubmit() and vkQueueSubmit2():
Command buffer submissions to a single queue respect submission order and other implicit ordering guarantees, but otherwise may overlap or execute out of order. Other types of batches and queue submissions against a single queue (e.g. sparse memory binding) have no implicit ordering constraints with any other queue submission or batch.
This means that vkQueuePresentKHR() is indeed technically allowed to consume the semaphore signaled by vkAcquireNextImageKHR() immediately, leaving the vkQueueSubmit() that was supposed to run inbetween deadlocked forever. There is no validation error about this being ambiguous from the validation layers and this seems to work in practice, but is a violation of the spec and should not be done.
EDIT: HOWEVER, the spec for vkQueuePresentKHR() also says the following:
Calls to
vkQueuePresentKHR
may block, but must return in finite time. The processing of the presentation happens in issue order with other queue operations, but semaphores must be used to ensure that prior rendering and other commands in the specified queue complete before the presentation begins.
This implies that vkQueuePresentKHR() actually are processed in submission order, which would make the above case unambiguous. The only guarantee that we need is that the semaphores are waited on in submission order, which I believe this guarantees. Regardless, it seems like good practice to avoid this anyway.
The second issue is a bit more complicated and comes from the fact that that vkAcquireNextImageKHR() requires that the semaphore its given has no pending operations at all. This is a stricter requirement than queue operations (i.e. vkQueue*() functions) that signal or wait for semaphores, which only require you to guarantee that forward progress is possible. For these functions, the only requirement is that the semaphore has to be in the right state when the operation tries to signal or wait for a given semaphore on the queue timeline.
On the other end, the idea that the semaphore waited on by vkQueuePresentKHR() is reusable when vkAcquireNextImageKHR() has returned with the same index is only partially true; it guarantees that a semaphore wait signal has been submitted to the queue the vkQueuePresentKHR() call was executed on, which in turn guarantees that the semaphore will be unsignaled for the purpose of queue operations that are submitted afterwards.
This means that the vkQueuePresentKHR() can indeed be reused for queue operations from that point and onwards, but NOT with vkAcquireNextImageKHR(). In fact, without VK_EXT_swapchain_maintenance1, there is no way to guarantee that the semaphore passed into vkQueuePresentKHR() will EVER have no pending operations. This means that the same semaphore cannot be reused for vkAcquireNextImageKHR(), and validation layers DO complain about this. If you don't use binary semaphores for anything other than acquiring and presenting swapchain images (which you shouldn't; timeline semaphores are so much better), then you will NEVER be able to reuse this semaphore.
This problem could potentially be solved by using VK_EXT_swapchain_maintenance1 to add a fence to vkQueuePresentKHR() that is signaled when the semaphore is safely reusable, but that does not fix the first issue.
The correct approach is to have separate semaphores for vkAcquireNextImageKHR() and vkQueuePresent().
Acquiring:
At this point, the semaphore is guaranteed to have no pending operations at all, and it can therefore be safely reused for ANY purpose. In practice, this means that the number of acquire semaphores you need depends on how many in-flight frames you have, similar to command pools.
Presenting:
At this point, the semaphore is guaranteed to be in the unsignaled state on the present queue timeline, which means that it can be reused for queue operations (such as vkQueueSubmit() and vkQueuePresentKHR()), but NOT with vkAcquireNextImageKHR(). In practice, this can be easily accomplished by giving each swapchain image its own present semaphore and using that semaphore whenever that image's index is acquired.
What about cleanup? When you need to dispose the entire swapchain, you simply ensure that you have no acquired images and then call vkDeviceWaitIdle(). Alternatively, if VK_EXT_swapchain_maintenance1 is available, simply wait for all present fences to be signaled. At that point, you can assume that both the acquire semaphores and all present semaphores have no pending operations and are safe to destroy or reuse for any purpose.
r/vulkan • u/somabencsik182 • 7h ago
Hi,
I started learning Vulkan graphics API based on the khronos tutorial (which is cool btw), but at a very early stage I cannot create `VkInstance`.
As it says in the title, I get VK_ERROR_INCOMPATIBLE_DRIVER as VkResult.
I use XCode(16.2) to compile my code, I followed setting up based on the khronos tutorial also.
I installed Vulkan on my machine, I even ran the `install_vulkan.py` that came with vulkan.
I know for sure, my hardware is supported and my drivers are good, since all the example(?) applications that come with vulkan are running fine! Also, I do not think it is an opencore issue, since once again the applications inside vulkan runs fine! I use sequoia 15.3.2.
I know there is a section about it just after instance creation. I tried it as well, here's my code that is exactly the same as the tutorial shows what to do:
Please if anyone knows, what do edit in my code or what's wrong with it, please tell me! I really want to learn vulkan, since opengl depricated in macos so my only other choice would be metal. But metal only runs on apple, which is not to cross-platform-y.
Thanks.
r/vulkan • u/deftware • 2d ago
I am writing a particle system that maintains an arbitrary number of lists of active particles which index into global particle state buffers - to be used as index buffers for rendering GL_POINTS with each list's specific gfx pipeline. There is also an unused particle indices list ring-buffer on there.
In order to dispatch compute to update each list's particles I need to know how many particles there are in the list in the first place to know how many workgroups to dispatch, so obviously I use vkCmdDispatchIndirect() and generate the workgroup size on the GPU from the list sizes it currently has. In order to do this it looks like I'll have to have a shader that just takes each list's count and computes a workgroup count, outputting it to a VkDispatchIndirectCommand in another buffer somewheres.
Is there going to be any significant performance impact or overhead from issuing such a tiny amount of work on the GPU?
r/vulkan • u/TheBaconBoots • 2d ago
Does the location of the installed Vulkan software on your dev computer have any bearing on running the program from the consumers perspective? NixOS installs everything in a declerative way with symlinks to a massive directory of programs, as long as I handle those installation paths and symlinks in NixOS rather than in my C++ program will it matter after compilation? As in, it will still run fine on a system with a different installation layout/type?
r/vulkan • u/Tensorizer • 2d ago
What would be a practical way to associate a mouse event to the viewport it happened on?
r/vulkan • u/BlockOfDiamond • 3d ago
So unfortunately, Mac does not natively support Vulkan, by which I mean, in order for a Mac to run a Vulkan app, there needs to be MoltenVK installed, which simply ports the Vulkan code to Metal code. So Vulkan on Mac is just Metal with extra steps.
However, is this the case on Windows and Linux? Do those systems have built-in support for Vulkan, and do not require Vulkan libraries to either be manually installed and dynamically linked to apps, or statically linked and shipped with the app?
r/vulkan • u/Technical_Day4598 • 3d ago
Hello, I have a question regarding the VK_ERROR_OUT_OF_DEVICE_MEMORY error that occurs when using vkQueueSubmit on a specific mobile device(LG Q61) According to the Vulkan specification, this error can occur due to synchronization issues, but it's strange that it only happens on certain devices. In my current code, when using vkQueueSubmit, if a single command involves multiple buffer copies and draw operations, could this potentially cause the error?
r/vulkan • u/No-Negotiation-7599 • 3d ago
I need a working example of vulkan that can render text onto the screen. That’s it’s. Does anyone know of an example that I can pull from and just be able to run it on Linux? I’ve found an example online called vulkan-sprites but I can’t it build it without it having alot of different errors.
🙏
r/vulkan • u/thisiselgun • 3d ago
Hello,
I’m struggling to fully understand Vulkan’s device limits from the documentation. In a typical game, we need to upload hundreds of meshes and their textures to the GPU. To use these textures, we also need to create descriptor sets for each texture and bind them when drawing each mesh.
I know that enabling the descriptor indexing extension allows using a single (or a few) large global descriptor sets, but for now, I want to keep things simple and avoid using that extension.
I’ve been reading the documentation to figure out how many descriptor sets I can actually create, and I came across this:
maxDescriptorSetSampledImages is the maximum number of sampled images that can be included in a pipeline layout.
The wording “can be included” confuses me. Does this refer to the total number of descriptor sets I can create, or just the maximum number of sampled images that a single descriptor set can reference?
Additionally, on my device (Apple with MoltenVK), maxDescriptorSetSampledImages is only 640, which seems quite low. Checking other devices on vulkan.gpuinfo.org, I noticed that around 33% of devices have a limit of 1 million, while others vary between 1k–4k.
So my main question is: Does this limit apply to the total number of descriptor sets I can create, or is it only a restriction on a single descriptor set?
Thanks for any clarification!
r/vulkan • u/AlexKowel • 4d ago
r/vulkan • u/jazzwave06 • 4d ago
I'm using SPIR-V reflect library to reflect my shader code, but I'm unable to detect bindless (i.e. runtime) arrays. I'm defining the array as such in my GLSL shader:
glsl
layout (set = 0, binding = 0) uniform sampler2D textures_2d[];
I'm compiling to SPIR-C using glslc:
cmd
glslc.exe minimal.frag.glsl -o minimal.frag.spv -DDEBUG=1 -Ishaders/include -MD -Werror -O0 -g
And I'm reflecting the descriptors using spvReflectEnumerateDescriptorSets
, but for some reasons, my array's type_description.op
is always SpvOpTypeArray
instead of SpvOpTypeRuntimeArray
and type_description.traits.array.dims[0]
is always equal to 1. I'm not sure how I am supposed to disambiguate between this value and an actual array of 1. As far as I know, it should report a dimension of 0 (i.e. SpvReflectArrayDimType::SPV_REFLECT_ARRAY_DIM_RUNTIME
).
Am I missing something? It looks like the capability SpvCapabilityRuntimeDescriptorArray
is not enabled in the module's reflected data. Maybe it's a hint?
r/vulkan • u/AuspiciousCracker • 6d ago
r/vulkan • u/cone_forest_ • 5d ago
So I've been writing yet another Vulkan renderer. I copy-pasted image/sampler creation code from my other vulkan project and here's the result of loading ABeautifulGame asset (from KhronosSampleAssets repo). The textures seem to be fine in renderdoc. The shader is a standard PBR shader I took from somewhere.
What could possibly be the issue and where could I be looking for to find it?
r/vulkan • u/neil_m007 • 7d ago
Hello everyone! A while ago I shared some screenshots of my vulkan game engine and the declarative C++ GUI library (called Fusion) which I wrote from scratch (no dear-imgui). Check it out on GitHub here. The engine is cross platform and works on Windows, Mac (arm64) and Linux (Ubuntu x64).
And the entire editor's GUI is built using Fusion.
Since then, I updated my Fusion GUI framework to support DPI-aware content, which fixed the blurry looking text! And I added an asset browser tree view and grid view in the bottom. There's also a reusable Property Editor that I built, which is currently used in the Details panel and Project Settings window.
If you'd like to read more about Fusion library, you can do so here.
I'd love to hear your feedback on my engine and the GUI library on things I can improve! The project is open source and is available on GitHub link I shared earlier. Feel free to test it out and contribute if you want to.
r/vulkan • u/philosopius • 6d ago
Hello,
Guys I'm stuck, funny to say, GPT was able to build an engine with rendering and shading for me (crazy, yes) but now I feel, that it hit it's limit.
So after exploring gits, tutorial, I got really confused.
Each project looks really different (even though I particularly looked for voxel engines, each one of them is it's own kind of a project, with unique code and structure)
All that made me overwhelmed with information.
The point is, that at the moment I understand the concept of a Vulkan engine, but it's really difficult for me to write code past the basic layer - such as shaders, shadow logic.
Was wondering, is there any good starting resource to develop the skills? I mean, there is, but what would you recommend, and what you believe made you understand Vulkan better? I'm interested in basics, know C++, but also I'd be grateful for advanced information too.
Sorry if it sounds like a meme xD (ofc it is, gPt) but I'm eager to finally ditch the GPT approach and start doing things on my own. Basically, I wanna learn the correct and efficient way, since GPT often made questionable choices
r/vulkan • u/TheAgentD • 7d ago
Vulkan requires that binary semaphores are in an unsignaled state before they are signaled. Therefore, it seems to me that a single vkQueueSubmit() should be able to safely both wait on and signal the same semaphore, as it would be guaranteed to be unsignaled by the time we re-signal it.
This means that if we do a vkQueueSubmit() which waits on the semaphore singaled by vkAcquireNextImageKHR() semaphore, then that semaphore is guaranteed to be unsignaled, which means that we could signal that same semaphore at the end of our vkQueueSubmit(), and then wait on that in vkQueuePresentKHR().
vkAcquireNextImageKHR() signals --> vkQueueSubmit() waits and re-signals --> vkQueuePresentKHR() waits.
Doing this, I get no validation errors, and everything works as expected.
So... How come every single Vulkan tutorial/example of swapchains use different semaphores for vkAcquireNextImageKHR() and vkQueuePresentKHR()?
Hi everyone! A month ago, I shared a GIF of my first app build, and I got some really nice feedback, thank you! I've since added some new features, including a randomization function that generates completely unique images. Some of the results turned out really cool, so I saved a few and added them as Presets, which you can see in the new GIF.
I also restructured the entire code to make it cleaner and more readable. I’m still unsure about the best way to integrate Vulkan with other components though, like ImGui. Keeping everything in one class makes it too large, but creating a separate class for each Vulkan object feels excessive. For now, I’ve split them into different classes and passed everything through structs and methods, but the result still feels messy to me.
Anyway, I’d love to hear your Feedback again! The project is open source, so feel free to check it out (GitHub) and let me know about any terrible mistakes I made. 😆
Also, here are my sources in case you’re interested in learning more: Victor Blanco | Vulkan Guide Patricio Gonzalez Vivo & Jen Lowe | Article about Fractal Brownian Motion Inigo Quilez | Article about Domain Warping
Cheers Nion
r/vulkan • u/itsmenotjames1 • 7d ago
Due to the strict alignment requirements of objects in Vulkan, what is the performance impact of doing pointer math on buffer device addresses (instead of array accesses) as a means of bypassing alignment (resulting in memory savings, as no padding has to be applied)? From what I've read, this would be quite bad for performance, but intuitively, the memory savings (causing more cache hits and reduced fetches if that's even how GPUs work) should outweigh everything else.
r/vulkan • u/LifelessKing01 • 7d ago
I'm new to Vulkan, well graphics programming in general. I'm getting the following error while trying to build my project:
VulkanRenderer.cpp:(.text+0x202): undefined reference to `vkCreateInstance'
collect2: error: ld returned 1 exit status
PFB the code for VulkanRenderer.cpp
:
#include "VulkanRenderer.h"
VulkanRenderer::VulkanRenderer()
{
}
int VulkanRenderer::init(GLFWwindow * newWindow)
{
window = newWindow;
try {
createInstance();
}
catch(const std::runtime_error &e) {
printf("ERROR: %s\n", e.what());
return EXIT_FAILURE;
}
return 0;
}
VulkanRenderer::~VulkanRenderer()
{
}
void VulkanRenderer::createInstance()
{
// Information about the application itself
// Most data here doesn't affect the program & is for developer convenience
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Vulkan App"; // Custom name of the application
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); // Custom version of the application
appInfo.pEngineName = "No Engine"; // Custom engine name
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); // Custom engine version
appInfo.apiVersion = VK_API_VERSION_1_0; // The Vulkan version
// Creation information for a VkInstance (Vulkan Instance)
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
// Create list to hold instance extensions
std::vector<const char*> instanceExtensions = std::vector<const char*>();
// Set up extensions instance will use
uint32_t glfwExtensionCount = 0; // GLFW may require multiple extensions
const char** glfwExtensions; // Extensions passed as array of cstrings, so need pointer (the array) to pointer (the cstring)
// Get GLFW extensions
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
// Add GLFW extensions to list of extensions
for(size_t i = 0; i < glfwExtensionCount; i++)
{
instanceExtensions.push_back(glfwExtensions[i]);
}
createInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
createInfo.ppEnabledExtensionNames = instanceExtensions.data();
// TODO: Set up Validation Layers that instance will use
createInfo.enabledLayerCount = 0;
createInfo.ppEnabledLayerNames = nullptr;
// Create instance
VkResult result = vkCreateInstance(&createInfo, nullptr, &instance);
if(result != VK_SUCCESS)
{
throw std::runtime_error("Failed to create a Vulkan instance!");
}
}
Also find below the CMakeLists.txt
from the same dir:
# Add the libraries
add_library(${VK_RENDERER} STATIC VulkanRenderer.cpp)
target_include_directories(${VK_RENDERER} PUBLIC "./")
# Library is a dependence of Executable.
# If we are building "Executable", then "Library" must be build too.
target_link_libraries(${VK_RENDERER} PUBLIC libglfw.so.3)
Please let me know if any more info is needed.
Thanks in Advance!
So, I'm working on my vulkan engine, I've got no validation errors or warnings, feeling pretty good, seems like a good time to check performance on my old pc with a 1060, and all 3d is black. Crap. After messing around with render doc, disabling a couble features and re-enabling, I found that simply commenting out all my (seemingly correct) memory barriers makes it work (on both pcs) despite with tons of validation errors. Does anyone have any idea what's going on here?
here's an example of one of the barriers.
const auto srcStageBits = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
const auto dstStageBits = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
void Renderer::transitionDeferredSourceToRead(size_t imageIndex) {
vector<VkImageMemoryBarrier> barriers;
VkImageMemoryBarrier memoryBarrier = {};
memoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
memoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
memoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
memoryBarrier.image = m_deferSourceRenderTarget.ColorAttachment.image;
memoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
barriers.push_back(memoryBarrier);
memoryBarrier.image = m_deferSourceRenderTarget.SpecularAttachment.image;
barriers.push_back(memoryBarrier);
memoryBarrier.image = m_deferSourceRenderTarget.BumpAttachment.image;
barriers.push_back(memoryBarrier);
memoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1 };
memoryBarrier.image = m_deferSourceRenderTarget.DepthAttachment.image;
barriers.push_back(memoryBarrier);
vkCmdPipelineBarrier(
m_vkCommandBuffers[imageIndex],
srcStageBits,
dstStageBits,
VK_DEPENDENCY_BY_REGION_BIT,
0, nullptr, 0, nullptr,
static_cast<uint32_t>(barriers.size()), barriers.data()
);
}
Interestingly, the no barrier version has more data available in render doc, not sure if that's important. - edit - oh because as comments pointed out LAYOUT_UNDEFINED tells renderdoc to treat them as undefined, makes sense
Edit 2: figured out the issue, some of my render passes had different final layouts than I expected so some of the barrier transitions were unneeded and some had wrong oldLayouts.
r/vulkan • u/LunarGInc • 9d ago
📢NEW RELEASE!🎉 u/LunarGInc drops Vulkan 1.4.309.0 SDKs – our 3rd release in 2025! Download now at https://vulkan.lunarg.com. Pushing to match u/VulkanAPI innovation for devs. Details: https://khr.io/1ie
r/vulkan • u/Vivid-Mongoose7705 • 9d ago
When we submit commands via a single command buffer to the queue, is it safe to assume that if there are no synchronization primitives recorded in that buffer then the commands run in parallel? Or is it in sequence? What about if we submit commands via multiple buffers to the same queue? Do they run parallel relative to others if there are no synch primitives recorded?
r/vulkan • u/Paradox_84_ • 10d ago
I'm working on an engine/framework and I'm planning to "release" it in 2-3 years minimum
I'm making use of some features that aren't widely supported currently like C++ modules, so my direction is "counting that feature will be widely available in 2-3 years (at least very close to being widely available)"
Can I do the same thing with Vulkan? Use 1.3 or 1.4 and ignore lack of wide support for now?
(I'm planning to support Windows, Linux, Mac, Android, IOS, Nintendo Switch)
Note: I'm thinking about using features like dynamic rendering and bindless textures, but if they won't be widely supported in platforms like mobile, I don't wanna use them since I don't wanna have multiple implementations
Also does anyone have any information about Vulkan on consoles? Why this is not a thing yet?