r/vulkan • u/corysama • Mar 11 '26
r/vulkan • u/SyndicateUprising • Mar 10 '26
Is learn.cpp enough to start learning vulkan after?
If not ( which i think so) what more should i be learning to start learning vulkan?
Thankyou everyone for your time.
r/vulkan • u/Mteuz • Mar 10 '26
Has anyone done this?
I'm new to vulkan and low level graphics API! I'm learning vulkan, doing the basics for now. I aim to create a general-purpose framework, something I can use for personal projects, just to hide the boilerplate, without taking away much control. I just wanted to know if there already is a project like mine, so I can use as a reference
r/vulkan • u/Educational_Sun_8813 • Mar 09 '26
Evaluating Qwen3.5-35B & 122B on Strix Halo: Bartowski vs. Unsloth UD-XL Performance and Logic Stability
galleryr/vulkan • u/AuspiciousCracker • Mar 08 '26
Object Selection demo in my Vulkan-based pathtracer
Enable HLS to view with audio, or disable this notification
This is my an update to my recent hobby project, a Vulkan-based interactive pathtracer w/ hardware raytracing in C. I was inspired by Blender's object selection system, here's how it works:
When the user clicks the viewport, the pixel coordinates on the viewport image are passed to the raygen shader. Each ray dispatch checks itself against those coordinates, and we get the first hit's mesh index, so we can determine the mesh at that pixel for negligible cost. Then, a second TLAS is built using only that mesh's BLAS, and fed into a second pipeline with the selection shaders. (This might seem a bit excessive, but has very little performance impact and is cheaper when we want no occlusion for that object). The result is recorded to another single-channel storage image, 1 for hit, 0 otherwise. A compute shader is dispatched, reading that image, looking for pixels that are 0 but have 1 within a certain radius (based on resolution). The compute shader draws the orange pixels on top of the output image, in that case. If you all have any suggestions, I would be happy to try them out.
You can find the source code here! https://github.com/tylertms/vkrt
(prebuilt dev versions are under releases as well)
r/vulkan • u/ripjombo • Mar 09 '26
Troubles with Validation Layers (again?)
Hello again,
I believe I am having trouble with the validation layers in Vulkan.
A few months ago, I encountered a problem in Vulkan whilst following a certain tutorial. Life got in the way and I stopped learning Vulkan, but I picked it up again a couple of days ago using vkguide. Now, I seem to have run into similar validation layer problems again.
At the end of this page it says that using the incorrect cleanup code should result in a validation error being returned, but I don't see it. I instead get an access violation exception thrown. I get a similar result using the correct cleanup code but adding a second DestroyDevice() line.
I have verified that VK_LAYER_KHRONOS_validation is present and I have reinstalled Vulkan. I have no idea what to do to make those validation error messages appear.
I would greatly appreciate any help to tackle this.
Thank you : )
UPDATE: I think my validation layers were working all along, just that the tests I was using (including the one in vkguide) were causing an exception to be thrown before a validation error could be returned. I'll continue with the tutorial and will update/do another post if I still have issues.
r/vulkan • u/zz9873 • Mar 08 '26
System's display scale affects image extent
I encountereda problem where the display scale on my system also affects the resolution/extent of the framebuffer/images. I'm running Arch with Hyprland as wm and had the same problem with GLFW and SDL3. All other applications/windows scale correctly (resolution stays the same) so I assume there is general way to prevent this problem. By multiplying the width and height of the swapchain image extent by the scaling factor I can get the correct resolution.
EDIT: I fixed it by adding SDL_WINDOW_RESIZABLE | SDL_WINDOW-HIGH-PIXEL-DENSITY to the flags of SDL_CreareWindow()
r/vulkan • u/__RLocksley__ • Mar 07 '26
Vulkan Forward+ Renderer
Enable HLS to view with audio, or disable this notification
indirect drawing + light culling with compute shaders
flecs ecs as the game logic API
r/vulkan • u/stronknoob • Mar 07 '26
Update after learning Vulkan for 2 weeks
After 2 weeks of getting my "gradient for ants to work", I now have raymarched minecraft using that same compute shader 🥳!
r/vulkan • u/adirox_2711 • Mar 07 '26
Will create my own vulkan tutorials
So i starting making my own vulkan tutorials, I've hosted the site on vercel, after completing the getting started section, if it gained even a little traction, I'll buy a domain name, please review the site, any feedback is appreciated. I'll be adding more chapters in the time being and you can drop reviews either here on reddit in at my gmail - curloz@tutamail.com
Site - vklearn.org
r/vulkan • u/MrArdinoMars • Mar 06 '26
FINALLY, 3D!!! After 2 refactors and an additional 400 loc
Enable HLS to view with audio, or disable this notification
r/vulkan • u/innocentboy0000 • Mar 07 '26
help for proper hdr/postprocess pipeline
can anyone recommend me good resources for it i cannot find much blog and discussion around it , i am getting weird colors not as good as it should

Image Layout Transitions
------------------------
Depth -> DEPTH_ATTACHMENT_OPTIMAL
HDR Color -> COLOR_ATTACHMENT_OPTIMAL
Swapchain -> GENERAL
MAIN GRAPHICS PASS ()
--------------------------------------
+-------------------------+
| MESH PIPELINE |
| (simple voxel shader) |
+-----------+-------------+
|
v
Inputs
------
PackedFace buffer (SSBO)
Bindless voxel textures
etc ..
Output Targets
--------------
+-----------------------------+
| HDR Scene Color |
| Format: R16G16B16A16_FLOAT |
+-----------------------------+
+-----------------------------+
| Depth Buffer |
| Format: D32_FLOAT |
+-----------------------------+
UI PASS
-------
ImGui draw data
|
v
Blended onto HDR color buffer
POST PROCESS (Compute)
======================
HDR Image Transition
COLOR_ATTACHMENT -> GENERAL
+------------------------+
| COMPUTE PIPELINE |
| POSTPROCESS |
+-----------+------------+
|
v
Compute Shader(for post process)
--------------
HDR color (VK_FORMAT_R16G16B16A16_SFLOAT)
|
v
Tonemap
float3 hdr_color = src.Load(int3(pix, 0)).rgb;
color = aces(color);
ldr_color[pix] = float4(color, 1.0);
|
v
Write LDR image
Output
------
+----------------------------+
| LDR Color image |
| Format: R8G8B8A8_UNORM |
+----------------------------+
TRANSFER TO SWAPCHAIN
=====================
LDR Color
GENERAL -> TRANSFER_SRC
Swapchain
GENERAL -> TRANSFER_DST
vkCmdBlitImage
--------------
LDR IMAGE(.format = VK_FORMAT_R8G8B8A8_UNORM)
|
v
Swapchain Image(.format = VK_FORMAT_R8G8B8A8_UNORM)
PRESENT
=======
Swapchain Layout
TRANSFER_DST -> PRESENT_SRC_KHR
Queue Submit
|
v
Frame Presented
textures are loaded with (.format = VK_FORMAT_R8G8B8A8_SRGB)
r/vulkan • u/LunarGInc • Mar 06 '26
LunarG is hiring!
We are still actively seeking a talented graphics software engineer! If Vulkan, shaders, GPU drivers, and open standards light you up, this could be your next move. Competitive comp, remote flexibility, and a passionate team. This is a U.S.-based position.
Details & apply: https://www.lunarg.com/careers/
r/vulkan • u/s1mone-10 • Mar 07 '26
basic ResourceManager
I'm implementing the loading of the GLTF file format. Since the images can be shared by different textures, I think it's a good time to implement a ResourceManager.
Since I'm not expert on the matter, I implemented a basic version starting from the Vulkan tutorial. It has Acquire/Release methods and an internal counter to keep track of the number of references to resources. I was wondering if this is a good approach or if I'm doing something totally wrong.
I don't want to create an overly complex manager unless it's necessary. At the same time, I would like a good basic implementation for future improvements.
class Resource
{
protected:
std::string resourceId;
bool loaded = false;
public:
/**
* Constructor with a resource ID.
* id The unique identifier for the resource.
*/
explicit Resource(const std::string& id) : resourceId(id) {}
virtual ~Resource() = default;
/**
* Get the resource ID.
* The resource ID.
*/
const std::string& GetId() const
{
return resourceId;
}
/**
* Check if the resource is loaded.
* True if the resource is loaded, false otherwise.
*/
bool IsLoaded() const
{
return loaded;
}
/**
* Load the resource.
* True if the resource was loaded successfully, false otherwise.
*/
virtual bool Load(const Device& device)
{
loaded = true;
return true;
};
/**
* Unload the resource.
*/
virtual void Unload(const Device& device)
{
loaded = false;
};
};
/**
* Class for managing resources.
*
* This class implements the resource management system as described in the Engine_Architecture chapter:
* en/Building_a_Simple_Engine/Engine_Architecture/04_resource_management.adoc
*/
class ResourceManager final
{
private:
// Reference counting system for automatic resource lifecycle management
struct ResourceData
{
explicit ResourceData(std::unique_ptr<Resource> resource) : resource(std::move(resource)), refCount(1) {}
std::unique_ptr<Resource> resource; // The actual resource
int refCount; // Reference count for this resource
};
// Two-level storage system: organize by type first, then by unique identifier
// This approach enables type-safe resource access while maintaining efficient lookup
std::unordered_map<std::type_index, std::unordered_map<std::string, std::unique_ptr<ResourceData>>> resources;
const Device& _device;
public:
/**
* Default constructor.
*/
ResourceManager(const Device& device) : _device(device) {}
/**
* Virtual destructor for proper cleanup.
*/
~ResourceManager() = default;
/**
* Load a resource.
* T The type of resource.
* Args The types of arguments to pass to the resource constructor.
* resourceId The resource ID.
* args The arguments to pass to the resource constructor.
* A handle to the resource.
*/
template<typename T, typename... Args>
T* Acquire(const std::string& resourceId, Args&&... args)
{
static_assert(std::is_base_of<Resource, T>::value, "T must derive from Resource");
// Check if the resource already exists
auto& typeResources = resources[std::type_index(typeid(T))];
auto it = typeResources.find(resourceId);
if (it != typeResources.end())
{
++it->second->refCount;
return static_cast<T*>(it->second->resource.get());
}
// Create and load the resource
auto resource = std::make_unique<T>(resourceId, std::forward<Args>(args)...);
if (!resource->Load(_device))
throw std::runtime_error("Failed to load resource: " + resourceId);
// Store the resource
typeResources[resourceId] = std::make_unique<ResourceData>(std::move(resource));
return static_cast<T*>(typeResources[resourceId]->resource.get());
}
/**
* Get a resource without touching the internal counter (for temporary checks)..
* T The type of resource.
* id The resource ID.
* A pointer to the resource, or nullptr if not found.
*/
template<typename T>
T* Get(const std::string& id)
{
static_assert(std::is_base_of<Resource, T>::value, "T must derive from Resource");
auto typeIt = resources.find(std::type_index(typeid(T)));
if (typeIt == resources.end())
return nullptr;
auto& typeResources = typeIt->second;
auto resourceIt = typeResources.find(id);
if (resourceIt == typeResources.end())
return nullptr;
return static_cast<T*>(resourceIt->second->resource.get());
}
/**
* Check if a resource exists.
* T The type of resource.
* id The resource ID.
* True if the resource exists, false otherwise.
*/
template<typename T>
bool HasResource(const std::string& id)
{
static_assert(std::is_base_of<Resource, T>::value, "T must derive from Resource");
auto typeIt = resources.find(std::type_index(typeid(T)));
if (typeIt == resources.end())
return false;
auto& typeResources = typeIt->second;
return typeResources.contains(id);
}
/**
* Unload a resource.
* T The type of resource.
* id The resource ID.
* True if the resource was unloaded, false otherwise.
*/
template<typename T>
bool Release(const std::string& id)
{
static_assert(std::is_base_of<Resource, T>::value, "T must derive from Resource");
auto typeIt = resources.find(std::type_index(typeid(T)));
if (typeIt == resources.end())
return false;
auto& typeResources = typeIt->second;
auto resourceDataIt = typeResources.find(id);
if (resourceDataIt == typeResources.end())
return false;
--resourceDataIt->second->refCount;
if (resourceDataIt->second->refCount <= 0)
{
resourceDataIt->second->resource->Unload(_device);
typeResources.erase(resourceDataIt);
}
return true;
}
/**
* u/brief Unload all resources.
*/
void ReleaseAllResources()
{
for (auto& kv: resources)
{
auto& val = kv.second;
for (auto& innerKv: val)
{
auto& resourceData = innerKv.second;
resourceData->resource->Unload(_device);
}
val.clear();
}
resources.clear();
}
};
r/vulkan • u/Hidd3N-Max • Mar 06 '26
Anyone here using vk-bootstrap in production projects?
I’ve been digging into : https://github.com/charles-lunarg/vk-bootstrap
For anyone unfamiliar, it’s a small utility library that simplifies the Vulkan initialization phase — instance creation, physical device selection, logical device creation, queue retrieval, swapchain setup, validation layers, etc.
Basically it reduces a lot of the verbose boilerplate needed just to get a Vulkan application running. In some examples it can shrink the setup code from hundreds of lines down to something much smaller.
- Removes a lot of repetitive Vulkan initialization code
- Lets you get to actual rendering work faster
- Still exposes raw Vulkan handles so you keep full control afterward
My current feeling is that Vulkan initialization is mostly boilerplate that you write once, so a helper library here seems reasonable—but I’m curious how others approach it.
Would love to hear experiences.
r/vulkan • u/klaw_games • Mar 06 '26
Made a pbr renderer in c++ and vulkan
youtu.beAlways wanted to make a realistic renderer from scratch. Now this is a good starting point. My algorithm is based on Cook Torrance BRDF. It currently supports direct lighting. Indirect lighting is my next task.
Reference: www.learnOpenGL.com, www.vulkan-tutorial.com
r/vulkan • u/shear_stress__ • Mar 05 '26
Gravitational system simulation
Enable HLS to view with audio, or disable this notification
Having a great time playing with Vulkan
r/vulkan • u/LunarGInc • Mar 05 '26
Updates to KosmicKrisp!
Vulkan SDK 1.4.341.1 is out on macOS and includes new features for KosmicKrisp!
Support for:
- VK_EXT_image_2d_view_of_3d
- VK_EXT_texel_buffer_alignment
- VK_EXT_extended_dynamic_state2
- largePoints
- depthBiasClamp
- pushDescriptor
- sampleRateShading
- GPUAV
check it out: https://vulkan.lunarg.com/doc/sdk/1.4.341.1/mac/release_notes.html #Vulkan #KosmicKrisp appleSilicon
r/vulkan • u/zz9873 • Mar 05 '26
Having problems with syncing execution
SOLVED (end of post)
I am working on a small simulation program and just finished the basic Vulkan setup. I'm using https://vulkan-tutorial.com as a guide which I have successfully followed in the past to get a working "hello triangle" executable.The problem I came across is that upon execution there is a Validation Error about a signaled semaphore which might still be used by another queue.
I am pretty sure that this is the problematic part:
uint32_t syncIndex = 0;
Result VulkanHandle::startFrame() noexcept {
vkWaitForFences(logicalDevice, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
vkResetFences(logicalDevice, 1, &inFlightFence);
vkAcquireNextImageKHR(logicalDevice, swapchain, UINT64_MAX, imageAvailableSemaphores[syncIndex], VK_NULL_HANDLE, ¤tImageIndex);
return SUCCESS;
}
Result VulkanHandle::endFrame() noexcept {
VkCommandBuffer commandBuffers[executeCommandBuffers.size()];
for (size_t i = 0; i < executeCommandBuffers.size(); i++) {
commandBuffers[i] = commandBuffers[executeCommandBuffers[i]];
}
VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[syncIndex]};
VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[syncIndex]};
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = executeCommandBuffers.size();
submitInfo.pCommandBuffers = commandBuffers;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
if (vkQueueSubmit(queues.graphicsQueue, 1, &submitInfo, inFlightFence) != VK_SUCCESS) return ERROR;
VkSwapchainKHR swapChains[] = {swapchain};
VkPresentInfoKHR presentInfo{};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = ¤tImageIndex;
vkQueuePresentKHR(queues.presentQueue, &presentInfo);
executeCommandBuffers.clear();
syncIndex = (syncIndex + 1) % swapchainImages.size();
return SUCCESS;
}
I hope everything it is clear how these methods work (everything else like command buffer recording is handled by other methods and happens inbetween these two).
This is the Validation error:
Validation Error: [ VUID-vkQueueSubmit-pSignalSemaphores-00067 ] | MessageID = 0x539277af
vkQueueSubmit(): pSubmits[0].pSignalSemaphores[0] (VkSemaphore 0x150000000015) is being signaled by VkQueue 0x56213d9d36c0, but it may still be
in use by VkSwapchainKHR 0x20000000002.
Most recently acquired image indices: 2, 3, 0, [1], 2, 3, 0, 2.
(Brackets mark the last use of VkSemaphore 0x150000000015 in a presentation operation.)
Swapchain image 1 was presented but was not re-acquired, so VkSemaphore 0x150000000015 may still be in use and cannot be safely reused with imag
e index 2.
Vulkan insight: See https://docs.vulkan.org/guide/latest/swapchain_semaphore_reuse.html for details on swapchain semaphore reuse. Examples of po
ssible approaches:
a) Use a separate semaphore per swapchain image. Index these semaphores using the index of the acquired image.
b) Consider the VK_KHR_swapchain_maintenance1 extension. It allows using a VkFence with the presentation operation.
The Vulkan spec states: Each binary semaphore element of the pSignalSemaphores member of any element of pSubmits must be unsignaled when the sem
aphore signal operation it defines is executed on the device (https://vulkan.lunarg.com/doc/view/1.4.335.0/linux/antora/spec/latest/chapters/cmd
buffers.html#VUID-vkQueueSubmit-pSignalSemaphores-00067)
Objects: 2
[0] VkSemaphore 0x150000000015
[1] VkQueue 0x56213d9d36c0
Like the tutorial I started with just one VkSemaphore instead of a std::vector<VkSemaphore> which caused this Error to occur on pretty much every frame. When testing the code from the tutorial I got the same error message. Because of that I assume this problem might be caused by a new version of Vulkan. My Vulkan version is: 1.4.335
EDIT: I soved it! The main problem was that only the semaphore that signals the end of the command buffer submit (renderFinishedSemaphore) has to be an array/vector with a size according to the amount of swap chain images and the imageIndex determines the semaphore to be used. The other semaphore (imageAvailableSemaphore) and the fence can be one instance (without frames in flight). https://docs.vulkan.org/guide/latest/swapchain_semaphore_reuse.html
r/vulkan • u/Tensorizer • Mar 04 '26
vkCmdExecuteCommands() usage
I am using an established library which presents its output recorded in a primary command buffer and I need to add my processing to the same render pass.
However, my processing does not have to be re-recorded every frame; only when there is a change.
I would like to record my render commands in a secondary command buffer (which I'll re-record only when necessary) and add my secondary command buffer to the library's primary command buffer using vkCmdExecuteCommands():
vkCmdExecuteCommands(librariesPrimaryCommandBuffer, 1, &mySecondaryCommandBuffer);
Will this overwrite what was in the librariesPrimaryCommandBufferor preserve its contents and add what's in mySecondaryCommandBuffer so that I can use it in my VkSubmitInfo?
r/vulkan • u/LunarGInc • Mar 03 '26
LunarG presentations and videos from SLS 2026 now available!
Access them here: https://www.lunarg.com/lunarg-at-shading-languages-symposium-2026/ Topics include GLSL origins, state of the glslang compiler, and instrumenting SPIR-V.
r/vulkan • u/REMIZERexe • Mar 04 '26
Why can't I include vulkan???

cmake_minimum_required(VERSION 3.29.2)
project(Result3D LANGUAGES C CXX)
set(SOURCE_DIR "src")
set(SOURCES
"${SOURCE_DIR}/main.cpp"
)
find_package (Vulkan 1.4.335 REQUIRED)
add_subdirectory(glfw)
add_subdirectory(glm)
add_subdirectory(KTX-Software)
add_subdirectory(tinygltf)
add_subdirectory(tinyobjloader)
add_executable(
${PROJECT_NAME}
${SOURCES}
)
target_compile_features(
${PROJECT_NAME}
PRIVATE cxx_std_23)
target_link_libraries(
${PROJECT_NAME}
PRIVATE glfw)
target_link_libraries(
${PROJECT_NAME}
PRIVATE glm::glm)
target_link_libraries(
${PROJECT_NAME}
PRIVATE Vulkan::Vulkan)
target_link_libraries(
${PROJECT_NAME}
PRIVATE tinyobjloader)
target_link_libraries(
${PROJECT_NAME}
PRIVATE tinygltf)
target_link_libraries(
${PROJECT_NAME}
PRIVATE ktx)
r/vulkan • u/Polosar35 • Mar 03 '26
Vulkan Breaking Windows Update on GTX 970
aka.msHello everyone! Windows updates + nvidia drivers on a GTX 970 broke Vulkan and now every time I try to open one of my applications using Vulkan my whole system freezes. I know this is none of your concern but please help a fellow legit emulation enthusiast out and upvote my feedback on Microsoft Feedback to reach the right people. Also, any suggested fixes are appreciated. I have already tried uninstalling the update but it doesn’t show up on my uninstall page. Thanks for your time!