Page 1 of 1

[2.2] Extract a slice from a texture array

Posted: Tue Dec 10, 2019 7:48 pm
by TaaTT4
What's the best way to obtain a TextureGpu* of a texture which resides inside a texture array? Do I have to use AsyncTextureTicket? Is there a use case scenario in the samples which I can study and take as a reference?
I'd like to use the cubemap of a specific probe as a Terra reflection map, but I need to extract it from the PCC cubemap array.

Re: [2.2] Extract a slice from a texture array

Posted: Tue Dec 10, 2019 8:05 pm
by dark_sylinc
Image2::convertFromTexture is an example which handles all cases even the edge ones.

This will download all slices though (and you can later access the slice you want via TextureBox).

However if you're interested in only download a particular slice, this modified excerpt from Image2 should do the trick:

Code: Select all

depthOrSlices = 1u; // Because we only need to allocate space to download just one, which is what we're interested. Note a cubemap has 6 slices
AsyncTextureTicket *asyncTicket =
		textureManager->createAsyncTextureTicket( width, height, depthOrSlices,
												  TextureTypes::Type2DArray,
												  texture->getPixelFormat() );
TextureBox srcBox = texture->getEmptyBox( mip );
srcBox.sliceStart = ...; // The slice you want. Just make sure sliceStart + numSlices doesn't go out of bounds
srcBox.numSlices = depthOrSlices;
// If you can wait a few frames to access the downloaded the data, set accurateTracking to false instead of true
asyncTicket->download( resolvedTexture, mip, true, &srcBox );

// You may want to do other stuff here until the data finishes downloading

const TextureBox finalBox = asyncTicket->map( 0 );
// access finalBox
asyncTicket->unmap();

textureManager->destroyAsyncTextureTicket( asyncTicket );
If you want more examples, just Find in Files for 'createAsyncTextureTicket'. Its only purpose is to get data from GPU textures to the CPU.

Accessing more than one slice that have been downloaded requires two paths for maximum performance. See 'if( asyncTicket->canMapMoreThanOneSlice() )' part of Image2.
Note that you can just assume canMapMoreThanOneSlice is always false and write only one codepath.