Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 03 Jul 2006
Offline Last Active Private

Posts I've Made

In Topic: Direct2D kills my CriticalSection...?

12 December 2014 - 06:42 PM

If you put a breakpoint on the TryEnterCriticalSection call you can inspect the state of the critical section in the debugger. You can also look at what the other thread is doing by using the threads window.


The most important values are:


OwningThread - 0x00000000 == none. Otherwise it's the ThreadID of the thread that owns it. Use the Threads window to see which thread that is, and look at what code it's running.

RecursionCount 0 == not locked. Essentially EnterCriticalSection() increments it and LeaveCriticalSection() decrements it.


It's also worth noting that TryEnterCriticalSection() can fail every time due to timing issues. That it it can find that whenever it tries it's locked. The longer the lock is held by other threads the less likely it is to work. In general you should keep them locked for as short a duration as possible. Don't write code that looks like this if you can avoid it:






This version is much better if you don't need the lock inside the process function. Even if Process() does need a lock, can it use a different one?



auto thing = queue.pop_front();



In Topic: is there an easy way to do this?

11 December 2014 - 06:31 PM

Add a separate function to set the current prefix?


Add a new parameter on the end with a default value?


enum BandMember { BM_UNKNOWN=-1, BM_GROG=0, ... };


extern void msg(const char *text, BandMember who = BM_UNKNOWN);

In Topic: sRGB and deferred rendering

09 December 2014 - 07:42 PM

The copy you perform will be done via your own shader which reads your intermediate texture and either returns sqrt( X ) or pow( X, 1.0 / 2.2 ) depending on how approximate you want to be in exchange for performance.


Err, you don't want to do that conversion in the shader at all. For a render target set up as sRGB the conversion will be done automatically when you draw to it, and that should be faster than doing it in the shader.


For deferred shading I'd go with something like this process:


1. Render all the opaque stuff. The diffuse MRT render target needs to have better than 8-bits-per-channel precision because it's in linear space.

2. You want to do lighting into a DXGI_FORMAT_R16G16B16A16_UNORM render target.

3. After that you want to render anything transparent (using forward lighting), and apply any linear space post effects.

4. At some point you will convert to sRGB, which may also involve an HDR tone mapping shader.

5. You can then do more post-processing in sRGB (e.g. I seem to remember that FXAA uses sRGB and not linear inputs).

6. If there's any 2D rendering, you should probably do that last, directly to the back buffer.


The last draw call that does a full screen sRGB render should have the destination render target as the back buffer, to avoid the need for an extra copy step at the end.


Note that you could switch to sRGB just after step 2 if you want to save on rendering to the bigger and slower linear texture. You'll get better precision by staying in linear space for longer though.

In Topic: Weird stuff happening when stepping through a threaded code

04 December 2014 - 05:26 PM

I'm not a C# programmer, and even to me that code is clearly not thread safe.


Mistakes I've noticed in the Update() function:

- You're using a for loop to go through the queue. Since the count can change at any time due to other threads this is just wrong. Don't use .Count at all.

- Calling ToList() is going to be bad, for the same reason. The only way you should be examining the list contents is via TryDequeue().

- You ignore the return value from TryDequeue(). This is bad because if it's false you've not got a valid object to work with - the list is empty.

- The code only sleeps when there's an item in the list. If it's empty the thread eats 100% of one CPU core for no reason. You want the exact opposite of that.

- Looping calling Thread.Sleep() is a bad way to wait for work anyway. You want to use some sort of blocking wait function, which may require a different container.


There's also no sign of any test code. Even if you think you've got threaded code right, it's generally a good idea to do some stress testing, just in case you missed something.


My recommendation would be to avoid using threads until you have more experience. They are difficult to use correctly, even for experienced programmers, and modern CPUs run code fast enough on a single core that you can easily get away without them.

In Topic: Alpha blending

02 December 2014 - 02:32 PM

There's another option that can make alpha blending faster. Enable alpha testing (or use clip() in the shader).


It's most helpful where memory bandwidth is limited as it trades off shader instructions for blending work. For that reason, the effect tends to be most noticeable on lower end hardware.