Jump to content

  • Log In with Google      Sign In   
  • Create Account


CrescentFresh

Member Since 12 Mar 2006
Offline Last Active Mar 26 2013 02:32 PM
-----

Topics I've Started

Recover full screen device, procedurally from other process.

26 February 2013 - 03:38 PM

I have a multi-monitor, multi-full screen dx9 device setup that need to work hand-in-hand with another process. This other process can make the dx9 app minimize so it can take the active foreground window... and when it's done, it signals the dx9 app (via local telnet) to recover itself and become active again. 

 

My finished product needs to accomplish this procedurally, as in I cannot use any input devices to either alt-tab or click the dx9 app in taskbar with mouse. When I try to do it procedurally, the different recovery code I've tried has managed to create two different outcomes.

 

  • The dx9 app does maximize, and recovers... but when I click the screen, if any windows are behind the game it immediately loses focus, as if the dx9 app is only rendering overtop the other windows but not actually there.
  • Or, the game comes back up, but shows only a white screen and the device is reports 'D3DERR_DEVICELOST', and never makes it to 'D3DERR_DEVICENOTRESET'... but if you actually click the screen it receives the input properly and plays the game.

 

I'm almost certain I'm freeing all the dx resources that I need to be, and that it's got to be some sort of focus issue.

 

I'm also aware that AllowSetForegroundWindow(), needs to present in the other process to be able to give up focus, and it is being called.

 

The dx9 app is a fairly large engine, so posting the code is a concise matter will be difficult, below is the general idea of things:

 

 All code is from dx9 app:

//
// A message comes in whether to minimize/maximize
if(m_bMinimize)
{
    LOG("minimize!");
    ShowWindow(deviceRef.GetWnd(), SW_MINIMIZE);//SW_HIDE);
}
else
{
    LOG("MAXIMIZE!");
    ShowWindow(deviceRef.GetWnd(), SW_SHOWNORMAL);
    SetForegroundWindow(deviceRef.GetWnd());
}

 

The below function CheckDevice() is called at the beginning of the render thread loop. It returns whether or not the device is okay.

// Returns true if it's okay to render
bool LtGRenderThread::CheckDevice()
{
    if(m_bLostDevice)
    {
        int j = 0;
	for(j = 0; j < m_iNumDevices; j++) //for(int j = m_iNumDevices-1; j >= 0; --j)
	{
	    HRESULT result = m_pDevices[j].m_pD3DDevice->TestCooperativeLevel();
	    if(FAILED(result))
	    {
	        if(D3DERR_DEVICENOTRESET == result)
		{
		    HRESULT result2 = m_pDevices[j].m_pD3DDevice->Reset(&m_pDevices[j].m_tPresentParams);

		    if(FAILED(result2))
		    {
			LOGF("Device %i: reset failed: %u", LOG_NORMAL, j, result2);			                                              }
		    else
		    {
			LOGF("Device %i: Reset successful...", LOG_NORMAL, j);
		    }
		}
                    break;
		
            }
	    else
	        LOGF("DEVICE %i has recovered!", LOG_TODO, j);
	}

	if(j == m_iNumDevices)
	{
	    LOG("Reloading all vRAM...");

	    for(j = 0; j < m_iNumDevices; j++)
	    {
	        m_pDevices[j].OnResetDevice();
	    }
	
	    // Tell Update thread that we need to reset the device
	    m_MsgManRef.MarkFlag(MSGMAN_ResetDevice);

	    m_bLostDevice = false;
        }
    }
    else
    {
	for(int j = 0; j < m_iNumDevices; j++)
	{
            HRESULT result = m_pDevices[j].m_pD3DDevice->TestCooperativeLevel();
	    if(FAILED(result) || m_pDevices[j].IsForceReset())
	    {
		LOG("A device has been lost! (Or forced to reset)");

		m_bLostDevice = true;
				
		// Clear out all DX resources
		for(int i = 0; i < m_iNumDevices; i++)
		    m_pDevices[i].OnLostDevice();

		m_MsgManRef.MarkFlag(MSGMAN_LostDevice);

	        break;
	    }
        }
    }
	
    return !m_bLostDevice;
}

 

 

I'm pretty sure no one is going to respond to this mess. But I'll just try to be hopeful that someone has some experience in doing something similar to this. Thanks for reading.


Multithreaded renderer (with multiple devices)

18 December 2012 - 01:20 PM

I have a directx 9 application that needs to run on a Windows XP (embedded) machine with two monitors.

My first iteration of the renderer was a single IDirect3DDevice9 object and then I IDirect3DDevice9::CreateAdditionalSwapChain() per "screen", which rendered out multiple 'windows' positioned and sized to simulate full screen.

This worked well, however I'd get lots of screen tearing since I used D3DPRESENT_INTERVAL_IMMEDIATE within the presentation parameters because I don't want to stall the updates waiting for vBlank. Also, I assume that with only one device querying one adapter, I'd not be able to safely assume the vBlank period for both monitors, only the 'main' monitor.

So this lead me to re-writing the renderer to use multiple devices (one for each monitor), and each device has its own adapter for its respective monitor. For my purposes, this is working just as well as the additional swap chains method, however I'm back to the same issue of tearing since the alternative is stalling the main thread twice for both vBlank's, which leads to unacceptable framerate jittering.

 
If I were to put forth the incredible amount of effort of rewriting my engine to be a multi-threaded renderer, will this solve my screen tearing issue? More specifically, am I able to create a thread for each device and render/present them independently? If I must keep all DX API calls on the same thread (which I believe is the case), will stalling multiple times waiting for vBlank still allow me to achieve a 60hz FPS?

-or-

Is there an easier way to know when to invoke IDirect3DSwapChain9::Present() without D3DPRESENT_INTERVAL_DEFAULT and on a single thread?

I've tried polling IDirect3DSwapChain9::GetRasterStatus() to manually present an already rendered backbuffer in the vBlank period (per device/monitor), but that doesn't seem to be accurate enough as I still get tearing.

Vsync window mode questions

27 October 2011 - 01:22 PM

I have an application that needs to run on a duel monitor chassis, and have created two windows with two swap chains, positioned and sized to simulate full screen. My device is set to windowed mode.

The way I'm currently handling screen tearing is by setting PresentParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE, and manually checking for vertical blank using SwapChain::GetRasterStatus() before rendering, otherwise skipping it until next update loop.

My issue is that I still get tearing, but near the top of the screen. Is this because my rendering is taking a little too long, and we leave vBlank before I present?

Also, in my case where I have two monitors and I'm rendering in Windowed mode, how does GetRasterStatus() know which monitor to query? What's stopping me from placing the window between the extended desktop?

When I set PresetnParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT without manually checking for vertical blank, my updates and rendering are throttled to 60FPS (obviously) and gets rid of tearing, but it produces inconsistent framerates which aren't acceptable.

When I set PresetnParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT and also manually check for vertical blank my rendering drops from 60FPS -> 30FPS... so it seems to be missing every other vBlank.

Any ideas?

[C++ DX9] Slow Down after losing window focus

25 October 2011 - 09:12 AM

I have a DX9 application that creates two windows and renders to each of them. These windows are not full-screen mode, they are windowed mode set to the system's resolution size to emulate full-screen. Everything works fine until the user either alt-tabs or minimizes the window, which the framerate is noticeably slower when they return.

-BEFORE LOSING FOCUS-
Update FPS: ~63000
Render FPS: 60 (throttled to match vSync)

-AFTER LOSING FOCUS AND RETURNING-
Update FPS: ~25000
Render FPS: 30

I find it odd that the render frames are cut in half perfectly*, however the update frames are cut significantly as well so it's clear I'm not getting the same CPU time slice from the OS prior to losing focus. This application is running on an XP Embedded OS system that is pretty bare bones. When I test this same scenario on my dev machine, which is Windows 7 64bit, I don't have this issue.

*Now that I think about it... my rendering is on the same thread as the updates are. I just skip the rendering portion if we're not in vSync. I'm starting to think now that since my updates are cut down, I'm missing every other vSync occurrence. It still doesn't explain why my updates are slow when returning focus though, if anyone has any input on that please let me know.

Thanks!

Can I render polygons over ID3DXSprite?

14 October 2011 - 10:29 AM

Can I render polygons/(orthographic 3D data) over ID3DXSprite? If so how is this done? Are there any good examples on D3DXSPRITE_OBJECTSPACE? I already have everything set up to use screen coordinates and like to keep it that way. Thanks.

PARTNERS