[UE4] StreamingされないTextureはStreaming Texture Poolに入るのか？？

(本記事はUE4.22を用いて検証しています)


表題の通りなのですが、Never Streamに設定されたりTexture GroupがUIとして設定されているなどでストリーミングされない設定となっているテクスチャは、Texture Streamingのメモリ領域に入るのかを確認してみました。

実は以前書いた[Texture Streaming Pool Sizeの決め方を考えてみる](https://qiita.com/EGJ-Nori_Shinoyama/items/cc959d201ff011df872f) という記事でも、以下の様に「プラットフォームによって異なる」とだけ説明しお茶を濁しておりました。

>(プラットフォームによって、r.streaming.poolsizeで確保したメモリ領域にNon-Streamingなtextureが入る場合と入らない場合があるのですが、最終的なPool用のメモリは上記Streaming Poolの値になる

今回は、この部分の具体的な説明となります。 


#最初にまとめ
忙しい人のために、最初にまとめを共有いたします。

-  ユーザはテクスチャストリーミング用のPool Sizeを *r.streaming.poolsize*で設定する
-  ストリーミング用のPoolの中にストリームされないテクスチャ(Never Streamなど)が含まれるかどうかは、**プラットフォーム及び設定やスペックよって違う**。 下表にUE4.22のデフォルト動作をまとめてみました。

|非ストリームテクスチャを含む| 各種Console|
|:-----------------:|:------------------:|
|VRAMを十分に持っている場合などに非ストリームテクスチャを含まない場合がある|**Windows, iOS, Android**|


-  ストリームされないテクスチャを含めるかどうかは、各プラットフォームの.iniファイルに*PoolSizeVRAMPercentage*が設定されており、更にVRAMが潤沢にありTexturePoolに非ストリーミングテクスチャを含まなくても良いと判断されたときに限る。
-  ストリーミングされるテクスチャが使えるPoolの容量は*stat streaming*の*Streaming Pool*で表示されるので、こちらを参照する。


#プラットフォームによって、 同一の設定でも*Streaming Pool*の値が異なる
例えば、*r.streaming.poolsize*を1000に設定したとしても、下の様に*Streaming Pool*の値が、プラットフォームによって異なります。 

**Windows**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/a168fd82-bda0-813d-454f-999b0c0c68e5.png)

**とあるConsole**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/36b7943c-1ffc-a349-c17b-1b6abde0346c.png)


Streaming Poolの値は、Windows上ではそのままr.stremaing.poolsizeの1000が設定されていますが、とあるConsole上では約830mbと少なくなっています。どちらの場合も非ストリーミングテクスチャであるNonStreaming Mipsが130MBほどあります。ここで、Consoleの830の方は、以下のような計算式となっています。

830 = 1000 - (130 + 35 + 5)

つまり、

**Streaming Pool = r.streaming.PoolSize - (NonStreaming Mips + Temporary Pool + Safety Pool)**

となっています。この様に、プラットフォームによっては、非ストリームなテクスチャであったりが含まれる場合があるので注意が必要です。


#含まれるか含まれないかは、PoolSizeVRAMPercentageの設定の有無による

非ストリームテクスチャらが含まれるか含まれないかは、.iniファイル内にPoolSizeVRAMPercentageによって決められます。例えば、WindowsやiOSの.iniファイルにはデフォルトで以下の記述がされています。

```
[TextureStreaming]
; PoolSizeVRAMPercentage is how much percentage of GPU Dedicated VRAM should be used as a TexturePool cache for streaming textures (0 - unlimited streaming)
PoolSizeVRAMPercentage=70
```

この記述によって、上記の様にストリームされないテクスチャを含まないようになります。Engine\Source\Runtime\Engine\Private\Streaming\AsyncTextureStreaming.cppのFAsyncTextureStreamingTask::UpdateBudgetedMips_Async()内部の以下の部分で行われておりますので、詳細が気になる方は参照してみてください。

```
if (GPoolSizeVRAMPercentage > 0 && TotalGraphicsMemory > 0)
{
	const int64 UsableVRAM = TotalGraphicsMemory * GPoolSizeVRAMPercentage / 100 - (int64)GCurrentRendertargetMemorySize * 1024ll; // Add any other...
	const int64 AvailableVRAMForStreaming = FMath::Min<int64>(UsableVRAM - NonStreamingTextureMemory - MemoryMargin, PoolSize);
	if (Settings.bLimitPoolSizeToVRAM || AvailableVRAMForStreaming > AvailableMemoryForStreaming)
	{
		AvailableMemoryForStreaming = AvailableVRAMForStreaming;
	}
}
```

上記コードの中の流れをメモした画像を発掘したので、こちらも貼っておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/c6ef8d26-ecde-4db3-3c2c-d18d6ed79d94.png)




#まとめ

簡単にですが、 StreamingされないTextureがStreaming Texture Poolに入る場合と入らない場合の差をまとめさせていただきました。最終的には、Texture Streamingの設定は、各プラットフォームごと個別に*stat streaming*のStreaming Pool, Required Pool, Wanted Pool, NonStreaming Mipsの4つの項目を見ながら、r.stremaing.poolsizeを決定しいく必要があるかと思います。ご参考になれば幸いです。