clray

changeset 55:df239a52a091

extensive render stats for the CPU raytracer
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 11 Sep 2010 03:00:21 +0100
parents 6a30f27fa1e6
children 14c8ebe8f122
files src/clray.cc src/dbgray.cc src/rt.cc src/rt.h
diffstat 4 files changed, 100 insertions(+), 4 deletions(-) [+]
line diff
     1.1 --- a/src/clray.cc	Fri Sep 10 16:47:00 2010 +0100
     1.2 +++ b/src/clray.cc	Sat Sep 11 03:00:21 2010 +0100
     1.3 @@ -198,6 +198,7 @@
     1.4  		if(!dbg_glrender) {
     1.5  			if(dbg_nocl) {
     1.6  				dbg_render(mat.m, inv_trans.m);
     1.7 +				print_render_stats();
     1.8  			} else {
     1.9  				if(!render()) {
    1.10  					exit(1);
     2.1 --- a/src/dbgray.cc	Fri Sep 10 16:47:00 2010 +0100
     2.2 +++ b/src/dbgray.cc	Sat Sep 11 03:00:21 2010 +0100
     2.3 @@ -1,5 +1,6 @@
     2.4  #include <string.h>
     2.5  #include <assert.h>
     2.6 +#include <limits.h>
     2.7  #include "rt.h"
     2.8  #include "ogl.h"
     2.9  #include "vector.h"
    2.10 @@ -25,7 +26,10 @@
    2.11  static unsigned int tex;
    2.12  static Scene *scn;
    2.13  static const Ray *prim_rays;
    2.14 +static int max_iter;
    2.15  
    2.16 +static RenderStats *rstat;
    2.17 +static int cur_ray_aabb_tests, cur_ray_triangle_tests;
    2.18  
    2.19  bool init_dbg_renderer(int width, int height, Scene *scene, unsigned int texid)
    2.20  {
    2.21 @@ -40,6 +44,9 @@
    2.22  	ysz = height;
    2.23  	tex = texid;
    2.24  	scn = scene;
    2.25 +
    2.26 +	rstat = (RenderStats*)get_render_stats();
    2.27 +
    2.28  	return true;
    2.29  }
    2.30  
    2.31 @@ -58,7 +65,12 @@
    2.32  {
    2.33  	unsigned long t0 = get_msec();
    2.34  
    2.35 -	int iter = get_render_option_int(ROPT_ITER);
    2.36 +	max_iter = get_render_option_int(ROPT_ITER);
    2.37 +
    2.38 +	// initialize render-stats
    2.39 +	memset(rstat, 0, sizeof *rstat);
    2.40 +	rstat->min_aabb_tests = rstat->min_triangle_tests = INT_MAX;
    2.41 +	rstat->max_aabb_tests = rstat->max_triangle_tests = 0;
    2.42  
    2.43  	int offs = 0;
    2.44  	for(int i=0; i<ysz; i++) {
    2.45 @@ -66,17 +78,45 @@
    2.46  			Ray ray = prim_rays[offs];
    2.47  			transform_ray(&ray, xform, invtrans_xform);
    2.48  
    2.49 -			trace_ray(fb + offs * 3, ray, iter, 1.0);
    2.50 +			cur_ray_aabb_tests = cur_ray_triangle_tests = 0;
    2.51 +
    2.52 +			trace_ray(fb + offs * 3, ray, max_iter, 1.0);
    2.53  			offs++;
    2.54 +
    2.55 +			// update stats as needed
    2.56 +			if(cur_ray_aabb_tests < rstat->min_aabb_tests) {
    2.57 +				rstat->min_aabb_tests = cur_ray_aabb_tests;
    2.58 +			}
    2.59 +			if(cur_ray_aabb_tests > rstat->max_aabb_tests) {
    2.60 +				rstat->max_aabb_tests = cur_ray_aabb_tests;
    2.61 +			}
    2.62 +			if(cur_ray_triangle_tests < rstat->min_triangle_tests) {
    2.63 +				rstat->min_triangle_tests = cur_ray_triangle_tests;
    2.64 +			}
    2.65 +			if(cur_ray_triangle_tests > rstat->max_triangle_tests) {
    2.66 +				rstat->max_triangle_tests = cur_ray_triangle_tests;
    2.67 +			}
    2.68 +			rstat->prim_rays++;
    2.69 +			rstat->aabb_tests += cur_ray_aabb_tests;
    2.70 +			rstat->triangle_tests += cur_ray_triangle_tests;
    2.71  		}
    2.72  	}
    2.73  
    2.74 +	unsigned long t1 = get_msec();
    2.75 +
    2.76  	glPushAttrib(GL_TEXTURE_BIT);
    2.77  	glBindTexture(GL_TEXTURE_2D, tex);
    2.78  	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, xsz, ysz, GL_RGB, GL_FLOAT, fb);
    2.79  	glPopAttrib();
    2.80 +	glFinish();
    2.81  
    2.82 -	printf("rendered in %lu msec\n", get_msec() - t0);
    2.83 +	rstat->render_time = t1 - t0;
    2.84 +	rstat->tex_update_time = get_msec() - t1;
    2.85 +
    2.86 +	rstat->rays_cast = rstat->prim_rays + rstat->refl_rays + rstat->shadow_rays;
    2.87 +	rstat->rays_per_sec = 1000 * rstat->rays_cast / rstat->render_time;
    2.88 +	rstat->avg_aabb_tests = (float)rstat->aabb_tests / (float)rstat->rays_cast;
    2.89 +	rstat->avg_triangle_tests = (float)rstat->triangle_tests / (float)rstat->rays_cast;
    2.90  }
    2.91  
    2.92  static void trace_ray(float *pixel, const Ray &ray, int iter, float energy)
    2.93 @@ -120,6 +160,7 @@
    2.94  		shadowray.dir[2] = ldir.z;
    2.95  
    2.96  		if(!cast_shadows || !find_intersection(shadowray, scn, scn->kdtree, 0)) {
    2.97 +			rstat->brdf_evals++;
    2.98  
    2.99  			ldir.normalize();
   2.100  
   2.101 @@ -140,6 +181,10 @@
   2.102  			scol[1] += mat->ks[1] * spec;
   2.103  			scol[2] += mat->ks[2] * spec;
   2.104  		}
   2.105 +
   2.106 +		if(cast_shadows) {
   2.107 +			rstat->shadow_rays++;
   2.108 +		}
   2.109  	}
   2.110  
   2.111  	float refl_color[3];
   2.112 @@ -164,6 +209,8 @@
   2.113  		scol[0] += rcol[0] * mat->ks[0] * mat->kr;
   2.114  		scol[1] += rcol[1] * mat->ks[1] * mat->kr;
   2.115  		scol[2] += rcol[2] * mat->ks[2] * mat->kr;
   2.116 +
   2.117 +		rstat->refl_rays++;
   2.118  	}
   2.119  
   2.120  	pixel[0] = dcol[0] + scol[0];
   2.121 @@ -210,6 +257,8 @@
   2.122  
   2.123  static bool ray_aabb_test(const Ray &ray, const AABBox &aabb)
   2.124  {
   2.125 +	cur_ray_aabb_tests++;
   2.126 +
   2.127  	if(ray.origin[0] >= aabb.min[0] && ray.origin[1] >= aabb.min[1] && ray.origin[2] >= aabb.min[2] &&
   2.128  			ray.origin[0] < aabb.max[0] && ray.origin[1] < aabb.max[1] && ray.origin[2] < aabb.max[2]) {
   2.129  		return true;
   2.130 @@ -252,6 +301,8 @@
   2.131  
   2.132  static bool ray_triangle_test(const Ray &ray, const Face *face, SurfPoint *sp)
   2.133  {
   2.134 +	cur_ray_triangle_tests++;
   2.135 +
   2.136  	Vector3 origin = ray.origin;
   2.137  	Vector3 dir = ray.dir;
   2.138  	Vector3 norm = face->normal;
     3.1 --- a/src/rt.cc	Fri Sep 10 16:47:00 2010 +0100
     3.2 +++ b/src/rt.cc	Sat Sep 11 03:00:21 2010 +0100
     3.3 @@ -35,6 +35,7 @@
     3.4  
     3.5  
     3.6  static RendInfo rinf;
     3.7 +static RenderStats rstat;
     3.8  static int saved_iter_val;
     3.9  
    3.10  static long timing_sample_sum;
    3.11 @@ -211,6 +212,31 @@
    3.12  	return &rinf;
    3.13  }
    3.14  
    3.15 +const RenderStats *get_render_stats()
    3.16 +{
    3.17 +	return &rstat;
    3.18 +}
    3.19 +
    3.20 +void print_render_stats(FILE *fp)
    3.21 +{
    3.22 +	fprintf(fp, "-- render stats --\n");
    3.23 +	fprintf(fp, "> timing\n");
    3.24 +	fprintf(fp, "   render time (msec): %lu\n", rstat.render_time);
    3.25 +	fprintf(fp, "   tex update time (msec): %lu\n", rstat.tex_update_time);
    3.26 +	fprintf(fp, "> counters\n");
    3.27 +	fprintf(fp, "   AABB tests: %d\n", rstat.aabb_tests);
    3.28 +	fprintf(fp, "   AABB tests per ray (min/max/avg): %d/%d/%f\n",
    3.29 +			rstat.min_aabb_tests, rstat.max_aabb_tests, rstat.avg_aabb_tests);
    3.30 +	fprintf(fp, "   triangle tests: %d\n", rstat.triangle_tests);
    3.31 +	fprintf(fp, "   triangle tests per ray (min/max/avg): %d/%d/%f\n",
    3.32 +			rstat.min_triangle_tests, rstat.max_triangle_tests, rstat.avg_triangle_tests);
    3.33 +	fprintf(fp, "   rays cast: %dp %dr %ds (sum: %d)\n", rstat.prim_rays,
    3.34 +			rstat.refl_rays, rstat.shadow_rays, rstat.rays_cast);
    3.35 +	fprintf(fp, "   rays per second: %d\n", rstat.rays_per_sec);
    3.36 +	fprintf(fp, "   BRDF evaluations: %d\n", rstat.brdf_evals);
    3.37 +	fputc('\n', fp);
    3.38 +}
    3.39 +
    3.40  void set_render_option(int opt, bool val)
    3.41  {
    3.42  	switch(opt) {
     4.1 --- a/src/rt.h	Fri Sep 10 16:47:00 2010 +0100
     4.2 +++ b/src/rt.h	Sat Sep 11 03:00:21 2010 +0100
     4.3 @@ -1,6 +1,7 @@
     4.4  #ifndef RT_H_
     4.5  #define RT_H_
     4.6  
     4.7 +#include <stdio.h>
     4.8  #include "scene.h"
     4.9  
    4.10  enum {
    4.11 @@ -23,6 +24,20 @@
    4.12  	float origin[4], dir[4];
    4.13  };
    4.14  
    4.15 +struct RenderStats {
    4.16 +	unsigned long render_time, tex_update_time;
    4.17 +
    4.18 +	int aabb_tests, triangle_tests;
    4.19 +	int min_aabb_tests, max_aabb_tests;
    4.20 +	float avg_aabb_tests;
    4.21 +	int min_triangle_tests, max_triangle_tests;
    4.22 +	float avg_triangle_tests;
    4.23 +
    4.24 +	int rays_cast, rays_per_sec;
    4.25 +	int prim_rays, refl_rays, shadow_rays;
    4.26 +	int brdf_evals;
    4.27 +};
    4.28 +
    4.29  
    4.30  bool init_renderer(int xsz, int ysz, Scene *scn, unsigned int tex);
    4.31  void destroy_renderer();
    4.32 @@ -30,6 +45,8 @@
    4.33  void set_xform(float *matrix, float *invtrans);
    4.34  
    4.35  const RendInfo *get_render_info();
    4.36 +const RenderStats *get_render_stats();
    4.37 +void print_render_stats(FILE *out = stdout);
    4.38  
    4.39  void set_render_option(int opt, bool val);
    4.40  void set_render_option(int opt, int val);
    4.41 @@ -39,12 +56,13 @@
    4.42  int get_render_option_int(int opt);
    4.43  float get_render_option_float(int opt);
    4.44  
    4.45 -// raytrace in the CPU
    4.46 +// regular C++ raytracing using the KD-tree (single-threaded, keeps extensive debug stats)
    4.47  bool init_dbg_renderer(int xsz, int ysz, Scene *scn, unsigned int texid);
    4.48  void destroy_dbg_renderer();
    4.49  void dbg_set_primary_rays(const Ray *rays);
    4.50  void dbg_render(const float *xform, const float *invtrans_xform, int num_threads = -1);
    4.51  
    4.52 +
    4.53  // visualize the scene using OpenGL
    4.54  void dbg_render_gl(Scene *scn, bool show_tree = false, bool show_obj = true);
    4.55