Vulkan Compute Layer #14
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Vulkan Compute API for Cyfra
Hey everyone! I wanted to share the compute API component I've been working on. This is just a small piece of the bigger system, but it adds a high-level abstraction layer for GPU compute operations using Vulkan.
Implementation Approach
I decided to wrap the LWJGL Vulkan bindings with a more user-friendly Scala API that handles boilerplate. This was my first time working with Vulkan, so there was definitely a learning curve, but I think the abstraction turned out good!
Here's how the API layers work:
The main components are:
ComputeContext: Controls the Vulkan environmentBuffer: Manages GPU memoryShader: Handles SPIR-V shader codePipeline: Manages compute pipelinesAPI Components
Buffer Management (
api/Buffer.scala)Represents memory on the GPU with methods for data transfer between host and device:
Compute Context (
ComputeContext.scala)Entry point for all compute operations, manages the Vulkan environment:
Usage example:
Shader Management (
Shader.scala)Encapsulates SPIR-V shader code and metadata:
Pipeline Execution (
Pipeline.scala)Manages compute pipeline creation and dispatch:
Layout Models (
LayoutModel.scala)Defines shader interface for buffer binding:
Memory Management
We use the Vulkan Memory Allocator (VMA) for efficient GPU memory allocation:
Memory types:
VMA_MEMORY_USAGE_CPU_TO_GPU: For host-visible buffers that need frequent updatesVMA_MEMORY_USAGE_GPU_ONLY: For device-local memory with optimal performanceCommand Buffer Lifecycle
Command buffers are created, recorded, submitted, and recycled:
Thread Safety
The API uses locks to ensure thread-safe execution:
Usage Examples
Basic Compute Operation
Complex Multi-Buffer Example
Direct Buffer Mapping
Current Issues I'm Working On
As this is just the first version, there are some issues I'm still figuring out:
Memory Management: Right now you have to close resources in reverse order, which is annoying:
// Close in reverse order of creation! outputBuffer.close() inputBuffer.close() pipeline.close() shader.close() context.close()Shader Support: Only compute shaders supported, but we'll need to expand this for the full rendering pipeline.
Error Reporting: The stack traces for Vulkan errors could be more helpful.
Buffer Sizing: Buffers must be pre-sized correctly, no resizing
I'm hoping to get time to work on the resource auto-closure system next week!
Please provide any feedback or suggest fixes! I'm especially looking for insights on improving the API design and memory management approach.