Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion 3dgs/GSScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "GSScene.h"

#include <random>
#include "shaders.h"

#include "../vulkan/Utils.h"
#include "../vulkan/DescriptorSet.h"
Expand Down Expand Up @@ -155,7 +156,9 @@ std::shared_ptr<Buffer> GSScene::createBuffer(const std::shared_ptr<VulkanContex
void GSScene::precomputeCov3D(const std::shared_ptr<VulkanContext>&context) {
cov3DBuffer = createBuffer(context, header.numVertices * sizeof(float) * 6);

auto pipeline = std::make_shared<ComputePipeline>(context, "precomp_cov3d");
auto pipeline = std::make_shared<ComputePipeline>(
context, std::make_shared<Shader>(context, "precomp_cov3d", SPV_PRECOMP_COV3D, SPV_PRECOMP_COV3D_len));

auto descriptorSet = std::make_shared<DescriptorSet>(context, FRAMES_IN_FLIGHT);
descriptorSet->bindBufferToDescriptorSet(0, vk::DescriptorType::eStorageBuffer, vk::ShaderStageFlagBits::eCompute,
vertexBuffer);
Expand Down
8 changes: 4 additions & 4 deletions 3dgs/GUIManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ void GUIManager::buildGui() {
ImPlot::SetupAxisLimits(ImAxis_Y1, 0, 1);
ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.5f);
for (auto& [name, values]: *metricsMap) {
if (!values.Data.empty()) {
ImPlot::PlotLine(name.c_str(), &values.Data[0].x, &values.Data[0].y, values.Data.size(), 0,
values.Offset, 2 * sizeof(float));
if (!values.data.empty()) {
ImPlot::PlotLine(name.c_str(), &values.data[0].x, &values.data[0].y, values.data.size(), 0,
values.offset, 2 * sizeof(float));
}
}
ImPlot::EndPlot();
Expand All @@ -47,7 +47,7 @@ void GUIManager::buildGui() {
void GUIManager::pushMetric(const std::string& name, float value) {
int maxSize = 600;
if (!metricsMap->contains(name)) {
metricsMap->insert({name, ScrollingBuffer(maxSize)});
metricsMap->insert({name, ScrollingBuffer{}});
}
metricsMap->at(name).addPoint(ImGui::GetTime(), value);
}
Expand Down
28 changes: 14 additions & 14 deletions 3dgs/GUIManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@
#include "implot/implot.h"

struct ScrollingBuffer {
int MaxSize;
int Offset;
ImVector<ImVec2> Data;
ScrollingBuffer(int max_size = 2000) {
MaxSize = max_size;
Offset = 0;
Data.reserve(MaxSize);
int maxSize;
int offset;
ImVector<ImVec2> data;
explicit ScrollingBuffer(const int max_size = 10000) {
maxSize = max_size;
offset = 0;
data.reserve(maxSize);
}
void addPoint(float x, float y) {
if (Data.size() < MaxSize)
Data.push_back(ImVec2(x,y));
if (data.size() < maxSize)
data.push_back(ImVec2(x,y));
else {
Data[Offset] = ImVec2(x,y);
Offset = (Offset + 1) % MaxSize;
data[offset] = ImVec2(x,y);
offset = (offset + 1) % maxSize;
}
}
void clear() {
if (Data.size() > 0) {
Data.shrink(0);
Offset = 0;
if (data.size() > 0) {
data.shrink(0);
offset = 0;
}
}
};
Expand Down
19 changes: 10 additions & 9 deletions 3dgs/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "../vulkan/Swapchain.h"

#include <memory>
#include <shaders.h>
#include <utility>

#include <glm/glm.hpp>
Expand Down Expand Up @@ -80,7 +81,7 @@ void Renderer::retrieveTimestamps() {

void Renderer::initializeVulkan() {
spdlog::debug("Initializing Vulkan");
window = std::make_shared<Window>("Vulkan Splatting", 800, 600);
window = std::make_shared<Window>("Vulkan Splatting", 1920, 1080);
context = std::make_shared<VulkanContext>(Window::getRequiredInstanceExtensions(), std::vector<std::string>{},
configuration.enableVulkanValidationLayers);

Expand Down Expand Up @@ -129,7 +130,7 @@ void Renderer::createPreprocessPipeline() {
vertexAttributeBuffer = Buffer::storage(context, scene->getNumVertices() * sizeof(VertexAttributeBuffer), false);
tileOverlapBuffer = Buffer::storage(context, scene->getNumVertices() * sizeof(uint32_t), false);

preprocessPipeline = std::make_shared<ComputePipeline>(context, "preprocess");
preprocessPipeline = std::make_shared<ComputePipeline>(context, std::make_shared<Shader>(context, "preprocess", SPV_PREPROCESS, SPV_PREPROCESS_len));
inputSet = std::make_shared<DescriptorSet>(context, FRAMES_IN_FLIGHT);
inputSet->bindBufferToDescriptorSet(0, vk::DescriptorType::eStorageBuffer, vk::ShaderStageFlagBits::eCompute,
scene->vertexBuffer);
Expand Down Expand Up @@ -174,7 +175,7 @@ void Renderer::createPrefixSumPipeline() {
prefixSumPongBuffer = Buffer::storage(context, scene->getNumVertices() * sizeof(uint32_t), false);
totalSumBufferHost = Buffer::staging(context, sizeof(uint32_t));

prefixSumPipeline = std::make_shared<ComputePipeline>(context, "prefix_sum");
prefixSumPipeline = std::make_shared<ComputePipeline>(context, std::make_shared<Shader>(context, "prefix_sum", SPV_PREFIX_SUM, SPV_PREFIX_SUM_len));
auto descriptorSet = std::make_shared<DescriptorSet>(context, FRAMES_IN_FLIGHT);
descriptorSet->bindBufferToDescriptorSet(0, vk::DescriptorType::eStorageBuffer, vk::ShaderStageFlagBits::eCompute,
prefixSumPingBuffer);
Expand Down Expand Up @@ -206,8 +207,8 @@ void Renderer::createRadixSortPipeline() {

sortHistBuffer = Buffer::storage(context, numWorkgroups * 256 * sizeof(uint32_t), false);

sortHistPipeline = std::make_shared<ComputePipeline>(context, "hist");
sortPipeline = std::make_shared<ComputePipeline>(context, "sort");
sortHistPipeline = std::make_shared<ComputePipeline>(context, std::make_shared<Shader>(context, "hist", SPV_HIST, SPV_HIST_len));
sortPipeline = std::make_shared<ComputePipeline>(context, std::make_shared<Shader>(context, "sort", SPV_SORT, SPV_SORT_len));

auto descriptorSet = std::make_shared<DescriptorSet>(context, FRAMES_IN_FLIGHT);
descriptorSet->bindBufferToDescriptorSet(0, vk::DescriptorType::eStorageBuffer, vk::ShaderStageFlagBits::eCompute,
Expand Down Expand Up @@ -248,7 +249,7 @@ void Renderer::createRadixSortPipeline() {

void Renderer::createPreprocessSortPipeline() {
spdlog::debug("Creating preprocess sort pipeline");
preprocessSortPipeline = std::make_shared<ComputePipeline>(context, "preprocess_sort");
preprocessSortPipeline = std::make_shared<ComputePipeline>(context, std::make_shared<Shader>(context, "preprocess_sort", SPV_PREPROCESS_SORT, SPV_PREPROCESS_SORT_len));
auto descriptorSet = std::make_shared<DescriptorSet>(context, FRAMES_IN_FLIGHT);
descriptorSet->bindBufferToDescriptorSet(0, vk::DescriptorType::eStorageBuffer, vk::ShaderStageFlagBits::eCompute,
vertexAttributeBuffer);
Expand All @@ -274,7 +275,7 @@ void Renderer::createTileBoundaryPipeline() {
auto tileY = (height + 16 - 1) / 16;
tileBoundaryBuffer = Buffer::storage(context, tileX * tileY * sizeof(uint32_t) * 2, false);

tileBoundaryPipeline = std::make_shared<ComputePipeline>(context, "tile_boundary");
tileBoundaryPipeline = std::make_shared<ComputePipeline>(context, std::make_shared<Shader>(context, "tile_boundary", SPV_TILE_BOUNDARY, SPV_TILE_BOUNDARY_len));
auto descriptorSet = std::make_shared<DescriptorSet>(context, FRAMES_IN_FLIGHT);
descriptorSet->bindBufferToDescriptorSet(0, vk::DescriptorType::eStorageBuffer, vk::ShaderStageFlagBits::eCompute,
sortKBufferEven);
Expand All @@ -291,7 +292,7 @@ void Renderer::createTileBoundaryPipeline() {

void Renderer::createRenderPipeline() {
spdlog::debug("Creating render pipeline");
renderPipeline = std::make_shared<ComputePipeline>(context, "render");
renderPipeline = std::make_shared<ComputePipeline>(context, std::make_shared<Shader>(context, "render", SPV_RENDER, SPV_RENDER_len));
auto inputSet = std::make_shared<DescriptorSet>(context, FRAMES_IN_FLIGHT);
inputSet->bindBufferToDescriptorSet(0, vk::DescriptorType::eStorageBuffer, vk::ShaderStageFlagBits::eCompute,
vertexAttributeBuffer);
Expand Down Expand Up @@ -639,7 +640,7 @@ void Renderer::updateUniforms() {
auto view = glm::inverse(translation * rotation);

data.view_mat = view;
data.proj_mat = glm::perspective(glm::radians(camera.fov), static_cast<float>(width) / static_cast<float>(height),
data.proj_mat = glm::perspective(glm::radians(camera.fov) / 2.0f, static_cast<float>(width) / static_cast<float>(height),
camera.nearPlane,
camera.farPlane) * view;

Expand Down
36 changes: 32 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ FetchContent_Declare(spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.13.0
)
FetchContent_MakeAvailable(spdlog)
FetchContent_GetProperties(spdlog)
if (NOT spdlog_POPULATED)
FetchContent_Populate(spdlog)
add_subdirectory(${spdlog_SOURCE_DIR} ${spdlog_BINARY_DIR})
endif()

FetchContent_Declare(imgui
GIT_REPOSITORY https://github.com/ocornut/imgui.git
Expand Down Expand Up @@ -89,21 +93,45 @@ if (APPLE)
list(APPEND GLSLC_DEFINE "-DAPPLE")
endif ()

add_executable(embedfile cmake/embedfile.c)

set(SHADER_HEADER "${PROJECT_BINARY_DIR}/shaders/shaders.h")
message(STATUS "Shader header file: ${SHADER_HEADER}")

# Delete old header file
add_custom_command(
OUTPUT ${SHADER_HEADER}
COMMAND ${CMAKE_COMMAND} -E remove ${SHADER_HEADER}
DEPENDS ${GLSL_SOURCE_FILES}
)

foreach (GLSL ${GLSL_SOURCE_FILES})
get_filename_component(FILE_NAME ${GLSL} NAME)
get_filename_component(FILE_NAME ${GLSL} NAME_WE)
string(TOUPPER ${FILE_NAME} FILE_NAME_UPPER)
set(FILE_NAME_UPPER "SPV_${FILE_NAME_UPPER}")
set(SPIRV "${PROJECT_BINARY_DIR}/shaders/${FILE_NAME}.spv")
SET(TEMP_HEADER "${PROJECT_BINARY_DIR}/shaders/${FILE_NAME}.h")
add_custom_command(
OUTPUT ${SPIRV}
COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/shaders/"
COMMAND ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE} "--target-env" "vulkan1.2" -V ${GLSL} -o ${SPIRV} ${GLSLC_DEFINE}
DEPENDS ${GLSL})
list(APPEND SPIRV_BINARY_FILES ${SPIRV})

add_custom_command(
OUTPUT ${SHADER_HEADER}
COMMAND embedfile ${FILE_NAME_UPPER} ${SPIRV} ${SHADER_HEADER}
DEPENDS ${SPIRV}
APPEND)

list(APPEND TEMP_HEADERS ${TEMP_HEADER})
endforeach (GLSL)

add_custom_target(
Shaders
DEPENDS ${SPIRV_BINARY_FILES}
DEPENDS ${SPIRV_BINARY_FILES} ${SHADER_HEADER}
)
include_directories(${PROJECT_BINARY_DIR}/shaders)

include_directories(third_party)

Expand Down Expand Up @@ -154,7 +182,7 @@ target_include_directories(vulkan_splatting PUBLIC
${spdlog_SOURCE_DIR}/include
)

target_link_libraries(vulkan_splatting PUBLIC glfw libenvpp::libenvpp)
target_link_libraries(vulkan_splatting PUBLIC glfw libenvpp::libenvpp spdlog::spdlog)
target_link_libraries(vulkan_splatting PUBLIC Vulkan::Vulkan)
if (UNIX)
target_link_libraries(vulkan_splatting PUBLIC ${CMAKE_DL_LIBS})
Expand Down
47 changes: 47 additions & 0 deletions cmake/embedfile.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <stdlib.h>
#include <stdio.h>

FILE* open_or_exit(const char* fname, const char* mode)
{
FILE* f = fopen(fname, mode);
if (f == NULL) {
perror(fname);
exit(EXIT_FAILURE);
}
return f;
}

int main(int argc, char** argv)
{
if (argc < 3) {
fprintf(stderr, "USAGE: %s {sym} {rsrc}\n\n"
" Creates {sym}.c from the contents of {rsrc}\n",
argv[0]);
return EXIT_FAILURE;
}

const char* sym = argv[1];
FILE* in = open_or_exit(argv[2], "rb");
FILE* out = open_or_exit(argv[3], "a");
fprintf(out, "static const unsigned char %s[] = {\n", sym);

unsigned char buf[256];
size_t nread = 0;
size_t linecount = 0;
do {
nread = fread(buf, 1, sizeof(buf), in);
size_t i;
for (i=0; i < nread; i++) {
fprintf(out, "0x%02x, ", buf[i]);
if (++linecount == 10) { fprintf(out, "\n"); linecount = 0; }
}
} while (nread > 0);
if (linecount > 0) fprintf(out, "\n");
fprintf(out, "};\n");
fprintf(out, "static const size_t %s_len = sizeof(%s);\n\n",sym,sym);

fclose(in);
fclose(out);

return EXIT_SUCCESS;
}
19 changes: 12 additions & 7 deletions vulkan/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
#include "Utils.h"

void Shader::load() {
auto filename = "shaders/" + name + ".comp.spv";
auto shader_code = Utils::readFile(filename);
if (shader_code.empty()) {
throw std::runtime_error("Failed to load shader: " + filename);
}
vk::ShaderModuleCreateInfo create_info;
create_info.codeSize = shader_code.size();
create_info.pCode = reinterpret_cast<const uint32_t *>(shader_code.data());
if (data == nullptr) {
auto fn = "shaders/" + filename + ".spv";
auto shader_code = Utils::readFile(fn);
if (shader_code.empty()) {
throw std::runtime_error("Failed to load shader: " + fn);
}
create_info.codeSize = shader_code.size();
create_info.pCode = reinterpret_cast<const uint32_t *>(shader_code.data());
} else {
create_info.codeSize = size;
create_info.pCode = reinterpret_cast<const uint32_t *>(data);
}
shader = context->device->createShaderModuleUnique(create_info);
}
22 changes: 19 additions & 3 deletions vulkan/Shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,33 @@

class Shader {
public:
Shader(const std::shared_ptr<VulkanContext>& _context, std::string name)
Shader(const std::shared_ptr<VulkanContext>& _context, std::string filename)
: context(_context),
name(std::move(name)) {
filename(std::move(filename)) {
}

Shader(const std::shared_ptr<VulkanContext>& _context, const unsigned char * data, size_t size)
: context(_context),
filename(""),
data(data),
size(size) {
}

Shader(const std::shared_ptr<VulkanContext>& context, const std::string& filename, const unsigned char * data, size_t size)
: filename(filename),
context(context),
data(data),
size(size) {
}

void load();

vk::UniqueShaderModule shader;
private:
const std::string name;
const std::string filename;
std::shared_ptr<VulkanContext> context;
const unsigned char* data = nullptr;
size_t size;
};


Expand Down
6 changes: 3 additions & 3 deletions vulkan/pipelines/ComputePipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

#include "ComputePipeline.h"

ComputePipeline::ComputePipeline(const std::shared_ptr<VulkanContext> &context, const std::string &shaderFile) : Pipeline(context), shader(context, shaderFile) {
shader.load();
ComputePipeline::ComputePipeline(const std::shared_ptr<VulkanContext>& context, std::shared_ptr<Shader> shader): Pipeline(context), shader(std::move(shader)) {
this->shader->load();
}

void ComputePipeline::build() {
buildPipelineLayout();

vk::PipelineShaderStageCreateInfo pipelineShaderStageCreateInfo({}, vk::ShaderStageFlagBits::eCompute, shader.shader.get(), "main");
vk::PipelineShaderStageCreateInfo pipelineShaderStageCreateInfo({}, vk::ShaderStageFlagBits::eCompute, shader->shader.get(), "main");
vk::ComputePipelineCreateInfo computePipelineCreateInfo({}, pipelineShaderStageCreateInfo, pipelineLayout.get());
pipeline = context->device->createComputePipelineUnique(nullptr, computePipelineCreateInfo).value;
}
5 changes: 3 additions & 2 deletions vulkan/pipelines/ComputePipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@


#include "Pipeline.h"
#include <memory>

class ComputePipeline : public Pipeline {
public:
explicit ComputePipeline(const std::shared_ptr<VulkanContext> &context, const std::string& shader);
explicit ComputePipeline(const std::shared_ptr<VulkanContext> &context, std::shared_ptr<Shader> shader);;

void build() override;
private:
Shader shader;
std::shared_ptr<Shader> shader;
};


Expand Down