D3D 9 und floating point precision



  • Wenn ich will dass mein eigener Code mit voller FPU precision rechnet, muss ich dann D3DCREATE_FPU_PRESERVE setzen?
    Die Berechnungen von D3D selbst sind mir hübsch egal, die sollen ruhig mit _PC_53 oder sogar _PC_24 laufen.
    Bei meinen eigenen Sachen hätte ich aber schon gern _PC_64.

    Die MSDN sagt dazu

    MSDN schrieb:

    D3DCREATE_FPU_PRESERVE

    Set the precision for Direct3D floating-point calculations to the precision used by the calling thread. If you do not specify this flag, Direct3D defaults to single-precision round-to-nearest mode for two reasons:
    * Double-precision mode will reduce Direct3D performance.
    * Portions of Direct3D assume floating-point unit exceptions are masked; unmasking these exceptions may result in undefined behavior.

    Ob D3D ohne D3DCREATE_FPU_PRESERVE die Genauigkeit auch ausserhalb von D3D Calls runterschraubt, steht aber nicht da.

    Und nochwas: Windows "merkt" sich die FP Flags ja angeblich pro Thread. D.h. wenn ich zwei Threads bereits laufen habe, und in einem Thread _controlfp() mache, dann darf das keinen Einfluss auf den anderen Thread haben. Kann das jemand bestätigen? (Also dass es funktioniert, nicht dass es so sein sollte :))


  • Mod

    hustbaer schrieb:

    Wenn ich will dass mein eigener Code mit voller FPU precision rechnet, muss ich dann D3DCREATE_FPU_PRESERVE setzen?
    Die Berechnungen von D3D selbst sind mir hübsch egal, die sollen ruhig mit _PC_53 oder sogar _PC_24 laufen.
    Bei meinen eigenen Sachen hätte ich aber schon gern _PC_64.

    64bit ist nur fpu intern, falls du in c(++) mit doubles rechnest, kannst du nur von 53 ausgehen

    Ob D3D ohne D3DCREATE_FPU_PRESERVE die Genauigkeit auch ausserhalb von D3D Calls runterschraubt, steht aber nicht da.

    bei d3dcreate wird auf 24 geschaltet.

    Und nochwas: Windows "merkt" sich die FP Flags ja angeblich pro Thread. D.h. wenn ich zwei Threads bereits laufen habe, und in einem Thread _controlfp() mache, dann darf das keinen Einfluss auf den anderen Thread haben. Kann das jemand bestätigen? (Also dass es funktioniert, nicht dass es so sein sollte :))

    jeder thread hat sein eigenes register set, windows muss diese gesondert halten, sonst waere _controlfp sinnfrei, entsprechend kannst du deine unterhose darauf verwetten dass es auch so ist.

    btw. precisionsflags wirken sich nur auf zwei instruktionen aus, divide und sqrt. mul, add etc. wird keinen unterschied machen.



  • Oops, ja, das mit den 64/54 Bit hab ich übersehen/nicht dran gedacht. Ist aber OK, mir reichen 54 Bit auch vollkommen. 24 sind halt ... u.U. grenzwertig.

    rapso schrieb:

    Ob D3D ohne D3DCREATE_FPU_PRESERVE die Genauigkeit auch ausserhalb von D3D Calls runterschraubt, steht aber nicht da.

    bei d3dcreate wird auf 24 geschaltet.

    OK.
    Was muss/soll ich also machen, wenn ich in meinem Programm mit 54 Bit Precision rechnen will?
    Einfach vor CreateDevice () auf double precision, round-to-nearest und exeptions=masked schalten, und dann D3DCREATE_FPU_PRESERVE übergeben?

    Oder vor/nach jedem D3D Aufruf _controlfp() machen?

    rapso schrieb:

    jeder thread hat sein eigenes register set, windows muss diese gesondert halten, sonst waere _controlfp sinnfrei, entsprechend kannst du deine unterhose darauf verwetten dass es auch so ist.

    Naja, _controlfp könnte prozessweit gelten (bei systemweit ist mir auch klar dass es nicht so sein kann :)). Zugegebenermassen recht weit hergeholt, aber ich wollte sicherheitshalber nochmal nachfragen.

    ps: kann es sein, dass _controlfp(0, 0) den Returnwert nicht aus den CPU Registern holt, sondern da irgendwo was böse cachen tut? Ich hab' nämlich bereits mit _controlfp(0, 0) "geguckt was eingestellt ist", und da hab ich 64 Bit Precision zurückbekommen. Trotzdem habe ich (ohne jeglichen _controlfp() Aufruf) nach einem einzigen div einen relativen Fehler in der Grössenordnung von e-8 (was ja ziemlich genau zu 24 Bit Precision passt).


Log in to reply