Skip to content

Commit

Permalink
Separate functionality of render targets and managed swapchain
Browse files Browse the repository at this point in the history
  • Loading branch information
shg8 committed Apr 3, 2024
1 parent 89d1a1b commit 683d863
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 140 deletions.
4 changes: 1 addition & 3 deletions apps/viewer/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,10 @@ int main(int argc, char** argv)
auto width = widthFlag ? args::get(widthFlag) : 1280;
auto height = heightFlag ? args::get(heightFlag) : 720;

config.renderingTarget = VulkanSplatting::createGlfwWindow("Vulkan Splatting", width, height);

#ifndef DEBUG
try {
#endif
auto renderer = VulkanSplatting(config);
auto renderer = VulkanSplatting(std::move(config), VulkanSplatting::createGlfwWindow("Vulkan Splatting", width, height, config.immediateSwapchain));
renderer.start();
#ifndef DEBUG
} catch (const std::exception& e) {
Expand Down
7 changes: 3 additions & 4 deletions include/3dgs/3dgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ class VulkanSplatting {
float near = 0.2f;
float far = 1000.0f;
bool enableGui = false;

std::shared_ptr<RenderTarget> renderingTarget;
};

explicit VulkanSplatting(RendererConfiguration configuration) : configuration(configuration) {}
explicit VulkanSplatting(RendererConfiguration configuration, std::shared_ptr<RenderTarget> renderTarget);

#ifdef VKGS_ENABLE_GLFW
static std::shared_ptr<RenderTarget> createGlfwWindow(std::string name, int width, int height);
static std::shared_ptr<RenderTarget> createGlfwWindow(std::string name, int width, int height, bool immediate);
#endif

#ifdef VKGS_ENABLE_METAL
Expand Down Expand Up @@ -61,6 +59,7 @@ class VulkanSplatting {
private:
RendererConfiguration configuration;
std::shared_ptr<Renderer> renderer;
std::weak_ptr<RenderTarget> renderTarget;
};

#endif //VULKANSPLATTING_H
18 changes: 13 additions & 5 deletions src/3dgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@

#ifdef VKGS_ENABLE_GLFW
#include "vulkan/targets/GLFWWindow.h"
std::shared_ptr<RenderTarget> VulkanSplatting::createGlfwWindow(std::string name, int width, int height) {
return std::make_shared<GLFWWindow>(name, width, height);

VulkanSplatting::VulkanSplatting(RendererConfiguration configuration,
std::shared_ptr<RenderTarget> renderTarget) : configuration(configuration),
renderTarget(renderTarget),
renderer(std::make_shared<Renderer>(
configuration, renderTarget)) {

}

std::shared_ptr<RenderTarget> VulkanSplatting::createGlfwWindow(std::string name, int width, int height, bool immediate) {
return std::make_shared<GLFWWindow>(name, width, height, immediate);
}
#endif

Expand All @@ -23,13 +32,11 @@ std::shared_ptr<RenderTarget> VulkanSplatting::createOpenXRRenderTarget(OpenXRCo

void VulkanSplatting::start() {
// Create the renderer
renderer = std::make_shared<Renderer>(configuration);
renderer->initialize();
renderer->run();
}

void VulkanSplatting::initialize() {
renderer = std::make_shared<Renderer>(configuration);
renderer->initialize();
}

Expand All @@ -38,7 +45,8 @@ void VulkanSplatting::draw() {
}

void VulkanSplatting::logTranslation(float x, float y) {
configuration.renderingTarget->logTranslation(x, y);
if (auto rt = renderTarget.lock())
rt->logTranslation(x, y);
}

void VulkanSplatting::logMovement(float x, float y, float z) {
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ add_library(3dgs_cpp STATIC
${EXTERNAL_SOURCE}
vulkan/targets/OpenXRStereo.cpp
vulkan/targets/OpenXRStereo.h
vulkan/targets/ManagedSwapchain.cpp
vulkan/targets/ManagedSwapchain.h
)

target_include_directories(3dgs_cpp
Expand Down
53 changes: 27 additions & 26 deletions src/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <spdlog/spdlog.h>

#include "vulkan/targets/ManagedSwapchain.h"
#include "vulkan/targets/OpenXRStereo.h"

void Renderer::initialize() {
Expand All @@ -33,12 +34,12 @@ void Renderer::initialize() {
}

void Renderer::handleInput() {
auto translation = window->getCursorTranslation();
auto keys = window->getKeys(); // W, A, S, D
auto translation = renderTarget->getCursorTranslation();
auto keys = renderTarget->getKeys(); // W, A, S, D

if ((!configuration.enableGui || (!guiManager.wantCaptureMouse() && !guiManager.mouseCapture)) && window->
if ((!configuration.enableGui || (!guiManager.wantCaptureMouse() && !guiManager.mouseCapture)) && renderTarget->
getMouseButton()[0]) {
window->mouseCapture(true);
renderTarget->mouseCapture(true);
guiManager.mouseCapture = true;
}

Expand Down Expand Up @@ -74,7 +75,7 @@ void Renderer::handleInput() {
direction += glm::vec3(0.0f, -1.0f, 0.0f);
}
if (keys[6]) {
window->mouseCapture(false);
renderTarget->mouseCapture(false);
guiManager.mouseCapture = false;
}
if (direction != glm::vec3(0.0f, 0.0f, 0.0f)) {
Expand Down Expand Up @@ -102,7 +103,7 @@ void Renderer::retrieveTimestamps() {
}

void Renderer::recreatePipelines() {
auto [width, height] = swapchain->currentExtent();
auto [width, height] = renderTarget->currentExtent();
auto tileX = (width + 16 - 1) / 16;
auto tileY = (height + 16 - 1) / 16;
tileBoundaryBuffer->realloc(tileX * tileY * sizeof(uint32_t) * 2);
Expand All @@ -114,14 +115,14 @@ void Renderer::recreatePipelines() {

void Renderer::initializeVulkan() {
spdlog::debug("Initializing Vulkan");
window = configuration.renderingTarget;
context = std::make_shared<VulkanContext>(window->getRequiredInstanceExtensions(), window->getRequiredDeviceExtensions(),

context = std::make_shared<VulkanContext>(renderTarget->getRequiredInstanceExtensions(), renderTarget->getRequiredDeviceExtensions(),
configuration.enableVulkanValidationLayers);

context->createInstance();
auto surface = static_cast<vk::SurfaceKHR>(window->createSurface(context));
if (auto requiredPhysicalDevice = window->requirePhysicalDevice(context->instance.get());
if (auto requiredPhysicalDevice = renderTarget->requirePhysicalDevice(context->instance.get());
!requiredPhysicalDevice.has_value()) {
auto surface = std::dynamic_pointer_cast<ManagedSwapchain>(renderTarget)->createSurface(context);
context->selectPhysicalDevice(configuration.physicalDeviceId, surface);
} else {
context->physicalDevice = requiredPhysicalDevice.value();
Expand All @@ -142,7 +143,8 @@ void Renderer::initializeVulkan() {
context->createLogicalDevice(pdf, pdf11, pdf12);
context->createDescriptorPool(1);

swapchain = std::make_shared<Swapchain>(context, window, configuration.immediateSwapchain);
if (auto managedSwapchain = std::dynamic_pointer_cast<ManagedSwapchain>(renderTarget))
managedSwapchain->setup(context);

for (int i = 0; i < FRAMES_IN_FLIGHT; i++) {
inflightFences.emplace_back(
Expand All @@ -154,7 +156,7 @@ void Renderer::initializeVulkan() {
renderFinishedSemaphores[i] = context->device->createSemaphoreUnique(vk::SemaphoreCreateInfo());
}

if (auto openXRBackend = std::dynamic_pointer_cast<OpenXRStereo>(window)) {
if (auto openXRBackend = std::dynamic_pointer_cast<OpenXRStereo>(renderTarget)) {
openXRBackend->postVulkanInit(context->instance.get(), context->physicalDevice, context->device.get(),
context->queues[VulkanContext::Queue::GRAPHICS].queueFamily,
context->queues[VulkanContext::Queue::GRAPHICS].queueIndex);
Expand Down Expand Up @@ -202,7 +204,7 @@ void Renderer::createPreprocessPipeline() {
preprocessPipeline->build();
}

Renderer::Renderer(VulkanSplatting::RendererConfiguration configuration) : configuration(std::move(configuration)) {
Renderer::Renderer(VulkanSplatting::RendererConfiguration configuration, std::shared_ptr<RenderTarget> renderTarget) : configuration(std::move(configuration)), renderTarget(std::move(renderTarget)) {
}

void Renderer::createGui() {
Expand All @@ -212,7 +214,7 @@ void Renderer::createGui() {

spdlog::debug("Creating GUI");

imguiManager = std::make_shared<ImguiManager>(context, swapchain, window);
imguiManager = std::make_shared<ImguiManager>(context, renderTarget);
imguiManager->init();
guiManager.init();
}
Expand Down Expand Up @@ -322,7 +324,7 @@ void Renderer::createPreprocessSortPipeline() {

void Renderer::createTileBoundaryPipeline() {
spdlog::debug("Creating tile boundary pipeline");
auto [width, height] = swapchain->currentExtent();
auto [width, height] = renderTarget->currentExtent();
auto tileX = (width + 16 - 1) / 16;
auto tileY = (height + 16 - 1) / 16;
tileBoundaryBuffer = Buffer::storage(context, tileX * tileY * sizeof(uint32_t) * 2, false);
Expand Down Expand Up @@ -359,7 +361,7 @@ void Renderer::createRenderPipeline() {
inputSet->build();

auto outputSet = std::make_shared<DescriptorSet>(context, 1);
for (auto &image: swapchain->swapchainImages) {
for (auto &image: renderTarget->swapchainImages) {
outputSet->bindImageToDescriptorSet(0, vk::DescriptorType::eStorageImage, vk::ShaderStageFlagBits::eCompute,
image);
}
Expand All @@ -377,16 +379,15 @@ void Renderer::draw() {
}
context->device->resetFences(inflightFences[0].get());

auto [optionalImageIndex, extentChanged] = swapchain->acquireNextImage();
auto [optionalImageIndex, extentChanged] = renderTarget->acquireNextImage();
if (extentChanged) {
recreatePipelines();
}

if (!optionalImageIndex.has_value()) {
return;
} else {
currentImageIndex = optionalImageIndex.value();
}
currentImageIndex = optionalImageIndex.value();

startOfRenderLoop:
handleInput();
Expand All @@ -406,13 +407,13 @@ void Renderer::draw() {
goto startOfRenderLoop;
}
vk::PipelineStageFlags waitStage = vk::PipelineStageFlagBits::eComputeShader;
submitInfo = vk::SubmitInfo{}.setWaitSemaphores(swapchain->imageAvailableSemaphores[0].get())
submitInfo = vk::SubmitInfo{}.setWaitSemaphores(renderTarget->imageAvailableSemaphores[0].get())
.setCommandBuffers(renderCommandBuffer.get())
.setSignalSemaphores(renderFinishedSemaphores[0].get())
.setWaitDstStageMask(waitStage);
context->queues[VulkanContext::Queue::COMPUTE].queue.submit(submitInfo, inflightFences[0].get());

extentChanged = swapchain->present(std::vector<vk::Semaphore>{renderFinishedSemaphores[0].get()}, currentImageIndex);
extentChanged = renderTarget->present(std::vector<vk::Semaphore>{renderFinishedSemaphores[0].get()}, currentImageIndex);

if (extentChanged) {
recreatePipelines();
Expand All @@ -421,7 +422,7 @@ void Renderer::draw() {

void Renderer::run() {
while (running) {
if (!window->tick()) {
if (!renderTarget->tick()) {
break;
}

Expand Down Expand Up @@ -573,7 +574,7 @@ bool Renderer::recordRenderCommandBuffer(uint32_t currentFrame) {
preprocessSortPipeline->bind(renderCommandBuffer, 0, iters % 2 == 0 ? 0 : 1);
renderCommandBuffer->writeTimestamp(vk::PipelineStageFlagBits::eComputeShader, context->queryPool.get(),
queryManager->registerQuery("preprocess_sort_start"));
uint32_t tileX = (swapchain->currentExtent().width + 16 - 1) / 16;
uint32_t tileX = (renderTarget->currentExtent().width + 16 - 1) / 16;
// assert(tileX == 50);
renderCommandBuffer->pushConstants(preprocessSortPipeline->pipelineLayout.get(),
vk::ShaderStageFlagBits::eCompute, 0,
Expand Down Expand Up @@ -648,7 +649,7 @@ bool Renderer::recordRenderCommandBuffer(uint32_t currentFrame) {
renderPipeline->bind(renderCommandBuffer, 0, std::vector<uint32_t>{0, currentImageIndex});
renderCommandBuffer->writeTimestamp(vk::PipelineStageFlagBits::eComputeShader, context->queryPool.get(),
queryManager->registerQuery("render_start"));
auto [width, height] = swapchain->currentExtent();
auto [width, height] = renderTarget->currentExtent();
uint32_t constants[2] = {width, height};
renderCommandBuffer->pushConstants(renderPipeline->pipelineLayout.get(),
vk::ShaderStageFlagBits::eCompute, 0,
Expand All @@ -658,7 +659,7 @@ bool Renderer::recordRenderCommandBuffer(uint32_t currentFrame) {
vk::ImageMemoryBarrier imageMemoryBarrier{};
imageMemoryBarrier.oldLayout = vk::ImageLayout::eUndefined;
imageMemoryBarrier.newLayout = vk::ImageLayout::eGeneral;
imageMemoryBarrier.image = swapchain->swapchainImages[currentImageIndex]->image;
imageMemoryBarrier.image = renderTarget->swapchainImages[currentImageIndex]->image;
imageMemoryBarrier.subresourceRange = {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1};
imageMemoryBarrier.srcAccessMask = vk::AccessFlagBits::eNoneKHR;
imageMemoryBarrier.dstAccessMask = vk::AccessFlagBits::eShaderWrite;
Expand Down Expand Up @@ -712,7 +713,7 @@ bool Renderer::recordRenderCommandBuffer(uint32_t currentFrame) {

void Renderer::updateUniforms() {
UniformBuffer data{};
auto [width, height] = swapchain->currentExtent();
auto [width, height] = renderTarget->currentExtent();
data.width = width;
data.height = height;
data.camera_position = glm::vec4(camera.position, 1.0f);
Expand Down
10 changes: 4 additions & 6 deletions src/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "vulkan/ImguiManager.h"
#include "vulkan/QueryManager.h"



class Renderer {
public:
struct alignas(16) UniformBuffer {
Expand Down Expand Up @@ -56,7 +58,7 @@ class Renderer {
uint32_t g_num_blocks_per_workgroup; // == NUM_BLOCKS_PER_WORKGROUP
};

explicit Renderer(VulkanSplatting::RendererConfiguration configuration);
explicit Renderer(VulkanSplatting::RendererConfiguration configuration, std::shared_ptr<RenderTarget> renderTarget);

void createGui();

Expand Down Expand Up @@ -86,8 +88,8 @@ class Renderer {

private:
VulkanSplatting::RendererConfiguration configuration;
std::shared_ptr<RenderTarget> window;
std::shared_ptr<VulkanContext> context;
std::shared_ptr<RenderTarget> renderTarget;
std::shared_ptr<ImguiManager> imguiManager;
std::shared_ptr<GSScene> scene;
std::shared_ptr<QueryManager> queryManager = std::make_shared<QueryManager>();
Expand Down Expand Up @@ -120,8 +122,6 @@ class Renderer {

std::vector<vk::UniqueFence> inflightFences;

std::shared_ptr<Swapchain> swapchain;

vk::UniqueCommandPool commandPool;

vk::UniqueCommandBuffer preprocessCommandBuffer;
Expand Down Expand Up @@ -166,6 +166,4 @@ class Renderer {

void updateUniforms();
};


#endif //RENDERER_H
12 changes: 6 additions & 6 deletions src/vulkan/ImguiManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

#include "targets/GLFWWindow.h"

ImguiManager::ImguiManager(std::shared_ptr<VulkanContext> context, std::shared_ptr<Swapchain> swapchain,
std::shared_ptr<RenderTarget> window) : context(context), swapchain(swapchain), window(window) {
ImguiManager::ImguiManager(std::shared_ptr<VulkanContext> context,
std::shared_ptr<RenderTarget> window) : context(context), window(window) {
}

void ImguiManager::createCommandPool() {
Expand Down Expand Up @@ -129,11 +129,11 @@ void ImguiManager::init() {
init_info.Queue = context->queues[VulkanContext::Queue::GRAPHICS].queue;
init_info.DescriptorPool = descriptorPool.get();
init_info.MinImageCount = 2;
init_info.ImageCount = swapchain->imageCount + 1;
init_info.ImageCount = window->imageCount + 1;
init_info.UseDynamicRendering = true;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.PipelineRenderingCreateInfo = vk::PipelineRenderingCreateInfo{
{}, 1, &swapchain->swapchainFormat
{}, 1, &window->swapchainFormat
};

ImGui_ImplVulkan_Init(&init_info);
Expand Down Expand Up @@ -169,9 +169,9 @@ void ImguiManager::draw(vk::CommandBuffer commandBuffer, uint32_t currentImageIn
ImGui::Render();

vk::RenderingAttachmentInfoKHR attachment_info{
swapchain->swapchainImages[currentImageIndex]->imageView.get(), vk::ImageLayout::eColorAttachmentOptimal
window->swapchainImages[currentImageIndex]->imageView.get(), vk::ImageLayout::eColorAttachmentOptimal
};
vk::RenderingInfoKHR rendering_info{{}, vk::Rect2D{{0, 0}, swapchain->currentExtent()}, 1, {}, 1, &attachment_info};
vk::RenderingInfoKHR rendering_info{{}, vk::Rect2D{{0, 0}, window->currentExtent()}, 1, {}, 1, &attachment_info};
commandBuffer.beginRenderingKHR(rendering_info);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffer);
commandBuffer.endRenderingKHR();
Expand Down
3 changes: 1 addition & 2 deletions src/vulkan/ImguiManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class ImguiManager {
public:
ImguiManager(std::shared_ptr<VulkanContext> context, std::shared_ptr<Swapchain> swapchain, std::shared_ptr<RenderTarget> window);
ImguiManager(std::shared_ptr<VulkanContext> context, std::shared_ptr<RenderTarget> window);

void createCommandPool();

Expand All @@ -24,7 +24,6 @@ class ImguiManager {

private:
std::shared_ptr<VulkanContext> context;
std::shared_ptr<Swapchain> swapchain;
std::shared_ptr<RenderTarget> window;
vk::UniqueCommandPool commandPool;
vk::UniqueCommandBuffer commandBuffer;
Expand Down
Loading

0 comments on commit 683d863

Please sign in to comment.