Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualcozzie

Posted 30 December 2012 - 03:08 PM

Hi,

Like any other enthousiast, before releasing my top selling FPS game, I'd like to make my 3d engine/ apps hardware variants proof smile.png

I see doing this with the following steps:

1. Check top 5 items while creating device and select 'lower' value if a specific adapter or bufferformat is not available (same for MSAA). Let's call this the basics (i.e. if MSAA not available, though requested, I select no MSAA and let the user continue). In place today and working fine.

2. Create a list of D3D (related) caps that are needed for the current functionalities, and check if these are available.
For now not available means, too bad. Application quits. I keep these up to date as soon as I add new functionality in my engine.

3. Create backwards compability variances for situaties in '2' where a device doesn't meet the requirements.
Same for the vertex and pixel shaders.

Step 3 is something I'll postpone for now, since I'm using D3D9 and PS/VS 2.0, which most devices today support.

I really to hear your advice and tips to make step 2 more efficient, I've posted the code I have now
(accepting that I send away users with hardware that doesn't meet the requirements smile.png)

 

bool CD3d::CheckDeviceCaps()
{
	int nrReqDevCaps = 9;
	DWORD reqDevCaps[9] =	{	D3DDEVCAPS_DRAWPRIMTLVERTEX,	D3DDEVCAPS_HWRASTERIZATION,		D3DDEVCAPS_TLVERTEXSYSTEMMEMORY, 
								D3DDEVCAPS_TLVERTEXVIDEOMEMORY, D3DPRASTERCAPS_ZBUFFERLESSHSR,	D3DPRASTERCAPS_ZTEST,
								D3DDEVCAPS_EXECUTESYSTEMMEMORY, D3DDEVCAPS_EXECUTEVIDEOMEMORY,  D3DDEVCAPS_TEXTUREVIDEOMEMORY };
	int nrReqPresentCaps = 3;
	DWORD reqPresentCaps[3] = {	D3DPRESENT_INTERVAL_ONE,		D3DPRESENT_INTERVAL_TWO,		D3DPRESENT_INTERVAL_IMMEDIATE };
	int nrReqTexFilterCaps = 4; 
	DWORD reqTexFilterCaps[4]= {D3DPTFILTERCAPS_MAGFLINEAR,		D3DPTFILTERCAPS_MINFLINEAR,		D3DPTFILTERCAPS_MIPFLINEAR,
								D3DPTFILTERCAPS_MINFANISOTROPIC };
	int nrReqPrimMiscCaps =3;
	DWORD reqPrimMiscCaps[3] = {D3DPMISCCAPS_CULLNONE,			D3DPMISCCAPS_CULLCW,			D3DPMISCCAPS_CULLCCW };
	int nrReqTextureCaps = 2;
	DWORD reqTextureCaps[2] = {	D3DPTEXTURECAPS_MIPMAP,			D3DPTEXTURECAPS_ALPHA };		// CUBEMAP and VOLUMEMAP later
	int nrReqTexAddrCaps = 5;
	DWORD reqTexAddrCaps[5] = {	D3DPTADDRESSCAPS_BORDER,		D3DPTADDRESSCAPS_CLAMP,			D3DPTADDRESSCAPS_WRAP,
								D3DPTADDRESSCAPS_INDEPENDENTUV,	D3DPTADDRESSCAPS_MIRROR  };
	int nrReqRasterCaps = 2;
	DWORD reqRasterCaps[2] = {	D3DPRASTERCAPS_ANISOTROPY,		D3DPRASTERCAPS_DITHER };
	int nrReqShadeCaps = 3;
	DWORD reqShadeCaps[3] = {	D3DPSHADECAPS_ALPHAGOURAUDBLEND,D3DPSHADECAPS_SPECULARGOURAUDRGB,
								D3DPSHADECAPS_COLORGOURAUDRGB };
	
	if(mD3d != NULL)
	{
		D3DCAPS9	caps;
		if(D3D_OK != mD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, mDevType, &caps)) return false;
		
		for(cc=0;cc<nrReqDevCaps;++cc)		{ if(!(caps.DevCaps & reqDevCaps[cc])) return false; }
		for(cc=0;cc<nrReqPresentCaps;++cc)	{ if(!(caps.PresentationIntervals & reqPresentCaps[cc])) return false; }
		for(cc=0;cc<nrReqTexFilterCaps;++cc){ if(!(caps.VertexTextureFilterCaps & reqTexFilterCaps[cc])) return false; }
		for(cc=0;cc<nrReqTexAddrCaps;++cc)	{ if(!(caps.TextureAddressCaps & reqTexAddrCaps[cc])) return false; }
		for(cc=0;cc<nrReqPrimMiscCaps;++cc) { if(!(caps.PrimitiveMiscCaps & reqPrimMiscCaps[cc])) return false; }
		for(cc=0;cc<nrReqRasterCaps;++cc)	{ if(!(caps.RasterCaps & reqRasterCaps[cc])) return false; }
		for(cc=0;cc<nrReqShadeCaps;++cc)	{ if(!(caps.ShadeCaps & reqShadeCaps[cc])) return false; }

		if(D3D_OK != mD3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, mDevType, mAdapterFormat, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)) return false;
		if(!(caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP)) return false;

		if(caps.VertexShaderVersion < D3DVS_VERSION(2,0)) return false;
		if(caps.PixelShaderVersion < D3DPS_VERSION(2,0)) return false;
		if(caps.MaxAnisotropy < 4) return false;
		if(caps.MaxTextureWidth < 256) return false;
		if(caps.MaxTextureHeight < 256) return false;
		if(caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) return false;

		return true;
	}
	else return false;
}

 

Can this be done, easier? (i.e. with an array of DWORD values / caps and the corresponding caps.'' etc.)


#2cozzie

Posted 30 December 2012 - 03:07 PM

Hi,

Like any other enthousiast, before releasing my top selling FPS game, I'd like to make my 3d engine/ apps hardware variants proof :)

I see doing this with the following steps:

1. Check top 5 items while creating device and select 'lower' value if a specific adapter or bufferformat is not available (same for MSAA). Let's call this the basics (i.e. if MSAA not available, though requested, I select no MSAA and let the user continue). In place today and working fine.

2. Create a list of D3D (related) caps that are needed for the current functionalities, and check if these are available.
For now not available means, too bad. Application quits. I keep these up to date as soon as I add new functionality in my engine.

3. Create backwards compability variances for situaties in '2' where a device doesn't meet the requirements.
Same for the vertex and pixel shaders.

Step 3 is something I'll postpone for now, since I'm using D3D9 and PS/VS 2.0, which most devices today support.

I really to hear your advice and tips to make step 2 more efficient, I've posted the code I have now
(accepting that I send away users with hardware that doesn't meet the requirements :))
bool CD3d::CheckDeviceCaps(){	int nrReqDevCaps = 9;	DWORD reqDevCaps[9] =	{	D3DDEVCAPS_DRAWPRIMTLVERTEX,	D3DDEVCAPS_HWRASTERIZATION,		D3DDEVCAPS_TLVERTEXSYSTEMMEMORY, 								D3DDEVCAPS_TLVERTEXVIDEOMEMORY, D3DPRASTERCAPS_ZBUFFERLESSHSR,	D3DPRASTERCAPS_ZTEST,								D3DDEVCAPS_EXECUTESYSTEMMEMORY, D3DDEVCAPS_EXECUTEVIDEOMEMORY,  D3DDEVCAPS_TEXTUREVIDEOMEMORY };	int nrReqPresentCaps = 3;	DWORD reqPresentCaps[3] = {	D3DPRESENT_INTERVAL_ONE,		D3DPRESENT_INTERVAL_TWO,		D3DPRESENT_INTERVAL_IMMEDIATE };	int nrReqTexFilterCaps = 4; 	DWORD reqTexFilterCaps[4]= {D3DPTFILTERCAPS_MAGFLINEAR,		D3DPTFILTERCAPS_MINFLINEAR,		D3DPTFILTERCAPS_MIPFLINEAR,								D3DPTFILTERCAPS_MINFANISOTROPIC };	int nrReqPrimMiscCaps =3;	DWORD reqPrimMiscCaps[3] = {D3DPMISCCAPS_CULLNONE,			D3DPMISCCAPS_CULLCW,			D3DPMISCCAPS_CULLCCW };	int nrReqTextureCaps = 2;	DWORD reqTextureCaps[2] = {	D3DPTEXTURECAPS_MIPMAP,			D3DPTEXTURECAPS_ALPHA };		// CUBEMAP and VOLUMEMAP later	int nrReqTexAddrCaps = 5;	DWORD reqTexAddrCaps[5] = {	D3DPTADDRESSCAPS_BORDER,		D3DPTADDRESSCAPS_CLAMP,			D3DPTADDRESSCAPS_WRAP,								D3DPTADDRESSCAPS_INDEPENDENTUV,	D3DPTADDRESSCAPS_MIRROR  };	int nrReqRasterCaps = 2;	DWORD reqRasterCaps[2] = {	D3DPRASTERCAPS_ANISOTROPY,		D3DPRASTERCAPS_DITHER };	int nrReqShadeCaps = 3;	DWORD reqShadeCaps[3] = {	D3DPSHADECAPS_ALPHAGOURAUDBLEND,D3DPSHADECAPS_SPECULARGOURAUDRGB,								D3DPSHADECAPS_COLORGOURAUDRGB };		if(mD3d != NULL)	{		D3DCAPS9	caps;		if(D3D_OK != mD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, mDevType, &caps)) return false;				for(cc=0;cc<nrReqDevCaps;++cc)		{ if(!(caps.DevCaps & reqDevCaps[cc])) return false; }		for(cc=0;cc<nrReqPresentCaps;++cc)	{ if(!(caps.PresentationIntervals & reqPresentCaps[cc])) return false; }		for(cc=0;cc<nrReqTexFilterCaps;++cc){ if(!(caps.VertexTextureFilterCaps & reqTexFilterCaps[cc])) return false; }		for(cc=0;cc<nrReqTexAddrCaps;++cc)	{ if(!(caps.TextureAddressCaps & reqTexAddrCaps[cc])) return false; }		for(cc=0;cc<nrReqPrimMiscCaps;++cc) { if(!(caps.PrimitiveMiscCaps & reqPrimMiscCaps[cc])) return false; }		for(cc=0;cc<nrReqRasterCaps;++cc)	{ if(!(caps.RasterCaps & reqRasterCaps[cc])) return false; }		for(cc=0;cc<nrReqShadeCaps;++cc)	{ if(!(caps.ShadeCaps & reqShadeCaps[cc])) return false; }		if(D3D_OK != mD3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, mDevType, mAdapterFormat, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)) return false;		if(!(caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP)) return false;		if(caps.VertexShaderVersion < D3DVS_VERSION(2,0)) return false;		if(caps.PixelShaderVersion < D3DPS_VERSION(2,0)) return false;		if(caps.MaxAnisotropy < 4) return false;		if(caps.MaxTextureWidth < 256) return false;		if(caps.MaxTextureHeight < 256) return false;		if(caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) return false;		return true;	}	else return false;}
Can this be done, easier? (i.e. with an array of DWORD values / caps and the corresponding caps.'<subcaps>' etc.)

#1cozzie

Posted 30 December 2012 - 03:06 PM

Hi,

 

Like any other enthousiast, for releasing top selling FPS games, I'd like to make my 3d engine/ apps hardware variants proof :)

I see doing this with the following steps:

 

1. Check top 5 items while creating device and select 'lower' value if a specific adapter or bufferformat is not available (same for MSAA).

Let's call this the basics (i.e. if MSAA not available, though requested, I select no MSAA and let the user continue).

 

2. Create a list of D3D (related) caps that are needed for the current functionalities, and check if these are available.

For now not available means, too bad. Application quits.

 

3. Create backwards compability variances for situaties in '2' where a device doesn't meet the requirements.

Same for the vertex and pixel shaders.

 

Step 3 is something I'll postpone for now, since I'm using D3D9 and PS/VS 2.0, which most devices today support.

 

I really to hear your advice and tips to make step 2 more efficient, I've posted the code I have now

(accepting that I send away users with hardware that doesn't meet the requirements :))

 

bool CD3d::CheckDeviceCaps()
{
	int nrReqDevCaps = 9;
	DWORD reqDevCaps[9] =	{	D3DDEVCAPS_DRAWPRIMTLVERTEX,	D3DDEVCAPS_HWRASTERIZATION,		D3DDEVCAPS_TLVERTEXSYSTEMMEMORY, 
								D3DDEVCAPS_TLVERTEXVIDEOMEMORY, D3DPRASTERCAPS_ZBUFFERLESSHSR,	D3DPRASTERCAPS_ZTEST,
								D3DDEVCAPS_EXECUTESYSTEMMEMORY, D3DDEVCAPS_EXECUTEVIDEOMEMORY,  D3DDEVCAPS_TEXTUREVIDEOMEMORY };
	int nrReqPresentCaps = 3;
	DWORD reqPresentCaps[3] = {	D3DPRESENT_INTERVAL_ONE,		D3DPRESENT_INTERVAL_TWO,		D3DPRESENT_INTERVAL_IMMEDIATE };
	int nrReqTexFilterCaps = 4; 
	DWORD reqTexFilterCaps[4]= {D3DPTFILTERCAPS_MAGFLINEAR,		D3DPTFILTERCAPS_MINFLINEAR,		D3DPTFILTERCAPS_MIPFLINEAR,
								D3DPTFILTERCAPS_MINFANISOTROPIC };
	int nrReqPrimMiscCaps =3;
	DWORD reqPrimMiscCaps[3] = {D3DPMISCCAPS_CULLNONE,			D3DPMISCCAPS_CULLCW,			D3DPMISCCAPS_CULLCCW };
	int nrReqTextureCaps = 2;
	DWORD reqTextureCaps[2] = {	D3DPTEXTURECAPS_MIPMAP,			D3DPTEXTURECAPS_ALPHA };		// CUBEMAP and VOLUMEMAP later
	int nrReqTexAddrCaps = 5;
	DWORD reqTexAddrCaps[5] = {	D3DPTADDRESSCAPS_BORDER,		D3DPTADDRESSCAPS_CLAMP,			D3DPTADDRESSCAPS_WRAP,
								D3DPTADDRESSCAPS_INDEPENDENTUV,	D3DPTADDRESSCAPS_MIRROR  };
	int nrReqRasterCaps = 2;
	DWORD reqRasterCaps[2] = {	D3DPRASTERCAPS_ANISOTROPY,		D3DPRASTERCAPS_DITHER };
	int nrReqShadeCaps = 3;
	DWORD reqShadeCaps[3] = {	D3DPSHADECAPS_ALPHAGOURAUDBLEND,D3DPSHADECAPS_SPECULARGOURAUDRGB,
								D3DPSHADECAPS_COLORGOURAUDRGB };
	
	if(mD3d != NULL)
	{
		D3DCAPS9	caps;
		if(D3D_OK != mD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, mDevType, &caps)) return false;
		
		for(cc=0;cc<nrReqDevCaps;++cc)		{ if(!(caps.DevCaps & reqDevCaps[cc])) return false; }
		for(cc=0;cc<nrReqPresentCaps;++cc)	{ if(!(caps.PresentationIntervals & reqPresentCaps[cc])) return false; }
		for(cc=0;cc<nrReqTexFilterCaps;++cc){ if(!(caps.VertexTextureFilterCaps & reqTexFilterCaps[cc])) return false; }
		for(cc=0;cc<nrReqTexAddrCaps;++cc)	{ if(!(caps.TextureAddressCaps & reqTexAddrCaps[cc])) return false; }
		for(cc=0;cc<nrReqPrimMiscCaps;++cc) { if(!(caps.PrimitiveMiscCaps & reqPrimMiscCaps[cc])) return false; }
		for(cc=0;cc<nrReqRasterCaps;++cc)	{ if(!(caps.RasterCaps & reqRasterCaps[cc])) return false; }
		for(cc=0;cc<nrReqShadeCaps;++cc)	{ if(!(caps.ShadeCaps & reqShadeCaps[cc])) return false; }

		if(D3D_OK != mD3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, mDevType, mAdapterFormat, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)) return false;
		if(!(caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP)) return false;

		if(caps.VertexShaderVersion < D3DVS_VERSION(2,0)) return false;
		if(caps.PixelShaderVersion < D3DPS_VERSION(2,0)) return false;
		if(caps.MaxAnisotropy < 4) return false;
		if(caps.MaxTextureWidth < 256) return false;
		if(caps.MaxTextureHeight < 256) return false;
		if(caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) return false;

		return true;
	}
	else return false;
}

Can this be done, easier? (i.e. with an array of DWORD values / caps and the corresponding caps.'<subcaps>' etc.)

 


PARTNERS