Exemplo n.º 1
0
BOOL gldCreateDrawable_DX(
	DGL_ctx *ctx,
//	BOOL bDefaultDriver,
	BOOL bDirectDrawPersistant,
	BOOL bPersistantBuffers)
{
	//
	// bDirectDrawPersistant:	applies to IDirect3D8
	// bPersistantBuffers:		applies to IDirect3DDevice8
	//

	HRESULT					hResult;
	GLD_driver_dx8			*lpCtx = NULL;
	D3DDEVTYPE				d3dDevType;
	D3DPRESENT_PARAMETERS	d3dpp;
	D3DDISPLAYMODE			d3ddm;
	DWORD					dwBehaviourFlags;
	D3DADAPTER_IDENTIFIER8	d3dIdent;

	// Error if context is NULL.
	if (ctx == NULL)
		return FALSE;

	if (ctx->glPriv) {
		lpCtx = ctx->glPriv;
		// Release any existing interfaces
		SAFE_RELEASE(lpCtx->pDev);
		SAFE_RELEASE(lpCtx->pD3D);
	} else {
		lpCtx = (GLD_driver_dx8*)malloc(sizeof(GLD_driver_dx8));
		ZeroMemory(lpCtx, sizeof(lpCtx));
	}

	d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF;
	// TODO: Check this
//	if (bDefaultDriver)
//		d3dDevType = D3DDEVTYPE_REF;

	// Use persistant interface if needed
	if (bDirectDrawPersistant && dx8Globals.bDirect3D) {
		lpCtx->pD3D = dx8Globals.pD3D;
		IDirect3D8_AddRef(lpCtx->pD3D);
		goto SkipDirectDrawCreate;
	}

	// Create Direct3D8 object
	lpCtx->pD3D = dx8Globals.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95);
	if (lpCtx->pD3D == NULL) {
		MessageBox(NULL, "Unable to initialize Direct3D8", "GLDirect", MB_OK);
		ddlogMessage(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D8 interface");
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}

	// Cache Direct3D interface for subsequent GLRCs
	if (bDirectDrawPersistant && !dx8Globals.bDirect3D) {
		dx8Globals.pD3D = lpCtx->pD3D;
		IDirect3D8_AddRef(dx8Globals.pD3D);
		dx8Globals.bDirect3D = TRUE;
	}
SkipDirectDrawCreate:

	// Get the display mode so we can make a compatible backbuffer
	hResult = IDirect3D8_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm);
	if (FAILED(hResult)) {
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}

	// Get device caps
	hResult = IDirect3D8_GetDeviceCaps(lpCtx->pD3D, glb.dwAdapter, d3dDevType, &lpCtx->d3dCaps8);
	if (FAILED(hResult)) {
		ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_GetDeviceCaps failed", hResult);
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}

	// Check for hardware transform & lighting
	lpCtx->bHasHWTnL = lpCtx->d3dCaps8.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE;

	// If this flag is present then we can't default to Mesa
	// SW rendering between BeginScene() and EndScene().
	if (lpCtx->d3dCaps8.Caps2 & D3DCAPS2_NO2DDURING3DSCENE) {
		ddlogMessage(DDLOG_WARN,
			"Warning          : No 2D allowed during 3D scene.\n");
	}

	//
	//	Create the Direct3D context
	//

	// Re-use original IDirect3DDevice if persistant buffers exist.
	// Note that we test for persistant IDirect3D8 as well
	// bDirectDrawPersistant == persistant IDirect3D8 (DirectDraw8 does not exist)
	if (bDirectDrawPersistant && bPersistantBuffers && dx8Globals.pD3D && dx8Globals.pDev) {
		lpCtx->pDev = dx8Globals.pDev;
		IDirect3DDevice8_AddRef(dx8Globals.pDev);
		goto skip_direct3ddevice_create;
	}

	// Clear the presentation parameters (sets all members to zero)
	ZeroMemory(&d3dpp, sizeof(d3dpp));

	// Recommended by MS; needed for MultiSample.
	// Be careful if altering this for FullScreenBlit
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

	d3dpp.BackBufferFormat	= d3ddm.Format;
	d3dpp.BackBufferCount	= 1;
	d3dpp.MultiSampleType	= _gldGetDeviceMultiSampleType(lpCtx->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen);
	d3dpp.AutoDepthStencilFormat	= ctx->lpPF->dwDriverData;
	d3dpp.EnableAutoDepthStencil	= (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE;

	if (ctx->bFullscreen) {
		ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen 
		d3dpp.Windowed							= FALSE;
		d3dpp.BackBufferWidth					= d3ddm.Width;
		d3dpp.BackBufferHeight					= d3ddm.Height;
		d3dpp.hDeviceWindow						= ctx->hWnd;
		d3dpp.FullScreen_RefreshRateInHz		= D3DPRESENT_RATE_DEFAULT;

		// Support for vertical retrace synchronisation.
		// Set default presentation interval in case caps bits are missing
		d3dpp.FullScreen_PresentationInterval	= D3DPRESENT_INTERVAL_DEFAULT;
		if (glb.bWaitForRetrace) {
			if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)
				d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
		} else {
			if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)
				d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
		}
	} else {
		ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages
		d3dpp.Windowed							= TRUE;
		d3dpp.BackBufferWidth					= ctx->dwWidth;
		d3dpp.BackBufferHeight					= ctx->dwHeight;
		d3dpp.hDeviceWindow						= ctx->hWnd;
		d3dpp.FullScreen_RefreshRateInHz		= 0;
		// FullScreen_PresentationInterval must be default for Windowed mode
		d3dpp.FullScreen_PresentationInterval	= D3DPRESENT_INTERVAL_DEFAULT;
	}

	// Decide if we can use hardware TnL
	dwBehaviourFlags = (lpCtx->bHasHWTnL) ?
		D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	// Add flag to tell D3D to be thread-safe
	if (glb.bMultiThreaded)
		dwBehaviourFlags |= D3DCREATE_MULTITHREADED;
	// Add flag to tell D3D to be FPU-safe
	if (!glb.bFastFPU)
		dwBehaviourFlags |= D3DCREATE_FPU_PRESERVE;
	hResult = IDirect3D8_CreateDevice(lpCtx->pD3D,
								glb.dwAdapter,
								d3dDevType,
								ctx->hWnd,
								dwBehaviourFlags,
								&d3dpp,
								&lpCtx->pDev);
    if (FAILED(hResult)) {
		ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_CreateDevice failed", hResult);
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}

	if (bDirectDrawPersistant && bPersistantBuffers && dx8Globals.pD3D) {
		dx8Globals.pDev = lpCtx->pDev;
		dx8Globals.bDirect3DDevice = TRUE;
	}

/*
	// See if DDraw interfaces are available (DaveM)
	hResult = IDirect3D8_QueryInterface(lpCtx->pDev,
		&IID_IDirectDraw7, (LPVOID*)&lpOpaque1);
	if (FAILED(hResult) || lpOpaque1 == NULL) {
		ddlogMessage(DDLOG_INFO, "DirectDraw QueryInterface unavailable\n");
	}

	hResult = IDirect3DDevice8_QueryInterface(lpCtx->pDev, 
		&IID_IDirectDrawSurface7, (LPVOID*)&lpOpaque2);
	if (FAILED(hResult) || lpOpaque2 == NULL) {
		ddlogMessage(DDLOG_INFO, "DirectDrawSurface QueryInterface unavialable\n");
	}
*/	
	// Dump some useful stats
	hResult = IDirect3D8_GetAdapterIdentifier(
		lpCtx->pD3D,
		glb.dwAdapter,
		D3DENUM_NO_WHQL_LEVEL, // Avoids 1 to 2 second delay
		&d3dIdent);
	if (SUCCEEDED(hResult)) {
		ddlogPrintf(DDLOG_INFO, "[Driver Description: %s]", &d3dIdent.Description);
		ddlogPrintf(DDLOG_INFO, "[Driver file: %s %d.%d.%02d.%d]",
			d3dIdent.Driver,
			HIWORD(d3dIdent.DriverVersion.HighPart),
			LOWORD(d3dIdent.DriverVersion.HighPart),
			HIWORD(d3dIdent.DriverVersion.LowPart),
			LOWORD(d3dIdent.DriverVersion.LowPart));
		ddlogPrintf(DDLOG_INFO, "[VendorId: 0x%X, DeviceId: 0x%X, SubSysId: 0x%X, Revision: 0x%X]",
			d3dIdent.VendorId, d3dIdent.DeviceId, d3dIdent.SubSysId, d3dIdent.Revision);
	}

	// Init projection matrix for D3D TnL
	D3DXMatrixIdentity(&lpCtx->matProjection);
	lpCtx->matModelView = lpCtx->matProjection;
//		gld->bUseMesaProjection = TRUE;

skip_direct3ddevice_create:

	// Create buffers to hold primitives
	lpCtx->PB2d.dwFVF		= GLD_FVF_2D_VERTEX;
	lpCtx->PB2d.dwPool		= D3DPOOL_SYSTEMMEM;
	lpCtx->PB2d.dwStride	= sizeof(GLD_2D_VERTEX);
	lpCtx->PB2d.dwUsage		= D3DUSAGE_DONOTCLIP |
								D3DUSAGE_DYNAMIC |
								D3DUSAGE_SOFTWAREPROCESSING |
								D3DUSAGE_WRITEONLY;
	hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB2d);
	if (FAILED(hResult))
		goto return_with_error;

	lpCtx->PB3d.dwFVF		= GLD_FVF_3D_VERTEX;
	lpCtx->PB3d.dwPool		= D3DPOOL_DEFAULT;
	lpCtx->PB3d.dwStride	= sizeof(GLD_3D_VERTEX);
	lpCtx->PB3d.dwUsage		= D3DUSAGE_DYNAMIC |
								D3DUSAGE_SOFTWAREPROCESSING |
								D3DUSAGE_WRITEONLY;
	hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB3d);
	if (FAILED(hResult))
		goto return_with_error;

/*	// NOTE: A FVF code of zero indicates a non-FVF vertex buffer (for vertex shaders)
	lpCtx->PBtwosidelight.dwFVF		= 0; //GLD_FVF_TWOSIDED_VERTEX;
	lpCtx->PBtwosidelight.dwPool	= D3DPOOL_DEFAULT;
	lpCtx->PBtwosidelight.dwStride	= sizeof(GLD_TWOSIDED_VERTEX);
	lpCtx->PBtwosidelight.dwUsage	= D3DUSAGE_DONOTCLIP |
								D3DUSAGE_DYNAMIC |
								D3DUSAGE_SOFTWAREPROCESSING |
								D3DUSAGE_WRITEONLY;
	hResult = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PBtwosidelight);
	if (FAILED(hResult))
		goto return_with_error;*/

	// Now try and create the DX8 Vertex Shaders
//	_gldCreateVertexShaders(lpCtx);

	// Zero the pipeline usage counters
	lpCtx->PipelineUsage.qwMesa.QuadPart = 
//	lpCtx->PipelineUsage.dwD3D2SVS.QuadPart =
	lpCtx->PipelineUsage.qwD3DFVF.QuadPart = 0;

	// Assign drawable to GL private
	ctx->glPriv = lpCtx;
	return TRUE;

return_with_error:
	// Clean up and bail

//	_gldDestroyVertexShaders(lpCtx);

//	_gldDestroyPrimitiveBuffer(&lpCtx->PBtwosidelight);
	_gldDestroyPrimitiveBuffer(&lpCtx->PB3d);
	_gldDestroyPrimitiveBuffer(&lpCtx->PB2d);

	SAFE_RELEASE(lpCtx->pDev);
	SAFE_RELEASE(lpCtx->pD3D);
	return FALSE;
}
Exemplo n.º 2
0
BOOL gldCreateDrawable_DX(
	DGL_ctx *ctx,
//	BOOL bDefaultDriver,
	BOOL bDirectDrawPersistant,
	BOOL bPersistantBuffers)
{
	//
	// bDirectDrawPersistant:	applies to IDirect3D8
	// bPersistantBuffers:		applies to IDirect3DDevice8
	//

//	D3DDEVTYPE				d3dDevType;
//	D3DPRESENT_PARAMETERS	d3dpp;
//	D3DDISPLAYMODE			d3ddm;
//	DWORD					dwBehaviourFlags;
//	D3DADAPTER_IDENTIFIER8	d3dIdent;

	HRESULT				hr;
	GLD_driver_dx7		*lpCtx = NULL;
	D3DX_VIDMODEDESC	d3ddm;

	// Parameters for D3DXCreateContextEx
	// These will be different for fullscreen and windowed
	DWORD				dwDeviceIndex;
	DWORD				dwFlags;
	HWND				hwnd;
	HWND				hwndFocus;
	DWORD				numColorBits;
	DWORD				numAlphaBits;
	DWORD				numDepthBits;
	DWORD				numStencilBits;
	DWORD				numBackBuffers;
	DWORD				dwWidth;
	DWORD				dwHeight;
	DWORD				refreshRate;

	// Error if context is NULL.
	if (ctx == NULL)
		return FALSE;

	if (ctx->glPriv) {
		lpCtx = ctx->glPriv;
		// Release any existing interfaces (in reverse order)
		SAFE_RELEASE(lpCtx->pDev);
		SAFE_RELEASE(lpCtx->pD3D);
		lpCtx->pD3DXContext->lpVtbl->Release(lpCtx->pD3DXContext);
		lpCtx->pD3DXContext = NULL;
	} else {
		lpCtx = (GLD_driver_dx7*)malloc(sizeof(GLD_driver_dx7));
		ZeroMemory(lpCtx, sizeof(lpCtx));
	}

//	d3dDevType = (glb.dwDriver == GLDS_DRIVER_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF;
	// Use REF device if requested. Otherwise D3DX_DEFAULT will choose highest level
	// of HW acceleration.
	dwDeviceIndex = (glb.dwDriver == GLDS_DRIVER_REF) ? D3DX_HWLEVEL_REFERENCE : D3DX_DEFAULT;

	// TODO: Check this
//	if (bDefaultDriver)
//		d3dDevType = D3DDEVTYPE_REF;

#ifdef _GLD_PERSISTANT
	// Use persistant interface if needed
	if (bDirectDrawPersistant && dx7Globals.bDirect3D) {
		lpCtx->pD3D = dx7Globals.pD3D;
		IDirect3D7_AddRef(lpCtx->pD3D);
		goto SkipDirectDrawCreate;
	}
#endif
/*
	// Create Direct3D7 object
	lpCtx->pD3D = dx7Globals.fnDirect3DCreate8(D3D_SDK_VERSION_DX8_SUPPORT_WIN95);
	if (lpCtx->pD3D == NULL) {
		MessageBox(NULL, "Unable to initialize Direct3D8", "GLDirect", MB_OK);
		ddlogMessage(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D8 interface");
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}
*/

#ifdef _GLD_PERSISTANT
	// Cache Direct3D interface for subsequent GLRCs
	if (bDirectDrawPersistant && !dx8Globals.bDirect3D) {
		dx7Globals.pD3D = lpCtx->pD3D;
		IDirect3D7_AddRef(dx7Globals.pD3D);
		dx7Globals.bDirect3D = TRUE;
	}
SkipDirectDrawCreate:
#endif
/*
	// Get the display mode so we can make a compatible backbuffer
	hResult = IDirect3D8_GetAdapterDisplayMode(lpCtx->pD3D, glb.dwAdapter, &d3ddm);
	if (FAILED(hResult)) {
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}
*/

#if 0
	// Get device caps
	hResult = IDirect3D8_GetDeviceCaps(lpCtx->pD3D, glb.dwAdapter, d3dDevType, &lpCtx->d3dCaps8);
	if (FAILED(hResult)) {
		ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_GetDeviceCaps failed", hResult);
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}

	// Check for hardware transform & lighting
	lpCtx->bHasHWTnL = lpCtx->d3dCaps8.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE;

	// If this flag is present then we can't default to Mesa
	// SW rendering between BeginScene() and EndScene().
	if (lpCtx->d3dCaps8.Caps2 & D3DCAPS2_NO2DDURING3DSCENE) {
		ddlogMessage(DDLOG_WARN,
			"Warning          : No 2D allowed during 3D scene.\n");
	}
#endif

	//
	//	Create the Direct3D context
	//

#ifdef _GLD_PERSISTANT
	// Re-use original IDirect3DDevice if persistant buffers exist.
	// Note that we test for persistant IDirect3D8 as well
	// bDirectDrawPersistant == persistant IDirect3D8 (DirectDraw8 does not exist)
	if (bDirectDrawPersistant && bPersistantBuffers && dx7Globals.pD3D && dx7Globals.pDev) {
		lpCtx->pDev = dx7Globals.pDev;
		IDirect3DDevice7_AddRef(dx7Globals.pDev);
		goto skip_direct3ddevice_create;
	}
#endif
/*
	// Clear the presentation parameters (sets all members to zero)
	ZeroMemory(&d3dpp, sizeof(d3dpp));

	// Recommended by MS; needed for MultiSample.
	// Be careful if altering this for FullScreenBlit
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

	d3dpp.BackBufferFormat	= d3ddm.Format;
	d3dpp.BackBufferCount	= 1;
	d3dpp.MultiSampleType	= _gldGetDeviceMultiSampleType(lpCtx->pD3D, d3ddm.Format, d3dDevType, !ctx->bFullscreen);
	d3dpp.AutoDepthStencilFormat	= ctx->lpPF->dwDriverData;
	d3dpp.EnableAutoDepthStencil	= (d3dpp.AutoDepthStencilFormat == D3DFMT_UNKNOWN) ? FALSE : TRUE;

	if (ctx->bFullscreen) {
		ddlogWarnOption(FALSE); // Don't popup any messages in fullscreen 
		d3dpp.Windowed							= FALSE;
		d3dpp.BackBufferWidth					= d3ddm.Width;
		d3dpp.BackBufferHeight					= d3ddm.Height;
		d3dpp.hDeviceWindow						= ctx->hWnd;
		d3dpp.FullScreen_RefreshRateInHz		= D3DPRESENT_RATE_DEFAULT;

		// Support for vertical retrace synchronisation.
		// Set default presentation interval in case caps bits are missing
		d3dpp.FullScreen_PresentationInterval	= D3DPRESENT_INTERVAL_DEFAULT;
		if (glb.bWaitForRetrace) {
			if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)
				d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
		} else {
			if (lpCtx->d3dCaps8.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)
				d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
		}
	} else {
		ddlogWarnOption(glb.bMessageBoxWarnings); // OK to popup messages
		d3dpp.Windowed							= TRUE;
		d3dpp.BackBufferWidth					= ctx->dwWidth;
		d3dpp.BackBufferHeight					= ctx->dwHeight;
		d3dpp.hDeviceWindow						= ctx->hWnd;
		d3dpp.FullScreen_RefreshRateInHz		= 0;
		// FullScreen_PresentationInterval must be default for Windowed mode
		d3dpp.FullScreen_PresentationInterval	= D3DPRESENT_INTERVAL_DEFAULT;
	}

	// Decide if we can use hardware TnL
	dwBehaviourFlags = (lpCtx->bHasHWTnL) ?
		D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	// Add flag to tell D3D to be thread-safe
	if (glb.bMultiThreaded)
		dwBehaviourFlags |= D3DCREATE_MULTITHREADED;
	hResult = IDirect3D8_CreateDevice(lpCtx->pD3D,
								glb.dwAdapter,
								d3dDevType,
								ctx->hWnd,
								dwBehaviourFlags,
								&d3dpp,
								&lpCtx->pDev);
    if (FAILED(hResult)) {
		ddlogError(DDLOG_CRITICAL_OR_WARN, "IDirect3D8_CreateDevice failed", hResult);
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}
*/

	// Create D3DX context
	if (ctx->bFullscreen) {
		//
		// FULLSCREEN
		//

		// Get display mode
		D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm);

		// Fullscreen Parameters
		dwFlags			= D3DX_CONTEXT_FULLSCREEN;
		hwnd			= ctx->hWnd;
		hwndFocus		= ctx->hWnd;
		numColorBits	= ctx->lpPF->pfd.cColorBits;
		numAlphaBits	= ctx->lpPF->pfd.cAlphaBits;
		numDepthBits	= ctx->lpPF->pfd.cDepthBits + ctx->lpPF->pfd.cStencilBits;
		numStencilBits	= ctx->lpPF->pfd.cStencilBits;
		numBackBuffers	= D3DX_DEFAULT; // Default is 1 backbuffer
		dwWidth			= d3ddm.width;
		dwHeight		= d3ddm.height;
		refreshRate		= d3ddm.refreshRate; // D3DX_DEFAULT;
	} else {
		//
		// WINDOWED
		//

		// Windowed Parameters
		dwFlags			= 0; // No flags means "windowed"
		hwnd			= ctx->hWnd;
		hwndFocus		= (HWND)D3DX_DEFAULT;
		numColorBits	= D3DX_DEFAULT; // Use Desktop depth
		numAlphaBits	= ctx->lpPF->pfd.cAlphaBits;
		numDepthBits	= ctx->lpPF->pfd.cDepthBits + ctx->lpPF->pfd.cStencilBits;
		numStencilBits	= ctx->lpPF->pfd.cStencilBits;
		numBackBuffers	= D3DX_DEFAULT; // Default is 1 backbuffer
		dwWidth			= ctx->dwWidth;
		dwHeight		= ctx->dwHeight;
		refreshRate		= D3DX_DEFAULT;
	}
	hr = D3DXCreateContextEx(dwDeviceIndex, dwFlags, hwnd, hwndFocus,
							numColorBits, numAlphaBits, numDepthBits, numStencilBits,
							numBackBuffers,
							dwWidth, dwHeight, refreshRate,
							&lpCtx->pD3DXContext);
    if (FAILED(hr)) {
		ddlogError(DDLOG_CRITICAL_OR_WARN, "D3DXCreateContextEx failed", hr);
        nContextError = GLDERR_D3D;
		goto return_with_error;
	}

	// Obtain D3D7 interfaces from ID3DXContext
//	lpCtx->pDD	= ID3DXContext_GetDD(lpCtx->pD3DXContext);
	lpCtx->pDD	= lpCtx->pD3DXContext->lpVtbl->GetDD(lpCtx->pD3DXContext);
	if (lpCtx->pDD == NULL)
		goto return_with_error;
	lpCtx->pD3D	= lpCtx->pD3DXContext->lpVtbl->GetD3D(lpCtx->pD3DXContext);
	if (lpCtx->pD3D == NULL)
		goto return_with_error;
	lpCtx->pDev	= lpCtx->pD3DXContext->lpVtbl->GetD3DDevice(lpCtx->pD3DXContext);
	if (lpCtx->pDev == NULL)
		goto return_with_error;

    // Need to manage clipper manually for multiple windows
    // since DX7 D3DX utility lib does not appear to do that. (DaveM)
    if (!ctx->bFullscreen) {
        // Get primary surface too
        lpDDSPrimary = lpCtx->pD3DXContext->lpVtbl->GetPrimary(lpCtx->pD3DXContext);
	    if (lpDDSPrimary == NULL) {
		    ddlogPrintf(DDLOG_WARN, "GetPrimary");
            goto return_with_error;
	    }
	    // Create clipper for correct window updates
        if (IDirectDraw7_CreateClipper(lpCtx->pDD, 0, &lpDDClipper, NULL) != DD_OK) {
		    ddlogPrintf(DDLOG_WARN, "CreateClipper");
		    goto return_with_error;
	    }
        // Set the window that the clipper belongs to
        if (IDirectDrawClipper_SetHWnd(lpDDClipper, 0, hwnd) != DD_OK) {
		    ddlogPrintf(DDLOG_WARN, "SetHWnd");
		    goto return_with_error;
	    }
        // Attach the clipper to the primary surface
        if (IDirectDrawSurface7_SetClipper(lpDDSPrimary, lpDDClipper) != DD_OK) {
		    ddlogPrintf(DDLOG_WARN, "SetClipper");
            goto return_with_error;
	    }
    }

	// Get device caps
	IDirect3DDevice7_GetCaps(lpCtx->pDev, &lpCtx->d3dCaps);

	// Determine HW TnL
	lpCtx->bHasHWTnL = lpCtx->d3dCaps.dwDevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ? TRUE : FALSE;

#ifdef _GLD_PERSISTANT
	if (bDirectDrawPersistant && bPersistantBuffers && dx7Globals.pD3D) {
		dx7Globals.pDev = lpCtx->pDev;
		dx7Globals.bDirect3DDevice = TRUE;
	}
#endif

#if 0
	// Dump some useful stats
	hResult = IDirect3D8_GetAdapterIdentifier(
		lpCtx->pD3D,
		glb.dwAdapter,
		D3DENUM_NO_WHQL_LEVEL, // Avoids 1 to 2 second delay
		&d3dIdent);
	if (SUCCEEDED(hResult)) {
		ddlogPrintf(DDLOG_INFO, "[Driver Description: %s]", &d3dIdent.Description);
		ddlogPrintf(DDLOG_INFO, "[Driver file: %s %d.%d.%02d.%d]",
			d3dIdent.Driver,
			HIWORD(d3dIdent.DriverVersion.HighPart),
			LOWORD(d3dIdent.DriverVersion.HighPart),
			HIWORD(d3dIdent.DriverVersion.LowPart),
			LOWORD(d3dIdent.DriverVersion.LowPart));
		ddlogPrintf(DDLOG_INFO, "[VendorId: 0x%X, DeviceId: 0x%X, SubSysId: 0x%X, Revision: 0x%X]",
			d3dIdent.VendorId, d3dIdent.DeviceId, d3dIdent.SubSysId, d3dIdent.Revision);
	}
#endif

	// Init projection matrix for D3D TnL
	D3DXMatrixIdentity((D3DXMATRIX*)&lpCtx->matProjection);
	lpCtx->matModelView = lpCtx->matProjection;
//		gld->bUseMesaProjection = TRUE;

skip_direct3ddevice_create:

	// Create buffers to hold primitives
	lpCtx->PB2d.dwFVF			= GLD_FVF_2D_VERTEX;
//	lpCtx->PB2d.dwPool			= D3DPOOL_SYSTEMMEM;
	lpCtx->PB2d.dwStride		= sizeof(GLD_2D_VERTEX);
	lpCtx->PB2d.dwCreateFlags	= D3DVBCAPS_DONOTCLIP |
									D3DVBCAPS_SYSTEMMEMORY |
									D3DVBCAPS_WRITEONLY;
	hr = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB2d);
	if (FAILED(hr))
		goto return_with_error;

	lpCtx->PB3d.dwFVF			= GLD_FVF_3D_VERTEX;
//	lpCtx->PB3d.dwPool			= D3DPOOL_DEFAULT;
	lpCtx->PB3d.dwStride		= sizeof(GLD_3D_VERTEX);
	lpCtx->PB3d.dwCreateFlags	= D3DVBCAPS_WRITEONLY;

	hr = _gldCreatePrimitiveBuffer(ctx->glCtx, lpCtx, &lpCtx->PB3d);
	if (FAILED(hr))
		goto return_with_error;

	// Zero the pipeline usage counters
	lpCtx->PipelineUsage.qwMesa.QuadPart = 
//	lpCtx->PipelineUsage.dwD3D2SVS.QuadPart =
	lpCtx->PipelineUsage.qwD3DFVF.QuadPart = 0;

	// Assign drawable to GL private
	ctx->glPriv = lpCtx;
	return TRUE;

return_with_error:
	// Clean up and bail
	_gldDestroyPrimitiveBuffer(&lpCtx->PB3d);
	_gldDestroyPrimitiveBuffer(&lpCtx->PB2d);

	SAFE_RELEASE(lpCtx->pDev);
	SAFE_RELEASE(lpCtx->pD3D);
	//SAFE_RELEASE(lpCtx->pD3DXContext);
	lpCtx->pD3DXContext->lpVtbl->Release(lpCtx->pD3DXContext);
	return FALSE;
}
Exemplo n.º 3
0
static BOOL _gldDriverError(void)
{
	ddlogMessage(DDLOG_CRITICAL, szDriverError);
	return FALSE;
}
Exemplo n.º 4
0
BOOL gldBuildPixelformatList_DX(void)
{
	D3DX_DEVICEDESC		d3dxdd;
	D3DX_VIDMODEDESC	d3ddm;
	D3DX_SURFACEFORMAT	fmt[64]; // 64 should be enough...
	DWORD				dwDeviceIndex;
	DWORD				surfClassFlags;
//	IDirect3D7			*pD3D = NULL;
	HRESULT				hr;
	int					nSupportedFormats = 0;		// Total formats
	int					nDepthOnlyFormats = 0;
	int					nDepthStencilFormats = 0;
	int					i;
	DGL_pixelFormat		*pPF;
	BYTE				cColorBits, cRedBits, cGreenBits, cBlueBits, cAlphaBits;
//	char				buf[128];
//	char				cat[8];

	// Direct3D (SW or HW)
	// These are arranged so that 'best' pixelformat
	// is higher in the list (for ChoosePixelFormat).
/*	const D3DFORMAT DepthStencil[4] = {
		D3DX_SF_Z16S0, //D3DX_SF_D16,
		D3DX_SF_Z15S1, //D3DX_SF_D15S1,
		D3DX_SF_Z32S0, //D3DX_SF_D32,
		D3DX_SF_Z24S8, //D3DX_SF_D24S8,
		//D3DX_SF_D24X8,
		//D3DX_SF_D24X4S4,
	};*/

	// Dump DX version
	ddlogMessage(GLDLOG_SYSTEM, "DirectX Version  : 7.0\n");

	// Release any existing pixelformat list
	if (glb.lpPF) {
		free(glb.lpPF);
	}

	glb.nPixelFormatCount	= 0;
	glb.lpPF				= NULL;

	//
	// Pixelformats for Direct3D (SW or HW) rendering
	//

	dwDeviceIndex = (glb.dwDriver == GLDS_DRIVER_REF) ? D3DX_HWLEVEL_REFERENCE : D3DX_DEFAULT;

	// Dump description
	D3DXGetDeviceDescription(dwDeviceIndex, &d3dxdd);
	ddlogPrintf(GLDLOG_SYSTEM, "Device: %s", d3dxdd.driverDesc);

	// Get display mode
	D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm);

#if 0
	// Phooey - this don't work...
/*
	// Since D3DXGetMaxSurfaceFormats() can lie to us, we'll need a workaround.
	// Explicitly test for matching depth/stencil to display bpp.
	if (d3ddm.bpp <= 16) {
		if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z16S0))
			fmt[nSupportedFormats++] = D3DX_SF_Z16S0;
		if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z15S1))
			fmt[nSupportedFormats++] = D3DX_SF_Z15S1;
		if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_S1Z15))
			fmt[nSupportedFormats++] = D3DX_SF_S1Z15;
		// Didn't find anything? Try default
		if (nSupportedFormats == 0) {
			if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z32S0))
				fmt[nSupportedFormats++] = D3DX_SF_Z32S0;
		}
	} else {
		if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z32S0))
			fmt[nSupportedFormats++] = D3DX_SF_Z32S0;
		if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z24S8))
			fmt[nSupportedFormats++] = D3DX_SF_Z24S8;
		if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_S8Z24))
			fmt[nSupportedFormats++] = D3DX_SF_S8Z24;
		// Didn't find anything? Try default
		if (nSupportedFormats == 0) {
			if (GLD_CheckDepthStencilMatch(dwDeviceIndex, D3DX_SF_Z16S0))
				fmt[nSupportedFormats++] = D3DX_SF_Z16S0;
		}
	}
*/
	// Go the Whole Hog...
	fmt[nSupportedFormats++] = _gldFindCompatibleDepthStencilFormat(dwDeviceIndex);
#else
	//
	// Depth buffer formats WITHOUT stencil
	//
	surfClassFlags = D3DX_SC_DEPTHBUFFER;
	nDepthOnlyFormats = D3DXGetMaxSurfaceFormats(dwDeviceIndex, NULL, surfClassFlags);
	//
	// Depth buffer formats WITH stencil
	//
	surfClassFlags = D3DX_SC_DEPTHBUFFER | D3DX_SC_STENCILBUFFER;
	nDepthStencilFormats = D3DXGetMaxSurfaceFormats(dwDeviceIndex, NULL, surfClassFlags);

	// Work out how many formats we have in total
	if ((nDepthOnlyFormats + nDepthStencilFormats) == 0)
		return FALSE; // Bail: no compliant pixelformats

	// Get depth buffer formats WITHOUT stencil
	surfClassFlags = D3DX_SC_DEPTHBUFFER;
	for (i=0; i<nDepthOnlyFormats; i++) {
		D3DXGetSurfaceFormat(dwDeviceIndex, NULL, surfClassFlags, i, &fmt[nSupportedFormats++]);
	}
	// NOTE: For some reason we already get stencil formats when only specifying D3DX_SC_DEPTHBUFFER
	/*
		// Get depth buffer formats WITH stencil
		surfClassFlags = D3DX_SC_DEPTHBUFFER | D3DX_SC_STENCILBUFFER;
		for (i=0; i<nDepthStencilFormats; i++) {
			D3DXGetSurfaceFormat(dwDeviceIndex, NULL, surfClassFlags, i, &fmt[nSupportedFormats++]);
		}
	*/
#endif

	// Total count of pixelformats is:
	// (nSupportedFormats+1)*2
	glb.lpPF = (DGL_pixelFormat *)calloc((nSupportedFormats)*2, sizeof(DGL_pixelFormat));
	glb.nPixelFormatCount = (nSupportedFormats)*2;
	if (glb.lpPF == NULL) {
		glb.nPixelFormatCount = 0;
		return FALSE;
	}

	// Get a copy of pointer that we can alter
	pPF = glb.lpPF;

	// Cache colour bits from display format
//	_BitsFromDisplayFormat(d3ddm.Format, &cColorBits, &cRedBits, &cGreenBits, &cBlueBits, &cAlphaBits);
	// Get display mode
	D3DXGetCurrentVideoMode(D3DX_DEFAULT, &d3ddm);
	cColorBits = d3ddm.bpp;
	cAlphaBits = 0;
	switch (d3ddm.bpp) {
	case 15:
		cRedBits = 5; cGreenBits = 5; cBlueBits = 5;
		break;
	case 16:
		cRedBits = 5; cGreenBits = 6; cBlueBits = 5;
		break;
	case 24:
	case 32:
		cRedBits = 8; cGreenBits = 8; cBlueBits = 8;
		break;
	default:
		cRedBits = 5; cGreenBits = 5; cBlueBits = 5;
	}

	//
	// Add single-buffer formats
	//

/*	// Single-buffer, no depth-stencil buffer
	memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat));
	pPF->pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag
	pPF->pfd.cColorBits		= cColorBits;
	pPF->pfd.cRedBits		= cRedBits;
	pPF->pfd.cGreenBits		= cGreenBits;
	pPF->pfd.cBlueBits		= cBlueBits;
	pPF->pfd.cAlphaBits		= cAlphaBits;
	pPF->pfd.cDepthBits		= 0;
	pPF->pfd.cStencilBits	= 0;
	pPF->dwDriverData		= D3DX_SF_UNKNOWN;
	pPF++;*/

	for (i=0; i<nSupportedFormats; i++, pPF++) {
		memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat));
		pPF->pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag
		pPF->pfd.cColorBits		= cColorBits;
		pPF->pfd.cRedBits		= cRedBits;
		pPF->pfd.cGreenBits		= cGreenBits;
		pPF->pfd.cBlueBits		= cBlueBits;
		pPF->pfd.cAlphaBits		= cAlphaBits;
		_BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits);
		pPF->dwDriverData		= fmt[i];
	}

	//
	// Add double-buffer formats
	//

/*	memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat));
	pPF->pfd.cColorBits		= cColorBits;
	pPF->pfd.cRedBits		= cRedBits;
	pPF->pfd.cGreenBits		= cGreenBits;
	pPF->pfd.cBlueBits		= cBlueBits;
	pPF->pfd.cAlphaBits		= cAlphaBits;
	pPF->pfd.cDepthBits		= 0;
	pPF->pfd.cStencilBits	= 0;
	pPF->dwDriverData		= D3DX_SF_UNKNOWN;
	pPF++;*/

	for (i=0; i<nSupportedFormats; i++, pPF++) {
		memcpy(pPF, &pfTemplateHW, sizeof(DGL_pixelFormat));
		pPF->pfd.cColorBits		= cColorBits;
		pPF->pfd.cRedBits		= cRedBits;
		pPF->pfd.cGreenBits		= cGreenBits;
		pPF->pfd.cBlueBits		= cBlueBits;
		pPF->pfd.cAlphaBits		= cAlphaBits;
		_BitsFromDepthStencilFormat(fmt[i], &pPF->pfd.cDepthBits, &pPF->pfd.cStencilBits);
		pPF->dwDriverData		= fmt[i];
	}

	// Popup warning message if non RGB color mode
	{
		// This is a hack. KeithH
		HDC hdcDesktop = GetDC(NULL);
		DWORD dwDisplayBitDepth = GetDeviceCaps(hdcDesktop, BITSPIXEL);
		ReleaseDC(0, hdcDesktop);
		if (dwDisplayBitDepth <= 8) {
			ddlogPrintf(DDLOG_WARN, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth);
			MessageBox(NULL, szColorDepthWarning, "GLDirect", MB_OK | MB_ICONWARNING);
		}
	}

	// Mark list as 'current'
	glb.bPixelformatsDirty = FALSE;

	return TRUE;
}
Exemplo n.º 5
0
static GLboolean gld_d3d_render_stage_run(
	GLcontext *ctx,
	struct tnl_pipeline_stage *stage)
{
	GLD_context				*gldCtx	= GLD_GET_CONTEXT(ctx);
	GLD_driver_dx7			*gld	= GLD_GET_DX7_DRIVER(gldCtx);

	TNLcontext				*tnl;
	struct vertex_buffer	*VB;
	tnl_render_func				*tab;
	GLint					pass;
	GLD_pb_dx7				*gldPB = &gld->PB3d;
	DWORD					dwFlags;

/*
	static int count = 0;
	count++;
	if (count != 2)
		return GL_FALSE;
*/
	// The "check" function should disable this stage,
	// but we'll test gld->bUseMesaTnL anyway.
	if (gld->bUseMesaTnL) {
		// Do nothing in this stage, but continue pipeline
		return GL_TRUE;
	}
	
	tnl = TNL_CONTEXT(ctx);
	VB = &tnl->vb;
	pass = 0;

   tnl->Driver.Render.Start( ctx );

#if 0
   // For debugging: Useful to see if an app passes colour data in
   // an unusual format.
   switch (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->Type) {
   case GL_FLOAT:
	   ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n");
	   break;
   case GL_UNSIGNED_BYTE:
	   ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_UNSIGNED_BYTE\n");
	   break;
   default:
	   ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: *?*\n");
	   break;
   }
#endif

   tnl->Driver.Render.Points		= gld_Points3D_DX7;
   if (ctx->_TriangleCaps & DD_FLATSHADE) {
	   tnl->Driver.Render.Line		= gld_Line3DFlat_DX7;
	   tnl->Driver.Render.Triangle	= gld_Triangle3DFlat_DX7;
	   tnl->Driver.Render.Quad		= gld_Quad3DFlat_DX7;
   } else {
	   tnl->Driver.Render.Line		= gld_Line3DSmooth_DX7;
	   tnl->Driver.Render.Triangle	= gld_Triangle3DSmooth_DX7;
	   tnl->Driver.Render.Quad		= gld_Quad3DSmooth_DX7;
   }

//	_GLD_DX7_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD));
	dwFlags = DDLOCK_DISCARDCONTENTS | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY;
	_GLD_DX7_VB(Lock(gldPB->pVB, dwFlags, &gldPB->pPoints, NULL));
	gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0;
	// Allocate primitive pointers
	// gldPB->pPoints is always first
	gldPB->pLines		= gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine);
	gldPB->pTriangles	= gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle);
	
	ASSERT(tnl->Driver.Render.BuildVertices);
	ASSERT(tnl->Driver.Render.PrimitiveNotify);
	ASSERT(tnl->Driver.Render.Points);
	ASSERT(tnl->Driver.Render.Line);
	ASSERT(tnl->Driver.Render.Triangle);
	ASSERT(tnl->Driver.Render.Quad);
	ASSERT(tnl->Driver.Render.ResetLineStipple);
	ASSERT(tnl->Driver.Render.Interp);
	ASSERT(tnl->Driver.Render.CopyPV);
	ASSERT(tnl->Driver.Render.ClippedLine);
	ASSERT(tnl->Driver.Render.ClippedPolygon);
	ASSERT(tnl->Driver.Render.Finish);

	tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts);
	
	do {
		GLuint i, length, flags = 0;
		for (i = 0 ; !(flags & PRIM_END) ; i += length)
		{
			flags = VB->Primitive[i].mode;
			length= VB->Primitive[i].count;
			ASSERT(length || (flags & PRIM_END));
			ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1);
			if (length)
				tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
		}
	} while (tnl->Driver.Render.Multipass &&
		tnl->Driver.Render.Multipass( ctx, ++pass ));
	
	_GLD_DX7_VB(Unlock(gldPB->pVB));

//	_GLD_DX7_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, gldPB->dwStride));

	_GLD_DX7_DEV(SetTransform(gld->pDev, D3DTRANSFORMSTATE_PROJECTION, &gld->matProjection));
	_GLD_DX7_DEV(SetTransform(gld->pDev, D3DTRANSFORMSTATE_WORLD, &gld->matModelView));

	if (gldPB->nPoints) {
//		_GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints));
		_GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_POINTLIST, gldPB->pVB, 0, gldPB->nPoints, 0));
		gldPB->nPoints = 0;
	}

	if (gldPB->nLines) {
//		_GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines));
		_GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_LINELIST, gldPB->pVB, gldPB->iFirstLine, gldPB->nLines, 0));
		gldPB->nLines = 0;
	}

	if (gldPB->nTriangles) {
//		_GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles));
		_GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_TRIANGLELIST, gldPB->pVB, gldPB->iFirstTriangle, gldPB->nTriangles, 0));
		gldPB->nTriangles = 0;
	}

	return GL_FALSE;		/* finished the pipe */
}