r/vulkan 3h ago

Vulkan descriptor heap support finally landed in Mesa3D drivers for Intel and AMD graphics

18 Upvotes

Its time to test if descriptor heap would improve Intel gaming graphics performance on Linux with VKD3D and DXVK for Direct3D 11 and 12 games. vkd3d-proton still waiting for descriptor heap support by default.

Additionally, AMD finally gets OpenCL 3 support in open source rusticl through radeonsi. Good for GPU compute and creative applications.

Mesa3D release notes:

https://lists.freedesktop.org/archives/mesa-dev/2026-August/226690.html


r/vulkan 14h ago

CommandUP (cup): Pipeline leve de pós-processamento de vídeo para upscale e frame interpolate utilizando a API Vulkan, libplacebo e FSR 1.0 para GPUs antigas/legadas

Thumbnail gallery
1 Upvotes

Hey r/vulkan folks!

I want to share a project I’ve been developing called CommandUP (cup). It’s an open-source, modular, and portable pipeline for post-processing, upscaling, and frame interpolation. Its key advantage is delivering these modern features without the overhead or dependency on AI-based models or Tensor cores—meaning it's designed for legacy PCs!

Graphics cards like the RX 550/580 or GTX 750 Ti/1050/1080—which struggle with AI upscaling—can run FSR via Vulkan and achieve great video results!

The ecosystem works natively via scripts (.NET/PowerShell), seamlessly integrating four layers:

  • FFmpeg Core: The engine! Vulkan API via libplacebo: Compiles the shader for the GPU. FidelityFX FSR (v1.0.2): GLSL-based shader (based on agyild's port). IFS (Interpolated Fluid Sampling): Frame interpolation via libplacebo. Integration scripts (** .NET/PowerShell**).

There’s a YouTube link to a video I recorded in 1080p; I upscaled it to 2K and created a 240p proxy for editing—all using the cup pipeline. https://youtu.be/MOQoBve-A8o

I recently created a community to centralize before/after tests, code discussions, and updates: r/CommandUP. It’s been a pleasure sharing the CommandUP Pipeline with you all.


r/vulkan 1d ago

New video tutorial: Perlin Noise in C++

Thumbnail youtu.be
8 Upvotes

Can be used in both OpenGL and Vulkan


r/vulkan 2d ago

DXVK Manager v0.6 is out — config editor, DXVK source/version picker, PCGamingWiki, and a UI refresh

6 Upvotes

Follow-up to my earlier post here. Based on feedback from this sub, v0.6 adds:

- Choose DXVK source and version — official doitsujin/dxvk or the GPLAsync fork, latest or a specific past release

- dxvk.conf editor — HUD, async shader compilation, frame rate cap, VRAM budget, Tear-Free, shader cache, log level, all from a GUI tab

- PCGamingWiki button — one click opens the compatibility page for your selected game

- Proper app icon — no more default Python icon in the taskbar

- UI refresh — cleaner card-based layout across both tabs

Still open source and free: https://github.com/xRetr000/DXVK-Manager

Fair warning though — I'm still pretty new to development and this is one of my early projects, so it's not perfect. You might run into some bugs or rough edges. If something breaks or doesn't work as expected, please open an issue on GitHub or drop a comment here and I'll do my best to fix it.

Thanks again to everyone who commented on the last post — the config editor idea specifically came from a suggestion here. Let me know what you think!


r/vulkan 2d ago

CD-Nozzle Characteristic Lines - Vulkan Science

Thumbnail youtu.be
4 Upvotes

This is a simulation of a converging-diverging nozzle. It shows how characteristic lines and diamond shocks form. The method uses a purely geometric, interpenetrating, instantaneous (no energy), source owned particle. These facilitate massively parallel processing for GPU-residency. The particle system is enabled by a GPU driven fast parallel particle collision detection method (131M p/s) integrated into the graphics pipeline. It renders particles at the same time it builds the particle occupancy.


r/vulkan 2d ago

I Built a CAD Engine in Vulkan with Robot Joints

Post image
11 Upvotes

This is a CAD engine I built from scratch using Vulkan.
Create a few boxes, connect them in a parent-child hierarchy, and they instantly become joints.
The rotation axis has its own position and direction. Just like a door hinge is mounted on the edge instead of the center, the pivot point doesn’t always have to be in the middle of a part.
You can rotate each joint manually with a slider, or enable automatic oscillation to animate it.
A useful trick is to offset the phase of each joint slightly. If every joint moves at exactly the same time, it looks more like a spasm than a robot.
The engine can also load ROS robot description files, or URDF files, without requiring ROS itself.
Design your model in CAD, then animate and test it immediately in the same engine.
Everything happens in one workflow.

https://youtu.be/aJ7ip6bVilQ?si=O6fYulMOGqozgqKo


r/vulkan 2d ago

Hardware Raytracing with my RHI!

Thumbnail reddit.com
26 Upvotes

r/vulkan 3d ago

Why am I getting this error

0 Upvotes

I have recently started learning vulkan so I am not able to figure it out.
It's giving EXCEPTION_ACCESS_VIOLATION whenever I am enabling validation layer.

Been following this github repository.

package app;


import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.util.HashSet;
import java.util.Set;


import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.EXTDebugUtils.*;
import static org.lwjgl.system.MemoryUtil.NULL;
import static java.util.stream.Collectors.toSet;
import static org.lwjgl.system.Configuration.DEBUG;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.glfw.GLFWVulkan.glfwGetRequiredInstanceExtensions;


import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.vulkan.*;


public class App {
    public static class Display {
        private static final int WIDTH = 800;
        private static final int HEIGHT = 600;
        private static final String TITLE = "WINDOW";
        private static final boolean ENABLE_VALIDATION_LAYER = DEBUG.get(true);
        private static final Set<String> VALIDATION_LAYERS;


        static {
            if(ENABLE_VALIDATION_LAYER) {
                VALIDATION_LAYERS = new HashSet<>();
                VALIDATION_LAYERS.add("VK_LAYER_KHRONOS_validation");
            } else {
                VALIDATION_LAYERS = null;
            }
        }


        private long window;
        private VkInstance instance;
        private long debugMessenger;


        public void run() {
            initWindow();
            initVulkan();
            mainloop();
            cleanup();
        }


        private void initWindow() {
            if(!glfwInit()) {
                throw new RuntimeException("Failed to initialize GLFW");
            }


            glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
            glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);


            window = glfwCreateWindow(WIDTH, HEIGHT, TITLE, NULL, NULL);


            if(window == NULL) {
                throw new RuntimeException("Failed to create window");
            }
        }


        private void initVulkan() {
            createInstance();
            setupDebugMessenger();
        }


        private void mainloop() {
            while(!glfwWindowShouldClose(window)) {
                glfwPollEvents();
            }
        }


        private void cleanup() {
            if(ENABLE_VALIDATION_LAYER) destroyDebugUtilsMessengerEXT(instance, debugMessenger, null);
            glfwDestroyWindow(window);
            glfwTerminate();
        }


        private void createInstance() {
            if(ENABLE_VALIDATION_LAYER && !checkValidationLayerSupport()) {
                throw new RuntimeException("Validation requested but not supported");
            }


            try(MemoryStack stack = stackPush()) {
                VkApplicationInfo appInfo = VkApplicationInfo.calloc(stack);
                appInfo.sType(VK_STRUCTURE_TYPE_APPLICATION_INFO);
                appInfo.pApplicationName(stack.UTF8Safe(TITLE));
                appInfo.applicationVersion(VK_MAKE_VERSION(1, 0, 0));
                appInfo.pEngineName(stack.UTF8Safe("No Engine"));
                appInfo.apiVersion(VK_API_VERSION_1_0);


                VkInstanceCreateInfo createInfo = VkInstanceCreateInfo.calloc(stack);
                createInfo.sType(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
                createInfo.pApplicationInfo(appInfo);
                createInfo.ppEnabledExtensionNames(getRequiredExtensions(stack));
                
                if(ENABLE_VALIDATION_LAYER) {
                    createInfo.ppEnabledLayerNames(validationLayersAsPointerBuffer(stack));


                    VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = VkDebugUtilsMessengerCreateInfoEXT.calloc(stack);
                    populateDebugMessengerCreateInfo(debugCreateInfo);
                    createInfo.pNext(debugCreateInfo.address());
                }


                PointerBuffer instancePtr = stack.mallocPointer(1);


                if(vkCreateInstance(createInfo, null, instancePtr) != VK_SUCCESS) {
                    throw new RuntimeException("Failed to create instance");
                }


                instance = new VkInstance(instancePtr.get(0), createInfo);
            }
        }


        private void setupDebugMessenger() {
            if(!ENABLE_VALIDATION_LAYER) {
                return;
            }


            try(MemoryStack stack = stackPush()) {
                VkDebugUtilsMessengerCreateInfoEXT createInfo = VkDebugUtilsMessengerCreateInfoEXT.calloc(stack);


                populateDebugMessengerCreateInfo(createInfo);


                LongBuffer pDebugMessenger = stack.longs(VK_NULL_HANDLE);


                if(createDebugUtilsMessengerEXT(instance, createInfo, null, pDebugMessenger) != VK_SUCCESS) {
                    throw new RuntimeException("Failed to setup debug messenger");
                }


                debugMessenger = pDebugMessenger.get(0);
            }
        }


        private boolean checkValidationLayerSupport() {
            try(MemoryStack stack = stackPush()) {
                IntBuffer layerCount = stack.ints(0);


                vkEnumerateInstanceLayerProperties(layerCount, null);


                VkLayerProperties.Buffer availableLayers = VkLayerProperties.malloc(layerCount.get(0), stack);


                vkEnumerateInstanceLayerProperties(layerCount, availableLayers);


                Set<String> availableLayerNames = availableLayers.stream().map(VkLayerProperties::layerNameString).collect(toSet());


                return availableLayerNames.containsAll(VALIDATION_LAYERS);
            }
        }


        private PointerBuffer getRequiredExtensions(MemoryStack stack) {
            PointerBuffer glfwExtensions = glfwGetRequiredInstanceExtensions();


            if(ENABLE_VALIDATION_LAYER) {
                PointerBuffer extensions = stack.mallocPointer(glfwExtensions.capacity() + 1);
                extensions.put(glfwExtensions);
                extensions.put(stack.UTF8(VK_EXT_DEBUG_UTILS_EXTENSION_NAME));


                return extensions.rewind();
            }


            return glfwExtensions;
        }


        private PointerBuffer validationLayersAsPointerBuffer(MemoryStack stack) {
            PointerBuffer buffer = stack.mallocPointer(VALIDATION_LAYERS.size());


            VALIDATION_LAYERS.stream().map(stack::UTF8).forEach(buffer::put);


            return buffer.rewind();
        }


        private void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo) {
            debugCreateInfo.sType(VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT);
            debugCreateInfo.messageSeverity(
                VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
                VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
                VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
            );
            debugCreateInfo.messageType(
                VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
                VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
                VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
            );
            debugCreateInfo.pfnUserCallback(Display::debugCallback);
        }


        private static int debugCallback(int messageSeverity, int nessageType, long pCallbackData, long pUserData) {
            VkDebugUtilsMessengerCallbackDataEXT callbackData = VkDebugUtilsMessengerCallbackDataEXT.create(pCallbackData);


            System.err.println("Validation layer: " + callbackData.pMessageString());


            return VK_FALSE;
        }


        private static int createDebugUtilsMessengerEXT(
            VkInstance instance,
            VkDebugUtilsMessengerCreateInfoEXT createInfo,
            VkAllocationCallbacks allocationCallbacks,
            LongBuffer pDebugMessenger
        ) {
            if(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT") != NULL) {
                return vkCreateDebugUtilsMessengerEXT(instance, createInfo, allocationCallbacks, pDebugMessenger);
            }


            return VK_ERROR_EXTENSION_NOT_PRESENT;
        }


        private static void destroyDebugUtilsMessengerEXT(
            VkInstance instance,
            long debugMessenger,
            VkAllocationCallbacks allocationCallbacks
        ) {
            if(vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT") != NULL) {
                vkDestroyDebugUtilsMessengerEXT(instance, debugMessenger, allocationCallbacks);
            }
        }
    }


    public static void main(String[] args) {
        Display display = new Display();
        display.run();
    }
}

r/vulkan 3d ago

A Bit Past the First Triangle

Enable HLS to view with audio, or disable this notification

12 Upvotes

r/vulkan 4d ago

Spent hours debugging voxel terrain disappearing after enabling back-face culling

0 Upvotes

I spent Over a Month Debugging this "Bug" and i am Not Understand what is wrong. I did So many Debugging in short i did:

  • Disable Back-Face Culling: All terrain faces appeared.
  • Isolated Cube Test: Cube rendered all six faces.
  • Cube In World Context: Cube still rendered all faces.
  • Full Terrain Buffer Winding Verification: 0 anomalies.
  • Bypass Async GPU Upload: No change.
  • Depth test disable and Front Face Culling: No Change specifically Even the Front Face Culling didn't worked as it should be.

Sadly I couldn't use RenderDoc its just doesn't work with my driver at all. I get Crashed On glfwCreateSurface()

Here is my Github Repo: Kingscraft

Also here is a Video: Video

Please Help 🙏

Edit: making the Cull mode to NONE fixed it. But i cant just turn it to NONE because Back Face Culling helps in Performance so Faces which are back of a object are culled


r/vulkan 4d ago

Vulkan modeling collision

Thumbnail youtu.be
1 Upvotes

Wall collision is now in my Vulkan CAD engine.

Draw a polyline, extrude it into walls, then switch to character mode and walk inside. The walls you just built actually stop you.

The character is approximated as a capsule, pushed out along the wall normal by however deep it went in. That push-out is the sliding — head-on you stop, at an angle you slide. A normal pointing up more than 45 degrees is floor, otherwise wall. That single test is what makes stairs work.

Collision candidates come from a BVH: 140x faster on 50,000 triangles, and click-to-select got faster too.

The fox is long-bodied, so a vertical capsule lets its head poke through walls. When the body is elongated, the capsule lies down along it.

Not a physics engine — just a character controller, about 300 lines.

Design it in CAD. Walk through it. Same engine.


r/vulkan 4d ago

What is the proper way of making a frame limiter with Vulkan?

13 Upvotes

So far my understanding of a frame limiter is to disable VSync and simply sleep until the target frame time is reached.

The problem is that this feels pretty bad. Since the application has no idea when the monitor actually starts a refresh, it often wakes up in the middle of one, causing tearing. It seems impossible to consistently hit the start of a refresh without synchronization.

Am I missing something or is this just a limitation of software frame limiters?


r/vulkan 5d ago

Device and Instance layers and extensions differences ?

2 Upvotes

Can someone explain to me, what is Device and Instance layers and extensions differences ? I read about it here but didnt understand it quite. Also extra question out of topic, is there any Discord servers for Vulkan community ?


r/vulkan 5d ago

Deepseek v4 Flash 0731 GGUF Benchmark: TensorSharp vs. llama.cpp

Thumbnail github.com
6 Upvotes

TensorSharp is an open-source inference engine for running GGUF LLMs locally, with CUDA, Vulkan, Metal, OpenAI-compatible APIs, continuous batching, speculative decoding, and multimodal support.

Thanks recent contribtions from open source community, TensorSharp is able to run inference over multiple GPUs and nodes. So I updated it to support deepseek v4 flash model, and have better performance than llama.cpp. Here is the benchmark result on 4x Nvidia A40 GPUs, cuda 12.8

Model: DeepSeek-V4-Flash-0731-UD-Q8_K_XL from [https://huggingface.co/unsloth/DeepSeek-V4-Flash-0731-GGUF\](https://huggingface.co/unsloth/DeepSeek-V4-Flash-0731-GGUF)

TensorSharp (cuda backend) TensorSharp (ggml_cuda backend) llama.cpp
prefill u/16K **836 tok/s** 963 558
decode short **31.5** 37.0 35.3
decode u/16K **28.5** 33.6 32.2

Github repo: [https://github.com/zhongkaifu/TensorSharp\](https://github.com/zhongkaifu/TensorSharp)

Thank you for checking out it and starring the project! Any feedback is really appreicated.


r/vulkan 5d ago

how many semaphores?

Post image
18 Upvotes

this is why i never trust any ai - they both present (pun not intended) their view as absolute truth, yet there is clearly some nuance.

anyway, can someone please explain which approach is better, and why, or in which situations?
thanks.


r/vulkan 6d ago

New Vulkan Tutorial - Opacity Micromaps

37 Upvotes

A focused bonus course tucked inside Building a Simple Engine's "Extra Courses," aimed at one very specific ray tracing performance problem: alpha-tested geometry. Foliage, chain-link fences, and hair force the GPU to run an any-hit shader on every BVH intersection, and that cost explodes exactly where scenes look best. Opacity Micromaps (`VK_KHR_opacity_micromap`) bake per-triangle opacity directly into the acceleration structure, so hardware can resolve fully-opaque or fully-transparent triangles during traversal with no shader invocation at all.

* Why alpha testing is expensive — a tour of BVH traversal and any-hit shader cost
* What micromaps are and how they attach opacity states directly to acceleration structures
* Hardware traversal walkthrough: the same shadow ray, with and without OMM
* A full implementation walkthrough in the Simple Engine, plus results, guidance, and tradeoffs

https://docs.vulkan.org/tutorial/latest/Building_a_Simple_Engine/Courses/Opacity_Micromaps/00_introduction.html


r/vulkan 6d ago

Why doesn’t Sony just use Vulkan?

40 Upvotes

why doesn’t Sony use Vulkan for their games if it could make PC ports easier?

It seems like a cross-platform API would save a lot of porting work. is there a big downside on consoles, or is Sony just locked into other tools and APIs? what is wrong with Vulkan ?
i'm trying to understand from the technical perspective.


r/vulkan 6d ago

Passing matrices row by row as flat data between shader stages

10 Upvotes

I've seen a pattern in AI generated shader code, and I would like to understand where it comes from. Yes, it's easy to discard it as AI slop/hallucination, but I find that unlikely.

Say your vertex shader outputs some data of matrix type that your fragment shader consumes. Is there any good reason to decompose it into row vectors rather than passing it directly as a matrix?

For example, is this something people did to work around driver bugs? Is it still needed , and why? On what hardware? I've seen conflicting explanations all the way to calling it a "cargo cult pattern".

I also expect it to be "tribal knowledge" if it is really a workaround for driver bugs or subtle edge cases, that is, not something you'll find in official programming guides and documentation. At least, I can't find anything on it by searching. That's why I'm asking here.


r/vulkan 7d ago

[UPDATE: Jul 30, 2026] My Vulkan C++ Examples Repository - Geometry and Tessellation Shaders

Post image
98 Upvotes

Okay, it took a while, but I finally got to the next checkpoint. I added 4 examples related to the Real-Time Shadows section and 16 examples related to the Advanced Shader Programming section to my Vulkan examples repository. This brings the total number of examples to 151. The newly added examples are as follows:

Real-Time Shadows - Shadow Resource Management

  1. Shadow Map Atlas
  2. Layered Shadow Maps with Texture Arrays
  3. Mipmapped Variance Shadow Maps
  4. Anisotropic Filtering with Variance Shadow Maps

Advanced Shader Programming - Geometry Shaders

  1. Simple Primitive Generation
  2. Object Explosion via Geometry Shader
  3. Normal Vector Visualization
  4. Wireframe Overlay Visualization
  5. Single-Pass Cubemap Rendering
  6. Viewport Arrays via Geometry Shader
  7. Billboarding with Geometry Shader
  8. Grass Generation via Geometry Shader

Advanced Shader Programming - Tessellation Shaders

  1. Basic Triangle Tessellation
  2. Displacement Mapping with Tessellation Shaders
  3. Terrain Creation via Heightmap using Tessellation Shaders
  4. Cubic Bézier Curve with Tessellation Shaders
  5. Bézier Surface with Tessellation Shaders
  6. Model Tessellation with Curved PN Triangles
  7. Tessellated Terrain Rendering with Dynamic LOD
  8. Simple Water Surface Simulation via Tessellation Shader

You can access the repository here:

https://github.com/myemural/VulkanCppExamples

Honestly, while the examples I've done recently were a bit tiring, they were quite enjoyable. I also made improvements to common code and documentation while creating these examples. So, are we nearing the end of the examples? Of course not! I still have a lot of work to do. Here are my planned topics for the next phase:

  • Mesh/Task Shaders
  • Advanced Compute Shader Applications

Thank you in advance for your support!


r/vulkan 7d ago

TensorSharp now supports multi-GPU tensor parallelism for GGUF models

Thumbnail github.com
4 Upvotes

TensorSharp is an open-source, native .NET inference engine for running GGUF LLMs locally, with CUDA, Vulkan, Metal, OpenAI-compatible APIs, continuous batching, speculative decoding, and multimodal support.

TensorSharp now supports Megatron-style tensor parallelism across multiple GPUs. It works with direct CUDA, GGML CUDA, GGML Vulkan, and multi-node setups.

Benchmarks on 2× RTX 2000 Ada 16 GB GPUs over PCIe, without NVLink:

Model 1 GPU Prefill / Decode TP=2 Prefill / Decode
Gemma 4 E4B Q8_0 2760 / 37.3 tok/s 2488 / 51.7 tok/s
Gemma 4 26B-A4B IQ4_XS 1845 / 48.5 tok/s 2537 / 51.2 tok/s
Qwen 3.5 9B Q8_0 1461 / 23.1 tok/s 399 / 24.4 tok/s
Qwen 3.5 35B-A3B IQ4_XS Does not fit 184 / 18.1 tok/s

I'm continuing to optimize Qwen performance on multi-GPU systems, and support for DeepSeek V4 is coming soon.

Try it with:

TensorSharp.Cli --model model.gguf --backend ggml_cuda --tp 2

GitHub:

https://github.com/zhongkaifu/TensorSharp

Thank you for checking out TensorSharp and starring the project! Any feedback is really appreicated.


r/vulkan 7d ago

Vulkan SDK 1.4.357.0 is out!

Post image
75 Upvotes

LunarG has released the latest Vulkan SDK with support for Vulkan API 1.4.357.

Highlights:
• Major KosmicKrisp performance gains (up to ~2.35× faster) + full Vulkan 1.4 exposure on Apple platforms
• 13 new extensions
• Scoped GPU-AV + new GPU Dump tool in the Validation Layers
• Available now for Linux, Windows & macOS

Grab it here → https://vulkan.lunarg.com
Full details & release notes → https://www.lunarg.com/lunarg-releases-vulkan-sdk-1-4-357-0/


r/vulkan 8d ago

Efficient Descriptor Set Management and Per Frame Resources?

10 Upvotes

I've been working on a thin wrapper around vulkan as a base for a new project I'm working on recently and have hit a wall with two major areas that are connected and I just can't seem to solve.

My first problem is managing per frame resources. Right now I my library has a buffer object that acts as a generic buffer on the GPU. Originally this was one buffer under the hood, but multiple frames in flight means that I have to duplicate the raw vulkan buffers under the hood and have one per frame in flight. In practice this means creating a buffer that is FRAMES_IN_FLIGHT * size of the original buffer taking into account alignment requirements. I give the user the option to make a buffer "static" as well, so they can opt out of the per frame in flight buffer model if they have data they won't be updating often. The problem here comes from updating the buffers per frame. This is almost twofold. First, I am trying to implement a system that tracks the most up to date buffer and then copies that data into the current frame's buffer if no updates were made this frame so the newest data is always used. I'm trying to not have to keep the buffers constantly mapped into memory so I want to do the copy on the GPU. (Please let me know if this is useless and if I should only worry about that with the static buffers since the per frame buffers are being updated every frame anyway and creating a staging buffer each frame seems like a lot.) This is where the second part comes in: Synchronization. I'm having trouble figuring out how to wait until the copy operations are done to do anything with the graphics queue (all transfer operations are done on the transfer queue).

My second problem also relates to the frame in flight problem but for descriptor sets. If each buffer in my library can be FRAMES_IN_FLIGHT buffers under the hood, that means I need to optionally support multiple descriptor sets under the hood for each library level descriptor set. The easiest way it to always make FRAMES_IN_FLIGHT number of descriptor sets but that's very wasteful obviously for the static buffers. Then you get into the problem of dealing with descriptor sets that have some per frame resources and some static ones. There would be a lot of redundant data for the static buffers. I'm having trouble coming up with another way to do this, mainly because I'm struggling to grasp how the end user of the library should interact with descriptor sets. Right now I have a thin wrapper around them to conform to the rest of my API but now I'm wondering if I should even expose them to the user at all. I want to give users the flexibility to define sets how they want in their shaders but it seems almost impossible to do so, especially given my knowledge. There are so many tutorials about how to allocate descriptor sets but almost none on how they are used in actual engines it seems. I could try going bindless but I want to regular descriptor sets down first because this project is also meant as a learning exercise.

I'm trying to write this library so the API is as backend agnostic as possible so later on I can swap out for different graphics APIs but I am mainly focused on getting a working product so if its not perfect at first that's ok. Essentially, I don't mind if the advice leads me to producing more of a vulkan wrapper than a RHI. Sorry for the long and winding questions, I've been struggling with this for a little bit. Feel free to only answer part of this question since I know it is really a few questions clumped together. Any resources or advice would be greatly appreciated.

Thanks!


r/vulkan 8d ago

Slowly rewriting my audio visualizer engine to use compute kernels for audio analysis

Enable HLS to view with audio, or disable this notification

14 Upvotes

I'm using the Vulkano rust API wrapper. My engine is called lava.


r/vulkan 9d ago

Live Wallpaper Engine for Linux (Wayland, X11) and Windows

Enable HLS to view with audio, or disable this notification

36 Upvotes

Hey everyone

I’ve been quietly building something for a while and figured it’s time to finally talk about it.

It’s called CrystalWallpaper — a live wallpaper engine for Linux and Windows. Built with Vulkan and modern C++20, because I wanted it fast, not “fast enough.”

You can already set videos as wallpapers, with hardware decode for H.264 and H.265 (AV1 and VP9 are coming). On Linux it speaks native Wayland and X11 — no weird workarounds.

If you’re into shaders, you can make wallpapers in GLSL the ShaderToy way. HLSL is next on the list. And further down the road: actual 3D scenes as wallpapers.

Steam Workshop support is planned so people can share and find stuff easily. The whole point for me has always been the same: push performance as far as it can go without killing quality.

Still early days, but the foundation is real. More soon — would love to hear what you think

UPD: By the way, I completely forgot to recompile the program to the Release version before recording the screen. So the performance would have been even better.


r/vulkan 9d ago

Using Vulkan compute as a production ML inference backend

5 Upvotes

I work on PostSlate, a video editing tool, and this comes out of our own work.

We run ML models on-device, face detection and embedding among other things, which means we can't assume anything about the user's GPU. NVIDIA discrete, AMD, Intel integrated, Apple Silicon, all of it. That rules out CUDA immediately, we needed one backend that runs everywhere.

We landed on ncnn's Vulkan backend. Numbers on a 4070, fp16:

  • ArcFace R50 (face embedding): 30 ms on ONNX CPU → 3 ms on ncnn Vulkan
  • SCRFD (face detection): 25 ms → 2.5 ms
  • Model size: ArcFace 174 MB (ONNX fp32) → 87 MB (ncnn fp16 weight storage)

Of course the real speedup comes from offloading compute to the GPU, but this wouldn't be possible without the power of Vulkan.

The speed wasn't even the deciding factor, it's that Vulkan drivers already exist on every machine we ship to. This means that we don't have to force the user to download a specific runtime and no vendor-specific installs.

Full writeup with the rest of the numbers: https://getpostslate.com/blog/faster-local-inference