Add --scale command line argument to mandelbrot and rt examples.

This applies a floating-point scale factor to the image resolution;
it's useful for experiments with many-core systems where the 
base image resolution may not give enough work for good load-balancing
with tasks.
This commit is contained in:
Matt Pharr
2011-09-07 20:07:51 -07:00
parent 2ea6d249d5
commit 5dedb6f836
4 changed files with 88 additions and 31 deletions

View File

@@ -99,8 +99,12 @@ ensureTargetISAIsSupported() {
}
}
static void usage() {
fprintf(stderr, "usage: mandelbrot [--scale=<factor]\n");
exit(1);
}
int main() {
int main(int argc, char *argv[]) {
unsigned int width = 1536;
unsigned int height = 1024;
float x0 = -2;
@@ -108,6 +112,25 @@ int main() {
float y0 = -1;
float y1 = 1;
if (argc == 1)
;
else if (argc == 2) {
if (strncmp(argv[1], "--scale=", 8) == 0) {
float scale = atof(argv[1] + 8);
if (scale == 0.f)
usage();
width *= scale;
height *= scale;
// round up to multiples of 16
width = (width + 0xf) & ~0xf;
height = (height + 0xf) & ~0xf;
}
else
usage();
}
else
usage();
ensureTargetISAIsSupported();
int maxIterations = 512;

View File

@@ -52,7 +52,8 @@ using namespace ispc;
typedef unsigned int uint;
extern void raytrace_serial(int width, int height, const float raster2camera[4][4],
extern void raytrace_serial(int width, int height, int baseWidth, int baseHeight,
const float raster2camera[4][4],
const float camera2world[4][4], float image[],
int id[], const LinearBVHNode nodes[],
const Triangle triangles[]);
@@ -127,12 +128,29 @@ ensureTargetISAIsSupported() {
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: rt <filename base>\n");
static void usage() {
fprintf(stderr, "rt [--scale=<factor>] <scene name base>\n");
exit(1);
}
int main(int argc, char *argv[]) {
float scale = 1.f;
const char *filename = NULL;
for (int i = 1; i < argc; ++i) {
if (strncmp(argv[i], "--scale=", 8) == 0) {
scale = atof(argv[i] + 8);
if (scale == 0.f)
usage();
}
else if (filename != NULL)
usage();
else
filename = argv[i];
}
if (filename == NULL)
usage();
ensureTargetISAIsSupported();
#define READ(var, n) \
@@ -145,10 +163,10 @@ int main(int argc, char *argv[]) {
// Read the camera specification information from the camera file
//
char fnbuf[1024];
sprintf(fnbuf, "%s.camera", argv[1]);
sprintf(fnbuf, "%s.camera", filename);
FILE *f = fopen(fnbuf, "rb");
if (!f) {
perror(argv[1]);
perror(fnbuf);
return 1;
}
@@ -156,20 +174,20 @@ int main(int argc, char *argv[]) {
// Nothing fancy, and trouble if we run on a big-endian system, just
// fread in the bits
//
int width, height;
int baseWidth, baseHeight;
float camera2world[4][4], raster2camera[4][4];
READ(width, 1);
READ(height, 1);
READ(baseWidth, 1);
READ(baseHeight, 1);
READ(camera2world[0][0], 16);
READ(raster2camera[0][0], 16);
//
// Read in the serialized BVH
//
sprintf(fnbuf, "%s.bvh", argv[1]);
sprintf(fnbuf, "%s.bvh", filename);
f = fopen(fnbuf, "rb");
if (!f) {
perror(argv[2]);
perror(fnbuf);
return 1;
}
@@ -216,10 +234,10 @@ int main(int argc, char *argv[]) {
}
fclose(f);
// round image resolution up to multiple of 4 to make things easy for
// round image resolution up to multiple of 16 to make things easy for
// the code that assigns pixels to ispc program instances
height = (height + 3) & ~3;
width = (width + 3) & ~3;
int height = (int(baseHeight * scale) + 0xf) & ~0xf;
int width = (int(baseWidth * scale) + 0xf) & ~0xf;
// allocate images; one to hold hit object ids, one to hold depth to
// the first interseciton
@@ -232,8 +250,8 @@ int main(int argc, char *argv[]) {
double minTimeISPC = 1e30;
for (int i = 0; i < 3; ++i) {
reset_and_start_timer();
raytrace_ispc(width, height, raster2camera, camera2world,
image, id, nodes, triangles);
raytrace_ispc(width, height, baseWidth, baseHeight, raster2camera,
camera2world, image, id, nodes, triangles);
double dt = get_elapsed_mcycles();
minTimeISPC = std::min(dt, minTimeISPC);
}
@@ -251,8 +269,8 @@ int main(int argc, char *argv[]) {
double minTimeISPCtasks = 1e30;
for (int i = 0; i < 3; ++i) {
reset_and_start_timer();
raytrace_ispc_tasks(width, height, raster2camera, camera2world,
image, id, nodes, triangles);
raytrace_ispc_tasks(width, height, baseWidth, baseHeight, raster2camera,
camera2world, image, id, nodes, triangles);
double dt = get_elapsed_mcycles();
minTimeISPCtasks = std::min(dt, minTimeISPCtasks);
}
@@ -271,8 +289,8 @@ int main(int argc, char *argv[]) {
double minTimeSerial = 1e30;
for (int i = 0; i < 3; ++i) {
reset_and_start_timer();
raytrace_serial(width, height, raster2camera, camera2world,
image, id, nodes, triangles);
raytrace_serial(width, height, baseWidth, baseHeight, raster2camera,
camera2world, image, id, nodes, triangles);
double dt = get_elapsed_mcycles();
minTimeSerial = std::min(dt, minTimeSerial);
}

View File

@@ -227,12 +227,17 @@ bool BVHIntersect(const LinearBVHNode nodes[], const Triangle tris[],
static void raytrace_tile(uniform int x0, uniform int x1,
uniform int y0, uniform int y1, uniform int width,
uniform int y0, uniform int y1,
uniform int width, uniform int height,
uniform int baseWidth, uniform int baseHeight,
const uniform float raster2camera[4][4],
const uniform float camera2world[4][4],
uniform float image[], uniform int id[],
const LinearBVHNode nodes[],
const Triangle triangles[]) {
uniform float widthScale = (float)(baseWidth) / (float)(width);
uniform float heightScale = (float)(baseHeight) / (float)(height);
static const uniform float udx[16] = { 0, 1, 0, 1, 2, 3, 2, 3,
0, 1, 0, 1, 2, 3, 2, 3 };
static const uniform float udy[16] = { 0, 0, 1, 1, 0, 0, 1, 1,
@@ -252,7 +257,8 @@ static void raytrace_tile(uniform int x0, uniform int x1,
const float dy = udy[o * programCount + programIndex];
Ray ray;
generateRay(raster2camera, camera2world, x+dx, y+dy, ray);
generateRay(raster2camera, camera2world, (x+dx)*widthScale,
(y+dy)*heightScale, ray);
BVHIntersect(nodes, triangles, ray);
int offset = (y + (int)dy) * width + (x + (int)dx);
@@ -265,29 +271,35 @@ static void raytrace_tile(uniform int x0, uniform int x1,
export void raytrace_ispc(uniform int width, uniform int height,
uniform int baseWidth, uniform int baseHeight,
const uniform float raster2camera[4][4],
const uniform float camera2world[4][4],
uniform float image[], uniform int id[],
const LinearBVHNode nodes[],
const Triangle triangles[]) {
raytrace_tile(0, width, 0, height, width, raster2camera, camera2world, image,
raytrace_tile(0, width, 0, height, width, height, baseWidth, baseHeight,
raster2camera, camera2world, image,
id, nodes, triangles);
}
task void raytrace_tile_task(uniform int x0, uniform int x1,
uniform int y0, uniform int y1, uniform int width,
uniform int y0, uniform int y1,
uniform int width, uniform int height,
uniform int baseWidth, uniform int baseHeight,
const uniform float raster2camera[4][4],
const uniform float camera2world[4][4],
uniform float image[], uniform int id[],
const LinearBVHNode nodes[],
const Triangle triangles[]) {
raytrace_tile(x0, x1, y0, y1, width, raster2camera, camera2world, image,
raytrace_tile(x0, x1, y0, y1, width, height, baseWidth, baseHeight,
raster2camera, camera2world, image,
id, nodes, triangles);
}
export void raytrace_ispc_tasks(uniform int width, uniform int height,
uniform int baseWidth, uniform int baseHeight,
const uniform float raster2camera[4][4],
const uniform float camera2world[4][4],
uniform float image[], uniform int id[],
@@ -298,9 +310,9 @@ export void raytrace_ispc_tasks(uniform int width, uniform int height,
uniform int y1 = min(y + dy, height);
for (uniform int x = 0; x < width; x += dx) {
uniform int x1 = min(x + dx, width);
launch < raytrace_tile_task(x, x1, y, y1, width, raster2camera,
camera2world, image, id, nodes,
triangles) >;
launch < raytrace_tile_task(x, x1, y, y1, width, height, baseWidth,
baseHeight, raster2camera, camera2world,
image, id, nodes, triangles) >;
}
}
}

View File

@@ -258,17 +258,21 @@ bool BVHIntersect(const LinearBVHNode nodes[], const Triangle tris[],
}
void raytrace_serial(int width, int height,
void raytrace_serial(int width, int height, int baseWidth, int baseHeight,
const float raster2camera[4][4],
const float camera2world[4][4],
float image[],
int id[],
const LinearBVHNode nodes[],
const Triangle triangles[]) {
float widthScale = float(baseWidth) / float(width);
float heightScale = float(baseHeight) / float(height);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
Ray ray;
generateRay(raster2camera, camera2world, x, y, ray);
generateRay(raster2camera, camera2world, x * widthScale,
y * heightScale, ray);
BVHIntersect(nodes, triangles, ray);
int offset = y * width + x;