...
 
Commits (8)
......@@ -60,6 +60,7 @@ add_library(
src/Lib/src/Util/Logging.cpp
src/Lib/src/Util/VectorConversions.cpp
src/Lib/src/Util/PerlinGenerator.cpp
src/Lib/src/Util/ExceptionBase.cpp
src/Lib/src/VkUtil/CompileShader.cpp
src/Lib/src/VkUtil/AccelerationStructureBase.cpp
......@@ -68,15 +69,17 @@ add_library(
src/Lib/src/VkUtil/NoUsableMemoryException.cpp
src/Lib/src/VkUtil/TopLevelAccelerationStructure.cpp
src/Lib/src/VkUtil/VkResult.cpp
src/Lib/src/VkUtil/Buffer.cpp
src/Lib/src/VkUtil/Texture.cpp
src/Lib/src/VkUtil/RenderTarget.cpp
src/Lib/src/VkUtil/StagedBuffer.cpp
src/Lib/src/VkUtil/OneTimeCommandBuffer.cpp
src/Lib/src/VkUtil/StbImageImpl.cpp
src/Lib/src/VkUtil/Texture/Texture.cpp
src/Lib/src/VkUtil/Texture/StbImageImpl.cpp
src/Lib/src/VkUtil/Memory/MappedMemory.cpp
src/Lib/src/VkUtil/Memory/Buffer.cpp
src/Lib/src/VkUtil/Memory/StagedBuffer.cpp
src/Lib/src/VkUtil/Memory/Memory.cpp
src/Lib/src/VkUtil/Memory/MemoryAllocation.cpp
src/Lib/src/VkUtil/Memory/OutOfMemoryException.cpp
src/submodules/dearImGui/imgui_demo.cpp
......
......@@ -130,7 +130,7 @@ beschrieben
- Anforderungen in Readme aktualisiert.
- FPS können nun im Fenstertitel angezeigt werden
### 1.1
## 1.1
- Diverse Optimierungen
- Integration von Dear ImGui
......@@ -138,3 +138,9 @@ beschrieben
- beliebige Anzahl an Hitgroups und Miss-Shadern kann geladen werden.
- Jitter-Cam
- Neue Szenen (Cornell-Box)
### 1.1.1 (WIP)
- Shader werden parallel geladen
- Shader können aus RAM geladen werden
- Umbauten für Speicherverwaltung 2.0
......@@ -23,8 +23,8 @@
#include "VkUtil/Shader.hpp"
#include "VkUtil/TopLevelAccelerationStructure.hpp"
#include "VkUtil/VkUtil.hpp"
#include "VkUtil/Texture.hpp"
#include "VkUtil/RenderTarget.hpp"
#include "VkUtil/Texture/Texture.hpp"
#include "imgui_impl_vulkan.h"
namespace lib
......
#pragma once
namespace lib
{
template <typename TIterator>
class Range
{
TIterator rangeBegin;
TIterator rangeEnd;
public:
template <typename TContainer>
Range(TContainer &container)
: rangeBegin(std::begin(container)),
rangeEnd(std::end(container))
{
}
Range(TIterator rangeBegin, TIterator rangeEnd)
: rangeBegin(rangeBegin),
rangeEnd(rangeEnd)
{
}
TIterator begin()
{
return this->rangeBegin;
}
TIterator end()
{
return this->rangeEnd;
}
};
} // namespace lib
\ No newline at end of file
#pragma once
#include "GlfwAndVulkan.hpp"
#include "VkUtil/Memory/MemoryAllocation.hpp"
#include "VkUtil/Memory/Memory.hpp"
#include "Util/TypeTraits.hpp"
namespace lib
{
class CgContext;
template <typename T>
class Reservation
{
private:
T &data;
Buffer2 &owner;
Reservation(T &data, Buffer2 &owner)
: data(data),
owner(owner)
{
}
public:
// Reservation(const Reservation &) = delete;
// Reservation(Reservation &&) = delete;
// Reservation &operator=(const Reservation &) = delete;
// Reservation &operator=(Reservation &&) = delete;
void Acquire(lib::Memory &memory)
{
this->owner.BindMemory(memory);
this->owner.WriteData(this->data);
}
friend class Buffer2;
};
class Buffer2
{
private:
lib::CgContext *parent;
vk::Buffer handle;
vk::BufferMemoryRequirementsInfo2 memoryRequirements;
lib::MemoryAllocation allocation;
public:
Buffer2(CgContext *parent);
Buffer2(const Buffer2 &copy) = delete;
Buffer2(Buffer2 &&move);
template <typename T>
Reservation<T> Reserve(T &data)
{
return Reservation{data, *this};
}
void BindMemory(Memory &);
template <typename T>
void WriteData(T &data)
{
this->allocation.Map().Write(data);
}
const vk::Buffer &GetHandle() const;
const vk::BufferMemoryRequirementsInfo2 &GetMemoryRequirements() const;
Buffer2 &operator=(const Buffer2 &copy) = delete;
Buffer2 &operator=(Buffer2 &&move);
};
} // namespace lib
\ No newline at end of file
......@@ -5,24 +5,76 @@
namespace lib
{
/**
* @brief Forward-Declaration für CgContext.
*/
class CgContext;
/**
* @brief Stell ein Stück allozierten Speicher dar.
*/
struct MemoryAllocation
class MemoryAllocation
{
MemoryAllocation() = default;
private:
/**
* @brief Der genutzte Context.
*/
CgContext *context;
inline MemoryAllocation(vk::DeviceMemory memory,
vk::DeviceSize offset,
vk::DeviceSize size)
: memory(memory),
offset(offset),
size(size)
{
}
/**
* @brief Das Handle zum Speicher.
*/
vk::DeviceMemory handle{nullptr};
vk::DeviceMemory memory{nullptr};
/**
* @brief Das Offset des Abschnitts in Byte.
*/
vk::DeviceSize offset{0};
/**
* @brief Die Größe des Abschnittes in Byte.
*/
vk::DeviceSize size{0};
public:
/**
* @brief Initialisiert eine neue Instanz der Memory Allocation Klasse.
*/
MemoryAllocation() = default;
/**
* @brief Initialisiert eine neue Instanz der Memory Allocation Klasse.
*
* @param context Der zu nutzende CgContext.
* @param handle Das Handle zum Speicher.
* @param offset Das Offset des Abschnitts in Byte.
* @param size Die Größe des Abschnittes in Byte.
*/
MemoryAllocation(CgContext *context,
vk::DeviceMemory handle,
vk::DeviceSize offset,
vk::DeviceSize size);
/**
* @brief Mapped den gesamten Speicher.
*
* @return MappedMemory Der Gemappedte Speicher.
*/
MappedMemory Map() const;
/**
* @brief Das Handle zum Speicher.
*/
const vk::DeviceMemory &GetMemoryHandle() const;
/**
* @brief Das Offset des Abschnitts in Byte.
*/
vk::DeviceSize GetOffset() const;
/**
* @brief Die Größe des Abschnittes in Byte.
*/
vk::DeviceSize GetSize() const;
};
} // namespace lib
......@@ -2,7 +2,7 @@
#include "GlfwAndVulkan.hpp"
#include "VkUtil/Texture.hpp"
#include "VkUtil/Texture/Texture.hpp"
#include <vector>
#include <map>
......
......@@ -51,6 +51,11 @@ namespace lib
* @brief Shader liegt als vorkompilierter SPIR-V-Binärcode vor.
*/
SpirV,
/**
* @brief Shader liegt nicht als Datei vor, sondern als Text.
*/
Plain,
};
/**
......@@ -64,6 +69,11 @@ namespace lib
*/
Debug,
/**
* @brief Keine Optimierungen anwenden.
*/
None,
/**
* @brief Möglichst schnellen Code erzeugen.
*/
......@@ -73,11 +83,6 @@ namespace lib
* @brief Möglichst kleinen Code erzeugen.
*/
Size,
/**
* @brief Keine Optimierungen anwenden.
*/
None,
};
/**
......@@ -93,8 +98,9 @@ namespace lib
*/
inline CompilerMacro(std::string name, std::string value = "")
: name(name),
value(value)
{}
value(value)
{
}
/**
* @brief Der Name des Makros, also der zu ersetzende Text.
......@@ -129,10 +135,17 @@ namespace lib
struct ShaderInfo final
{
/**
* @brief Der Pfad zur Quell-Datei.
* @brief Der Pfad zur Quell-Datei. Wird nur beachtet wenn `type` entweder
* `ShaderFileType::Glsl` oder `ShaderFileType::SpirV` ist.
*/
std::string path;
/**
* @brief Der Text des Shaders als GLSL. Wird nur beachtet wenn `type` gleich
* `ShaderFileType::Plain` ist.
*/
std::string shaderText;
/**
* @brief Der Typ des Shaders.
*/
......
......@@ -8,6 +8,7 @@
#include <limits>
#include <set>
#include <random>
#include <future>
#include "Config.hpp"
#include "Core/CameraModel.hpp"
......@@ -33,14 +34,12 @@ using lib::log::Warning;
bool lib::CgContext::TryCreateRasterizerPipeline()
{
auto success = true;
auto vertexModule = this->LoadShader(this->appInfo.shaderTable.postProcessingVertexShader);
auto waitForVertexModule = std::async(&CgContext::LoadShader, this, this->appInfo.shaderTable.postProcessingVertexShader);
auto waitForFragmentModule = std::async(&CgContext::LoadShader, this, this->appInfo.shaderTable.postProcessingFragmentShader);
success = success && vertexModule;
auto fragmentModule = this->LoadShader(this->appInfo.shaderTable.postProcessingFragmentShader);
success = success && fragmentModule;
auto vertexModule = waitForVertexModule.get();
auto fragmentModule = waitForFragmentModule.get();
auto success = vertexModule && fragmentModule;
if (success)
{
......@@ -173,7 +172,7 @@ void lib::CgContext::CreateRasterizationDescriptorSets()
for (size_t i = 0; i < count; i++)
{
auto &frame = this->temporalInterpolationFrames[i];
frame.rasterizationDescriptorSet = *setsIt++;
std::vector<vk::DescriptorImageInfo> imageInfos;
......@@ -185,8 +184,8 @@ void lib::CgContext::CreateRasterizationDescriptorSets()
for (uint32_t j = 0; j < this->temporalInterpolationCount + 1; j++)
{
auto frameIndex = this->temporalInterpolationCount > 0
? (this->temporalInterpolationCount + i - j) % this->temporalInterpolationCount
: i;
? (this->temporalInterpolationCount + i - j) % this->temporalInterpolationCount
: i;
auto &backFrame = this->temporalInterpolationFrames[frameIndex];
......
......@@ -8,6 +8,7 @@
#include <limits>
#include <set>
#include <random>
#include <future>
#include "Config.hpp"
#include "Core/CameraModel.hpp"
......@@ -281,31 +282,47 @@ void lib::CgContext::CreateRaytracingDescriptorSets()
bool lib::CgContext::TryCreateRayTracingPipeline()
{
auto raygenModule = this->LoadShader(this->appInfo.shaderTable.raygenShader);
auto success = static_cast<bool>(raygenModule);
auto waitForRaygenModule = std::async(&CgContext::LoadShader, this, this->appInfo.shaderTable.raygenShader);
std::vector<std::future<vk::ShaderModule>> waitForMissModules;
std::vector<vk::ShaderModule> missModules;
std::vector<std::future<vk::ShaderModule>> waitForClosestHitModules;
std::vector<vk::ShaderModule> closestHitModules;
waitForMissModules.reserve(this->appInfo.shaderTable.missShaders.size());
missModules.reserve(this->appInfo.shaderTable.missShaders.size());
waitForClosestHitModules.reserve(this->appInfo.shaderTable.closestHitShaders.size());
closestHitModules.reserve(this->appInfo.shaderTable.closestHitShaders.size());
for (const auto &missModule : this->appInfo.shaderTable.missShaders)
{
missModules.push_back(this->LoadShader(missModule));
success = success && missModules.back();
waitForMissModules.emplace_back(std::async(&CgContext::LoadShader, this, missModule));
}
std::vector<vk::ShaderModule> closestHitModules;
closestHitModules.reserve(this->appInfo.shaderTable.closestHitShaders.size());
for (const auto &closestHitModule : this->appInfo.shaderTable.closestHitShaders)
{
closestHitModules.push_back(this->LoadShader(closestHitModule));
success = success && closestHitModules.back();
waitForClosestHitModules.emplace_back(std::async(&CgContext::LoadShader, this, closestHitModule));
}
this->shaderOffsets.rayGen = 0;
this->shaderOffsets.miss = 1;
this->shaderOffsets.hitGroup = static_cast<uint32_t>(missModules.size() + this->shaderOffsets.miss);
this->shaderOffsets.count = static_cast<uint32_t>(this->shaderOffsets.hitGroup + closestHitModules.size());
this->shaderOffsets.hitGroup = static_cast<uint32_t>(this->appInfo.shaderTable.missShaders.size() + this->shaderOffsets.miss);
this->shaderOffsets.count = static_cast<uint32_t>(this->appInfo.shaderTable.closestHitShaders.size() + this->shaderOffsets.hitGroup);
auto raygenModule = waitForRaygenModule.get();
auto success = static_cast<bool>(raygenModule);
for (auto &waitForMissModule : waitForMissModules)
{
missModules.push_back(waitForMissModule.get());
success = success && missModules.back();
}
for (auto &waitForClosestHitModule : waitForClosestHitModules)
{
closestHitModules.push_back(waitForClosestHitModule.get());
success = success && closestHitModules.back();
}
if (success)
{
......@@ -332,7 +349,6 @@ bool lib::CgContext::TryCreateRayTracingPipeline()
for (size_t i = 0; i < missModules.size(); i++)
{
vk::PipelineShaderStageCreateInfo stageCreateInfo;
stageCreateInfo.stage = vk::ShaderStageFlagBits::eMissNV;
stageCreateInfo.module = missModules[i];
......
......@@ -775,7 +775,7 @@ void lib::CgContext::UpdateCommandBuffer(uint32_t imageIndex, uint32_t temporalI
this->shaderBindingTableBuffer->GetBufferHandle(), this->shaderOffsets.hitGroup * sbtEntrySize, sbtEntrySize,
this->shaderBindingTableBuffer->GetBufferHandle(), 0, 0,
this->swapChainExtent.width, this->swapChainExtent.height, 1);
TransitionImageLayout(frame.commandBuffer,
interpolationFrame.raytracingRenderTarget->GetHandle(), this->swapChainImageFormat,
vk::ImageLayout::eGeneral, vk::ImageLayout::eShaderReadOnlyOptimal,
......@@ -933,7 +933,9 @@ vk::ShaderModule lib::CgContext::LoadShader(const ShaderInfo &info)
{
lib::CodeBuffer buf;
if (info.fileType == ShaderFileType::Glsl)
switch (info.fileType)
{
case ShaderFileType::Glsl:
{
std::string stringBuf;
......@@ -951,7 +953,8 @@ vk::ShaderModule lib::CgContext::LoadShader(const ShaderInfo &info)
return vk::ShaderModule();
}
}
else
break;
case ShaderFileType::SpirV:
{
if (!lib::TryLoadFile(info.path, buf))
{
......@@ -960,6 +963,19 @@ vk::ShaderModule lib::CgContext::LoadShader(const ShaderInfo &info)
return vk::ShaderModule();
}
}
break;
case ShaderFileType::Plain:
{
if (!CompileShader(info.shaderText, info, buf))
{
lib::log::Error("Failed to load shader\"%\": compilation failed!", info.shaderText);
return vk::ShaderModule();
}
}
break;
}
vk::ShaderModuleCreateInfo createInfo;
createInfo.codeSize = buf.size() * 4;
......
#include <iostream>
#include <mutex>
#include "Util/Logging.hpp"
......@@ -9,6 +10,8 @@ namespace
lib::log::ChannelState{true, "[Info] ", "", true},
lib::log::ChannelState{true, "[Warning] ", "", true},
lib::log::ChannelState{true, "[Error] ", "", true}};
std::mutex loggingIoMutex{};
} // namespace
lib::log::State &lib::log::GetState()
......@@ -25,7 +28,10 @@ void lib::log::Debug(const std::string &text)
return;
}
std::cout << ::state.info.prefix << text << ::state.info.suffix << '\n';
{
const std::lock_guard lock{::loggingIoMutex};
std::cout << ::state.info.prefix << text << ::state.info.suffix << '\n';
}
if (::state.info.flush)
{
......@@ -41,7 +47,10 @@ void lib::log::Info(const std::string &text)
return;
}
std::cout << ::state.info.prefix << text << ::state.info.suffix << '\n';
{
const std::lock_guard lock{::loggingIoMutex};
std::cout << ::state.info.prefix << text << ::state.info.suffix << '\n';
}
if (::state.info.flush)
{
......@@ -56,7 +65,10 @@ void lib::log::Error(const std::string &text)
return;
}
std::cout << ::state.error.prefix << text << ::state.error.suffix << '\n';
{
const std::lock_guard lock{::loggingIoMutex};
std::cout << ::state.error.prefix << text << ::state.error.suffix << '\n';
}
if (::state.error.flush)
{
......@@ -71,7 +83,10 @@ void lib::log::Warning(const std::string &text)
return;
}
std::cout << ::state.warning.prefix << text << ::state.warning.suffix << '\n';
{
const std::lock_guard lock{::loggingIoMutex};
std::cout << ::state.warning.prefix << text << ::state.warning.suffix << '\n';
}
if (::state.warning.flush)
{
......
......@@ -42,6 +42,7 @@ lib::MemoryAllocation lib::Memory::Acquire(vk::DeviceSize size)
}
MemoryAllocation res{
this->context,
this->handle,
this->allocationEnd,
size};
......
#include "VkUtil/Memory/MemoryAllocation.hpp"
lib::MemoryAllocation::MemoryAllocation(CgContext *context,
vk::DeviceMemory handle,
vk::DeviceSize offset,
vk::DeviceSize size)
: context(context),
handle(handle),
offset(offset),
size(size)
{
}
lib::MappedMemory lib::MemoryAllocation::Map() const
{
return MappedMemory{this->context, this->handle, this->offset, this->size};
}
const vk::DeviceMemory &lib::MemoryAllocation::GetMemoryHandle() const
{
return this->handle;
}
vk::DeviceSize lib::MemoryAllocation::GetOffset() const
{
return this->offset;
}
vk::DeviceSize lib::MemoryAllocation::GetSize() const
{
return this->size;
}
\ No newline at end of file
#include "Core/CgContext.hpp"
#include "VkUtil/Texture.hpp"
#include "VkUtil/Texture/Texture.hpp"
#include "stb_image.h"
#include "VkUtil/VkUtil.hpp"
#include "Util/Utils.hpp"
......