HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VaryingRef< T > Class Template Reference

#include <varyingref.h>

Public Member Functions

 VaryingRef ()
 
 VaryingRef (void *ptr_, int step_=0)
 
 VaryingRef (T &ptr_)
 
void init (T *ptr_, int step_=0)
 
const VaryingRefoperator= (T &ptr_)
 
bool is_null () const
 
 operator void * () const
 
bool is_varying () const
 
bool is_uniform () const
 
VaryingRefoperator++ ()
 
void operator++ (int)
 
Toperator* () const
 
Toperator[] (int i) const
 
Tptr () const
 
int step () const
 

Detailed Description

template<class T>
class VaryingRef< T >

VaryingRef is a templated class (on class T) that holds either a pointer to a single T value, or an "array" of T values, each separated by a certain number of bytes. For those versed in the lingo of SIMD shading, this encapsulates 'uniform' and 'varying' references.

Suppose you have a computation 'kernel' that is performing an operation while looping over several computation 'points.' Each of the several operands of the kernel may either be a 'uniform' value (identical for each point), or 'varying' (having a potentially different value for each point).

Here is a concrete example. Suppose you have the following function:

void add (int n, float *a, float *b, float *result) {
for (int i = 0; i < n; ++i)
result[i] = a[i] + b[i];
}

But if the caller of this function has only a single b value (let's say, you always want to add 3 to every a[i]), you would be forced to replicate an entire array full of 3's in order to call the function.

Instead, we may wish to generalize the function so that each operand may rever to EITHER a single value or an array of values, without making the code more complicated. We can do this with VaryingRef:

float *result) {
for (int i = 0; i < n; ++i)
result[i] = a[i] + b[i];
}

VaryingRef overloads operator [] to properly decode whether it is uniform (point to the one value) or varying (index the right array element). It also overloads the increment operator ++ and the pointer indirection operator '*', so you could also write the function equivalently as:

float *result) {
for (int i = 0; i < n; ++i, ++a, ++b) // note increments
result[i] = (*a) + (*b);
}

An example of calling this function would be:

float a[n];
float b; // just 1 value
float result[n];
add (n, VaryingRef<float>(a,sizeof(a[0])),
VaryingRef<float>(b), result);

In this example, we're passing a truly varying 'a' (signified by giving a step size from element to element), but a uniform 'b' (signified by no step size, or a step size of zero).

There are Varying() and Uniform() templated functions that provide a helpful shorthand:

add (n, Varying(a), Uniform(b), result);

Now let's take it a step further and fully optimize the 'add' function for when both operands are uniform:

if (a.is_uniform() && b.is_uniform()) {
float r = (*a) + (*b);
for (int i = 0; i < n; ++i)
result[i] = r;
} else {
// One or both are varying
for (int i = 0; i < n; ++i, ++a, ++b)
result[i] = (*a) + (*b);
}
}

This is the basis for handling uniform and varying values efficiently inside a SIMD shading system.

Definition at line 127 of file varyingref.h.

Constructor & Destructor Documentation

template<class T>
VaryingRef< T >::VaryingRef ( )
inline

Definition at line 129 of file varyingref.h.

template<class T>
VaryingRef< T >::VaryingRef ( void ptr_,
int  step_ = 0 
)
inline

Construct a VaryingRef either of a single value pointed to by ptr (if step == 0 or no step is provided), or of a varying set of values beginning with ptr and with successive values every 'step' bytes.

Definition at line 135 of file varyingref.h.

template<class T>
VaryingRef< T >::VaryingRef ( T ptr_)
inline

Construct a uniform VaryingRef from a single value.

Definition at line 139 of file varyingref.h.

Member Function Documentation

template<class T>
void VaryingRef< T >::init ( T ptr_,
int  step_ = 0 
)
inline

Initialize this VaryingRef to either of a single value pointed to by ptr (if step == 0 or no step is provided), or of a varying set of values beginning with ptr and with successive values every 'step' bytes.

Definition at line 145 of file varyingref.h.

template<class T>
bool VaryingRef< T >::is_null ( ) const
inline

Is this reference pointing nowhere?

Definition at line 161 of file varyingref.h.

template<class T>
bool VaryingRef< T >::is_uniform ( ) const
inline

Is this VaryingRef referring to a uniform value, signified by having a step size of zero between elements?

Definition at line 173 of file varyingref.h.

template<class T>
bool VaryingRef< T >::is_varying ( ) const
inline

Is this VaryingRef referring to a varying value, signified by having a nonzero step size between elements?

Definition at line 169 of file varyingref.h.

template<class T>
VaryingRef< T >::operator void * ( ) const
inline

Cast to void* returns the pointer, but the real purpose is so you can use a VaryingRef as if it were a 'bool' value in a test.

Definition at line 165 of file varyingref.h.

template<class T>
T& VaryingRef< T >::operator* ( void  ) const
inline

Pointer indirection will return the first value currently pointed to by this VaryingRef.

Definition at line 201 of file varyingref.h.

template<class T>
VaryingRef& VaryingRef< T >::operator++ ( )
inline

Pre-increment: If this VaryingRef is varying, increment its pointer to the next element in the series, but don't change anything if it's uniform. In either case, return a reference to its new state.

Definition at line 179 of file varyingref.h.

template<class T>
void VaryingRef< T >::operator++ ( int  )
inline

Post-increment: If this VaryingRef is varying, increment its pointer to the next element in the series, but don't change anything if it's uniform. No value is returned, so it's not legal to do 'bar = foo++' if foo and bar are VaryingRef's.

Definition at line 190 of file varyingref.h.

template<class T>
const VaryingRef& VaryingRef< T >::operator= ( T ptr_)
inline

Initialize this VaryingRef to be uniform and point to a particular value reference.

Definition at line 153 of file varyingref.h.

template<class T>
T& VaryingRef< T >::operator[] ( int  i) const
inline

Array indexing operator will return a reference to the single element if *this is uniform, or to the i-th element of the series if *this is varying.

Definition at line 206 of file varyingref.h.

template<class T>
T* VaryingRef< T >::ptr ( ) const
inline

Return the raw pointer underneath.

Definition at line 210 of file varyingref.h.

template<class T>
int VaryingRef< T >::step ( ) const
inline

Return the raw step underneath.

Definition at line 214 of file varyingref.h.


The documentation for this class was generated from the following file: