Skip to content

Commit a4a1621

Browse files
authored
Bug fix: incorrect instance merging when unspecified-length arrays differed. (#656)
Because the altered data offset wasn't transferred from the instance overrides to the instance's full symbol table, it was comparing the default values rather than the actual values, so two instances that should not have been merged, were merged. Also fixed a (harmless) bug in ShadingSystemImpl::ShaderGroupBegin, where the serialized group is parsed, where it was double-calling Parameter() to add the parameters. Fixes #655
1 parent 2cd745c commit a4a1621

File tree

8 files changed

+43
-9
lines changed

8 files changed

+43
-9
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ TESTSUITE ( and-or-not-synonyms aastep arithmetic array array-derivs array-range
543543
layers layers-Ciassign layers-entry layers-lazy
544544
layers-nonlazycopy layers-repeatedoutputs
545545
linearstep
546-
logic loop matrix message mergeinstances-nouserdata
546+
logic loop matrix message
547+
mergeinstances-nouserdata mergeinstances-vararray
547548
metadata-braces miscmath missing-shader
548549
noise noise-cell
549550
noise-gabor noise-gabor2d-filter noise-gabor3d-filter

src/liboslexec/instance.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,13 @@ ShaderInstance::parameters (const ParamValueList &params)
214214

215215
m_instoverrides.resize (std::max (0, lastparam()));
216216

217-
// Set the initial lockgeom on the instoverrides, based on the master.
218-
for (int i = 0, e = (int)m_instoverrides.size(); i < e; ++i)
219-
m_instoverrides[i].lockgeom (master()->symbol(i)->lockgeom());
217+
// Set the initial lockgeom and dataoffset on the instoverrides, based
218+
// on the master.
219+
for (int i = 0, e = (int)m_instoverrides.size(); i < e; ++i) {
220+
Symbol *sym = master()->symbol(i);
221+
m_instoverrides[i].lockgeom (sym->lockgeom());
222+
m_instoverrides[i].dataoffset (sym->dataoffset());
223+
}
220224

221225
BOOST_FOREACH (const ParamValue &p, params) {
222226
if (p.name().size() == 0)
@@ -257,6 +261,9 @@ ShaderInstance::parameters (const ParamValueList &params)
257261
p.interp() == ParamValue::INTERP_CONSTANT);
258262
so->lockgeom (lockgeom);
259263

264+
DASSERT (so->dataoffset() == sm->dataoffset());
265+
so->dataoffset (sm->dataoffset());
266+
260267
if (paramtype.arraylen < 0) {
261268
// An array of definite size was supplied to a parameter
262269
// that was an array of indefinite size. Magic! The trick
@@ -460,6 +467,7 @@ ShaderInstance::copy_code_from_master (ShaderGroup &group)
460467
si->valuesource (m_instoverrides[i].valuesource());
461468
si->connected_down (m_instoverrides[i].connected_down());
462469
si->lockgeom (m_instoverrides[i].lockgeom());
470+
si->dataoffset (m_instoverrides[i].dataoffset());
463471
si->data (param_storage(i));
464472
}
465473
if (shadingsys().is_renderer_output (layername(), si->name(), &group)) {

src/liboslexec/shadingsys.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,7 +2117,6 @@ ShadingSystemImpl::ShaderGroupBegin (string_view groupname,
21172117
// Zero-pad if we parsed fewer values than we needed
21182118
intvals.resize (type.numelements()*type.aggregate, 0);
21192119
ASSERT (int(type.numelements())*type.aggregate == int(intvals.size()));
2120-
Parameter (paramname, type, &intvals[0], lockgeom);
21212120
} else if (type.basetype == TypeDesc::FLOAT) {
21222121
floatvals.clear ();
21232122
floatvals.reserve (vals_to_preallocate);
@@ -2137,7 +2136,6 @@ ShadingSystemImpl::ShaderGroupBegin (string_view groupname,
21372136
// Zero-pad if we parsed fewer values than we needed
21382137
floatvals.resize (type.numelements()*type.aggregate, 0);
21392138
ASSERT (int(type.numelements())*type.aggregate == int(floatvals.size()));
2140-
Parameter (paramname, type, &floatvals[0], lockgeom);
21412139
} else if (type.basetype == TypeDesc::STRING) {
21422140
stringvals.clear ();
21432141
stringvals.reserve (vals_to_preallocate);
@@ -2167,7 +2165,6 @@ ShadingSystemImpl::ShaderGroupBegin (string_view groupname,
21672165
// Zero-pad if we parsed fewer values than we needed
21682166
stringvals.resize (type.numelements()*type.aggregate, ustring());
21692167
ASSERT (int(type.numelements())*type.aggregate == int(stringvals.size()));
2170-
Parameter (paramname, type, &stringvals[0], lockgeom);
21712168
}
21722169

21732170
if (Strutil::parse_prefix (p, "[[")) { // hints
@@ -3177,5 +3174,3 @@ osl_bind_interpolated_param (void *sg_, const void *name, long long type,
31773174
}
31783175
return 0; // no such user data
31793176
}
3180-
3181-
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
shader arrayparam(
2+
color in_value[] = { color(1) },
3+
output color out_value = in_value[0] )
4+
{
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Compiled arrayparam.osl -> arrayparam.oso
2+
Compiled simple.osl -> simple.oso
3+
1.000000 0.000000 1.000000
4+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env python
2+
3+
# This is a regression test for a bug in which instance merging was
4+
# done incorrectly for shaders that differed only in the values given
5+
# to parameters which were arrays of unspecified length.
6+
7+
command = testshade("--group data/shadergroup")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
param color[1] in_value 0 0 1 ;
2+
shader arrayparam param_node_2 ;
3+
param color[1] in_value 1 0 0 ;
4+
shader arrayparam param_node_1 ;
5+
shader simple simple_surface ;
6+
connect param_node_1.out_value simple_surface.a ;
7+
connect param_node_2.out_value simple_surface.b ;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
surface simple(
2+
color a = color(0),
3+
color b = color(0) )
4+
{
5+
printf("%f\n", a + b);
6+
Ci = emission() * (a + b);
7+
}

0 commit comments

Comments
 (0)