Is it possible to unbind a miss program?

Our application has several different operating modes, each utilizing very similar Optix hierarchies and flow. When switching between the modes, I naturally try to trigger re-compilation as little as possible, and try to make any absolutely required changes affect only the lowest nodes.
I have now reached a situation where one operating mode had a Miss program, which simply does not apply to the new mode. Is there a way to unbind a Miss program from its Context?

Calling (through the C++ wrapper) context->setMissProgram( RAYTYPE, NULL) obviously fails.

Since programs are context (as opposed to material) bound, I would really hate to destroy my entire context and reload/recompile/refit all the data.

A possible workaround that I currently implemented was to replace the program with a dummy empty miss program. Does this incur a performance penalty ( ie- is there an overhead in the inner workings of Optix that makes it less efficient to run an empty Miss program as opposed to not setting one at all)?

Thanks!

Good question. Your call to setMissProgram() with a NULL program should have worked, and it does indeed work in the C API if you call rtContextSetMissProgram with a NULL program.

It turns out you found a bug in our C++ API wrapper. But since the bug is in a header only, you can patch it in place: edit the file “include/optixu/optixpp_namespace.h” in your OptiX 4.0.2 distribution as follows:

inline void ContextObj::setMissProgram(unsigned int ray_type_index, Program  program)
{
    // added NULL check for program below
    checkError( rtContextSetMissProgram( m_context, ray_type_index, program ? program->get() : 0 ) );
}

Then recompile your app to pick this up. Some other set*Program functions in that header need the same treatment; we’ll fix them for the next release.

If you don’t want to change the header, there are two workarounds:

  • use the C API
  • use the C++ API to set the miss program to a valid Program object, e.g., from a PTX file. Then immediately call program->destroy().

Did this fix work for you? Please post back either way so I know it’s resolved.

Thanks for your quick response.

  1. Using the header is less optimal, since I am not the only one building this solution. Also, and this leads to the next bullet point:

  2. calling the C API directly through

rtContextSetMissProgram( m_Context->get(), RAYTYPE, NULL );

returns the ret code RT_ERROR_INVALID_VALUE (1281).
Now, I am aware that in this issue we do differ, since we are still using optix 3.8.1, the last version which still supported x86 (from which we still cannot migrate due to business concerns).

  1. As for the third proposed option:
m_Context->setMissProgram( RAYTYPE, m_MissProg );	
m_MissProg ->destroy();
m_Context->validate();

Validate throws the following exception
“Invalid context (Details: Function “_rtContextValidate” caught exception: Validation error: Unknown type for variable: $missProgram_2. Declaration of variable not found in PTX., [4915381])”

So in summary, setting a dummy empty miss program is the only current workaround I have to avoid destroying the whole context.

Specs:
Optix: 3.8.1
CUDA: 7.0
OS: Windows 7 x64
GPU: GTX 750 Ti
Driver: 355.82

I can’t find a 3.8.1 public release at the moment, but I found 3.8.0 and verified your results. Looks like my suggested workarounds are only for 4.0.2.

For now it sounds like the dummy miss program is the current best option if you can’t upgrade to 4.0.2. As far as performance overhead, this really needs to be measured per application. I would not expect much overhead though.

Allright then.
I guess that on the grand scale of workarounds, setting a dummy program is a relatively minor issue. I’ll leave a note to come back to this once we do upgrade Optix.
On a side note, I’m kind of surprised no one has tried to do this action and met the issue until now…

Thanks for your help!