     cudaChannelFormatDesc _dog_3d_desc;
     cudaExtent            _dog_3d_ext;
     cudaTextureObject_t   _dog_3d_tex;
+#ifdef WITH_SURFACE
+    cudaSurfaceObject_t   _dog_3d_surf;
+#endif // WITH_SURFACE
 
     _dog_3d_desc.f = cudaChannelFormatKindFloat;
     _dog_3d_desc.x = 32;

    }

#if 0
    err = cudaMemcpyToArray( _dog_3d,
                             0, 0,
                             array,
                             10*4*2*sizeof(float),
                             // 10*4*sizeof(float),
                             cudaMemcpyHostToDevice );
#else
    cudaMemcpy3DParms s = { 0 };
    s.srcPtr = make_cudaPitchedPtr( array, 10*sizeof(float), 10, 4 );
    s.dstArray = _dog_3d;
    s.extent = make_cudaExtent( width, height, levels );
    s.kind = cudaMemcpyHostToDevice;
    err = cudaMemcpy3D( &s );
#endif
    if( err != cudaSuccess ) {
        cerr << "CUDA memcpy 3D failed: " << cudaGetErrorString(err) << endl;
    } else {
        cerr << "CUDA memcpy 3D succeeded" << endl;
    }

    testPrintArray
        <<<1,1>>>
        ( _dog_3d_tex, width, height, levels );

    err = cudaFreeHost( array );
    if( err != cudaSuccess ) {
        cerr << "CUDA free host failed" << endl;
    } else {
        cerr << "CUDA free host success" << endl;
    }

    err = cudaDestroyTextureObject( _dog_3d_tex );
    if( err != cudaSuccess ) {
        cerr << "CUDA destroy texture failed" << endl;
    } else {
        cerr << "CUDA destroy texture success" << endl;
    }

                                   &dog_tex_desc, 0 );
    if( err != cudaSuccess ) {
        cerr << "CUDA create texture failed: " << cudaGetErrorString(err) << endl;
        exit( -1 );
    } else {
        cerr << "CUDA create texture succeeded" << endl;
    }

    // cudaResourceDesc dog_res_desc;
    // dog_res_desc.resType         = cudaResourceTypeArray;
    // dog_res_desc.res.array.array = _dog_3d;

#ifdef WITH_SURFACE
    err = cudaCreateSurfaceObject( &_dog_3d_surf, &dog_res_desc );
    if( err != cudaSuccess ) {
        cerr << "CUDA create surface failed: " << cudaGetErrorString(err) << endl;
        exit( -1 );
    } else {
        cerr << "CUDA create surface succeeded" << endl;
    }
#endif // WITH_SURFACE

    float* array;
    err = cudaMallocHost( &array, width*height*levels*sizeof(float) );
    if( err != cudaSuccess ) {
        cerr << "CUDA malloc host failed: " << cudaGetErrorString(err) << endl;
        exit( -1 );
    } else {
        cerr << "CUDA malloc host succeeded" << endl;
    }

    cerr << "== host-sided printing of array ==" << endl;
    for( int z=0; z<levels; z++ ) {
        for( int y=0; y<height; y++ ) {
            for( int x=0; x<width; x++ ) {
                int val = x + 10*y + 100*z;
                array[(z*height + y)*width + x] = val;
                cerr << val << " ";
            }
            cerr << endl;
        }
