DX11 Resize von SwapChain bei Multithreading
Verfasst: 31.05.2013, 21:54
Hallo zusammen,
ich bastel gerade wieder etwas mit DirectX11 rum und habe mir gedacht, auch mal etwas in Richtung Multithreading dazuzulernen. Ich weiß, dass die ganze Synchronisierung der Objekte und vor allem in Verbindung mit DirectX kein triviales Thema ist. Aber irgendwann muss man damit ja mal anfangen. Also habe ich eine neue Threadklasse erstellt, die von einem ThreadWrapper gestartet und beendet wird. In dem Thread läuft dann die Renderingmethode.
Soweit so gut. Das ganze eingebaut und das Bild wird sauber gerendert. Nun wollte ich auf das Resizen des Fensters reagieren und habe versucht mich dabei an die Anleitung vom MSDN zu halten:
http://msdn.microsoft.com/en-us/library ... w_Resizing
Mein Code sieht dann so aus:
Prinzipiell funktioniert es auch, wenn man Vollbild umschaltet oder Maximiert läuft es wunderbar, wenn ich allerdings am Rand vom Fenster ziehe, läuft es ganz kurz, bis der ganze Rechner stehe oder Windows mit BlueScreen abstürzt. Wenn ich die gleichen Methode ohne eigenen Renderthread benutze, funktioniert auch der Resize.
Ich kann mir auch denken, woran das liegt: Beim Singlethreaded stoppt das Rendern, bis man das Resizen beendet und man bekommt damit die Nachricht nur 1x. Beim Multithreading feuert die WindowProc für jeden Pixel den man die Fenstergröße verändert eine Nachricht, worauf die Resizefunktion aufgerufen wird.
Mir fehlt aber eine gute Idee, wie man damit umgehen soll. Man müsste eigentlich den Thread pausieren, bis das Resizing beendet ist, aber ich komme im Resizing nicht an den Thread heran.
Kann mir jemand sagen, wie ich es besser mache? Oder wie macht ihr das mit dem Resizing? Vielleicht stimmt bei mir auch etwas mit den Threadlocks noch nicht...
ich bastel gerade wieder etwas mit DirectX11 rum und habe mir gedacht, auch mal etwas in Richtung Multithreading dazuzulernen. Ich weiß, dass die ganze Synchronisierung der Objekte und vor allem in Verbindung mit DirectX kein triviales Thema ist. Aber irgendwann muss man damit ja mal anfangen. Also habe ich eine neue Threadklasse erstellt, die von einem ThreadWrapper gestartet und beendet wird. In dem Thread läuft dann die Renderingmethode.
Soweit so gut. Das ganze eingebaut und das Bild wird sauber gerendert. Nun wollte ich auf das Resizen des Fensters reagieren und habe versucht mich dabei an die Anleitung vom MSDN zu halten:
http://msdn.microsoft.com/en-us/library ... w_Resizing
Mein Code sieht dann so aus:
Code: Alles auswählen
void CRenderWindowDX11::Resize(uint16 width,uint16 height)
{
m_critSection.Enter();
if(CRenderTargetDX11::GetCurrentRenderTarget()==m_renderTarget)
{
((CRenderEngineDX11*)m_engine)->GetDeviceContext()->OMSetRenderTargets(0, 0, 0);
}
((CRenderTargetDX11*)m_renderTarget)->Resize(width,height,m_swapChain);
if(CRenderTargetDX11::GetCurrentRenderTarget()==m_renderTarget)
{
m_renderTarget->Apply();
}
m_critSection.Leave();
}
void CRenderTargetDX11::Resize(uint16 width,uint16 height,IDXGISwapChain* swapChain)
{
m_critSection.Enter();
ClearRenderTargetViews();
TextureListIterator it = m_renderTargetTexture.begin();
for(;it!=m_renderTargetTexture.end();it++)
{
((CTextureDX11*)(*it).get())->Release();
}
uint16 i=0;
if(swapChain)
{
HRESULT result;
// Preserve the existing buffer count and format.
// Automatically choose the width and height to match the client rect for HWNDs.
result = swapChain->ResizeBuffers(0, width, height, DXGI_FORMAT_UNKNOWN, 0);
if(FAILED(result))
{
return;
}
ID3D11Texture2D* backBufferPtr;
result = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
if(FAILED(result))
{
return;
}
STexture backBuffer = ((CFactoryTextureDX11*)CFactoryTextureDX11::getInstance())->createTextureFromDX11Tex(backBufferPtr);
BindTexture(0,backBuffer);
SAFE_RELEASE(backBufferPtr)
i++;
}
for(;i<m_renderTargetTexture.size();i++)
{
STexture tex = ((CFactoryTextureDX11*)CFactoryTextureDX11::getInstance())->createTexture(width,height,m_renderTargetTexture[i]->getFormat(),false);
BindTexture(i,tex);
}
m_critSection.Leave();
}
Ich kann mir auch denken, woran das liegt: Beim Singlethreaded stoppt das Rendern, bis man das Resizen beendet und man bekommt damit die Nachricht nur 1x. Beim Multithreading feuert die WindowProc für jeden Pixel den man die Fenstergröße verändert eine Nachricht, worauf die Resizefunktion aufgerufen wird.
Mir fehlt aber eine gute Idee, wie man damit umgehen soll. Man müsste eigentlich den Thread pausieren, bis das Resizing beendet ist, aber ich komme im Resizing nicht an den Thread heran.
Kann mir jemand sagen, wie ich es besser mache? Oder wie macht ihr das mit dem Resizing? Vielleicht stimmt bei mir auch etwas mit den Threadlocks noch nicht...