16 builder.
add(
"Parameter",
ParamType(param.type, param.variable->data_type()));
33constexpr int tot_variable_value_types = 6;
48 static inline constexpr ValueType
static_type = ValueType::GVArray;
60 static inline constexpr ValueType
static_type = ValueType::Span;
71 static inline constexpr ValueType
static_type = ValueType::GVVectorArray;
81 static inline constexpr ValueType
static_type = ValueType::GVectorArray;
93 static inline constexpr ValueType
static_type = ValueType::OneSingle;
102 static inline constexpr ValueType
static_type = ValueType::OneVector;
108static_assert(std::is_trivially_destructible_v<VariableValue_GVArray>);
109static_assert(std::is_trivially_destructible_v<VariableValue_Span>);
110static_assert(std::is_trivially_destructible_v<VariableValue_GVVectorArray>);
111static_assert(std::is_trivially_destructible_v<VariableValue_GVectorArray>);
112static_assert(std::is_trivially_destructible_v<VariableValue_OneSingle>);
113static_assert(std::is_trivially_destructible_v<VariableValue_OneVector>);
127 static constexpr inline int min_alignment = 64;
136 std::array<Stack<VariableValue *>, tot_variable_value_types> variable_value_free_lists_;
146 static constexpr inline int small_value_max_size = 16;
147 static constexpr inline int small_value_max_alignment = 8;
156 return this->obtain<VariableValue_GVArray>(varray);
161 return this->obtain<VariableValue_GVVectorArray>(varray);
166 return this->obtain<VariableValue_Span>(buffer,
false);
171 void *buffer =
nullptr;
173 const int64_t element_size = type.size();
174 const int64_t alignment = type.alignment();
176 if (alignment > min_alignment) {
178 buffer = linear_allocator_.
allocate(element_size * size, alignment);
181 Stack<void *> *stack = type.can_exist_in_buffer(small_value_max_size,
182 small_value_max_alignment) ?
183 &small_span_buffers_free_list_ :
184 span_buffers_free_lists_.
lookup_ptr(element_size);
185 if (stack ==
nullptr || stack->
is_empty()) {
186 buffer = linear_allocator_.
allocate(
187 std::max<int64_t>(element_size, small_value_max_size) * size, min_alignment);
191 buffer = stack->
pop();
195 return this->obtain<VariableValue_Span>(buffer,
true);
200 return this->obtain<VariableValue_GVectorArray>(data,
false);
206 return this->obtain<VariableValue_GVectorArray>(*vector_array,
true);
211 const bool is_small = type.can_exist_in_buffer(small_value_max_size,
212 small_value_max_alignment);
213 Stack<void *> &stack = is_small ? small_single_value_free_list_ :
217 buffer = linear_allocator_.
allocate(
218 std::max<int>(small_value_max_size, type.size()),
219 std::max<int>(small_value_max_alignment, type.alignment()));
222 buffer = stack.
pop();
224 return this->obtain<VariableValue_OneSingle>(buffer);
230 return this->obtain<VariableValue_OneVector>(*vector_array);
235 switch (value->type) {
236 case ValueType::GVArray: {
239 case ValueType::Span: {
241 if (value_typed->owned) {
245 small_value_max_alignment) ?
246 small_span_buffers_free_list_ :
248 buffers.push(value_typed->data);
252 case ValueType::GVVectorArray: {
255 case ValueType::GVectorArray: {
257 if (value_typed->owned) {
258 delete &value_typed->
data;
262 case ValueType::OneSingle: {
265 if (value_typed->is_initialized) {
268 const bool is_small = type.can_exist_in_buffer(small_value_max_size,
269 small_value_max_alignment);
271 small_single_value_free_list_.
push(value_typed->data);
278 case ValueType::OneVector: {
280 delete &value_typed->
data;
290 template<
typename T,
typename... Args> T *obtain(Args &&...args)
292 static_assert(std::is_base_of_v<VariableValue, T>);
295 void *buffer = linear_allocator_.
allocate(
sizeof(T),
alignof(T));
296 return new (buffer)
T(std::forward<Args>(args)...);
298 return new (stack.
pop())
T(std::forward<Args>(args)...);
328 case ValueType::GVArray:
330 case ValueType::Span:
332 case ValueType::GVVectorArray:
334 case ValueType::GVectorArray:
336 case ValueType::OneSingle:
338 case ValueType::OneVector:
363 case ValueType::GVArray: {
367 case ValueType::Span: {
370 params.add_readonly_single_input(span);
373 case ValueType::GVVectorArray: {
377 case ValueType::GVectorArray: {
381 case ValueType::OneSingle: {
385 params.add_readonly_single_input(gpointer);
388 case ValueType::OneVector: {
410 new_value = value_allocator.
obtain_Span(type, array_size);
420 full_mask, new_value->
data);
422 else if (
value_->
type == ValueType::OneSingle) {
424 if (old_value_typed_->is_initialized) {
426 type.fill_construct_indices(old_value_typed_->data, new_value->
data, full_mask);
448 if (
value_->
type == ValueType::GVVectorArray) {
452 else if (
value_->
type == ValueType::OneVector) {
481 case ValueType::Span: {
484 params.add_single_mutable(span);
487 case ValueType::GVectorArray: {
491 case ValueType::GVArray:
492 case ValueType::GVVectorArray:
493 case ValueType::OneSingle:
494 case ValueType::OneVector: {
513 case ValueType::Span: {
516 params.add_uninitialized_single_output(span);
519 case ValueType::GVectorArray: {
523 case ValueType::GVArray:
524 case ValueType::GVVectorArray:
525 case ValueType::OneSingle:
526 case ValueType::OneVector: {
541 case ValueType::GVArray: {
545 case ValueType::GVVectorArray: {
549 case ValueType::OneSingle: {
556 case ValueType::OneVector: {
560 case ValueType::Span:
561 case ValueType::GVectorArray: {
571 if (value_ !=
nullptr &&
ELEM(
value_->
type, ValueType::OneSingle, ValueType::OneVector)) {
601 if (
value_->
type == ValueType::GVVectorArray) {
606 else if (
value_->
type == ValueType::GVectorArray) {
630 case ValueType::OneSingle: {
636 case ValueType::OneVector: {
640 case ValueType::GVArray:
641 case ValueType::Span:
642 case ValueType::GVVectorArray:
643 case ValueType::GVectorArray: {
660 case ValueType::OneSingle: {
663 params.add_uninitialized_single_output(
666 value_typed->is_initialized =
true;
669 case ValueType::OneVector: {
672 params.add_vector_output(value_typed->data);
675 case ValueType::GVArray:
676 case ValueType::Span:
677 case ValueType::GVVectorArray:
678 case ValueType::GVectorArray: {
704 case ValueType::GVArray: {
705 if (mask.size() < full_mask.
size()) {
715 case ValueType::Span: {
720 case ValueType::GVVectorArray: {
721 if (mask.size() < full_mask.
size()) {
731 case ValueType::GVectorArray: {
735 case ValueType::OneSingle: {
742 value_typed->is_initialized =
false;
746 case ValueType::OneVector: {
757 const bool should_self_destruct = new_tot_initialized == 0 &&
759 return should_self_destruct;
768 case ValueType::GVArray: {
773 case ValueType::Span: {
776 mask.min_array_size());
777 mask.foreach_index([&](
const int64_t i) { r_indices[span[i]].append(i); });
780 case ValueType::OneSingle: {
783 const bool condition = *
static_cast<const bool *
>(value_typed->data);
785 indices.
reserve(indices.size() + mask.size());
786 mask.foreach_index_optimized<
int64_t>([&](
const int64_t i) { indices.append(i); });
789 case ValueType::GVVectorArray:
790 case ValueType::GVectorArray:
791 case ValueType::OneVector: {
802 return static_cast<T *
>(
value_);
809 return static_cast<T *
>(
value_);
826 : value_allocator_(linear_allocator),
827 procedure_(procedure),
828 variable_states_(procedure.variables().size()),
835 for (
const int variable_i : procedure_.
variables().index_range()) {
837 if (
state.value_ !=
nullptr) {
839 state.destruct_value(value_allocator_, variable->data_type());
846 return value_allocator_;
860 const Variable *variable = procedure.
params()[param_index].variable;
863 bool input_is_initialized,
864 void *caller_provided_storage =
nullptr) {
865 const int tot_initialized = input_is_initialized ? full_mask_.
size() : 0;
866 const int variable_i = variable->index_in_procedure();
867 VariableState &variable_state = variable_states_[variable_i];
869 variable_state.
value_ = value;
876 const GVArray &data =
params.readonly_single_input(param_index);
956 if (variable_state.
destruct(mask, full_mask_, variable.data_type(), value_allocator_)) {
957 variable_state.
destruct_value(value_allocator_, variable.data_type());
963 const int variable_i = variable.index_in_procedure();
964 VariableState &variable_state = variable_states_[variable_i];
965 return variable_state;
973 if (mask.size() < full_mask.
size()) {
977 if (
state !=
nullptr &&
state->value_ !=
nullptr && !
state->is_one()) {
991 if (variable ==
nullptr) {
992 r_param_variable_states[param_index] =
nullptr;
996 r_param_variable_states[param_index] = &variable_state;
1009 VariableState *variable_state = param_variable_states[param_index];
1010 if (variable_state ==
nullptr) {
1011 params.add_ignored_single_output();
1027 VariableState *variable_state = param_variable_states[param_index];
1028 if (variable_state ==
nullptr) {
1029 params.add_ignored_single_output();
1095 return this->indices.
mask();
1098 operator bool()
const
1100 return this->instruction !=
nullptr;
1117 if (mask.is_empty()) {
1122 next_instructions_.
push({&instruction, std::move(new_indices)});
1127 if (indices.is_empty()) {
1132 new_indices.
memory = std::make_unique<IndexMaskMemory>();
1135 next_instructions_.
push({&instruction, std::move(new_indices)});
1140 return next_instructions_.
is_empty();
1146 return next_instructions_.
peek();
1151 next_instructions_.
peek().instruction = &instruction;
1156 return next_instructions_.
pop();
1168 VariableStates variable_states{linear_allocator, procedure_, full_mask};
1169 variable_states.add_initial_variable_states(*
this, procedure_,
params);
1175 while (!scheduler.
is_done()) {
1178 switch (instruction.
type()) {
1190 VariableState &variable_state = variable_states.get_variable_state(*condition_var);
1203 variable_states.destruct(*variable, instr_info.
mask());
1223 const Variable *variable = procedure_.
params()[param_index].variable;
1224 VariableState &variable_state = variable_states.get_variable_state(*variable);
#define BLI_assert_unreachable()
#define UNUSED_VARS_NDEBUG(...)
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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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
void destruct_indices(void *ptr, const IndexMask &mask) const
void destruct(void *ptr) const
void extend(int64_t index, const GVArray &values)
void provide_buffer(void *buffer, const int64_t size)
void * allocate(const int64_t size, const int64_t alignment)
const Value * lookup_ptr(const Key &key) const
Value & lookup_or_add_default(const Key &key)
void push(const T &value)
void resize(const int64_t new_size)
void reserve(const int64_t min_capacity)
Instruction * branch_false()
Instruction * branch_true()
Span< Variable * > params()
const MultiFunction & fn() const
const CPPType & vector_base_type() const
Category category() const
const CPPType & single_type() const
NextInstructionInfo pop()
const NextInstructionInfo & peek() const
void add_referenced_indices(const Instruction &instruction, const IndexMask &mask)
void add_owned_indices(const Instruction &instruction, Vector< int64_t > indices)
void update_instruction_pointer(const Instruction &instruction)
InstructionScheduler()=default
InstructionType type() const
void set_signature(const Signature *signature)
ParamType param_type(int param_index) const
virtual void call(const IndexMask &mask, Params params, Context context) const =0
IndexRange param_indices() const
void call_auto(const IndexMask &mask, Params params, Context context) const
const DataType & data_type() const
InterfaceType interface_type() const
ParamCategory category() const
void call(const IndexMask &mask, Params params, Context context) const override
ProcedureExecutor(const Procedure &procedure)
Span< Variable * > variables()
Span< ConstParameter > params() const
void add(ParamTag< Category, T >, const char *name)
VariableValue_GVectorArray * obtain_GVectorArray(const CPPType &type, int size)
VariableValue_GVectorArray * obtain_GVectorArray_not_owned(GVectorArray &data)
ValueAllocator(LinearAllocator<> &linear_allocator)
void release_value(VariableValue *value, const DataType &data_type)
VariableValue_OneSingle * obtain_OneSingle(const CPPType &type)
VariableValue_GVArray * obtain_GVArray(const GVArray &varray)
VariableValue_Span * obtain_Span(const CPPType &type, int size)
VariableValue_Span * obtain_Span_not_owned(void *buffer)
VariableValue_GVVectorArray * obtain_GVVectorArray(const GVVectorArray &varray)
VariableValue_OneVector * obtain_OneVector(const CPPType &type)
bool is_fully_initialized(const IndexMask &full_mask)
void indices_split(const IndexMask &mask, IndicesSplitVectors &r_indices)
void destruct_value(ValueAllocator &value_allocator, const DataType &data_type)
void ensure_is_mutable(const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
const T * value_as() const
void * caller_provided_storage_
void add_as_mutable(ParamsBuilder ¶ms, const IndexMask &mask, const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
void add_as_output(ParamsBuilder ¶ms, const IndexMask &mask, const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
void add_as_input__one(ParamsBuilder ¶ms, const DataType &data_type) const
void ensure_is_mutable__one(const DataType &data_type, ValueAllocator &value_allocator)
void add_as_input(ParamsBuilder ¶ms, const IndexMask &mask, const DataType &data_type) const
void add_as_output__one(ParamsBuilder ¶ms, const IndexMask &mask, const DataType &data_type, ValueAllocator &value_allocator)
bool destruct(const IndexMask &mask, const IndexMask &full_mask, const DataType &data_type, ValueAllocator &value_allocator)
bool is_fully_uninitialized(const IndexMask &full_mask)
void add_as_mutable__one(ParamsBuilder ¶ms, const DataType &data_type, ValueAllocator &value_allocator)
VariableState & get_variable_state(const Variable &variable)
const IndexMask & full_mask() const
void destruct(const Variable &variable, const IndexMask &mask)
void add_initial_variable_states(const ProcedureExecutor &fn, const Procedure &procedure, Params ¶ms)
void add_as_param__one(VariableState &variable_state, ParamsBuilder ¶ms, const ParamType ¶m_type, const IndexMask &mask)
void add_as_param(VariableState &variable_state, ParamsBuilder ¶ms, const ParamType ¶m_type, const IndexMask &mask)
VariableStates(LinearAllocator<> &linear_allocator, const Procedure &procedure, const IndexMask &full_mask)
ValueAllocator & value_allocator()
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
int64_t min_array_size() const
void foreach_index(Fn &&fn) const
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
ccl_device_inline float4 mask(const int4 mask, const float4 a)
static bool evaluate_as_one(Span< VariableState * > param_variable_states, const IndexMask &mask, const IndexMask &full_mask)
static void gather_parameter_variable_states(const MultiFunction &fn, const CallInstruction &instruction, VariableStates &variable_states, MutableSpan< VariableState * > r_param_variable_states)
static void fill_params(const MultiFunction &fn, const IndexMask &mask, ParamsBuilder ¶ms, VariableStates &variable_states, const Span< VariableState * > param_variable_states)
static void execute_call_instruction(const CallInstruction &instruction, const IndexMask &mask, VariableStates &variable_states, const Context &context)
static void fill_params__one(const MultiFunction &fn, const IndexMask &mask, ParamsBuilder ¶ms, VariableStates &variable_states, const Span< VariableState * > param_variable_states)
std::array< Vector< int64_t >, 2 > IndicesSplitVectors
const IndexMask & mask() const
IndexMask referenced_indices
std::unique_ptr< IndexMaskMemory > memory
InstructionIndices indices
const Instruction * instruction
const IndexMask & mask() const
static constexpr ValueType static_type
VariableValue_GVArray(const GVArray &data)
const GVVectorArray & data
static constexpr ValueType static_type
VariableValue_GVVectorArray(const GVVectorArray &data)
static constexpr ValueType static_type
VariableValue_GVectorArray(GVectorArray &data, bool owned)
static constexpr ValueType static_type
VariableValue_OneSingle(void *data)
VariableValue_OneVector(GVectorArray &data)
static constexpr ValueType static_type
static constexpr ValueType static_type
VariableValue_Span(void *data, bool owned)
VariableValue(ValueType type)