Skip to content

Commit

Permalink
Traktor: Big refactor of the RenderContext, able to properly execute …
Browse files Browse the repository at this point in the history
…compute jobs before dependent render passes. Also able to specify barriers properly.
  • Loading branch information
apistol78 committed Jan 22, 2024
1 parent 4cb86fb commit 5170fab
Show file tree
Hide file tree
Showing 49 changed files with 271 additions and 208 deletions.
2 changes: 1 addition & 1 deletion code/Animation/Cloth/ClothComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ void ClothComponent::build(
render::RenderContext* renderContext = context.getRenderContext();
T_ASSERT(renderContext);

auto renderBlock = renderContext->alloc< render::IndexedRenderBlock >(L"Cloth");
auto renderBlock = renderContext->allocNamed< render::IndexedRenderBlock >(L"Cloth");
renderBlock->distance = 0.0f;
renderBlock->program = sp.program;
renderBlock->programParams = renderContext->alloc< render::ProgramParameters >();
Expand Down
4 changes: 2 additions & 2 deletions code/Animation/Editor/AnimationPreviewControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,11 @@ void AnimationPreviewControl::eventPaint(ui::PaintEvent* event)

m_primitiveRenderer->end(0);

auto rb = renderContext->alloc< render::LambdaRenderBlock >(L"Debug wire");
auto rb = renderContext->allocNamed< render::LambdaRenderBlock >(L"Debug wire");
rb->lambda = [&](render::IRenderView* renderView) {
m_primitiveRenderer->render(m_renderView, 0);
};
renderContext->enqueue(rb);
renderContext->draw(rb);
});
m_renderGraph->addPass(rp);

Expand Down
4 changes: 2 additions & 2 deletions code/Mesh/Instance/InstanceMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void InstanceMesh::build(
instanceLastBatch[j] = instanceWorld[batchOffset + j].data0;
}

auto renderBlock = renderContext->alloc< render::InstancingRenderBlock >(L"InstanceMesh opaque");
auto renderBlock = renderContext->allocNamed< render::InstancingRenderBlock >(L"InstanceMesh opaque");
renderBlock->distance = instanceWorld[batchOffset + batchCount - 1].distance;
renderBlock->program = sp.program;
renderBlock->programParams = renderContext->alloc< render::ProgramParameters >();
Expand Down Expand Up @@ -178,7 +178,7 @@ void InstanceMesh::build(
instanceLastBatch[j] = instanceWorld[batchOffset + j].data0;
}

auto renderBlock = renderContext->alloc< render::InstancingRenderBlock >(L"InstanceMesh blend");
auto renderBlock = renderContext->allocNamed< render::InstancingRenderBlock >(L"InstanceMesh blend");
renderBlock->distance = instanceWorld[batchOffset + batchCount - 1].distance;
renderBlock->program = sp.program;
renderBlock->programParams = renderContext->alloc< render::ProgramParameters >();
Expand Down
2 changes: 1 addition & 1 deletion code/Mesh/Skinned/SkinnedMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void SkinnedMesh::build(
if (!sp)
continue;

render::SimpleRenderBlock* renderBlock = renderContext->alloc< render::SimpleRenderBlock >(L"SkinnedMesh");
render::SimpleRenderBlock* renderBlock = renderContext->allocNamed< render::SimpleRenderBlock >(L"SkinnedMesh");
renderBlock->distance = distance;
renderBlock->program = sp.program;
renderBlock->programParams = programParams;
Expand Down
2 changes: 1 addition & 1 deletion code/Mesh/Static/StaticMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void StaticMesh::build(
if (!sp)
continue;

render::SimpleRenderBlock* renderBlock = renderContext->alloc< render::SimpleRenderBlock >(L"StaticMesh");
render::SimpleRenderBlock* renderBlock = renderContext->allocNamed< render::SimpleRenderBlock >(L"StaticMesh");
renderBlock->distance = distance;
renderBlock->program = sp.program;
renderBlock->programParams = programParams;
Expand Down
2 changes: 1 addition & 1 deletion code/Render/Context/RenderBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ void BarrierRenderBlock::render(IRenderView* renderView) const
{
T_CONTEXT_PUSH_MARKER(renderView, name);

renderView->barrier();
renderView->barrier(from, to);

T_CONTEXT_POP_MARKER(renderView);
}
Expand Down
13 changes: 12 additions & 1 deletion code/Render/Context/RenderBlock.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* TRAKTOR
* Copyright (c) 2022 Anders Pistol.
* Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -238,6 +238,17 @@ class T_DLLCLASS SetViewportRenderBlock : public RenderBlock
class T_DLLCLASS BarrierRenderBlock : public RenderBlock
{
public:
Stage from = Stage::Invalid;
Stage to = Stage::Invalid;

BarrierRenderBlock() = default;

explicit BarrierRenderBlock(Stage from_, Stage to_)
: from(from_)
, to(to_)
{
}

virtual void render(IRenderView* renderView) const override final;
};

Expand Down
49 changes: 30 additions & 19 deletions code/Render/Context/RenderContext.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* TRAKTOR
* Copyright (c) 2022 Anders Pistol.
* Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -81,14 +81,14 @@ void* RenderContext::alloc(uint32_t blockSize, uint32_t align)
return alloc(blockSize);
}

void RenderContext::enqueue(RenderBlock* renderBlock)
void RenderContext::compute(RenderBlock* renderBlock)
{
m_renderQueue.push_back(renderBlock);
m_computeQueue.push_back(renderBlock);
}

void RenderContext::compute(ComputeRenderBlock* renderBlock)
void RenderContext::draw(RenderBlock* renderBlock)
{
m_computeQueue.push_back(renderBlock);
m_drawQueue.push_back(renderBlock);
}

void RenderContext::draw(uint32_t type, DrawableRenderBlock* renderBlock)
Expand All @@ -107,61 +107,69 @@ void RenderContext::draw(uint32_t type, DrawableRenderBlock* renderBlock)
m_priorityQueue[5].push_back(renderBlock);
}

void RenderContext::mergeCompute()
{
m_renderQueue.insert(m_renderQueue.end(), m_computeQueue.begin(), m_computeQueue.end());
m_computeQueue.resize(0);
}

void RenderContext::mergeDraw(uint32_t priorities)
void RenderContext::mergePriorityIntoDraw(uint32_t priorities)
{
// Merge setup blocks unsorted.
if (priorities & RenderPriority::Setup)
{
m_renderQueue.insert(m_renderQueue.end(), m_priorityQueue[0].begin(), m_priorityQueue[0].end());
m_drawQueue.insert(m_drawQueue.end(), m_priorityQueue[0].begin(), m_priorityQueue[0].end());
m_priorityQueue[0].resize(0);
}

// Merge opaque blocks, sorted by shader.
if (priorities & RenderPriority::Opaque)
{
std::sort(m_priorityQueue[1].begin(), m_priorityQueue[1].end(), SortOpaquePredicate);
m_renderQueue.insert(m_renderQueue.end(), m_priorityQueue[1].begin(), m_priorityQueue[1].end());
m_drawQueue.insert(m_drawQueue.end(), m_priorityQueue[1].begin(), m_priorityQueue[1].end());
m_priorityQueue[1].resize(0);
}

// Merge post opaque blocks, sorted by shader.
if (priorities & RenderPriority::PostOpaque)
{
std::sort(m_priorityQueue[2].begin(), m_priorityQueue[2].end(), SortOpaquePredicate);
m_renderQueue.insert(m_renderQueue.end(), m_priorityQueue[2].begin(), m_priorityQueue[2].end());
m_drawQueue.insert(m_drawQueue.end(), m_priorityQueue[2].begin(), m_priorityQueue[2].end());
m_priorityQueue[2].resize(0);
}

// Merge alpha blend blocks back to front.
if (priorities & RenderPriority::AlphaBlend)
{
std::sort(m_priorityQueue[3].begin(), m_priorityQueue[3].end(), SortAlphaBlendPredicate);
m_renderQueue.insert(m_renderQueue.end(), m_priorityQueue[3].begin(), m_priorityQueue[3].end());
m_drawQueue.insert(m_drawQueue.end(), m_priorityQueue[3].begin(), m_priorityQueue[3].end());
m_priorityQueue[3].resize(0);
}

// Merge post alpha blend blocks back to front.
if (priorities & RenderPriority::PostAlphaBlend)
{
std::sort(m_priorityQueue[4].begin(), m_priorityQueue[4].end(), SortAlphaBlendPredicate);
m_renderQueue.insert(m_renderQueue.end(), m_priorityQueue[4].begin(), m_priorityQueue[4].end());
m_drawQueue.insert(m_drawQueue.end(), m_priorityQueue[4].begin(), m_priorityQueue[4].end());
m_priorityQueue[4].resize(0);
}

// Merge overlay blocks unsorted.
if (priorities & RenderPriority::Overlay)
{
m_renderQueue.insert(m_renderQueue.end(), m_priorityQueue[5].begin(), m_priorityQueue[5].end());
m_drawQueue.insert(m_drawQueue.end(), m_priorityQueue[5].begin(), m_priorityQueue[5].end());
m_priorityQueue[5].resize(0);
}
}

void RenderContext::mergeComputeIntoRender()
{
// Merge compute blocks.
m_renderQueue.insert(m_renderQueue.end(), m_computeQueue.begin(), m_computeQueue.end());
m_computeQueue.resize(0);
}

void RenderContext::mergeDrawIntoRender()
{
// Merge draw blocks.
m_renderQueue.insert(m_renderQueue.end(), m_drawQueue.begin(), m_drawQueue.end());
m_drawQueue.resize(0);
}

void RenderContext::render(IRenderView* renderView) const
{
const size_t csize = m_computeQueue.size();
Expand Down Expand Up @@ -189,11 +197,14 @@ void RenderContext::flush()

// As blocks are allocated from a fixed pool we need to manually call destructors.
for (auto renderBlock : m_computeQueue)
renderBlock->~ComputeRenderBlock();
renderBlock->~RenderBlock();
for (auto renderBlock : m_drawQueue)
renderBlock->~RenderBlock();
for (auto renderBlock : m_renderQueue)
renderBlock->~RenderBlock();

m_computeQueue.resize(0);
m_drawQueue.resize(0);
m_renderQueue.resize(0);

m_heapPtr = m_heap.ptr();
Expand Down
56 changes: 34 additions & 22 deletions code/Render/Context/RenderContext.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* TRAKTOR
* Copyright (c) 2022 Anders Pistol.
* Copyright (c) 2022-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -51,44 +51,55 @@ class T_DLLCLASS RenderContext : public Object
void* alloc(uint32_t blockSize, uint32_t align);

/*! Allocate object from context's heap. */
template < typename ObjectType >
ObjectType* alloc()
template < typename ObjectType, typename ... ArgumentTypes >
ObjectType* alloc(ArgumentTypes&& ... args)
{
void* object = alloc((uint32_t)sizeof(ObjectType), (uint32_t)alignOf< ObjectType >());
return new (object) ObjectType();
return new (object) ObjectType(std::forward< ArgumentTypes >(args) ...);
}

/*! Allocate named object from context's heap. */
template < typename ObjectType >
ObjectType* alloc(const std::wstring& name)
template < typename ObjectType, typename ... ArgumentTypes >
ObjectType* allocNamed(const std::wstring_view& name, ArgumentTypes&& ... args)
{
ObjectType* object = alloc< ObjectType >();
ObjectType* object = alloc< ObjectType, ArgumentTypes... >(std::forward< ArgumentTypes >(args) ...);
object->name = name;
return object;
}

/*! Enqueue a render block in context. */
void enqueue(RenderBlock* renderBlock);
/*! Add block to compute queue. */
void compute(RenderBlock* renderBlock);

/*! Enqueue a render block in context. */
template < typename ObjectType >
void enqueue()
/*! Add block to compute queue. */
template < typename ObjectType, typename ... ArgumentTypes >
void compute(ArgumentTypes&& ... args)
{
ObjectType* object = alloc< ObjectType >();
enqueue(object);
ObjectType* object = alloc< ObjectType, ArgumentTypes... >(std::forward< ArgumentTypes >(args) ...);
compute(object);
}

/*! Add compute render block to context. */
void compute(ComputeRenderBlock* renderBlock);
/*! Add a render block to draw queue. */
void draw(RenderBlock* renderBlock);

/*! Add a render block to draw queue. */
template < typename ObjectType, typename ... ArgumentTypes >
void draw(ArgumentTypes&& ... args)
{
ObjectType* object = alloc< ObjectType, ArgumentTypes... >(std::forward< ArgumentTypes >(args) ...);
draw(object);
}

/*! Add render block to sorting queue. */
void draw(uint32_t type, DrawableRenderBlock* renderBlock);

/*! Merge compute blocks into render queue. */
void mergeCompute();
/*! Merge sorting queues into draw queue. */
void mergePriorityIntoDraw(uint32_t priorities);

/*! Merge sorting queues into render queue. */
void mergeDraw(uint32_t priorities);
/*! Merge compute queues into render queue. */
void mergeComputeIntoRender();

/*! Merge draw queues into render queue. */
void mergeDrawIntoRender();

/*! Render blocks queued in render queue. */
void render(IRenderView* renderView) const;
Expand All @@ -109,9 +120,10 @@ class T_DLLCLASS RenderContext : public Object
AutoPtr< uint8_t, AllocFreeAlign > m_heap;
uint8_t* m_heapEnd;
uint8_t* m_heapPtr;
AlignedVector< ComputeRenderBlock* > m_computeQueue;
AlignedVector< RenderBlock* > m_renderQueue;
AlignedVector< RenderBlock* > m_computeQueue;
AlignedVector< DrawableRenderBlock* > m_priorityQueue[6];
AlignedVector< RenderBlock* > m_drawQueue;
AlignedVector< RenderBlock* > m_renderQueue;
};

}
Loading

0 comments on commit 5170fab

Please sign in to comment.