Skip to content

Commit

Permalink
api: Add ShadingSystem query to ask if attribute derivatives are requ…
Browse files Browse the repository at this point in the history
…ested. (#1932)

This PR adds an API to ask the shading system if derivatives are required for attributes needed by a shader group.

Signed-off-by: Curtis Black <[email protected]>
  • Loading branch information
curtisblack authored Jan 31, 2025
1 parent b795e3e commit e2caeb0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 11 deletions.
6 changes: 6 additions & 0 deletions src/include/OSL/oslexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,9 @@ class OSLEXECPUBLIC ShadingSystem {
/// ptr userdata_offsets Retrieves a pointer to the array of
/// int describing the userdata offsets
/// within the heap.
/// ptr userdata_derivs Retrieves a pointer to the array of
/// bools (as bytes) describing if derivatives
/// are requested for each userdata.
/// int num_attributes_needed The number of attribute/scope pairs that
/// are known to be queried by the group (the
/// length of the attributes_needed and
Expand All @@ -499,6 +502,9 @@ class OSLEXECPUBLIC ShadingSystem {
/// in the attributes_needed array.
/// ptr attribute_types Retrieves a pointer to the array of
/// TypeDesc describing the attributes.
/// ptr attribute_derivs Retrieves a pointer to the array of
/// bools (as bytes) describing if derivatives
/// are requested for each attribute.
/// int unknown_attributes_needed Nonzero if additional attributes may be
/// needed, whose names will not be known
/// until the shader actually runs.
Expand Down
7 changes: 5 additions & 2 deletions src/liboslexec/oslexec_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,11 @@ struct AttributeNeeded {
ustring name;
ustring scope;
TypeDesc type;
bool derivs;

AttributeNeeded(ustring name, ustring scope = ustring(),
TypeDesc type = TypeUnknown)
: name(name), scope(scope), type(type)
TypeDesc type = TypeUnknown, bool derivs = false)
: name(name), scope(scope), type(type), derivs(derivs)
{
}

Expand All @@ -240,6 +241,7 @@ struct AttributeNeeded {
// Ignore vector semantics
// if (a.type.vecsemantics != b.type.vecsemantics)
// return a.type.vecsemantics < b.type.vecsemantics;
// Do not sort based on derivs
return false; // they are equal
}
};
Expand Down Expand Up @@ -2035,6 +2037,7 @@ class ShaderGroup {
std::vector<ustring> m_attributes_needed;
std::vector<ustring> m_attribute_scopes;
std::vector<TypeDesc> m_attribute_types;
std::vector<char> m_attribute_derivs;
std::vector<ustring> m_renderer_outputs; ///< Names of renderer outputs
std::vector<SymLocationDesc> m_symlocs; ///< SORTED!!
bool m_unknown_textures_needed;
Expand Down
30 changes: 21 additions & 9 deletions src/liboslexec/runtimeoptimize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3369,39 +3369,51 @@ RuntimeOptimizer::run()
Symbol* sym1 = opargsym(op, 1);
OSL_DASSERT(sym1 && sym1->typespec().is_string());
if (sym1->is_constant()) {
const auto insert = [&](const AttributeNeeded& attr) {
auto found = m_attributes_needed.find(attr);
if (found == m_attributes_needed.end())
m_attributes_needed.insert(attr);
else if (attr.derivs && !found->derivs) {
m_attributes_needed.erase(found);
m_attributes_needed.insert(attr);
}
};
if (op.nargs() == 3) {
Symbol* sym2 = opargsym(op, 2);
// getattribute( attributename, result )
m_attributes_needed.insert(
AttributeNeeded(sym1->get_string(), ustring(),
sym2->typespec().simpletype()));
insert(AttributeNeeded(sym1->get_string(), ustring(),
sym2->typespec().simpletype(),
sym2->has_derivs()));
} else if (op.nargs() == 4) {
Symbol* sym2 = opargsym(op, 2);
Symbol* sym3 = opargsym(op, 3);
if (sym2->typespec().is_string()) {
// getattribute( scopename, attributename, result )
if (sym2->is_constant()) {
m_attributes_needed.insert(AttributeNeeded(
insert(AttributeNeeded(
sym2->get_string(), sym1->get_string(),
sym3->typespec().simpletype()));
sym3->typespec().simpletype(),
sym3->has_derivs()));
} else {
m_unknown_attributes_needed = true;
}
} else {
// getattribute( attributename, arrayindex, result )
m_attributes_needed.insert(
insert(
AttributeNeeded(sym1->get_string(), ustring(),
sym3->typespec().simpletype()));
sym3->typespec().simpletype(),
sym3->has_derivs()));
}
} else if (op.nargs() == 5) {
Symbol* sym2 = opargsym(op, 2);
Symbol* sym4 = opargsym(op, 4);
if (sym2->typespec().is_string()) {
// getattribute( scopename, attributename, arrayindex, result )
if (sym2->is_constant()) {
m_attributes_needed.insert(AttributeNeeded(
insert(AttributeNeeded(
sym2->get_string(), sym1->get_string(),
sym4->typespec().simpletype()));
sym4->typespec().simpletype(),
sym4->has_derivs()));
} else {
m_unknown_attributes_needed = true;
}
Expand Down
6 changes: 6 additions & 0 deletions src/liboslexec/shadingsys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2282,6 +2282,11 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
*(TypeDesc**)val = n ? &group->m_attribute_types[0] : NULL;
return true;
}
if (name == "attribute_derivs" && type.basetype == TypeDesc::PTR) {
size_t n = group->m_attribute_derivs.size();
*(char**)val = n ? &group->m_attribute_derivs[0] : NULL;
return true;
}
if (name == "unknown_attributes_needed" && type == TypeInt) {
*(int*)val = (int)group->m_unknown_attributes_needed;
return true;
Expand Down Expand Up @@ -3792,6 +3797,7 @@ ShadingSystemImpl::optimize_group(ShaderGroup& group, ShadingContext* ctx,
group.m_attributes_needed.push_back(f.name);
group.m_attribute_scopes.push_back(f.scope);
group.m_attribute_types.push_back(f.type);
group.m_attribute_derivs.push_back(f.derivs);
}
group.m_optimized = true;

Expand Down

0 comments on commit e2caeb0

Please sign in to comment.