Skip to content
Snippets Groups Projects
Commit 7ae0c95d authored by Alexander Gauggel's avatar Alexander Gauggel
Browse files

[#87] Resolve merge conflicts

parents 40f4700c 25fdb8d3
No related branches found
No related tags found
1 merge request!74Resolve "Mesh Shader Implementation"
Pipeline #26496 failed
Showing
with 485 additions and 45 deletions
......@@ -18,3 +18,8 @@ cmake-build-release/
# GUI configuration files
imgui.ini
# Generated source and header files for shaders
*.hxx
*.cxx
......@@ -28,3 +28,6 @@
[submodule "lib/VulkanMemoryAllocator-Hpp"]
path = lib/VulkanMemoryAllocator-Hpp
url = https://github.com/malte-v/VulkanMemoryAllocator-Hpp.git
[submodule "modules/upscaling/lib/FidelityFX-FSR"]
path = modules/upscaling/lib/FidelityFX-FSR
url = https://github.com/GPUOpen-Effects/FidelityFX-FSR.git
......@@ -40,6 +40,9 @@ endif ()
# fix dependencies for different Linux distros (looking at you Ubuntu)
include(${vkcv_config_ext}/CheckLibraries.cmake)
# add custom function to include a file like a shader as string
include(${vkcv_config_ext}/IncludeShader.cmake)
# cleanup of compiler definitions aka preprocessor variables
if (vkcv_definitions)
list(REMOVE_DUPLICATES vkcv_definitions)
......
......@@ -6,6 +6,9 @@ set(vkcv_sources
${vkcv_include}/vkcv/Core.hpp
${vkcv_source}/vkcv/Core.cpp
${vkcv_include}/vkcv/File.hpp
${vkcv_source}/vkcv/File.cpp
${vkcv_include}/vkcv/PassConfig.hpp
${vkcv_source}/vkcv/PassConfig.cpp
......
function(include_shader shader include_dir source_dir)
if (NOT EXISTS ${shader})
message(WARNING "Shader file does not exist: ${shader}")
else()
get_filename_component(filename ${shader} NAME)
file(SIZE ${shader} filesize)
set(include_target_file ${include_dir}/${filename}.hxx)
set(source_target_file ${source_dir}/${filename}.cxx)
if ((EXISTS ${source_target_file}) AND (EXISTS ${include_target_file}))
file(TIMESTAMP ${shader} shader_timestamp "%Y-%m-%dT%H:%M:%S")
file(TIMESTAMP ${source_target_file} source_timestamp "%Y-%m-%dT%H:%M:%S")
string(COMPARE GREATER ${shader_timestamp} ${source_timestamp} shader_update)
else()
set(shader_update true)
endif()
if (shader_update)
string(TOUPPER ${filename} varname)
string(REPLACE "." "_" varname ${varname})
set(shader_header "#pragma once\n")
string(APPEND shader_header "// This file is auto-generated via cmake, so don't touch it!\n")
string(APPEND shader_header "extern unsigned char ${varname} [${filesize}]\;\n")
string(APPEND shader_header "extern unsigned int ${varname}_LEN\;\n")
string(APPEND shader_header "const std::string ${varname}_SHADER (reinterpret_cast<const char*>(${varname}), ${varname}_LEN)\;")
file(WRITE ${include_target_file} ${shader_header})
find_program(xxd_program "xxd")
if (EXISTS ${xxd_program})
get_filename_component(shader_directory ${shader} DIRECTORY)
add_custom_command(
OUTPUT ${source_target_file}
WORKING_DIRECTORY "${shader_directory}"
COMMAND xxd -i -C "${filename}" "${source_target_file}"
COMMENT "Processing shader into source files: ${shader}"
)
else()
set(shader_source "// This file is auto-generated via cmake, so don't touch it!\n")
string(APPEND shader_source "unsigned char ${varname}[] = {")
math(EXPR max_fileoffset "${filesize} - 1" OUTPUT_FORMAT DECIMAL)
message(STATUS "Processing shader into source files: ${shader}")
foreach(fileoffset RANGE ${max_fileoffset})
file(READ ${shader} shader_source_byte OFFSET ${fileoffset} LIMIT 1 HEX)
math(EXPR offset_modulo "${fileoffset} % 12" OUTPUT_FORMAT DECIMAL)
if (${offset_modulo} EQUAL 0)
string(APPEND shader_source "\n ")
endif()
if (${fileoffset} LESS ${max_fileoffset})
string(APPEND shader_source "0x${shader_source_byte}, ")
else()
string(APPEND shader_source "0x${shader_source_byte}\n")
endif()
endforeach()
string(APPEND shader_source "}\;\n")
string(APPEND shader_source "unsigned int ${varname}_LEN = ${filesize}\;")
file(WRITE ${source_target_file} ${shader_source})
endif()
endif()
endif()
endfunction()
......@@ -38,12 +38,11 @@ namespace vkcv
[[nodiscard]]
const vma::Allocator& getAllocator() const;
static Context create(
const char* applicationName,
uint32_t applicationVersion,
std::vector<vk::QueueFlagBits> queueFlags,
std::vector<const char *> instanceExtensions,
std::vector<const char *> deviceExtensions);
static Context create(const char *applicationName,
uint32_t applicationVersion,
const std::vector<vk::QueueFlagBits>& queueFlags,
const std::vector<const char *>& instanceExtensions,
const std::vector<const char *>& deviceExtensions);
private:
/**
......
......@@ -138,9 +138,9 @@ namespace vkcv
static Core create(Window &window,
const char *applicationName,
uint32_t applicationVersion,
std::vector<vk::QueueFlagBits> queueFlags = {},
std::vector<const char*> instanceExtensions = {},
std::vector<const char*> deviceExtensions = {});
const std::vector<vk::QueueFlagBits>& queueFlags = {},
const std::vector<const char*>& instanceExtensions = {},
const std::vector<const char*>& deviceExtensions = {});
/**
* Creates a basic vulkan graphics pipeline using @p config from the pipeline config class and returns it using the @p handle.
......@@ -163,7 +163,7 @@ namespace vkcv
*/
[[nodiscard]]
PipelineHandle createComputePipeline(
const ShaderProgram &config,
const ShaderProgram &shaderProgram,
const std::vector<vk::DescriptorSetLayout> &descriptorSetLayouts);
/**
......@@ -196,11 +196,13 @@ namespace vkcv
* @param minFilter Minimizing filter
* @param mipmapMode Mipmapping filter
* @param addressMode Address mode
* @param mipLodBias Mip level of detail bias
* @return Sampler handle
*/
[[nodiscard]]
SamplerHandle createSampler(SamplerFilterType magFilter, SamplerFilterType minFilter,
SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode);
SamplerMipmapMode mipmapMode, SamplerAddressMode addressMode,
float mipLodBias = 0.0f);
/**
* Creates an #Image with a given format, width, height and depth.
......@@ -223,9 +225,13 @@ namespace vkcv
Multisampling multisampling = Multisampling::None);
[[nodiscard]]
uint32_t getImageWidth(ImageHandle imageHandle);
uint32_t getImageWidth(const ImageHandle& image);
[[nodiscard]]
uint32_t getImageHeight(ImageHandle imageHandle);
uint32_t getImageHeight(const ImageHandle& image);
[[nodiscard]]
vk::Format getImageFormat(const ImageHandle& image);
/** TODO:
* @param setDescriptions
......@@ -291,15 +297,21 @@ namespace vkcv
const RecordCommandFunction &record,
const FinishCommandFunction &finish);
void submitCommandStream(const CommandStreamHandle handle);
void prepareSwapchainImageForPresent(const CommandStreamHandle handle);
void prepareImageForSampling(const CommandStreamHandle cmdStream, const ImageHandle image);
void prepareImageForStorage(const CommandStreamHandle cmdStream, const ImageHandle image);
void recordImageMemoryBarrier(const CommandStreamHandle cmdStream, const ImageHandle image);
void recordBufferMemoryBarrier(const CommandStreamHandle cmdStream, const BufferHandle buffer);
void resolveMSAAImage(CommandStreamHandle cmdStream, ImageHandle src, ImageHandle dst);
void submitCommandStream(const CommandStreamHandle& handle);
void prepareSwapchainImageForPresent(const CommandStreamHandle& handle);
void prepareImageForSampling(const CommandStreamHandle& cmdStream, const ImageHandle& image);
void prepareImageForStorage(const CommandStreamHandle& cmdStream, const ImageHandle& image);
void recordImageMemoryBarrier(const CommandStreamHandle& cmdStream, const ImageHandle& image);
void recordBufferMemoryBarrier(const CommandStreamHandle& cmdStream, const BufferHandle& buffer);
void resolveMSAAImage(const CommandStreamHandle& cmdStream, const ImageHandle& src, const ImageHandle& dst);
[[nodiscard]]
vk::ImageView getSwapchainImageView() const;
void recordMemoryBarrier(const CommandStreamHandle& cmdStream);
void recordBlitImage(const CommandStreamHandle& cmdStream, const ImageHandle& src, const ImageHandle& dst,
SamplerFilterType filterType);
};
}
......@@ -23,7 +23,9 @@ namespace vkcv
STORAGE_BUFFER,
SAMPLER,
IMAGE_SAMPLED,
IMAGE_STORAGE
IMAGE_STORAGE,
UNIFORM_BUFFER_DYNAMIC,
STORAGE_BUFFER_DYNAMIC
};
/*
......
......@@ -20,16 +20,15 @@ namespace vkcv {
uint32_t mipLevel;
};
struct UniformBufferDescriptorWrite {
inline UniformBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {};
uint32_t binding;
BufferHandle buffer;
};
struct StorageBufferDescriptorWrite {
inline StorageBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {};
struct BufferDescriptorWrite {
inline BufferDescriptorWrite(uint32_t binding, BufferHandle buffer, bool dynamic = false,
uint32_t offset = 0, uint32_t size = 0) :
binding(binding), buffer(buffer), dynamic(dynamic), offset(offset), size(size) {};
uint32_t binding;
BufferHandle buffer;
bool dynamic;
uint32_t offset;
uint32_t size;
};
struct SamplerDescriptorWrite {
......@@ -41,8 +40,8 @@ namespace vkcv {
struct DescriptorWrites {
std::vector<SampledImageDescriptorWrite> sampledImageWrites;
std::vector<StorageImageDescriptorWrite> storageImageWrites;
std::vector<UniformBufferDescriptorWrite> uniformBufferWrites;
std::vector<StorageBufferDescriptorWrite> storageBufferWrites;
std::vector<BufferDescriptorWrite> uniformBufferWrites;
std::vector<BufferDescriptorWrite> storageBufferWrites;
std::vector<SamplerDescriptorWrite> samplerWrites;
};
}
\ No newline at end of file
......@@ -19,11 +19,13 @@ namespace vkcv {
};
struct DescriptorSetUsage {
inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle) noexcept
: setLocation(setLocation), vulkanHandle(vulkanHandle) {}
inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle,
const std::vector<uint32_t>& dynamicOffsets = {}) noexcept
: setLocation(setLocation), vulkanHandle(vulkanHandle), dynamicOffsets(dynamicOffsets) {}
const uint32_t setLocation;
const vk::DescriptorSet vulkanHandle;
const uint32_t setLocation;
const vk::DescriptorSet vulkanHandle;
const std::vector<uint32_t> dynamicOffsets;
};
struct Mesh {
......
#pragma once
#include <filesystem>
namespace vkcv {
std::filesystem::path generateTemporaryFilePath();
std::filesystem::path generateTemporaryDirectoryPath();
}
......@@ -32,8 +32,8 @@ namespace vkcv {
const std::vector<Queue> &getTransferQueues() const;
static void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice,
std::vector<float> &queuePriorities,
std::vector<vk::QueueFlagBits> &queueFlags,
const std::vector<float> &queuePriorities,
const std::vector<vk::QueueFlagBits> &queueFlags,
std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos,
std::vector<std::pair<int, int>> &queuePairsGraphics,
std::vector<std::pair<int, int>> &queuePairsCompute,
......
......@@ -8,3 +8,4 @@ add_subdirectory(meshlet)
add_subdirectory(scene)
add_subdirectory(shader_compiler)
add_subdirectory(testing)
add_subdirectory(upscaling)
......@@ -12,8 +12,8 @@ set(vkcv_meshlet_include ${PROJECT_SOURCE_DIR}/include)
set(vkcv_meshlet_sources
${vkcv_meshlet_include}/vkcv/meshlet/Meshlet.hpp
${vkcv_meshlet_source}/vkcv/meshlet/Meshlet.cpp
# ${vkcv_meshlet_include}/vkcv/meshlet/Tipsify.hpp
# ${vkcv_meshlet_source}/vkcv/meshlet/Tipsify.cpp
${vkcv_meshlet_include}/vkcv/meshlet/Tipsify.hpp
${vkcv_meshlet_source}/vkcv/meshlet/Tipsify.cpp
)
# adding source files to the module
......
#pragma once
#include "Meshlet.hpp"
#include <algorithm>
#include <iostream>
namespace vkcv::meshlet {
/**
* reorders the IndexBuffer, so all usages of vertices to triangle are as close as possible
* @param indexBuffer32Bit current IndexBuffer
* @param vertexCount of the mesh
* @param cacheSize of the priority cache <br>
* Recommended: 20. Keep the value between 5 and 50 <br>
* low: more random and patchy<br>
* high: closer vertices have higher chance -> leads to sinuous lines
* @return new IndexBuffer that replaces the input IndexBuffer
*/
std::vector<uint32_t> tipsifyMesh(
const std::vector<uint32_t> &indexBuffer32Bit,
const int vertexCount, const unsigned int cacheSize = 20);
}
\ No newline at end of file
//
// Created by Dradozer on 20.07.2021.
//
#include <vkcv/Logger.hpp>
#include "vkcv/meshlet/Tipsify.hpp"
#include <iostream>
const int maxUsedVertices = 128;
namespace vkcv::meshlet {
/**
* modulo operation with maxUsedVertices
* @param number for modulo operation
* @return number between 0 and maxUsedVertices - 1
*/
int mod( int number ){
return (number + maxUsedVertices) % maxUsedVertices;
}
/**
* searches for the next VertexIndex that was used before or returns any vertexIndex if no used was found
* @param livingTriangles
* @param usedVerticeStack
* @param usedVerticeCount
* @param usedVerticeOffset
* @param vertexCount
* @param lowestLivingVertexIndex
* @return a VertexIndex to be used as fanningVertexIndex
*/
int skipDeadEnd(
const std::vector<uint8_t> &livingTriangles,
const std::vector<uint32_t> &usedVerticeStack,
int &usedVerticeCount,
int &usedVerticeOffset,
int vertexCount,
int &lowestLivingVertexIndex) {
// returns the latest vertex used that has a living triangle
while (mod(usedVerticeCount) != usedVerticeOffset) {
// iterate from the latest to the oldest. + maxUsedVertices to always make it a positive number in the range 0 to maxUsedVertices -1
int nextVertex = usedVerticeStack[mod(--usedVerticeCount)];
if (livingTriangles[nextVertex] > 0) {
return nextVertex;
}
}
// returns any vertexIndex since no last used has a living triangle
while (lowestLivingVertexIndex + 1 < vertexCount) {
lowestLivingVertexIndex++;
if (livingTriangles[lowestLivingVertexIndex] > 0) {
return lowestLivingVertexIndex;
}
}
return -1;
}
/**
* searches for the best next candidate as a fanningVertexIndex
* @param vertexCount
* @param lowestLivingVertexIndex
* @param cacheSize
* @param possibleCandidates
* @param numPossibleCandidates
* @param lastTimestampCache
* @param currentTimeStamp
* @param livingTriangles
* @param usedVerticeStack
* @param usedVerticeCount
* @param usedVerticeOffset
* @return a VertexIndex to be used as fanningVertexIndex
*/
int getNextVertexIndex(int vertexCount,
int &lowestLivingVertexIndex,
int cacheSize,
const std::vector<uint32_t> &possibleCandidates,
int numPossibleCandidates,
const std::vector<uint32_t> &lastTimestampCache,
int currentTimeStamp,
const std::vector<uint8_t> &livingTriangles,
const std::vector<uint32_t> &usedVerticeStack,
int &usedVerticeCount,
int &usedVerticeOffset) {
int nextVertexIndex = -1;
int maxPriority = -1;
// calculates the next possibleCandidates that is recently used
for (int j = 0; j < numPossibleCandidates; j++) {
int vertexIndex = possibleCandidates[j];
// the candidate needs to be not fanned out yet
if (livingTriangles[vertexIndex] > 0) {
int priority = -1;
// prioritizes recent used vertices, but tries not to pick one that has many triangles -> fills holes better
if ( currentTimeStamp - lastTimestampCache[vertexIndex] + 2 * livingTriangles[vertexIndex] <=
cacheSize) {
priority = currentTimeStamp - lastTimestampCache[vertexIndex];
}
// select the vertexIndex with the highest priority
if (priority > maxPriority) {
maxPriority = priority;
nextVertexIndex = vertexIndex;
}
}
}
// if no candidate is alive, try and find another one
if (nextVertexIndex == -1) {
nextVertexIndex = skipDeadEnd(
livingTriangles,
usedVerticeStack,
usedVerticeCount,
usedVerticeOffset,
vertexCount,
lowestLivingVertexIndex);
}
return nextVertexIndex;
}
std::vector<uint32_t> tipsifyMesh(
const std::vector<uint32_t> &indexBuffer32Bit,
const int vertexCount,
const unsigned int cacheSize) {
if (indexBuffer32Bit.empty() || vertexCount <= 0) {
vkcv_log(LogLevel::ERROR, "Invalid Input.");
return indexBuffer32Bit;
}
int triangleCount = indexBuffer32Bit.size() / 3;
// dynamic array for vertexOccurrence
std::vector<uint8_t> vertexOccurrence(vertexCount, 0);
// count the occurrence of a vertex in all among all triangles
for (size_t i = 0; i < triangleCount * 3; i++) {
vertexOccurrence[indexBuffer32Bit[i]]++;
}
int sum = 0;
std::vector<uint32_t> offsetVertexOccurrence(vertexCount + 1, 0);
// highest offset for later iteration
int maxOffset = 0;
// calculate the offset of each vertex from the start
for (int i = 0; i < vertexCount; i++) {
offsetVertexOccurrence[i] = sum;
sum += vertexOccurrence[i];
if (vertexOccurrence[i] > maxOffset) {
maxOffset = vertexOccurrence[i];
}
// reset for reuse
vertexOccurrence[i] = 0;
}
offsetVertexOccurrence[vertexCount] = sum;
// vertexIndexToTriangle = which vertex belongs to which triangle
std::vector<uint32_t> vertexIndexToTriangle(3 * triangleCount, 0);
// vertexOccurrence functions as number of usages in all triangles
// lowestLivingVertexIndex = number of a triangle
for (int i = 0; i < triangleCount; i++) {
// get the pointer to the first vertex of the triangle
// this allows us to iterate over the indexBuffer with the first vertex of the triangle as start
const uint32_t *vertexIndexOfTriangle = &indexBuffer32Bit[i * 3];
vertexIndexToTriangle[offsetVertexOccurrence[vertexIndexOfTriangle[0]] + vertexOccurrence[vertexIndexOfTriangle[0]]] = i;
vertexOccurrence[vertexIndexOfTriangle[0]]++;
vertexIndexToTriangle[offsetVertexOccurrence[vertexIndexOfTriangle[1]] + vertexOccurrence[vertexIndexOfTriangle[1]]] = i;
vertexOccurrence[vertexIndexOfTriangle[1]]++;
vertexIndexToTriangle[offsetVertexOccurrence[vertexIndexOfTriangle[2]] + vertexOccurrence[vertexIndexOfTriangle[2]]] = i;
vertexOccurrence[vertexIndexOfTriangle[2]]++;
}
// counts if a triangle still uses this vertex
std::vector<uint8_t> livingVertices = vertexOccurrence;
std::vector<uint32_t> lastTimestampCache(vertexCount, 0);
// stack of already used vertices, if it'currentTimeStamp full it will write to 0 again
std::vector<uint32_t> usedVerticeStack(maxUsedVertices, 0);
//currently used vertices
int usedVerticeCount = 0;
// offset if maxUsedVertices was reached and it loops back to 0
int usedVerticeOffset = 0;
// saves if a triangle was emitted (used in the IndexBuffer)
std::vector<bool> isEmittedTriangles(triangleCount, false);
// reordered Triangles that get rewritten to the new IndexBuffer
std::vector<uint32_t> reorderedTriangleIndexBuffer(triangleCount, 0);
// offset to the latest not used triangleIndex
int triangleOutputOffset = 0;
// vertexIndex to fan out from (fanning VertexIndex)
int currentVertexIndex = 0;
int currentTimeStamp = cacheSize + 1;
int lowestLivingVertexIndex = 0;
std::vector<uint32_t> possibleCandidates(3 * maxOffset);
// run while not all indices are fanned out, -1 equals all are fanned out
while (currentVertexIndex >= 0) {
// number of possible candidates for a fanning VertexIndex
int numPossibleCandidates = 0;
// offset of currentVertexIndex and the next VertexIndex
int startOffset = offsetVertexOccurrence[currentVertexIndex];
int endOffset = offsetVertexOccurrence[currentVertexIndex + 1];
// iterates over every triangle of currentVertexIndex
for (int offset = startOffset; offset < endOffset; offset++) {
int triangleIndex = vertexIndexToTriangle[offset];
// checks if the triangle is already emitted
if (!isEmittedTriangles[triangleIndex]) {
// get the pointer to the first vertex of the triangle
// this allows us to iterate over the indexBuffer with the first vertex of the triangle as start
const uint32_t *vertexIndexOfTriangle = &indexBuffer32Bit[3 * triangleIndex];
// save emitted vertexIndexOfTriangle to reorderedTriangleIndexBuffer and set it to emitted
reorderedTriangleIndexBuffer[triangleOutputOffset++] = triangleIndex;
isEmittedTriangles[triangleIndex] = true;
// save all vertexIndices of the triangle to reuse as soon as possible
for (int j = 0; j < 3; j++) {
int vertexIndex = vertexIndexOfTriangle[j];
//save vertexIndex to reuseStack
usedVerticeStack[mod(usedVerticeCount++)] = vertexIndex;
// after looping back increase the start, so it only overrides the oldest vertexIndex
if ((mod(usedVerticeCount)) ==
(mod(usedVerticeOffset))) {
usedVerticeOffset = mod(usedVerticeOffset + 1);
}
// add vertex to next possibleCandidates as fanning vertex
possibleCandidates[numPossibleCandidates++] = vertexIndex;
// remove one occurrence of the vertex, since the triangle is used
livingVertices[vertexIndex]--;
// writes the timestamp (number of iteration) of the last usage, if it wasn't used within the last cacheSize iterations
if (currentTimeStamp - lastTimestampCache[vertexIndex] > cacheSize) {
lastTimestampCache[vertexIndex] = currentTimeStamp;
currentTimeStamp++;
}
}
}
}
// search for the next vertexIndex to fan out
currentVertexIndex = getNextVertexIndex(
vertexCount, lowestLivingVertexIndex, cacheSize, possibleCandidates, numPossibleCandidates, lastTimestampCache, currentTimeStamp,
livingVertices, usedVerticeStack, usedVerticeCount, usedVerticeOffset);
}
std::vector<uint32_t> reorderedIndexBuffer(3 * triangleCount);
triangleOutputOffset = 0;
// rewriting the TriangleIndexBuffer to the new IndexBuffer
for (int i = 0; i < triangleCount; i++) {
int triangleIndex = reorderedTriangleIndexBuffer[i];
// rewriting the triangle index to vertices
for (int j = 0; j < 3; j++) {
int vertexIndex = indexBuffer32Bit[(3 * triangleIndex) + j];
reorderedIndexBuffer[triangleOutputOffset++] = vertexIndex;
}
}
return reorderedIndexBuffer;
}
}
\ No newline at end of file
......@@ -10,6 +10,9 @@ set(vkcv_shader_compiler_include ${PROJECT_SOURCE_DIR}/include)
# Add source and header files to the module
set(vkcv_shader_compiler_sources
${vkcv_shader_compiler_include}/vkcv/shader/Compiler.hpp
${vkcv_shader_compiler_source}/vkcv/shader/Compiler.cpp
${vkcv_shader_compiler_include}/vkcv/shader/GLSLCompiler.hpp
${vkcv_shader_compiler_source}/vkcv/shader/GLSLCompiler.cpp
)
......
#pragma once
#include <filesystem>
#include <string>
#include <unordered_map>
#include <vkcv/Event.hpp>
#include <vkcv/ShaderStage.hpp>
namespace vkcv::shader {
......@@ -8,10 +13,21 @@ namespace vkcv::shader {
class Compiler {
private:
protected:
std::unordered_map<std::string, std::string> m_defines;
public:
virtual bool compileSource(ShaderStage shaderStage, const char* shaderSource,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath) = 0;
virtual void compile(ShaderStage shaderStage, const std::filesystem::path& shaderPath,
const ShaderCompiledFunction& compiled, bool update = false) = 0;
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath, bool update) = 0;
std::string getDefine(const std::string& name) const;
void setDefine(const std::string& name, const std::string& value);
};
}
......@@ -7,7 +7,7 @@
namespace vkcv::shader {
class GLSLCompiler {
class GLSLCompiler : public Compiler {
private:
public:
GLSLCompiler();
......@@ -20,8 +20,13 @@ namespace vkcv::shader {
GLSLCompiler& operator=(const GLSLCompiler& other);
GLSLCompiler& operator=(GLSLCompiler&& other) = default;
bool compileSource(ShaderStage shaderStage, const char* shaderSource,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath);
void compile(ShaderStage shaderStage, const std::filesystem::path& shaderPath,
const ShaderCompiledFunction& compiled, bool update = false);
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath = "", bool update = false) override;
};
......
#include "vkcv/shader/Compiler.hpp"
namespace vkcv::shader {
std::string Compiler::getDefine(const std::string &name) const {
return m_defines.at(name);
}
void Compiler::setDefine(const std::string &name, const std::string &value) {
m_defines[name] = value;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment