Fehler bei DirectX11 ?

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Fehler bei DirectX11 ?

Beitrag von gdsWizard »

Hallo,

ich schreibe an der 2.Version vom Softcube Designer und habe auf DirectX11 umgestellt. Nun habe ich aber das Problem das sich das Programm nach tausenden Aufraufen von "pSurface->GetDC" oder bei "pDeviceContext->Map( *ppTexture, 0, D3D11_MAP_READ, 0, pSubResource )" aufhängt. Der Thread kommt einfach nicht aus einer der beiden Funktionen zurück. Es gibt keine Fehlermeldung, Exception oder ähnliches. Auch keine Meldungen von DirectX das etwas nicht stimmt.

Nachfolgend die beiden Funktionen

Code: Alles auswählen

bool fxgRenderTargetPresent::GetDC( HDC *pHDC, ID3D11Texture2D **ppBackBuffer, IDXGISurface1 **ppDXGISurface)
{
	if (m_pSwapChain==NULL)
		return false;

	if (S_OK!=m_pSwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), (void **)ppBackBuffer))
	{
		return false;
	}

	if (S_OK!=(*ppBackBuffer)->QueryInterface(__uuidof(IDXGISurface1), (void **)(ppDXGISurface)))
	{
		(*ppBackBuffer)->Release();

		return false;
	}

        // hier hängt er sich dann auf ************************************************************

	if (S_OK!=(*ppDXGISurface)->GetDC( false, pHDC ))
	{
		(*ppDXGISurface)->Release();

		(*ppBackBuffer)->Release();

		return false;
	}

	return true;
}

Code: Alles auswählen

bool fxgRenderTargetPickup::GetBuffer(ID3D11Texture2D **ppTexture,D3D11_TEXTURE2D_DESC *pTexDescr,D3D11_MAPPED_SUBRESOURCE *pSubResource)
{
	ID3D11Texture2D			*pPresentBackBuffer;

	GetRenderTargetPresent()->UnSetRenderTargets();

	if ( !GetRenderTargetPresent()->GetBuffer( &pPresentBackBuffer ))
		return false;


	pPresentBackBuffer->GetDesc(pTexDescr);

	pTexDescr->CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	pTexDescr->Usage = D3D11_USAGE_STAGING;
	pTexDescr->BindFlags = 0;
	pTexDescr->MiscFlags = 0;

	if (S_OK!=GetRenderDevice()->GetD3DDevice()->CreateTexture2D( pTexDescr, NULL, ppTexture ))
	{
		pPresentBackBuffer->Release();

		return false;
	}

	GetRenderDevice()->GetDeviceContext()->CopyResource( *ppTexture, pPresentBackBuffer );



        // hier ist der andere Funktionsaufruf bei der er nicht zurück kommt *****************************************************************

	if (S_OK!=GetRenderDevice()->GetDeviceContext()->Map( *ppTexture, 0, D3D11_MAP_READ, /*D3D11_MAP_FLAG_DO_NOT_WAIT*/0, pSubResource ))
	{
		GetRenderDevice()->GetApplication()->Trace("Map Error");

		(*ppTexture)->Release();

		pPresentBackBuffer->Release();

		return false;
	}

	pPresentBackBuffer->Release();

	return true;
}

Wie bereits geschrieben hängt er sich erst nach einiger Zeit auf. Deshalb kann ich den Fehler nur schwer reproduzieren.

Hat jemand Tipps oder eine Idee ?
Benutzeravatar
dot
Establishment
Beiträge: 1746
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von dot »

Ich kann dir nur schwer empfehlen Smartpointer zu benutzen. Gut möglich, dass du irgendwo einfach vergisst was zu releasen. Was sagt eigentlich die Debugruntime?
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von gdsWizard »

Die debug runtime sagt auch nix , also keine Fehlermeldungen. Smartpointer würden natürlich auch Fehler ausschliessen. Ich muß aber erst mal googeln was es da bereits Fertiges gibt. Aber einen Versuch ist es wert.

Danke für den Tipp.
Benutzeravatar
dot
Establishment
Beiträge: 1746
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von dot »

http://msdn.microsoft.com/en-us/library/417w8b3b.aspx
http://msdn.microsoft.com/en-us/library/ezzw7k98.aspx

Code: Alles auswählen

#ifndef COMPTR_INCLUDED
#define COMPTR_INCLUDED

#pragma once


template <class T>
class com_ptr
{
private:
  T* ptr;

  static void release(T* ptr)
  {
    if (ptr)
      ptr->Release();
  }

  static void acquire(T* ptr)
  {
    if (ptr)
      ptr->AddRef();
  }

public:
  com_ptr(T* ptr = nullptr)
    : ptr(ptr)
  {
  }

  com_ptr(const com_ptr& p)
    : ptr(p.ptr)
  {
    acquire(ptr);
  }

  com_ptr(com_ptr&& p)
    : ptr(p.ptr)
  {
    p.ptr = nullptr;
  }

  ~com_ptr()
  {
    release(ptr);
  }

  com_ptr& operator =(const com_ptr& p)
  {
    acquire(p.ptr);
    release(ptr);
    ptr = p.ptr;
    return *this;
  }

  com_ptr& operator =(com_ptr&& p)
  {
    std::swap(ptr, p.ptr);
    return *this;
  }

  void release()
  {
    release(ptr);
    ptr = nullptr;
  }

  T* operator ->() const { return ptr; }

  operator T*() const { return ptr; }

  T** operator &() { return &ptr; }

};


#endif  // COMPTR_INCLUDED
;)
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von gdsWizard »

Du bist aber fix. Ich werde mich nach dem Mittag gleich dran machen und vielleicht kann ich heute noch schreiben ob es das schon war. Jetzt gibt es erst mal Mittag. :) Danke
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von CodingCat »

Ich schlage folgende Änderungen vor:
  • explicit com_ptr(T* ptr = nullptr) [...],
    denn gerade mit dem impliziten Raw-Pointer-Cast und somit weiteren rumfliegenden Raw-Pointers bindet man sonst evtl. sehr schnell dieselbe Referenz mehrfach an verschiedene com_ptrs
  • T** operator &() { return &ptr; }

    Code: Alles auswählen

    T** rebind()
    {
       release();
       return &ptr;
    }
    Überladung von operator & vermeide ich praktisch immer. In diesem konkreten Fall hat der Operator außerdem das Problem, dass er bei der typischen COM-Akquisitation Get*(&ptr) bereits zuvor an ptr gebundenen Referenzen leakt.
  • T*const& get() const { return ptr; } ersetzt die andere Hälfte des überladenen operator &, weil DirectX 11 gerne mal Arrays von konstanten Zeigern erwartet.
Zuletzt geändert von CodingCat am 01.11.2011, 12:02, insgesamt 4-mal geändert.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von CodingCat »

Eine noch etwas andere Bindungssemantik habe ich in meine eigenen com_ptr-Implementierung in lean, wenn sich jemand dafür interessiert. ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von gdsWizard »

Das der Fehler erst nach tausenden Aufrufen auftritt spricht schon für eine fehlende Freigabe. Danke für die Implementierungen, die schaue ich mir genau an :)

Jetzt gibt es aber wirklich Mittag
Benutzeravatar
dot
Establishment
Beiträge: 1746
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von dot »

Ich hab mir schon lang keine Gedanken mehr über meinen com_ptr gemacht, das sind ein paar wirklich gute Ideen, Danke :)
Vor allem das Leak beim Rebind ist mir teilweise echt schon auf die Nerven gegangen, aber irgendwie hab ich nie versucht was dagegen zu unternehmen :mrgreen:
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von gdsWizard »

Hallo,

der Bug tritt immer noch auf. Ich erzeuge die Buffer inzwischen auch nicht mehr dynamisch sondern nur noch bei einem resize. Ich verwende überall jetzt ein Pointer Template. Da ich die Buffer nicht mehr dynamisch erzeuge scheiden AddRef und Release eigentlich auch aus. Inzwischen gehen mir die Ideen aus. Wie gesagt er kommt einfach aus den Funktionen nicht mehr heraus und verbraucht einen ganzen Kern weil er igrendwas macht.

Das mit den Smartpointern wollte ich eigentlich auch schon früher mal machen, aber irgendwie hatte ich die aus den Augen verloren. :)

Vielleicht hat noch jemand eine Idee oder einen Tipp ?
gdsWizard
Establishment
Beiträge: 237
Registriert: 04.02.2005, 09:12
Benutzertext: www.gamedevstudio.com
Echter Name: Thomas Mittelsdorf
Wohnort: Meiningen
Kontaktdaten:

Re: Fehler bei DirectX11 ?

Beitrag von gdsWizard »

Ich habe eben einen neuen Treiber von nvidia gesaugt und installiert. Jetzt scheint das Problem nicht mehr aufzutauchen. Da ich aber den Fehler nicht richtig reproduzieren kann muß ich das noch eine Weile testen.
Bin gespannt ob es jetzt weiterhin klappt.

Danke an nvidia für das 4 tägige sinnlose Fehlersuchen.
Antworten