42 static const char*
const s_kernelDir =
"src/rt/kernels";
43 static const char*
const s_initialMeshDir =
"scenes/rt/sibenik";
44 static const char*
const s_defaultMeshFile =
"scenes/rt/sibenik/sibenik.obj";
48 static const char*
const s_defaultCameras[] =
50 "conference",
"6omr/04j3200bR6Z/0/3ZEAz/x4smy19///c/05frY109Qx7w////m100",
51 "fairyforest",
"cIxMx/sK/Ty/EFu3z/5m9mWx/YPA5z/8///m007toC10AnAHx///Uy200",
52 "sibenik",
"ytIa02G35kz1i:ZZ/0//iSay/5W6Ex19///c/05frY109Qx7w////m100",
53 "sanmiguel",
"Yciwz1oRQmz/Xvsm005CwjHx/b70nx18tVI7005frY108Y/:x/v3/z100",
59 static const char*
const s_rayTypeNames[] =
70 static const char*
const s_aboutText =
71 "\"Understanding the Efficiency of Ray Traversal on GPUs\",\n"
72 "Timo Aila and Samuli Laine,\n"
73 "Proc. High-Performance Graphics 2009\n"
75 "Implementation by Tero Karras, Timo Aila, and Samuli Laine\n"
76 "Copyright 2009-2012 NVIDIA Corporation\n"
78 "http://code.google.com/p/understanding-the-efficiency-of-ray-traversal-on-gpus/\n"
83 static const char*
const s_commandHelpText =
85 "Usage: rt <mode> [options]\n"
87 "Supported values for <mode>:\n"
89 " interactive Start in interactive mode.\n"
90 " benchmark Run benchmark for given mesh.\n"
94 " --log=<file.log> Log all output to file.\n"
95 " --size=<w>x<h> Frame size. Default is \"1024x768\".\n"
97 "Options for \"rt interactive\":\n"
99 " --state=<file.dat> Load state from the given file.\n"
101 "Options for \"rt benchmark\":\n"
103 " --mesh=<file.obj> Mesh to benchmark.\n"
104 " --camera=\"<sig>\" Camera signature. Can specify multiple times.\n"
105 " --kernel=<name> CUDA kernel. Can specify multiple. Default = all.\n"
106 " --sbvh-alpha=<value> SBVH alpha parameter. Default is \"1.0e-5\".\n"
107 " --ao-radius=<value> AO ray length. Default is \"5\".\n"
108 " --samples=<value> Secondary rays per pixel. Default is \"32\".\n"
109 " --sort=<1/0> Sort secondary rays. Default is \"1\".\n"
110 " --warmup-repeats=<num> Launches prior to measurement. Default is \"2\".\n"
111 " --measure-repeats=<num> Launches to measure per batch. Default is \"10\".\n"
117 static const char*
const s_guiHelpText =
120 "\tF1\tHide this message\n"
121 "\tEsc\tExit (also Alt-F4)\n"
122 "\tTab\tShow all GUI controls\n"
123 "\tNum\tLoad numbered state\n"
124 "\tAlt-Num\tSave numbered state\n"
125 "\tF9\tShow/hide FPS counter\n"
126 "\tF10\tShow/hide GUI\n"
127 "\tF11\tToggle fullscreen mode\n"
128 "\tPrtScn\tSave screenshot\n"
132 "\tDrag\tRotate (left), strafe (middle), zoom (right)\n"
134 "\tW\tMove forward (also Alt-UpArrow)\n"
135 "\tS\tMove back (also Alt-DownArrow)\n"
136 "\tA\tStrafe left (also Alt-LeftArrow)\n"
137 "\tD\tStrafe right (also Alt-RightArrow)\n"
138 "\tR\tStrafe up (also PageUp)\n"
139 "\tF\tStrafe down (also PageDown)\n"
140 "\tWheel\tAdjust movement speed\n"
141 "\tSpace\tMove faster (hold)\n"
142 "\tCtrl\tMove slower (hold)\n"
144 "Uncheck \"Retain camera alignment\" to enable:\n"
146 "\tQ\tRoll counter-clockwise (also Insert)\n"
147 "\tE\tRoll clockwise (also Home)\n"
155 m_action (Action_None),
158 m_rayType (
Renderer::RayType_Primary),
164 m_showCameraControls (false),
165 m_showKernelSelector (false),
169 if (!m_kernelNames.getSize())
170 fail(
"No CUDA kernel sources found!");
181 else if (bvh ==
"KDTree")
190 m_window.
setTitle(
"GPU Ray Traversal");
228 bool v = (!m_showCameraControls || !m_showKernelSelector);
229 m_showCameraControls =
v;
230 m_showKernelSelector =
v;
242 Action action = m_action;
243 m_action = Action_None;
255 case Action_LoadMesh:
261 case Action_ResetCamera:
265 m_commonCtrl.
message(
"Camera reset");
269 case Action_ExportCameraSignature:
271 printf(
"\nCamera signature:\n");
276 case Action_ImportCameraSignature:
279 printf(
"\nEnter camera signature:\n");
307 render(m_window.
getGL());
320 s.
get(meshFileName,
"m_meshFileName");
321 s.
get((
S32&)m_rayType,
"m_rayType");
322 s.
get(m_aoRadius,
"m_aoRadius");
323 s.
get(m_numSamples,
"m_numSamples");
324 s.
get(kernelName,
"m_kernelName");
327 if (m_meshFileName != meshFileName && meshFileName.
getLength())
328 loadMesh(meshFileName);
329 if (m_kernelNames.contains(kernelName))
330 m_kernelNameIdx = m_kernelNames.indexOf(kernelName);
339 s.
set(m_meshFileName,
"m_meshFileName");
340 s.
set((
S32&)m_rayType,
"m_rayType");
341 s.
set(m_aoRadius,
"m_aoRadius");
342 s.
set(m_numSamples,
"m_numSamples");
343 s.
set(m_kernelNames[m_kernelNameIdx],
"m_kernelName");
349 void App::rebuildGui(
void)
382 for (
int i = 0; i < m_kernelNames.getSize(); i++)
393 void App::waitKey(
void)
395 printf(
"Press any key to continue . . . ");
415 params.
kernelName = m_kernelNames[m_kernelNameIdx];
436 String rayStats =
sprintf(
"%.2f million %s rays, %.2f ms, %.2f MRays/s",
437 (
F32)numRays * 1.0e-6
f,
438 s_rayTypeNames[m_rayType],
440 (
F32)numRays * 1.0e-6
f / launchTime);
442 String bvhStats =
sprintf(
"%.2f Mtris, %.2f MB (%.2f MB for nodes, %.2f MB for tris)",
444 (
F32)(nodeBytes + triBytes) *
exp2(-20),
448 m_commonCtrl.
message(rayStats,
"rayStats");
449 m_commonCtrl.
message(bvhStats,
"bvhStats");
468 String str = s_guiHelpText;
471 while (startIdx < str.getLength())
473 if (str[startIdx] ==
'\n')
474 pos =
Vec2f(0.0
f, pos.y - (
F32)fontSize);
475 else if (str[startIdx] ==
'\t')
478 int endIdx = startIdx;
479 while (endIdx < str.getLength() && str[endIdx] !=
'\n' && str[endIdx] !=
'\t')
482 gl->
drawLabel(str.substring(startIdx, endIdx), pos + origin,
Vec2f(0.0
f, 1.0
f), 0xFFFFFFFF);
483 startIdx =
max(endIdx, startIdx + 1);
492 bool App::loadMesh(
const String& fileName)
511 m_meshFileName = fileName;
519 void App::resetCamera(
void)
533 for (
const char*
const*
ptr = s_defaultCameras;
ptr[0];
ptr += 2)
549 void App::firstTimeInit(
void)
553 String kernel =
"tesla_persistent_while_while";
555 kernel =
"tesla_persistent_speculative_while_while";
557 kernel =
"fermi_speculative_while_while";
559 kernel =
"kepler_dynamic_fetch";
560 if (m_kernelNames.contains(kernel))
561 m_kernelNameIdx = m_kernelNames.indexOf(kernel);
565 loadMesh(s_defaultMeshFile);
579 HANDLE h = FindFirstFile(
sprintf(
"%s/*.cu", s_kernelDir).getPtr(), &fd);
580 if (h != INVALID_HANDLE_VALUE)
584 String name = fd.cFileName;
587 while (FindNextFile(h, &fd) != 0);
601 printf(
"Starting up...\n");
623 const Vec2i& frameSize,
639 printf(
"Running benchmark for \"%s\".\n", meshFile.
getPtr());
673 for (
int kernelIdx = 0; kernelIdx < kernels.
getSize(); kernelIdx++)
675 for (
int rayType = 0; rayType < numRayTypes; rayType++)
678 F32 totalLaunchTime = 0.0f;
680 for (
int cameraIdx = 0; cameraIdx < cameras.
getSize(); cameraIdx++)
684 String title =
sprintf(
"%s, %s, camera %d", kernels[kernelIdx].getPtr(), s_rayTypeNames[rayType], cameraIdx);
709 for (
int i = 0; i < 3; i++)
717 for (
int i = 0; i < warmupRepeats; i++)
719 for (
int i = 0; i < measureRepeats; i++)
731 F32 mraysPerSec = (
F32)totalRays / totalLaunchTime * 1.0e-6
f;
732 results.
add(mraysPerSec);
733 printf(
"Mrays/s = %.2f\n", mraysPerSec);
743 printf(
"%-42s",
"Kernel");
744 for (
int i = 0; i < numRayTypes; i++)
745 printf(
"%-10s", s_rayTypeNames[i]);
749 for (
int i = 0; i < numRayTypes; i++)
753 for (
int i = 0; i < kernels.
getSize(); i++)
755 printf(
"%-42s", kernels[i].getPtr());
756 for (
int j = 0; j < numRayTypes; j++)
757 printf(
"%-10.2f", results[i * numRayTypes + j]);
762 for (
int i = 0; i < numRayTypes; i++)
774 bool modeInteractive =
false;
775 bool modeBenchmark =
false;
776 bool showHelp =
false;
780 printf(
"Specify \"--help\" for a list of command-line options.\n\n");
781 modeInteractive =
true;
786 if (mode ==
"interactive") modeInteractive =
true;
787 else if (mode ==
"benchmark") modeBenchmark =
true;
788 else showHelp =
true;
799 F32 sbvhAlpha = 1.0e-5
f;
802 bool sortRays =
true;
803 int warmupRepeats = 2;
804 int measureRepeats = 10;
806 for (
int i = 2; i <
argc; i++)
825 else if (modeInteractive &&
parseLiteral(ptr,
"--state="))
837 else if (modeBenchmark &&
parseLiteral(ptr,
"--camera="))
843 else if (modeBenchmark &&
parseLiteral(ptr,
"--kernel="))
849 else if (modeBenchmark &&
parseLiteral(ptr,
"--sbvh-alpha="))
851 if (!
parseFloat(ptr, sbvhAlpha) || *ptr || sbvhAlpha < 0.0f || sbvhAlpha > 1.0
f)
854 else if (modeBenchmark &&
parseLiteral(ptr,
"--ao-radius="))
856 if (!
parseFloat(ptr, aoRadius) || *ptr || aoRadius < 0.0
f)
859 else if (modeBenchmark &&
parseLiteral(ptr,
"--samples="))
861 if (!
parseInt(ptr, numSamples) || *ptr || numSamples < 1)
867 if (!
parseInt(ptr, value) || *ptr || value < 0 || value > 1)
868 setError(
"Invalid ray sorting enable/disable '%s'!",
argv[i]);
869 sortRays = (value != 0);
871 else if (modeBenchmark &&
parseLiteral(ptr,
"--warmup-repeats="))
873 if (!
parseInt(ptr, warmupRepeats) || *ptr || warmupRepeats < 0)
874 setError(
"Invalid number of warmup repeats '%s'!",
argv[i]);
876 else if (modeBenchmark &&
parseLiteral(ptr,
"--measure-repeats="))
878 if (!
parseInt(ptr, measureRepeats) || *ptr || measureRepeats < 1)
879 setError(
"Invalid number of measurement repeats '%s'!",
argv[i]);
891 printf(
"%s", s_commandHelpText);
907 setError(
"Mesh file (--mesh) not specified!");
909 setError(
"No camera signatures (--camera) specified!");
920 runBenchmark(frameSize, meshFile, cameras, kernels, sbvhAlpha, aoRadius, numSamples, sortRays, warmupRepeats, measureRepeats);
MeshBase * importMesh(const String &fileName)
void addStateObject(StateObject *obj)
void addGUIControls(void)
Stucture holding the BVH build parameters.
String substring(int start, int end) const
void runInteractive(const Vec2i &frameSize, const String &stateFile)
const char * getPtr(void) const
String getFileName(void) const
Mat4f setVGXform(const Mat4f &m)
bool GetStringValue(const char *name, char *value, const bool isFatal=false) const
void setDefaultFont(void)
void setWindowSize(const Vec2i &size)
CudaAS * getCudaBVH(void)
void setError(const char *fmt,...)
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void p CUfunction unsigned int bytes CUtexref pTexRef CUtexref CUarray unsigned int Flags CUtexref int CUaddress_mode am CUtexref unsigned int Flags CUaddress_mode CUtexref int dim CUarray_format int CUtexref hTexRef CUfunction unsigned int numbytes CUfunction int float value CUfunction int CUtexref hTexRef CUfunction int int grid_height CUevent unsigned int Flags CUevent hEvent CUevent hEvent CUstream unsigned int Flags CUstream hStream GLuint bufferobj unsigned int CUdevice dev CUdeviceptr unsigned int CUmodule const char name CUdeviceptr unsigned int bytesize CUdeviceptr dptr void unsigned int bytesize void CUdeviceptr unsigned int ByteCount CUarray unsigned int CUdeviceptr unsigned int ByteCount CUarray unsigned int const void unsigned int ByteCount CUarray unsigned int CUarray unsigned int unsigned int ByteCount void CUarray unsigned int unsigned int CUstream hStream const CUDA_MEMCPY2D pCopy CUdeviceptr const void unsigned int CUstream hStream const CUDA_MEMCPY2D CUstream hStream CUdeviceptr unsigned char unsigned int N CUdeviceptr unsigned int unsigned int N CUdeviceptr unsigned int unsigned short unsigned int unsigned int Height CUarray const CUDA_ARRAY_DESCRIPTOR pAllocateArray CUarray const CUDA_ARRAY3D_DESCRIPTOR pAllocateArray unsigned int CUtexref CUdeviceptr unsigned int bytes CUcontext unsigned int CUdevice device GLenum texture GLenum GLuint buffer GLenum GLuint renderbuffer GLenum GLsizeiptr const GLvoid GLenum usage GLuint shader GLenum type GLsizei const GLuint framebuffers GLsizei const GLuint renderbuffers GLuint v GLuint v GLenum GLenum GLenum GLuint GLint level GLsizei GLuint framebuffers GLuint const GLchar name GLenum GLintptr GLsizeiptr GLvoid data GLuint GLenum GLint param GLuint GLenum GLint param GLhandleARB programObj GLenum GLenum GLsizei GLsizei height GLenum GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid pixels GLint GLsizei const GLfloat value GLint GLfloat GLfloat v1 GLint GLfloat GLfloat GLfloat v2 GLint GLsizei const GLfloat value GLint GLsizei GLboolean const GLfloat value GLuint program GLuint GLfloat GLfloat GLfloat z GLuint GLint GLenum GLboolean GLsizei const GLvoid pointer GLuint GLuint const GLchar name GLenum GLsizei GLenum GLsizei GLsizei height GLenum GLuint renderbuffer GLenum GLenum GLint * params
Vec2i drawLabel(const String &str, const Vec4f &pos, const Vec2f &align, U32 fgABGR, U32 bgABGR)
virtual Buffer & getTriWoopBuffer(void)=0
Returns buffer of woopified triangles.
void addListener(Listener *listener)
void addToggle(bool *target, const String &key, const String &title, bool *dirtyNotify=NULL)
void setStateFilePrefix(const String &prefix)
void beginSliderStack(void)
void addSlider(F32 *target, F32 minValue, F32 maxValue, bool isExponential, const String &increaseKey, const String &decreaseKey, const String &format, F32 speed=0.25f, bool *dirtyNotify=NULL)
virtual Buffer & getTriIndexBuffer(void)=0
Returns buffer of triangle indexes.
int lastIndexOf(char chr) const
F32 splitAlpha
Spatial split area threshold.
bool restoreError(const String &old)
void setEnableRandom(bool enable)
bool parseLiteral(const char *&ptr, const char *str)
static int getComputeCapability(void)
F32 renderFrame(GLContext *gl, const CameraControls &camera)
virtual void readState(StateDump &d)
void loadDefaultState(void)
void listKernels(Array< String > &kernelNames)
bool ReadEnvFile(const char *filename)
void setBuildParams(const BVH::BuildParams ¶ms)
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void p CUfunction unsigned int bytes CUtexref pTexRef CUtexref CUarray unsigned int Flags CUtexref int CUaddress_mode am CUtexref unsigned int Flags CUaddress_mode CUtexref int dim CUarray_format int CUtexref hTexRef CUfunction unsigned int numbytes CUfunction int float value CUfunction int CUtexref hTexRef CUfunction int int grid_height CUevent unsigned int Flags CUevent hEvent CUevent hEvent CUstream unsigned int Flags CUstream hStream GLuint bufferobj unsigned int CUdevice dev CUdeviceptr unsigned int CUmodule const char name CUdeviceptr unsigned int bytesize CUdeviceptr dptr void unsigned int bytesize void CUdeviceptr unsigned int ByteCount CUarray unsigned int CUdeviceptr unsigned int ByteCount CUarray unsigned int const void unsigned int ByteCount CUarray unsigned int CUarray unsigned int unsigned int ByteCount void CUarray unsigned int unsigned int CUstream hStream const CUDA_MEMCPY2D pCopy CUdeviceptr const void unsigned int CUstream hStream const CUDA_MEMCPY2D CUstream hStream CUdeviceptr unsigned char unsigned int N CUdeviceptr unsigned int unsigned int N CUdeviceptr unsigned int unsigned short unsigned int unsigned int Height CUarray const CUDA_ARRAY_DESCRIPTOR pAllocateArray CUarray const CUDA_ARRAY3D_DESCRIPTOR pAllocateArray unsigned int CUtexref CUdeviceptr unsigned int bytes CUcontext unsigned int CUdevice device GLenum texture GLenum GLuint buffer GLenum GLuint renderbuffer GLenum GLsizeiptr const GLvoid GLenum usage GLuint shader GLenum type GLsizei const GLuint framebuffers GLsizei const GLuint renderbuffers GLuint v
const String & getError(void)
void set(const StateDump &other)
void showModalMessage(const String &msg)
FW_CUDA_FUNC T min(const VectorBase< T, L, S > &v)
void setVisible(bool visible)
virtual void writeState(StateDump &d) const
FW_CUDA_FUNC T max(const VectorBase< T, L, S > &v)
void setFont(const String &name, int size, U32 style)
void setControlVisibility(bool visible)
void setMesh(MeshBase *mesh)
void pushLogFile(const String &name, bool append=true)
String getMeshImportFilter(void)
int getLength(void) const
String showFileLoadDialog(const String &title, const String &filters="", const String &initialDir="", bool forceInitialDir=false)
void setSize(const Vec2i &size)
Mat4f xformMatchPixels(void) const
String encodeSignature(void) const
String sprintf(const char *fmt,...)
static bool isAvailable(void)
bool parseInt(const char *&ptr, S32 &value)
void setParams(const Params ¶ms)
void addButton(bool *target, const String &key, const String &title, bool *dirtyNotify=NULL)
String getStateFileName(int idx) const
int getTotalNumRays(void)
void showMessageDialog(const String &title, const String &text)
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void p CUfunction unsigned int bytes CUtexref pTexRef CUtexref CUarray unsigned int Flags CUtexref int CUaddress_mode am CUtexref unsigned int Flags CUaddress_mode CUtexref int dim CUarray_format int CUtexref hTexRef CUfunction unsigned int numbytes CUfunction int float value CUfunction int CUtexref hTexRef CUfunction f
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void p CUfunction unsigned int bytes CUtexref pTexRef CUtexref CUarray unsigned int Flags CUtexref int CUaddress_mode am CUtexref unsigned int Flags CUaddress_mode CUtexref int dim CUarray_format int CUtexref hTexRef CUfunction unsigned int numbytes CUfunction int float value
static void pollMessages(void)
void initForMesh(const MeshBase *mesh)
void printf(const char *fmt,...)
void setMessageWindow(Window *window)
bool parseFloat(const char *&ptr, F32 &value)
void pushOwner(const String &id)
bool loadState(const String &fileName)
int numTriangles(void) const
void runBenchmark(const Vec2i &frameSize, const String &meshFile, const Array< String > &cameras, const Array< String > &kernels, F32 sbvhAlpha, F32 aoRadius, int numSamples, bool sortSecondary, int warmupRepeats, int measureRepeats)
const Array< U8 > * get(const String &id) const
void decodeSignature(const String &sig)
const Vec2i & getViewSize(void) const
virtual Buffer & getNodeBuffer(void)=0
Returns node buffer.
static void staticInit(void)
void fail(const char *fmt,...)
void setTitle(const String &title)
void endSliderStack(void)
void flashButtonTitles(void)
void displayResult(GLContext *gl)
bool saveState(const String &fileName)
Interface for acceleration structure.
void beginFrame(GLContext *gl, const CameraControls &camera)
void message(const String &str, const String &volatileID="", U32 abgr=0xffffffffu)
virtual bool handleEvent(const Window::Event &ev)
void drawModalMessage(const String &msg)