Seite 128 von 252

Re: Jammer-Thread

Verfasst: 25.03.2014, 14:23
von Artificial Mind
Aus dem Windows-Header minwindef.h:

Code: Alles auswählen

#define far
#define near
Aus meinem Code:

Code: Alles auswählen

float near = dist - (set.max_radius + set.size);
float far = dist + (set.max_radius + set.size);
:'(

Re: Jammer-Thread

Verfasst: 25.03.2014, 20:13
von Krishty
Grund #42, keinen fremden Quelltext einzubinden …

————
CodingCat hat geschrieben:
Krishty hat geschrieben:Können wir jetzt bitte virtualisierten Grafikspeicher haben? Dann könnte man die Textur teilen wie alles andere auch – in eine temporäre Memory-Mapped File legen …
So ein Zufall, ab 17 Uhr läuft die Keynote der von NVIDIA veranstalteten GTC:
http://www.pro-clockers.com/forums/showthread.php?p=14215 hat geschrieben:March 25th, 9:00 AM
It's time again for NVIDIA CEO Jen-Hsun Huang to open the annual GPU Tech Conference with a 2-hour keynote. The show's on from 9:00am to 10:50am.

- Preview of the new 20nm high-end Maxwell GPU architecture (GM10x/GeForce 8xx) with unified virtual memory.
- Amazing real-time graphics demos (as always).
- More DirectX 12 goodness.
- OpenGL goodness.
- Demos of the to-be-released CPU-optimized GeForce driver
- GameWorks demos.
- Exciting announcements.

Live Stream
http://www.twitch.tv/nvidia

Related links:
http://www.gputechconf.com
Wundervoll … nur ist meine Online-Präsenz limitiert und Präsentationen sind leider eine der ineffizientesten Arten, Information zu transportieren. Sind irgendwo registrierungsfreie Slides, die ich in 120 Sekunden durchackern kann?

Re: Jammer-Thread

Verfasst: 26.03.2014, 00:52
von CodingCat
Nichts wirklich unerwartetes, demnächst Maxwell-Generation mit Unified Virtual Memory, 2016 dann Pascal-Generation mit 12-24 GB VRAM, 0.5-1 TB/s Bandwidth und schnellem Zugriff auf RAM und Peer GPUs.

Re: Jammer-Thread

Verfasst: 26.03.2014, 01:58
von eXile
Krishty hat geschrieben:Können wir jetzt bitte virtualisierten Grafikspeicher haben? Dann könnte man die Textur teilen wie alles andere auch – in eine temporäre Memory-Mapped File legen …
Virtualisierung ist doch schon seit dem WDDM drin (sogar komplett mit Paging), und zwar im VidMM von dxgkrnl.sys, aber vollkommen uneinsehbar für den User-Mode. Texturen müsstest du aber trotzdem (natürlich ganz anders) teilen können.

Re: Jammer-Thread

Verfasst: 04.04.2014, 10:46
von Krishty
OMG

32-Bit-GetCursorPos() ist nicht /LARGEADDRESSAWARE-kompatibel?!

Microsoft Connect 381683: GetCursorPos fails with large addresses in Large-Address-Aware 32-bit process (WPF)

WHAT THE FUCK

Offenbar ist es mittlerweile ab Vista gepatcht … aber was ist mit XP und /3GB-Switch?

Re: Jammer-Thread

Verfasst: 05.04.2014, 12:11
von Krishty
JPEGs mit Rotationsinformationen in EXIF, wie sie z.B. das iPhone produziert. Sehen unter Windows 7 falsch aus, aber unter Windows 8 richtig. Hat man sie in Windows 7 zurechtrotiert, sehen sie unter Windows 8 falsch aus. WARUM WARUM WARUM

Re: Jammer-Thread

Verfasst: 06.04.2014, 14:06
von anonym

Code: Alles auswählen

 -lz -lpthread -lffi -lcurses -ldl -lm -lLLVMInstrumentation -lLLVMIRReader -lLLVMAsmParser -lLLVMDebugInfo -lLLVMOption -lLLVMLTO -lLLVMLinker -lLLVMipo -lLLVMVectorize -lLLVMBitWriter -lLLVMBitReader -lLLVMTableGen -lLLVMR600CodeGen -lLLVMR600Desc -lLLVMR600Info -lLLVMR600AsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMHexagonCodeGen -lLLVMHexagonAsmPrinter -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMCppBackendCodeGen -lLLVMCppBackendInfo -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMSparcCodeGen -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCDisassembler -lLLVMMCParser -lLLVMInterpreter -lLLVMMCJIT -lLLVMJIT -lLLVMCodeGen -lLLVMObjCARCOpts -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMTarget -lLLVMMC -lLLVMObject -lLLVMCore -lLLVMSupport -lclangFrontendTool -lclangFrontend -lclangDriver -lclangSerialization -lclangCodeGen -lclangParse -lclangSema -lclangStaticAnalyzerFrontend -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangAnalysis -lclangARCMigrate -lclangRewriteFrontend -lclangRewriteCore -lclangEdit -lclangAST -lclangASTMatchers -lclangTooling -lclangLex -lclangBasic
:evil:

Re: Jammer-Thread

Verfasst: 09.04.2014, 09:02
von Krishty
Immerhin sind die Namen aussagekräftig. Es hätte ja auch -li -lirr -lap -ldi -lo -llto -ll … sein können …

do while ist so abgefuckt. Warum kann ich das nicht schreiben?:

  do {
    auto result = operation();
  } while(SUCCESS == result);


Scheiß Geltungsbereiche! Wer hat den Leuten bloß ins Hirn geschissen, das derart zu versemmeln?!

Re: Jammer-Thread

Verfasst: 09.04.2014, 09:33
von xq
@Krishty:
--signed--

Re: Jammer-Thread

Verfasst: 09.04.2014, 14:17
von Krishty
Fortschritt am Berliner Flughafen:
Die Planer haben jetzt ihre Entrauchungsanlage verstanden.
(via fefe)

Wie auf der Arbeit. Da habe ich auch ein halbes Jahr gebraucht um zu verstehen, wie Speichern/Laden implementiert wurde.

Re: Jammer-Thread

Verfasst: 10.04.2014, 11:38
von Krishty
Die Leute müssen endlich aufhören, doppelt und dreifach negierte Sätze zu formulieren. Verdammte Scheiße, wird das Lesen dadurch kompliziert. Als Beispiel Ben Hutchings’ Kommentar von hier:
Windows makes it hard to do one wrong thing, i.e. creating dialogs that don't scale, but it also makes it hard to avoid doing another wrong thing, i.e. creating dialogs that can't be resized manually.
Wartewarte. Findet er manual resizing nun gut oder schlecht? Erstmal vereinfachen:
Windows makes it hard to avoid doing another wrong thing: creating dialogs that can't be resized manually.
hard to avoid doing bedeutet easy to do:
Windows makes it easy to do another wrong thing: creating dialogs that can't be resized manually.
Wenn can't be resized manually wrong ist, dann muss can be resized manually also right sein. Wenn die Falsche Sache easy to do ist, muss die richtige Sache hard to do sein:
Windows makes it hard to do a right thing: creating dialogs that can be resized manually.
Aha. Jetzt verstehe ich den Satz! Danke, dass ich eine Minute meines Lebens auf die Formulierung deiner Meinung verschwendet habe.

Und bitte leitet das an meinen lokalen Nahverkehrsanbieter weiter, denn der sagt
Die Anzeigetafeln funktionieren im Augenblick nicht fehlerfrei.

Re: Jammer-Thread

Verfasst: 13.04.2014, 21:59
von Krishty
WinAPI: Doppelklick auf die Titelleiste eines Fenster maximiert es; löst aber zugleich ein WM_LBUTTONUP aus ohne, dass ein WM_LBUTTONDOWN ankam. Stattdessen kommt vorher ein WM_NCLBUTTONDOWN. Ist man unvorsichtig, löst das einen Klick aus wo keiner sein sollte (hat man auch bei Chrome gemerkt).

Jetzt muss ich zurückverfolgen, ob dem Loslassen der Taste auch ein Drücken auf der Client-Fläche vorausging :( Überall Zustand …

Re: Jammer-Thread

Verfasst: 13.04.2014, 22:20
von CodingCat
Krishty hat geschrieben:Jetzt muss ich zurückverfolgen, ob dem Loslassen der Taste auch ein Drücken auf der Client-Fläche vorausging :( Überall Zustand …
Tatsächlich würde man für die Maus üblicherweise beim Klicken sogar das geklickte Element speichern und nachfolgende Mausnachrichten bis zum Loslassen auf dieses Element beschränken (-> Mouse Capture). Dieses Verhalten ist in nahezu allen Steuerelementen wünschenswert (z.B. Scrollbalken!), Mouse Capture erhöht den Komfort von Benutzeroberflächen teilweise bedeutend (insbesondere verhindert es effektiv versehentliche Ansteuerung). Mit einer Prüfung auf aktives Mouse Capture beim Loslassen fallen die Fehlalarme raus.

Re: Jammer-Thread

Verfasst: 14.04.2014, 09:31
von Krishty
Ja. In diesem konkreten Fall geht es nicht einmal ums Ziehen oder Schieben von irgendwas, sondern ich brauche nur einen Klick und wollte aufs Loslassen warten damit man es sich mittendrin noch anders überlegen kann. Aber wahrscheinlich ist das Fangen der Maus da immernoch die bessere Lösung; vor allem für Fälle wie das Abgleiten der Maus vom Fenster.

Re: Jammer-Thread

Verfasst: 18.04.2014, 23:30
von xq
Warum müssen NVIDIA, Intel und AMD insgesamt 5 verschiedene Compiler für OpenCL C verwenden? Bei 4 gehts, der eine schluckts nicht. 3 kommen mit UTF8 klar, 2 nicht. Was machen die eigentlich alle?

Re: Jammer-Thread

Verfasst: 19.04.2014, 17:06
von antisteo
Also Intel und Amd bauen inzwischen auf Clang auf.

Re: Jammer-Thread

Verfasst: 22.04.2014, 00:17
von glassbear
In dem Moment, als ich mich entscheide doch nicht zur Google IO 2014 zu gehen, landet das Ticket in meiner Inbox :evil: #firstworldproblems

Re: Jammer-Thread

Verfasst: 25.04.2014, 13:54
von antisteo
Ich muss MS Office verwenden, da LO die pptx-Vorlage nicht richtig importieren kann. Dazu muss ich jetzt jedes mal, wenn ich die Präsentation bearbeiten muss, in den PC-Pool gehen.

Re: Jammer-Thread

Verfasst: 09.05.2014, 12:03
von Krishty
Ich lade Bilder via GDI+. Nun hat GDI+ etwas, das Direct3D leider nie konnte: negative Strides. Und die sind für LockBits() sogar ordentlich dokumentiert!
http://msdn.microsoft.com/en-us/data/ms534421(v=vs.98) hat geschrieben:Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.
So weit, so gut.

Jetzt habe ich meine iterier-über-alle-Pixel-Schleifen optimiert und wollte testen, ob der Pfad auch mit negativen Werten funktioniert. Und was, denkt ihr, passiert?

GDI+ verpasst geladenen Bildern niemals negativen Stride. Sogar dann nicht, wenn sie aus einer Bottom-up-Bitmap kommen.

Offenbar tauchen negative Strides nur auf, wenn man entweder
  • selber eine Bitmap erzeugt und dabei manuell negativen Stride angibt; oder
  • eine Bitmap aus einer passenden Win32-HBITMAP erzeugt.
Ich kann als Testfall also nicht einfach eine .bmp reinschmeißen wie ich dachte, sondern darf mir selber einen Testfall programmieren. Klasse!

Re: Jammer-Thread

Verfasst: 16.05.2014, 10:24
von Krishty
MessageBox() funktioniert nicht im Callback von Fensterprozeduren. Und zwar funktioniert es nicht nur einfach nicht, sondern es verursacht eine Zugriffsverletzung.

Das hat ziemlich üble Auswirkungen auf assert()-ähnliche Makros. Wird eine Zusage z.B. während WM_MOUSEMOVE verletzt, löst MessageBox() aus. Das verursacht die Zugriffsverletzung. Jetzt wird es bunt:

Während der Nachrichtenverarbeitung gehört der Aufrufstapel zum Teil Windows. Eine Ausnahme, die in einer WNDPROC auftritt und dort nicht gefangen wird, passiert also DispatchMessage() der WinAPI. Die ist jedoch darauf ausgelegt, die Ausnahme still zu verschlucken und als Fehlschlag der Fensterprozedur zu interpretieren.

Nicht nur kommt kein Nachrichtenfenster, und nicht nur geht das komplett am Debugger vorbei, sondern die Prozedur wurde mittendrin abgebrochen und alle Datenstrukturen, die sie bearbeitet hat, sind inkonsistent. Dann wird die nächste Nachricht verarbeitet, greift auf die kaputten Daten zu, und je nach Art der Nachricht rauscht das Programm dann doch in den Debugger, aber der Fehler ist meilenweit entfernt.

Ich werde also um meine assert()-Implementierung ein

  __try {
    MessageBox();
  } __except(1) { // EXCEPTION_EXECUTE_HANDLER
    __debugbreak();
  }


einbauen, damit der Debugger unter diesen Umständen anhält.

(Bei anderen assert()-Implementierungen, wie denen der MFC, kann es dazu kommen, dass die MessageBox() zwar angezeigt wird, aber viel zu oft. Man sollte den Text auch immer via DebugOutputString() ausgeben, damit man zumindest über die Ausgabekonsole nachvollziehen kann, wann das Unheil seinen Lauf nahm. Und ich befürchte, dass das Verschlucken der Ausnahmen durch einen automatischen Kompatibilitäts-Shim in Windows 8 ausgelöst wird.)

Re: Jammer-Thread

Verfasst: 18.05.2014, 10:28
von Sternmull
Ich finde die "MessageBox bei Assertion"-Geschichte eh ziehmlich witzlos. Im eigenen Code verwende ich deshalb oft "if (badState){__asm{int 3}}". Das triggert den Debugger direkt ohne Message-Box-Hokuspokus und lässt ihn auch im richtigen Frame landen (bei DebugBreak muss ich immer erst ein paar Frames zurück gehen um zur Stelle mit der Assertion zu kommen).

Re: Jammer-Thread

Verfasst: 18.05.2014, 12:23
von Spiele Programmierer
__asm{int 3} gibt es wegen Inlineassembler nicht mehr bei modernen 64 Bit Anwendungen.
Mit "__debugbreak()" sollte es das Problem nicht geben und außerdem meiner Meinung nach nicht bloß portabler sondern auch eleganter.

Re: Jammer-Thread

Verfasst: 18.05.2014, 13:08
von Artificial Mind
Spiele Programmierer hat geschrieben:__asm{int 3} gibt es wegen Inlineassembler nicht mehr bei modernen 64 Bit Anwendungen.
Mit "__debugbreak()" sollte es das Problem nicht geben und außerdem meiner Meinung nach nicht bloß portabler sondern auch eleganter.
So portabel ist __debugbreak nicht, aber es ist wenigstens einfacher dafür ein #define zu schreiben. (Insbesondere da __ in Usercode häufig undefiniertes Verhalten ist, darf sich niemand beschweren wenn #define __debugbreak iwas_anderes irgendwas anderes kaputt macht ;) )
Für gcc/clang gibt es hier ein paar Alternativen: http://stackoverflow.com/questions/1736 ... debugbreak

Re: Jammer-Thread

Verfasst: 18.05.2014, 19:56
von Krishty
Sternmull hat geschrieben:Ich finde die "MessageBox bei Assertion"-Geschichte eh ziehmlich witzlos. Im eigenen Code verwende ich deshalb oft "if (badState){__asm{int 3}}".
Ja; ich benutze die Boxen auch nur bei Eigenprojekten. Sobald andere mitarbeiten neigen sie dazu, die Boxen einfach wegzuklicken.

Ich würde aber trotzdem ein Makro draus machen. Nicht nur aus den Portabilitätsgründen, die die anderen schon genannt haben, sondern auch, weil du dem Compiler darüber Wissen zukommen lassen kannst, das er allein nicht erarbeiten kann. Unter Visual C++ sollte das Makro in Release-Versionen etwa zu __assume(!badState) evaluieren damit der Optimizer die entsprechenden Pfade optimieren kann.

Re: Jammer-Thread

Verfasst: 27.05.2014, 12:50
von Krishty
HeapFree() akzeptiert nicht nur den Anfang des allokierten Bereichs, sondern auch Zeiger in den Speicherbereich hinein. HeapReAlloc() stürzt dann aber einfach mit critical error c0000730 ab. Meh.

Re: Jammer-Thread

Verfasst: 28.05.2014, 21:26
von Krishty
Wenn ich eine bestimmte Anzahl float-Variablen in einer Funktion überschreite, stürzt Visual C++ 2012 mit einem internen Compiler-Fehler ab. Knapp vor der Anzahl werden die Maschinenbefehle fehlerhaft. Deswegen kann ich seit Monaten keine Release-Version meines Editors bauen.

Ich habe es jetzt umgangen, indem ich Variablen in engere Geltungsbereiche gezogen habe.

Re: Jammer-Thread

Verfasst: 28.05.2014, 21:50
von Spiele Programmierer
Wieviele Variablen sind es denn?

Re: Jammer-Thread

Verfasst: 28.05.2014, 21:59
von Krishty
Zähl nach ;)

Code: Alles auswählen

void Foo::triangulate(
	WallSurface & surface,
	float const   minimalHeight,
	float const   maximalHeight,
	float const   uOffset, // for continuous UV along loops
	float const   vOffset, // for continuous UV along loops
	float const   re,
	float const   gr,
	float const   bl
) {
	growCapacity(vertices, 64);
	growCapacity(pickingVertices, 32);

	surface.startOfPickingTriangles = WallTriangleIndex(lengthOf(pickingVertices) / 3);
	surface.startOfTriangles        = WallTriangleIndex(lengthOf(vertices) / 3);
	surface.yMinimum = minimalHeight;
	surface.yMaximum = maximalHeight;

	auto const & a = surface.from;
	auto const & b = surface.to;

	// Picking triangles:
	{
		// Connect the top of the surface to the anchors. This is required to avoid annoying picking issues.
		auto const & anchorA = anchors[surface.anchors[0]].position;
		auto const & anchorB = anchors[surface.anchors[1]].position;
		Math::Point<float, 3> const points[] = {
			{ a.x,       minimalHeight, a.y       },
			{ b.x,       minimalHeight, b.y       },
			{ b.x,       maximalHeight, b.y       },
			{ a.x,       maximalHeight, a.y       },
			{ anchorA.x, maximalHeight, anchorA.y },
			{ anchorB.x, maximalHeight, anchorB.y }
		};

		// Front of the surface:
		*pickingVertices.toEnd++ = points[0];
		*pickingVertices.toEnd++ = points[1];
		*pickingVertices.toEnd++ = points[2];
		*pickingVertices.toEnd++ = points[0];
		*pickingVertices.toEnd++ = points[2];
		*pickingVertices.toEnd++ = points[3];
		// Top:
		*pickingVertices.toEnd++ = points[3];
		*pickingVertices.toEnd++ = points[5];
		*pickingVertices.toEnd++ = points[4];
		*pickingVertices.toEnd++ = points[3];
		*pickingVertices.toEnd++ = points[2];
		*pickingVertices.toEnd++ = points[5];
	}

	// Connect the top of the surface to the anchors. It just looks so much better.
	{
		auto const & anchorA = anchors[surface.anchors[0]].position;
		auto const & anchorB = anchors[surface.anchors[1]].position;
		WallVertex const points[] = {
			{ { b.x,       maximalHeight, b.y       }, { } },
			{ { a.x,       maximalHeight, a.y       }, { } },
			{ { anchorA.x, maximalHeight, anchorA.y }, { } },
			{ { anchorB.x, maximalHeight, anchorB.y }, { } }
		};

		// Top:
		*vertices.toEnd++ = points[1];
		*vertices.toEnd++ = points[2];
		*vertices.toEnd++ = points[3];
		*vertices.toEnd++ = points[1];
		*vertices.toEnd++ = points[3];
		*vertices.toEnd++ = points[0];
	}

	auto const brightnessBottom = 0.2f;
	auto const brightnessCenter = 0.5f;

	auto const brightness_S_B = surface.brightnessStart * brightnessBottom;
	auto const brightness_C_B = brightnessBottom;
	auto const brightness_E_B = surface.brightnessEnd * brightnessBottom;
	auto const brightness_S_C = surface.brightnessStart * brightnessCenter;
	auto const brightness_C_C = brightnessCenter;
	auto const brightness_E_C = surface.brightnessEnd * brightnessCenter;
	auto const brightness_S_T = surface.brightnessStart;
	auto const brightness_C_T = 1.0f;
	auto const brightness_E_T = surface.brightnessEnd;

	if(hasPortal(surface)) {
		auto const & portal = portals[surface.portalIndex];
		auto const length      = distanceBetween(a, b); // * 0.5 because height is 2 (scale uniformly)
		auto const halfWidth   = 0.5f * portal.width;
		auto const stepHeight  = portal.heightBegin;
		auto const totalHeight = portal.heightEnd;
		MUST(portal.heightEnd <= maximalHeight);
		auto const startToEndDirection = normalized(b - a);
		auto const brightness_B = Math::interpolateLinearly(brightnessBottom, stepHeight / 2.0f, 1.0f);

		auto const al = a + startToEndDirection * (0.5f * length - halfWidth);
		auto const ar = a + startToEndDirection * (0.5f * length + halfWidth);

		auto const & aa = anchors[surface.anchors[0]].position;
		auto const & ab = anchors[surface.anchors[1]].position;
		auto const alength = distanceBetween(ab, aa);

		auto const aal = aa + startToEndDirection * (0.5f * alength - halfWidth);
		auto const aar = aa + startToEndDirection * (0.5f * alength + halfWidth);

		auto const uMin = uOffset;
		auto const ual  = uOffset + 0.5f * (0.5f * length - halfWidth); // * 0.5 because height is 2 (scale uniformly)
		auto const uar  = uOffset + 0.5f * (0.5f * length + halfWidth); // * 0.5 because height is 2 (scale uniformly)
		auto const uMax = uOffset + 0.5f * length; // * 0.5 because height is 2 (scale uniformly)

		auto const vMin   = vOffset;
		auto const vStep  = vOffset + 0.5f * stepHeight;
		auto const vTotal = vOffset + 0.5f * totalHeight;
		auto const vMax   = vOffset + 0.5f * maximalHeight;

		//  0------1
		//  | 4--5 |   8--9
		//  | |  | |   |  |
		//  | |  | |   |  |
		//  | 6--7 |  10--11
		//  2------3
		WallVertex const vertz[] = {
			{ {   a.x, maximalHeight,  a.y }, { uMin,   vMax }, re, gr, bl },
			{ {   b.x, maximalHeight,  b.y }, { uMax,   vMax }, re, gr, bl },
			{ {   a.x, minimalHeight,  a.y }, { uMin,   vMin }, re * brightnessBottom, gr * brightnessBottom, bl * brightnessBottom },
			{ {   b.x, minimalHeight,  b.y }, { uMax,   vMin }, re * brightnessBottom, gr * brightnessBottom, bl * brightnessBottom },
			{ {  al.x, totalHeight,   al.y }, {  ual, vTotal }, re, gr, bl },
			{ {  ar.x, totalHeight,   ar.y }, {  uar, vTotal }, re, gr, bl },
			{ {  al.x, stepHeight,    al.y }, {  ual,  vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B },
			{ {  ar.x, stepHeight,    ar.y }, {  uar,  vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B },
			{ { aal.x, totalHeight,  aal.y }, {  ual, vTotal }, 0.5f * re, 0.5f * gr, 0.5f * bl },
			{ { aar.x, totalHeight,  aar.y }, {  uar, vTotal }, 0.5f * re, 0.5f * gr, 0.5f * bl },
			{ { aal.x, stepHeight,   aal.y }, {  ual,  vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B },
			{ { aar.x, stepHeight,   aar.y }, {  uar,  vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B }
		};

		// Outsides
		*vertices.toEnd++ = vertz[0];
		*vertices.toEnd++ = vertz[4];
		*vertices.toEnd++ = vertz[2];
		*vertices.toEnd++ = vertz[4];
		*vertices.toEnd++ = vertz[6];
		*vertices.toEnd++ = vertz[2];

		*vertices.toEnd++ = vertz[0];
		*vertices.toEnd++ = vertz[1];
		*vertices.toEnd++ = vertz[4];
		*vertices.toEnd++ = vertz[1];
		*vertices.toEnd++ = vertz[5];
		*vertices.toEnd++ = vertz[4];

		*vertices.toEnd++ = vertz[6];
		*vertices.toEnd++ = vertz[7];
		*vertices.toEnd++ = vertz[2];
		*vertices.toEnd++ = vertz[2];
		*vertices.toEnd++ = vertz[7];
		*vertices.toEnd++ = vertz[3];

		*vertices.toEnd++ = vertz[1];
		*vertices.toEnd++ = vertz[3];
		*vertices.toEnd++ = vertz[5];
		*vertices.toEnd++ = vertz[3];
		*vertices.toEnd++ = vertz[7];
		*vertices.toEnd++ = vertz[5];

		// door insides
		*vertices.toEnd++ = vertz[8];
		*vertices.toEnd++ = vertz[4];
		*vertices.toEnd++ = vertz[5];
		*vertices.toEnd++ = vertz[8];
		*vertices.toEnd++ = vertz[5];
		*vertices.toEnd++ = vertz[9];

		*vertices.toEnd++ = vertz[6];
		*vertices.toEnd++ = vertz[4];
		*vertices.toEnd++ = vertz[8];
		*vertices.toEnd++ = vertz[6];
		*vertices.toEnd++ = vertz[8];
		*vertices.toEnd++ = vertz[10];

		*vertices.toEnd++ = vertz[5];
		*vertices.toEnd++ = vertz[11];
		*vertices.toEnd++ = vertz[9];
		*vertices.toEnd++ = vertz[7];
		*vertices.toEnd++ = vertz[11];
		*vertices.toEnd++ = vertz[5];

		// If this is a door, then the triangles are already covered by the room's floor.
		if(false == isDoor(portal)) {
			*vertices.toEnd++ = vertz[6];
			*vertices.toEnd++ = vertz[10];
			*vertices.toEnd++ = vertz[7];
			*vertices.toEnd++ = vertz[7];
			*vertices.toEnd++ = vertz[10];
			*vertices.toEnd++ = vertz[11];
		}

	} else {
		auto const length = distanceBetween(surface.from, surface.to);

		auto const uMin = uOffset;
		auto const uMid = uOffset + 0.25f * length; // * 0.5 because height is 2 (scale uniformly)
		auto const uMax = uOffset +  0.5f * length; // * 0.5 because height is 2 (scale uniformly)

		auto const vMin = vOffset;
		auto const vMid = vOffset + 0.25f * maximalHeight;
		auto const vMax = vOffset +  0.5f * maximalHeight;

		auto const ab = centerOf(a, b);
		auto const halfHeight = Math::interpolateLinearly(minimalHeight, 0.5f, maximalHeight);
		WallVertex const vertz[16] = {
			{ {  a.x, minimalHeight,  a.y }, { uMin, vMin }, re * brightness_E_B, gr * brightness_E_B, bl * brightness_E_B, { } },
			{ { ab.x, minimalHeight, ab.y }, { uMid, vMin }, re * brightness_C_B, gr * brightness_C_B, bl * brightness_C_B, { } },
			{ { ab.x, halfHeight,    ab.y }, { uMid, vMid }, re * brightness_C_C, gr * brightness_C_C, bl * brightness_C_C, { } },
			{ {  a.x, halfHeight,     a.y }, { uMin, vMid }, re * brightness_E_C, gr * brightness_E_C, bl * brightness_E_C, { } },
			{ {  b.x, minimalHeight,  b.y }, { uMax, vMin }, re * brightness_S_B, gr * brightness_S_B, bl * brightness_S_B, { } },
			{ {  b.x, halfHeight,     b.y }, { uMax, vMid }, re * brightness_S_C, gr * brightness_S_C, bl * brightness_S_C, { } },
			{ {  a.x, halfHeight,     a.y }, { uMin, vMid }, re * brightness_E_C, gr * brightness_E_C, bl * brightness_E_C, { } },
#if _DEBUG
			{ { ab.x, halfHeight,    ab.y }, { uMid, vMid }, re * brightness_C_C, gr * brightness_C_C, bl * brightness_C_C, { } },
			{ { ab.x, maximalHeight, ab.y }, { uMid, vMax }, re * brightness_C_T, gr * brightness_C_T, bl * brightness_C_T, { } },
			{ {  a.x, maximalHeight,  a.y }, { uMin, vMax }, re * brightness_E_T, gr * brightness_E_T, bl * brightness_E_T, { } },
			{ { ab.x, halfHeight,    ab.y }, { uMid, vMid }, re * brightness_C_C, gr * brightness_C_C, bl * brightness_C_C, { } },
			{ {  b.x, halfHeight,     b.y }, { uMax, vMid }, re * brightness_S_C, gr * brightness_S_C, bl * brightness_S_C, { } },
			{ {  b.x, maximalHeight,  b.y }, { uMax, vMax }, re * brightness_S_T, gr * brightness_S_T, bl * brightness_S_T, { } },
			{ { ab.x, maximalHeight, ab.y }, { uMid, vMax }, re * brightness_C_T, gr * brightness_C_T, bl * brightness_C_T, { } }
#endif
		};

		*vertices.toEnd++ = vertz[0];
		*vertices.toEnd++ = vertz[2];
		*vertices.toEnd++ = vertz[1];
		*vertices.toEnd++ = vertz[0];
		*vertices.toEnd++ = vertz[3];
		*vertices.toEnd++ = vertz[2];

		*vertices.toEnd++ = vertz[1];
		*vertices.toEnd++ = vertz[5];
		*vertices.toEnd++ = vertz[4];
		*vertices.toEnd++ = vertz[1];
		*vertices.toEnd++ = vertz[2];
		*vertices.toEnd++ = vertz[5];

#if _DEBUG
		*vertices.toEnd++ = vertz[6];
		*vertices.toEnd++ = vertz[8];
		*vertices.toEnd++ = vertz[7];
		*vertices.toEnd++ = vertz[6];
		*vertices.toEnd++ = vertz[9];
		*vertices.toEnd++ = vertz[8];

		*vertices.toEnd++ = vertz[10];
		*vertices.toEnd++ = vertz[12];
		*vertices.toEnd++ = vertz[11];
		*vertices.toEnd++ = vertz[10];
		*vertices.toEnd++ = vertz[13];
		*vertices.toEnd++ = vertz[12];
#endif
	}

	surface.endOfPickingTriangles = WallTriangleIndex(lengthOf(pickingVertices) / 3);
	surface.endOfTriangles        = WallTriangleIndex(lengthOf(vertices) / 3);
}
Ganz am Ende ist ein #if _DEBUG damit die Release-Version nicht abstürzt. Wenn ich das betreffende Array um 1 größer mache oder 2 Zuweisungen mehr einkommentiere, stürzt der Compiler ab. Gelöst habe ich es, indem ich die doppelten Variablen entfernt habe (dann gingen 9 Array-Elemente und 3 Zuweisungen mehr); und brightness_C_C mit Konsorten aus dem Funktions-Scope ins else geholt habe (dann ging alles).

Re: Jammer-Thread

Verfasst: 28.05.2014, 22:23
von Spiele Programmierer
Kann es vielleicht sein, das es vielleicht mit dem inflationären Gebrauch von "auto" oder anderen Dingen zusammen hängt? Soooo viele Variablen sind es jetzt auch nicht. Da müsste das Problem doch bereits häufig aufgetreten und gefixt worden sein, oder nicht? Ich kann mir jedenfalls gerade irgendwie nicht vorstellen, dass die Anzahl "float"-Variablen alleine schuld ist.

Re: Jammer-Thread

Verfasst: 28.05.2014, 22:40
von Krishty
Der Compiler stürzt nicht beim Parsen ab (wo auto Auswirkungen hat), sondern beim Erzeugen des Maschinentexts (LTCG). Wenn ich zehn temporäre Variablen tiefer ins innere Scope schiebe, kann ich 6 Zuweisungen mehr machen. Sieht nach einem festen Limit an virtuellen Registern aus.

Die Vertex-Struktur enthält übrigens 10 floats. Der Compiler baut für *vertices.toEnd++ = vertz[5]; auch tatsächlich 12 Befehle – dementsprechend gigantisch ist der erzeugte Maschinentext. War halt schnell hingehackt.

Rant am Rande: Meine Anwendung allokiert 120 MiB RAM. Fünf Sechstel sind … Überfluss. Allein 42 MiB gehen für DLLs drauf, allen voran Shell32 (das niemals benutzt, aber von Treibern eingebunden wird) und AMD-/Direct3D-DLLs. 10 MiB Adressraum gehen für die Stacks von Worker Threads in Windows und im AMD-Treiber drauf, die eigentlich niemals mehr als 100 KiB benötigen. Aber ganze 60 MiB stecken in privaten Bereichen, die für Write Combining gemappt sind – wahrscheinlich Scratch Space für GPU-Uploads in D3D oder den Treibern.

Wie viel davon tatsächlich mein Kram ist? Nicht einmal 3 MiB. Drei popelige MiB aus 120 MiB Allokationen. Mein privater Arbeitssatz liegt bei knapp unter 4 MiB; und da sind dann Treiber-Stacks und Write Combining usw schon drin.

Unfassbar, wie viel da verblasen wird.