gpt4 book ai didi

opengl - CUDA 立方体贴图纹理

转载 作者:行者123 更新时间:2023-12-03 20:56:52 25 4
gpt4 key购买 nike

如何在 CUDA 中处理 OpenGL 立方体贴图纹理?

当想要在 CUDA 内核中使用 OpenGL 纹理时,要做的一件事是从注册的图像和映射资源中检索一个 CUDA 数组,在这种情况下是一个纹理。在驱动程序 API 中,它由 cuGraphicsSubResourceGetMappedArray 完成。调用,这在 2D 纹理的情况下不是问题。但是在谈到上述立方体贴图时,此函数的第三个参数需要一个面枚举(如 CU_CUBEMAP_FACE_POSITIVE_X )。因此出现了一些问题 - 当一个人通过这样的枚举时,返回的纹理数组将只包含该特定面部的数据,对吗?那么如何将立方体纹理作为一个整体来进行立方体映射,同样:

color = texCube(cubeMap, x, y, z);

还是在 CUDA 内核中不可能这样做,并且需要在用户代码中使用具有适当计算和采样的 2D 纹理?

最佳答案

好的 - 我自己设法解决了这个问题,虽然解决方案不像使用另一个 CUDA 函数那么简单。

要将 CUDA 纹理引用与任何纹理绑定(bind),无论是从 OpenGL 还是 D3D 获得的纹理,都必须使用 cuGraphicsSubResourceGetMappedArray 提供映射到资源的 CUDA 数组。检索它。正如我在问题中提到的,在一维或二维纹理的情况下很简单。但是对于其他可用类型,它会更加复杂。

在任何时候,我们都需要一个引用绑定(bind)到的 CUDA 数组。立方体贴图纹理也是如此。但在这种情况下,阵列必须是 3D 阵列。问题在于 CUDA 驱动程序 API 仅提供上述函数来从此类纹理资源中检索单个图层,并将其映射到单个二维数组。为了得到我们想要的,我们必须让我们自己成为包含所有层的 3D 数组 (或立方体贴图的面)。

首先,我们必须使用上述函数为每个层/面获取数组。下一步是通过调用 cuArray3DCreate 创建 3D 数组。 ,输入适当的参数集(大小/层数、细节级别、数据格式、每个纹素的 channel 数和一些标志)。然后我们要复制图层的数组通过一系列调用 cuMemcpy3D 到 3D ,每个层/面阵列一个。

最后,我们将 objective-c UDA 纹理引用设置为 cuTexRefSetArray 。 ,输入我们创建并复制到的 3D 数组。在设备代码内部,我们创建了一个具有适当纹理类型和模式(float4 和立方体贴图)的引用,并使用 texCubemap 对其进行采样.

下面我放了一个功能的片段,它可以在 CIRT Repository 中找到完整的功能。 (cirt_server.c 文件,函数 cirtTexImage3D)。

//...
if (result)
{
// Create a 3D array...
CUDA_ARRAY3D_DESCRIPTOR layeredTextureDescr;
layeredTextureDescr.Width = w;
layeredTextureDescr.Height = h;
layeredTextureDescr.Depth = d;
layeredTextureDescr.Format = map_type_to_format(type);
layeredTextureDescr.NumChannels = format == CIRT_RGB ? CIRT_RGBA : format;
layeredTextureDescr.Flags = map_target_to_flags(target);

if (result) result = LogCUDADriverCall(cuArray3DCreate(&hTexRefArray, &layeredTextureDescr),
FUN_NAME(": cuArray3DCreate_tex3D"), __FILE_LINE__);

// Copy the acquired layer/face arrays into the collective 3D one...
CUDA_MEMCPY3D layerCopyDescr;
layerCopyDescr.srcMemoryType = CU_MEMORYTYPE_ARRAY;
layerCopyDescr.srcXInBytes = 0;
layerCopyDescr.srcZ = 0;
layerCopyDescr.srcY = 0;
layerCopyDescr.srcLOD = 0;

layerCopyDescr.dstMemoryType = CU_MEMORYTYPE_ARRAY;
layerCopyDescr.dstLOD = 0;

layerCopyDescr.WidthInBytes = layeredTextureDescr.NumChannels * w;
layerCopyDescr.Height = h;
layerCopyDescr.Depth = target == CIRT_TEXTURE_CUBE_MAP ? 1 : d;
layerCopyDescr.dstArray = hTexRefArray;

for (i = 0; i < num_layers; ++i)
{
layer = ((num_layers == 6) ? CU_CUBEMAP_FACE_POSITIVE_X + i : i);
layerCopyDescr.dstXInBytes = 0;
layerCopyDescr.dstY = 0;
layerCopyDescr.dstZ = i;
layerCopyDescr.srcArray = hLayres[i];

if (result) result = LogCUDADriverCall(cuMemcpy3D(&layerCopyDescr),
FUN_NAME(": cuMemcpy3D_tex3D"), __FILE_LINE__);
}

// Finally bind the 3D array with texture reference...
if (result) LogCUDADriverCall(cuTexRefSetArray(hTexRef, hTexRefArray, CU_TRSA_OVERRIDE_FORMAT),
FUN_NAME(": cuTexRefSetArray_tex3D"), __FILE_LINE__);

if (hLayres)
free(hLayres);

if (result)
current->m_oTextureManager.m_cuTextureRes[current->m_oTextureManager.m_nTexCount++] = hTexResource;
}
//...

我现在只用立方体贴图检查过它,但它应该也适用于 3D 纹理。

关于opengl - CUDA 立方体贴图纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22681018/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com