[Gelöst] Effects11 CompileEffectFromFile im Release funktioniert nicht



  • Hallo alle zusammen,

    heute habe ich die Konfiguration von Debug auf Release geschalten und musste dabei feststellen dass mein Projekt plötzlich nicht mehr funktioniert.
    Ich habe mir einen Basis Shader Klasse erstellt welche die grundlegenden Pointer hält und eine virtuelle Funktion hat die den Shader compilieren soll.
    So weit so gut. Im Debug funktioniert alles wunderbar, doch im Release ist mein m_effect Pointer immer null und ich komme einfach nicht drauf woran das liegen könnte.
    Genau so seltsam ist aber auch dass ich im Debug ein "warning X4717" erhalte und im Release nicht.

    So erstelle compiliere ich den Shader:

    #ifndef __SHADER_H__
    #define __SHADER_H__
    
    //...
    
    class Shader
    {
    public:
    	//...
    	virtual bool CreateShaderFromFile( ID3D11Device* _device, std::wstring _shaderFile )
    	{
    		ID3D10Blob* errorMsgs = 00;
    
    		HR( D3DX11CompileEffectFromFile( _shaderFile.c_str(), 00, 00, 1 << 15, 0, _device, &m_effect, &errorMsgs ) );
    
    		if(errorMsgs != 00)
    		{
    			MessageBoxA( 0, static_cast<char*>(errorMsgs->GetBufferPointer()), 0, MB_OK );
    			Memory::ReleaseCom( errorMsgs );
    		}
    
    		if(m_effect == 00)
    		{
    			return false;
    		}
    
    		return true;
    	}
    	//...
    
    protected:
    	ID3DX11Effect*			m_effect;
    	//...
    };
    
    #endif //__SHADER_H__
    

    Falls ich irgendwas wichtiges vergessen habe einfach bescheid geben und ich werde es hinzufügen.

    Gruß BlackArma



  • Wie ist das HR Makro in einem Release Build definiert?



  • Ist so definiert:

    #if defined ( _DEBUG )
    	#ifndef HR
    	#define HR(x)															\
    			{																\
    			HRESULT hr = ( x );												\
    			if(FAILED( hr ))												\
    				{															\
    					DXTrace( __FILEW__, (DWORD)__LINE__, hr, L#x, true );	\
    				}															\
    			}
    	#endif
    #else
    	#define HR(x)	
    #endif
    


  • BlackArma schrieb:

    Ist so definiert:

    #if defined ( _DEBUG )
    	#ifndef HR
    	#define HR(x)															\
    			{																\
    			HRESULT hr = ( x );												\
    			if(FAILED( hr ))												\
    				{															\
    					DXTrace( __FILEW__, (DWORD)__LINE__, hr, L#x, true );	\
    				}															\
    			}
    	#endif
    #else
    	#define HR(x)	
    #endif
    

    Also werden alle x, welche als HR(x) aufgerufen werden, im Release Modus ignoriert. Hier liegt die Antwort.



  • OK.
    Das ist ein reichlich furchtbares Makro. Ich würde das nicht verwenden.
    Und zwar weil
    a) Ich den Namen schrecklich finde (=man kann daraus nicht ableiten was das Ding macht) und
    b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und
    c) Es in Release Builds einfach *nichts* macht - was das Makro mMn. kaum sinnvoll anwendbar macht.

    Wobei sich letzteres leicht beheben liesse indem man es einfach als

    #if defined ( _DEBUG )
    // ...
    #else
    	#define HR(x)	((void)(x))
    #endif
    

    definiert.
    Wenn du dir dann noch einen besseren Namen für das Makro ausdenkst und den darin verwendeten Variablennamen in z.B. hr_CF63361A567D447EA643CA1887CD20E8 änderst, dann wäre das schonmal besser.

    Dann würde nur noch fehlen den darin enthaltenen Scope in ein do { ... } while (false) zu verwandeln.

    BTW: Wo ist dieses HR Makro her?
    Microsoft Header?
    Microsoft Beispielcode?
    Code den du von sonst wo übernommen hast?



  • hustbaer schrieb:

    a) Ich den Namen schrecklich finde (=man kann daraus nicht ableiten was das
    Ding macht) und

    Nicht nur das. Er ist auch kurz und erhöht später die Wahrscheinichkeit von Namenskonflikten. Sag jemand der gerade wieder arglos "windows.h" eingebunden hat, und daraufhin seinen eigenen Code bös vor die Wand gefahren hat ( std::max() und #define max ... in Windows-Headern lassen grüssen, ein Klassiker! :D).

    hustbaer schrieb:

    b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und

    Jo, das ist nicht schön, wenn es sich vermeiden lässt. Aber hat der Code-Block des Makros nicht seinen eigenen Scope und sollte das dort lokale hr nicht dennoch eine eigene lokale Variable sein (Shadowing... wie auch immer der deutsche Ausdruck dafür lauten mag)?

    hustbaer schrieb:

    c) Es in Release Builds einfach *nichts* macht - was das Makro mMn. kaum sinnvoll anwendbar macht.

    Es ist sicherlich auch für den Release sinnvoll das HRESULT auf Fehler zu überprüfen und diese einigermassen zu behandeln (in diesem Fall: "Shader-Datei fehlt/Kann nicht" gelesen werden, oder sowas wie "Shader Model blablub wird von Grafikkarte nicht unterstützt").

    Und noch eine Anregung an BlackArma zu dem Memory::ReleaseCom . Ich weiss zwar nicht, was das für eine Funktion ist, aber vielleicht schaust du dir mal die Klasse Microsoft::WRL:ComPtr an, das ist ein relativ sorgenfreier Smart Pointer für COM-Objekte. Damit kann man sich die ganzen manuellen Release()-Aufrufe sparen, zusammen mit all den Problemen, die damit einhergeben (Exception safety et al.).

    Finnegan



  • hustbaer schrieb:

    OK.
    Das ist ein reichlich furchtbares Makro. Ich würde das nicht verwenden.
    Und zwar weil
    a) Ich den Namen schrecklich finde (=man kann daraus nicht ableiten was das Ding macht) und
    b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und
    c) Es in Release Builds einfach *nichts* macht - was das Makro mMn. kaum sinnvoll anwendbar macht.

    Mit deiner Erklärung kann ich das wundervoll nachvollziehen.

    hustbaer schrieb:

    Wobei sich letzteres leicht beheben liesse indem man es einfach als

    #if defined ( _DEBUG )
    // ...
    #else
    	#define HR(x)	((void)(x))
    #endif
    

    definiert.

    Vielen dank, so funktioniert es!

    hustbaer schrieb:

    Wenn du dir dann noch einen besseren Namen für das Makro ausdenkst und den darin verwendeten Variablennamen in z.B. hr_CF63361A567D447EA643CA1887CD20E8 änderst, dann wäre das schonmal besser.

    Werde ich machen.

    hustbaer schrieb:

    BTW: Wo ist dieses HR Makro her?
    Microsoft Header?
    Microsoft Beispielcode?
    Code den du von sonst wo übernommen hast?

    Das Makro habe ich aus dem Buch "Introduction to 3D Game Programming with Direct3D 11.0" von Frank Luna. Mir fällt auch erst jetzt auf dass ich einfach einen Copy&Past Fehler gemacht habe weshalb es nicht funktionierte.

    Nochmals vielen Dank hustbaer und Finnegan, werde mir eure Ratschläge zu Herzen nehmen!



  • hustbaer schrieb:

    hustbaer schrieb:

    b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und

    Jo, das ist nicht schön, wenn es sich vermeiden lässt. Aber hat der Code-Block des Makros nicht seinen eigenen Scope und sollte das dort lokale hr nicht dennoch eine eigene lokale Variable sein (Shadowing... wie auch immer der deutsche Ausdruck dafür lauten mag)?

    Das Problem ist, dass das Makro beim Aufruf HR(hr) dann zu...

    {
                HRESULT hr = ( hr ); // <---------
                if(FAILED( hr ))
                {
                    DXTrace( __FILEW__, (DWORD)__LINE__, hr, L#x, true );
                }
            }
    

    ...erweitert wird.
    Dummerweise compiliert das, führt aber nicht zu dem Ergebnis das man haben möchte, da das hr bei der Initialisierung der lokalen Variable bereits auf die lokale Variable hr verweist. Man initialisiert die lokale Variable also "mit sich selbst".


Log in to reply