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 width = 1536;
unsigned int height = 1024; unsigned int height = 1024;
float x0 = -2; float x0 = -2;
@@ -108,6 +112,25 @@ int main() {
float y0 = -1; float y0 = -1;
float y1 = 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(); ensureTargetISAIsSupported();
int maxIterations = 512; int maxIterations = 512;

View File

@@ -52,7 +52,8 @@ using namespace ispc;
typedef unsigned int uint; 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[], const float camera2world[4][4], float image[],
int id[], const LinearBVHNode nodes[], int id[], const LinearBVHNode nodes[],
const Triangle triangles[]); const Triangle triangles[]);
@@ -127,11 +128,28 @@ ensureTargetISAIsSupported() {
} }
static void usage() {
fprintf(stderr, "rt [--scale=<factor>] <scene name base>\n");
exit(1);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc != 2) { float scale = 1.f;
fprintf(stderr, "usage: rt <filename base>\n"); const char *filename = NULL;
exit(1); 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(); ensureTargetISAIsSupported();
@@ -145,10 +163,10 @@ int main(int argc, char *argv[]) {
// Read the camera specification information from the camera file // Read the camera specification information from the camera file
// //
char fnbuf[1024]; char fnbuf[1024];
sprintf(fnbuf, "%s.camera", argv[1]); sprintf(fnbuf, "%s.camera", filename);
FILE *f = fopen(fnbuf, "rb"); FILE *f = fopen(fnbuf, "rb");
if (!f) { if (!f) {
perror(argv[1]); perror(fnbuf);
return 1; 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 // Nothing fancy, and trouble if we run on a big-endian system, just
// fread in the bits // fread in the bits
// //
int width, height; int baseWidth, baseHeight;
float camera2world[4][4], raster2camera[4][4]; float camera2world[4][4], raster2camera[4][4];
READ(width, 1); READ(baseWidth, 1);
READ(height, 1); READ(baseHeight, 1);
READ(camera2world[0][0], 16); READ(camera2world[0][0], 16);
READ(raster2camera[0][0], 16); READ(raster2camera[0][0], 16);
// //
// Read in the serialized BVH // Read in the serialized BVH
// //
sprintf(fnbuf, "%s.bvh", argv[1]); sprintf(fnbuf, "%s.bvh", filename);
f = fopen(fnbuf, "rb"); f = fopen(fnbuf, "rb");
if (!f) { if (!f) {
perror(argv[2]); perror(fnbuf);
return 1; return 1;
} }
@@ -216,10 +234,10 @@ int main(int argc, char *argv[]) {
} }
fclose(f); 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 // the code that assigns pixels to ispc program instances
height = (height + 3) & ~3; int height = (int(baseHeight * scale) + 0xf) & ~0xf;
width = (width + 3) & ~3; int width = (int(baseWidth * scale) + 0xf) & ~0xf;
// allocate images; one to hold hit object ids, one to hold depth to // allocate images; one to hold hit object ids, one to hold depth to
// the first interseciton // the first interseciton
@@ -232,8 +250,8 @@ int main(int argc, char *argv[]) {
double minTimeISPC = 1e30; double minTimeISPC = 1e30;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
reset_and_start_timer(); reset_and_start_timer();
raytrace_ispc(width, height, raster2camera, camera2world, raytrace_ispc(width, height, baseWidth, baseHeight, raster2camera,
image, id, nodes, triangles); camera2world, image, id, nodes, triangles);
double dt = get_elapsed_mcycles(); double dt = get_elapsed_mcycles();
minTimeISPC = std::min(dt, minTimeISPC); minTimeISPC = std::min(dt, minTimeISPC);
} }
@@ -251,8 +269,8 @@ int main(int argc, char *argv[]) {
double minTimeISPCtasks = 1e30; double minTimeISPCtasks = 1e30;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
reset_and_start_timer(); reset_and_start_timer();
raytrace_ispc_tasks(width, height, raster2camera, camera2world, raytrace_ispc_tasks(width, height, baseWidth, baseHeight, raster2camera,
image, id, nodes, triangles); camera2world, image, id, nodes, triangles);
double dt = get_elapsed_mcycles(); double dt = get_elapsed_mcycles();
minTimeISPCtasks = std::min(dt, minTimeISPCtasks); minTimeISPCtasks = std::min(dt, minTimeISPCtasks);
} }
@@ -271,8 +289,8 @@ int main(int argc, char *argv[]) {
double minTimeSerial = 1e30; double minTimeSerial = 1e30;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
reset_and_start_timer(); reset_and_start_timer();
raytrace_serial(width, height, raster2camera, camera2world, raytrace_serial(width, height, baseWidth, baseHeight, raster2camera,
image, id, nodes, triangles); camera2world, image, id, nodes, triangles);
double dt = get_elapsed_mcycles(); double dt = get_elapsed_mcycles();
minTimeSerial = std::min(dt, minTimeSerial); 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, 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 raster2camera[4][4],
const uniform float camera2world[4][4], const uniform float camera2world[4][4],
uniform float image[], uniform int id[], uniform float image[], uniform int id[],
const LinearBVHNode nodes[], const LinearBVHNode nodes[],
const Triangle triangles[]) { 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, static const uniform float udx[16] = { 0, 1, 0, 1, 2, 3, 2, 3,
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, 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]; const float dy = udy[o * programCount + programIndex];
Ray ray; Ray ray;
generateRay(raster2camera, camera2world, x+dx, y+dy, ray); generateRay(raster2camera, camera2world, (x+dx)*widthScale,
(y+dy)*heightScale, ray);
BVHIntersect(nodes, triangles, ray); BVHIntersect(nodes, triangles, ray);
int offset = (y + (int)dy) * width + (x + (int)dx); 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, 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 raster2camera[4][4],
const uniform float camera2world[4][4], const uniform float camera2world[4][4],
uniform float image[], uniform int id[], uniform float image[], uniform int id[],
const LinearBVHNode nodes[], const LinearBVHNode nodes[],
const Triangle triangles[]) { 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); id, nodes, triangles);
} }
task void raytrace_tile_task(uniform int x0, uniform int x1, 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 raster2camera[4][4],
const uniform float camera2world[4][4], const uniform float camera2world[4][4],
uniform float image[], uniform int id[], uniform float image[], uniform int id[],
const LinearBVHNode nodes[], const LinearBVHNode nodes[],
const Triangle triangles[]) { 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); id, nodes, triangles);
} }
export void raytrace_ispc_tasks(uniform int width, uniform int height, 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 raster2camera[4][4],
const uniform float camera2world[4][4], const uniform float camera2world[4][4],
uniform float image[], uniform int id[], 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); uniform int y1 = min(y + dy, height);
for (uniform int x = 0; x < width; x += dx) { for (uniform int x = 0; x < width; x += dx) {
uniform int x1 = min(x + dx, width); uniform int x1 = min(x + dx, width);
launch < raytrace_tile_task(x, x1, y, y1, width, raster2camera, launch < raytrace_tile_task(x, x1, y, y1, width, height, baseWidth,
camera2world, image, id, nodes, baseHeight, raster2camera, camera2world,
triangles) >; 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 raster2camera[4][4],
const float camera2world[4][4], const float camera2world[4][4],
float image[], float image[],
int id[], int id[],
const LinearBVHNode nodes[], const LinearBVHNode nodes[],
const Triangle triangles[]) { const Triangle triangles[]) {
float widthScale = float(baseWidth) / float(width);
float heightScale = float(baseHeight) / float(height);
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
Ray ray; Ray ray;
generateRay(raster2camera, camera2world, x, y, ray); generateRay(raster2camera, camera2world, x * widthScale,
y * heightScale, ray);
BVHIntersect(nodes, triangles, ray); BVHIntersect(nodes, triangles, ray);
int offset = y * width + x; int offset = y * width + x;