Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
RenderQueue.cpp
Go to the documentation of this file.
1
2
4
14
15namespace Divide
16{
19 _stage( stage )
20 {
21 }
22
24 {
26 switch ( rbType )
27 {
29 {
30 // Opaque items should be rendered front to back in depth passes for early-Z reasons
33 } break;
35 {
36 sortOrder = RenderingOrder::NONE;
37 } break;
42 {
44 } break;
46 {
47 // We are using weighted blended OIT. State is fine (and faster)
48 // Use an override one level up from this if we need a regular forward-style pass
49 sortOrder = RenderingOrder::BY_STATE;
50 } break;
51 default:
53 {
54 Console::errorfn( LOCALE_STR( "ERROR_INVALID_RENDER_BIN_CREATION" ) );
55 } break;
56 };
57
58 return sortOrder;
59 }
60
62 {
63 switch ( node->getNode().type() )
64 {
72 {
73 constexpr U32 compareMask = to_U32( ComponentType::SPOT_LIGHT ) |
77 if ( node->componentMask() & compareMask )
78 {
80 }
81 } break;
82 default:
83 {
84 if ( Is3DObject( node->getNode().type() ) )
85 {
86 // Check if the object has a material with transparency/translucency
87 if ( matInstance != INVALID_HANDLE<Material> && Get(matInstance)->hasTransparency() )
88 {
89 // Add it to the appropriate bin if so ...
91 }
92
93 //... else add it to the general geometry bin
95 }
96 } break;
98 }
99
101 }
102
104 const RenderStagePass stagePass,
105 const F32 minDistToCameraSq,
106 const RenderBinType targetBinType )
107 {
108 const RenderingComponent* const renderingCmp = sgn->get<RenderingComponent>();
109 // We need a rendering component to render the node
110 assert( renderingCmp != nullptr );
111 RenderBinType rbType = getBinForNode( sgn, renderingCmp->getMaterialInstance() );
112 assert( rbType != RenderBinType::COUNT );
113
114 if ( targetBinType == RenderBinType::COUNT || rbType == targetBinType )
115 {
116 getBin(rbType).addNodeToBin(sgn, stagePass, minDistToCameraSq);
117 }
118 }
119
121 {
123
124 if ( params._binType == RenderBinType::COUNT )
125 {
126 if ( !params._filterByBinType )
127 {
128 for ( const RenderBin& renderBin : _renderBins )
129 {
130 renderBin.populateRenderQueue( params._stagePass, queueInOut );
131 }
132 }
133 else
134 {
135 // Why are we allowed to exclude everything? idk.
136 NOP();
137 }
138 }
139 else
140 {
141 if ( !params._filterByBinType )
142 {
143 if ( params._binType != RenderBinType::COUNT)
144 {
145 getBin(params._binType).populateRenderQueue(params._stagePass, queueInOut);
146 }
147 }
148 else
149 {
150 for ( U8 i = 0u; i < to_base( RenderBinType::COUNT ); ++i )
151 {
152 if ( i == to_base( params._binType ) )
153 {
154 continue;
155 }
156 _renderBins[i].populateRenderQueue( params._stagePass, queueInOut );
157 }
158 }
159 }
160 }
161
162 void RenderQueue::postRender( const SceneRenderState& renderState, const RenderStagePass stagePass, GFX::CommandBuffer& bufferInOut )
163 {
164 for ( RenderBin& renderBin : _renderBins )
165 {
166 renderBin.postRender( renderState, stagePass, bufferInOut );
167 }
168 }
169
170 void RenderQueue::sort( const RenderStagePass stagePass, const RenderBinType targetBinType, const RenderingOrder renderOrder )
171 {
173
174 // How many elements should a render bin contain before we decide that sorting should happen on a separate thread
175 constexpr U16 k_threadBias = 64u;
176
177 if ( targetBinType != RenderBinType::COUNT )
178 {
179 const RenderingOrder sortOrder = renderOrder == RenderingOrder::COUNT ? getSortOrder( stagePass, targetBinType ) : renderOrder;
180 _renderBins[to_base( targetBinType )].sort( targetBinType, sortOrder );
181 }
182 else
183 {
184 bool sortTaskDirty = false;
186 Task* sortTask = CreateTask( TASK_NOP );
187 for (U8 i = 0u; i < to_base( RenderBinType::COUNT ); ++i)
188 {
189 RenderBin& renderBin = _renderBins[i];
190 const RenderBinType rbType = static_cast<RenderBinType>(i);
191
192 if ( renderBin.getBinSize() > k_threadBias )
193 {
194 const RenderingOrder sortOrder = renderOrder == RenderingOrder::COUNT ? getSortOrder( stagePass, rbType ) : renderOrder;
195 Start( *CreateTask( sortTask,
196 [&renderBin, rbType, sortOrder]( const Task& )
197 {
198 renderBin.sort( rbType, sortOrder );
199 } ),
200 pool );
201 sortTaskDirty = true;
202 }
203 }
204
205 if ( sortTaskDirty )
206 {
207 Start( *sortTask, pool );
208 }
209
210 for ( U8 i = 0u; i < to_base( RenderBinType::COUNT ); ++i )
211 {
212 RenderBin& renderBin = _renderBins[i];
213 if ( renderBin.getBinSize() <= k_threadBias )
214 {
215 const RenderBinType rbType = static_cast<RenderBinType>(i);
216 const RenderingOrder sortOrder = renderOrder == RenderingOrder::COUNT ? getSortOrder( stagePass, rbType ) : renderOrder;
217 renderBin.sort( rbType, sortOrder );
218 }
219 }
220
221 if ( sortTaskDirty )
222 {
223 Wait( *sortTask, pool );
224 }
225 }
226 }
227
228 void RenderQueue::clear( const RenderBinType targetBinType ) noexcept
229 {
230 if ( targetBinType == RenderBinType::COUNT )
231 {
232 for ( RenderBin& renderBin : _renderBins )
233 {
234 renderBin.clear();
235 }
236 }
237 else
238 {
239 for ( U8 i = 0u; i < to_base( RenderBinType::COUNT ); ++i )
240 {
241 if ( i == to_base( targetBinType ) )
242 {
243 _renderBins[i].clear();
244 }
245 }
246 }
247 }
248
250 {
252
253 size_t countOut = 0u;
254
255 if ( binTypes.empty() )
256 {
257 for ( U8 i = 0u; i < to_base( RenderBinType::COUNT ); ++i )
258 {
259 countOut += _renderBins[i].getSortedNodes( queuesOut[i] );
260 }
261 }
262 else
263 {
264 for ( const RenderBinType type : binTypes )
265 {
266 countOut += getBin( type ).getSortedNodes( queuesOut[to_base( type )] );
267 }
268 }
269 return countOut;
270 }
271
272} //namespace Divide
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_UNEXPECTED_CALL()
#define NOP()
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
Kernel & parent() noexcept
The kernel is the main system that connects all of our various systems: windows, gfx,...
Definition: Kernel.h:81
FORCE_INLINE PlatformContext & platformContext() noexcept
Definition: Kernel.h:129
TaskPool & taskPool(const TaskPoolType type) noexcept
This class contains a list of "RenderBinItem"'s and stores them sorted depending on designation.
Definition: RenderBin.h:112
void addNodeToBin(const SceneGraphNode *sgn, RenderStagePass renderStagePass, F32 minDistToCameraSq)
Definition: RenderBin.cpp:123
void populateRenderQueue(RenderStagePass stagePass, RenderQueuePackages &queueInOut) const
Definition: RenderBin.cpp:140
U16 getSortedNodes(SortedQueue &nodes) const
Definition: RenderBin.cpp:108
std::array< SortedQueue, to_base(RenderBinType::COUNT)> SortedQueues
Definition: RenderBin.h:116
void sort(RenderBinType type, RenderingOrder renderOrder)
Definition: RenderBin.cpp:16
U16 getBinSize() const noexcept
Definition: RenderBin.cpp:103
RenderingOrder getSortOrder(RenderStagePass stagePass, RenderBinType rbType) const
Definition: RenderQueue.cpp:23
RenderBinArray _renderBins
Definition: RenderQueue.h:85
RenderBinType getBinForNode(const SceneGraphNode *node, Handle< Material > matInstance)
Definition: RenderQueue.cpp:61
void populateRenderQueues(const PopulateQueueParams &params, RenderQueuePackages &queueInOut)
void clear(RenderBinType targetBinType=RenderBinType::COUNT) noexcept
const RenderBin & getBin(const RenderBinType rbType) const noexcept
Definition: RenderQueue.h:71
void sort(RenderStagePass stagePass, RenderBinType targetBinType=RenderBinType::COUNT, RenderingOrder renderOrder=RenderingOrder::COUNT)
void postRender(const SceneRenderState &renderState, RenderStagePass stagePass, GFX::CommandBuffer &bufferInOut)
size_t getSortedQueues(const vector< RenderBinType > &binTypes, RenderBin::SortedQueues &queuesOut) const
void addNodeToQueue(const SceneGraphNode *sgn, RenderStagePass stagePass, F32 minDistToCameraSq, RenderBinType targetBinType=RenderBinType::COUNT)
RenderQueue(Kernel &parent, RenderStage stage)
Definition: RenderQueue.cpp:17
Handle< Material > getMaterialInstance() const noexcept
FORCE_INLINE T * get() const
Returns a pointer to a specific component. Returns null if the SGN does not have the component reques...
T & getNode() noexcept
constexpr Optick::Category::Type GameLogic
Definition: Profiler.h:63
constexpr Optick::Category::Type Scene
Definition: Profiler.h:66
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
eastl::fixed_vector< RenderQueuePackage, Config::MAX_VISIBLE_NODES, false > RenderQueuePackages
Definition: RenderBin.h:109
static constexpr bool IsDepthPass(const RenderStagePass stagePass) noexcept
constexpr U32 to_U32(const T value)
void Wait(const Task &task, TaskPool &pool)
Definition: Task.cpp:20
RenderBinType
Definition: RenderBin.h:73
@ WATER
Water might end up being as expensive as terrain, so these will probably need reshuffling.
@ IMPOSTOR
Impostors should be overlayed over everything since they are a debugging tool.
@ TERRAIN_AUX
E.g. infinite ground plane.
@ TRANSLUCENT
Translucent items use a [0.0...1.0] alpha value supplied via an opacity map or via the albedo's alpha...
@ SKY
Sky needs to be drawn after ALL opaque geometry to save on fillrate.
@ TERRAIN
Actual terrain. It should cover most of the remaining empty screen space.
@ OPAQUE
Opaque objects will occlude a lot of the terrain and terrain is REALLY expensive to render,...
uint8_t U8
Task * CreateTask(Predicate &&threadedFunction, bool allowedInIdle=true)
Definition: TaskPool.inl:45
constexpr auto TASK_NOP
Definition: Task.h:57
eastl::vector< Type > vector
Definition: Vector.h:42
Project & parent
Definition: DefaultScene.h:41
uint16_t U16
FORCE_INLINE constexpr bool Is3DObject(const SceneNodeType type) noexcept
Definition: SceneNodeFwd.h:98
void Start(Task &task, TaskPool &pool, TaskPriority priority=TaskPriority::DONT_CARE, const DELEGATE< void > &onCompletionFunction={})
Definition: Task.cpp:9
RenderingOrder
Definition: RenderBin.h:63
FORCE_INLINE T * Get(const Handle< T > handle)
uint32_t U32
constexpr auto to_base(const Type value) -> Type
static NO_INLINE void errorfn(const char *format, T &&... args)