Draw: Custom IDs #105261
|
@ -47,6 +47,19 @@ struct ResourceHandle {
|
|||
}
|
||||
};
|
||||
|
||||
struct ResourceThinHandle {
|
||||
ResourceHandle object_handle;
|
||||
uint raw;
|
||||
|
||||
ResourceThinHandle(const ResourceHandle object_handle, uint thin_index)
|
||||
: object_handle(object_handle), raw(thin_index) {};
|
||||
|
||||
uint resource_index() const
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
};
|
||||
|
||||
/* TODO(fclem): Move to somewhere more appropriated after cleaning up the header dependencies. */
|
||||
struct ObjectRef {
|
||||
Object *object;
|
||||
|
|
|
@ -30,6 +30,7 @@ void Manager::begin_sync()
|
|||
matrix_buf.swap();
|
||||
bounds_buf.swap();
|
||||
infos_buf.swap();
|
||||
thin_map_buf.swap();
|
||||
|
||||
/* TODO: This means the reference is kept until further redraw or manager tear-down. Instead,
|
||||
* they should be released after each draw loop. But for now, mimics old DRW behavior. */
|
||||
|
@ -52,8 +53,12 @@ void Manager::begin_sync()
|
|||
memset(infos_buf.current().data(),
|
||||
0xF0,
|
||||
matrix_buf.current().size() * sizeof(*infos_buf.current().data()));
|
||||
memset(thin_map_buf.current().data(),
|
||||
0xF0,
|
||||
thin_map_buf.current().size() * sizeof(*thin_map_buf.current().data()));
|
||||
#endif
|
||||
resource_len_ = 0;
|
||||
resource_thin_len_ = 0;
|
||||
attribute_len_ = 0;
|
||||
/* TODO(fclem): Resize buffers if too big, but with an hysteresis threshold. */
|
||||
|
||||
|
@ -101,6 +106,7 @@ void Manager::end_sync()
|
|||
matrix_buf.current().push_update();
|
||||
bounds_buf.current().push_update();
|
||||
infos_buf.current().push_update();
|
||||
thin_map_buf.current().push_update();
|
||||
attributes_buf.push_update();
|
||||
layer_attributes_buf.push_update();
|
||||
attributes_buf_legacy.push_update();
|
||||
|
@ -253,6 +259,7 @@ Manager::DataDebugOutput Manager::data_debug()
|
|||
matrix_buf.current().read();
|
||||
bounds_buf.current().read();
|
||||
infos_buf.current().read();
|
||||
/* TODO (Miguel Pozo): thin_map_buf.current().read(); */
|
||||
|
||||
Manager::DataDebugOutput output;
|
||||
output.matrices = {matrix_buf.current().data(), resource_len_};
|
||||
|
|
|
@ -43,6 +43,7 @@ class Manager {
|
|||
using ObjectMatricesBuf = StorageArrayBuffer<ObjectMatrices, 128>;
|
||||
using ObjectBoundsBuf = StorageArrayBuffer<ObjectBounds, 128>;
|
||||
using ObjectInfosBuf = StorageArrayBuffer<ObjectInfos, 128>;
|
||||
using ThinMapBuf = StorageArrayBuffer<uint, 128>;
|
||||
using ObjectAttributeBuf = StorageArrayBuffer<ObjectAttribute, 128>;
|
||||
using LayerAttributeBuf = UniformArrayBuffer<LayerAttribute, 512>;
|
||||
/**
|
||||
|
@ -76,6 +77,8 @@ class Manager {
|
|||
SwapChain<ObjectBoundsBuf, 2> bounds_buf;
|
||||
SwapChain<ObjectInfosBuf, 2> infos_buf;
|
||||
|
||||
SwapChain<ThinMapBuf, 2> thin_map_buf;
|
||||
|
||||
/**
|
||||
* Object Attributes are reference by indirection data inside ObjectInfos.
|
||||
* This is because attribute list is arbitrary.
|
||||
|
@ -106,6 +109,8 @@ class Manager {
|
|||
private:
|
||||
/** Number of resource handle recorded. */
|
||||
uint resource_len_ = 0;
|
||||
/** Number of resource thin handle recorded. */
|
||||
uint resource_thin_len_ = 0;
|
||||
/** Number of object attribute recorded. */
|
||||
uint attribute_len_ = 0;
|
||||
|
||||
|
@ -134,6 +139,8 @@ class Manager {
|
|||
const float3 &bounds_center,
|
||||
const float3 &bounds_half_extent);
|
||||
|
||||
ResourceThinHandle resource_thin_handle(const ResourceHandle object_handle);
|
||||
|
||||
/**
|
||||
* Populate additional per resource data on demand.
|
||||
*/
|
||||
|
@ -217,6 +224,12 @@ inline ResourceHandle Manager::resource_handle(const float4x4 &model_matrix,
|
|||
return ResourceHandle(resource_len_++, false);
|
||||
}
|
||||
|
||||
inline ResourceThinHandle Manager::resource_thin_handle(const ResourceHandle object_handle)
|
||||
{
|
||||
thin_map_buf.current().get_or_resize(resource_thin_len_) = object_handle.raw;
|
||||
return ResourceThinHandle(object_handle, resource_thin_len_++);
|
||||
}
|
||||
|
||||
inline void Manager::extract_object_attributes(ResourceHandle handle,
|
||||
const ObjectRef &ref,
|
||||
Span<GPUMaterial *> materials)
|
||||
|
|
|
@ -253,6 +253,16 @@ class PassBase {
|
|||
StorageBuffer<DrawCommand, true> &indirect_buffer,
|
||||
ResourceHandle handle = {0});
|
||||
|
||||
/**
|
||||
* Thin variants.
|
||||
*/
|
||||
void draw(GPUBatch *batch,
|
||||
uint instance_len = -1,
|
||||
uint vertex_len = -1,
|
||||
uint vertex_first = -1,
|
||||
ResourceThinHandle handle = {0});
|
||||
void draw(GPUBatch *batch, ResourceThinHandle handle);
|
||||
|
||||
/**
|
||||
* Record a compute dispatch call.
|
||||
*/
|
||||
|
@ -706,6 +716,32 @@ inline void PassBase<T>::draw_procedural_indirect(
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Thin Handle draw calls
|
||||
* \{ */
|
||||
|
||||
template<class T>
|
||||
inline void PassBase<T>::draw(GPUBatch *batch,
|
||||
uint instance_len,
|
||||
uint vertex_len,
|
||||
uint vertex_first,
|
||||
ResourceThinHandle handle)
|
||||
{
|
||||
if (instance_len == 0 || vertex_len == 0) {
|
||||
return;
|
||||
}
|
||||
BLI_assert(shader_);
|
||||
draw_commands_buf_.append_draw(
|
||||
headers_, commands_, batch, instance_len, vertex_len, vertex_first, handle);
|
||||
}
|
||||
|
||||
template<class T> inline void PassBase<T>::draw(GPUBatch *batch, ResourceThinHandle handle)
|
||||
{
|
||||
this->draw(batch, -1, -1, -1, handle);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Compute Dispatch Implementation
|
||||
* \{ */
|
||||
|
|
Loading…
Reference in New Issue