Skip to content

Commit

Permalink
Compile GLSL shaders at runtime
Browse files Browse the repository at this point in the history
This will require shaderc as a new dep
  • Loading branch information
GhostNaN committed Nov 12, 2020
1 parent fad1a34 commit fe1cb39
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 14 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ The Bad:
- Teminal display
- libconfig
- Config file manager
- shaderc
- Runtime shader compilation

#### Must have at least one:
- portaudio(optional)
Expand All @@ -39,6 +41,7 @@ AUR package - https://aur.archlinux.org/packages/recidia-audio-visualizer/
#### Requirements:
- meson
- ninja
- vulkan-headers

#### To build:
```
Expand All @@ -52,6 +55,7 @@ And if you wish to install:
ninja -C build install
mkdir ~/.config/recidia/
cp settings.cfg ~/.config/recidia/
cp -r shaders ~/.config/recidia/
```

## Usage
Expand Down
3 changes: 2 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ fftw = dependency('fftw3')
threads = dependency('threads')
curses = dependency('ncursesw')
libconfig = dependency('libconfig++')
shaderc = dependency('shaderc')

audio_check = false

Expand All @@ -31,4 +32,4 @@ qt5 = dependency('qt5', modules: ['Core', 'Gui', 'Widgets'])
executable(meson.project_name(), ['src/main.cpp', 'src/audio.c', 'src/processing.cpp',
'src/curses.cpp', 'src/config.cpp', 'src/window.cpp', 'src/vulkan.cpp'],
include_directories : ['inc'],
dependencies: [gsl, fftw, threads, curses, libconfig, pulse_simple, portaudio, qt5], install: true)
dependencies: [gsl, fftw, threads, curses, libconfig, pulse_simple, portaudio, qt5, shaderc], install: true)
File renamed without changes.
File renamed without changes.
39 changes: 26 additions & 13 deletions src/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <QVulkanFunctions>

#include <glm/glm.hpp>
#include <shaderc/shaderc.hpp>

#include <qt_window.h>

Expand Down Expand Up @@ -82,30 +83,42 @@ VulkanRenderer::VulkanRenderer(VulkanWindow *window) {
vulkan_window = window;
}

VkShaderModule createShader(const string name) {
VkShaderModule createShader(const string name, shaderc_shader_kind shader_kind) {
string homeDir = getenv("HOME");
vector<string> shaderFileLocations = {"shaders/",
"../shaders/",
homeDir + "/.config/recidia/shaders/",
"/etc/recidia/shaders/"};
// Read shader file
ifstream file(name, ios::ate | ios::binary);
ifstream file;
for (uint i=0; i < shaderFileLocations.size(); i++) {
file.open(shaderFileLocations[i] + name);
if (file.is_open()) {
break;
}
}
if (!file.is_open()) {
throw std::runtime_error("failed to open file!");
throw std::runtime_error("Failed to find shader file!");
}
size_t fileSize = (size_t) file.tellg();
std::vector<char> buffer(fileSize);
file.seekg(0);
file.read(buffer.data(), fileSize);
std::string shaderText( (std::istreambuf_iterator<char>(file) ),
(std::istreambuf_iterator<char>() ) );
file.close();

auto shaderCode = buffer;
shaderc::Compiler compiler;
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(shaderText, shader_kind, "");
vector<uint32_t> spvCode;
spvCode.assign(result.cbegin(), result.cend());

VkShaderModuleCreateInfo shaderInfo;
shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderInfo.codeSize = shaderCode.size();
shaderInfo.pCode = reinterpret_cast<const uint32_t *>(shaderCode.data());
shaderInfo.codeSize = sizeof(uint32_t) * spvCode.size();
shaderInfo.pCode = (const uint32_t*) spvCode.data();
shaderInfo.pNext = nullptr; // WILL SEGV WITHOUT

VkShaderModule shaderModule;
VkResult err = dev_funct->vkCreateShaderModule(vulkan_dev, &shaderInfo, nullptr, &shaderModule);
if (err != VK_SUCCESS) {
qWarning("Failed to create shader module: %d", err);
printf("Failed to create shader module: %d\n", err);
return VK_NULL_HANDLE;
}

Expand Down Expand Up @@ -167,8 +180,8 @@ void VulkanRenderer::initResources() {
pipelineInfo.pVertexInputState = &vertexInputInfo;

// Shaders
VkShaderModule vertShaderModule = createShader("../vulkan/vert.spv");
VkShaderModule fragShaderModule = createShader("../vulkan/frag.spv");
VkShaderModule vertShaderModule = createShader("default.vert", shaderc_shader_kind::shaderc_glsl_vertex_shader);
VkShaderModule fragShaderModule = createShader("default.frag", shaderc_shader_kind::shaderc_glsl_fragment_shader);

VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
Expand Down
Binary file removed vulkan/frag.spv
Binary file not shown.
Binary file removed vulkan/vert.spv
Binary file not shown.

0 comments on commit fe1cb39

Please sign in to comment.