Skip to content

Commit a4d3257

Browse files
more ITransformTreeManager design
1 parent 4730007 commit a4d3257

File tree

1 file changed

+71
-29
lines changed

1 file changed

+71
-29
lines changed

include/nbl/scene/ITransformTreeManager.h

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@ namespace nbl
1313
namespace scene
1414
{
1515

16-
16+
// TODO: split into ITT and ITTM because no need for multiple pipeline copies for multiple TTs
1717
class ITransformTreeManager : public virtual core::IReferenceCounted
1818
{
1919
public:
2020
using node_t = uint32_t;
2121
_NBL_STATIC_INLINE_CONSTEXPR node_t invalid_node = video::IPropertyPool::invalid_index;
2222

2323
using timestamp_t = video::IGPUAnimationLibrary::timestamp_t;
24+
// two timestamp values are reserved for initialization
25+
_NBL_STATIC_INLINE_CONSTEXPR timestamp_t min_timestamp = 0u;
26+
_NBL_STATIC_INLINE_CONSTEXPR timestamp_t max_timestamp = 0xfffffffdu;
2427

28+
_NBL_STATIC_INLINE_CONSTEXPR uint32_t parent_prop_ix = 0u;
2529
_NBL_STATIC_INLINE_CONSTEXPR uint32_t global_transform_prop_ix = 3u;
2630
private:
2731
using parent_t = node_t;
@@ -37,6 +41,42 @@ class ITransformTreeManager : public virtual core::IReferenceCounted
3741
global_transform_t,recomputed_stamp_t
3842
>;
3943

44+
struct RelativeTransformModificationRequest
45+
{
46+
public:
47+
enum E_TYPE : uint32_t
48+
{
49+
ET_OVERWRITE=0u, // exchange the value `This(vertex)`
50+
ET_CONCATENATE_AFTER=1u, // apply transform after `This(Previous(vertex))`
51+
ET_CONCATENATE_BEFORE=2u, // apply transform before `Previous(This(vertex))`
52+
ET_WEIGHTED_ACCUMULATE=3u, // add to existing value `(Previous+This)(vertex)`
53+
ET_COUNT
54+
};
55+
RelativeTransformModificationRequest(const E_TYPE type, const core::matrix3x4SIMD& _weightedModification) : storage(_weightedModification)
56+
{
57+
constexpr uint32_t log2ET_COUNT = 2u;
58+
static_assert(ET_COUNT<=(0x1u<<log2ET_COUNT),"Need to rewrite the type encoding routine!");
59+
60+
uint32_t typeBits[log2ET_COUNT];
61+
for (uint32_t i=0u; i<log2ET_COUNT; i++)
62+
typeBits[i] = (type>>i)&0x1u;
63+
64+
// stuff the bits into x and z components of scale (without a rotation)
65+
reinterpret_cast<uint32_t&>(storage.rows[0].x) |= typeBits[0];
66+
reinterpret_cast<uint32_t&>(storage.rows[2].z) |= typeBits[1];
67+
}
68+
RelativeTransformModificationRequest(const E_TYPE type, const core::matrix3x4SIMD& _modification, const float weight) : RelativeTransformModificationRequest(type,_modification*weight) {}
69+
70+
inline E_TYPE getType() const
71+
{
72+
uint32_t retval = reinterpret_cast<const uint32_t&>(storage.rows[0].x)&0x1u;
73+
retval |= (reinterpret_cast<const uint32_t&>(storage.rows[2].z)&0x1u)<<1u;
74+
return static_cast<E_TYPE>(retval);
75+
}
76+
private:
77+
core::matrix3x4SIMD storage;
78+
};
79+
4080
// creation
4181
static inline core::smart_refctd_ptr<ITransformTreeManager> create(video::IVideoDriver* _driver, asset::SBufferRange<video::IGPUBuffer>&& memoryBlock, core::allocator<uint8_t>&& alloc = core::allocator<uint8_t>())
4282
{
@@ -71,6 +111,10 @@ class ITransformTreeManager : public virtual core::IReferenceCounted
71111
asset::SBufferRange<video::IGPUBuffer> retval = {m_nodeStorage->getPropertyOffset(global_transform_prop_ix),m_nodeStorage->getCapacity()*sizeof(global_transform_t),m_nodeStorage->getMemoryBlock().buffer};
72112
return retval;
73113
}
114+
115+
// need to at least initialize with the parent node property with the recompute and update timestamps at 0xfffffffeu and 0xffffffffu respectively
116+
// but a function with optional relative transform would be nice
117+
// need our own compute shader to initialize the properties ;(
74118
#if 0
75119
//
76120
struct AllocationRequest
@@ -104,21 +148,23 @@ class ITransformTreeManager : public virtual core::IReferenceCounted
104148
}
105149

106150
// TODO: make all these functions take a pipeline barrier type (future new API) with default being a full barrier
107-
void updateLocalTransforms(const asset::SBufferBinding<video::IGPUBuffer>& dispatchIndirectParameters, const asset::SBufferBinding<video::IGPUBuffer>& requestBuffer) //do we take a per-request nodeID buffer too?
151+
template<typename... Args>
152+
inline void updateLocalTransforms(Args&&... args)
108153
{
109-
assert(false); // TODO
154+
soleUpdateOrFusedRecompute_impl(m_updatePipeline.get(),std::forward<Args>(args)...);
110155
}
111156
//
112-
void recomputeGlobalTransforms(/*dispatchIndirectParams,nodeList*/)
157+
void recomputeGlobalTransforms(const asset::SBufferBinding<video::IGPUBuffer>& dispatchIndirectParameters,const asset::SBufferBinding<video::IGPUBuffer>& nodeIDBuffer)
113158
{
114159
// TODO: do it properly
115160
auto out = getGlobalTransformationBufferRange();
116161
m_driver->copyBuffer(m_nodeStorage->getMemoryBlock().buffer.get(),out.buffer.get(),m_nodeStorage->getPropertyOffset(1u),out.offset,out.size);
117162
}
118163
//
119-
void updateAndRecomputeGlobalTransforms(/*Same args as `updateLocalTransforms` and `recomputeGlobalTransforms`*/)
164+
template<typename... Args>
165+
inline void updateAndRecomputeTransforms(Args&&... args)
120166
{
121-
assert(false); // TODO
167+
soleUpdateOrFusedRecompute_impl(m_updateAndRecomputePipeline.get(),std::forward<Args>(args)...);
122168
}
123169

124170
//
@@ -141,34 +187,30 @@ class ITransformTreeManager : public virtual core::IReferenceCounted
141187
}
142188
~ITransformTreeManager()
143189
{
144-
//
190+
// everything drops itself automatically
145191
}
146192

147-
#if 0
148-
struct RootNodeParentIterator
193+
void soleUpdateOrFusedRecompute_impl(
194+
const video::IGPUComputePipeline* pipeline,
195+
const asset::SBufferBinding<video::IGPUBuffer>& dispatchIndirectParameters,
196+
const asset::SBufferBinding<video::IGPUBuffer>& nodeIDBuffer, // first uint in the nodeIDBuffer is used to denote how many requests we have
197+
const asset::SBufferBinding<video::IGPUBuffer>& modificationRequestBuffer,
198+
const asset::SBufferBinding<video::IGPUBuffer>& modificationRequestTimestampBuffer
199+
)
149200
{
150-
inline RootNodeParentIterator& operator++()
151-
{
152-
//do nothing
153-
return *this;
154-
}
155-
inline RootNodeParentIterator operator++(int)
156-
{
157-
//do nothing
158-
}
159-
160-
inline node_t operator*() const
161-
{
162-
return invalid_node;
163-
}
164-
165-
//using iterator_category = typename std::iterator_traits::;
166-
//using difference_type = ptrdiff_t;
167-
using value_type = node_t;
168-
};
169-
#endif
201+
// TODO: first a dispatch to sort the modification requests and timestamps according to node frequency
202+
m_driver->bindComputePipeline(pipeline);
203+
assert(false); // TODO: get a descriptor set to populate with our input buffers (plus indirect dispatch buffer + nodeIDBuffer if pipeline==m_updateAndRecomputePipeline)
204+
const video::IGPUDescriptorSet* descSets[] = { m_transformHierarchyDS.get(),nullptr };
205+
m_driver->bindDescriptorSets(video::EPBP_COMPUTE,pipeline->getLayout(),0u,2u,descSets,nullptr);
206+
m_driver->dispatchIndirect(dispatchIndirectParameters.buffer.get(),dispatchIndirectParameters.offset);
207+
// TODO: pipeline barrier for UBO, SSBO and TBO and if pipeline==m_updatePipeline then COMMAND_BIT too
208+
}
209+
170210
video::IVideoDriver* m_driver;
171211
core::smart_refctd_ptr<property_pool_t> m_nodeStorage;
212+
core::smart_refctd_ptr<video::IGPUComputePipeline> m_updatePipeline,m_recomputePipeline,m_updateAndRecomputePipeline;
213+
core::smart_refctd_ptr<video::IGPUDescriptorSet> m_transformHierarchyDS;
172214
};
173215

174216

0 commit comments

Comments
 (0)