Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type information for needed attributes. #1650

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/include/OSL/oslexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,15 @@ class OSLEXECPUBLIC ShadingSystem {
/// ptr attributes_needed Retrieves a pointer to the ustring array
/// containing the names of the needed attributes.
/// Note that if the same attribute
/// is requested in multiple scopes, it will
/// is requested in multiple scopes, or with
/// multiple different types, it will
/// appear in the array multiple times - once for
/// each scope in which is is queried.
/// each scope/type in which is is queried.
/// ptr attribute_scopes Retrieves a pointer to a ustring array containing
/// the scopes associated with each attribute query
/// in the attributes_needed array.
/// ptr attribute_types Retrieves a pointer to the array of
/// TypeDesc describing the attributes.
/// int unknown_attributes_needed Nonzero if additional attributes may be
/// needed, whose names will not be known
/// until the shader actually runs.
Expand Down
16 changes: 14 additions & 2 deletions src/liboslexec/oslexec_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,11 @@ struct UserDataNeeded {
struct AttributeNeeded {
ustring name;
ustring scope;
TypeDesc type;

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

Expand All @@ -223,6 +225,15 @@ struct AttributeNeeded {
return a.name < b.name;
if (a.scope != b.scope)
return a.scope < b.scope;
if (a.type.basetype != b.type.basetype)
return a.type.basetype < b.type.basetype;
if (a.type.aggregate != b.type.aggregate)
return a.type.aggregate < b.type.aggregate;
if (a.type.arraylen != b.type.arraylen)
return a.type.arraylen < b.type.arraylen;
// Ignore vector semantics
// if (a.type.vecsemantics != b.type.vecsemantics)
// return a.type.vecsemantics < b.type.vecsemantics;
return false; // they are equal
}
};
Expand Down Expand Up @@ -1938,6 +1949,7 @@ class ShaderGroup {
std::vector<void*> m_userdata_init_vals;
std::vector<ustring> m_attributes_needed;
std::vector<ustring> m_attribute_scopes;
std::vector<TypeDesc> m_attribute_types;
std::vector<ustring> m_renderer_outputs; ///< Names of renderer outputs
std::vector<SymLocationDesc> m_symlocs; ///< SORTED!!
bool m_unknown_textures_needed;
Expand Down
38 changes: 28 additions & 10 deletions src/liboslexec/runtimeoptimize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3331,27 +3331,44 @@ RuntimeOptimizer::run()
OSL_DASSERT(sym1 && sym1->typespec().is_string());
if (sym1->is_constant()) {
if (op.nargs() == 3) {
Symbol* sym2 = opargsym(op, 2);
// getattribute( attributename, result )
m_attributes_needed.insert(
AttributeNeeded(sym1->get_string()));
} else {
OSL_DASSERT(op.nargs() == 4 || op.nargs() == 5);
AttributeNeeded(sym1->get_string(), ustring(),
sym2->typespec().simpletype()));
} else if (op.nargs() == 4) {
Symbol* sym2 = opargsym(op, 2);
Symbol* sym3 = opargsym(op, 3);
if (sym2->typespec().is_string()) {
// getattribute( scopename, attributename, result ) or
// getattribute( scopename, attributename, arrayindex, result )
// getattribute( scopename, attributename, result )
if (sym2->is_constant()) {
m_attributes_needed.insert(
AttributeNeeded(sym2->get_string(),
sym1->get_string()));
m_attributes_needed.insert(AttributeNeeded(
sym2->get_string(), sym1->get_string(),
sym3->typespec().simpletype()));
} else {
m_unknown_attributes_needed = true;
}
} else {
// getattribute( attributename, arrayindex, result )
m_attributes_needed.insert(
AttributeNeeded(sym1->get_string()));
AttributeNeeded(sym1->get_string(), ustring(),
sym3->typespec().simpletype()));
}
} 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(
sym2->get_string(), sym1->get_string(),
sym4->typespec().simpletype()));
} else {
m_unknown_attributes_needed = true;
}
}
} else {
OSL_DASSERT(false);
}
} else { // sym1 not constant
m_unknown_attributes_needed = true;
Expand Down Expand Up @@ -3405,7 +3422,8 @@ RuntimeOptimizer::run()
if (m_attributes_needed.size()) {
shadingcontext()->infofmt("Group needs attributes:");
for (auto&& f : m_attributes_needed)
shadingcontext()->infofmt(" {} {}", f.name, f.scope);
shadingcontext()->infofmt(" {} {} {}", f.name, f.scope,
f.type);
if (m_unknown_attributes_needed)
shadingcontext()->infofmt(
" Also may construct attribute names on the fly.");
Expand Down
6 changes: 6 additions & 0 deletions src/liboslexec/shadingsys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,11 @@ ShadingSystemImpl::getattribute(ShaderGroup* group, string_view name,
*(ustring**)val = n ? &group->m_attribute_scopes[0] : NULL;
return true;
}
if (name == "attribute_types" && type.basetype == TypeDesc::PTR) {
size_t n = group->m_attribute_types.size();
*(TypeDesc**)val = n ? &group->m_attribute_types[0] : NULL;
return true;
}
if (name == "unknown_attributes_needed" && type == TypeDesc::TypeInt) {
*(int*)val = (int)group->m_unknown_attributes_needed;
return true;
Expand Down Expand Up @@ -3563,6 +3568,7 @@ ShadingSystemImpl::optimize_group(ShaderGroup& group, ShadingContext* ctx,
for (auto&& f : rop.m_attributes_needed) {
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_optimized = true;

Expand Down
8 changes: 6 additions & 2 deletions src/testshade/testshade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1465,13 +1465,17 @@ test_group_attributes(ShaderGroup* group)
std::cout << "Need " << nattr << " attributes:\n";
ustring* names = NULL;
ustring* scopes = NULL;
TypeDesc* types = NULL;
shadingsys->getattribute(group, "attributes_needed", TypeDesc::PTR,
&names);
shadingsys->getattribute(group, "attribute_scopes", TypeDesc::PTR,
&scopes);
OSL_DASSERT(names && scopes);
shadingsys->getattribute(group, "attribute_types", TypeDesc::PTR,
&types);
OSL_DASSERT(names && scopes && types);
for (int i = 0; i < nattr; ++i)
std::cout << " " << names[i] << ' ' << scopes[i] << "\n";
std::cout << " " << names[i] << ' ' << scopes[i] << ' '
<< types[i] << "\n";

int unk = 0;
shadingsys->getattribute(group, "unknown_attributes_needed", unk);
Expand Down