Example #1
0
std::string RenderingDevice::getDesc() const
{
   char tmpStr[1024];

   sprintf_s(tmpStr, 1024, 
   "Device no. %d \n"                           \
   "\tType %s\n"                                \
   "\tFullscreen %s\n"                          \
   "\tMode\n"                                   \
   "\t\tdisplay - [%d, %d, %d, %s]\n"           \
   "\t\tadapter fmt - %s\n"                     \
   "\t\tback buffer fmt - %s\n"                 \
   "\t\tdepth stencil fmt - %s\n"               \
   "\t\tvertex processing model - %s\n"         \
   "\tCapabilities\n"                           \
   "\t\tpixel shader %d.%d\n"                   \
   "\t\tvertex shader %d.%d",
   adapterOrdinal,
   descDevType(deviceType).c_str(),
   (windowed ? "NO" : "YES"),
   displayMode.Width, displayMode.Height, displayMode.RefreshRate, descFormat(displayMode.Format).c_str(),
   descFormat(adapterFormat).c_str(),
   descFormat(backBufferFormat).c_str(),
   descFormat(depthStencilFormats[0]).c_str(),
   descVtxProcessType(vertexProcessingType).c_str(),
   D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion), D3DSHADER_VERSION_MINOR(caps.PixelShaderVersion),
   D3DSHADER_VERSION_MAJOR(caps.VertexShaderVersion), D3DSHADER_VERSION_MINOR(caps.VertexShaderVersion));

   return tmpStr;
}
Example #2
0
IHLSLCodeGenerator::CodeVersion DxStdMtl2::GetPixelShaderSupport(LPDIRECT3DDEVICE9 pd3dDevice, DWORD & instSlots)
{
	D3DCAPS9	Caps;
	IHLSLCodeGenerator::CodeVersion code;
	pd3dDevice->GetDeviceCaps(&Caps);
	UINT major = D3DSHADER_VERSION_MAJOR(Caps.PixelShaderVersion);
	UINT minor = D3DSHADER_VERSION_MINOR(Caps.PixelShaderVersion);

	instSlots = 96;

	if(major < 2 )
		code = IHLSLCodeGenerator::PS_1_X;
	else if(major == 2)
	{
		instSlots = Caps.PS20Caps.NumInstructionSlots;
		if(minor > 0)
			code = IHLSLCodeGenerator::PS_2_X;
		else
			code = IHLSLCodeGenerator::PS_2_0;
	}
	else if(major >=3)
	{
		instSlots = Caps.MaxPixelShader30InstructionSlots;
		code = IHLSLCodeGenerator::PS_3_0;
	}
	else
	{
		code = IHLSLCodeGenerator::PS_1_X;
	}

	return code;

}
Example #3
0
extern "C" __declspec(dllexport) BOOLEAN hasPixelShader3()
{
	SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
	HINSTANCE hD3D9 = NULL;
	hD3D9 = LoadLibrary("D3D9.DLL");
	if (!hD3D9) return false;
	typedef IDirect3D9* (WINAPI *DIRECT3DCREATE_PTR)(UINT SDKVersion);
	DIRECT3DCREATE_PTR pfnD3DCreate = (DIRECT3DCREATE_PTR)GetProcAddress(hD3D9, "Direct3DCreate9");
	if (!pfnD3DCreate)
	{
		FreeLibrary(hD3D9);
		return false;
	}
	LPDIRECT3D9 pD3D = pfnD3DCreate(D3D_SDK_VERSION);
	D3DCAPS9 videocardspec;
	ZeroMemory(&videocardspec, sizeof(D3DCAPS9));
	pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE::D3DDEVTYPE_HAL, &videocardspec);
	int major_ver, minor_ver;
	major_ver = D3DSHADER_VERSION_MAJOR(videocardspec.PixelShaderVersion);
	minor_ver = D3DSHADER_VERSION_MINOR(videocardspec.PixelShaderVersion);
	pD3D->Release();
	FreeLibrary(hD3D9);
	if (major_ver >= 3)
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
Example #4
0
DWORD	LcD3D_GetPixelShaderVersionMajor(PDEV pDev)
{
	D3DCAPS9 caps;
	DWORD	Version;
	pDev->GetDeviceCaps(&caps);

	Version = caps.PixelShaderVersion;
	return D3DSHADER_VERSION_MAJOR(Version);
}
// FIXME: <rdar://6507851> Share this code with CoreAnimation.
static bool hardwareCapabilitiesIndicateCoreAnimationSupport(const D3DCAPS9& caps)
{
    // CoreAnimation needs two or more texture units.
    if (caps.MaxTextureBlendStages < 2)
        return false;

    // CoreAnimation needs non-power-of-two textures.
    if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
        return false;

    // CoreAnimation needs vertex shader 2.0 or greater.
    if (D3DSHADER_VERSION_MAJOR(caps.VertexShaderVersion) < 2)
        return false;

    // CoreAnimation needs pixel shader 2.0 or greater.
    if (D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion) < 2)
        return false;

    return true;
}
bool ShaderUtils::GetDX9AsmKeyWords(ShaderUtils::KeyWordsList& keyWords, const DWORD* pdwShader)
{
    keyWords.clear();

    if (pdwShader == NULL)
    {
        return false;
    }

    return GetDX9AsmKeyWords(keyWords, DECODE_D3D9_SHADER_TYPE(*pdwShader), (WORD) D3DSHADER_VERSION_MAJOR(*pdwShader), (WORD) D3DSHADER_VERSION_MINOR(*pdwShader));
}
Example #7
0
/********************************************************************
WixQueryDirectXCaps - entry point for WixQueryDirectXCaps CA

 Called as Type 1 custom action (DLL from the Binary table) from
 Windows Installer to set properties that identify the DirectX
 capabilities ("caps") of the system.
********************************************************************/
extern "C" UINT __stdcall WixQueryDirectXCaps(
    __in MSIHANDLE hInstall
    )
{
#if 0
    ::MessageBoxA(0, "break into debugger now please", "---->> ATTACH TO ME!", MB_ICONEXCLAMATION);
#endif

    HRESULT hr = S_OK;
    DWORD er = ERROR_SUCCESS;
    LPDIRECT3D9 pD3D = NULL;

    hr = WcaInitialize(hInstall, "WixQueryDirectXCaps");
    ExitOnFailure(hr, "failed to initialize");

    pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    ExitOnNull(pD3D, hr, E_FAIL, "Direct3DCreate9 failed");

    D3DCAPS9 d3dCaps;
    hr = pD3D->GetDeviceCaps(
        0,                 // first adapter
        D3DDEVTYPE_HAL,    // fail on non-HAL devices
        &d3dCaps
    );
    ExitOnFailure(hr, "GetDeviceCaps call failed");

    int iVertexShaderVersion = D3DSHADER_VERSION_MAJOR(d3dCaps.VertexShaderVersion) * 100 + D3DSHADER_VERSION_MINOR(d3dCaps.VertexShaderVersion);
    WcaSetIntProperty(L"WIX_DIRECTX_VERTEXSHADERVERSION", iVertexShaderVersion);

    int iPixelShaderVersion = D3DSHADER_VERSION_MAJOR(d3dCaps.PixelShaderVersion) * 100 + D3DSHADER_VERSION_MINOR(d3dCaps.PixelShaderVersion);
    WcaSetIntProperty(L"WIX_DIRECTX_PIXELSHADERVERSION", iPixelShaderVersion);

LExit:
    ReleaseObject(pD3D);
    return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er);
}
Example #8
0
VShader::VShader(const DWORD *pFunction, HANDLE Handle)
{
    _Handle = Handle;

    Assert(pFunction != NULL, "Invalid function tokens");
    UINT TokenIndex = 0;
    DWORD VersionToken = pFunction[TokenIndex++];
    _MinorVersion = D3DSHADER_VERSION_MINOR(VersionToken);
    _MajorVersion = D3DSHADER_VERSION_MAJOR(VersionToken);
    bool Done = false;

    if(_MajorVersion == 1)
    {
        g_Context->Files.Assert << "Shader version 1 not supported\n";
        Done = true;
    }

    while(!Done)
    {
        DWORD CurrentToken = pFunction[TokenIndex++];
        if(CurrentToken == D3DVS_END())
        {
            Done = true;
        }
        else if((CurrentToken & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
        {
            CompleteInstructions.PushEnd();
            CompleteShaderInstruction &CurInstruction = CompleteInstructions.Last();
            CurInstruction._Instruction._InstructionToken = InstructionToken(CurrentToken);
            UINT CommentLength = (CurrentToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
            for(UINT i = 0; i < CommentLength; i++)
            {
                DWORD CurrentComment = pFunction[TokenIndex++];
                UCHAR *CommentStream = (UCHAR *)&CurrentComment;
                for(UINT i2 = 0; i2 < 4; i2++)
                {
                    CurInstruction.Comment.PushEnd(CommentStream[i2]);
                }
            }
        }
        else
        {
Example #9
0
void GenerateCaps(IDirect3D9 *d3d9,
                  IDirect3DDevice9 *device,
                  D3DDEVTYPE deviceType,
                  UINT adapter,
                  gl::Caps *caps,
                  gl::TextureCapsMap *textureCapsMap,
                  gl::Extensions *extensions,
                  gl::Limitations *limitations)
{
    D3DCAPS9 deviceCaps;
    if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps)))
    {
        // Can't continue with out device caps
        return;
    }

    D3DDISPLAYMODE currentDisplayMode;
    d3d9->GetAdapterDisplayMode(adapter, &currentDisplayMode);

    GLuint maxSamples = 0;
    for (GLenum internalFormat : gl::GetAllSizedInternalFormats())
    {
        gl::TextureCaps textureCaps = GenerateTextureFormatCaps(internalFormat, d3d9, deviceType,
                                                                adapter, currentDisplayMode.Format);
        textureCapsMap->insert(internalFormat, textureCaps);

        maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());

        if (gl::GetSizedInternalFormatInfo(internalFormat).compressed)
        {
            caps->compressedTextureFormats.push_back(internalFormat);
        }
    }

    // GL core feature limits
    caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());

    // 3D textures are unimplemented in D3D9
    caps->max3DTextureSize = 1;

    // Only one limit in GL, use the minimum dimension
    caps->max2DTextureSize = std::min(deviceCaps.MaxTextureWidth, deviceCaps.MaxTextureHeight);

    // D3D treats cube maps as a special case of 2D textures
    caps->maxCubeMapTextureSize = caps->max2DTextureSize;

    // Array textures are not available in D3D9
    caps->maxArrayTextureLayers = 1;

    // ES3-only feature
    caps->maxLODBias = 0.0f;

    // No specific limits on render target size, maximum 2D texture size is equivalent
    caps->maxRenderbufferSize = caps->max2DTextureSize;

    // Draw buffers are not supported in D3D9
    caps->maxDrawBuffers      = 1;
    caps->maxColorAttachments = 1;

    // No specific limits on viewport size, maximum 2D texture size is equivalent
    caps->maxViewportWidth  = caps->max2DTextureSize;
    caps->maxViewportHeight = caps->maxViewportWidth;

    // Point size is clamped to 1.0f when the shader model is less than 3
    caps->minAliasedPointSize = 1.0f;
    caps->maxAliasedPointSize =
        ((D3DSHADER_VERSION_MAJOR(deviceCaps.PixelShaderVersion) >= 3) ? deviceCaps.MaxPointSize
                                                                       : 1.0f);

    // Wide lines not supported
    caps->minAliasedLineWidth = 1.0f;
    caps->maxAliasedLineWidth = 1.0f;

    // Primitive count limits (unused in ES2)
    caps->maxElementsIndices  = 0;
    caps->maxElementsVertices = 0;

    // Program and shader binary formats (no supported shader binary formats)
    caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);

    caps->vertexHighpFloat.setIEEEFloat();
    caps->vertexMediumpFloat.setIEEEFloat();
    caps->vertexLowpFloat.setIEEEFloat();
    caps->fragmentHighpFloat.setIEEEFloat();
    caps->fragmentMediumpFloat.setIEEEFloat();
    caps->fragmentLowpFloat.setIEEEFloat();

    // Some (most) hardware only supports single-precision floating-point numbers,
    // which can accurately represent integers up to +/-16777216
    caps->vertexHighpInt.setSimulatedInt(24);
    caps->vertexMediumpInt.setSimulatedInt(24);
    caps->vertexLowpInt.setSimulatedInt(24);
    caps->fragmentHighpInt.setSimulatedInt(24);
    caps->fragmentMediumpInt.setSimulatedInt(24);
    caps->fragmentLowpInt.setSimulatedInt(24);

    // WaitSync is ES3-only, set to zero
    caps->maxServerWaitTimeout = 0;

    // Vertex shader limits
    caps->maxVertexAttributes = 16;
    // Vertex Attrib Binding not supported.
    caps->maxVertexAttribBindings = caps->maxVertexAttributes;

    const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256;
    caps->maxVertexUniformVectors =
        MAX_VERTEX_CONSTANT_VECTORS_D3D9 - GetReservedVertexUniformVectors();
    caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4;

    caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] = 0;

    // SM3 only supports 12 output variables, but the special 12th register is only for PSIZE.
    const unsigned int MAX_VERTEX_OUTPUT_VECTORS_SM3 = 12 - GetReservedVaryingVectors();
    const unsigned int MAX_VERTEX_OUTPUT_VECTORS_SM2 = 10 - GetReservedVaryingVectors();
    caps->maxVertexOutputComponents =
        ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3
                                                                 : MAX_VERTEX_OUTPUT_VECTORS_SM2) *
        4;

    // Only Direct3D 10 ready devices support all the necessary vertex texture formats.
    // We test this using D3D9 by checking support for the R16F format.
    if (deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0) &&
        SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, currentDisplayMode.Format,
                                          D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE,
                                          D3DFMT_R16F)))
    {
        const size_t MAX_TEXTURE_IMAGE_UNITS_VTF_SM3             = 4;
        caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = MAX_TEXTURE_IMAGE_UNITS_VTF_SM3;
    }
    else
    {
        caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = 0;
    }

    // Fragment shader limits
    const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224;
    const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32;
    caps->maxFragmentUniformVectors =
        ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3
                                                                : MAX_PIXEL_CONSTANT_VECTORS_SM2) -
        GetReservedFragmentUniformVectors();
    caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
        caps->maxFragmentUniformVectors * 4;
    caps->maxShaderUniformBlocks[gl::ShaderType::Fragment]     = 0;
    caps->maxFragmentInputComponents                           = caps->maxVertexOutputComponents;
    caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] = 16;
    caps->minProgramTexelOffset                                = 0;
    caps->maxProgramTexelOffset                                = 0;

    // Aggregate shader limits (unused in ES2)
    caps->maxUniformBufferBindings                                     = 0;
    caps->maxUniformBlockSize                                          = 0;
    caps->uniformBufferOffsetAlignment                                 = 0;
    caps->maxCombinedUniformBlocks                                     = 0;
    caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex]   = 0;
    caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] = 0;
    caps->maxVaryingComponents                                         = 0;

    // Aggregate shader limits
    caps->maxVaryingVectors            = caps->maxVertexOutputComponents / 4;
    caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] +
                                         caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment];

    // Transform feedback limits
    caps->maxTransformFeedbackInterleavedComponents = 0;
    caps->maxTransformFeedbackSeparateAttributes    = 0;
    caps->maxTransformFeedbackSeparateComponents    = 0;

    // Multisample limits
    caps->maxSamples = maxSamples;

    // GL extension support
    extensions->setTextureExtensionSupport(*textureCapsMap);
    extensions->elementIndexUint  = deviceCaps.MaxVertexIndex >= (1 << 16);
    extensions->getProgramBinary  = true;
    extensions->rgb8rgba8         = true;
    extensions->readFormatBGRA    = true;
    extensions->pixelBufferObject = false;
    extensions->mapBuffer         = false;
    extensions->mapBufferRange    = false;

    // textureRG is emulated and not performant.
    extensions->textureRG = false;

    D3DADAPTER_IDENTIFIER9 adapterId = {};
    if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId)))
    {
        // ATI cards on XP have problems with non-power-of-two textures.
        extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
                                  !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
                                  !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
                                  !(!isWindowsVistaOrGreater() && IsAMD(adapterId.VendorId));

        // Disable depth texture support on AMD cards (See ANGLE issue 839)
        if (IsAMD(adapterId.VendorId))
        {
            extensions->depthTextures = false;
        }
    }
    else
    {
        extensions->textureNPOT = false;
    }

    extensions->drawBuffers    = false;
    extensions->textureStorage = true;

    // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per
    // the spec
    extensions->textureFilterAnisotropic =
        (deviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && deviceCaps.MaxAnisotropy >= 2;
    extensions->maxTextureAnisotropy = static_cast<GLfloat>(deviceCaps.MaxAnisotropy);

    // Check occlusion query support by trying to create one
    IDirect3DQuery9 *occlusionQuery = nullptr;
    extensions->occlusionQueryBoolean =
        SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery;
    SafeRelease(occlusionQuery);

    // Check event query support by trying to create one
    IDirect3DQuery9 *eventQuery = nullptr;
    extensions->fence =
        SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery;
    SafeRelease(eventQuery);

    extensions->disjointTimerQuery = false;
    extensions->robustness         = true;
    // It seems that only DirectX 10 and higher enforce the well-defined behavior of always
    // returning zero values when out-of-bounds reads. See
    // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt
    extensions->robustBufferAccessBehavior = false;
    extensions->blendMinMax                = true;
    extensions->framebufferBlit            = true;
    extensions->framebufferMultisample     = true;
    extensions->instancedArrays            = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
    extensions->packReverseRowOrder        = true;
    extensions->standardDerivatives =
        (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
    extensions->shaderTextureLOD       = true;
    extensions->fragDepth              = true;
    extensions->textureUsage           = true;
    extensions->translatedShaderSource = true;
    extensions->fboRenderMipmap        = false;
    extensions->discardFramebuffer     = false;  // It would be valid to set this to true, since
                                                 // glDiscardFramebufferEXT is just a hint
    extensions->colorBufferFloat   = false;
    extensions->debugMarker        = true;
    extensions->eglImage           = true;
    extensions->eglImageExternal   = true;
    extensions->unpackSubimage     = true;
    extensions->packSubimage       = true;
    extensions->syncQuery          = extensions->fence;
    extensions->copyTexture        = true;
    extensions->textureBorderClamp = true;

    // D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil
    // state.
    limitations->noSeparateStencilRefsAndMasks = true;

    // D3D9 shader models have limited support for looping, so the Appendix A
    // index/loop limitations are necessary. Workarounds that are needed to
    // support dynamic indexing of vectors on HLSL also don't work on D3D9.
    limitations->shadersRequireIndexedLoopValidation = true;

    // D3D9 cannot support constant color and alpha blend funcs together
    limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true;

    // D3D9 cannot support packing more than one variable to a single varying.
    // TODO(jmadill): Implement more sophisticated component packing in D3D9.
    limitations->noFlexibleVaryingPacking = true;
}
Example #10
0
	bool Init(IDirect3DDevice9 *d3dev)
	{
		D3DXEFFECT_DESC		desc;
		
		{
			D3DCAPS9 hal_caps;
			ZeroMemory(&hal_caps, sizeof(D3DCAPS9));
			if(d3dev->GetDeviceCaps(&hal_caps)!=S_OK)
				return false;
			UINT ps_major = D3DSHADER_VERSION_MAJOR(hal_caps.PixelShaderVersion);
			UINT ps_minor = D3DSHADER_VERSION_MAJOR(hal_caps.PixelShaderVersion);
			if(ps_major<2)
				return false;
 		}

		{
			LPD3DXBUFFER		pErrorMsgs = NULL;
			if(FAILED(D3DXCreateEffectFromFile(d3dev, filename, NULL, NULL, 0, NULL, &effect, &pErrorMsgs)))
			{
				if(pErrorMsgs != NULL)
				{
					unsigned char* message = (unsigned char*)pErrorMsgs->GetBufferPointer();
					{ // save error log
						char					path[ALIB_PATH];
						FILE					*fic;
						strcpy(path, root);
						strcat(path, "\\shaders\\_errors.txt");
						fic=fopen(path, "w");
						if(fic)
						{
							fprintf(fic, (char *)message);
							fclose(fic);
						}
					}
				}
				return false;
			}
		}
		
		if(FAILED(effect->GetDesc(&desc)))
			return false;
		
		{
			int					i;
			for(i=0; i<(int)desc.Parameters; i++)
			{
				D3DXHANDLE			hp=effect->GetParameter(NULL, i);
				D3DXPARAMETER_DESC	descp;
				
				if(!hp)
					continue;
				
				if(FAILED(effect->GetParameterDesc(hp, &descp)))
					continue;
					
				if((descp.Class==D3DXPC_VECTOR)&&(descp.Type==D3DXPT_FLOAT))
				{
					if(!strcmp(descp.Name, "color"))
					{
						hColor=hp;
						hp=NULL;
					}
				}
				else if((descp.Class==D3DXPC_SCALAR)&&(descp.Type==D3DXPT_FLOAT))
				{	
					if(!strcmp(descp.Name, "power"))
						hPower=hp;
				}
			}
		}

		if(FAILED(d3dev->CreateVertexBuffer(VBUFSIZE, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &vb, NULL)))
			return false;

		return true;
	}
Example #11
0
bool Screen3D::Create(HWND hwnd, DisplayModeInfo& m, float viewdistance)
{

	if( NULL == ( D3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
	    return false;


	D3DDISPLAYMODE d3ddm;
	if( FAILED( D3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
		return false;
	
	hWnd = hwnd;

	
	//Get the client rectangle dimensions  of the window.
	RECT WindowRect;
	GetClientRect(hwnd, &WindowRect);

	if( m.Width == -1 || m.Height == -1)
	{
		DisplayMode.Width  = WindowRect.right - WindowRect.left;
		DisplayMode.Height = WindowRect.bottom - WindowRect.top;
	}
	else
	{
		DisplayMode.Width  = m.Width;
		DisplayMode.Height = m.Height;
	}

	OutputMessage( "Attempting Resolution: %dx%d\n", DisplayMode.Width, DisplayMode.Height);

    // Set up the structure used to create the D3DDevice. 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
	if ( DisplayMode.Fullscreen )
	{
		d3dpp.Windowed   = FALSE; 
		d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //D3DSWAPEFFECT_COPY ;
		d3dpp.PresentationInterval =  D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT_INTERVAL_ONE  ;
		d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT ;
	}
	else
	{
		d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
		d3dpp.Windowed = TRUE; 
		d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	}
    
	d3dpp.BackBufferWidth  = DisplayMode.Width ;
	d3dpp.BackBufferHeight = DisplayMode.Height;
    d3dpp.BackBufferFormat = d3ddm.Format;
	d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

	
	OutputMessage( "BackBuffer: %d\n", d3ddm.Format );

	//Get the depth/stencil caps

	//check for 32bit depth buffer
	if(  SUCCEEDED ( D3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, 
		D3DRTYPE_SURFACE, D3DFMT_D32) ))
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
	}

	//second choice is 24bit buffer with 8 bit stencil
	else if(  SUCCEEDED ( D3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, 
		D3DRTYPE_SURFACE, D3DFMT_D24S8) ))
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
	}

	//third  choice is 24bit buffer with 4 bit stencil
	else if(  SUCCEEDED ( D3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, 
		D3DRTYPE_SURFACE, D3DFMT_D24X4S4) ))
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D24X4S4;
	}

	//fourth choice is 24bit buffer with 8 bits wasted
	else if(  SUCCEEDED ( D3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, 
		D3DRTYPE_SURFACE, D3DFMT_D24X8) ))
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
	}

	//fifth choice is 16bit buffer
	else if(  SUCCEEDED ( D3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, 
		D3DRTYPE_SURFACE, D3DFMT_D16) ) )
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	}

	//last choice is 15bit depth buffer with 1 bit stencil
	else if(  SUCCEEDED ( D3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, 
		D3DRTYPE_SURFACE, D3DFMT_D15S1) ) )
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D15S1;
	}

	OutputMessage( "DepthStencil: %d\n", d3dpp.AutoDepthStencilFormat );
	

    // Create the D3DDevice
	HRESULT hr;
	DWORD VertexFlags=0;
	if(true)
		VertexFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		VertexFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;


	// Set default settings
	//UINT AdapterToUse=D3DADAPTER_DEFAULT; //D3D->GetAdapterCount()-1
	//D3DDEVTYPE DeviceType=D3DDEVTYPE_HAL; //D3DDEVTYPE_REF
#ifdef NVPERFHUD
	UINT AdapterToUse=D3D->GetAdapterCount()-1;
	D3DDEVTYPE DeviceType=D3DDEVTYPE_REF;
#else
	UINT AdapterToUse=D3DADAPTER_DEFAULT; //D3D->GetAdapterCount()-1
	D3DDEVTYPE DeviceType=D3DDEVTYPE_HAL; //D3DDEVTYPE_REF
#endif

	// Look for 'NVIDIA NVPerfHUD' adapter
	// If it is present, override default settings
	for (UINT Adapter=0;Adapter<D3D->GetAdapterCount();Adapter++)
	{
		D3DADAPTER_IDENTIFIER9 Identifier;
		HRESULT Res;
		Res = D3D->GetAdapterIdentifier(Adapter,0,&Identifier);
		if (strcmp(Identifier.Description,"NVIDIA NVPerfHUD") == 0)
		{
			AdapterToUse=Adapter;
			DeviceType=D3DDEVTYPE_REF;
			break;
		}
	}


    if( FAILED( hr = D3D->CreateDevice(
								AdapterToUse,//D3DADAPTER_DEFAULT,
								DeviceType,//D3DDEVTYPE_HAL, 
								hwnd,
								VertexFlags ,
								&d3dpp, 
								&D3DDevice 
								)
		) )
    {
		OutputDXError( hr, "D3D Device Init Failed ");
		return false;
    }
	else
	{

		//We have a mixed device, so figure out the level of T&L support
		D3DCAPS9 tlcaps;
		D3DDevice->GetDeviceCaps(&tlcaps);       // initialize m_pd3dDevice before using

		//check the shader version
		if(	D3DSHADER_VERSION_MAJOR( tlcaps.VertexShaderVersion ) < 1 ) 
			TLSupport = S3D_STANDARD;

		//Major version is 1, so check minor versions
		else if(D3DSHADER_VERSION_MINOR( tlcaps.VertexShaderVersion ) < 1 ) 
			TLSupport = S3D_VS_1_0; //Vertex shader 1.0
		else
			TLSupport = S3D_VS_1_1; //Vertex shader 1.1 or above
	}


	//set up the projection matrix
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, RADIAN(60), (float)DisplayMode.Width/(float)DisplayMode.Height, 1.0f, viewdistance );
    D3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );

	//figure out the field of view
	CalculateFOV();


    // initial render state
    D3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
    D3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
    D3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE  );

	D3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
    D3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    D3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    D3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
	D3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	D3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

	SetLinearTextureFiltering();
    	
	//init the texture manager
	TM.Init(this);
	TM.RestoreTextures();

	InitialAvailableMem = D3DDevice->GetAvailableTextureMem();

	//Init the font manager
	FM.Init( *this );
	//return OK
	return true;

}
void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps,
                  gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
{
    D3DCAPS9 deviceCaps;
    if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps)))
    {
        // Can't continue with out device caps
        return;
    }

    D3DDISPLAYMODE currentDisplayMode;
    d3d9->GetAdapterDisplayMode(adapter, &currentDisplayMode);

    GLuint maxSamples = 0;
    const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
    for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
    {
        gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter,
                                                                currentDisplayMode.Format);
        textureCapsMap->insert(*internalFormat, textureCaps);

        maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());

        if (gl::GetInternalFormatInfo(*internalFormat).compressed)
        {
            caps->compressedTextureFormats.push_back(*internalFormat);
        }
    }

    // GL core feature limits
    caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());

    // 3D textures are unimplemented in D3D9
    caps->max3DTextureSize = 1;

    // Only one limit in GL, use the minimum dimension
    caps->max2DTextureSize = std::min(deviceCaps.MaxTextureWidth, deviceCaps.MaxTextureHeight);

    // D3D treats cube maps as a special case of 2D textures
    caps->maxCubeMapTextureSize = caps->max2DTextureSize;

    // Array textures are not available in D3D9
    caps->maxArrayTextureLayers = 1;

    // ES3-only feature
    caps->maxLODBias = 0.0f;

    // No specific limits on render target size, maximum 2D texture size is equivalent
    caps->maxRenderbufferSize = caps->max2DTextureSize;

    // Draw buffers are not supported in D3D9
    caps->maxDrawBuffers = 1;
    caps->maxColorAttachments = 1;

    // No specific limits on viewport size, maximum 2D texture size is equivalent
    caps->maxViewportWidth = caps->max2DTextureSize;
    caps->maxViewportHeight = caps->maxViewportWidth;

    // Point size is clamped to 1.0f when the shader model is less than 3
    caps->minAliasedPointSize = 1.0f;
    caps->maxAliasedPointSize = ((D3DSHADER_VERSION_MAJOR(deviceCaps.PixelShaderVersion) >= 3) ? deviceCaps.MaxPointSize : 1.0f);

    // Wide lines not supported
    caps->minAliasedLineWidth = 1.0f;
    caps->maxAliasedLineWidth = 1.0f;

    // Primitive count limits (unused in ES2)
    caps->maxElementsIndices = 0;
    caps->maxElementsVertices = 0;

    // Program and shader binary formats (no supported shader binary formats)
    caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);

    caps->vertexHighpFloat.setIEEEFloat();
    caps->vertexMediumpFloat.setIEEEFloat();
    caps->vertexLowpFloat.setIEEEFloat();
    caps->fragmentHighpFloat.setIEEEFloat();
    caps->fragmentMediumpFloat.setIEEEFloat();
    caps->fragmentLowpFloat.setIEEEFloat();

    // Some (most) hardware only supports single-precision floating-point numbers,
    // which can accurately represent integers up to +/-16777216
    caps->vertexHighpInt.setSimulatedInt(24);
    caps->vertexMediumpInt.setSimulatedInt(24);
    caps->vertexLowpInt.setSimulatedInt(24);
    caps->fragmentHighpInt.setSimulatedInt(24);
    caps->fragmentMediumpInt.setSimulatedInt(24);
    caps->fragmentLowpInt.setSimulatedInt(24);

    // WaitSync is ES3-only, set to zero
    caps->maxServerWaitTimeout = 0;

    // Vertex shader limits
    caps->maxVertexAttributes = 16;

    const size_t reservedVertexUniformVectors = 2; // dx_ViewAdjust and dx_DepthRange.
    const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256;
    caps->maxVertexUniformVectors = MAX_VERTEX_CONSTANT_VECTORS_D3D9 - reservedVertexUniformVectors;
    caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4;

    caps->maxVertexUniformBlocks = 0;

    // SM3 only supports 11 output variables, with a special 12th register for PSIZE.
    const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 9;
    const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 7;
    caps->maxVertexOutputComponents = ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3
                                                                                               : MAX_VERTEX_OUTPUT_VECTORS_SM2) * 4;

    // Only Direct3D 10 ready devices support all the necessary vertex texture formats.
    // We test this using D3D9 by checking support for the R16F format.
    if (deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0) &&
        SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, currentDisplayMode.Format,
                                          D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)))
    {
        const size_t MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4;
        caps->maxVertexTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS_VTF_SM3;
    }
    else
    {
        caps->maxVertexTextureImageUnits = 0;
    }

    // Fragment shader limits
    const size_t reservedPixelUniformVectors = 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange.

    const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224;
    const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32;
    caps->maxFragmentUniformVectors = ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3
                                                                                              : MAX_PIXEL_CONSTANT_VECTORS_SM2) - reservedPixelUniformVectors;
    caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4;
    caps->maxFragmentUniformBlocks = 0;
    caps->maxFragmentInputComponents = caps->maxVertexOutputComponents;
    caps->maxTextureImageUnits = 16;
    caps->minProgramTexelOffset = 0;
    caps->maxProgramTexelOffset = 0;

    // Aggregate shader limits (unused in ES2)
    caps->maxUniformBufferBindings = 0;
    caps->maxUniformBlockSize = 0;
    caps->uniformBufferOffsetAlignment = 0;
    caps->maxCombinedUniformBlocks = 0;
    caps->maxCombinedVertexUniformComponents = 0;
    caps->maxCombinedFragmentUniformComponents = 0;
    caps->maxVaryingComponents = 0;

    // Aggregate shader limits
    caps->maxVaryingVectors = caps->maxVertexOutputComponents / 4;
    caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;

    // Transform feedback limits
    caps->maxTransformFeedbackInterleavedComponents = 0;
    caps->maxTransformFeedbackSeparateAttributes = 0;
    caps->maxTransformFeedbackSeparateComponents = 0;

    // Multisample limits
    caps->maxSamples = maxSamples;

    // GL extension support
    extensions->setTextureExtensionSupport(*textureCapsMap);
    extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16);
    extensions->getProgramBinary = true;
    extensions->rgb8rgba8 = true;
    extensions->readFormatBGRA = true;
    extensions->pixelBufferObject = false;
    extensions->mapBuffer = false;
    extensions->mapBufferRange = false;

    // textureRG is emulated and not performant.
    extensions->textureRG = false;

    D3DADAPTER_IDENTIFIER9 adapterId = {};
    if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId)))
    {
        // ATI cards on XP have problems with non-power-of-two textures.
        extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
                                      !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
                                      !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
                                      !(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);

        // Disable depth texture support on AMD cards (See ANGLE issue 839)
        if (adapterId.VendorId == VENDOR_ID_AMD)
        {
            extensions->depthTextures = false;
        }
    }
    else
    {
        extensions->textureNPOT = false;
    }

    extensions->drawBuffers = false;
    extensions->textureStorage = true;

    // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
    extensions->textureFilterAnisotropic = (deviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && deviceCaps.MaxAnisotropy >= 2;
    extensions->maxTextureAnisotropy = static_cast<GLfloat>(deviceCaps.MaxAnisotropy);

    // Check occlusion query support by trying to create one
    IDirect3DQuery9 *occlusionQuery = NULL;
    extensions->occlusionQueryBoolean = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery;
    SafeRelease(occlusionQuery);

    // Check event query support by trying to create one
    IDirect3DQuery9 *eventQuery = NULL;
    extensions->fence = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery;
    SafeRelease(eventQuery);

    extensions->timerQuery = false; // Unimplemented
    extensions->robustness = true;
    extensions->blendMinMax = true;
    extensions->framebufferBlit = true;
    extensions->framebufferMultisample = true;
    extensions->instancedArrays = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
    extensions->packReverseRowOrder = true;
    extensions->standardDerivatives = (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
    extensions->shaderTextureLOD = true;
    extensions->fragDepth = true;
    extensions->textureUsage = true;
    extensions->translatedShaderSource = true;
    extensions->fboRenderMipmap = false;
    extensions->discardFramebuffer = false; // It would be valid to set this to true, since glDiscardFramebufferEXT is just a hint
    extensions->colorBufferFloat = false;
    extensions->debugMarker = true;
}
Example #13
0
// Initialise runtime
bool CRuntime::Initialise(CRuntimeSetup* crSetup)
{
	// Start by getting and saving the CPU capabilities.
	DWORD cpuFeatures = GetCPUCaps();
	supportMMX = cpuFeatures & CPU_FEATURE_MMX;
	supportSSE = cpuFeatures & CPU_FEATURE_SSE;
	supportSSE2 = cpuFeatures & CPU_FEATURE_SSE2;

	// Construct requires MMX for collisions
#ifndef APPRUNTIME
	if (!supportMMX)
		throw runtime_error("Your CPU does not support MMX technology (it must be pretty old!).  Please buy a newer PC then try again!");

#endif

	// Save hInstance
	hInstance = crSetup->hInstance;

	CapReader.pRuntime = this;

	CreateTempDirectory();

	// Get app properties
	BYTE* pData;
	int dataSize;
	HGLOBAL hData = OpenResourceBinary(997, "APPBLOCK", pData, dataSize);
	CapReader.ReadAppProperties(pData, dataSize, props);
	FreeResource(hData);

	// Cannot use both multisampling and motion blur
#ifndef APPRUNTIME
	if (multisamples > 0 && motionBlur)
		throw runtime_error("Cannot enable both multisamples and motion blur.  Please change one of these settings.");
#endif

#ifdef PYTHON
	// Get python
	hData = OpenResourceBinary(992, "PYTHONLIBS", pData, dataSize);
	CapReader.ReadPythonResources(pData, dataSize);
	FreeResource(hData);
	if(!SearchPath(NULL, "python26.dll", NULL, 0, NULL, NULL))
		throw runtime_error("Python26.dll was not found and is required to run this application or feature.  Reinstalling the application "
								"may fix this problem.");
	Py_Initialize();
#endif

	// Get menu resources
	hData = OpenResourceBinary(993, "MENUBLOCK", pData, dataSize);
	CapReader.ReadMenuResources(pData, dataSize, menus);
	FreeResource(hData);

	crSetup->winWidth = props.winWidth;
	crSetup->winHeight = props.winHeight;
	crSetup->eyeDistance = props.eyeDistance;
	crSetup->screensaver = props.screensaver;
	fpsMode = props.fpsMode;
	userFps = props.fps;

	//if (disableWindowsKey)
	//	g_hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,  DisableWinKeyKeyboardProc, hInstance, 0);

#ifdef CONSTRUCT_DIRECTX9
	crSetup->display_params.fps_mode = props.fpsMode;
	crSetup->display_params.fullscreen = fullscreen = props.fullscreen;
	crSetup->display_params.backbuffer_width = props.winWidth;
	crSetup->display_params.backbuffer_height = props.winHeight;

	switch (multisamples) {
	case 0:	// Off
		crSetup->display_params.multisamples = 0;
		break;
	case 1: // 2x
		crSetup->display_params.multisamples = 2;
		break;
	case 2:	// 4x
		crSetup->display_params.multisamples = 4;
		break;
	case 3: // 8x
		crSetup->display_params.multisamples = 8;
		break;
	default:
		crSetup->display_params.multisamples = 0;
		break;
	}

	// PreInit gets the D3D caps and allows MakeWindows to create the correct number of windows to pass to Init()
	//Display.SetMultiMonitorMode(MMM_CLONE);
	//Display.PreInit();
	renderer.LoadD3D();
#endif

#ifndef CONSTRUCT_SDL
	// Create a window for the runtime
	if (!MakeWindows(crSetup))
		throw runtime_error("Cannot create window");
#else
	if (SDL_Init(SDL_INIT_VIDEO) < 0) 
		exit(1);

	// Register SDL_Quit to be called at exit; makes sure things are cleaned up when we quit.
	atexit(SDL_Quit);
    
	// Attempt to create window with 32bit pixels in hardware
	Display.screen = SDL_SetVideoMode(props.winWidth, props.winHeight, 32, SDL_HWSURFACE);
	SDL_SetAlpha(Display.screen, SDL_SRCALPHA, 255); // Set alpha to normal
#endif

	InitCommonControls();

	// The preview runtimes show the runtime in the title bar.
#ifdef CONSTRUCT_PREVIEW
	#ifdef CONSTRUCT_DIRECTX9
	props.appTitle += " (DX9 runtime)";
	#endif
	#ifdef APPRUNTIME
	props.appTitle += " (App runtime)";
	#endif
	#ifdef CONSTRUCT_SDL
	props.appTitle += " (SDL runtime)";
	#endif
#endif

#ifndef CONSTRUCT_SDL
	SetWindowText(hWnds.front(), props.appTitle);
#else
	SDL_WM_SetCaption(props.appTitle, NULL);
#endif

	// Restore mouse cursor from hourglass
	if (!props.screensaver)
		SetCursor(LoadCursor(NULL, IDC_ARROW));

	// Load a menu
	if (props.UseMenu)
		if (menus.size() != 0)
			SetMenu(hWnds.front(), menus[0]);

#ifndef APPRUNTIME
#ifndef CONSTRUCT_SDL
	// Direct-X setup
	crSetup->display_params.hWnds = hWnds;
	crSetup->display_params.hFocusWnd = hWnds.front();

	winWidthOffset = 0;
	winHeightOffset = 0;

	// Retrieve all display modes: can't set an invalid display mode size
	if (crSetup->display_params.fullscreen) {
		BOOL bRetVal;
		DEVMODE devMode;
		int iMode = 0;

		int wantedWidth = crSetup->display_params.backbuffer_width;
		int wantedHeight = crSetup->display_params.backbuffer_height;
		int bestWidth = 100000;
		int bestHeight = 100000;

		bool found = false;

		do
		{
			bRetVal = ::EnumDisplaySettings(NULL, iMode, &devMode);
			iMode++;

			if (bRetVal)
			{
				int curWidth = devMode.dmPelsWidth;
				int curHeight = devMode.dmPelsHeight;

				// Display mode found!
				if (curWidth == wantedWidth && curHeight == wantedHeight)
					found = true;

				// This display mode is big enough to fit the display in, but is smaller than the last best size
				if ((curWidth >= wantedWidth && curHeight >= wantedHeight)
					&& (curWidth < bestWidth && curHeight < bestHeight)) {
					bestWidth = curWidth;
					bestHeight = curHeight;
				}
			}
		}
		while (bRetVal);

		// Identical display mode not found: use next best that can fit it all on
		if (!found) {

			// Still 100000x100000: no resolution found that supports this
			if (bestWidth == 100000 || bestHeight == 100000)
				throw runtime_error("The display resolution required by this application is not supported.");

	#ifdef CONSTRUCT_PREVIEW
			CString msg;
			msg.Format("Switching to Fullscreen mode: Display mode %d x %d not supported, switching to next best %d x %d.\n\n"
				"The 'Window Width' and 'Window Height' values in Application Properties define the fullscreen resolution.",
				crSetup->display_params.backbuffer_width, crSetup->display_params.backbuffer_height, bestWidth, bestHeight);
			MessageBox(NULL, msg, "Fullscreen preview", MB_OK | MB_ICONEXCLAMATION);
	#endif

			crSetup->display_params.backbuffer_width = wantedWidth = bestWidth;
			crSetup->display_params.backbuffer_height = wantedHeight = bestHeight;
		}
	}

	// Set the eye distance before we initialize
	eyeDistance = crSetup->eyeDistance;
	renderer.SetEyeDistance(eyeDistance);

	// Start up the display engine
	//Display.Init(&(crSetup->d3dDisplaySetup));
	renderer.CreateDevice(crSetup->display_params);

	/*
	// No identical match for display mode
	if (crSetup->d3dDisplaySetup.resWidth != actualDisplayWidth || crSetup->d3dDisplaySetup.resHeight != actualDisplayHeight)
		if (tempDisplayTarget == unallocated_texture)
			tempDisplayTarget = CreateDisplayTargetTexture();

		winWidthOffset = (actualDisplayWidth - crSetup->d3dDisplaySetup.resWidth) / 2;
		winHeightOffset = (actualDisplayHeight - crSetup->d3dDisplaySetup.resHeight) / 2;
	}
	*/

	GetSwapChains();

	// Multi-monitor settings require the temp display target

	if (renderer.GetMultiMonitorMode() != cr::multimonitor_singlescreen) {
		if (tempDisplayTarget == unallocated_texture)
				tempDisplayTarget = CreateDisplayTargetTexture();
	}

	// Linear resizers
	if (props.sampler == 0) {
		renderer.SetSamplerState(cr::ss_magfilter, cr::ssv_point);
		renderer.SetSamplerState(cr::ss_minfilter, cr::ssv_point);
	}
	if (props.sampler == 1) {
		renderer.SetSamplerState(cr::ss_magfilter, cr::ssv_linear);
		renderer.SetSamplerState(cr::ss_minfilter, cr::ssv_linear);
	}

	// Premultiplied alpha mode
	renderer.SetAlphaBlending();

	// Runtime uses clamp-sampling
	renderer.SetSamplerState(cr::ss_addressu, cr::ssv_clamp);
	renderer.SetSamplerState(cr::ss_addressv, cr::ssv_clamp);

	// Create the multisampling target if one required
	//if (multisamples > 0)		// 0 is off
	//	multisampleTargets[0] = renderer.CreateRenderTargetTexture(crSetup->winWidth, crSetup->winHeight, cr::texture_format_a8r8g8b8, true);

#if defined(CONSTRUCT_DIRECTX9) && defined(CONSTRUCT_PREVIEW)
	// Handle shader simulation
	if (simShader != SS_NOSIM) {

		UINT ps_major = D3DSHADER_VERSION_MAJOR(renderer.GetCaps().PixelShaderVersion);
		UINT ps_minor = D3DSHADER_VERSION_MINOR(renderer.GetCaps().PixelShaderVersion);

		CString hardwarePS;
		hardwarePS.Format("%d.%d", ps_major, ps_minor);

		CString simulatedPS;

		switch (simShader) {
		case SS_PS14:
			simulatedPS = "1.4";
			break;
		case SS_PS11:
			simulatedPS = "1.1";
			break;
		case SS_PS00:
			simulatedPS = "0.0";
			break;
		}

		float ps_version = atof(hardwarePS);
		float sim_version = atof(simulatedPS);

		// If fullscreen MessageBox()'s won't work
		if (!fullscreen) {
		
			if (sim_version > ps_version) {
				CString msg;
				msg.Format("You have chosen to simulate a pixel shader version (PS %s) higher than your hardware supports (PS %s).  "
					"You can only simulate lower hardware capabilities.  The application will continue to use PS %s.",
					simulatedPS, hardwarePS, simulatedPS);
				MessageBox(NULL, msg, "Simulate shader", MB_OK | MB_ICONEXCLAMATION);
			}
			else if (sim_version == ps_version) {
				CString msg;
				msg.Format("You have chosen to simulate the same pixel shader version as your hardware supports (PS %s).  "
					"The application will continue normally.", hardwarePS);
				MessageBox(NULL, msg, "Simulate shader", MB_OK | MB_ICONINFORMATION);
			}
			else {
				CString msg;
				msg.Format("You are simulating pixel shader %s capabilites.  Your hardware supports pixel shader %s.",
					simulatedPS, hardwarePS);
				MessageBox(NULL, msg, "Simulate shader", MB_OK | MB_ICONEXCLAMATION);
			}

		}
	}
#endif // shader sims
#endif

	// Load the PNG image list
	hData = OpenResourceBinary(995, "IMAGEBLOCK", pData, dataSize);
	CapReader.ReadImageData(pData, dataSize, imagehandle_to_address);
	FreeResource(hData);

#ifdef CONSTRUCT_DIRECTX9
	// Initialise DirectInput
	if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
								IID_IDirectInput8, (void**)&dinput, NULL)))
		throw runtime_error("Failed to initialise DirectInput.  Please ensure you have DirectX 8 or above installed!");

	// Initialize the keyboard
	if (FAILED(dinput->CreateDevice(GUID_SysKeyboard, &d_keyboard, NULL)))
		throw runtime_error("Failed to initialise DirectInput.");
	if (FAILED(d_keyboard->SetDataFormat(&c_dfDIKeyboard)))
		throw runtime_error("Failed to initialise DirectInput.");

	if (FAILED(d_keyboard->SetCooperativeLevel(hWnds.front(), DISCL_BACKGROUND |
											 DISCL_NONEXCLUSIVE)))
		throw runtime_error("Failed to initialise DirectInput.");

	if (FAILED(d_keyboard->Acquire()))
		throw runtime_error("Failed to initialise DirectInput.");

	// initialize the mouse
	if (FAILED(dinput->CreateDevice(GUID_SysMouse, &d_mouse, NULL)))
		throw runtime_error("Failed to initialise DirectInput.");
	if (FAILED(d_mouse->SetCooperativeLevel(hWnds.front(), DISCL_BACKGROUND |
										  DISCL_NONEXCLUSIVE)))
		throw runtime_error("Failed to initialise DirectInput.");

	if (FAILED(d_mouse->SetDataFormat(&c_dfDIMouse)))
		throw runtime_error("Failed to initialise DirectInput.");

	if (FAILED(d_mouse->Acquire()))
		throw runtime_error("Failed to initialise DirectInput.");

	inputState.isDirectInput = true;

#endif
#endif //#ifndef APPRUNTIME

	// Save window dimensions
	winWidth = crSetup->winWidth;
	winHeight = crSetup->winHeight;
	RECT clientSize;
	GetClientRect(hWnds.front(), &clientSize);
	realWinWidth = clientSize.right - clientSize.left;
	realWinHeight = clientSize.bottom - clientSize.top;

	// Unpack dependencies before loading plugins
	UnpackDependencies();

	// Unpack the resource plugins to the temp dir and load them
	UnpackPlugins(1000);

	// Read the frame data
	hData = OpenResourceBinary(998, "LEVELBLOCK", pData, dataSize);
	CapReader.ReadFrameData(pData, dataSize);
	FreeResource(hData);

	// Map object type names to their pointers
	for (vector<CRunObjType*>::iterator i = objects.begin(); i != objects.end(); i++)
	{
		CString lowername = (*i)->Name;
		lowername.MakeLower();
		name_to_object[lowername] = *i;
	}

#ifdef CONSTRUCT_DEBUGGER
	// Create debugger once object types are known but before parsing event block (which may send logs)
	// Create invisible initially
	pDebug->Create();
	pDebug->ShowWindow(SW_HIDE);
#endif

	// Read the CAP event tree
	hData = OpenResourceBinary(999, "EVENTBLOCK", pData, dataSize);
	CapReader.ReadEventList(pData, dataSize);
	FreeResource(hData);

	// Iterate all events determining their modifiers
	vector<CRunLayout*>::iterator f = Frames.begin();
	const vector<CRunLayout*>::const_iterator Frames_end = Frames.end();

	for ( ; f != Frames_end; f++) {
		EventIterator e = (*f)->Events.begin();
		EventConstIterator Events_end = (*f)->Events.end();

		for ( ; e != Events_end; ++e) {

			// Recurse down tree finding SOL modifiers
			(*e)->GetSolModifiers(*f);

			// If this event line is a group, it can be marked as top level for optimisation
			if ((*e)->GetType() == EVENT_GROUP)
				((CEventGroup*)*e)->isTopLevel = true;
		}
	}

	// Initialise effects
#ifdef CONSTRUCT_DIRECTX9
	hData = OpenResourceBinary(994, "HLSL", pData, dataSize);
	CapReader.ReadHLSLData(pData, dataSize);
	FreeResource(hData);

	// If motionblur is required, set up the textures
	if (motionBlur) {

		InitMotionBlur();

	}

#endif //APPRUNTIME

	// Clock offset (timers relative to Run())
	clockOffset = clock();
	curFrame = 0;

	// Mark objects which are not to serialize
	CRunObjType* pNoSerialize = GetTypeFromName("No serialize");

	if (pNoSerialize) {
		if (!pNoSerialize->teams.empty()) {
			ObjTypeIterator t = pNoSerialize->teams.begin();
			ObjTypeIterator end = pNoSerialize->teams.end();

			for ( ; t != end; t++)
				(*t)->noSerialize = true;
		}		
	}

	// Set current frame
	CRunLayout* pFirstFrame = Frames.front();
	runningFrames.push_back(pFirstFrame);
	system.pLayout = pFirstFrame;
	pFirstFrame->systemDrawn = true;
	pFirstFrame->Load();

	// Load any other layouts which want their textures loaded on startup
	vector<CRunLayout*>::iterator ly = Frames.begin();
	ly++;	// already loaded 1st layout

	for ( ; ly != Frames.end(); ++ly) {
		if ((*ly)->texture_loading == CRunLayout::tl_load_on_app_start)
			(*ly)->LoadLayoutTextures();
		else if ((*ly)->texture_loading == CRunLayout::tl_use_app_setting && texture_loading == tl_load_on_app_start)
			(*ly)->LoadLayoutTextures();
	}

	// Directories exist etc. by now.
	completedInitialisation = true;

	// Initial frame mouse coord
	POINT mouse;
	GetCursorPos(&mouse);

	if (!fullscreen)
		ScreenToClient(hWnds.front(), &mouse);

	pFirstFrame->mouseX = mouse.x;
	pFirstFrame->mouseY = mouse.y;

	// Create initial frame objects (generatevent works)
	pFirstFrame->CreateInitialObjects();

	FlushDelayedObjects();

	system.changeResWidth = winWidth;
	system.changeResHeight = winHeight;

	// Start of Layout triggered only if not previewing another layout
	if (previewLayout <= 0)
		GenerateEvent(-1, SYSTEM_STARTOFFRAME, NULL);

#ifdef CONSTRUCT_DEBUGGER
	pDebug->ShowWindow(SW_SHOW);
	pDebug->SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
	pDebug->ModifyStyleEx(0, WS_EX_TOPMOST);
#endif

	// Previewing single layout?
	if (previewLayout > 0)		// if == 0, no need to jump anywhere, already on layout 1
		system.DoFrameChange(previewLayout, "none", 0);

	return true;
}
void hsG3DDeviceSelector::ITryDirect3DTnLDevice(D3DEnum_DeviceInfo* devInfo, hsG3DDeviceRecord& devRec)
{
    devRec.SetDeviceDesc(devInfo->fStrName);

    if( devInfo->fDDType == D3DDEVTYPE_REF )
        devRec.SetG3DHALorHEL( kHHD3DRefDev );
    else if( devInfo->fDDType == D3DDEVTYPE_HAL )
    {
        if( devInfo->fDDCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
        {
            devRec.SetG3DHALorHEL( kHHD3DTnLHalDev );
            devRec.SetCap( kCapsHWTransform );
        }
        else
            devRec.SetG3DHALorHEL( kHHD3DHALDev );
    }

    if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP )
        devRec.SetCap( kCapsCubicTextures );

    devRec.SetLayersAtOnce( devInfo->fDDCaps.MaxSimultaneousTextures );

    if( devInfo->fDDCaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR )
        devRec.SetCap( kCapsMipmap );
    if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP )
        devRec.SetCap( kCapsCubicMipmap );
    if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_PERSPECTIVE )
        devRec.SetCap(kCapsPerspective);
    if( devInfo->fIsHardware )
        devRec.SetCap( kCapsHardware );
    if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_DITHER )
        devRec.SetCap(kCapsDither);
    if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_WBUFFER )
        devRec.SetCap(kCapsWBuffer);
    if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE )
    {
        devRec.SetCap( kCapsFogLinear );
        devRec.SetCap( kCapsFogExp );
        devRec.SetCap( kCapsFogExp2 );
        devRec.SetCap( kCapsPixelFog );
    }
    else
    {
        devRec.SetCap( kCapsFogLinear );
    }
    if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE )
        devRec.SetCap( kCapsFogRange );

    if( devInfo->fDDCaps.MaxAnisotropy <= 1 )
        devRec.SetMaxAnisotropicSamples( 0 );
    else
        devRec.SetMaxAnisotropicSamples( (uint8_t)devInfo->fDDCaps.MaxAnisotropy );

    if (D3DSHADER_VERSION_MAJOR(devInfo->fDDCaps.PixelShaderVersion) > 0)
        devRec.SetCap(kCapsPixelShader);

    /// Assume these by default
    devRec.SetCap( kCapsCompressTextures );
    devRec.SetCap( kCapsDoesSmallTextures );

#if 1 // mf - want to leave this one off by default
    //  if( devInfo->fCanAntialias )
    //      devRec.SetCap( kCapsAntiAlias );
#endif // mf - want to leave this one off by default

    hsG3DDeviceMode devMode;
    int i, j;

    const struct
    {
        D3DFORMAT fmt;
        uint16_t depth;
    } depths[] = { { D3DFMT_D16, 0x0010 }, { D3DFMT_D24X8, 0x0018 }, { D3DFMT_D32, 0x0020 },
        { D3DFMT_D15S1, 0x010f }, { D3DFMT_D24X4S4, 0x0418 }, { D3DFMT_D24S8, 0x0818 }, { D3DFMT_UNKNOWN, 0 }
    };

    for( i = 0; i < devInfo->fModes.GetCount(); i++ )
    {
        D3DEnum_ModeInfo* modeInfo = &devInfo->fModes[i];

        devMode.Clear();
        devMode.SetWidth( modeInfo->fDDmode.Width );
        devMode.SetHeight( modeInfo->fDDmode.Height );
        devMode.SetColorDepth( modeInfo->fBitDepth );

        if( modeInfo->fCanRenderToCubic )
            devMode.SetCanRenderToCubics( true );
        else
            devMode.SetCanRenderToCubics( false );

        for( j = 0; depths[ j ].depth != 0; j++ )
        {
            if( modeInfo->fDepthFormats.Find( depths[ j ].fmt ) != modeInfo->fDepthFormats.kMissingIndex )
                devMode.AddZStencilDepth( depths[ j ].depth );
        }

        for( j = 2; j <= 16; j++ )
        {
            if( modeInfo->fFSAATypes.Find( (D3DMULTISAMPLE_TYPE)j ) != modeInfo->fFSAATypes.kMissingIndex )
                devMode.AddFSAAType( j );
        }

        devRec.GetModes().Append( devMode );
    }
}
Example #15
0
void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps,
                  gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
{
    D3DCAPS9 deviceCaps;
    if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps)))
    {
        // Can't continue with out device caps
        return;
    }

    D3DDISPLAYMODE currentDisplayMode;
    d3d9->GetAdapterDisplayMode(adapter, &currentDisplayMode);

    const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
    for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
    {
        gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter,
                                                                currentDisplayMode.Format);
        textureCapsMap->insert(*internalFormat, textureCaps);
    }

    // GL core feature limits
    caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());

    // 3D textures are unimplemented in D3D9
    caps->max3DTextureSize = 1;

    // Only one limit in GL, use the minimum dimension
    caps->max2DTextureSize = std::min(deviceCaps.MaxTextureWidth, deviceCaps.MaxTextureHeight);

    // D3D treats cube maps as a special case of 2D textures
    caps->maxCubeMapTextureSize = caps->max2DTextureSize;

    // Array textures are not available in D3D9
    caps->maxArrayTextureLayers = 1;

    // ES3-only feature
    caps->maxLODBias = 0.0f;

    // No specific limits on render target size, maximum 2D texture size is equivalent
    caps->maxRenderbufferSize = caps->max2DTextureSize;

    // Draw buffers are not supported in D3D9
    caps->maxDrawBuffers = 1;
    caps->maxColorAttachments = 1;

    // No specific limits on viewport size, maximum 2D texture size is equivalent
    caps->maxViewportWidth = caps->max2DTextureSize;
    caps->maxViewportHeight = caps->maxViewportWidth;

    // Point size is clamped to 1.0f when the shader model is less than 3
    caps->minAliasedPointSize = 1.0f;
    caps->maxAliasedPointSize = ((D3DSHADER_VERSION_MAJOR(deviceCaps.PixelShaderVersion) >= 3) ? deviceCaps.MaxPointSize : 1.0f);

    // Wide lines not supported
    caps->minAliasedLineWidth = 1.0f;
    caps->maxAliasedLineWidth = 1.0f;

    // GL extension support
    extensions->setTextureExtensionSupport(*textureCapsMap);
    extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16);
    extensions->packedDepthStencil = true;
    extensions->getProgramBinary = true;
    extensions->rgb8rgba8 = true;
    extensions->readFormatBGRA = true;
    extensions->pixelBufferObject = false;
    extensions->mapBuffer = false;
    extensions->mapBufferRange = false;

    // ATI cards on XP have problems with non-power-of-two textures.
    D3DADAPTER_IDENTIFIER9 adapterId = { 0 };
    if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId)))
    {
        extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
                                      !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
                                      !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
                                      !(isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);
    }
    else
    {
        extensions->textureNPOT = false;
    }

    extensions->drawBuffers = false;
    extensions->textureStorage = true;

    // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
    extensions->textureFilterAnisotropic = (deviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && deviceCaps.MaxAnisotropy >= 2;
    extensions->maxTextureAnisotropy = static_cast<GLfloat>(deviceCaps.MaxAnisotropy);

    // Check occlusion query support by trying to create one
    IDirect3DQuery9 *occlusionQuery = NULL;
    extensions->occlusionQueryBoolean = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery;
    SafeRelease(occlusionQuery);

    // Check event query support by trying to create one
    IDirect3DQuery9 *eventQuery = NULL;
    extensions->fence = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery;
    SafeRelease(eventQuery);

    extensions->timerQuery = false; // Unimplemented
    extensions->robustness = true;
    extensions->blendMinMax = true;
    extensions->framebufferBlit = true;
    extensions->framebufferMultisample = true;
    extensions->instancedArrays = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
    extensions->packReverseRowOrder = true;
    extensions->standardDerivatives = (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
    extensions->shaderTextureLOD = true;
    extensions->fragDepth = true;
    extensions->textureUsage = true;
    extensions->translatedShaderSource = true;
    extensions->colorBufferFloat = false;
}
Example #16
0
HRESULT CPixelShaderCompiler::InternalCompile(
    LPCSTR pSrcData,
    SIZE_T SrcDataSize,
    LPCSTR pSourceName,
    LPCSTR pEntrypoint,
    LPCSTR pProfile,
    DWORD Flags,
    IDirect3DPixelShader9** ppPixelShader,
    CString* pDisasm,
    CString* pErrMsg)
{
    if (!m_pD3DCompile) {
        return E_FAIL;
    }

    if (pDisasm && !m_pD3DDisassemble) {
        return E_FAIL;
    }

    if (ppPixelShader && !m_pD3DDev) {
        return E_FAIL;
    }

    LPCSTR pSelProfile = pProfile;
    if (!pSelProfile || *pSelProfile == '\0') {
        D3DCAPS9 caps;
        if (m_pD3DDev && m_pD3DDev->GetDeviceCaps(&caps) == D3D_OK) {
            switch (D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion)) {
                case 2:
                    if (caps.PS20Caps.NumInstructionSlots < 512) {
                        pSelProfile = "ps_2_0";
                    } else if (caps.PS20Caps.Caps > 0) {
                        pSelProfile = "ps_2_a";
                    } else {
                        pSelProfile = "ps_2_b";
                    }
                    break;
                case 3:
                    pSelProfile = "ps_3_0";
                    break;
            }
        } else {
            ASSERT(FALSE);
        }
    }

    if (!pSelProfile || *pSelProfile == '\0') {
        return E_FAIL;
    }

    LPCSTR defProfile = "MPC_HC_SHADER_PROFILE";
    LPCSTR defProfileVal;
    if (!strcmp(pSelProfile, "ps_2_0")) {
        defProfileVal = "0";
    } else if (!strcmp(pSelProfile, "ps_2_b")) {
        defProfileVal = "1";
    } else if (!strcmp(pSelProfile, "ps_2_a") || !strcmp(pSelProfile, "ps_2_sw")) {
        defProfileVal = "2";
    } else if (!strcmp(pSelProfile, "ps_3_0") || !strcmp(pSelProfile, "ps_3_sw")) {
        defProfileVal = "3";
    } else {
        defProfileVal = "-1";
    }

    if (ppPixelShader && SUCCEEDED(m_Cache.CreatePixelShader(defProfileVal, pSrcData, SrcDataSize, ppPixelShader))) {
        return S_OK;
    }

    D3D_SHADER_MACRO macros[] = { { defProfile, defProfileVal }, { 0 } };

    CComPtr<ID3DBlob> pShaderBlob, pErrorBlob;
    HRESULT hr = m_pD3DCompile(pSrcData, SrcDataSize, pSourceName, macros, nullptr, pEntrypoint,
                               pSelProfile, Flags, 0, &pShaderBlob, &pErrorBlob);

    if (pErrMsg) {
        CStringA msg;
        if (pErrorBlob) {
            auto len = pErrorBlob->GetBufferSize();
            VERIFY(memcpy_s(msg.GetBufferSetLength((int)len), len, pErrorBlob->GetBufferPointer(), len) == 0);
            msg.ReleaseBuffer((int)len);
        }
        *pErrMsg = msg;
    }

    if (FAILED(hr)) {
        return hr;
    }

    if (ppPixelShader) {
        hr = m_pD3DDev->CreatePixelShader((DWORD*)pShaderBlob->GetBufferPointer(), ppPixelShader);
        if (FAILED(hr)) {
            return hr;
        }

        m_Cache.SavePixelShader(defProfileVal, pSrcData, SrcDataSize,
                                (void*)pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize());
    }

    if (pDisasm) {
        CComPtr<ID3DBlob> pDisasmBlob;
        CStringA defs;
        for (auto pMacro = macros; pMacro && pMacro->Name && pMacro->Definition; pMacro++) {
            defs.Append("// #define ");
            defs.Append(pMacro->Name);
            defs.Append(" ");
            defs.Append(pMacro->Definition);
            defs.Append("\n");
        }
        hr = m_pD3DDisassemble(pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(),
                               0, defs, &pDisasmBlob);
        if (SUCCEEDED(hr)) {
            CStringA disasm;
            auto len = pDisasmBlob->GetBufferSize();
            VERIFY(memcpy_s(disasm.GetBufferSetLength((int)len), len, pDisasmBlob->GetBufferPointer(), len) == 0);
            disasm.ReleaseBuffer((int)len);
            *pDisasm = disasm;
        }
    }

    return S_OK;
}
Example #17
0
void PropertiesBar::DoAppProperties()
{
	CExtPropertyItem* pRoot;
	CExtPropertyItem* pItem;
	CExtGridCellString* pString;
	CExtGridCellDropListComboBox* pCombo;
	CExtGridCellNumber* pNumber;
	CExtGridCellCheckBox* pCheck;
	CExtGridCellHyperLinkEx* pLink;

	CApplication* app = m_pCurrentApplication;

	//////////////////////////
	// INFORMATION CATEGORY ///////////////////////////////////////////////////
	pRoot = InsertCategory(PROPERTIES_INFORMATION, PROPERTIES_DESC_INFORMATION);

	pItem = InsertAppItem(PROPERTIES_CREATOR, PROPERTIES_DESC_CREATOR, pRoot);
	pString = GetEdit(pItem);
	pString->TextSet(app->file_information.creator);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem(PROPERTIES_TITLE, PROPERTIES_DESC_TITLE, pRoot);
	pString = GetEdit(pItem);
	pString->TextSet(app->file_information.name);
	pItem->ValueActiveFromDefault();

	/////////////////////
	// WINDOW CATEGORY ///////////////////////////////////////////////////
	pRoot = InsertCategory(PROPERTIES_WINDOW, PROPERTIES_DESC_WINDOW);

	pItem = InsertAppItem("Menu", "Show a menu by default.", pRoot);
	pCheck = GetCheckBox(pItem);
	pCheck->SetCheck(app->window_information.show_menu);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem("Caption", "Have a window titlebar and border.", pRoot);
	pCheck = GetCheckBox(pItem);
	pCheck->SetCheck(app->window_information.caption);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem("Resizing", "Make the window resizable and decide what happens when the window is resized.", pRoot);
	pCombo = GetCombo(pItem);
		pCombo->InsertString("Disabled");
		pCombo->InsertString("Show more window content");

		// Stretch option only available to DX games
	if (m_pCurrentApplication->runtime == CApplication::rt_directx)
		pCombo->InsertString("Stretch window content");

		pCombo->SetCurSel(app->window_information.resizable);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem("Minimize Box", "Show a minimize box on the application window.", pRoot);
	pCheck = GetCheckBox(pItem);
	pCheck->SetCheck(app->window_information.minimize_box);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem("Maximize Box", "Show a maximize box on the application window.", pRoot);
	pCheck = GetCheckBox(pItem);
	pCheck->SetCheck(app->window_information.maximize_box);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem(PROPERTIES_WINDOWWIDTH, PROPERTIES_DESC_WINDOWWIDTH, pRoot);
	pNumber = GetInteger(pItem);
	pNumber->_VariantAssign(app->window_information.window_width);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem(PROPERTIES_WINDOWHEIGHT, PROPERTIES_DESC_WINDOWHEIGHT, pRoot);
	pNumber = GetInteger(pItem);
	pNumber->_VariantAssign(app->window_information.window_height);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem("Eye Distance (3d)", "If you use 3d box or a 3d mesh distortion, this value determines how far back the eye of the viewer is from the screen", pRoot);
	pNumber = GetFloat(pItem);
	pNumber->_VariantAssign(app->window_information.eye_distance);
	pItem->ValueActiveFromDefault();


	//////////////////////
	// RUNTIME CATEGORY ///////////////////////////////////////////////////
	pRoot = InsertCategory(PROPERTIES_CRUNTIME, PROPERTIES_DESC_CRUNTIME);

	pItem = InsertAppItem("Enable Scripting", "Enable Python scripting.  Requires Python26.dll redistribution.", pRoot);
	pCheck = GetCheckBox(pItem);
	pCheck->SetCheck(app->game_information.use_python);
	pItem->ValueActiveFromDefault();

	if (m_pCurrentApplication->runtime == CApplication::rt_directx)
	{
		pItem = InsertAppItem(PROPERTIES_FRAMERATEMODE, PROPERTIES_DESC_FRAMERATEMODE, pRoot);
		pCombo = GetCombo(pItem);
		pCombo->InsertString(PROPERTIES_VSYNCED);
		pCombo->InsertString(PROPERTIES_UNLIMITED);
		pCombo->InsertString(PROPERTIES_FIXED);
		pCombo->SetCurSel(app->game_information.fps_mode);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem(PROPERTIES_FPS, PROPERTIES_DESC_FPS, pRoot);
		pNumber = GetInteger(pItem);
		pNumber->_VariantAssign(app->game_information.fps);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem("FPS in caption", "Show the framerate in the window caption.", pRoot);
		pCheck = GetCheckBox(pItem);
		pCheck->SetCheck(app->game_information.fps_in_caption);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem(PROPERTIES_FULLSCREEN, PROPERTIES_DESC_FULLSCREEN, pRoot);
		pCheck = GetCheckBox(pItem);
		pCheck->SetCheck(app->game_information.fullscreen);
		pItem->ValueActiveFromDefault();
	}

	pItem = InsertAppItem(PROPERTIES_RUNTIME, PROPERTIES_DESC_RUNTIME, pRoot);
	pCombo = GetCombo(pItem);
	pCombo->InsertString(PROPERTIES_APPLICATION);
	pCombo->InsertString(_T("Direct-X 9"));
	pCombo->SetCurSel(app->runtime);
	pItem->ValueActiveFromDefault();

	// SDL not yet implemented -AG
	/*
	if (m_pCurrentApplication->m_Runtime == RUNTIME_SDL) 
	{
		pItem = InsertAppItem(_T("Use hardware"), _T("SDL will use hardware acceleration where available."), pRoot);
		pCheck = GetCheckBox(pItem);
		pCheck->SetCheck(m_pCurrentApplication->m_SDLUseHardware);
		pItem->ValueActiveFromDefault();
	}
	*/

	if (m_pCurrentApplication->runtime == CApplication::rt_directx) 
	{
		pItem = InsertAppItem(_T("Load Textures"), _T("Specify when object textures are loaded in to VRAM."), pRoot);
		pCombo = GetCombo(pItem);
		pCombo->InsertString(_T("On application start"));
		pCombo->InsertString(_T("Per layout"));
		pCombo->SetCurSel((int)app->game_information.texture_loading);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem(_T("Sampling"), _T("Specify point or linear sampling for rotations and scaling."), pRoot);
		pCombo = GetCombo(pItem);
		pCombo->InsertString(_T("Point"));
		pCombo->InsertString(_T("Linear"));
		pCombo->SetCurSel((int)app->game_information.sampler);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem(_T("Text rendering"), _T("Specify the quality of the text rendering."), pRoot);
		pCombo = GetCombo(pItem);
		pCombo->InsertString(_T("Aliased"));
		pCombo->InsertString(_T("Antialiased"));
		pCombo->InsertString(_T("Cleartype"));
		pCombo->SetCurSel((int)app->game_information.text_rendering_mode);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem(_T("Multisampling"), _T("Antialiasing of object edges"), pRoot);
		pCombo = GetCombo(pItem);
		pCombo->InsertString(_T("Off"));
		pCombo->InsertString(_T("2x"));
		pCombo->InsertString(_T("4x"));
		pCombo->InsertString(_T("8x"));
		pCombo->SetCurSel((int)app->game_information.multisamples);
		pItem->ValueActiveFromDefault();
	}

	// Advanced timedelta settings subcategory
	pRoot = InsertCategory("Advanced", "Advanced runtime settings", pRoot);

	pItem = InsertAppItem("Minimum FPS", "Minimum framerate.  Game slows down below this point to compensate.", pRoot);
	pNumber = GetFloat(pItem);
	pNumber->_VariantAssign(app->game_information.minimum_fps);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem("Override TimeDelta", "Override the time delta such that a constant value is returned.", pRoot);
	pCheck = GetCheckBox(pItem);
	pCheck->SetCheck(app->game_information.override_timedelta);
	pItem->ValueActiveFromDefault();

	pItem = InsertAppItem("Timer FPS", "The intended framerate.  TimeDelta will evaluate to 1 divided by this value.", pRoot);
	pNumber = GetInteger(pItem);
	pNumber->_VariantAssign(app->game_information.time_delta_override);
	pItem->ValueActiveFromDefault();

	if (m_pCurrentApplication->runtime == CApplication::rt_directx)
	{
	
		pRoot = InsertCategory("Effects", "Settings and information about this application's pixel shaders and effects.");

		CString s;

		CD3DDisplay* pDisplay = m_pCurrentApplication->m_display;

		if (pDisplay != NULL) {

			// For version checking shaders
			UINT ps_major = D3DSHADER_VERSION_MAJOR(pDisplay->GetD3DCaps()->PixelShaderVersion);
			UINT ps_minor = D3DSHADER_VERSION_MINOR(pDisplay->GetD3DCaps()->PixelShaderVersion);
			s.Format("PS %d.%d", ps_major, ps_minor);
		}
		else
			s = "Unknown";

		pItem = InsertAppItem("Shader version", "Your computer's supported pixel shader version.", pRoot);
		pString = GetEdit(pItem);
		pString->ModifyStyle(__EGCS_READ_ONLY | __EGCS_NO_INPLACE_CONTROL);
		pString->TextSet(s);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem(_T("Run without PS"), _T("Allow effects not supported by hardware to be disabled, and continue running game."), pRoot);
		pCheck = GetCheckBox(pItem);
		pCheck->SetCheck(m_pCurrentApplication->game_information.run_without_ps);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem("Simulate shader", "Simulate limited pixel shader capability for testing.", pRoot);
		pCombo = GetCombo(pItem);
		pCombo->AddString("(no override)");
		pCombo->AddString("PS 1.4");
		pCombo->AddString("PS 1.1");
		pCombo->AddString("PS 0.0");
		pCombo->SetCurSel((int)m_pCurrentApplication->game_information.simulate_shaders);
		pItem->ValueActiveFromDefault();

		int MotionBlurCombo[] = {
			0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20
		};

		pItem = InsertAppItem("Motion Blur", "Enable a global motion blur effect at runtime.", pRoot);
		pCombo = GetCombo(pItem);
		pCombo->AddString("Off");
		pCombo->AddString("2x (lowest quality)");
		pCombo->AddString("3x");
		pCombo->AddString("4x");
		pCombo->AddString("5x (recommended)");
		pCombo->AddString("6x");
		pCombo->AddString("7x");
		pCombo->AddString("8x");
		pCombo->AddString("9x");
		pCombo->AddString("10x");
		pCombo->AddString("15x");
		pCombo->AddString("20x (highest quality)");

		int x;
		for (x = 0; x < 12; x++) {
			if (MotionBlurCombo[x] == m_pCurrentApplication->game_information.motion_blur_steps)
				break;
		}
		pCombo->SetCurSel(x);
		pItem->ValueActiveFromDefault();
	}
/*
	pRoot = InsertCategory(PROPERTIES_GLOBALVARS, PROPERTIES_DESC_GLOBALVARS);

		// Add global vars
		list<CApplication::GlobalVariable>::iterator g = m_pCurrentApplication->global_variables.begin();
		list<CApplication::GlobalVariable>::iterator globals_end = m_pCurrentApplication->global_variables.end();

		for ( ; g != globals_end; g++) {

			pItem = InsertGlobalItem(g->name, PROPERTIES_DESC_GLOBALVAR, pRoot);
			pString = GetEdit(pItem);
			pString->TextSet(g->value);
			pItem->ValueActiveFromDefault();
		}

		pItem = InsertAppItem(PROPERTIES_EDITGLOBALS, PROPERTIES_DESC_EDITGLOBALS , pRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet(PROPERTIES_ADD_EDIT);
		pItem->ValueActiveFromDefault();*/

	CExtPropertyItem* pTransitionRoot = InsertCategory("Transitions", "A list of all transitions available to the application.");
	
		list<CTransition>::iterator t = m_pCurrentApplication->m_Transitions.begin();

		for ( ; t != m_pCurrentApplication->m_Transitions.end(); t++) {

			CExtPropertyItem* pTransitionCat = InsertCategory(t->m_Name, "", pTransitionRoot);

			pItem = InsertTransitionItem("Name", "", &(*t), pTransitionCat);
			pString = GetEdit(pItem);
			pString->TextSet(t->m_Name);
			pItem->ValueActiveFromDefault();

			// Add each of the transition's properties.
			vector<EffectParameter>::iterator i = t->params.begin();
			const vector<EffectParameter>::const_iterator params_end = t->params.end();

			for ( ; i != params_end; i++) {

				// Make a fake set of information to represent this property and add it
				CPropItem item;
				item.Description = i->description;
				item.Label = i->name;
				item.Type = i->type;
				item.Text = "???";

				CString itemText = i->value;

				PropReturn itemValue;
				itemValue.fVal = atof(itemText);
				itemValue.val = atoi(itemText);
				itemValue.val64 = _atoi64(itemText);

				pItem = InsertTransitionItem(item.Label, item.Description, &(*t), pTransitionCat);
				AddPropertyItemToTree(item, pItem, itemText, itemValue);
				pItem->ValueActiveFromDefault();
			}

			pItem = InsertTransitionItem("Remove", "", &(*t), pTransitionCat);
			pLink = GetHyperLink(pItem);
			pLink->TextSet("Remove");
			pItem->ValueActiveFromDefault();
		}

		pItem = InsertAppItem("Add transition", "Click to add a new transition.", pTransitionRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet(PROPERTIES_ADD_EDIT);
		pItem->ValueActiveFromDefault();

		// Event lists
		/*CExtPropertyItem* pEventSheetRoot = InsertCategory("Event Sheets", "A list of all event sheets in the application.");
	
		list<EventSheet*>::iterator e = m_pCurrentApplication->event_sheets.begin();

		for ( ; e != m_pCurrentApplication->event_sheets.end(); e++) 
		{
			CExtPropertyItem* pEventSheet = InsertEventSheetItem((*e)->GetName(), "", (*e), pEventSheetRoot);
			pLink = GetHyperLink(pEventSheet);
			pLink->TextSet("Edit");
			pEventSheet->ValueActiveFromDefault();		
		}

		pItem = InsertAppItem("Manage Event Sheets", "Click to edit and delete all the application's event sheets.", pEventSheetRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet(PROPERTIES_ADD_EDIT);
		pItem->ValueActiveFromDefault();*/

	pRoot = InsertCategory("Grouping", "Modify the grouping tools in this application.");

		pItem = InsertAppItem("Edit Attributes", "Click to edit which attributes are available in Construct.", pRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet(PROPERTIES_ADD_EDIT);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem("Edit Families", "Click to edit which families are available in Construct.", pRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet(PROPERTIES_ADD_EDIT);
		pItem->ValueActiveFromDefault();

		pItem = InsertAppItem("Manage Families", "Click to edit which families are available in Construct.", pRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet("Open");
		pItem->ValueActiveFromDefault();

	pRoot = InsertCategory("Controls", "Set the controls used for movements.");

		vector<BehaviorControl>::iterator c = app->m_Controls.begin();

		for ( ; c != app->m_Controls.end(); c++) {

			CString label;
			label.Format("%s (P%d)", c->name, c->player + 1);
			pItem = InsertControlItem(label, "A control key.", c->player, pRoot);
			pCombo = GetCombo(pItem);

			int numElems = sizeof(controlTable) / sizeof(ControlTableEntry);

			for (int i = 0; i < numElems; i++)
				pCombo->InsertString(controlTable[i].name);

			pCombo->SetCurSel(c->comboIndex);

			pItem->ValueActiveFromDefault();
		}

		pItem = InsertAppItem("Manage Controls", "Click to edit controls.", pRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet(PROPERTIES_ADD_EDIT);
		pItem->ValueActiveFromDefault();

		/*
	pRoot = InsertCategory("Python", "Setting for python script");
		pItem = InsertAppItem("Manage Python", "Click to edit python distribution options.", pRoot);
		pLink = GetHyperLink(pItem);
		pLink->TextSet(PROPERTIES_ADD_EDIT);
		pItem->ValueActiveFromDefault();
		*/

	/*
		pItem = InsertAppItem(_T("Runjlkj without PS"), _T(""), pRoot);
		pCheck = GetCheckBox(pItem);
		pCheck->SetCheck(m_pCurrentApplication->m_runWithoutPs);
		pItem->ValueActiveFromDefault();
*/
}
Example #18
0
HRESULT CDirect3D::InitD3D(void)
{
    IDirect3D9 *(APIENTRY *pDirect3DCreate9)(UINT) = (IDirect3D9 *(APIENTRY *)(UINT))GetProcAddress(mhmodDX9, "Direct3DCreate9");
    if(!pDirect3DCreate9)
	return E_FAIL;

    // create the IDirect3D9 object
    pD3D9 = pDirect3DCreate9(D3D_SDK_VERSION);
    if(pD3D9 == NULL)
	return E_FAIL;

    D3DCAPS9 d3dCaps;
    // get device capabilities
    ZeroMemory(&d3dCaps, sizeof(d3dCaps));
    if(FAILED(pD3D9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps)))
	return E_FAIL;

    // get the display mode
    D3DDISPLAYMODE d3ddm;
    pD3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
    d3dpp.BackBufferFormat = d3ddm.Format;

    HRESULT hr;

    // Check if hardware vertex processing is available
    if(d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
        // Create device with hardware vertex processing
        hr = pD3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hwnd,
            D3DCREATE_HARDWARE_VERTEXPROCESSING|0x00000800L|D3DCREATE_FPU_PRESERVE, &d3dpp, &pD3DDevice9);
    } else {
        // Create device with software vertex processing
        hr = pD3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hwnd,
            D3DCREATE_SOFTWARE_VERTEXPROCESSING|0x00000800L|D3DCREATE_FPU_PRESERVE, &d3dpp, &pD3DDevice9);
    }

    // Make sure device was created
    if(FAILED(hr)) {
	LOG_MSG("D3D:Unable to create D3D device!");
	return E_FAIL;
    }

    if(FAILED(pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format,
			    0, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8))) {
	if(FAILED(pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format,
			    0, D3DRTYPE_TEXTURE, D3DFMT_R5G6B5))) {
	    DestroyD3D();
	    LOG_MSG("Error: Cannot find a working texture color format!");
	    return E_FAIL;
	}

	bpp16 = true;
	LOG_MSG("D3D:Running in 16-bit color mode");
    }

    if(d3dCaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) {
#if LOG_D3D
	LOG_MSG("D3D:Square-only textures");
#endif
	square = true;
    } else {
#if LOG_D3D
	LOG_MSG("D3D:Non-square textures");
#endif
	square = false;
    }

    if(d3dCaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
        if(d3dCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) {
#if LOG_D3D
	    LOG_MSG("D3D:Conditional non-pow2 texture size support");
#endif
	    pow2 = false;
        } else {
#if LOG_D3D
	    LOG_MSG("D3D:Textures must be a power of 2 in size");
#endif
	    pow2 = true;
	}
    } else {
#if LOG_D3D
       LOG_MSG("D3D:Textures do not need to be a power of 2 in size");
#endif
       pow2 = false;
    }

    if(d3dCaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) {
#if LOG_D3D
	LOG_MSG("D3D:Dynamic textures supported");
#endif
	dynamic = true;
    } else {
	LOG_MSG("D3D:Dynamic textures NOT supported. Performance will suffer!");
	dynamic = false;
    }

#if LOG_D3D
    LOG_MSG("D3D:Max texture width: %d", d3dCaps.MaxTextureWidth);
    LOG_MSG("D3D:Max texture height: %d", d3dCaps.MaxTextureHeight);
#endif

    if((d3dCaps.MaxTextureWidth < 1024) || (d3dCaps.MaxTextureHeight < 1024)) {
	DestroyD3D();
	LOG_MSG("Error: Your card does not support large textures!");
	return E_FAIL;
    }

#if C_D3DSHADERS
    // allow scale2x_ps14.fx with 1.4 shaders, everything else requires 2.0
    if(d3dCaps.PixelShaderVersion >= D3DPS_VERSION(1,4)) {
#if LOG_D3D
	LOG_MSG("D3D:Hardware PS version %d.%d", D3DSHADER_VERSION_MAJOR(d3dCaps.PixelShaderVersion),
						    D3DSHADER_VERSION_MINOR(d3dCaps.PixelShaderVersion));
#endif
	if(d3dCaps.PixelShaderVersion == D3DPS_VERSION(1,4))
	    LOG_MSG("D3D:Hardware PS version 1.4 detected. Most shaders probably won't work...");
	if((d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) && (dynamic)) {
	    psEnabled = true;
	    square = true;
	    pow2 = true;			// pow2 texture size has to be enabled as well
	} else {
	    LOG_MSG("D3D:Error when initializing pixel shader support. Disabling shaders.");
	    psEnabled = false;
	}
    }
    else {
	LOG_MSG("D3D:Hardware PS version too low. Disabling support for shaders.");
	psEnabled = false;
    }
#endif

    DWORD		dwNumAdapterModes;
    D3DDISPLAYMODE	DisplayMode;
    DWORD		m;

    dwNumModes = 0;

    if(bpp16)
	dwNumAdapterModes = pD3D9->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_R5G6B5);
    else
	dwNumAdapterModes = pD3D9->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);

    if(dwNumAdapterModes == 0) {
	LOG_MSG("D3D:No display modes found");
	return E_FAIL;
    }

#if LOG_D3D
    LOG_MSG("D3D:Found %d display modes", dwNumAdapterModes);
#endif
    modes = (D3DDISPLAYMODE*)malloc(sizeof(D3DDISPLAYMODE)*dwNumAdapterModes);

    if(!modes) {
	LOG_MSG("D3D:Error allocating memory!");
	DestroyD3D();
	return E_FAIL;
    }

    for(iMode=0;iMode<dwNumAdapterModes;iMode++) {
	// Get the display mode attributes
	if(bpp16)
	    pD3D9->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_R5G6B5, iMode, &DisplayMode);
	else
	    pD3D9->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, iMode, &DisplayMode);

	// Check if the mode already exists
	for(m=0;m<dwNumModes;m++) {
	    if((modes[m].Width == DisplayMode.Width) && (modes[m].Height == DisplayMode.Height) &&
		(modes[m].Format == DisplayMode.Format))
		break;
	}

	// If we found a new mode, add it to the list of modes
	if(m==dwNumModes) {
#if LOG_D3D
	    LOG_MSG("D3D:Display mode: %dx%dx%d", DisplayMode.Width, DisplayMode.Height, DisplayMode.Format);
#endif
	    // Try to sort resolutions
	    if(dwNumModes>0) {
		if(((modes[m - 1].Width == DisplayMode.Width) && (modes[m - 1].Height > DisplayMode.Height)) ||
		   (modes[m - 1].Width  > DisplayMode.Width)) {
		    modes[m].Width  = modes[m - 1].Width;
		    modes[m].Height = modes[m - 1].Height;
		    modes[m].Format = modes[m - 1].Format;
		    m--;
		}
	    }

	    modes[m].Width       = DisplayMode.Width;
	    modes[m].Height      = DisplayMode.Height;
	    modes[m].Format      = DisplayMode.Format;
	    modes[m].RefreshRate = 0;
	    ++dwNumModes;
	}
    }

    // Free some unused memory
    modes = (D3DDISPLAYMODE*)realloc(modes, sizeof(D3DDISPLAYMODE)*dwNumModes);

    if(!modes) {
	LOG_MSG("D3D:Error allocating memory!");
	DestroyD3D();
	return E_FAIL;
    }

    dwTexHeight = 0;
    dwTexWidth = 0;

    return S_OK;
}