Lock/Read RHITexture on Vulkan

Hi folks,

in code, i use a FTexture2DRHIRef to store the results from a compute-shader. to read the data on the cpu, i use FRHICommandListImmediate::LockTexture2D( …, EResourceLockMode::RLM_ReadOnly, … ) which works fine on DirectX12.

On Vulkan, this fails and informs that Reading is not implemented yet:
https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/Runtime/VulkanRHI/Private/VulkanTexture.cpp#L1246

Is there any proper way/workaround to read single-channel texture-values from the gpu on the cpu? or any estimation on the roadmap when this part could be implemented? or any idea how to upgrade this in the engine-code?

FByteBulkData::Lock( LOCK_READ_ONLY ) is not suitable since i do not use UTexture.
FRHICommandListImmediate::ReadSurfaceData( … ) does only work with four-channel textures, but i use a single-channel format (to read and write in the shader simultaniously).

Cheers

Looks like RHICmdList.MapStagingSurface() does work fine as kind of a workaround. Had to create another RHITexture2D for that, with the TexCreate_CPUReadback | TexCreate_CPUWritable flags applied. Then you do an additional RHICmdList.CopyTexture() and read then the “mapped-surface” on the cpu.

int ThreadGroupAmount = FMath::DivideAndRoundUp( GetResolution().X, THREADSPERGROUP );
TShaderMapRef< FOutputShader1D > ComputeShader( GetGlobalShaderMap( GMaxRHIFeatureLevel ) );
FComputeShaderUtils::Dispatch( RHICmdList, ComputeShader, GetIOParameters(), FIntVector( ThreadGroupAmount, 1, 1 ) );
		
RHICmdList.CopyTexture( IORHITextureGPU, IORHITextureCPU, FRHICopyTextureInfo() );

TArray<float> OutputArray;

void* OutputBuffer = NULL;
int32 Width; int32 Height;
RHICmdList.MapStagingSurface( IORHITextureCPU, OutputBuffer, Width, Height );
{
	for( int i = 0; i < GetResolution().X; ++i )
	{
		OutputArray.Add( (float)((uint8*)OutputBuffer)[ i ] / 255.0f );
	}
}
RHICmdList.UnmapStagingSurface( IORHITextureCPU );

Since i only use 1D-Data and i do know the Resolution of ma data, i do not care about the Width and Height of the map. Don’t know how this behaves on other Pixel-Formats.

Also i do not do any WaitForDistpatch(), Flushes, Texture-Transition or so which are usually used in the engine-code on things like that. Still works fine. I would be very happy about some suggestions in this regard :smiley: