トップページ > 記事閲覧
MakeScreen連続呼び出し時不具合?
名前:Marshal 日時: 2020/07/31 15:03

管理人様 DX.MakeScreenにおける挙動について不安定な場合があるようです。 MakeScreenを数十回連続で呼び出す必要があるのですが、稀に数回目(何回目でエラーとなるかは未確定)でエラーとなることがあります。 使用しているバージョンは、3.22になります。 何か考えられる理由と対応方法はあるのでしょうか? 以上、何卒宜しくお願い致します。
メンテ

Page: 1 |

Re: MakeScreen連続呼び出し時不具合? ( No.1 )
名前:管理人 日時:2020/07/31 23:37

うーん謎ですね… 一応連続で呼び出しても問題は発生しない筈ですが… プログラムを実行すると作成される Log.txt に何かエラーのログなどは出力されていないでしょうか? あとは…DXライブラリは1つのスレッドからのみ関数が呼ばれることを前提としていますので、 もし複数のスレッドからDXライブラリの関数を呼んでいたりしますと、それが原因でエラーが 発生することもあると思います
メンテ
Re: MakeScreen連続呼び出し時不具合? ( No.2 )
名前:Marshal 日時:2020/08/03 16:30

管理人様 原因究明中ですが、同じコンテキスト内で初期化(MakeScreen)を呼び出しています。 別のPC(HD Graphics630)で動作させたところ、問題なく何回起動しても問題ありませんでした。 下記のGPUで動作させると稀にMakeScreen APIから何も返ってきません。 つまり内部でデッドロックしているようです。 現在動作させているPCは、NVIDIA GeForce RTX 2070 with Max-Qです。 正常時のlogを比較しましたが、特にエラーとなる事由は見当たりませんでした。。 DXHandle.cpp,DxCompileConfig.hコードを読んでいたのですが、AddHandle内処理の非同期読み込み有効(=DX_NON_ASYNCLOADがコメントアウト)になっているようですが、これが影響しているとか ありますでしょうか?もしくは、クリティカルセクションのロック/アンロック不具合? ちなみに、本件とは関係ないと思いますが、DxLib_EndをApp終了前にコールすると、log(A)で吐いていたそれまでの情報がクリアされており、 下記のログ(@)を吐きなおしているようです。 @: 0:DirectInput関係初期化処理 3: XInput DLL の読み込み中... 成功 9: DirectInput7 の取得中... DirectInput8 の取得を試みます...成功 15: 引き続き初期化処理... 初期化成功 26: ジョイパッドの初期化... A :ChangeWindowMode実行 2:ウインドウモードフラグが立てられました 305:ChangeWindowMode実行 370:ChangeWindowMode実行 373:dxgi.dll の読み込み.... 成功 423:API CreateDXGIFactory2 のアドレスを取得します.... 成功 429:IDXGIFactory2 を作成します.... 成功 447:IDXGIAdapter を列挙 451: Adapter No.0 Desc:NVIDIA GeForce RTX 2070 with Max-Q Design 454: Output Device No.0 Name:\\.\DISPLAY1 456: Adapter No.1 Desc:Intel(R) UHD Graphics 630 460: Adapter No.2 Desc:Microsoft Basic Render Driver 463:dxgi.dll の解放 1 466:ディスプレイ情報のセットアップ開始 470: モニターの数:1 ディスプレイデバイスの数:7 473: No.0 モニター名:\\.\DISPLAY1 3840x2160 32bit 59Hz 516:ディスプレイ情報のセットアップ完了 631:DXライブラリの初期化処理開始 637: システムの情報を出力します 639: DXライブラリ Ver3.22 642: 論理プロセッサの数 : 12 645: OS Windows10 ( Build 18363 ) 751: 現時点のCPU動作速度:大体2.60GHz 754: MMX命令を使用します 757: SSE命令が使用可能です 760: SSE2命令が使用可能です 762: CPUベンダ:GenuineIntel 778: CPU名:Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 781: COMの初期化... 失敗 788: 非同期読み込み処理の初期化...成功 796: ファイルアクセス処理の初期化...成功 802: メモリ総量:16206.86MB 空きメモリ領域:8220.03MB 805: タイマーの精度を検査します 808: 精度結果 更新回数 マルチメディアタイマー:0 パフォーマンスカウンター:60 811: パフォーマンスカウンターを使用します タイマー精度 : 10000.000000 KHz 818: ソフトの二重起動検査... 二重起動はされていませんでした 828: IMEを無効にしました 4889: DirectInput関係初期化処理 4893: XInput DLL の読み込み中... 成功 4907: DirectInput7 の取得中... DirectInput8 の取得を試みます...成功 4947: 引き続き初期化処理... 初期化成功 4955: ジョイパッドの初期化... 5113: ジョイパッドの初期化は正常に終了しました 5117: マウスデバイスの初期化... 初期化成功 5125: キーボードデバイスの初期化... 初期化成功 5134: DirectInput 関連の初期化は正常に終了しました 5142: WASAPI の初期化を行います 5440: デフォルト遅延時間 : 10.000 ms 5444: 最小遅延時間 : 3.000 ms 5447: 遅延時間 : 10.000 ms 5460: チャンネル数   : 8 ch 5464: 量子化ビット深度 : 32 bit 5467: 有効ビット深度  : 32 bit 5470: サンプリングレート : 48000 Hz 5473: データ形式 : 浮動小数点型 5549: 動作モード : 共有モード 5553: WASAPI の初期化は正常に終了しました 5557: d3d11.dll の読み込み.... 成功 5565: dxgi.dll の読み込み.... 成功 5573: API CreateDXGIFactory2 のアドレスを取得します.... 成功 5582: IDXGIFactory2 を作成します.... 成功 5589: API D3D11CreateDevice のアドレスを取得します.... 成功 5596: IDXGIAdapter を取得します.... 成功 5603: Direct3D 11 FeatureLevel 11_0 以上を対象とします 5606: ID3D11Device オブジェクトを取得します.... 成功 5687: IDXGIDevice1 を取得します.... 成功 5695: IDXGIDevice1->SetMaximunFrameLatency( 1 ); を実行しました 5700: [ウインドウモード 3840x2160] 5704: IDXGISwapChain2 を作成します.... 成功 5713: IDXGIFactory2->CreateSwapChainForHwnd の戻り値:0x00000000 5718: IDXGIOutput を取得します.... 成功 5727: Graphics Device:NVIDIA GeForce RTX 2070 with Max-Q Design 5733: 画面のフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です 5738: 16bit Zバッファフォーマットは DXGI_FORMAT_D16_UNORM です 5743: 24bit Zバッファフォーマットは DXGI_FORMAT_D24_UNORM_S8_UINT です 5748: 32bit Zバッファフォーマットは DXGI_FORMAT_D32_FLOAT です 5751: 16bit カラーフォーマットは DXGI_FORMAT_B5G6R5_UNORM です 5755: 32bit カラーフォーマットは DXGI_FORMAT_B8G8R8X8_UNORM です 5759: アルファ付き 16bit カラーフォーマットは DXGI_FORMAT_B4G4R4A4_UNORM です 5763: アルファ付き 32bit カラーフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です 5768: アルファテスト用 16bit カラーフォーマットは DXGI_FORMAT_B5G5R5A1_UNORM です 5772: アルファテスト用 32bit カラーフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です 5776: DXT1テクスチャフォーマットは DXGI_FORMAT_BC1_UNORM です 5780: DXT2テクスチャフォーマットは使えません 5784: DXT3テクスチャフォーマットは DXGI_FORMAT_BC2_UNORM です 5787: DXT4テクスチャフォーマットは使えません 5791: DXT5テクスチャフォーマットは DXGI_FORMAT_BC3_UNORM です 5795: BC7_UNORM テクスチャフォーマットは DXGI_FORMAT_BC7_UNORM です 5799: BC7_UNORM_SRGB テクスチャフォーマットは DXGI_FORMAT_BC7_UNORM_SRGB です 5803: ABGR 整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_UNORM です 5806: ABGR 浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_FLOAT です 5810: ABGR 浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32B32A32_FLOAT です 5813: 1チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8_UNORM です 5817: 1チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_UNORM です 5821: 1チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_FLOAT です 5825: 1チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32_FLOAT です 5829: 2チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8G8_UNORM です 5833: 2チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_UNORM です 5836: 2チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_FLOAT です 5840: 2チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32_FLOAT です 5844: 描画用 16bit カラーフォーマットは DXGI_FORMAT_B5G6R5_UNORM です 5847: 描画用 32bit カラーフォーマットは DXGI_FORMAT_B8G8R8X8_UNORM です 5851: 描画用アルファ付き 32bit カラーフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です 5856: 描画用 ABGR 整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_UNORM です 5859: 描画用 ABGR 浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_FLOAT です 5863: 描画用 ABGR 浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32B32A32_FLOAT です 5866: 描画用1チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8_UNORM です 5870: 描画用1チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_UNORM です 5874: 描画用1チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_FLOAT です 5878: 描画用1チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32_FLOAT です 5882: 描画用2チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8G8_UNORM です 5886: 描画用2チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_UNORM です 5890: 描画用2チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_FLOAT です 5894: 描画用2チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32_FLOAT です 5899: 使用する機能レベル:D3D_FEATURE_LEVEL_11_1 5903: 同時にレンダリングできるバッファの数:8 5907: 最大テクスチャサイズ 幅:16384 高さ:16384 5911: 標準描画用の頂点バッファの作成.... 成功 5919: シェーダーコード関係の初期化.... 成功 5932: 各種シェーダー用定数バッファの作成.... 成功 5941: 各種 ID3D11InputLayout の作成.... 成功 5970: 画像の単純転送処理の初期化... 成功 5981: 深度バッファを作成します.... 成功 5991: フォントの初期化を行います 5997: フォントの初期化は正常に終了しました 6069: 文字コードバッファの初期化を行います... 完了しました 6097:DXライブラリの初期化処理終了
メンテ
Re: MakeScreen連続呼び出し時不具合? ( No.3 )
名前:管理人 日時:2020/08/04 00:29

> 原因究明中ですが、同じコンテキスト内で初期化(MakeScreen)を呼び出しています。 すみません、C# は詳しくないのですが、『同じコンテキスト内』というのは 『同じスレッド内』と同義なのでしょうか? > 下記のGPUで動作させると稀にMakeScreen APIから何も返ってきません。 > つまり内部でデッドロックしているようです。 デッドロックとは複数のスレッドからある処理を呼び出した時に、内部で処理が衝突して 無限ループになってしまっていることを指す言葉だと思うのですが、 複数のスレッドからDXライブラリの関数を呼んでいる箇所があるということでしょうか? > DXHandle.cpp,DxCompileConfig.hコードを読んでいたのですが、AddHandle内処理の非同期読み込み有効(=DX_NON_ASYNCLOADがコメントアウト)になっているようですが、これが影響しているとか > ありますでしょうか?もしくは、クリティカルセクションのロック/アンロック不具合? AddHandle については、こちらのことを仰られているのかと思いますが #ifndef DX_NON_ASYNCLOAD // 非同期読み込みが完了したらハンドルを削除するフラグを初期化 ( *ppHandleInfo )->ASyncLoadFinishDeleteRequestFlag = FALSE ; // 非同期スレッドから呼ばれた場合は非同期読み込みカウントを1にする if( ASyncThread ) { ( *ppHandleInfo )->ASyncLoadCount = 1 ; ( *ppHandleInfo )->ASyncDataNumber = -1 ; } #endif // DX_NON_ASYNCLOAD こちらは #ifndef DX_NON_ASYNCLOAD // 非同期読み込みが完了したらハンドルを削除するフラグを初期化 ( *ppHandleInfo )->ASyncLoadFinishDeleteRequestFlag = FALSE ; // 非同期スレッドから呼ばれた場合は非同期読み込みカウントを1にする if( ASyncThread ) { ( *ppHandleInfo )->ASyncLoadCount = 1 ; ( *ppHandleInfo )->ASyncDataNumber = -1 ; } #endif こう書くと #endif が、どの #ifndef と組になる #endif なのか分からないので #endif // DX_NON_ASYNCLOAD と、#ifndef DX_NON_ASYNCLOAD に対する #endif と分かるように記述しているものなので、 あっても無くてもプログラムの動作には関わらないただのコメントです ( #ifndef と #endif の間に入る行数がこれだけ少ない場合はこのコメントが無くても 分かりますが、中には #ifndef から #endif まで100行以上離れていたりすることもあるので… ) > ちなみに、本件とは関係ないと思いますが、DxLib_EndをApp終了前にコールすると、log(A)で吐いていたそれまでの情報がクリアされており、 > 下記のログ(@)を吐きなおしているようです。 恐らくどこかで DxLib_Init が呼ばれてしまっていると思われます DxLib_Init の後に再度 DxLib_Init を呼んでも無視され何も起こりませんが、 DxLib_End の後に再度 DxLib_Init を呼ぶと再度DXライブラリの初期化が行われ、ログファイルも再作成されますので、 恐らく DxLib_Init が App終了前に呼ばれてしまっているのだと思います DxLib_End を呼ばない場合 = App終了直前に DxLib_Init は呼ばれているが、DxLib_End が呼ばれていないので無視される DxLib_End を呼ぶ場合 = DxLib_End が呼ばれた後に DxLib_Init が呼ばれているため、再度DXライブラリの初期化が行われている ↑このような状態なのだと思います よろしければ DxLib_Init を呼んでいる箇所が終了直前に実行されていないか確認してみてください m(_ _)m
メンテ
Re: MakeScreen連続呼び出し時不具合? ( No.4 )
名前:Marshal 日時:2020/08/04 09:37

管理人様 >すみません、C# は詳しくないのですが、『同じコンテキスト内』というのは『同じスレッド内』と同義なのでしょうか? はい、同じスレッド内と同義です。 >デッドロックとは複数のスレッドからある処理を呼び出した時に、内部で処理が衝突して >無限ループになってしまっていることを指す言葉だと思うのですが、 >複数のスレッドからDXライブラリの関数を呼んでいる箇所があるということでしょうか? すみません、分かりにくかったかもしれないです。バイナリセマフォを使用しているかと思いますが、DxHandle/AddHandle()内の CRITICALSECTION_LOCK( &HandleManage->CriticalSection )、CriticalSection_Unlock( &HandleManage->CriticalSection )。 この資源関連で、どこかのソースコードで、ライブロック(orデッドロック)を起こしている可能性等はありえないでしょうか? ちなみに、App側のDx関連の処理は、すべて同じスレッド内で処理しているため、マルチスレッドにはしていないつもりです。 下記の通り、DX_NON_ASYNCLOADですが、DxCompileConfig.hの144行目で下記のようにコメントアウトされているようです。 そのため、DxHandle.cpp/AddHandle()の223行目〜233行目の処理には入るかと存じます。 (DxHandle.cpp/AddHandle) #ifndef DX_NON_ASYNCLOAD 〜 #endif // DX_NON_ASYNCLOAD (DxCompileConfig.h) // 非同期読み込みを無効にする場合は次のコメントを外して下さい //#define DX_NON_ASYNCLOAD DxLib_Initの件ですが、特に終了時に呼ばれてはいないようです。。 問題なく動作しているGPUもあるため、いろいろとデバッグしながら原因を調べたいと思います><; 何か分かりましたら、また改めてご連絡させて頂きたいと思います。
メンテ
Re: MakeScreen連続呼び出し時不具合? ( No.5 )
名前:管理人 日時:2020/08/05 02:06

> >すみません、C# は詳しくないのですが、『同じコンテキスト内』というのは『同じスレッド内』と同義なのでしょうか? > はい、同じスレッド内と同義です。 了解です、ご返答ありがとうございます > すみません、分かりにくかったかもしれないです。バイナリセマフォを使用しているかと思いますが、DxHandle/AddHandle()内の > CRITICALSECTION_LOCK( &HandleManage->CriticalSection )、CriticalSection_Unlock( &HandleManage->CriticalSection )。 > この資源関連で、どこかのソースコードで、ライブロック(orデッドロック)を起こしている可能性等はありえないでしょうか? 本件の現象の原因がDXライブラリ内部のコードにある場合はこの辺りのコードも関係している可能性はあると思います > 下記の通り、DX_NON_ASYNCLOADですが、DxCompileConfig.hの144行目で下記のようにコメントアウトされているようです。 > そのため、DxHandle.cpp/AddHandle()の223行目〜233行目の処理には入るかと存じます。 失礼しました、文章をちゃんと読んでいなかったようです、改めてご返答を > DXHandle.cpp,DxCompileConfig.hコードを読んでいたのですが、AddHandle内処理の非同期読み込み有効(=DX_NON_ASYNCLOADがコメントアウト)になっているようですが、これが影響しているとか > ありますでしょうか? DX_NON_ASYNCLOAD がコメントアウトされていても SetUseASyncLoadFlag( TRUE ); を実行して非同期読み込みを有効にしていない限りは DX_NON_ASYNCLOAD がコメントアウトされていない状態と 行われる処理は同じになります Marhsalさんは本件の現象が発生するプログラムで SetUseASyncLoadFlag( TRUE ); は使用していますでしょうか? あと、テストで以下のような MakeScreen を大量に呼び出すプログラムを組んでみたのですが、 エラーは発生せず正常に動作しました #include "DxLib.h" #define MAKE_SCREEN_NUM (500) int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int i ; int LoopCount = 0 ; int ErrorCount = 0 ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // メインループ while( ProcessMessage() == 0 ) { // 画面のクリア ClearDrawScreen() ; // MakeScreen を繰り返すループ for( i = 0; i < MAKE_SCREEN_NUM; i++ ) { int Handle = MakeScreen( 256, 256, TRUE ) ; // MakeScreen が失敗したらエラーカウントをインクリメント if( Handle < 0 ) { ErrorCount++ ; } else { DeleteGraph( Handle ) ; } } // ループカウントをインクリメント LoopCount ++ ; // MakeScreen の回数とエラーの回数を描画 DrawFormatString( 0, 0, GetColor( 255,255,255 ), "MakeScreenの回数 : %d エラーの回数 : %d", LoopCount * MAKE_SCREEN_NUM, ErrorCount ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } よろしければ Marshalさんの環境でも上記のプログラムではエラーが発生しないか 試してみていただけないでしょうか? m(_ _)m
メンテ
Re: MakeScreen連続呼び出し時不具合? ( No.6 )
名前:Marshal 日時:2020/08/06 09:47

管理人様 ご回答頂き有難うございます。 SetUseASyncLoadFlag( TRUE );ですが、使用していないため、このあたりは原因ではなさそうですね。 MakeScreen を大量に呼び出すプログラムを全く同じ内容にして実行してみました。 IntelのGPUでは、問題なく何度実行しても大丈夫でしたが、NvidiaのRTX2070で実行しますと、 MakeScreen()から応答が返ってこない事が稀にあるようです。 PC環境が何かしら影響しているのか等、、とりあえず、私のほうも並行して調査したいと思います。
メンテ
Re: MakeScreen連続呼び出し時不具合? ( No.7 )
名前:管理人 日時:2020/08/08 00:11

> SetUseASyncLoadFlag( TRUE );ですが、使用していないため、このあたりは原因ではなさそうですね。 了解です > MakeScreen を大量に呼び出すプログラムを全く同じ内容にして実行してみました。 > IntelのGPUでは、問題なく何度実行しても大丈夫でしたが、NvidiaのRTX2070で実行しますと、 > MakeScreen()から応答が返ってこない事が稀にあるようです。 確認したところ、私のPCに搭載されているGPUは MarshalさんのPCと近い GeForce RTX2080 でした 稀に MakeScreen()から応答が返ってこないとのことですが、どのくらいの頻度でしょうか? ( とりあえずテストプログラムでの『MakeScreenの回数』が 11300000 になるまで放置しましたが、  MakeScreen()から応答が返ってこなくなることはありませんでした ) もし Marshalさんの環境では高確率で応答が返ってこなくなるということでしたら、よろしければ こちらの『DXライブラリのソース丸ごとコンパイルして実行するテストプロジェクト』 をダウンロードして実行していただけないでしょうか? m(_ _)m https://dxlib.xsrv.jp/temp/DxLibSourceTest_WithUseCLib.zip VisualStudio2019 のプロジェクトなので、VisualStudio2019 をインストールされていない場合は インストールして頂かなければプロジェクトを開けませんが… 以下の手順でDXライブラリ内部のどこで止まってしまっているのかが 突き止められると思いますので、よろしければ止まっている箇所を確認して、 プログラムのファイル名と行番号を教えていただけないでしょうか? m(_ _;m 1. プロジェクトを開いて F5 で実行して No.5 に書き込んだテストプログラムを実行 2. プログラムを実行している途中で MakeScreen から応答が返ってこなくなるまで待つ 3. MakeScreen から応答が返ってこなくなったらメニューから  『デバッグ(D)』→『すべて中断(H)』でプログラムを一時停止 4. プログラムが一時停止したら『デバッグ(D)』→『ウィンドウ(W)』→『スレッド(H)』でスレッドウィンドウを開き   スレッド一覧の中から『メイン スレッド』と書かれているスレッドをダブルクリックしてアクティブにして   画面に表示されるDXライブラリのプログラムの実行中の行を確認する 5. 一時停止している箇所が Direct3D 等のAPI内だった場合は『デバッグ(D)』→『ウィンドウ(W)』→   『呼び出し履歴(C)』でコールスタックを表示して、DXライブラリの関数まで呼び出し関数を遡り、   DXライブラリのプログラムの何処が実行されているかを確認する
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存