RT_EXCEPTION_TEXTURE_ID_INVALID when texture sampler is updated (sample code included)

Hi

I tried to enable exceptions in my program to see if silent errors occured, and stumbled upon the following behaviour : I first setup all my scene and parameters, and launch the engine. All seems OK.

Then, I setup some sampler again (because its contents could have been modified since last launch call), and call launch again. This is when RT_EXCEPTION_TEXTURE_ID_INVALID appears.

The following code reproduces the problem (based on “device_exception” SDK sample code)

device_exception.cpp :

#include <optixu/optixpp_namespace.h>
#include <sutil.h>

#define LAUNCH_SIZE     (10)
#define STRING_LENGTH   (512)
#if _WIN32
#  define snprintf _snprintf
#endif

optix::TextureSampler updateSampler(optix::Context & context)
{
    optix::TextureSampler sampler = context->createTextureSampler();
    sampler->setWrapMode(0, RT_WRAP_MIRROR);
    sampler->setFilteringModes(RT_FILTER_NEAREST, RT_FILTER_NEAREST, RT_FILTER_NEAREST);
    sampler->setIndexingMode(RT_TEXTURE_INDEX_NORMALIZED_COORDINATES);
    sampler->setReadMode(RT_TEXTURE_READ_ELEMENT_TYPE);
    sampler->setMipLevelCount(1);
    sampler->setArraySize(1);
    optix::Buffer d_texture_contents = context->createBuffer(RT_BUFFER_INPUT_OUTPUT, RT_FORMAT_FLOAT, 1);
    d_texture_contents->setSize(10);
    sampler->setBuffer(0, 0, d_texture_contents);
    context["sampler_id"]->setInt(sampler->getId());

    return sampler;
}

int main(int argc, char* argv[])
{
    //
    char path_to_ptx[STRING_LENGTH];
    if (snprintf( path_to_ptx, STRING_LENGTH, "%s/%s", sutilSamplesPtxDir(), "device_exceptions_generated_device_exceptions.cu.ptx" ) >= STRING_LENGTH) {
        sutilReportError("PTX filename size is too large.\n");
    }

    //
    optix::Context context = optix::Context::create();

    // Context-level configuration
    context->setEntryPointCount(1);
    context->setRayTypeCount(1);
    context->setRayGenerationProgram(0, context->createProgramFromPTXFile(path_to_ptx, "raygen"));
    context->setMissProgram(0, context->createProgramFromPTXFile(path_to_ptx, "miss"));
    context["result_buffer"]->setBuffer(context->createBuffer(RT_BUFFER_INPUT_OUTPUT, RT_FORMAT_FLOAT, LAUNCH_SIZE));

    // Create dummy scene graph
    optix::Geometry geometry = context->createGeometry();
    geometry->setBoundingBoxProgram(context->createProgramFromPTXFile(path_to_ptx, "bounding_box"));
    geometry->setIntersectionProgram(context->createProgramFromPTXFile(path_to_ptx, "intersection"));
    geometry->setPrimitiveCount(1);
    optix::Material material = context->createMaterial();
    material->setClosestHitProgram(0, context->createProgramFromPTXFile(path_to_ptx, "closest_hit"));
    optix::GeometryInstance geometry_instance = context->createGeometryInstance();
    geometry_instance->setGeometry(geometry);
    geometry_instance->setMaterialCount(1);
    geometry_instance->setMaterial(0, material);
    optix::GeometryGroup geometry_group = context->createGeometryGroup();
    geometry_group->setChildCount(1);
    geometry_group->setChild(0, geometry_instance);
    optix::Acceleration acceleration = context->createAcceleration("NoAccel", "NoAccel");
    geometry_group->setAcceleration(acceleration);
    context["dummy_object"]->set(geometry_group);

    // Exceptions
    context->setExceptionProgram(0, context->createProgramFromPTXFile(path_to_ptx, "exception"));
    context->setExceptionEnabled(RT_EXCEPTION_ALL, true);
    context->setPrintEnabled(true);

    // Sampler
    optix::TextureSampler sampler = updateSampler(context);
    
    RTresult compilation_result = rtContextCompile(context->get());
    if( compilation_result != RT_SUCCESS) {
        std::string err_msg = context->getErrorString(compilation_result);
        fprintf(stderr, "%s\n", err_msg.c_str());
    }
    else
    {
        // first pass
        fprintf(stderr, "pass 1...\n");
        context->launch(0, LAUNCH_SIZE, 1, 1);

        // update sampler
        sampler->destroy();
        sampler = updateSampler(context);

        // second pass
        fprintf(stderr, "pass 2...\n");
        context->launch(0, LAUNCH_SIZE, 1, 1);
    }

    return 0;
}

device_exception.cu :

#include <optix.h>
#include <optixu/optixu_aabb_namespace.h>
#include <optixu/optixu_math_namespace.h>

// optix variables
rtDeclareVariable(uint3, launch_index, rtLaunchIndex, );
rtDeclareVariable(rtObject,   dummy_object, , );
rtDeclareVariable(int, sampler_id, , );
rtBuffer<float, 1> result_buffer;

// raygen
RT_PROGRAM void raygen()
{
    unsigned int dummy_payload;
    optix::Ray ray = optix::make_Ray(make_float3(0,0,0), make_float3(0,0,0), 0, 0, RT_DEFAULT_MAX);
    rtTrace(dummy_object, ray, dummy_payload);
}

// miss
RT_PROGRAM void miss()
{
}

// BBox
RT_PROGRAM void bounding_box(int primIdx, float result[6])
{
    optix::Aabb* aabb = (optix::Aabb*)result;
    aabb->set(make_float3(-1.0f), make_float3(1.0f));
}

// intersection test
RT_PROGRAM void intersection(int primIdx)
{
    rtPotentialIntersection(0.f);
    rtReportIntersection(0);
}

// closest hit
RT_PROGRAM void closest_hit()
{
    const float fetch_result = optix::rtTex1D<float>(sampler_id, .5f);
    result_buffer[launch_index.x] = fetch_result;
}

// exception
RT_PROGRAM void exception()
{
    rtPrintExceptionDetails();
}

How to get rid of this exception ?

thanks

edit :
Windows 7
Optix 3.7 beta 2, 32bit
CUDA 6.0
GTX 580, driver 340.52

Please always provide the following information when reporting a problem:
OS version, OS bitness, installed GPU(s), display driver version, OptiX version, CUDA Toolkit version.

Please try OptiX 3.7.0 beta 2 if you’re not on that. There have been fixes for ID based exceptions.
See https://devtalk.nvidia.com/default/topic/794982/optix/announcing-optix-3-7-beta/

If that is not helping, please try to add the following calls before the first launch to isolate things a little more:

context->validate();
context->compile();
context->launch(0, 0, 0); // Dummy launch to build everything.

Other notes:

  • Be very careful about which buffers you mark as RT_BUFFER_INPUT_OUTPUT. Buffers assigned to textures should normally be RT_BUFFER_INPUT only.
  • You leak the buffer you created for the existing sampler when calling sampler->destroy(). There is no ref-counting on the assigned buffer.
  • Use RT_FILTER_NONE as last parameter in setFilteringModes(). OptiX doesn’t implement mipmap filtering.

Edit: Ok already on 3.7 beta 2 then. :-)
Would you be able to test 64-bit as well?

. I added what you said (validate/compile/dummy_launch), it does not change anything

. I changed buffer type to RT_BUFFER_INPUT, to no avail. (btw all buffer in actual code are RT_BUFFER_INPUT, but thank you for pointing this out)

. I changed filtering mode argument to RT_FILTER_NONE, thank you (but no change either)

. I took care of buffer allocation (didn’t know that btw, thanks), but that changed nothing either

I can’t test 64 bit right now, because I’d have to recompile loads of third parties. But I’ll do it some day.

So the problem remains…

The problem is reproduced with a 64-bit build as well

Any feedback on this ?
Do you reproduce the behaviour ?

I just ran the source code you provided and it doesn’t fail for me in 64-bit. I’ve tried 3.7 beta 1 and beta 2 and post-beta 2.
I’m using a rel 346 driver. You might try using 343 or 346 and see if it fixes it for you.

You could also try making an OAC trace and sending it to us, in case cutting and pasting the source code is somehow causing it to not repro.

I upgraded my driver to the latest 347.25. The exception is still thrown with real code. I can’t test with the example code, but I’ll try when possible.

What does “OAC” stands for ?

OAC stands for OptiX API Capture. Please find details in this thread:
https://devtalk.nvidia.com/default/topic/803116/optix/error-with-rtpmodelupdate/

Ok thank you.
I reproduce the exception being thrown

OAC :

http://www.filedropper.com/oac00000

specs:
Windows 7 64-bit
GTX 580
driver 347.25
Visual studio 2013, 64-bit compilation
CUDA 6.5
Optix 3.7.0 beta 3

When I go to that link it redirects to the filedropper.com home page. Is the link wrong? Did the drop expire already?

Try putting it here:
https://drive.google.com/folderview?id=0B5e648cs-WDWfkFVNmVLbWRnWEszNEFGcHNEMUdXbFlMQ3hCaEFaZlpjZXhBZ3A3eHd4bG8&usp=sharing

This uses Nvidia’s secure Google Drive service, but anyone can read/write that particular folder.

Here you go :

https://drive.google.com/file/d/0B77-HnBCtrLVQVZnYjA4enIwZk0/view?usp=sharing

thanks

Hi

Did the OAC give any hint on what’s going on ?

Just so you know, the problem disappeared in latest 3.8.0 release

I have to guess it’s been fixed with the 3.8 rtTextureSamplerGetId fix.

Actually, the rtTextureSamplerGetId recompile was caused by an over-aggressive fix for this.

Glad it all works now.