DXライブラリ関数はスレッドフリーでしょうか?
Posted: 2012年12月14日(金) 10:42
お世話になります。
C言語 & DirectX初心者です。
質問ですが、DXライブラリの関数はスレッドフリーでしょうか?
[やりたいこと]
4CoreのCPUを使用して、4段のパイプライン処理を実現したい。
画像データをパイプラインで引き渡してゆき、各Coreで表示位置を変えて画面上に表示する。
画像は720X480 8bitX3CHのカラー画像でデータはRGBの順に並んでいる
test0000.raw 全面赤色
test0001.raw 全面黄色
test0002.raw 全面青色
test0003.raw 全面緑色
4枚の画像を逐次Readしては、ImageXにSetし、描画し、次のパイプラインに引き渡す。
READ用,WRITE用のメモリバッファはダブルバッファとして、READ中のメモリのWRITE,
WRITE中のメモリのREADはしないようにする。
ということで下記のようなコードを作ってみました。
一応、所定の動作はしているのですが、気になるのは、329行目-349行目の
// グラフィックハンドル作成&描画(Core0)
grhandle1 = CreateGraphFromSoftImage( handle1 ) ;
DrawGraph( 0, 0, grhandle1, TRUE ) ;
// グラフィックハンドル作成&描画(Core1)
grhandle2 = CreateGraphFromSoftImage( handle2 ) ;
DrawGraph( xoffset ,0, grhandle2, TRUE ) ;
// グラフィックハンドル作成&描画(Core2)
grhandle3 = CreateGraphFromSoftImage( handle3 ) ;
DrawGraph( 0 ,yoffset, grhandle3, TRUE ) ;
// グラフィックハンドル作成&描画(Core3)
grhandle4 = CreateGraphFromSoftImage( handle4 ) ;
DrawGraph(xoffset,yoffset,grhandle4,TRUE);
DrawFormatString( 0 ,0, Color, "Thread No:%d\n",n0 ) ;
DrawFormatString( xoffset, 0 , Color, "Thread No:%d\n",n1 ) ;
DrawFormatString( 0, yoffset , Color, "Thread No:%d\n",n2 ) ;
DrawFormatString( xoffset, yoffset , Color, "Thread No:%d\n",n3 ) ;
の部分をOpenMPで並列化している部分で実行すると、(コメントアウトしている209,210,247,248,284,285,321,322行目で描画する。)
アクセスのエラーが生じ、プログラムが落ちます。
DXライブラリの描画関係の関数はスレッドフリーにはなっていないということでしょうか?
それともコードになにか問題がありますでしょうか?
ご教授頂ければ幸いです。
C言語 & DirectX初心者です。
質問ですが、DXライブラリの関数はスレッドフリーでしょうか?
[やりたいこと]
4CoreのCPUを使用して、4段のパイプライン処理を実現したい。
画像データをパイプラインで引き渡してゆき、各Coreで表示位置を変えて画面上に表示する。
画像は720X480 8bitX3CHのカラー画像でデータはRGBの順に並んでいる
test0000.raw 全面赤色
test0001.raw 全面黄色
test0002.raw 全面青色
test0003.raw 全面緑色
4枚の画像を逐次Readしては、ImageXにSetし、描画し、次のパイプラインに引き渡す。
READ用,WRITE用のメモリバッファはダブルバッファとして、READ中のメモリのWRITE,
WRITE中のメモリのREADはしないようにする。
ということで下記のようなコードを作ってみました。
一応、所定の動作はしているのですが、気になるのは、329行目-349行目の
// グラフィックハンドル作成&描画(Core0)
grhandle1 = CreateGraphFromSoftImage( handle1 ) ;
DrawGraph( 0, 0, grhandle1, TRUE ) ;
// グラフィックハンドル作成&描画(Core1)
grhandle2 = CreateGraphFromSoftImage( handle2 ) ;
DrawGraph( xoffset ,0, grhandle2, TRUE ) ;
// グラフィックハンドル作成&描画(Core2)
grhandle3 = CreateGraphFromSoftImage( handle3 ) ;
DrawGraph( 0 ,yoffset, grhandle3, TRUE ) ;
// グラフィックハンドル作成&描画(Core3)
grhandle4 = CreateGraphFromSoftImage( handle4 ) ;
DrawGraph(xoffset,yoffset,grhandle4,TRUE);
DrawFormatString( 0 ,0, Color, "Thread No:%d\n",n0 ) ;
DrawFormatString( xoffset, 0 , Color, "Thread No:%d\n",n1 ) ;
DrawFormatString( 0, yoffset , Color, "Thread No:%d\n",n2 ) ;
DrawFormatString( xoffset, yoffset , Color, "Thread No:%d\n",n3 ) ;
の部分をOpenMPで並列化している部分で実行すると、(コメントアウトしている209,210,247,248,284,285,321,322行目で描画する。)
アクセスのエラーが生じ、プログラムが落ちます。
DXライブラリの描画関係の関数はスレッドフリーにはなっていないということでしょうか?
それともコードになにか問題がありますでしょうか?
ご教授頂ければ幸いです。
#include "DxLib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <omp.h>
int WindowWidth = 1600;
int WindowHeight = 1200;
int LOOP;
int START = 0;
int END = 1000;
//int END = 0;
//int inwidth = 1500;
//int inheight = 1000;
//int inwidth = 1400;
//int inheight = 933;
//int inwidth = 1300;
//int inheight = 866;
//int inwidth = 1200;
//int inheight = 800;
//int inwidth = 1100;
//int inheight = 733;
//int inwidth = 1000;
//int inheight = 666;
int inwidth = 720;
int inheight = 480;
int xoffset = 740;
int yoffset = 500;
int Color;
int outwidth = 0;
int outheight =0;
int x,y,i,j,cno,xx=0;
int StartTime0,EndTime0,EndTime1,EndTime2,Endtime3;
int FLAG;
int n0,n1,n2,n3;
int thread_num = 1;
char ch1[512],ch2[512] ;
char st1[25],st2[25];
char c_zero[6] = "00000";
char no[10];
unsigned char* pSrc8u_1;
unsigned char* pSrc8u_A;
unsigned char* pSrc8u_B;
unsigned char* pSrc8u_C;
unsigned char* pSrc8u_D;
unsigned char* pSrc8u_E;
unsigned char* pSrc8u_F;
unsigned char* image1;
unsigned char* image2;
unsigned char* image3;
unsigned char* image4;
FILE *fp1;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int handle1,handle2,handle3,handle4 ;
int grhandle1,grhandle2,grhandle3,grhandle4;
//入出力カラー画像のメモリエリア確保
pSrc8u_1= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
pSrc8u_A= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
pSrc8u_B= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
pSrc8u_C= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
pSrc8u_D= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
pSrc8u_E= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
pSrc8u_F= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
//LCD表示初期設定
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1;
//描画Windowsのサイズ設定
SetGraphMode( WindowWidth , WindowHeight , 32 ) ;
ChangeWindowMode(TRUE); // ウィンドウモードに設定
SetDrawScreen( DX_SCREEN_BACK ); //描画先を表画面に設定
// 空のフルカラー画像を作成する
handle1 = MakeRGB8ColorSoftImage(inwidth,inheight) ;
handle2 = MakeRGB8ColorSoftImage(inwidth,inheight) ;
handle3 = MakeRGB8ColorSoftImage(inwidth,inheight) ;
handle4 = MakeRGB8ColorSoftImage(inwidth,inheight) ;
//各グラフィックハンドルの先頭アドレスを読み込む。
image1 = ( unsigned char * )GetImageAddressSoftImage( handle1 ) ;
image2 = ( unsigned char * )GetImageAddressSoftImage( handle2 ) ;
image3 = ( unsigned char * )GetImageAddressSoftImage( handle3 ) ;
image4 = ( unsigned char * )GetImageAddressSoftImage( handle4 ) ;
//*******************
//** 動画処理ループ
//*******************
for(LOOP = START;LOOP <= END;LOOP++){
FLAG = LOOP%2 ;
//入力画像データFILE名作成
//Input_image Read from FILE
sprintf(no,"%d",LOOP%4);
cno = (int)(strlen(no));
//sprintf(st1,"%d",inwidth);
//sprintf(st2,"%d",inheight);
strcpy(ch1,"");
//strcat(ch1,st1);
//strcat(ch1,"_");
//strcat(ch1,st2);
//strcat(ch1,"_");
strcat(ch1,"test");
strncat(ch1,c_zero,4 -cno);
strcat(ch1,no);
strcat(ch1,".raw");
//Buffer確保
//Input_image Read from FILE
fp1 = fopen(ch1,"rb");
if(fp1 == NULL){
printf("Input FILE Error!!\n");
getchar();
return -1;
}
fread(pSrc8u_1,sizeof(unsigned char),inwidth*3*inheight,fp1);
fclose(fp1);
//*************
//初期画面表示
//*************
ClearDrawScreen();//ScreenのClear
// 白色の値を取得
Color = GetColor( 255 , 255 , 255 ) ;
//Thread数の設定
#pragma omp parallel num_threads(4)
#pragma omp sections
{
//Core0処理
#pragma omp section
{
n0 = omp_get_thread_num() ;
// 入力データを画面表示メモリにSetする。
for( i = 0; i <inwidth*inheight; i++ )
{
image1[i*3] = pSrc8u_1[i*3 + 2];
image1[i*3+1] = pSrc8u_1[i*3 + 1];
image1[i*3+2] = pSrc8u_1[i*3];
}
//grhandle1 = CreateGraphFromSoftImage( handle1 ) ;
//DrawGraph( 0, 0, grhandle1, TRUE ) ;
switch(FLAG){
case 0:
memcpy(pSrc8u_A,image1,sizeof(unsigned char)*3*inwidth*inheight);
break;
case 1:
memcpy(pSrc8u_B,image1,sizeof(unsigned char)*3*inwidth*inheight);
break;
}
}
//Core1処理
#pragma omp section
{
n1 = omp_get_thread_num() ;
switch(FLAG){
case 0:
memcpy(image2,pSrc8u_B,sizeof(unsigned char)*3*inwidth*inheight);
break;
case 1:
memcpy(image2,pSrc8u_A,sizeof(unsigned char)*3*inwidth*inheight);
break;
}
//grhandle2 = CreateGraphFromSoftImage( handle2 ) ;
//DrawGraph( xoffset ,0, grhandle2, TRUE ) ;
switch(FLAG){
case 0:
memcpy(pSrc8u_C,image2,sizeof(unsigned char)*3*inwidth*inheight);
break;
case 1:
memcpy(pSrc8u_D,image2,sizeof(unsigned char)*3*inwidth*inheight);
break;
}
}
//Core2処理
#pragma omp section
{
n2 = omp_get_thread_num() ;
DrawFormatString( 0,yoffset, Color, "Thread No:%d",omp_get_thread_num() ) ;
switch(FLAG){
case 0:
memcpy(image3,pSrc8u_D,sizeof(unsigned char)*3*inwidth*inheight);
break;
case 1:
memcpy(image3,pSrc8u_C,sizeof(unsigned char)*3*inwidth*inheight);
break;
}
//grhandle3 = CreateGraphFromSoftImage( handle3 ) ;
//DrawGraph( 0 ,yoffset, grhandle3, TRUE ) ;
switch(FLAG){
case 0:
memcpy(pSrc8u_E,image3,sizeof(unsigned char)*3*inwidth*inheight);
break;
case 1:
memcpy(pSrc8u_F,image3,sizeof(unsigned char)*3*inwidth*inheight);
break;
}
}
//Core3処理
#pragma omp section
{
n3 = omp_get_thread_num() ;
switch(FLAG){
case 0:
memcpy(image4,pSrc8u_F,sizeof(unsigned char)*3*inwidth*inheight);
break;
case 1:
memcpy(image4,pSrc8u_E,sizeof(unsigned char)*3*inwidth*inheight);
break;
}
//grhandle4 = CreateGraphFromSoftImage( handle4 ) ;
//DrawGraph(xoffset,yoffset,grhandle4,TRUE);
}
}//End #pragma omp sections
// グラフィックハンドル作成&描画(Core0)
grhandle1 = CreateGraphFromSoftImage( handle1 ) ;
DrawGraph( 0, 0, grhandle1, TRUE ) ;
// グラフィックハンドル作成&描画(Core1)
grhandle2 = CreateGraphFromSoftImage( handle2 ) ;
DrawGraph( xoffset ,0, grhandle2, TRUE ) ;
// グラフィックハンドル作成&描画(Core2)
grhandle3 = CreateGraphFromSoftImage( handle3 ) ;
DrawGraph( 0 ,yoffset, grhandle3, TRUE ) ;
// グラフィックハンドル作成&描画(Core3)
grhandle4 = CreateGraphFromSoftImage( handle4 ) ;
DrawGraph(xoffset,yoffset,grhandle4,TRUE);
DrawFormatString( 0 ,0, Color, "Thread No:%d\n",n0 ) ;
DrawFormatString( xoffset, 0 , Color, "Thread No:%d\n",n1 ) ;
DrawFormatString( 0, yoffset , Color, "Thread No:%d\n",n2 ) ;
DrawFormatString( xoffset, yoffset , Color, "Thread No:%d\n",n3 ) ;
//LCD Vsync 2Wait(30FPS)
WaitVSync(15) ;
ScreenFlip(); //裏画面を表画面に反映
//メモリ読み込んだ画像を消去する。
//これを入れないと、多数の静止画を読み込んだ時、メモリが更新されなくなる。
InitGraph() ;
}//End For
// 使い終わっったハンドルを解放
DeleteSoftImage( handle1 ) ;
DeleteSoftImage( handle2 ) ;
DeleteSoftImage( handle3 ) ;
DeleteSoftImage( handle4 ) ;
free( pSrc8u_1);
free( pSrc8u_A);
free( pSrc8u_B);
free( pSrc8u_C);
free( pSrc8u_D);
free( pSrc8u_E);
free( pSrc8u_F);
// キー入力待ち
WaitKey();
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}