Created
October 5, 2025 11:39
-
-
Save Themaister/dcbcb8dfaa4c1e9877008895f501e6b6 to your computer and use it in GitHub Desktop.
Bringup sample #4 - Mandelbulb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "device.hpp" | |
| #include "context.hpp" | |
| #include "logging.hpp" | |
| #include <stdlib.h> | |
| static const uint32_t mandelbulb_shader[] = | |
| #include "mandelbulb.h" | |
| ; | |
| static void run_some_code(Vulkan::Device &dev) | |
| { | |
| auto info = Vulkan::ImageCreateInfo::immutable_2d_image(1280, 720, VK_FORMAT_R8G8B8A8_UNORM); | |
| info.usage = VK_IMAGE_USAGE_STORAGE_BIT; | |
| // Image layouts comes into play later. | |
| info.initial_layout = VK_IMAGE_LAYOUT_GENERAL; | |
| Vulkan::ImageHandle img = dev.create_image(info); | |
| Vulkan::Program *prog = dev.request_program(mandelbulb_shader, sizeof(mandelbulb_shader)); | |
| // Copy CPU memory into VRAM, but using shaders. | |
| Vulkan::CommandBufferHandle cmd = dev.request_command_buffer(Vulkan::CommandBuffer::Type::Generic); | |
| cmd->set_program(prog); | |
| cmd->set_storage_texture(0, 0, img->get_view()); | |
| constexpr uint32_t workgroup_size_x = 8; | |
| constexpr uint32_t workgroup_size_y = 8; | |
| struct | |
| { | |
| float width, height; | |
| float time; | |
| } push = {}; | |
| push.width = info.width; | |
| push.height = info.height; | |
| push.time = 4.55f; | |
| cmd->push_constants(&push, 0, sizeof(push)); | |
| cmd->dispatch(1280 / workgroup_size_x, 720 / workgroup_size_y, 1); | |
| dev.submit(cmd); | |
| // This functions as garbage collection. Memory is not reclaimed unless this is called regularly. | |
| dev.next_frame_context(); | |
| } | |
| int main() | |
| { | |
| // Loads the Vulkan loader dynamically. | |
| // The loader is the entry point to figure out | |
| // which drivers are available on the system. | |
| // The default is: | |
| // - libvulkan.so.1 on Linux (installed with vulkan-icd-loader) | |
| // - vulkan-1.dll (Installed on Windows by your driver or standalone with Vulkan SDK) | |
| // - libvulkan.so on Android (included on OS if it's not comically old) | |
| if (!Vulkan::Context::init_loader(nullptr)) | |
| return EXIT_FAILURE; | |
| // The context owns a VkInstance, VkPhysicalDevice and VkDevice. | |
| // Don't enable any optional extensions and fancy features for now. | |
| Vulkan::Context ctx; | |
| if (!ctx.init_instance_and_device( | |
| nullptr, 0, nullptr, 0)) | |
| return EXIT_FAILURE; | |
| // Doesn't do much real work, but instantiates a logical device that borrows the handles from Context. | |
| Vulkan::Device dev; | |
| dev.set_context(ctx); | |
| // Capturing Vulkan in debuggers is typically done in two ways: | |
| // - Frame captures. Requires the debugger to understand what a "frame" is, typically requires presenting on screen, | |
| // which we're not going to do. | |
| // - Using the RenderDoc API to trigger captures programmatically. | |
| // Needs RenderDoc to be loaded into the process already. | |
| bool has_rdoc = Vulkan::Device::init_renderdoc_capture(); | |
| if (has_rdoc) | |
| dev.begin_renderdoc_capture(); | |
| run_some_code(dev); | |
| if (has_rdoc) | |
| dev.end_renderdoc_capture(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment