qdtk / openshadinglanguage

Automatically exported from code.google.com/p/openshadinglanguage
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Only compute derivatives when we need them #31

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Right now, all variables compute their derivatives, which is a whole lot of 
unnecessary computation (and storage). Instead, we should use 
dependency analysis to figure out exactly which variables need to track derivs 
(only the ones that lead to inputs to functions that take derivs of 
their arguments). Be careful about how shader networks are strung together -- 
you don't know at compile time whether a particular shader 
output will be connected to another node that will take a derivative of that 
output, so there is also a runtime component to getting this all 
correct. But it's worth it, this should reduce the amount of math done in 
shader evaluation by a factor of 2-3.

12/08/09 11:16:10 changed by lg 

Compiler side at: <edit>

Summary from the review:

This is the compiler side to dependency tracking. As usual, it looks pretty 
small now that I've removed all the debugging scaffolding, which was 
much larger than the actual changes. :-)

Anyway, here's the basic idea of what's changed:

* The master function table has additional markers to denote which functions 
(only a few) take derivatives internally.

* ASTfunction_call::typecheck_builtin_specialcase checks those special cases 
and uses a new bitfield in the ASTfunction_call to denote exactly 
which arguments to the function have derivs taken.

* ASTfunction_call::codegen transfers this information to the actual opcode 
that is generated (which has a bitfield for derivative-taking much like 
it does for reading/writing).

* New function, OSLCompilerImpl::track_variable_dependencies, is run after all 
code is generated, uses the read/write/deriv data to generate 
data dependency among all the symbols, and in particular figures out all the 
parameters that lead, in one way or another, to derivative routines.

* When outputting the oso file, several new hints are added:

parameters whose derivs are known to be needed are marked as such (so the 
runtime knows those, and not the others, will need derivs 
supplied);
all OUTPUT params and globals are marked with which INPUT params & globals they 
depend on (so that when the runtime connects shaders, it 
can propagate derivative necessity to earlier layers);
all ops that take derivatives are so marked (this is just for debugging)
Runtime portion is coming later, but I think this approximately completes the 
compiler side.

---

Amending with a test shader and its output, so you can see what this additional 
info looks like (look for %derivparam, %inputdep, and 
%argderivs):

shader test ( float a = 1, float b = 1, float Kd = 0.5 )
{
    float s = a * 0.5;
    float t = b;
    color Ct = texture ("foo.tx", s, t, "alpha", s);
    Ci = Kd * Ct * diffuse (N);
}

OpenShadingLanguage 0.0
# Compiled by oslc FIXME-VERSION
shader test
param   float   a       1                %read{0,0} %write{2147483647,-1} 
%derivparam
param   float   b       1                %read{1,1} %write{2147483647,-1} 
%derivparam
param   float   Kd      0.5              %read{3,3} %write{2147483647,-1}
global  normal  N        %read{4,4} %write{2147483647,-1}
global  closure color   Ci       %read{2147483647,-1} %write{5,5} 
%inputdep{N,a,b,Kd}
local   float   s        %read{2,2} %write{0,2}
local   float   t        %read{2,2} %write{1,1}
local   color   Ct       %read{3,3} %write{2,2}
const   float   $const1 0.5              %read{0,0} %write{2147483647,-1}
const   string  $const2 "foo.tx"                 %read{2,2} 
%write{2147483647,-1}
const   string  $const3 "alpha"          %read{2,2} %write{2147483647,-1}
local   color   $tmp1    %read{5,5} %write{3,3}
local   closure color   $tmp2    %read{5,5} %write{4,4}
code ___main___
        mul             s a $const1     %filename{"test.osl"} %line{3} %argrw{"wrr"}
        assign          t b     %line{4} %argrw{"wr"}
        texture         Ct $const2 s t $const3 s        %line{5} %argrw{"wrrrrw"} %argderivs{2,3}
        mul             $tmp1 Kd Ct     %line{6} %argrw{"wrr"}
        diffuse         $tmp2 N         %argrw{"wr"}
        mul             Ci $tmp1 $tmp2  %argrw{"wrr"}
        end
Testing Done:

It can't be tested in images until the runtime part is completed (um... even 
then, I'm not sure it will ever make an image different unless it's 
broken, in which case it would just be missing derivs where they are needed, or 
unnecessary derivs where they are not).

But I did inspect the compiled oso of several test shaders to verify that it's 
working correctly.

Original issue reported on code.google.com by rene.lim...@gmail.com on 11 Jan 2010 at 7:05

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago

Original comment by rene.lim...@gmail.com on 13 Jan 2010 at 1:03

GoogleCodeExporter commented 9 years ago
Fixed ages ago

Original comment by larrygr...@gmail.com on 23 Feb 2011 at 11:07