17

Let's take the following 6 VkFormats for example:

VK_FORMAT_R8_UNORM
VK_FORMAT_R8_SNORM
VK_FORMAT_R8_USCALED
VK_FORMAT_R8_SSCALED
VK_FORMAT_R8_UINT
VK_FORMAT_R8_SINT

All of these specify a one-component 8-bit format that has a single 8-bit R component.

The formats differ in whether they are (a) normalized, (b) scaled; or (c) integer. What does that mean? What are the differences between those three things? Where is that specified?

Are all 256 possible values of 8-bits meaningful and valid in all six formats?

(They also differ in whether they are signed or unsigned. I assume this means whether their underlying types are like the C types int8_t or uint8_t ?)

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319

1 Answers1

29

Refer to Identification of Formats and Conversion from Normalized Fixed-Point to Floating-Point in the specification.

  • UNORM is a float in the range of [0, 1].
  • SNORM is the same but in the range of [-1, 1]
  • USCALED is the unsigned integer value converted to float
  • SSCALED is the integer value converted to float
  • UINT is an unsigned integer
  • SINT is a signed integer

I.e. for the VK_FORMAT_R8_*:

  • for UNORM raw 0 would give 0.0f, raw 255 would give 1.0f
  • for SNORM raw -127 (resp. 129) would give -1.0f, raw 127 would give 1.0f
  • USCALED raw 0 would give 0.0f, raw 255 would give 255.0f
  • SSCALEDraw -128 (resp. 128) would give -128.0f, raw 127 would give 127.0f

-128 (-2n-1) is not meaningful in SNORM, and simply clamps to -1.0f.

krOoze
  • 12,301
  • 1
  • 20
  • 34
  • Thanks @krOoze, 32.1.3 was sneakily hiding between the lengthy 31.1 and 31.2 :) – Andrew Tomazos Jan 08 '20 at 11:42
  • @krOoze what does the "_unsigned integer value converted to `float`_" imply? Is it that the image buffer contains unsigned integers which are then returned as floats when sampled? Or is it that upon buffering the image, a pointer to unsigned int must be given, whose data is converted to a float storage format? Am I even asking the right question? – alexpanter Aug 17 '23 at 12:53
  • 1
    @alexpanter It means in virtually the same as C++ cast. E.g. if the data (with this format) is represented with 42u raw value, then it yields 42.0f value. – krOoze Aug 17 '23 at 15:51
  • @krOoze so it's a sampling thing? And in this particular case - the source image data in main memory should be `uint8_t*`. ? And when I sample in a GLSL shader, if as you say the sampled texel contains 42u in memory, the sampler returns 42.0f. ? And thank you! – alexpanter Aug 18 '23 at 11:12
  • 1
    @alexpanter It doesn't have apriori anything to do with sampling (the value can simply be fetched or loaded some other way). Or be written into for that matter. Yea, `USCALED` is (interpreted as) a float type, and its representation is N bits (where N is in the name of the format). The bits are interpreted akin to if you read the bits as `uintN_t` and then (arithmetically) assigned the value to f32. 0b1 yields 1.0f, 0b10 yields 2.0f, 0b11 yields 3.0f, and so on. – krOoze Aug 18 '23 at 12:11