【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
シエル

【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#1

投稿記事 by シエル » 15年前

お世話になります。
下記のページで質問があります。
http://marupeke296.com/DXG_Show3Dto2D.html

このページのレンダリングターゲットのサーフェイスへのポインタを取得するところで、

【GetRenderTarget関数でサーフェイスへのポインタを取得すると、
そのサーフェイスの内部参照カウンタが1つ増えます。
具体的には、初期化の後にバックバッファへのポインタを取得した段階で、
バックバッファの内部参照カウンタは「2」になります。
よって取得したバックバッファのポインタを使用しなくなった段階で
Release関数を呼び出さないとメモリリークが発生します。】

という記述があるのですが、この内部参照カウンタというものはどういうものなのでしょうか?

それと、このポインタを使用しなくなった段階で、リリースしないとメモリリークが発生する
というのも意味がよく分かりません。
プログラム終了時にリリースするのでは駄目なのでしょうか?

よろしくお願い致します。

Poco

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#2

投稿記事 by Poco » 15年前

> という記述があるのですが、この内部参照カウンタというものはどういうものなのでしょうか?

オブジェクト内部で自分を必要としている他人を記憶しているってことです。
他人A「僕は君が必要だ。」
自分「1人に必要とされている。」
他人B「僕も君が必要だ。」
自分「2人に必要とされている。」
他人A「僕には君が不要だ。」
自分「1人に必要とされている。」
他人C「僕は君が必要だ。」
自分「2人に必要とされている。」
他人B「僕には君が不要だ。」
他人C「僕には君が不要だ。」
自分「誰にも必要とされていない、僕の人生終わりだ。」

といった感じで、自分で自分の寿命を決定するための仕組みです。
オブジェクトが共有される場合には、「誰が解放するの?」という問題があります。
上の例では、他人Aが解放すると他人B,Cは困るかも知れません。
そこで、自分に管理してもらっているのです。

> それと、このポインタを使用しなくなった段階で、リリースしないとメモリリークが発生する
> というのも意味がよく分かりません。

上の例で、他人Cが「不要だ」と言わなかった場合、自分は誰かに必要だと言われているので、
永久に生き続けようとします。

> プログラム終了時にリリースするのでは駄目なのでしょうか?

OKですよ。
重くならないorそれが気にならないのなら。

naohiro19

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#3

投稿記事 by naohiro19 » 15年前

MSDNのヘルプでも
「このメソッドを呼び出すと、IDirect3DSurface9 インターフェイスについての内部参照カウントが増加する。この IDirect3DSurface9 インターフェイスを使い終わったときに IUnknown::Release を呼び出さないと、メモリ リークが発生する。」
と記述があります。

シエル

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#4

投稿記事 by シエル » 15年前

ぽこさん!ありがとうございます!

大体意味は分かったのですが、
おっしゃっている「オブジェクト」というのは、実際にサーフェイスに描かれている画像データのことでしょうか?

最初からカウンタが1になっているのは、DirectXの初期化処理の中で、
既にバックバッファ用のサーフェイスへのポインタが取得されているからなのでしょうか?

もしそうだとすると、初期化後にバックバッファへのポインタを取得した段階で2になったカウンタは
リリースを行っても1になるだけなので、画像データ自体はメモリから消えていないということでしょうか?

質問ばかりですみません。。

シエル

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#5

投稿記事 by シエル » 15年前

>>naohiro19さん

ありがとうございます。
MSDNは読んだのですが、何とも不親切な説明しかないので、いつも困っています!
特にDirectXのヘルプは読んでも意味わからないことばかりです。

Poco

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#6

投稿記事 by Poco » 15年前

> 大体意味は分かったのですが、
> おっしゃっている「オブジェクト」というのは、実際にサーフェイスに描かれている画像データのことでしょうか?

ごめんなさい。
DirectXを扱ってことが無いので、正確には分からないです。
シエルさんが提示したリンク先の文章を読むに、バックバッファが「オブジェクト」に該当すると思います。

> 最初からカウンタが1になっているのは、DirectXの初期化処理の中で、
> 既にバックバッファ用のサーフェイスへのポインタが取得されているからなのでしょうか?

だと思います。

> もしそうだとすると、初期化後にバックバッファへのポインタを取得した段階で2になったカウンタは
> リリースを行っても1になるだけなので、画像データ自体はメモリから消えていないということでしょうか?

これは、微妙です。
1である状態が、誰からも参照されていない状態ならば、保証できません。

シエル

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#7

投稿記事 by シエル » 15年前

DirectXは扱ったことがありませんでしたか。
それなのにこれだけ解説できるとは…すごいです。

大体内部参照カウンタのイメージはつかめたので、
とりあえず使わなくなったら解放するってことだけ覚えておきます。
そのうち、使い慣れていく内に完全に理解できることを信じて、一応解決にしておきます

ありがとうございました!

Poco

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#8

投稿記事 by Poco » 15年前

> それなのにこれだけ解説できるとは…すごいです。

参照カウンタってのは、オブジェクト(寿命)管理の基本的な
テクニックなんですよ。
マイクロソフトの他のライブラリでも随所で使用されています。

シエル

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#9

投稿記事 by シエル » 15年前

>参照カウンタってのは、オブジェクト(寿命)管理の基本的な
>テクニックなんですよ。
>マイクロソフトの他のライブラリでも随所で使用されています。

そうなんですね。勉強になります。
忘れず覚えておきます。ありがとうございました。

ISLe

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#10

投稿記事 by ISLe » 15年前

> 最初からカウンタが1になっているのは、DirectXの初期化処理の中で、
> 既にバックバッファ用のサーフェイスへのポインタが取得されているからなのでしょうか?

件のページに関しては、CreateTextureメソッドで作られた(テクスチャのイメージを展開する)サーフェスなのでCreateTextureメソッドが1にしています。
テクスチャをリリースしたときはテクスチャに関連付けられたサーフェスの参照カウンタもついでに減らされます。

シエル

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#11

投稿記事 by シエル » 15年前

ISLeさんありがとうございます!

これで全てすっきりしました!
それにしても、MSDNにも載ってないことよくわかりますね。。。

追記:
あ~すいません追加で、
初期化時に作成されたそのテクスチャが解放されるタイミングはいつですか?
D3Dデバイスを解放するタイミングでしょうか? 画像

ISLe

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#12

投稿記事 by ISLe » 15年前

> 追記:
> あ~すいません追加で、
> 初期化時に作成されたそのテクスチャが解放されるタイミングはいつですか?
> D3Dデバイスを解放するタイミングでしょうか?

CreateTextureメソッドで作ったテクスチャは不要になったときにReleaseメソッドを呼び出す必要があります。
pTexture->Release();
CreateTextureメソッドでテクスチャ自身の参照カウンタも1になります。
Releaseメソッドを呼び出した結果参照カウンタが0になれば解放されます。


> それにしても、MSDNにも載ってないことよくわかりますね。。。

MSDNに載ってなかったですかね。
DirectX SDKのドキュメントに仕組みが書いてあったような。
IUnknownだからDirectXじゃなくてWindowsSDKのCOMモデルの解説だったかも。

ULONG cRef = pTexture->AddRef() - 1;
pTexture->Release();
というコードで現在の参照カウンタの数値が分かります。

シエル

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#13

投稿記事 by シエル » 15年前

すいません。私の質問の仕方がまずかったかもしれません。

レンダリングターゲットにしようとしているテクスチャのサーフェイスの話ではなくて、
バックバッファのサーフェイスの話なんですが。。。

このページに載っているレンダリングターゲットのテクスチャは、確かにCreateTextureで作成しているので、
参照カウンタが最初から1になっているのは分かりますが、
なぜ、バックバッファのサーフェイスも何故最初から1になっているのかと疑問に思ったのです。

なので、DirectXの初期化処理(D3Dデバイス作成等)の中で、内部的にバックバッファ自体もCreateTextureで
テクスチャが作成されているから、最初からカウンタが1なのではないかと思ったのですが
正しいでしょうか?

何か変なこと言ってたら申し訳ありません。

追記:
参照カウンタの調査方法ありがとうございます。調べてみます! 画像

ISLe

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#14

投稿記事 by ISLe » 15年前

> バックバッファのサーフェイスの話なんですが。。。

バックバッファの作成はIDirect3D9::CreateDeviceメソッドのパラメータで指示します。
バックバッファはディスプレイに表示される画面と直接結び付いているのでデバイスと関連付けられていると考えられますね。

シエル

Re:【DirectX】レンダリングターゲットのサーフェイスへのポインタ取得について

#15

投稿記事 by シエル » 15年前

わかりました!ISLeさん、ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る