Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r475 - trunk/Engine/ImageTraversers


Chronological Thread 
  • From: bigler@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r475 - trunk/Engine/ImageTraversers
  • Date: Tue, 16 Aug 2005 15:22:32 -0600 (MDT)

Author: bigler
Date: Tue Aug 16 15:22:31 2005
New Revision: 475

Modified:
   trunk/Engine/ImageTraversers/CMakeLists.txt
   trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.cc
   trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.h
Log:

CMakeLists.txt

  Added DissolveTiledImageTraverser.cc to the build list.

DissolveTiledImageTraverser.cc
DissolveTiledImageTraverser.h

  Things work now.  Pulled out the old code and replaced it with
  functional code.


Modified: trunk/Engine/ImageTraversers/CMakeLists.txt
==============================================================================
--- trunk/Engine/ImageTraversers/CMakeLists.txt (original)
+++ trunk/Engine/ImageTraversers/CMakeLists.txt Tue Aug 16 15:22:31 2005
@@ -4,6 +4,7 @@
      ImageTraversers/TiledImageTraverser.cc
      ImageTraversers/FramelessImageTraverser.cc
      ImageTraversers/DissolveImageTraverser.cc
+     ImageTraversers/DissolveTiledImageTraverser.cc
      ImageTraversers/AFImageTraverser.cc
      ImageTraversers/AFR/stats.cc
      ImageTraversers/AFR/tiles.cc

Modified: trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.cc
==============================================================================
--- trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.cc (original)
+++ trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.cc Tue Aug 16 
15:22:31 2005
@@ -70,9 +70,9 @@
       if (iters_per_frame < 1)
         throw IllegalArgument("-itersPerFrame must be greater than 0",
                               i, args);
-    if(arg == "-tilesize"){
+    } else if(arg == "-tilesize"){
       if(!getResolutionArg(i, args, xtilesize, ytilesize))
-       throw IllegalArgument("TiledImageTraverser -tilesize", i, args);
+        throw IllegalArgument("TiledImageTraverser -tilesize", i, args);
     } else {
       throw IllegalArgument("DissolveTiledImageTraverser", i, args);
     }
@@ -103,36 +103,26 @@
   unsigned int xtiles = (xres + xtilesize-1)/xtilesize;
   unsigned int ytiles = (yres + ytilesize-1)/ytilesize;
   unsigned int numAssignments = xtiles * ytiles;
+  unsigned int numTiles = numAssignments/context.numProcs;
+  unsigned int numTiles_leftover = numAssignments%context.numProcs;
 
-  // Try an educated guess for the tiles per sample
-  unsigned int tiles_per_pass =
-    (xtiles*ytiles)/context.numProcs/iters_per_frame;
-
-  // Compute the mask
-  unsigned int num_x_bits = numBinaryDigits(xres-1);
-  unsigned int num_y_bits = numBinaryDigits(yres-1);
-  unsigned int num_all_bits = num_x_bits + num_y_bits;
-  if (num_all_bits > 32)
-    throw 
InternalError("DissolveTiledImageTraverser::setupDisplayChannel::number of 
bits needed for random number exceeds 32", __FILE__, __LINE__);
-
-  ChannelContext& cdata = channel_data[context.channelIndex];
-  cdata.mask = MaskValues[num_all_bits];
-  cdata.num_y_bits = num_y_bits;
-  cdata.y_bit_mask = (1 << num_y_bits) - 1;
-  
-  // Reset the starting pixel
-  unsigned int next_pixel = 1;
-  per_thread_data[0].next_pixel[context.channelIndex] = next_pixel;
-  for(size_t i = 1; i < per_thread_data.size(); i++) {
-    int x,y;
-    do {
-      computeNextSample(next_pixel, cdata.mask);
-      x = next_pixel >> cdata.num_y_bits;
-      y = next_pixel &  cdata.y_bit_mask;
-    } while (x >= xres || y >= yres);
-    per_thread_data[i].next_pixel[context.channelIndex] = next_pixel;
+  // Try an educated guess for the tiles per pass
+  for(size_t i = 0; i < per_thread_data.size(); ++i) {
+    ChannelContext& cdata = 
per_thread_data[i].channel_data[context.channelIndex];
+    cdata.numTiles = numTiles;
+    // Add extra assignments to the latter processors
+    if (per_thread_data.size()-i >= numTiles_leftover)
+      cdata.numTiles++;
+    cdata.tiles_per_pass = cdata.numTiles/iters_per_frame;
+    // Inialize the random number stuff.
+    cdata.next_tile = 1;
+    // Figure out the mask
+    int num_bits = numBinaryDigits(cdata.numTiles);
+    if (num_bits > 32)
+      throw 
InternalError("DissolveTiledImageTraverser::setupDisplayChannel::number of 
bits needed for random number exceeds 32", __FILE__, __LINE__);
+    cdata.rng_mask = MaskValues[num_bits];
   }
-  
+
   // Single bufferd, please.
   context.constrainPipelineDepth(1,1);
 
@@ -152,71 +142,51 @@
   bool stereo;
   int xres, yres;
   image->getResolution(stereo, xres, yres);
+  int ytiles = (yres + ytilesize-1)/ytilesize;
 
-  // Pull out needed parameters for this frame based on the channel
-  // and the processor index.
-  unsigned int next_pixel = 
per_thread_data[context.proc].next_pixel[context.channelIndex];
-  ChannelContext& cdata = channel_data[context.channelIndex];
-
-  Fragment frag;
-  frag.setFlags(Fragment::ConstantEye);
-  unsigned int pixel = 0;
-  // We need to render the (0,0) pixel every once in a while, so see
-  // if we are the last processor and if we've gone through so many
-  // frames.
-  if (context.proc == context.numProcs-1 &&
-      context.frameState->frameNumber%iters_per_frame == 0) {
-    frag.addElement(0,0,0);
-    // In order to make sure the compute the same number of pixels per
-    // iteration pixel should not be incremented.
-    pixel++;
-  }
-  while ( pixel < pixels_per_pass ) {
-    int x = next_pixel >> cdata.num_y_bits;
-    int y = next_pixel &  cdata.y_bit_mask;
-    if (x < xres && y < yres) {
-      // This is a good pixel so let's add it.
-      pixel++;
-      frag.addElement(x, y, 0);
-      if(stereo){
-        // I'm not sure you want to do stereo
-      }
-      // Check to see if your fragment is full.  If it is, then render it.
-      if (frag.getSize() == Fragment::MaxFragmentSize) {
+  // Pull out this variable for convience.
+  ChannelContext& cdata = 
per_thread_data[context.proc].channel_data[context.channelIndex];
+
+  unsigned int next_tile = cdata.next_tile;
+  // Loop over all the assignments.  tc stands for tile count.
+  for(unsigned int tc = 0; tc < cdata.tiles_per_pass; ++tc) {
+    // Get the next assignment.
+    unsigned int tile = (next_tile-1)*context.numProcs + context.proc;
+    // Get the geometry of the tile
+    int xtile = tile/ytiles;
+    int ytile = tile%ytiles;
+    int xstart = xtile * xtilesize;
+    int xend = (xtile+1) * xtilesize;
+    if(xend > xres)
+      xend = xres;
+    int ystart = ytile * ytilesize;
+    int yend = (ytile+1) * ytilesize;
+    if(yend > yres)
+      yend = yres;
+    for(int y = ystart; y<yend; y++){
+      for(int x = xstart; x<xend; x+= Fragment::MaxFragmentSize){
+        // Create a Fragment that is consecutive in X pixels
+        Fragment frag(0, x, xend, y);
         context.pixelSampler->renderFragment(context, frag);
-#if 0
-        for(int f = 0; f < frag.getSize(); f++)
-          switch (context.proc) {
-          case 0: frag.setColor(f, Color(RGBColor(1,0,0))); break;
-          case 1: frag.setColor(f, Color(RGBColor(0,0,1))); break;
-          case 2: frag.setColor(f, Color(RGBColor(0,1,0))); break;
-          case 3: frag.setColor(f, Color(RGBColor(1,1,0))); break;
-          }
-#endif
         image->set(frag);
-        // Reset the Fragment, so we can start filling it up again.
-        frag.resetSize();
+        if(stereo){
+          Fragment frag(1, x, xend, y);
+          context.pixelSampler->renderFragment(context, frag);
+          image->set(frag);
+        }
       }
-    }
-    // Generate the next pixel.  But we need to find the Nth good
-    // pixel, so only count pixels if we find them.
-    for(int i = 0; i < context.numProcs;) {
-      computeNextSample(next_pixel, cdata.mask);
-      int x = next_pixel >> cdata.num_y_bits;
-      int y = next_pixel &  cdata.y_bit_mask;
-      // Found a good pixel, so find the next one.
-      if (x < xres && y < yres) i++;
-    }
-  }
-  // Pick up strays
-  if (frag.getSize()) {
-    context.pixelSampler->renderFragment(context, frag);
-    image->set(frag);
+    } // end looping over the tile
+    
+    // Get the next random number, skipping values that aren't within
+    // our range.
+    do {
+      computeNextSample(next_tile, cdata.rng_mask);
+    } while (next_tile > cdata.numTiles);
+    
   }
-
-  // Stash out next_pixel for the next iteration of the frame.
-  per_thread_data[context.proc].next_pixel[context.channelIndex] = 
next_pixel;
-
+  // Save the next tile for the next iteration.
+  cdata.next_tile = next_tile;
+  
   // This can potentially happen before the other procesors are finished
   // rendering, but that is okay because it won't get displayed until
   // everyone enters the barrier anyway

Modified: trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.h
==============================================================================
--- trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.h  (original)
+++ trunk/Engine/ImageTraversers/DissolveTiledImageTraverser.h  Tue Aug 16 
15:22:31 2005
@@ -3,18 +3,15 @@
 
   A frameless rendering image traverser.  It attemps to use a pseudo
   random number generator with variable period to eventually fill the
-  screen.  The pixel locations are not precomputed but rather computed
-  when needed.  The technique is based on the article "A Digital
-  "Dissolve" Effect" by Mike Morton found in Graphics Gems I
-  (pg. 221-232).
-
-  There are some interesting things about this method.  First for N
-  processors, ever Nth pixel is computed by each thread.  Once the
-  period of the random number generator has been reached it starts
-  over (but not necessarily from the same point).  The net effect is
-  that a single processor can do a different set of pixels the next
-  full frame.  I'm not entirely sure what the implications are for
-  over drawing of pixels, but it looks OK for now.
+  screen.  The screen is filled tile by tile.  The size of the tiles
+  can be anything from 1x1 to 32x2 (default for TiledImageTraverser)
+  or anything else you can imagine.  The tile orders are not
+  precomputed but rather computed when needed.  The technique is based
+  on the article "A Digital "Dissolve" Effect" by Mike Morton found in
+  Graphics Gems I (pg. 221-232).
+
+  Every thread computes every Nth tile (where N is the number of
+  threads).
   
   Author: James Bigler
   Date: Aug. 2005
@@ -75,18 +72,6 @@
 
     vector<ThreadContext> per_thread_data; // size = numProcs
 
-//     // This is the information needed to produce the next random
-//     // number.  Since the masks are based on the size of the channel,
-//     // each channel must maintain its own set of masks to allow for
-//     // varying sizes of channels.
-//     struct ChannelContext {
-//       unsigned int mask;
-//       unsigned int num_y_bits;
-//       unsigned int y_bit_mask;
-//     };
-//     // channel_masks.size() == numChannels
-//     vector<ChannelContext> channel_data;
-    
     inline void computeNextSample(unsigned int& val, unsigned int mask) {
       if (val & 1)
         val = (val >> 1) ^ mask;




  • [MANTA] r475 - trunk/Engine/ImageTraversers, bigler, 08/16/2005

Archive powered by MHonArc 2.6.16.

Top of page