はかせのラボ

私の頭の中を書いていく雑記ブログです

DirectX 今日の事件 ~なんかメモリ使用量多くない?~

あいさつ

とりあえず小さなことでも出そうと思い始めたはかせです。
今回は今日発覚したとある事件のお話です。

事件概要

みなさんVisualStudioを使って開発するときデバックをすると思います。
VisualStudioのデバッガは書いたプログラムについて色々教えてくれます。
その中にメモリ使用量を教えてくれる場所があります。
↓こんなやつ
f:id:hakase0274:20181115201447p:plain

今日開発中に何気なくこの画面を見てみたらですねなんと・・・

使用量が1GBを超えていたことが発覚しました(・ω<)
※画像は余りの驚きで撮り忘れましたm(__)m

これはとんでもないことになりました。

犯人は?

犯人は明らかです。おまわりさんこいつです。
DirectX ついに絵が出た - はかせのラボ

絵出すまでは100とかで済んでましたもの。
あれから弾幕出したりし始めましたけど
それだけで使用量10倍はありえません。

つまりテクスチャが悪さしてるということですね。
悪さしてるこいつを突き出せば事件は解決です。

ですが、いくら悪さしたからと言って問答無用で
おまわりさんに突き出すのはしのびありません。
何か理由があるかもしれません。
突き出すのは話を聞いてからでも遅くはありません。
まずは話を聞きましょう。

なんでこんなことしたんだ

(私)「なんでこんなことしたんだ。
  こんなメモリ使用量じゃこのあと物が増えたとき困るじゃないか。」

(絵)「僕だってこんなことしたくなかったんだ。だけど仕方ないじゃないか。
   オブジェクト毎に新しく作れって言われたんだもの。

(私)「( ゚д゚)ポカーン・・・すまんかったorz」

キャッシュしましょう

どうやら今回の事件の真犯人は他でもない私だったようですorz
ようはテクスチャを出すとき同じものでも
新しく作っていたのが問題だったみたいです。

というわけでデータをキャッシュしていきます。

//テクスチャ情報を保持
struct TextureData
{
	wchar_t* fileName;
	ID3D11Resource* texture;
	ID3D11ShaderResourceView* shaderView;
};

TextureData* pReturn = nullptr;
//保持してるテクスチャ情報を検索
for (auto &tex : mTextureList)
{
   //出そうとしてるテクスチャがあるか
	if(fileName == tex.get()->fileName)
	{
		pReturn = tex.get();
		break;
	}
}
//テクスチャがなかったから新しく作る
if(pReturn == nullptr)
{
	auto pData = std::make_unique<TextureData>();
	pData.get()->fileName = fileName;
	CreateWICTextureFromFile(mDevice, fileName, &pData.get()->texture, &pData.get()->shaderView);
	pReturn = pData.get();
	mTextureList.push_back(std::move(pData));	
}
return pReturn;

やってることは至極単純なオブジェクトプーリングです。
テクスチャのパスと必要データを保持する構造体を作成し
同じものがあれば使いまわしてます。

今回の事件は些細な行き違いで発生した悲しい事件でした。
みなさまもこんな事件が起こらないよう
キャッシュできるものはしておきましょうね。


追記
削減結果を書くのを忘れてましたorz
1GB→140MB程度にまでメモリ使用量を減らせました。
キャッシュは偉大( ゚д゚)ウム

今回作ったものはgithubに上げました
github.com