testsuite/example-cuda/cuda_grid_renderer.cpp
/// Given the name of a texture, return an opaque handle that can be
/// used with texture calls to avoid the name lookups.
Given the name of a texture, return an opaque handle that can be
used with texture calls to avoid the name lookups.
Given the name of a texture return an opaque handle that can be used with texture calls to avoid the name lookups .
RendererServices::TextureHandle*
CudaGridRenderer::get_texture_handle(OIIO::ustring filename,
                                     ShadingContext* shading_context)
{
    auto itr = _samplers.find(filename);
    if (itr == _samplers.end()) {
        OIIO::ImageBuf image;
        if (!image.init_spec(filename, 0, 0)) {
            std::cerr << "Could not load " << filename << std::endl;
            return (TextureHandle*)nullptr;
        }
        OIIO::ROI roi = OIIO::get_roi_full(image.spec());
        int32_t width = roi.width(), height = roi.height();
        std::vector<float> pixels(width * height * 4);
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {
                image.getpixel(i, j, 0, &pixels[((j * width) + i) * 4 + 0]);
            }
        }
        cudaResourceDesc res_desc = {};
        int32_t pitch = width * 4 * sizeof(float);
        cudaChannelFormatDesc channel_desc
            = cudaCreateChannelDesc(32, 32, 32, 32, cudaChannelFormatKindFloat);
        cudaArray_t pixelArray;
        CUDA_CHECK(cudaMallocArray(&pixelArray, &channel_desc, width, height));
        CUDA_CHECK(cudaMemcpy2DToArray(pixelArray,
                                        0, 0, pixels.data(), pitch,
                                       pitch, height, cudaMemcpyHostToDevice));
        res_desc.resType         = cudaResourceTypeArray;
        res_desc.res.array.array = pixelArray;
        cudaTextureDesc tex_desc = {};
        tex_desc.addressMode[0]  = cudaAddressModeWrap;
        tex_desc.addressMode[1]  = cudaAddressModeWrap;
        tex_desc.filterMode      = cudaFilterModeLinear;
        tex_desc.readMode
            = cudaReadModeElementType;  
        tex_desc.normalizedCoords    = 1;
        tex_desc.maxAnisotropy       = 1;
        tex_desc.maxMipmapLevelClamp = 99;
        tex_desc.minMipmapLevelClamp = 0;
        tex_desc.mipmapFilterMode    = cudaFilterModePoint;
        tex_desc.borderColor[0]      = 1.0f;
        tex_desc.sRGB                = 0;
        cudaTextureObject_t cuda_tex = 0;
        CUDA_CHECK(
            cudaCreateTextureObject(&cuda_tex, &res_desc, &tex_desc, nullptr));
        itr = _samplers.emplace(std::move(filename), std::move(cuda_tex)).first;
    }
    return reinterpret_cast<RendererServices::TextureHandle*>(itr->second);
}
RendererServices :: TextureHandle * CudaGridRenderer :: get_texture_handle ( OIIO :: ustring filename , ShadingContext * shading_context ) { auto itr = _samplers . find ( filename ) ; if ( itr == _samplers . end ( ) ) { OIIO :: ImageBuf image ; if ( ! image . init_spec ( filename , 0 , 0 ) ) { std :: cerr << " " << filename << std :: endl ; return ( TextureHandle * ) nullptr ; } OIIO :: ROI roi = OIIO :: get_roi_full ( image . spec ( ) ) ; int32_t width = roi . width ( ) , height = roi . height ( ) ; std :: vector < float > pixels ( width * height * 4 ) ; for ( int j = 0 ; j < height ; j ++ ) { for ( int i = 0 ; i < width ; i ++ ) { image . getpixel ( i , j , 0 , & pixels [ ( ( j * width ) + i ) * 4 + 0 ] ) ; } } cudaResourceDesc res_desc = { } ; int32_t pitch = width * 4 * sizeof ( float ) ; cudaChannelFormatDesc channel_desc = cudaCreateChannelDesc ( 32 , 32 , 32 , 32 , cudaChannelFormatKindFloat ) ; cudaArray_t pixelArray ; CUDA_CHECK ( cudaMallocArray ( & pixelArray , & channel_desc , width , height ) ) ; CUDA_CHECK ( cudaMemcpy2DToArray ( pixelArray , 0 , 0 , pixels . data ( ) , pitch , pitch , height , cudaMemcpyHostToDevice ) ) ; res_desc . resType = cudaResourceTypeArray ; res_desc . res . array . array = pixelArray ; cudaTextureDesc tex_desc = { } ; tex_desc . addressMode [ 0 ] = cudaAddressModeWrap ; tex_desc . addressMode [ 1 ] = cudaAddressModeWrap ; tex_desc . filterMode = cudaFilterModeLinear ; tex_desc . readMode = cudaReadModeElementType ; tex_desc . normalizedCoords = 1 ; tex_desc . maxAnisotropy = 1 ; tex_desc . maxMipmapLevelClamp = 99 ; tex_desc . minMipmapLevelClamp = 0 ; tex_desc . mipmapFilterMode = cudaFilterModePoint ; tex_desc . borderColor [ 0 ] = 1.0f ; tex_desc . sRGB = 0 ; cudaTextureObject_t cuda_tex = 0 ; CUDA_CHECK ( cudaCreateTextureObject ( & cuda_tex , & res_desc , & tex_desc , nullptr ) ) ; itr = _samplers . emplace ( std :: move ( filename ) , std :: move ( cuda_tex ) ) . first ; } return reinterpret_cast < RendererServices :: TextureHandle * > ( itr -> second ) ; }
Given the name of a texture, return an opaque handle that can be
used with texture calls to avoid the name lookups.
Given the name of a texture return an opaque handle that can be used with texture calls to avoid the name lookups .
// Open image // hard-code textures to 4 channels /* offset */ // cudaReadModeNormalizedFloat; // Create texture object