Advertisement

HLSL's snorm and unorm

Started by April 24, 2018 09:29 AM
3 comments, last by Matias Goldberg 6 years, 9 months ago

I noticed that snorm and unorm are, apparently, HLSL keywords (after trying to use them as variable names).

MSDN is very brief about these "type modifiers":

Quote

 

Differences between Direct3D 9 and Direct3D 10:

In Direct3D 10, the following types are modifiers to the float type.

snorm float - IEEE 32-bit signed-normalized float in range -1 to 1 inclusive.
unorm float - IEEE 32-bit unsigned-normalized float in range 0 to 1 inclusive.
For example, here is a 4-component signed-normalized float-variable declaration.

snorm float4 fourComponentIEEEFloat;

 

So I wonder:

  1. Does casting between snorm float and unorm float and float work as intended?
  2. What happens when casting from a float that is out-of-range to a snorm and unorm?
  3. Is it also possible to add these type modifiers to half and double.
  4. Should one prefer these type modifiers over a manual conversion (is a "mad" instruction guaranteed?)

🧙

I've only seen these used with typed UAV loads:

Quote

When using typed UAV loads to read from a UNORM or SNORM resource, you must properly declare the element type of the HLSL object to be unorm or snorm. It is specified as undefined behavior to mismatch the element type declared in HLSL with the underlying resource data type. For example, if you are using typed UAV loads on a buffer resource with R8_UNORM data, then you must declare the element type as unorm float:

 
 


RWBuffer<unorm float> uav;

https://msdn.microsoft.com/en-us/library/windows/desktop/dn903947(v=vs.85).aspx#using_unorm_and_snorm_typed_uav_loads_from_hlsl

Advertisement
13 minutes ago, Hodgman said:

Didn't expect this. Thought it would be transparent as is the case for SRVs/RTVs.

🧙

UAVs require this. These modifiers are not meant for local variables thus it's very likely an unorm float local variable will just behave like a regular float.

As to your out of range conversion, saturation happens. Snorm -1 becomes 0 when stored to an unorm buffer. 5.7 becomes 1.0 when stored to u/snorm, and -7 becomes -1 when stored to snorm. I don't remember about nans but I think they get covered to zero.

Also watch out for -0 (negative zero) as it becomes +0 when stored as snorm

This topic is closed to new replies.

Advertisement