Text archives Help
- 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.