Documentation/Source code in deep

From PixieWiki

Jump to: navigation, search

Contents

[edit] Introduction

This page is an attempt to understand and explain the (really beautiful) Pixie code.

You can download a Doxygen documentation from here. You can find an explanation about how make you own Pixie Doxygen Documentation here.

Pixie is based on the Reyes algorithm, you can found some descriptions here:

[edit] sdrc

The RenderMan Shading Language compiler

Uncompiled shader "ambientindirect":

/*	ambientindirect light source shader
 *
 * 	Pixie is:
 * 	(c) Copyright 1999-2003 Okan Arikan. All rights reserved.
 */

light ambientindirect (float numSamples=16,intensity=0.2) {
	vector Nf = faceforward(normalize(N),I);
   Cl = indirectdiffuse(P,Nf,numSamples);
   L = 0;
}

Compiled shader "ambientindirect":

#!version 2.2.6
light
#!parameters:
uniform	float	numSamples	=	16
uniform	float	intensity	=	0.2
#!variables:
varying	vector	Nf
varying	vector	temporary_0
varying	float	temporary_1
uniform	vector	temporary_2
#!Init:
	return            
#!Code:
	normalize	("v=v")  temporary_0  N 
	faceforward	("v=vv")  Nf  temporary_0  I 
	vufloat            temporary_1 numSamples
	indirectdiffuse	("c=pnf")  Cl  P  Nf  temporary_1 
	vfromf            	temporary_2 0
	vuvector           L temporary_2
	return            

Apparently the structure is:

#!version Version
Type
#!parameters
Parameters list, can contain "Temporary_X" where X is a number, to store temporal data in memory.
#!variables
Variable list and initial values
#!Init:
Initialize values, example:
	ftoa               OccBendNormal 0 0
#!Code:
Process list
#!LabelX:
Where X is a number, appear to be functions or GoTos

[edit] sdr

A library for parsing compiled shaders

[edit] sdrinfo

A program that uses sdr to display information about compiled shaders

[edit] rndr

The program that uses "ri" to render your RIB files. Is a RIB parser and manage the network render.

[edit] Main

Read the parameters.

A lot of data is missing in --help

$ rndr -sizereport
Size Report:
        sizeof(char): 1
       sizeof(short): 2
         sizeof(int): 4
        sizeof(long): 8
   sizeof(long long): 8
      sizeof(void *): 8
         sizeof(T32): 4
         sizeof(T64): 8
      sizeof(TMutex): 40

Launch local servers if needed, create the command line for the ri.

Launch RiBegin (ri.cpp) with a string with the parameters. RiBegin launch CRendererContext(ri/renderContext.cpp) to initialize the render context. And launch RiInit to init the static variables.

Main have a While that launch every file passed on rndr parameters, the cicle launch RiReadArchive.

missing things

Finally launch RiEnd(ri.cpp) that fills currentBlock with blocks.pop(), launch RiTini that ditch the allocated static variables, and delete renderMan var.

[edit] riThread

Is the main rendering thread.

[edit] ri

The main RenderMan Ri library described as "RenderMan Interface Implementation"

[edit] Resources

[edit] Description

Initializes:

  • Token definitions
  • Filter types
  • Non-Standard options/attributes entry points
  • Non-Standard attributes
    • Dice attributes
    • Displacementbound attributes
    • Visibility attributes
    • Trace attributes
    • Photon attributes
    • Motionfactor attribute
    • Cull attributes
  • Non-Standard options
    • Searchpath options
    • Limits options
    • Trace options
    • Statstics options
    • Irradiance options
    • Hider options
    • IO options
    • Shutter options
    • Misc junk
    • Error handling
  • The cubic spline basis definition

Actions:

  • Make sure the command is good for a given nesting
  • Extract a parameter from the command string
  • Read the parameter list and set nTokens,tokens,values
  • Init the static variables
  • Check PIXIE_RUNPROGRAM variable (If we're a runprogram, we should be writing out to stdout!)
  • RenderMan Interface begins her: define a lot of function necessary to make the render. The function's body is in #renderContext.

On windows only defines the function erfc(x):

Computation of the complementary error function erfc(x).
The algorithm is based on a Chebyshev fit as denoted in
Numerical Recipes 2nd ed. on p. 214 (W.H.Press et al.).
The fractional error is always less than 1.2e-7.
The parameters of the Chebyshev fit
  • Define filters (Boxblur don't work? return 1)
  • "We treat displacement as an attribute, not an xform"
  • Resource related functions
  • Archieving functions
  • Conditional evaluation function
  • Archieve reading functions

[edit] RiReadArchive

RiReadArchive is the main function that execute the render. Launch RiReadArchiveV that launch renderMan->RiReadArchiveV, renderMan is a CRiInterface type variable, CRiInterface is a virtual class that implements the RenderMan interface.

[edit] renderContext

  • Initiate the renderer
  • Init the graphics state
  • Init the object stack
  • Init the object instance junk
  • Allocate the initial graphics state
  • And some misc data used in the RI interface

[edit] RiReadArchiveV

Try locating the file (locateFile) on success, parse the file: ribParse(tmp,callback);

[edit] rib

C LALR(1) parser skeleton written by Richard Stallman, by
simplifying the original so-called "semantic" parser.

All symbols defined below should begin with yy or YY, to avoid
infringing on user name space.  This should be done even for local
variables, as they might otherwise be expanded by user macros.
There are some unavoidable exceptions within include files to
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below.

[edit] Resources

[edit] ribParser

  • Save the environment first
  • Guard against the depreciated fdopen on windoze
  • Init the environment
    • Read from stdin
    • Read from an arbitrary stream
    • Read from file
  • Create a new lex buffer and switch to it
Note: there are two stacking methods here,
one is explicitly handled when lexing for ReadArchive
the other uses the return stack (and increments ribDepth)
  • Put a checkpoint in the global memory. This checkpoint is restored after every RIB command
  • Parse the RIB: ribparse();
  • Restore the memory to the latest checkpoint
  • Clear the lights

[edit] render

  • Record startup time
  • Save the context
  • Reset the stats
  • Init the global memory

[edit] Create the synchronization objects

[edit] jobMutex

This mutex serializes the job assignments.

[edit] commitMutex

This mutex is used to serialize job assignment of buckets It is also used to serialize receiving of remote channels - each dispatch of a job must be mutexed so that it goes to one thread only - in a network render context, all recieves and commits of remote channels and bucket data must lock this mutex

FIXME - usage doesn't seem clear

[edit] displayKillMutex

This mutex is used to make sure we unload a display driver only once.


[edit] networkMutex

This mutex is used to serialize usage of network resources in the global space. Only the servers actually use this mutex: - To ask for bucket index to render from the client - To send rendered bucket data to the renderer - To receive a file from the client


[edit] tesselateMutex

Used to ensure we serialize creation of CTesselationPatch objects so the list of tesselations is maintained. This also means that we must lock the mutex whilst examining the list in purge

Also used to ensure we only have one thread re-tesselating a level if TESSELATION_LOCK_PER_ENTRY is not enabled (but it is by default)

[edit] textureMutex

Used to ensure we serialize purging of texture blocks The serial creation of blocks is handled by the fact that textures are loaded on request from shader PL references shader PL unpacking is serialized.

Also used to ensure we only have one thread loading a block if PERBLOCK_LOCK is not enabled (but it is by default)

Note: if we change shaderMutex usage, we will need to ensure creation of texture blocks is serialized

[edit] shaderMutex

Used to ensure that each shader PL gets unpacked by one thread only.

Note: if we change this, we'll need to mutex other operations like texture loading - all PL modifications in execute must be mutexed

TODO - we can get away without locking most of the time if we use a check-lock-check idiom as elsewhere

[edit] delayedMutex

Used to ensure that only one thread at a time is expanding delayed objects - so we have only one thread in rib parse and only one thread executing a DynamicLoad Procedural

FIXME - there are still some remaining issues that can be caused by a thread in rib parse whilst others continue see memoryMutex

[edit] deepShadowMutex

Used to ensure all writes to the deep shadow file are serialized

[edit] hierarchyMutex

Used to serialize the bounding volume hierarchy creation

[edit] atomicMutex

Used to serialize the atomic operations on unsupported platforms

  • Init the files
  • Init the declarations
  • Init the network (if applicable)
  • Init the light sources we use
  • Record the start overhead
  • Create a temporary directory for the lifetime of the renderer

[edit] Displays

[edit] file

"file" display driver

[edit] framebuffer

"framebuffer" display driver

[edit] openexr

"openexr" display driver

[edit] rgbe

"rgbe" display driver

[edit] texmake

A program that converts textures into Pixie's format

[edit] common

A library for common functions

[edit] precomp

A program that generates misc. code for Pixie

[edit] gui

A dynamic library that provides user interface functionality

[edit] show

A program that displays various data computed using "ri"

[edit] dsotest

An example DSO shadeop