[Solved] Cannot access UVolumeTexture/Texture3D GetNativeResource()

Hello,

this is Christian and I’m trying to get access to a native resource (DirectX 11) of a ID3D11Texture3D (UVolumeTexture). Sadly everything I’ve tried results in a NULL pointer. With a UTexture2D it works fine under dx11 and when I switch to dx12 it also works with a UVolumeTexture. I guess it’s not supported by the engine under dx11. Can someone confirm this?

I think the initialization process looks fine. The UVolumeTexture shows up in Editor correctly, but the following calls do all return NULL



    (*Texture)->Resource->TextureRHI->GetTexture3D()->GetNativeResource()
    (*Texture)->Resource->TextureRHI->GetTexture3D()->GetNativeShaderResourceView()
    (*Texture)->Resource->TextureRHI->GetNativeResource()


Maybe there is another way to get access to the native resource of a UVolumeTexture? I sadly cannot switch to dx12 because of other depending code. Maybe creating the ID3D11Texture3D by myself is an option. Do someone has experience with this issue?

This is the code where I create the UVolumeTexture:



    *Texture = NewObject<UVolumeTexture>(GetTransientPackage(), NAME_None, RF_Transient);
    if (*Texture) {
        (*Texture)->PlatformData = new FTexturePlatformData();
        (*Texture)->PlatformData->PixelFormat = PF_FloatRGBA;
        (*Texture)->PlatformData->SizeX = Dimensions.X;
        (*Texture)->PlatformData->SizeY = Dimensions.Y;
        (*Texture)->PlatformData->NumSlices = Dimensions.Z;
        (*Texture)->NeverStream = true;
        (*Texture)->CompressionNone = true;
        (*Texture)->SRGB = false;

        FTexture2DMipMap * MipMap = new FTexture2DMipMap();
        MipMap->SizeX = Dimensions.X;
        MipMap->SizeY = Dimensions.Y;
        MipMap->SizeZ = Dimensions.Z;

        MipMap->BulkData.Lock(LOCK_READ_WRITE);
        int PixelByteSize = GetPixelByteSize(PF_FloatRGBA);
        if (PixelByteSize == 0) {
            UE_LOG(LogSim, Error, TEXT("Invalid PixelFormat"));
            return;
        }
        const long long TotalSize = (long long)Dimensions.X * Dimensions.Y * Dimensions.Z * PixelByteSize;
        uint8 * ByteArray = (uint8 *)MipMap->BulkData.Realloc(TotalSize);

        FMemory::Memcpy(ByteArray, (uint8 *)Data3D.GetData(), TotalSize);

        MipMap->BulkData.Unlock();

        (*Texture)->PlatformData->Mips.Add(MipMap);

        (*Texture)->UpdateResource();
        FlushRenderingCommands();
    }


Thank you very much in advance for any help!
Christian

Problem solved!
When you are using D3D11 you can use the following code to get acces to native resources:



    FD3D11TextureBase * D3D11Texture = GetD3D11TextureFromRHITexture((*Texture)->Resource->TextureRHI);
    void * NativeResource3D = D3D11Texture->GetResource();


Dont forget to add the D3D header files



    #include "DynamicRHI.h"
    #include "D3D11RHI.h"
    #include "D3D11RHIBasePrivate.h"
    #include "D3D11StateCachePrivate.h"
    #include "D3D11Util.h"
    #include "D3D11State.h"
    #include "D3D11Resources.h"


The ZED Unreal Plugin is a very good reference to find a solid starting point regarding D3D and native resource stuff. Take a look into [FONT=courier new]StereolabsTexture.cpp.

Note: You have to add the modules [FONT=courier new]RenderCore, [FONT=courier new]RHI and [FONT=courier new]D3D11RHI to your build file.



    PrivateDependencyModuleNames.AddRange(
        new string] { 
            "Core", 
            "CoreUObject", 
            "Engine", 
            "InputCore",
            "RenderCore",
            "RHI", 
            "D3D11RHI"
        }
    );


Plus: You also have to add the include paths and the [FONT=courier new]dxgi.lib to your build file.



    string EnginePath = Path.GetFullPath(Target.RelativeEnginePath);
    PrivateIncludePaths.AddRange(
        new string]
        {
            EnginePath + "Source/Runtime/Windows/D3D11RHI/Private/",
            EnginePath + "Source/Runtime/Windows/D3D11RHI/Private/Windows/"
        }
    );

    PublicIncludePaths.AddRange(
        new string]
        {
            EnginePath + "Source/Runtime/Windows/D3D11RHI/Public/"
        }
    );

    PublicAdditionalLibraries.Add("dxgi.lib");


Hope this helps if someone else is struggling with native resource issues!

Best!
Chrisian

2 Likes