• Advertisement
Sign in to follow this  

What's the benefit of using specific resource format vs using DXGI_FORMAT_UNKNON during CreateCommittedResource

This topic is 570 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey Guys,

 

Often in time, we call CreateCommitedResource with format set to DXGI_FORMAT_UNKNOWN, and then during view creation, we give the actual format we needed (like DXGI_FORMAT_R16G16B16A16_FLOAT). And this works just fine.

 

But I just wondering, there must be some reasons for having resource format in CreateCommitedResource params list. So what's the benefit of using specific resource format (like DXGI_FORMAT_R16G16B16A16_FLOAT) than just general DXGI_FORMAT_UNKNOWN during resource creation?

 

Also another silly question:

if my per component data is float within range [-1.f,1.f] what's the advantages of using DXGI_FORMAT_R16G16B16A16_SNORM than DXGI_FORMAT_R16G16B16A16_FLOAT?

 

Thanks

Share this post


Link to post
Share on other sites
Advertisement

To be clear, are you talking about creating texture resources with DXGI_FORMAT_UNKNOWN, or are you talking about buffers? To my knowledge the format is required to be DXGI_FORMAT_UNKNOWN for buffer resources, and must be a valid supported format for texture resources.

 

An SNORM format will use a fixed-point integer representation where every bit combination represents a valid value within the [-1.0, 1.0] range. In other words, you have 16-bits where every bit of precision is in your target range. This is not true for for FLOAT formats, where only a subset of the bit patterns represent values in the [-1.0, 1.0] range. So essentially some of your bits are "wasted" on values you'll never store.

 

There's also the issue of how the precision is distributed across the [-1, 1] range. With a 16-bit SNORM format, the precision is evenly distributed across the possible range: increasing by 1 always results in a difference of 1/65536. With floating-point formats this is not the case, due to the use of the exponent: your "steps" will be much smaller closer to 0, and will increase as you get further from 1. This effectively means that you'll have higher precision closer to 0 then you will closer to 1. For 16-bit floats the step size is 1/1024 at 1.0, which is equivalent to 10-bit fixed point.

Share this post


Link to post
Share on other sites

To be clear, are you talking about creating texture resources with DXGI_FORMAT_UNKNOWN, or are you talking about buffers? To my knowledge the format is required to be DXGI_FORMAT_UNKNOWN for buffer resources, and must be a valid supported format for texture resources.

 

An SNORM format will use a fixed-point integer representation where every bit combination represents a valid value within the [-1.0, 1.0] range. In other words, you have 16-bits where every bit of precision is in your target range. This is not true for for FLOAT formats, where only a subset of the bit patterns represent values in the [-1.0, 1.0] range. So essentially some of your bits are "wasted" on values you'll never store.

 

There's also the issue of how the precision is distributed across the [-1, 1] range. With a 16-bit SNORM format, the precision is evenly distributed across the possible range: increasing by 1 always results in a difference of 1/65536. With floating-point formats this is not the case, due to the use of the exponent: your "steps" will be much smaller closer to 0, and will increase as you get further from 1. This effectively means that you'll have higher precision closer to 0 then you will closer to 1. For 16-bit floats the step size is 1/1024 at 1.0, which is equivalent to 10-bit fixed point.

Sorry about my first question, I totally forget about that...

Thanks so much for such detailed explanation. 

Share this post


Link to post
Share on other sites

Just a small correction. 16-bit SNORM will have a step size of 1/32767 due to the fact that only half the bit patterns represent 0.0f to 1.0f (and half for -1.0 to 0.0f). 0.0f is represented only once and both -32768 and -32767 represent -1.0f. This has the benefit of ensuring a symmetrical set of possible values either side of 0.0f. Without this you'd have steps of 1/32768 on the negative side and 1/32767 on the positive side.

Thanks Adam and MJP. So if I know my data is pretty evenly spread within a finite range, I'd better use X16_SNORM (with scale factor to map my data range into [-1,1]) to get better even precision). And if I need more precision I'd better use X32_SINT(with scale factor) instead of X32_FLOAT.

 

Also could I say that using X16_SNORM is almost identical as using X16_SINT with factor 1/32767 (since that is essentially fixed precision float)

 

So in general if our data value is far from 1.0, and we know all operations won't scale the value crazily, should we avoid FLOAT for precision considerations?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement