24 enum class ValueType {
32 constexpr
int tot_variable_value_types = 6;
49 static inline constexpr ValueType
static_type = ValueType::GVArray;
61 static inline constexpr ValueType
static_type = ValueType::Span;
72 static inline constexpr ValueType
static_type = ValueType::GVVectorArray;
82 static inline constexpr ValueType
static_type = ValueType::GVectorArray;
94 static inline constexpr ValueType
static_type = ValueType::OneSingle;
105 static inline constexpr ValueType
static_type = ValueType::OneVector;
113 static_assert(std::is_trivially_destructible_v<VariableValue_GVArray>);
114 static_assert(std::is_trivially_destructible_v<VariableValue_Span>);
115 static_assert(std::is_trivially_destructible_v<VariableValue_GVVectorArray>);
116 static_assert(std::is_trivially_destructible_v<VariableValue_GVectorArray>);
117 static_assert(std::is_trivially_destructible_v<VariableValue_OneSingle>);
118 static_assert(std::is_trivially_destructible_v<VariableValue_OneVector>);
132 static constexpr
inline int min_alignment = 64;
141 std::array<Stack<VariableValue *>, tot_variable_value_types> variable_value_free_lists_;
151 static constexpr
inline int small_value_max_size = 16;
152 static constexpr
inline int small_value_max_alignment = 8;
163 return this->obtain<VariableValue_GVArray>(varray);
168 return this->obtain<VariableValue_GVVectorArray>(varray);
173 return this->obtain<VariableValue_Span>(
buffer,
false);
183 if (alignment > min_alignment) {
189 small_value_max_alignment) ?
190 &small_span_buffers_free_list_ :
191 span_buffers_free_lists_.
lookup_ptr(element_size);
192 if (stack ==
nullptr || stack->
is_empty()) {
194 std::max<int64_t>(element_size, small_value_max_size) *
size, min_alignment);
202 return this->obtain<VariableValue_Span>(
buffer,
true);
207 return this->obtain<VariableValue_GVectorArray>(
data,
false);
213 return this->obtain<VariableValue_GVectorArray>(*vector_array,
true);
218 const bool is_small =
type.can_exist_in_buffer(small_value_max_size,
219 small_value_max_alignment);
220 Stack<void *> &stack = is_small ? small_single_value_free_list_ :
225 std::max<int>(small_value_max_size,
type.size()),
226 std::max<int>(small_value_max_alignment,
type.alignment()));
231 return this->obtain<VariableValue_OneSingle>(
buffer);
237 return this->obtain<VariableValue_OneVector>(*vector_array);
242 switch (value->
type) {
243 case ValueType::GVArray: {
246 case ValueType::Span: {
248 if (value_typed->owned) {
252 small_value_max_alignment) ?
253 small_span_buffers_free_list_ :
255 buffers.
push(value_typed->data);
259 case ValueType::GVVectorArray: {
262 case ValueType::GVectorArray: {
264 if (value_typed->owned) {
265 delete &value_typed->
data;
269 case ValueType::OneSingle: {
272 if (value_typed->is_initialized) {
273 type.destruct(value_typed->data);
275 const bool is_small =
type.can_exist_in_buffer(small_value_max_size,
276 small_value_max_alignment);
278 small_single_value_free_list_.
push(value_typed->data);
285 case ValueType::OneVector: {
287 delete &value_typed->
data;
297 template<
typename T,
typename... Args>
T *obtain(Args &&...args)
299 static_assert(std::is_base_of_v<VariableValue, T>);
303 return new (
buffer)
T(std::forward<Args>(args)...);
305 return new (stack.
pop())
T(std::forward<Args>(args)...);
335 case ValueType::GVArray:
336 return this->value_as<VariableValue_GVArray>()->data.is_single();
337 case ValueType::Span:
339 case ValueType::GVVectorArray:
340 return this->value_as<VariableValue_GVVectorArray>()->data.is_single_vector();
341 case ValueType::GVectorArray:
343 case ValueType::OneSingle:
345 case ValueType::OneVector:
370 case ValueType::GVArray: {
371 params.add_readonly_single_input(this->value_as<VariableValue_GVArray>()->
data);
374 case ValueType::Span: {
375 const void *
data = this->value_as<VariableValue_Span>()->data;
377 params.add_readonly_single_input(span);
380 case ValueType::GVVectorArray: {
381 params.add_readonly_vector_input(this->value_as<VariableValue_GVVectorArray>()->
data);
384 case ValueType::GVectorArray: {
385 params.add_readonly_vector_input(this->value_as<VariableValue_GVectorArray>()->
data);
388 case ValueType::OneSingle: {
389 const auto *value_typed = this->value_as<VariableValue_OneSingle>();
392 params.add_readonly_single_input(gpointer);
395 case ValueType::OneVector: {
396 params.add_readonly_vector_input(this->value_as<VariableValue_OneVector>()->
data[0]);
426 this->value_as<VariableValue_GVArray>()->
data.materialize_to_uninitialized(
427 full_mask, new_value->
data);
429 else if (
value_->
type == ValueType::OneSingle) {
430 auto *old_value_typed_ = this->value_as<VariableValue_OneSingle>();
431 if (old_value_typed_->is_initialized) {
433 type.fill_construct_indices(old_value_typed_->data, new_value->
data, full_mask);
455 if (
value_->
type == ValueType::GVVectorArray) {
457 new_value->
data.
extend(full_mask, this->value_as<VariableValue_GVVectorArray>()->
data);
459 else if (
value_->
type == ValueType::OneVector) {
461 const GSpan vector = this->value_as<VariableValue_OneVector>()->data[0];
488 case ValueType::Span: {
489 void *
data = this->value_as<VariableValue_Span>()->data;
491 params.add_single_mutable(span);
494 case ValueType::GVectorArray: {
495 params.add_vector_mutable(this->value_as<VariableValue_GVectorArray>()->
data);
498 case ValueType::GVArray:
499 case ValueType::GVVectorArray:
500 case ValueType::OneSingle:
501 case ValueType::OneVector: {
520 case ValueType::Span: {
521 void *
data = this->value_as<VariableValue_Span>()->data;
523 params.add_uninitialized_single_output(span);
526 case ValueType::GVectorArray: {
527 params.add_vector_output(this->value_as<VariableValue_GVectorArray>()->
data);
530 case ValueType::GVArray:
531 case ValueType::GVVectorArray:
532 case ValueType::OneSingle:
533 case ValueType::OneVector: {
548 case ValueType::GVArray: {
549 params.add_readonly_single_input(this->value_as<VariableValue_GVArray>()->
data);
552 case ValueType::GVVectorArray: {
553 params.add_readonly_vector_input(this->value_as<VariableValue_GVVectorArray>()->
data);
556 case ValueType::OneSingle: {
557 const auto *value_typed = this->value_as<VariableValue_OneSingle>();
563 case ValueType::OneVector: {
564 params.add_readonly_vector_input(this->value_as<VariableValue_OneVector>()->
data);
567 case ValueType::Span:
568 case ValueType::GVectorArray: {
578 if (value_ !=
nullptr &&
ELEM(
value_->
type, ValueType::OneSingle, ValueType::OneVector)) {
588 this->value_as<VariableValue_GVArray>()->
data.get_internal_single_to_uninitialized(
608 if (
value_->
type == ValueType::GVVectorArray) {
610 this->value_as<VariableValue_GVVectorArray>()->data;
613 else if (
value_->
type == ValueType::GVectorArray) {
637 case ValueType::OneSingle: {
638 auto *value_typed = this->value_as<VariableValue_OneSingle>();
643 case ValueType::OneVector: {
644 params.add_vector_mutable(this->value_as<VariableValue_OneVector>()->
data);
647 case ValueType::GVArray:
648 case ValueType::Span:
649 case ValueType::GVVectorArray:
650 case ValueType::GVectorArray: {
667 case ValueType::OneSingle: {
668 auto *value_typed = this->value_as<VariableValue_OneSingle>();
670 params.add_uninitialized_single_output(
673 value_typed->is_initialized =
true;
676 case ValueType::OneVector: {
677 auto *value_typed = this->value_as<VariableValue_OneVector>();
679 params.add_vector_output(value_typed->data);
682 case ValueType::GVArray:
683 case ValueType::Span:
684 case ValueType::GVVectorArray:
685 case ValueType::GVectorArray: {
711 case ValueType::GVArray: {
712 if (
mask.size() < full_mask.
size()) {
718 type.destruct_indices(this->value_as<VariableValue_Span>()->
data,
mask);
722 case ValueType::Span: {
724 type.destruct_indices(this->value_as<VariableValue_Span>()->
data,
mask);
727 case ValueType::GVVectorArray: {
728 if (
mask.size() < full_mask.
size()) {
734 this->value_as<VariableValue_GVectorArray>()->data.clear(
mask);
738 case ValueType::GVectorArray: {
739 this->value_as<VariableValue_GVectorArray>()->data.clear(
mask);
742 case ValueType::OneSingle: {
743 auto *value_typed = this->value_as<VariableValue_OneSingle>();
748 type.destruct(value_typed->data);
749 value_typed->is_initialized =
false;
753 case ValueType::OneVector: {
754 auto *value_typed = this->value_as<VariableValue_OneVector>();
764 const bool should_self_destruct = new_tot_initialized == 0 &&
766 return should_self_destruct;
775 case ValueType::GVArray: {
776 const VArray<bool> varray = this->value_as<VariableValue_GVArray>()->data.typed<
bool>();
777 for (
const int i :
mask) {
778 r_indices[varray[i]].append(i);
782 case ValueType::Span: {
783 const Span<bool> span((
bool *)this->value_as<VariableValue_Span>()->
data,
784 mask.min_array_size());
785 for (
const int i :
mask) {
786 r_indices[span[i]].append(i);
790 case ValueType::OneSingle: {
791 auto *value_typed = this->value_as<VariableValue_OneSingle>();
793 const bool condition = *(
bool *)value_typed->data;
794 r_indices[condition].extend(
mask);
797 case ValueType::GVVectorArray:
798 case ValueType::GVectorArray:
799 case ValueType::OneVector: {
810 return static_cast<T *
>(
value_);
817 return static_cast<T *
>(
value_);
834 : value_allocator_(linear_allocator),
835 procedure_(procedure),
836 variable_states_(procedure.variables().
size()),
843 for (
const int variable_i : procedure_.
variables().index_range()) {
845 if (
state.value_ !=
nullptr) {
854 return value_allocator_;
871 bool input_is_initialized,
872 void *caller_provided_storage =
nullptr) {
873 const int tot_initialized = input_is_initialized ? full_mask_.
size() : 0;
875 VariableState &variable_state = variable_states_[variable_i];
877 variable_state.
value_ = value;
972 VariableState &variable_state = variable_states_[variable_i];
973 return variable_state;
985 if (
mask.size() < full_mask.
size()) {
989 if (
state !=
nullptr &&
state->value_ !=
nullptr && !
state->is_one()) {
1003 if (variable ==
nullptr) {
1004 r_param_variable_states[param_index] =
nullptr;
1008 r_param_variable_states[param_index] = &variable_state;
1021 VariableState *variable_state = param_variable_states[param_index];
1022 if (variable_state ==
nullptr) {
1023 params.add_ignored_single_output();
1039 VariableState *variable_state = param_variable_states[param_index];
1040 if (variable_state ==
nullptr) {
1041 params.add_ignored_single_output();
1096 if (this->is_owned) {
1097 return this->owned_indices.
as_span();
1110 return this->indices.
mask();
1115 return this->instruction !=
nullptr;
1132 if (
mask.is_empty()) {
1138 next_instructions_.
push({&instruction, std::move(new_indices)});
1151 next_instructions_.
push({&instruction, std::move(new_indices)});
1156 return next_instructions_.
is_empty();
1162 return next_instructions_.
peek();
1167 next_instructions_.
peek().instruction = &instruction;
1172 return next_instructions_.
pop();
1184 VariableStates variable_states{linear_allocator, procedure_, full_mask};
1185 variable_states.add_initial_variable_states(*
this, procedure_,
params);
1191 while (!scheduler.
is_done()) {
1194 switch (instruction.
type()) {
1206 VariableState &variable_state = variable_states.get_variable_state(*condition_var);
1219 variable_states.destruct(*variable, instr_info.
mask());
1240 VariableState &variable_state = variable_states.get_variable_state(*variable);
#define BLI_assert_unreachable()
#define UNUSED_VARS_NDEBUG(...)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a vector
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void extend(int64_t index, const GVArray &values)
static bool indices_are_valid_index_mask(Span< int64_t > indices)
int64_t min_array_size() const
void provide_buffer(void *buffer, uint size)
void * allocate(const int64_t size, const int64_t alignment)
Value & lookup_or_add_default(const Key &key)
const Value * lookup_ptr(const Key &key) const
void push(const T &value)
Span< T > as_span() const
void resize(const int64_t new_size)
void update_instruction_pointer(const MFInstruction &instruction)
void add_referenced_indices(const MFInstruction &instruction, IndexMask mask)
void add_owned_indices(const MFInstruction &instruction, Vector< int64_t > indices)
const NextInstructionInfo & peek() const
InstructionScheduler()=default
NextInstructionInfo pop()
MFInstruction * branch_true()
MFInstruction * branch_false()
const MultiFunction & fn() const
Span< MFVariable * > params()
const CPPType & vector_base_type() const
const CPPType & single_type() const
Category category() const
MFInstructionType type() const
MFDataType data_type() const
InterfaceType interface_type() const
MFParamCategory category() const
MFProcedureExecutor(const MFProcedure &procedure)
void call(IndexMask mask, MFParams params, MFContext context) const override
Span< MFVariable * > variables()
Span< ConstMFParameter > params() const
MFDataType data_type() const
int index_in_procedure() const
bool depends_on_context() const
MFParamType param_type(int param_index) const
IndexRange param_indices() const
void call_auto(IndexMask mask, MFParams params, MFContext context) const
void set_signature(const MFSignature *signature)
virtual void call(IndexMask mask, MFParams params, MFContext context) const =0
const MFSignature & signature() const
VariableValue_OneSingle * obtain_OneSingle(const CPPType &type)
ValueAllocator(LinearAllocator<> &linear_allocator)
VariableValue_GVectorArray * obtain_GVectorArray(const CPPType &type, int size)
VariableValue_GVectorArray * obtain_GVectorArray_not_owned(GVectorArray &data)
VariableValue_GVArray * obtain_GVArray(const GVArray &varray)
VariableValue_Span * obtain_Span_not_owned(void *buffer)
void release_value(VariableValue *value, const MFDataType &data_type)
VariableValue_OneVector * obtain_OneVector(const CPPType &type)
VariableValue_Span * obtain_Span(const CPPType &type, int size)
VariableValue_GVVectorArray * obtain_GVVectorArray(const GVVectorArray &varray)
void * caller_provided_storage_
void add_as_input(MFParamsBuilder ¶ms, IndexMask mask, const MFDataType &data_type) const
void ensure_is_mutable(IndexMask full_mask, const MFDataType &data_type, ValueAllocator &value_allocator)
bool is_fully_uninitialized(const IndexMask full_mask)
void add_as_output(MFParamsBuilder ¶ms, IndexMask mask, IndexMask full_mask, const MFDataType &data_type, ValueAllocator &value_allocator)
void add_as_mutable(MFParamsBuilder ¶ms, IndexMask mask, IndexMask full_mask, const MFDataType &data_type, ValueAllocator &value_allocator)
bool destruct(IndexMask mask, IndexMask full_mask, const MFDataType &data_type, ValueAllocator &value_allocator)
void add_as_mutable__one(MFParamsBuilder ¶ms, const MFDataType &data_type, ValueAllocator &value_allocator)
bool is_fully_initialized(const IndexMask full_mask)
void add_as_input__one(MFParamsBuilder ¶ms, const MFDataType &data_type) const
void ensure_is_mutable__one(const MFDataType &data_type, ValueAllocator &value_allocator)
void add_as_output__one(MFParamsBuilder ¶ms, IndexMask mask, const MFDataType &data_type, ValueAllocator &value_allocator)
const T * value_as() const
void indices_split(IndexMask mask, IndicesSplitVectors &r_indices)
void destruct_value(ValueAllocator &value_allocator, const MFDataType &data_type)
const IndexMask & full_mask() const
void destruct(const MFVariable &variable, const IndexMask &mask)
void add_as_param__one(VariableState &variable_state, MFParamsBuilder ¶ms, const MFParamType ¶m_type, const IndexMask &mask)
VariableStates(LinearAllocator<> &linear_allocator, const MFProcedure &procedure, IndexMask full_mask)
ValueAllocator & value_allocator()
VariableState & get_variable_state(const MFVariable &variable)
void add_as_param(VariableState &variable_state, MFParamsBuilder ¶ms, const MFParamType ¶m_type, const IndexMask &mask)
void add_initial_variable_states(const MFProcedureExecutor &fn, const MFProcedure &procedure, MFParams ¶ms)
ccl_global float * buffer
ccl_gpu_kernel_postfix int ccl_global int * indices
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
static void execute_call_instruction(const MFCallInstruction &instruction, const IndexMask mask, VariableStates &variable_states, const MFContext &context)
static void fill_params(const MultiFunction &fn, const IndexMask mask, MFParamsBuilder ¶ms, VariableStates &variable_states, const Span< VariableState * > param_variable_states)
static void gather_parameter_variable_states(const MultiFunction &fn, const MFCallInstruction &instruction, VariableStates &variable_states, MutableSpan< VariableState * > r_param_variable_states)
std::array< Vector< int64_t >, 2 > IndicesSplitVectors
static void fill_params__one(const MultiFunction &fn, const IndexMask mask, MFParamsBuilder ¶ms, VariableStates &variable_states, const Span< VariableState * > param_variable_states)
static bool evaluate_as_one(const MultiFunction &fn, Span< VariableState * > param_variable_states, const IndexMask &mask, const IndexMask &full_mask)
Vector< int64_t > owned_indices
IndexMask referenced_indices
InstructionIndices indices
const MFInstruction * instruction
static constexpr ValueType static_type
VariableValue_GVArray(const GVArray &data)
const GVVectorArray & data
static constexpr ValueType static_type
VariableValue_GVVectorArray(const GVVectorArray &data)
VariableValue_GVectorArray(GVectorArray &data, bool owned)
static constexpr ValueType static_type
static constexpr ValueType static_type
VariableValue_OneSingle(void *data)
VariableValue_OneVector(GVectorArray &data)
static constexpr ValueType static_type
VariableValue_Span(void *data, bool owned)
static constexpr ValueType static_type
VariableValue(ValueType type)