Restructuring renderpasses

This commit is contained in:
Dynamitos
2021-09-29 22:12:56 +02:00
parent 632d120f6d
commit bd739068d6
43 changed files with 258 additions and 800 deletions
-2
View File
@@ -29,8 +29,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/bin/Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/bin/Release)
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
if (USE_SUPERBUILD)
project (SUPERBUILD NONE)
# execute the superbuild (this script will be invoked again without the
-1
View File
@@ -6,7 +6,6 @@ target_sources(SeeleEngine
add_subdirectory(Asset/)
add_subdirectory(Containers/)
#add_subdirectory(Fibers/)
add_subdirectory(Graphics/)
add_subdirectory(Material/)
add_subdirectory(Math/)
+23 -34
View File
@@ -237,44 +237,13 @@ namespace Seele
{
return endIt;
}
T &add(const T &item = T())
{
if (arraySize == allocated)
{
size_t newSize = arraySize + 1;
allocated = calculateGrowth(newSize);
T *tempArray = new T[allocated];
assert(tempArray != nullptr);
for (size_t i = 0; i < arraySize; ++i)
{
tempArray[i] = _data[i];
}
delete[] _data;
_data = tempArray;
}
_data[arraySize++] = item;
markIteratorDirty();
return _data[arraySize - 1];
return addInternal(item);
}
T &add(T&& item)
{
if (arraySize == allocated)
{
size_t newSize = arraySize + 1;
allocated = calculateGrowth(newSize);
T *tempArray = new T[allocated];
assert(tempArray != nullptr);
for (size_t i = 0; i < arraySize; ++i)
{
tempArray[i] = std::move(_data[i]);
}
delete[] _data;
_data = tempArray;
}
_data[arraySize++] = std::move(item);
markIteratorDirty();
return _data[arraySize - 1];
return addInternal(std::forward<T>(item));
}
T &addUnique(const T &item = T())
{
@@ -283,7 +252,7 @@ namespace Seele
{
return *it;
}
return add(item);
return addInternal(item);
}
template<typename... args>
T &emplace(args... arguments)
@@ -429,6 +398,26 @@ namespace Seele
beginIt = Iterator(_data);
endIt = Iterator(_data + arraySize);
}
template<typename Type>
T& addInternal(Type&& t)
{
if (arraySize == allocated)
{
size_t newSize = arraySize + 1;
allocated = calculateGrowth(newSize);
T *tempArray = new T[allocated];
assert(tempArray != nullptr);
for (size_t i = 0; i < arraySize; ++i)
{
tempArray[i] = std::forward<Type>(_data[i]);
}
delete[] _data;
_data = tempArray;
}
_data[arraySize++] = std::forward<Type>(t);
markIteratorDirty();
return _data[arraySize - 1];
}
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
-6
View File
@@ -1,6 +0,0 @@
#target_sources(SeeleEngine
# PRIVATE
# Fibers.h
# Fibers.cpp
# JobQueue.h
# JobQueue.cpp)
-36
View File
@@ -1,36 +0,0 @@
#include "Fibers.h"
using namespace Seele;
using namespace Seele::Fibers;
std::atomic_uint64_t FiberJob::jobIDGenerator;
Counter::Counter()
{
count.store(0);
}
Counter::Counter(uint64 initialValue)
{
count.store(initialValue);
}
Counter::~Counter()
{
}
AwaitCounter&& FiberTask::promise_type::await_transform(AwaitCounter&& awaitCounter)
{
counter = awaitCounter.counter;
target = awaitCounter.target;
priority = awaitCounter.priority;
return std::move(awaitCounter);
}
FiberJob::FiberJob()
{
}
FiberJob::~FiberJob()
{
}
-203
View File
@@ -1,203 +0,0 @@
#pragma once
#include "MinimalEngine.h"
#include "JobQueue.h"
namespace Seele
{
namespace Fibers
{
class Counter
{
public:
Counter();
Counter(uint64 initialValue);
~Counter();
inline void increment()
{
count++;
}
inline void decrement()
{
count--;
}
inline void setValue(uint64 value)
{
count.store(value);
}
inline uint64 getValue()
{
return count.load();
}
inline bool greaterEqual(uint64 target)
{
return count.load() >= target;
}
inline bool greaterThan(uint64 target)
{
return count.load() > target;
}
inline bool lessEqual(uint64 target)
{
return count.load() <= target;
}
inline bool lessThan(uint64 target)
{
return count.load() < target;
}
inline bool equals(uint64 target)
{
return count.load() == target;
}
friend std::strong_ordering operator<=>(const Counter& counter, uint64 other)
{
return counter.count.load() <=> other;
}
friend std::ostream& operator<<(std::ostream& stream, const Counter* counter)
{
stream << counter->count;
return stream;
}
friend std::ostream& operator<<(std::ostream& stream, PCounter counter)
{
stream << counter->count;
return stream;
}
private:
std::atomic_uint64_t count;
};
DEFINE_REF(Counter)
struct AwaitCounter
{
PCounter counter;
uint64 target;
JobPriority priority = JobPriority::MEDIUM;
bool await_ready() { return counter->greaterEqual(target); }
void await_suspend(std::coroutine_handle<>) {
}
void await_resume() {}
};
struct AwaitCounter;
class FiberTask
{
public:
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
private:
promise_type* promise;
public:
FiberTask() = default;
explicit FiberTask(promise_type* promise)
: promise(promise) {}
FiberTask(const FiberTask& other)
: promise(other.promise) {}
FiberTask(FiberTask&& other)
: promise(std::move(other.promise)) {}
FiberTask& operator=(const FiberTask& other)
{
promise = other.promise;
return *this;
}
FiberTask& operator=(FiberTask&& other)
{
promise = std::move(other.promise);
return *this;
}
inline void resume() { promise->resume(); }
inline void destroy() { promise->destroy(); }
inline bool done() { return promise->done(); }
inline PCounter getCounter() const { return promise->counter; }
inline uint64 getTarget() const { return promise->target; }
inline JobPriority getPriority() const { return promise->priority; }
struct promise_type
{
promise_type()
{
handle = handle_type::from_promise(*this);
}
~promise_type() = default;
promise_type(const promise_type&) = delete;
promise_type(promise_type&&) = delete;
promise_type &operator=(const promise_type&) = delete;
promise_type &operator=(promise_type&&) = delete;
FiberTask get_return_object()
{
return FiberTask(this);
}
auto initial_suspend() { return std::suspend_never{}; }
auto final_suspend() noexcept { return std::suspend_always{}; }
auto return_void() {}
void unhandled_exception() { std::exit(1); }
AwaitCounter&& await_transform(AwaitCounter&& awaitCounter);
inline void resume() { handle.resume(); }
inline void destroy() { handle.destroy(); }
inline bool done() { return handle.done(); }
private:
handle_type handle;
PCounter counter;
uint64 target;
JobPriority priority;
friend class FiberTask;
};
};
class FiberJob
{
public:
FiberJob();
template<typename func, typename... args>
FiberJob(PCounter counter, func function, args... arg)
: counter(counter), function(std::bind(function, arg...))
{
jobID = jobIDGenerator.fetch_add(1);
}
template<typename func, typename...args>
FiberJob(PCounter counter, JobPriority priority, func function, args... arg)
: counter(counter), priority(priority), function(std::bind(function, arg...))
{
}
FiberJob(const FiberJob& other) = delete;
FiberJob(FiberJob&& other)
: counter(std::move(other.counter))
, jobID(std::move(other.jobID))
, priority(std::move(other.priority))
, function(std::move(other.function))
{
}
~FiberJob();
FiberJob& operator=(const FiberJob& other) = delete;
FiberJob& operator=(FiberJob&& other)
{
if(this != &other)
{
counter = std::move(other.counter);
jobID = std::move(other.jobID);
priority = std::move(other.priority);
function = std::move(other.function);
}
return *this;
}
void operator()()
{
FiberTask task = function();
if(!task.done())
{
JobQueue::suspendJob(std::move(task));
}
else
{
counter->increment();
task.destroy();
}
}
inline JobPriority getPriority()
{
return priority;
}
private:
PCounter counter;
uint64 jobID;
static std::atomic_uint64_t jobIDGenerator;
JobPriority priority = JobPriority::MEDIUM;
std::function<FiberTask()> function;
};
} // namespace Fibers
} // namespace Seele
-134
View File
@@ -1,134 +0,0 @@
#include "JobQueue.h"
#include "Fibers.h"
#include <Windows.h>
#include <processthreadsapi.h>
using namespace Seele;
using namespace Seele::Fibers;
std::wstring toString(JobPriority priority)
{
switch (priority)
{
case JobPriority::HIGH:
return L"HIGH";
case JobPriority::MEDIUM:
return L"MEDIUM";
case JobPriority::LOW:
return L"LOW";
case JobPriority::IO:
return L"IO";
default:
return L"Illegal Priority";
}
}
Array<JobQueue*> JobQueue::workers;
StaticArray<JobPriorityInfo, (size_t)JobPriority::NUM_PRIORITIES> JobQueue::priorityQueues;
JobQueue::JobQueue(JobPriority priority)
: priority(priority)
{
threadHandle = std::thread(&JobQueue::work, this);
SetThreadDescription(threadHandle.native_handle(), toString(priority).c_str());
}
JobQueue::~JobQueue()
{
running = false;
threadHandle.join();
}
void JobQueue::initJobQueues()
{
// TODO: make this dependent on actual cores
JobPriority priorities[16] = {
JobPriority::IO, JobPriority::IO,
JobPriority::LOW, JobPriority::LOW, JobPriority::LOW, JobPriority::LOW,
JobPriority::MEDIUM, JobPriority::MEDIUM, JobPriority::MEDIUM, JobPriority::MEDIUM, JobPriority::MEDIUM,
JobPriority::HIGH, JobPriority::HIGH, JobPriority::HIGH, JobPriority::HIGH, JobPriority::HIGH};
for(uint32 i = 0; i < 16; ++i)
{
workers.add(new JobQueue(priorities[i]));
}
}
void JobQueue::cleanupJobQueues()
{
for(auto worker : workers)
{
delete worker;
}
}
void JobQueue::runJobs(FiberJob* jobs, uint32 numJobs)
{
for(uint32 i = 0; i < numJobs; ++i)
{
JobPriorityInfo& info = priorityQueues[(size_t)jobs[i].getPriority()];
std::unique_lock lock(info.jobQueueLock);
info.jobQueue.add(std::move(jobs[i]));
//info.jobQueueCV.notify_one();
}
}
void JobQueue::waitForCounter(PCounter counter, uint32 waitFor)
{
while(counter->lessThan(waitFor))
std::this_thread::yield();
}
void JobQueue::suspendJob(FiberTask&& task)
{
JobPriorityInfo& info = priorityQueues[(size_t)task.getPriority()];
std::unique_lock lock(info.jobQueueLock);
info.waiterQueue[task.getCounter()].add(task);
}
void JobQueue::refreshWaiterQueue()
{
JobPriorityInfo& info = priorityQueues[(size_t)priority];
//shortcut to avoid iterator creation
if(info.waiterQueue.empty())
return;
for(auto it : info.waiterQueue)
{
auto& entries = info.waiterQueue[it.key];
for(uint32 i = 0; i < entries.size(); ++i)
{
if(it.key->greaterEqual(entries[i].getTarget()))
{
info.resumableTasks.add(std::move(entries[i]));
entries.remove(i);
i--;
}
}
}
}
void JobQueue::work()
{
JobPriorityInfo& targetInfo = priorityQueues[(size_t)priority];
auto& jobQueue = targetInfo.jobQueue;
auto& resumableTasks = targetInfo.resumableTasks;
while(running)
{
std::unique_lock lock(targetInfo.jobQueueLock);
refreshWaiterQueue();
if(resumableTasks.size() > 0)
{
FiberTask task = std::move(resumableTasks.front());
resumableTasks.popFront();
lock.unlock();
task.resume();
lock.lock();
}
if(jobQueue.size() > 0)
{
FiberJob job = std::move(jobQueue.front());
jobQueue.popFront();
lock.unlock();
job();
lock.lock();
}
}
}
-55
View File
@@ -1,55 +0,0 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
namespace Seele
{
namespace Fibers
{
class FiberJob;
DECLARE_REF(Counter)
enum class JobPriority : size_t
{
HIGH = 0,
MEDIUM,
LOW,
IO,
NUM_PRIORITIES
};
struct AtomicJobQueue
{
};
class FiberTask;
struct JobPriorityInfo
{
List<FiberJob> jobQueue;
Map<PCounter, Array<FiberTask>> waiterQueue;
List<FiberTask> resumableTasks;
std::mutex jobQueueLock;
};
class JobQueue
{
public:
JobQueue(JobPriority priority);
JobQueue(const JobQueue& other) = delete;
JobQueue(JobQueue&& other) = delete;
JobQueue& operator=(const JobQueue& other) = delete;
JobQueue& operator=(JobQueue&& other) = delete;
~JobQueue();
static void initJobQueues();
static void cleanupJobQueues();
static void runJobs(FiberJob* jobs, uint32 numJobs);
//This does in fact not do any coroutine stuff, but is a simple busy wait
//For coroutine waits, you have to be in a coroutine, and
static void waitForCounter(PCounter counter, uint32 waitFor);
static void suspendJob(FiberTask&& task);
void refreshWaiterQueue();
private:
void work();
static Array<JobQueue*> workers;
static StaticArray<JobPriorityInfo, (size_t)JobPriority::NUM_PRIORITIES> priorityQueues;
std::thread threadHandle;
JobPriority priority;
bool running = true;
};
} // namespace Fibers
} // namespace Seele
-2
View File
@@ -10,8 +10,6 @@ target_sources(SeeleEngine
Mesh.h
Mesh.cpp
MeshBatch.h
RenderCore.h
RenderCore.cpp
RenderMaterial.h
RenderMaterial.cpp
ShaderCompiler.h
-29
View File
@@ -1,29 +0,0 @@
#include "RenderCore.h"
#include "Window/SceneView.h"
Seele::RenderCore::RenderCore()
{
windowManager = new WindowManager();
}
Seele::RenderCore::~RenderCore()
{
}
void Seele::RenderCore::init()
{
}
void Seele::RenderCore::renderLoop()
{
while (windowManager->isActive())
{
windowManager->beginFrame();
windowManager->render();
windowManager->endFrame();
}
}
void Seele::RenderCore::shutdown()
{
}
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include "Window/WindowManager.h"
#include "Scene/Scene.h"
namespace Seele
{
class RenderCore
{
public:
RenderCore();
~RenderCore();
void init();
void renderLoop();
void shutdown();
PWindowManager getWindowManager() const { return windowManager; };
private:
PScene scene;
PWindowManager windowManager;
};
} // namespace Seele
+9 -5
View File
@@ -82,7 +82,6 @@ void BasePassMeshProcessor::clearCommands()
BasePass::BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
: RenderPass(renderGraph, graphics, viewport)
, processor(new BasePassMeshProcessor(scene, viewport, graphics, false))
, scene(scene)
, descriptorSets(4)
, source(source->getCameraComponent())
{
@@ -125,6 +124,11 @@ BasePass::~BasePass()
{
}
void BasePass::updateViewFrame(PViewFrame viewFrame)
{
}
void BasePass::beginFrame()
{
processor->clearCommands();
@@ -145,10 +149,10 @@ void BasePass::beginFrame()
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
for(auto &&meshBatch : scene->getStaticMeshes())
/*for(auto &&meshBatch : scene->getStaticMeshes())
{
meshBatch.material->updateDescriptorData();
}
}*/
}
void BasePass::render()
@@ -169,10 +173,10 @@ void BasePass::render()
descriptorSets[INDEX_LIGHT_ENV]->updateTexture(5, oLightGrid);
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
graphics->beginRenderPass(renderPass);
for (auto &&meshBatch : scene->getStaticMeshes())
/*for (auto &&meshBatch : scene->getStaticMeshes())
{
processor->addMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets);
}
}*/
graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass();
}
+6 -1
View File
@@ -31,11 +31,17 @@ private:
DEFINE_REF(BasePassMeshProcessor)
DECLARE_REF(CameraActor)
DECLARE_REF(CameraComponent)
struct BasePassData
{
const LightEnv lightEnv;
const Array<StaticMeshBatch> staticDrawList;
};
class BasePass : public RenderPass
{
public:
BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
virtual ~BasePass();
virtual void updateViewFrame(PViewFrame viewFrame) override;
virtual void beginFrame() override;
virtual void render() override;
virtual void endFrame() override;
@@ -47,7 +53,6 @@ private:
Gfx::PTexture2D depthBuffer;
UPBasePassMeshProcessor processor;
const PScene scene;
Array<Gfx::PDescriptorSet> descriptorSets;
PCameraComponent source;
Gfx::PPipelineLayout basePassLayout;
@@ -81,7 +81,6 @@ void DepthPrepassMeshProcessor::clearCommands()
DepthPrepass::DepthPrepass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
: RenderPass(renderGraph, graphics, viewport)
, processor(new DepthPrepassMeshProcessor(scene, viewport, graphics))
, scene(scene)
, descriptorSets(3)
, source(source->getCameraComponent())
{
@@ -108,7 +107,7 @@ DepthPrepass::~DepthPrepass()
{
}
void DepthPrepass::beginFrame()
void DepthPrepass::beginFrame(UPViewFrame& viewFrame)
{
processor->clearCommands();
primitiveLayout->reset();
@@ -126,28 +125,28 @@ void DepthPrepass::beginFrame()
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
for(auto &&meshBatch : scene->getStaticMeshes())
/*for(auto &&meshBatch : scene->getStaticMeshes())
{
meshBatch.material->updateDescriptorData();
}
}*/
}
void DepthPrepass::render()
void DepthPrepass::render(UPViewFrame& viewFrame)
{
depthAttachment->getTexture()->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS);
graphics->beginRenderPass(renderPass);
for (auto &&meshBatch : scene->getStaticMeshes())
/*for (auto &&meshBatch : scene->getStaticMeshes())
{
processor->addMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets);
}
}*/
graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass();
}
void DepthPrepass::endFrame()
void DepthPrepass::endFrame(UPViewFrame& viewFrame)
{
}
@@ -45,7 +45,6 @@ private:
Gfx::PRenderTargetAttachment depthAttachment;
Gfx::PTexture2D depthBuffer;
UPDepthPrepassMeshProcessor processor;
const PScene scene;
Array<Gfx::PDescriptorSet> descriptorSets;
PCameraComponent source;
@@ -9,7 +9,6 @@ using namespace Seele;
LightCullingPass::LightCullingPass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera)
: RenderPass(renderGraph, graphics, viewport)
, scene(scene)
, source(camera->getCameraComponent())
{
}
@@ -19,7 +18,7 @@ LightCullingPass::~LightCullingPass()
}
void LightCullingPass::beginFrame()
void LightCullingPass::beginFrame(UPViewFrame& viewFrame)
{
uint32_t viewportWidth = viewport->getSizeX();
uint32_t viewportHeight = viewport->getSizeY();
@@ -34,7 +33,7 @@ void LightCullingPass::beginFrame()
uniformUpdate.data = (uint8*)&viewParams;
viewParamsBuffer->updateContents(uniformUpdate);
LightEnv lightEnv = scene->getLightBuffer();
/*LightEnv lightEnv = scene->getLightBuffer();
for(uint32 i = 0; i < lightEnv.numPointLights; ++i)
{
lightEnv.pointLights[i].positionVS = lightEnv.pointLights[i].positionWS;
@@ -42,7 +41,7 @@ void LightCullingPass::beginFrame()
uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
uniformUpdate.data = (uint8*)&lightEnv.pointLights;
pointLightBuffer->updateContents(uniformUpdate);
*/
BulkResourceData counterReset;
uint32 reset = 0;
counterReset.data = (uint8*)&reset;
@@ -72,7 +71,7 @@ void LightCullingPass::beginFrame()
lightEnvDescriptorSet->writeChanges();
}
void LightCullingPass::render()
void LightCullingPass::render(UPViewFrame& viewFrame)
{
oLightIndexList->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
@@ -98,7 +97,7 @@ void LightCullingPass::render()
depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS);
}
void LightCullingPass::endFrame()
void LightCullingPass::endFrame(UPViewFrame& viewFrame)
{
}
@@ -133,23 +132,23 @@ void LightCullingPass::publishOutputs()
tLightIndexList = graphics->createStructuredBuffer(structInfo);
renderGraph->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
renderGraph->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
const LightEnv& lightEnv = scene->getLightBuffer();
/*const LightEnv& lightEnv = scene->getLightBuffer();
resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
resourceData.data = (uint8*)&lightEnv.directionalLights;
resourceData.data = (uint8*)&lightEnv.directionalLights;*/
structInfo.resourceData = resourceData;
structInfo.bDynamic = true;
directLightBuffer = graphics->createStructuredBuffer(structInfo);
resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
resourceData.data = (uint8*)&lightEnv.pointLights;
//resourceData.data = (uint8*)&lightEnv.pointLights;
structInfo.resourceData = resourceData;
pointLightBuffer = graphics->createStructuredBuffer(structInfo);
UniformBufferCreateInfo uniformInfo;
resourceData.size = sizeof(uint32);
resourceData.data = (uint8*)&lightEnv.numDirectionalLights;
//resourceData.data = (uint8*)&lightEnv.numDirectionalLights;
uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true;
numDirLightBuffer = graphics->createUniformBuffer(uniformInfo);
resourceData.data = (uint8*)&lightEnv.numPointLights;
//resourceData.data = (uint8*)&lightEnv.numPointLights;
uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true;
numPointLightBuffer = graphics->createUniformBuffer(uniformInfo);
@@ -42,9 +42,7 @@ private:
{
Plane planes[4];
};
PScene scene;
Gfx::PStructuredBuffer frustumBuffer;
Gfx::PUniformBuffer dispatchParamsBuffer;
Gfx::PUniformBuffer viewParamsBuffer;
@@ -54,7 +52,6 @@ private:
Gfx::PComputePipeline frustumPipeline;
Gfx::PTexture2D depthAttachment;
//Gfx::PTexture2D depthComputeTexture;
Gfx::PStructuredBuffer frustums;
Gfx::PStructuredBuffer oLightIndexCounter;
Gfx::PStructuredBuffer tLightIndexCounter;
+20 -4
View File
@@ -13,19 +13,35 @@ RenderGraph::~RenderGraph()
void RenderGraph::setup()
{
for(auto pass : renderPasses)
for(auto& pass : renderPasses)
{
pass->publishOutputs();
}
for(auto pass : renderPasses)
for(auto& pass : renderPasses)
{
pass->createRenderPass();
}
}
void RenderGraph::addRenderPass(PRenderPass renderPass)
void RenderGraph::addRenderPass(UPRenderPass renderPass)
{
renderPasses.add(renderPass);
renderPasses.add(std::move(renderPass));
}
void RenderGraph::render(PViewFrame viewFrame)
{
for(auto& pass : renderPasses)
{
pass->beginFrame(viewFrame);
}
for(auto& pass : renderPasses)
{
pass->render(viewFrame);
}
for(auto& pass : renderPasses)
{
pass->endFrame(viewFrame);
}
}
Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string& outputName)
+4 -2
View File
@@ -5,13 +5,15 @@
namespace Seele
{
DECLARE_REF(ViewFrame)
class RenderGraph
{
public:
RenderGraph();
~RenderGraph();
void setup();
void addRenderPass(PRenderPass renderPass);
void addRenderPass(UPRenderPass renderPass);
void render(PViewFrame viewFrame);
Gfx::PRenderTargetAttachment requestRenderTarget(const std::string& outputName);
Gfx::PTexture requestTexture(const std::string& outputName);
Gfx::PStructuredBuffer requestBuffer(const std::string& outputName);
@@ -25,7 +27,7 @@ private:
Map<std::string, Gfx::PTexture> registeredTextures;
Map<std::string, Gfx::PStructuredBuffer> registeredBuffers;
Map<std::string, Gfx::PUniformBuffer> registeredUniforms;
List<PRenderPass> renderPasses;
List<UPRenderPass> renderPasses;
};
DEFINE_REF(RenderGraph)
} // namespace Seele
@@ -13,6 +13,7 @@ class RenderPass
public:
RenderPass(PRenderGraph rendergraph, Gfx::PGraphics graphics, Gfx::PViewport viewport);
virtual ~RenderPass();
virtual void updateViewFrame(PViewFrame viewFrame) = 0;
virtual void beginFrame() = 0;
virtual void render() = 0;
virtual void endFrame() = 0;
+3 -3
View File
@@ -15,12 +15,12 @@ UIPass::~UIPass()
}
void UIPass::beginFrame()
void UIPass::beginFrame(UPViewFrame& viewFrame)
{
}
void UIPass::render()
void UIPass::render(UPViewFrame& viewFrame)
{
graphics->beginRenderPass(renderPass);
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
@@ -31,7 +31,7 @@ void UIPass::render()
graphics->endRenderPass();
}
void UIPass::endFrame()
void UIPass::endFrame(UPViewFrame& viewFrame)
{
}
+5 -1
View File
@@ -7,6 +7,10 @@ namespace Seele
{
DECLARE_NAME_REF(Gfx, Texture2D)
DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
struct UIPassData
{
const UI::RenderHierarchy hierarchy;
};
class UIPass : public RenderPass
{
public:
@@ -18,7 +22,7 @@ public:
virtual void publishOutputs() override;
virtual void createRenderPass() override;
private:
UI::RenderHierarchy hierarchy;
PUIViewFrame uiFrame;
Gfx::PRenderTargetAttachment renderTarget;
Gfx::PRenderTargetAttachment depthAttachment;
Gfx::PTexture2D depthBuffer;
+36 -28
View File
@@ -275,33 +275,6 @@ private:
ar & *object->getHandle();
}
};
//A weak pointer has no ownership over an object and thus cant delete it
template <typename T>
class WeakPtr
{
public:
WeakPtr()
: pointer(nullptr)
{
}
WeakPtr(RefPtr<T> &sharedPtr)
: pointer(sharedPtr)
{
}
WeakPtr &operator=(WeakPtr<T> &weakPtr)
{
pointer = weakPtr.pointer;
return *this;
}
WeakPtr &operator=(RefPtr<T> &sharedPtr)
{
pointer = sharedPtr;
return *this;
}
private:
RefPtr<T> pointer;
};
template <typename T>
class UniquePtr
{
@@ -335,7 +308,15 @@ public:
{
delete handle;
}
T *operator->()
inline bool operator==(const UniquePtr &other) const
{
return handle == other.handle;
}
inline bool operator!=(const UniquePtr &other) const
{
return handle != other.handle;
}
inline T *operator->()
{
return handle;
}
@@ -353,6 +334,33 @@ private:
ar & *handle;
}
};
//A weak pointer has no ownership over an object and thus cant delete it
template <typename T>
class WeakPtr
{
public:
WeakPtr()
: pointer(nullptr)
{
}
WeakPtr(RefPtr<T> &sharedPtr)
: pointer(sharedPtr)
{
}
WeakPtr &operator=(WeakPtr<T> &weakPtr)
{
pointer = weakPtr.pointer;
return *this;
}
WeakPtr &operator=(RefPtr<T> &sharedPtr)
{
pointer = sharedPtr;
return *this;
}
private:
RefPtr<T> pointer;
};
} // namespace Seele
using namespace Seele;
+2
View File
@@ -29,6 +29,8 @@ public:
const Rect getBoundingBox() const;
protected:
Rect boundingBox;
bool dirty;
bool enabled;
PElement parent;
Array<PElement> children;
+1
View File
@@ -11,5 +11,6 @@ public:
Panel();
virtual ~Panel();
};
DEFINE_REF(Panel);
} // namespace UI
} // namespace Seele
+8
View File
@@ -22,3 +22,11 @@ RenderHierarchy::~RenderHierarchy()
{
}
void RenderHierarchy::updateHierarchyIndices()
{
for (uint32 i = 0; i < drawElements.size(); i++)
{
drawElements[i].hierarchyIndex = i;
}
}
+11
View File
@@ -12,16 +12,27 @@ public:
RenderElement();
virtual ~RenderElement();
private:
uint32 hierarchyIndex;
RenderElement* parent;
PElement referencedElement;
Gfx::PRenderCommand renderCommand;
friend class RenderHierarchy;
};
struct RenderHierarchyUpdate
{};
DEFINE_REF(RenderHierarchyUpdate)
class RenderHierarchy
{
public:
RenderHierarchy();
~RenderHierarchy();
private:
void updateHierarchyIndices();
// List of all drawable elements in draw order
Array<RenderElement> drawElements;
};
+2 -4
View File
@@ -1,13 +1,11 @@
target_sources(SeeleEngine
PRIVATE
Frame.h
Frame.cpp
InspectorView.h
InspectorView.cpp
RenderPath.h
RenderPath.cpp
SceneView.h
SceneView.cpp
SceneRenderPath.h
SceneRenderPath.cpp
View.h
View.cpp
Window.cpp
+1 -5
View File
@@ -8,8 +8,7 @@ InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const View
{
renderGraph = new RenderGraph();
Gfx::PRenderTargetAttachment attachment = new Gfx::SwapchainAttachment(window->getGfxHandle());
uiPass = new UIPass(renderGraph, graphics, viewport, attachment);
renderGraph->addRenderPass(uiPass);
renderGraph->addRenderPass(new UIPass(renderGraph, graphics, viewport, attachment));
renderGraph->setup();
}
@@ -19,17 +18,14 @@ InspectorView::~InspectorView()
void InspectorView::beginFrame()
{
uiPass->beginFrame();
}
void InspectorView::render()
{
uiPass->render();
}
void InspectorView::endFrame()
{
uiPass->endFrame();
}
void InspectorView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier)
+9 -3
View File
@@ -2,10 +2,18 @@
#include "View.h"
#include "Graphics/RenderPass/RenderGraph.h"
#include "Graphics/RenderPass/UIPass.h"
#include "UI/Elements/Panel.h"
namespace Seele
{
DECLARE_REF(Actor)
class InspectorViewFrame : public ViewFrame
{
public:
protected:
const UI::RenderHierarchy hierarchy;
};
class InspectorView : public View
{
public:
@@ -17,10 +25,8 @@ public:
void selectActor();
protected:
Array<UI::PElement> rootElements;
PUIPass uiPass;
UI::PPanel rootPanel;
PActor selectedActor;
PRenderGraph renderGraph;
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) override;
virtual void mouseMoveCallback(double xPos, double yPos) override;
-18
View File
@@ -1,18 +0,0 @@
#include "RenderPath.h"
#include "Graphics/GraphicsResources.h"
#include "Material/MaterialAsset.h"
Seele::RenderPath::RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target)
: graphics(graphics), target(target)
{
}
Seele::RenderPath::~RenderPath()
{
}
void Seele::RenderPath::applyArea(URect newArea)
{
target->resize(newArea.size.x, newArea.size.y);
target->move(newArea.offset.x, newArea.offset.y);
}
-22
View File
@@ -1,22 +0,0 @@
#pragma once
#include "Graphics/Graphics.h"
namespace Seele
{
//A renderpath is a general Renderer for a view.
class RenderPath
{
public:
RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
virtual ~RenderPath();
virtual void applyArea(URect area);
virtual void init() = 0;
virtual void beginFrame() = 0;
virtual void render() = 0;
virtual void endFrame() = 0;
protected:
Gfx::PGraphics graphics;
Gfx::PViewport target;
};
DEFINE_REF(RenderPath)
} // namespace Seele
-56
View File
@@ -1,56 +0,0 @@
#include "SceneRenderPath.h"
#include "Scene/Scene.h"
#include "Material/Material.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/RenderPass/RenderGraph.h"
using namespace Seele;
SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target, PCameraActor source)
: RenderPath(graphics, target)
, scene(scene)
{
renderGraph = new RenderGraph();
depthPrepass = new DepthPrepass(renderGraph, scene, graphics, target, source);
lightCullingPass = new LightCullingPass(renderGraph, scene, graphics, target, source);
basePass = new BasePass(renderGraph, scene, graphics, target, source);
renderGraph->addRenderPass(depthPrepass);
renderGraph->addRenderPass(lightCullingPass);
renderGraph->addRenderPass(basePass);
renderGraph->setup();
}
SceneRenderPath::~SceneRenderPath()
{
}
void SceneRenderPath::setTargetScene(PScene newScene)
{
scene = newScene;
}
void SceneRenderPath::init()
{
}
void SceneRenderPath::beginFrame()
{
depthPrepass->beginFrame();
lightCullingPass->beginFrame();
basePass->beginFrame();
}
void SceneRenderPath::render()
{
depthPrepass->render();
lightCullingPass->render();
basePass->render();
}
void SceneRenderPath::endFrame()
{
depthPrepass->endFrame();
lightCullingPass->endFrame();
basePass->endFrame();
}
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include "RenderPath.h"
#include "Graphics/RenderPass/DepthPrepass.h"
#include "Graphics/RenderPass/LightCullingPass.h"
#include "Graphics/RenderPass/BasePass.h"
namespace Seele
{
DECLARE_REF(Scene)
DECLARE_REF(CameraActor)
class SceneRenderPath : public RenderPath
{
public:
SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target, PCameraActor source);
virtual ~SceneRenderPath();
void setTargetScene(PScene scene);
virtual void init();
virtual void beginFrame();
virtual void render();
virtual void endFrame();
protected:
PScene scene;
PRenderGraph renderGraph;
PDepthPrepass depthPrepass;
PLightCullingPass lightCullingPass;
PBasePass basePass;
};
} // namespace Seele
+9 -3
View File
@@ -1,9 +1,11 @@
#include "SceneView.h"
#include "SceneRenderPath.h"
#include "Scene/Scene.h"
#include "Window.h"
#include "Scene/Actor/CameraActor.h"
#include "Scene/Components/CameraComponent.h"
#include "Graphics/RenderPass/DepthPrepass.h"
#include "Graphics/RenderPass/LightCullingPass.h"
#include "Graphics/RenderPass/BasePass.h"
using namespace Seele;
@@ -13,7 +15,11 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
scene = new Scene(graphics);
activeCamera = new CameraActor();
scene->addActor(activeCamera);
renderer = new SceneRenderPath(scene, graphics, viewport, activeCamera);
renderGraph = new RenderGraph();
renderGraph->addRenderPass(new DepthPrepass(renderGraph, scene, graphics, viewport, activeCamera));
renderGraph->addRenderPass(new LightCullingPass(renderGraph, scene, graphics, viewport, activeCamera));
renderGraph->addRenderPass(new BasePass(renderGraph, scene, graphics, viewport, activeCamera));
renderGraph->setup();
}
Seele::SceneView::~SceneView()
@@ -23,7 +29,7 @@ Seele::SceneView::~SceneView()
void SceneView::beginFrame()
{
View::beginFrame();
scene->tick(Gfx::currentFrameDelta);//TODO: update in separate thread
scene->tick(Gfx::currentFrameDelta);
}
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier)
+10
View File
@@ -4,6 +4,15 @@ namespace Seele
{
DECLARE_REF(Scene)
DECLARE_REF(CameraActor)
class SceneViewFrame : public ViewFrame
{
public:
protected:
const PScene scene;
};
DEFINE_REF(SceneViewFrame)
class SceneView : public View
{
public:
@@ -14,6 +23,7 @@ public:
private:
PScene scene;
PCameraActor activeCamera;
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) override;
virtual void mouseMoveCallback(double xPos, double yPos) override;
virtual void mouseButtonCallback(MouseButton button, InputAction action, KeyModifier modifier) override;
+3 -5
View File
@@ -1,6 +1,6 @@
#pragma once
#include "View.h"
#include "Window.h"
#include "Graphics/Graphics.h"
Seele::View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &viewportInfo)
: graphics(graphics), owner(window)
@@ -14,22 +14,20 @@ Seele::View::~View()
void Seele::View::beginFrame()
{
renderer->beginFrame();
}
void Seele::View::render()
{
renderer->render();
}
void Seele::View::endFrame()
{
renderer->endFrame();
}
void Seele::View::applyArea(URect area)
{
renderer->applyArea(area);
}
void View::setFocused()
+14 -3
View File
@@ -1,9 +1,19 @@
#pragma once
#include "RenderPath.h"
#include "Graphics/RenderPass/RenderGraph.h"
namespace Seele
{
DECLARE_REF(Window)
// A view is a part of the window, which can be anything from a viewport to an inspector
// A ViewFrame is the render relevant data of a View
class ViewFrame
{
public:
protected:
};
DEFINE_REF(ViewFrame)
// A view is a part of the window, which can be anything from a scene viewport to an inspector
class View
{
public:
@@ -16,10 +26,11 @@ public:
void setFocused();
protected:
UPViewFrame currentFrame;
Gfx::PGraphics graphics;
Gfx::PViewport viewport;
PWindow owner;
PRenderPath renderer;
PRenderGraph renderGraph;
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) = 0;
virtual void mouseMoveCallback(double xPos, double yPos) = 0;
+35 -25
View File
@@ -1,54 +1,51 @@
#include "Window.h"
#include <functional>
Seele::Window::Window(Gfx::PWindow handle)
using namespace Seele;
Window::Window(Gfx::PWindow handle)
: gfxHandle(handle)
{
}
Seele::Window::~Window()
Window::~Window()
{
}
void Seele::Window::addView(PView view)
void Window::addView(PView view)
{
viewports.add(view);
WindowView* windowView = new WindowView();
windowView->view = view;
windowView->renderGraph = view->renderGraph;
windowView->worker = std::thread(&Window::viewWorker, this, windowView);
views.add(windowView);
}
void Seele::Window::beginFrame()
void Window::render()
{
gfxHandle->beginFrame();
for (auto view : viewports)
for(auto& windowView : views)
{
view->beginFrame();
UPViewFrame frame;
{
std::lock_guard lock(windowView->workerMutex);
frame = std::move(windowView->currentFrame);
}
if(frame != nullptr)
{
windowView->renderGraph->render(std::move(frame));
}
}
}
void Seele::Window::render()
{
for (auto view : viewports)
{
view->render();
}
}
void Seele::Window::endFrame()
{
gfxHandle->endFrame();
for (auto view : viewports)
{
view->endFrame();
}
}
Gfx::PWindow Seele::Window::getGfxHandle()
Gfx::PWindow Window::getGfxHandle()
{
return gfxHandle;
}
void Window::setFocused(PView view)
{
focusedView = view;
auto keyFunction = std::bind(&View::keyCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
auto mouseMoveFunction = std::bind(&View::mouseMoveCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2);
auto mouseButtonFunction = std::bind(&View::mouseButtonCallback, view.getHandle(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
@@ -60,3 +57,16 @@ void Window::setFocused(PView view)
gfxHandle->setScrollCallback(scrollFunction);
gfxHandle->setFileCallback(fileFunction);
}
void Window::viewWorker(WindowView* windowView)
{
while(true)
{
windowView->view->beginFrame();
windowView->view->render();
windowView->view->endFrame();
std::lock_guard lock(windowView->workerMutex);
windowView->currentFrame = std::move(windowView->view->currentFrame);
}
}
+13 -5
View File
@@ -4,6 +4,15 @@
namespace Seele
{
struct WindowView
{
PView view;
PRenderGraph renderGraph;
UPViewFrame currentFrame;
std::thread worker;
std::mutex workerMutex;
};
DEFINE_REF(WindowView)
// The logical window, with the graphics proxy
class Window
{
@@ -11,16 +20,15 @@ public:
Window(Gfx::PWindow handle);
~Window();
void addView(PView view);
void beginFrame();
void render();
void endFrame();
Gfx::PWindow getGfxHandle();
void setFocused(PView view);
private:
Array<PView> viewports;
PView focusedView;
protected:
Array<WindowView*> views;
Gfx::PWindow gfxHandle;
void viewWorker(WindowView* view);
};
DEFINE_REF(Window)
} // namespace Seele
+5 -18
View File
@@ -1,9 +1,11 @@
#include "WindowManager.h"
#include "Graphics/Vulkan/VulkanGraphics.h"
using namespace Seele;
Gfx::PGraphics WindowManager::graphics;
Seele::WindowManager::WindowManager()
WindowManager::WindowManager()
{
graphics = new Vulkan::Graphics();
GraphicsInitializer initializer;
@@ -22,11 +24,11 @@ Seele::WindowManager::WindowManager()
Gfx::PUniformBuffer testUniform = graphics->createUniformBuffer(uniformInitializer);
}
Seele::WindowManager::~WindowManager()
WindowManager::~WindowManager()
{
}
PWindow Seele::WindowManager::addWindow(const WindowCreateInfo &createInfo)
PWindow WindowManager::addWindow(const WindowCreateInfo &createInfo)
{
Gfx::PWindow handle = graphics->createWindow(createInfo);
PWindow window = new Window(handle);
@@ -34,14 +36,6 @@ PWindow Seele::WindowManager::addWindow(const WindowCreateInfo &createInfo)
return window;
}
void Seele::WindowManager::beginFrame()
{
for (auto window : windows)
{
window->beginFrame();
}
}
void WindowManager::render()
{
for(auto window : windows)
@@ -50,10 +44,3 @@ void WindowManager::render()
}
}
void Seele::WindowManager::endFrame()
{
for (auto window : windows)
{
window->endFrame();
}
}
-2
View File
@@ -12,9 +12,7 @@ public:
WindowManager();
~WindowManager();
PWindow addWindow(const WindowCreateInfo &createInfo);
void beginFrame();
void render();
void endFrame();
static Gfx::PGraphics getGraphics()
{
return graphics;
+10 -12
View File
@@ -1,16 +1,14 @@
#include "Graphics/RenderCore.h"
#include "Window/WindowManager.h"
#include "Scene/Components/PrimitiveComponent.h"
#include "Window/SceneView.h"
#include "Window/InspectorView.h"
#include "Asset/AssetRegistry.h"
#include "Fibers/Fibers.h"
#include <queue>
using namespace Seele;
int main()
{
RenderCore core;
core.init();
PWindowManager windowManager = new WindowManager();
WindowCreateInfo mainWindowInfo;
mainWindowInfo.title = "SeeleEngine";
mainWindowInfo.width = 1280;
@@ -18,13 +16,13 @@ int main()
mainWindowInfo.bFullscreen = false;
mainWindowInfo.numSamples = 1;
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
auto window = core.getWindowManager()->addWindow(mainWindowInfo);
auto window = windowManager->addWindow(mainWindowInfo);
ViewportCreateInfo sceneViewInfo;
sceneViewInfo.sizeX = 640;
sceneViewInfo.sizeY = 720;
sceneViewInfo.offsetX = 0;
sceneViewInfo.offsetY = 0;
PSceneView sceneView = new SceneView(core.getWindowManager()->getGraphics(), window, sceneViewInfo);
PSceneView sceneView = new SceneView(windowManager->getGraphics(), window, sceneViewInfo);
window->addView(sceneView);
ViewportCreateInfo inspectorViewInfo;
@@ -32,7 +30,7 @@ int main()
inspectorViewInfo.sizeY = 720;
inspectorViewInfo.offsetX = 640;
inspectorViewInfo.offsetY = 0;
PInspectorView inspectorView = new InspectorView(core.getWindowManager()->getGraphics(), window, inspectorViewInfo);
PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
window->addView(inspectorView);
sceneView->setFocused();
AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject\\");
@@ -44,9 +42,9 @@ int main()
PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely"));
arissa->addWorldTranslation(Vector(0, 0, 100));
arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f));
sceneView->getScene()->addPrimitiveComponent(plane);
sceneView->getScene()->addPrimitiveComponent(arissa);
core.renderLoop();
core.shutdown();
while (windowManager->isActive())
{
windowManager->render();
}
return 0;
}