diff --git a/.gitignore b/.gitignore index a1965f8..2baa00f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ mandelbrot-* *.lib *.exp +**.spv # vs code settings .vscode/ diff --git a/Makefile b/Makefile index 64e4a6a..4dad19f 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,22 @@ -EXE=mandelbrot-mac +MANDEL_EXE=mandelbrot-mac -all: $(EXE) +DEBUG_FLAGS= +# DEBUG_FLAGS=-DNDEBUG -$(EXE): src/main.cpp src/lodepng.cpp src/lodepng.h shaders/mandelbrot.spv - g++ -std=c++11 -O3 -I$(VULKAN_SDK)include/ src/main.cpp src/lodepng.cpp -o $(EXE) -L$(VULKAN_SDK)lib/ -lvulkan +UTIL_HEADERS=src/lodepng.h +UTIL_CPPS=src/lodepng.cpp + +all: $(MANDEL_EXE) + +$(MANDEL_EXE): src/main.cpp $(UTIL_HEADERS) $(UTIL_CPPS) shaders/mandelbrot.generated.spv Makefile + g++ -std=c++11 -O3 -I$(VULKAN_SDK)include -DMANDELBROT_MODE $(DEBUG_FLAGS) src/main.cpp $(UTIL_CPPS) -o $(MANDEL_EXE) -L$(VULKAN_SDK)lib -lvulkan + +shaders/mandelbrot.generated.spv: shaders/mandelbrot.comp Makefile + $(VULKAN_SDK)bin/glslangValidator -V shaders/mandelbrot.comp -o shaders/mandelbrot.generated.spv + +run: $(MANDEL_EXE) + ./$(MANDEL_EXE) && qlmanage -p pathtracer.png >> /dev/null 2>&1 -shaders/mandelbrot.spv: shaders/mandelbrot.comp - $(VULKAN_SDK)bin/glslangValidator -V shaders/mandelbrot.comp -o shaders/mandelbrot.spv clean: - rm -f $(EXE) + rm -f $(MANDEL_EXE) mandelbrot.png shaders/mandelbrot.generated.spv diff --git a/Makefile.win32 b/Makefile.win32 new file mode 100644 index 0000000..960c37f --- /dev/null +++ b/Makefile.win32 @@ -0,0 +1,21 @@ +MANDEL_EXE=mandelbrot-win32.exe + +DEBUG_FLAGS= +# DEBUG_FLAGS=-DNDEBUG + +UTIL_HEADERS=src\lodepng.h +UTIL_CPPS=src\lodepng.cpp + +all: $(MANDEL_EXE) + +$(MANDEL_EXE): src\main.cpp $(UTIL_HEADERS) $(UTIL_CPPS) shaders\mandelbrot.generated.spv Makefile.win32 + g++ -std=c++11 -O3 -I$(VULKAN_SDK)\include -DMANDELBROT_MODE $(DEBUG_FLAGS) $(UTIL_CPPS) src\main.cpp -o $(MANDEL_EXE) -L$(VULKAN_SDK)\lib -lvulkan-1 + +shaders\mandelbrot.generated.spv: shaders\mandelbrot.comp Makefile.win32 + $(VULKAN_SDK)\bin\glslangValidator -V shaders\mandelbrot.comp -o shaders\mandelbrot.generated.spv + +run: $(MANDEL_EXE) + $(MANDEL_EXE) + +clean: + del /Q $(MANDEL_EXE) mandelbrot.png shaders\mandelbrot.generated.spv diff --git a/README.md b/README.md index c0f9324..7dc0242 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,20 @@ # Vulkan Minimal Compute -This is a simple demo that demonstrates how to use Vulkan for compute operations only. -In other words, this demo does nothing related to graphics, -and only uses Vulkan to execute some computation on the GPU. -For this demo, Vulkan is used to render the Mandelbrot set on the GPU. The demo is very simple, -and is only ~400LOC. **The code is heavily commented, so it should be useful for people interested in learning Vulkan**. +This is a simple demo that demonstrates how to use Vulkan compute shaders to calculate the Mandelbrot set on the GPU. **The code is heavily commented, so it can be seen as a rough getting-started tutorial for using Vulkan compute shaders**. -The only depdendencies are Vulkan and `lodepng`. `lodepng` is simply used for png encoding. Vulkan can be installed -from `lunarg.com` +The only depdendencies are Vulkan and `lodepng`, which is merely used for png encoding. The Vulkan SDK can be installed from `lunarg.com` ![](imageForReadme.png) # Demo -The application launches a compute shader that renders the mandelbrot set, by rendering it into a storage buffer. -The storage buffer is then read from the GPU, and saved as `.png`. Check the source code comments -for further info. +The application launches a compute shader that calculates the Mandelbrot set, and writes resulting pixels into a storage buffer. +The storage buffer is then transferred from GPU- to CPU memory, and saved as `.png`. -## Building +# Building -The project uses CMake, and all dependencies are included, so you -should use CMake to generate a "Visual Studio Solution"/makefile, -and then use that to compile the program. If you then run the program, -a file named `mandelbrot.png` should be created. This is a Mandelbrot -set that has been rendered by using Vulkan. +The project uses a bare-bones Makefile, which can also be run on Windows using `mingw32-make -f Makefile.win32` (tested with [tdm-gcc v10.3.0](https://jmeubank.github.io/tdm-gcc/) installation on Windows 10). + +# Running + +When running the created program, the png file `mandelbrot.png` is created. diff --git a/imageForReadme.png b/imageForReadme.png index 21c6203..4abe43e 100644 Binary files a/imageForReadme.png and b/imageForReadme.png differ diff --git a/shaders/mandelbrot.comp b/shaders/mandelbrot.comp index 5e4cb1e..a698663 100644 --- a/shaders/mandelbrot.comp +++ b/shaders/mandelbrot.comp @@ -1,8 +1,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable -#define WIDTH 3200 -#define HEIGHT 2400 +#define WIDTH 1000 // => must match main.cpp +#define HEIGHT 1000 // => must match main.cpp #define WORKGROUP_SIZE 32 layout (local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1 ) in; diff --git a/src/main.cpp b/src/main.cpp index 24902d2..7f53919 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,8 +9,8 @@ #include "lodepng.h" //Used for png encoding. -const int WIDTH = 3200; // Size of rendered mandelbrot set. -const int HEIGHT = 2400; // Size of renderered mandelbrot set. +const int WIDTH = 1000; // Size of rendered mandelbrot set. => must match mandelbrot.comp +const int HEIGHT = 1000; // Size of renderered mandelbrot set. => must match mandelbrot.comp const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader. #ifdef NDEBUG @@ -628,7 +628,7 @@ class ComputeApplication { // $(VULKAN_SDK)bin/glslangValidator -V mandelbrot.comp -o mandelbrot.spv // NOTE: if the instructions in mac-vulkan-setup-guide.md were followed, $(VULKAN_SDK)bin/ is // actually part of the path, so you can just type 'glslangValidator -V mandelbrot.comp -o mandelbrot.spv' - uint32_t* code = readFile(filelength, "shaders/mandelbrot.spv"); + uint32_t* code = readFile(filelength, "shaders/mandelbrot.generated.spv"); VkShaderModuleCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.pCode = code;