Skip to content

Commit

Permalink
WIP threaded rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
Supercomet committed Sep 26, 2023
1 parent 8facdbc commit 19ec1b6
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 88 deletions.
203 changes: 122 additions & 81 deletions Application/src/TestApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,6 @@ struct EntityInfo
void SyncToGraphicsWorld()
{
auto& gfxWorldObjectInstance = gs_GraphicsWorld.GetObjectInstance(gfxID);
gfxWorldObjectInstance.position = position;
gfxWorldObjectInstance.scale = scale;
gfxWorldObjectInstance.rot = rot;
gfxWorldObjectInstance.rotVec = rotVec;
gfxWorldObjectInstance.localToWorld = getLocalToWorld();
gfxWorldObjectInstance.flags = flags;
}
Expand Down Expand Up @@ -205,10 +201,6 @@ void CreateGraphicsEntityHelper(EntityInfo& ei)
//UpdateBV(gs_RenderEngine->models[e.modelID].cpuModel, e);
ObjectInstance o{};
o.name = ei.name;
o.position = ei.position;
o.scale = ei.scale;
o.rot = ei.rot;
o.rotVec = ei.rotVec;
o.bindlessGlobalTextureIndex_Albedo = ei.bindlessGlobalTextureIndex_Albedo;
o.bindlessGlobalTextureIndex_Normal = ei.bindlessGlobalTextureIndex_Normal;
o.bindlessGlobalTextureIndex_Roughness = ei.bindlessGlobalTextureIndex_Roughness;
Expand Down Expand Up @@ -737,6 +729,40 @@ void TestApplication::Run()

gs_GraphicsWorld.m_HardcodedDecalInstance.position = glm::vec3{ 0.0f,0.0f,0.0f };

std::mutex g_ImguiMutex;

bool renderMe = true;
auto renderWorker = [renderer = gs_RenderEngine, &keepRendering = renderMe, &mut = g_ImguiMutex]() {
OPTICK_THREAD("RenderThread");
auto lastTime = std::chrono::high_resolution_clock::now();
while (keepRendering == true)
{
PROFILE_FRAME("RENDER LOOP");
auto now = std::chrono::high_resolution_clock::now();
float deltaTime = std::chrono::duration<float>(now - lastTime).count();
lastTime = now;

renderer->renderClock += deltaTime;
renderer->deltaTime = deltaTime;



if (renderer->PrepareFrame() == true)
{
renderer->RenderFrame();

mut.lock();
renderer->DrawGUI();
mut.unlock();

renderer->Present();
}

}

};

std::thread renderThread(renderWorker);
//----------------------------------------------------------------------------------------------------
// Application Loop
//----------------------------------------------------------------------------------------------------
Expand All @@ -754,8 +780,8 @@ void TestApplication::Run()
m_ApplicationTimer += deltaTime;
m_ApplicationDT = deltaTime;
// Pass frame information to the render engine
gs_RenderEngine->renderClock += deltaTime;
gs_RenderEngine->deltaTime = deltaTime;
// gs_RenderEngine->renderClock += deltaTime;
// gs_RenderEngine->deltaTime = deltaTime;

//reset keys
Input::Begin();
Expand All @@ -773,14 +799,17 @@ void TestApplication::Run()
// If the aspect ratio changes, then the projection matrix must be updated correctly...
camera.SetAspectRatio((float)mainWindow.m_width / (float)mainWindow.m_height);
gs_CameraController.Update(deltaTime);
}
}


{
PROFILE_SCOPED("ImGui::NewFrame");
g_ImguiMutex.lock();
ImGui_ImplVulkan_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
}
}


{
PROFILE_SCOPED("ImGui::Update");
Expand Down Expand Up @@ -858,79 +887,81 @@ void TestApplication::Run()

}

if (gs_RenderEngine->PrepareFrame() == true)
{
PROFILE_SCOPED("gs_RenderEngine->PrepareFrame() == true");

if (s_freezeLight == false)
{
OmniLightInstance* lights[hardCodedLights];
for (size_t i = 0; i < hardCodedLights; i++)
// if (gs_RenderEngine->PrepareFrame() == true)
// {
// PROFILE_SCOPED("gs_RenderEngine->PrepareFrame() == true");
//
// if (s_freezeLight == false)
// {
// OmniLightInstance* lights[hardCodedLights];
// for (size_t i = 0; i < hardCodedLights; i++)
// {
// lights[i] = &gs_GraphicsWorld.GetLightInstance(someLights[i]);
// }
//
//
// static float lightTimer = 0.0f;
// lightTimer += deltaTime * 0.25f;
//
//
// lights[0]->position.x = sin(glm::radians(360.0f * lightTimer)) * 5.0f;
// lights[0]->position.z = cos(glm::radians(360.0f * lightTimer)) * 5.0f;
//
// lights[1]->position.x = -4.0f + sin(glm::radians(360.0f * lightTimer) + 45.0f) * 2.0f;
// lights[1]->position.z = 0.0f + cos(glm::radians(360.0f * lightTimer) + 45.0f) * 2.0f;
//
// lights[2]->position.x = 4.0f + sin(glm::radians(360.0f * lightTimer)) * 2.0f;
// lights[2]->position.z = 0.0f + cos(glm::radians(360.0f * lightTimer)) * 2.0f;
//
// lights[4]->position.x = 0.0f + sin(glm::radians(360.0f * lightTimer + 90.0f)) * 5.0f;
// lights[4]->position.z = 0.0f - cos(glm::radians(360.0f * lightTimer + 45.0f)) * 5.0f;
//
// lights[5]->position.x = 0.0f + sin(glm::radians(-360.0f * lightTimer + 135.0f)) * 10.0f;
// lights[5]->position.z = 0.0f - cos(glm::radians(-360.0f * lightTimer - 45.0f)) * 10.0f;
//
// }
//
// // We need to test debug draw...
RunTest_DebugDraw();
//
// // Render the frame
// gs_RenderEngine->RenderFrame();
//
// Create a dockspace over the mainviewport so that we can dock stuff
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(),
ImGuiDockNodeFlags_PassthruCentralNode // make the dockspace transparent
| ImGuiDockNodeFlags_NoDockingInCentralNode // dont allow docking in the central area
);
//
// if (m_ShowImGuiDemoWindow)
// {
// PROFILE_SCOPED("ImGui::ShowDemoWindow");
// ImGui::ShowDemoWindow();
// }
//
// ImGuizmo
Tool_HandleGizmoManipulation();

// Display ImGui Window
{
lights[i] = &gs_GraphicsWorld.GetLightInstance(someLights[i]);
PROFILE_SCOPED("ImGuiSceneHelper");
Tool_HandleUI();
}
//
// {
// PROFILE_SCOPED("ImGui::Render");
// ImGui::Render(); // Rendering UI
// }
// gs_RenderEngine->DrawGUI();
//
// gs_RenderEngine->Present();
// }


static float lightTimer = 0.0f;
lightTimer += deltaTime * 0.25f;


lights[0]->position.x = sin(glm::radians(360.0f * lightTimer)) * 5.0f;
lights[0]->position.z = cos(glm::radians(360.0f * lightTimer)) * 5.0f;

lights[1]->position.x = -4.0f + sin(glm::radians(360.0f * lightTimer) + 45.0f) * 2.0f;
lights[1]->position.z = 0.0f + cos(glm::radians(360.0f * lightTimer) + 45.0f) * 2.0f;

lights[2]->position.x = 4.0f + sin(glm::radians(360.0f * lightTimer)) * 2.0f;
lights[2]->position.z = 0.0f + cos(glm::radians(360.0f * lightTimer)) * 2.0f;

lights[4]->position.x = 0.0f + sin(glm::radians(360.0f * lightTimer + 90.0f)) * 5.0f;
lights[4]->position.z = 0.0f - cos(glm::radians(360.0f * lightTimer + 45.0f)) * 5.0f;

lights[5]->position.x = 0.0f + sin(glm::radians(-360.0f * lightTimer + 135.0f)) * 10.0f;
lights[5]->position.z = 0.0f - cos(glm::radians(-360.0f * lightTimer - 45.0f)) * 10.0f;

}

// Upload CPU light data to GPU. Ideally this should only contain lights that intersects the camera frustum.
gs_RenderEngine->UploadLights();

// We need to test debug draw...
RunTest_DebugDraw();

// Render the frame
gs_RenderEngine->RenderFrame();

// Create a dockspace over the mainviewport so that we can dock stuff
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(),
ImGuiDockNodeFlags_PassthruCentralNode // make the dockspace transparent
| ImGuiDockNodeFlags_NoDockingInCentralNode // dont allow docking in the central area
);

if (m_ShowImGuiDemoWindow)
{
PROFILE_SCOPED("ImGui::ShowDemoWindow");
ImGui::ShowDemoWindow();
}

// ImGuizmo
Tool_HandleGizmoManipulation();

// Display ImGui Window
{
PROFILE_SCOPED("ImGuiSceneHelper");
Tool_HandleUI();
}

{
PROFILE_SCOPED("ImGui::Render");
ImGui::Render(); // Rendering UI
}
gs_RenderEngine->DrawGUI();

gs_RenderEngine->Present();
{
PROFILE_SCOPED("ImGui::Render");
ImGui::Render(); // Rendering UI
g_ImguiMutex.unlock();
}

//finish for all windows
ImGui::EndFrame();
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
Expand All @@ -939,12 +970,22 @@ void TestApplication::Run()
ImGui::RenderPlatformWindowsDefault();
}

//finish for all windows
// ImGui::EndFrame();
// if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
// {
// ImGui::UpdatePlatformWindows();
// ImGui::RenderPlatformWindowsDefault();
// }

}
}

//----------------------------------------------------------------------------------------------------
// Application Shutdown
//----------------------------------------------------------------------------------------------------
renderMe = false;
renderThread.join();

gs_RenderEngine->DestroyWorld(&gs_GraphicsWorld);
gs_RenderEngine->DestroyImGUI();
Expand Down
27 changes: 27 additions & 0 deletions OO_Vulkan/src/GraphicsWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@ Technology is prohibited.
void GraphicsWorld::BeginFrame()
{
// TODO: What do you do at the beginning of the frame?
m_objectsCopy.clear();
m_objectsCopy.reserve(m_ObjectInstances.size());
for (const ObjectInstance& src: m_ObjectInstances)
{
m_objectsCopy.emplace_back(src);
}

m_EmitterCopy.clear();
m_EmitterCopy.reserve(m_EmitterInstances.size());
for (const EmitterInstance& src: m_EmitterInstances)
{
m_EmitterCopy.emplace_back(src);
}

m_UIcopy.clear();
m_UIcopy.reserve(m_UIInstances.size());
for (const UIInstance& src: m_UIInstances)
{
m_UIcopy.emplace_back(src);
}

m_OmniLightCopy.clear();
m_OmniLightCopy.reserve(m_OmniLightInstances.size());
for (const OmniLightInstance& src: m_OmniLightInstances)
{
m_OmniLightCopy.emplace_back(src);
}
}

void GraphicsWorld::EndFrame()
Expand Down
11 changes: 5 additions & 6 deletions OO_Vulkan/src/GraphicsWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@ ENUM_OPERATORS_GEN(UIInstanceFlags, uint32_t)
struct ObjectInstance
{
std::string name;
// Begin These are temp until its fully integrated
glm::vec3 position{};
glm::vec3 scale{1.0f};
float rot{};
glm::vec3 rotVec{0.0f,1.0f,0.0f};

uint32_t bindlessGlobalTextureIndex_Albedo{ 0xFFFFFFFF };
uint32_t bindlessGlobalTextureIndex_Normal{ 0xFFFFFFFF };
Expand Down Expand Up @@ -285,6 +280,7 @@ class GraphicsWorld
}vignetteSettings{};

friend class VulkanRenderer;
friend class GraphicsBatch;
private:
int32_t m_entityCount{};
BitContainer<ObjectInstance> m_ObjectInstances;
Expand All @@ -297,7 +293,10 @@ class GraphicsWorld
bool initialized = false;

//etc

std::vector<ObjectInstance> m_objectsCopy;
std::vector<UIInstance> m_UIcopy;
std::vector<OmniLightInstance> m_OmniLightCopy;
std::vector<EmitterInstance> m_EmitterCopy;
// + Spatial Acceleration Structures
// + Culling object BV against frustum
};
7 changes: 6 additions & 1 deletion OO_Vulkan/src/VulkanRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,11 @@ void VulkanRenderer::DrawGUI()
}
}
vkCmdBeginRenderPass(cmdlist, &GUIpassInfo, VK_SUBPASS_CONTENTS_INLINE);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmdlist);
auto* drawData = ImGui::GetDrawData();
if (drawData)
{
ImGui_ImplVulkan_RenderDrawData(drawData, cmdlist);
}
vkCmdEndRenderPass(cmdlist);

for (size_t i = 0; i < renderTargets.size(); i++)
Expand Down Expand Up @@ -2274,6 +2278,7 @@ void VulkanRenderer::BeginDraw()

if (currWorld)
{
currWorld->BeginFrame();
batches = GraphicsBatch::Init(currWorld, this, MAX_OBJECTS);
batches.GenerateBatches();
}
Expand Down

0 comments on commit 19ec1b6

Please sign in to comment.