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; }
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; }
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; }
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)); }
/******************************************************************** 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); }
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 {
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, ¤tDisplayMode); 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; }
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; }
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, ¤tDisplayMode); 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; }
// 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 ); } }
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, ¤tDisplayMode); 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; }
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; }
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(); */ }
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; }