HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
1019
ひろかずhgimg3での垂直同期について16解決


ひろかず

リンク

2019/10/19(Sat) 14:27:41|NO.88650

hgimg3使用時での垂直同期について改善したい点があるのですが、どうしたら良いのか
解決策が分からない為、質問いたします。

現在、hgimg3を利用した自作のゲームで、フルスクリーン時に垂直同期を取るために、
掲示板に投稿されていたmod_d3d9vsyncというモジュールを使用しております。
http://hsp.tv/play/pforum.php?mode=pastwch&num=53549

おかげさまで標準命令では出来ないfpsの安定化は果たせたのですが、
良く見ると時々fpsが落ち込んでいて少々気になっております。
自作のゲームで計測してみたのですが、約13分(全46563フレーム)のプレイで、
fps60が44885フレーム、59が1558フレーム、58以下が120フレームという結果になりました。
ちなみに、mod_d3d9vsyncモジュール内のd3d9vsync_fps(1秒間のフレーム数)を
記録しての計測です。
可能であればfps60の状態をもっと増やしたいと考えておりますが、どうすれば
改善することが出来るのか悩んでおります。

最初に疑ったのは、ゲームの処理自体が重いからフレーム落ちが発生しているのでは?
という事です。
しかし、mod_d3d9vsync内でタイミングを取るために行っているSleep処理の時間を見ると
おおむね8msから14msの間であり、ゲームの処理自体は4msから9ms前後で済んでいると
判明しました。
ただ、0msというのがまれに出ており(計18フレーム)少々気にはなりましたが、
fpsが59以下になった時に発生している訳ではないので関連性は不明です。

次に疑ったのは、mod_d3d9vsync内でタイミングを取っているSleep処理が長すぎる為
フレーム落ちが発生しているのでは?、という事です。
mod_d3d9vsyncモジュール内を見ると、フルスクリーン時のSleep減算値として
Sleep_adjust_fullという変数があり、そこに1が入っていた為2に増やして、
Sleep時間を減らしてみました。
しかし状況は改善されませんでした。3に増やしても同様でした。

そもそも走査線を監視しているならSleep処理は必要ないのでは、と思いSleep処理の
行をコメントアウトしてみました。しかし状況は改善されませんでした。
しかも、タイトル画面の処理で120fps前後に急上昇するような不安定な状況に
なりました。

次に、mod_d3d9vsyncモジュール内にあるRasterAdjustという命令を使用して
走査線監視位置を10に変更してみましたがこれも効果はありませんでした。

このように、原因がよく分からないのでどう対処すれば良いのか分からず
お手上げ状態です。
他に原因を突き止める手段はありますでしょうか?
よろしくお願い申し上げます。

もうひとつ、mod_d3d9vsyncモジュールに関して要望点があります。
それは、フレームレートを小数点以下にも対応して欲しいという事です。
自分のデスクトップ環境は1920x1200dot 59.94Hzの為、自作のゲームを
ウィンドウモードで遊ぶとスクロールがガクガクになってしまいます。
d3d9vsync_initでフレームレートを60に設定、59に設定、どちらにしても
綺麗にスクロールしてくれません。

以上、よろしくお願い申し上げます。



この記事に返信する


暇人

リンク

2019/10/20(Sun) 00:33:04|NO.88653

>現在、hgimg3を利用した自作のゲームで、フルスクリーン時に垂直同期を取るために、
えっと、まず
hgimg3にはフルスクリーンモードがあり
> hgsetreq SYSREQ_DXMODE,1 ; フルスクリーンモードを指定
> hgsetreq SYSREQ_DXWIDTH,640 ; フルスクリーン解像度X
> hgsetreq SYSREQ_DXHEIGHT,480 ; フルスクリーン解像度Y
> hgini
これを使用した場合はd3d9vsyncを使わなくても垂直同期されます。
但し、ディスプレイドライバの設定で常にオフになってる場合は垂直同期はされません。

>しかも、タイトル画面の処理で120fps前後に急上昇
これを読む限りhgimg3のフルスクリーンモードを使って無いか
ドライバの設定でオフになってるか・・・

>そもそも走査線を監視しているならSleep処理は必要ないのでは、
走査線監視はwaitを掛けずにループするしか無い(1msでも遅い)ので
走査線監視を16msする必要がある場合15msまでSleepしてから
走査線監視をします。(Sleepの精度は1msに設定してるけどPC環境で2msぐらいは有り得る・・・)

とりあえず、フルスクリーンはどうやってるのかと
実際に使ってるd3d9vsync_init、d3d9vsync、hgsyncの部分をコピペしてみてください。


>自分のデスクトップ環境は1920x1200dot 59.94Hzの為、自作の
自分の環境は60Hzしかないので、DirectX側にはどう設定されてるのか確認してみたいので

d3d9vsync_initの後にd3d9vsync_logsaveを実行して出来るd3d9vsync.logの

------------------------------- D3DDISPLAYMODE ------------------------------- 0 : 1920 1 : 1080 2 : 60 3 : 22
を見せて欲しいかな・・・
d3d9vsync.logは実行時のカレントフォルダに出来ます。(通常はソースフォルダ)

あと、
http://hsp.tv/play/pforum.php?mode=all&num=46392
のサンプルもガクガクします?



暇人

リンク

2019/10/20(Sun) 00:55:41|NO.88654

書き忘れ

>走査線監視位置を10に変更してみましたがこれも効果はありませんでした。
これは数値が大きい方がd3d9vsyncを早く抜けます。
通常は20なので480ラインの走査線なら460以上になった時に似ぬけます。
(実際には水平走査線数1080を基準にしてるので480の場合472以上になる)



ひろかず

リンク

2019/10/22(Tue) 17:18:19|NO.88666

>>暇人さん

ご返信頂き、誠に有り難うございます。
色々と情報が不足しており、申し訳ございませんでした。

フルスクリーンの初期設定は以下の通りです。

bgscr 0,1280,720,0 ; フルスクリーンは必ずbgscrで作成 mouse -1 ; マウスカーソルを消す hgsetreq SYSREQ_DXMODE,1 ; フルスクリーンモードを指定 hgsetreq SYSREQ_DXWIDTH,1280 ; フルスクリーン解像度 X=1280 hgsetreq SYSREQ_DXHEIGHT,720 ; フルスクリーン解像度 Y=720 hgsetreq SYSREQ_FPUPRESERVE ,1 ; 計算精度を落とさない hgini

d3d9vsyncの初期化です。


d3d9vsync_init 60,1 gsel 0,1 redraw 0

描画更新処理です。


d3d9vsync 0 hgsync 0 await 0

また、ウィンドウモード時のd3d9vsync.logです。

-------------------------------
D3DDISPLAYMODE
-------------------------------
0 : 1920
1 : 1200
2 : 59
3 : 22

フルスクリーン時は以下の通りです。

-------------------------------
D3DDISPLAYMODE
-------------------------------
0 : 1280
1 : 720
2 : 60
3 : 22

使用グラフィックカードはGeForce GTX 1050 Tiで、使用モニターはMITSUBISHI MDT242WGと
なります。
NVIDIA設定で「3D設定の管理」では垂直同期「オン」になっております。

暇人さんの頂いた情報で色々と見直してみたいと思います。
その他の情報は改めて書き込みさせて頂きます。
有り難うございました。



ひろかず

リンク

2019/10/22(Tue) 19:11:21|NO.88667

追記です。
私が使用しているモニターですが、メニューボタンが付いており、そこから画面情報を出すと
1920x1200 H 74KHz V 59.9Hzと表示されます。

また、下記のhgimg3の使用例を実行しました。
http://hsp.tv/play/pforum.php?mode=pastwch&num=46392

実行結果ですが、目視での判断になりますが、14〜15秒間は綺麗にスクロールし、
その後3〜4秒間はガクガクとしたスクロールになります。
それが交互に発生するという状況です。

また、下記のFPS固定取得モジュールで上記hgimg3の使用例を改造して実行しました。
http://hsp.tv/play/pforum.php?mode=pastwch&num=56080

SetFps 60.00で上記とほぼ同じ状況になります。
SetFps 59.94でかなり安定して綺麗にスクロールされますが、完璧ではなく、
一端ガクガクになると、かなり長い間ガクガクになる状況です。
目視ですが、ティアリングは発生していないように見えます。



ひろかず

リンク

2019/10/22(Tue) 19:37:12|NO.88668

何度も追記して申し訳ございません。

>これを使用した場合はd3d9vsyncを使わなくても垂直同期されます。

との事ですが、私の環境ですと上記(NO.88666の書き込み)のスクリプトから
「d3d9vsync 0」をコメントアウトすると超速度でゲームが実行されます。
これは、私の環境に問題があるという事なのでしょうか?

よろしくお願い申し上げます。



暇人

リンク

2019/10/23(Wed) 22:40:46|NO.88675

モジュールのテスト報告等ありがとうございます。
このモジュールは、あくまでティアリングを回避するのが目的なので
がたつきを完全に無くすのは難しいかも知れません。
ウィンドウの更新が反映するのはWIndows側が握ってるので・・・
XPまで(VistaのAero無効)は単純だったんだけど・・・


>「d3d9vsync 0」をコメントアウトすると超速度でゲームが実行されます。
原因が分かりました。

「Windows10での外部ツールについて」
http://thwiki.info/?Windows10%A4%C7%A4%CE%B3%B0%C9%F4%A5%C4%A1%BC%A5%EB

WIndows10上でのDirectX8の動作にバグがあるようです。
これって、垂直同期できるかどうか確認して切り替えてるDirectX8のゲームは全滅か・・・
(多分ハード側に出来るかどうか確認したら出来るって返ってくるだろうし)

>一端ガクガクになると、かなり長い間ガクガクになる状況です。
タイトルバーをクリックするとガクガクが直ったりします?
> 目視ですが、ティアリングは発生していないように見えます。
WIndows10はティアリングを発生しないので・・・


http://hsp.tv/play/pforum.php?mode=pastwch&num=46392
のサンプルで
> d3d9vsync 0
> hgsync 0
の所を

GetRasterStatus v,r if r>r_bak { repeat GetRasterStatus v,r if v=1{break} loop } repeat await 0 GetRasterStatus v,r if r>ginfo_wy2 {r_bak=r:break} loop hgsync 0
に差し替えてもがたつくかな・・・



ひろかず

リンク

2019/10/24(Thu) 01:27:59|NO.88677

>>暇人さん

様々な情報、誠に有り難うございます。
お陰様で、hgimg3のフルスクリーンでfpsが安定しない件については原因が判明しました。
感謝申し上げます。

原因はWindows10上でのDirectX8の動作バグでした。・・・お前の仕業だったのか orz
DirectX8に関する不具合は、今更マイクロソフトも対処はしてもらえないですよね・・・

という事で、自作のゲームソフトに「DX8 to DX9 Converter」を導入する事で
フルスクリーン時のfpsを安定させる事に成功しました。
また「d3d9vsync 0」をコメントアウトしても正常に垂直同期が行われ、
ゲームが超スピードで実行される事も無くなりました。

 また、ウインドウズモードの件ですが、

>>一端ガクガクになると、かなり長い間ガクガクになる状況です。
>タイトルバーをクリックするとガクガクが直ったりします?

タイトルバーをクリックするとスクロールの処理が一時停止されますが、
クリックをはなすとスクロールの処理が再開され、その時はガクガクが直っています。

>> d3d9vsync 0
>> hgsync 0
>の所を
>(スクリプト省略)
>に差し替えてもがたつくかな・・・

がたつかず、綺麗にスクロール表示されました。
2分程度の確認ですが、がたつきは一切発生しませんでした。


 お陰様で、フルスクリーンの件は「DX8 to DX9 Converter」を導入する事で解決したのですが、
新たな問題が発生するようになりました。

ゲーム中で、hgrotate命令を使用して画像の拡大コピーを行っているのですが、
その画像にアンチエイリアスがかかるようになってしまいました。
対策として、hginiの前に以下の命令を追加してみたのですが、効果はありませんでした。


hgsetreq SYSREQ_2DFILTER,1 ; 2D描画時のテクスチャ補間モード 補間なし hgsetreq SYSREQ_2DFILTER2,1 ; 2D直接描画時のテクスチャ補間モード 補間なし

スプライトの拡大処理は試していないのですが、おそらく同様にアンチエイリアスが
かかるのではないかと思います。
「DX8 to DX9 Converter」を導入というイレギュラーな事をしているので、しょうがないと
言えばしょうがないのですが、アンチエイリアスを無くす事は出来ないのでしょうか?



暇人

リンク

2019/10/24(Thu) 20:19:00|NO.88681

>クリックをはなすとスクロールの処理が再開され、その時はガクガクが直っています。
hgsyncのタイミング次第でガクつきが出てるって事かなぁ

>がたつかず、綺麗にスクロール表示されました。
> 2分程度の確認ですが、がたつきは一切発生しませんでした。
一定のタイミング(今回はウィンドウの下)を守ればガクつきは防げると・・・


> if r>ginfo_wy2 {r_bak=r:break}
これを

if r>(ginfo_wy2-200) {r_bak=r:break}
とかにしてもガクつきは有りませんか?


>その画像にアンチエイリアスがかかるようになってしまいました。
DirectXの命令でSetTextureStageStateを直接実行しても
D3DTSS_MAGFILTER(拡大時の補間)がD3DTEXF_LINEARに固定されてる感じ
D3DTEXF_POINTをセットして直ぐに確認してもD3DTEXF_LINEARに・・・
D3DTSS_MINFILTER(縮小時)の方は自分で設定できる・・・

Converterの方に設定出来ないと難しい感じ



ひろかず

リンク

2019/10/25(Fri) 00:03:51|NO.88685

>>暇人さん

 ウインドウズモードの件ですが、前回の報告では検証不足であることが判明しました。
色々と試して頂いているのに、申し訳ございません。
お詫び申し上げます。

> if r>ginfo_wy2 {r_bak=r:break}

 この状態で、前回は問題無いと報告しましたが、間違いでした。お詫びして訂正します。
ウィンドウの位置で状況が変わりました。
前回は、ウィンドウがデスクトップの上部にあった場合のみしか確認していませんでした。

 ウィンドウをタスクバーのあたりまで下げると、スクロールが常にガクガクした状態に
なりました。
ウィンドウの位置を徐々に上げると、たまにガクガクといった状況に変化し、一定の位置まで
ウィンドウを上げると綺麗にスクロールされる状況になります。
だいたい、140ラインぐらいウィンドウを上げるとガクガクがなくなるといった状況です。
境界線は、はっきりとは分かりません。

 それで、今回ご呈示頂いた
>if r>(ginfo_wy2-200) {r_bak=r:break}
に変更したところ、ウィンドウをどの位置に変更しても、ガクガクにならず、
綺麗にスクロール表示される事を確認しました。
ただし、ウィンドウをタスクバーの下にまで埋め込んだ場合は、ガクガクが発生します。
だいたい、140ラインぐらいウィンドウの下部が見えなくなるまで埋め込んだ場合に発生します。
この状況になることは実際の所無いですし、ゲームもまともに遊べないので問題無いと
思いますが、念のためご報告申し上げます。

>DirectXの命令でSetTextureStageStateを直接実行しても
>D3DTSS_MAGFILTER(拡大時の補間)がD3DTEXF_LINEARに固定されてる感じ
>Converterの方に設定出来ないと難しい感じ

色々と試行して頂き、有り難うございます。どうやら難しいようですね。
現状、アンチエイリアスがかかると絶対に困ると言う訳では無いので、これはこれで良いと
納得いたしました。有り難うございました。



暇人

リンク

2019/10/25(Fri) 23:15:51|NO.88693

>ウィンドウの位置で状況が変わりました。
予想は出来てたので問題無いです。

>思いますが、念のためご報告申し上げます。
ありがとうございます。
後はウィンドウ位置は気にしないで、特定の水平ラインで
hgsyncを実行しても安定するならフルスクリーンでも使えるかも

>if r>(ginfo_wy2-200) {r_bak=r:break}
これを

if r>(ginfo_dispy/2) {r_bak=r:break}
に置き換えてガクつかないかな?
(自分もwin10はあるんだけどシングルコアのノートだからこのテストには向かない・・・)



ひろかず

リンク

2019/10/25(Fri) 23:37:43|NO.88694

>>暇人さん

>if r>(ginfo_dispy/2) {r_bak=r:break}
>に置き換えてガクつかないかな?

確認しました。
ウィンドウをどの位置に変更してもカクツキは発生しませんでした。
ウィンドウをタスクバーの下にまで埋め込んで、ほとんど画面が見えない状態でも
問題はありませんでした。素晴らしいです。



暇人

リンク

2019/10/26(Sat) 13:33:52|NO.88700

>ウィンドウをどの位置に変更してもカクツキは発生しませんでした。
確認ありがとうございます。

ではNO.88675で差し替えたのを

await 0 //念のため GetRasterStatus v,r if r>(ginfo_dispy/2) { repeat _Sleep@mod_d3d9vsync 1 GetRasterStatus v,r if r<(ginfo_dispy/2) {break} loop } repeat _Sleep@mod_d3d9vsync 1 GetRasterStatus v,r if r>(ginfo_dispy/2) {break} loop hgsync 0
に置き換えて安定してれば
無駄にCPUを使用しなくて済みますが、どうでしょう?



暇人

リンク

2019/10/26(Sat) 16:53:14|NO.88701

秒間fps(fps_sec)と平均fps(fps_avg)表示用の処理
hgsync 0 の後に

//fps表示用処理 fpstemp++ ntim=d3d9vsync_GetTime if (ntim-stim)>=1000 { min_cnt++ stim=ntim-((ntim-stim)\1000) fps_sec=fpstemp //秒間fps if min_cnt > 2 {//2秒以降の平均を取る fps_total+fps_sec fps_avg=double(fps_total)/(min_cnt-2) //平均fps } fpstemp=0 }



ひろかず

リンク

2019/10/26(Sat) 20:35:02|NO.88704

>>暇人さん

NO.88700のスクリプトに差し替えて実行しました。
お陰様でウィンドウモードでも綺麗なスクロール処理がされるようになりました。
有り難うございます。

 これにて解決済みにしたいと思いますが、最後に幾つか不明な点がるので、
お答え頂けませんでしょうか?

1.ウィンドウモードにおいて「d3d9vsync_init 60,1」という設定にしているにも関わらず、
59.9Hzという私のモニター環境で綺麗なスクロールが実現されているのは何故ですか?
以下のようなスクリプトを組む必要は無いのでしょうか?

d3d9vsync_init 60,1 if stat = 59 : d3d9vsync_init 59,1 ; 59の場合は59フレームで再度設定する
また、60Hz以外のモニターでウィンドウモードを実行した場合はどうなるのでしょうか。
例えば75Hzのモニターで実行した場合は75フレームになってしまうのでしょうか?

2.念のためという理由で「await 0」が挿入されていますが、これはどういった理由なのでしょうか?
既に「hgsync 0」の後に「await 0」を入れているので、1フレームに2回もawaitを入れる
必要は無いように感じるのですが。
「await 0」を入れないと、どのようなリスクがあるのでしょうか?

3.現状「d3d9vsync_init 60,1」と走査線監視モードを優先していますが、
hgimg3を利用する上で「d3d9vsync_init 60,0」とタイマーモードを使用するケースはありますか?

以上、よろしくお願い申し上げます。



暇人

リンク

2019/10/26(Sat) 23:55:23|NO.88707

>お陰様でウィンドウモードでも綺麗なスクロール処理がされるようになりました。
報告ありがとうございます。

>59.9Hzという私のモニター環境で綺麗なスクロールが実現されているのは何故ですか?
これは走査線を監視して実際に秒間59.94フレームになってるからです。

>以下のようなスクリプトを組む必要は無いのでしょうか?
d3d9vsync_initの設定は走査線モードを有効にしないと
GetRasterStatus命令を使う準備が出来ないので、d3d9vsync命令を使わなくても
一度は設定が必要ですが、フレームレートの指定は意味を持ちません。

>例えば75Hzのモニターで実行した場合は75フレームになってしまうのでしょうか?
そうなります。
なのでNO.88700のはPC環境に左右されずに60フレームに固定される
フルスクリーン向けな感じに・・・(垂直同期が取れないwin10用だけど)

>「await 0」を入れないと、どのようなリスクがあるのでしょうか?
ただの気持ちの問題かな16ms近くOSにタスクが渡らないのが分かってるから
その前にって感じ(マルチコアなら気にする事も無いけど)
秒間60フレームなら一回awaitすれば問題無いと思う
そもそもhgsyncでOSにタスクを渡してる・・・
(でもawaitも無いと安定しないって環境もあるみたい)

>hgimg3を利用する上で「d3d9vsync_init 60,0」とタイマーモードを使用するケースはありますか?
d3d9vsync_init 60,0の場合リフレーシュレートも60なら走査線監視モードになります。
リフレーシュレートが違うならタイマーモードになります。
これはFPS固定取得モジュールと同じ処理になります。(小数点以下が指定できませんが)

リフレーシュレートが60じゃ無かった場合
60,1はスクロールがガタついてもティアリングを防ぎたい場合
60,0はティアリングが発生しても均等のタイミングで画面更新したい場合

で、今の現状だとウィンドウズがティアリングを発生しないようにしてるので
本来は、このモジュールの出番事態が無くなってる・・・


ティアリングが発生しないWin用にフレームレート安定化でちょっと作り直すか
Win10のhgimg3フルスクリーン問題もあるし・・・



ひろかず

リンク

2019/10/27(Sun) 00:41:43|NO.88709

>>暇人さん

 ご回答頂き、誠に有り難うございました。お陰様でよく分かりました。
問題点の確認作業やスクリプトの修正など大変お世話になりました。
厚く御礼申し上げます。



ONION software Copyright 1997-2021(c) All rights reserved.