Proper texture object creation for block compressed formats after v11.5

Hello,

I’m trying to create a texture object for block compressed formats with CUDA 12.2.
CUDA introduced dedicated enum members for block compressed texture formats in CUDA 11.5 (e.g. CUarray_format_enum::CU_AD_FORMAT_BC1_UNORM).

I could create a CUDA mipmapped array for 32x32, 6 mipmap levels:

int32_t width = 32;
int32_t height = 32;
int32_t numMipmapLevels = 6;

CUDA_ARRAY3D_DESCRIPTOR arrayDesc = {};
arrayDesc.Format = CU_AD_FORMAT_BC1_UNORM;
arrayDesc.Width = width;
arrayDesc.Height = height;
arrayDesc.Depth = 0;
arrayDesc.NumChannels = 4;

CUmipmappedArray mipmappedArray;
CUDADRV_CHECK(cuMipmappedArrayCreate(&mipmappedArray, &arrayDesc, numMipmapLevels));

std::vector<CUarray> arrays(numMipmapLevels);
for (int mipLevel = 0; mipLevel < numMipmapLevels; ++mipLevel) {
    CUDADRV_CHECK(cuMipmappedArrayGetLevel(&arrays[mipLevel], mipmappedArray, mipLevel));
}

but I couldn’t create a texture object from that array:

CUDA_RESOURCE_DESC resDesc = {};
resDesc.resType = CU_RESOURCE_TYPE_MIPMAPPED_ARRAY;
resDesc.res.mipmap.hMipmappedArray = mipmappedArray;

CUDA_RESOURCE_VIEW_DESC resViewDesc = {};
resViewDesc.format = CU_RES_VIEW_FORMAT_UNSIGNED_BC1;
resViewDesc.width = width;
resViewDesc.height = height;
resViewDesc.depth = 0;
resViewDesc.firstMipmapLevel = 0;
resViewDesc.lastMipmapLevel = numMipmapLevels - 1;

CUDA_TEXTURE_DESC texDesc = {};
texDesc.maxMipmapLevelClamp = static_cast<float>(numMipmapLevels - 1);
CUtexObject texObj;
CUDADRV_CHECK(cuTexObjectCreate(&texObj, &resDesc, &texDesc, &resViewDesc));

The error is:

CUDA API Error
    Function: cuTexObjectCreate
    Error   : CUDA_ERROR_INVALID_VALUE(1)
    Desc    : invalid argument

What is the proper way to create a texture object using a dedicated enum value for block compressed texture?

The descriptions on cudaCreateTextureObject and cuTexObjectCreate seem to say something related:

  • cudaResourceViewDesc::format specifies how the data contained in the CUDA array or CUDA mipmapped array should be interpreted. Note that this can incur a change in size of the texture data. If the resource view format is a block compressed format, then the underlying CUDA array or CUDA mipmapped array has to have a 32-bit unsigned integer format with 2 or 4 channels, depending on the block compressed format. For ex., BC1 and BC4 require the underlying CUDA array to have a 32-bit unsigned int with 2 channels. The other BC formats require the underlying resource to have the same 32-bit unsigned int format but with 4 channels.

but this description seems outdated because the same has been here since even before CUDA 11.5.

I uploaded the above repro:

Thanks,

You might want to double check the number of channels. There seems to be a mismatch between requirements and actual usage.

That description seems outdated.
I have the error at cuMipmappedArrayCreate when specifying 2 for BC1 format.
I’m talking about new usage after CUDA 11.5.

From a different part of the official docs:

CU_AD_FORMAT_BC1_UNORM = 0x91
4 channel unsigned normalized block-compressed (BC1 compression) format

So it looks like you were on the right track. I do not use the CUDA driver API (I was the very first user of the CUDA runtime, ca. 2006 and refuse to go back), so you will have to wait for someone familiar with the driver API. I could not find anything relevant in an internet search.

Is there any sample code for BC textures, or even non-official samples?

this may be of interest

Thanks for the link, but this is old unfortunately.

As I wrote in the first post, as you know, CUDA 11.5 added the dedicated enum for BC textures. It should change the way to create a texture object and I hope it also fixes some mip-map issues that has been in CUDA for a long time.

Isn’t there anyone in NVIDIA knows how to create a texture object for CUDA with block compressed texture with full mip-map levels??

Who made this feature for what?

NVIDIA GPU architecture supports BCn formats natively and already had limited support in CUDA through texture resource views. We now introduce new BC CUDA array formats in the driver and runtime APIs.

Or do I have some misunderstanding?

Thanks,

I made another repro.
[CUDA_BCTexture.zip]

With this repro you can see the program outputs images, each for each mip-level when using old-style array/texture object creation like the following.

Mip Level 0


Mip Level 4

Mip Level 8

However the old style requires us to make the array with 1/4 size and this means we lose the last two mips.
On the other hand, when using (probably) new-style creation, it seems we can specify the actual size to initialize a CUDA array, but an error occurs when creating a texture object.

You may wish to file a bug. The instructions are linked to a sticky post in the top of this sub-forum.

I tried to report a bug but some “information security policy” error…
I’m contacting the support.

The bug reporting portal has an aggressive system to prevent rogue behavior. You can start by filing a bug that has relatively little information in it, then you are less likely to trigger the content system/error. For example, provide minimal information plus a link to this forum thread.

I finally succeeded to create a texture object with full mip-levels for BC textures.

The proper way for this is specifying nullptr as the resource view descriptor when creating a texture object for BC textures.

The current document lacks the description for this. I got this solution from the bug report system.
https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__TEXOBJECT.html#group__CUDA__TEXOBJECT_1g1f6dd0f9cbf56db725b1f45aa0a7218a
So I hope a future SDK will improve this part (at least the document should describe this).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.