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

Started by
3 comments, last by Mr_Fox 7 years, 6 months ago

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

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.

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.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

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.

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?

This topic is closed to new replies.

Advertisement