这是indexloc提供的服务,不要输入任何密码
Skip to content

minutiae: What happens to GPUColors outside the range of f32? #5020

@kainino0x

Description

@kainino0x

GPUColor is a 4-component color type using f64 (double aka JS Number), to be able to safely represent f32, i32, and u32 values without lost of range or precision. However it does not allow NaN or Infinity because of WebIDL (it's not an unrestricted double).

It is used in two places:

  • GPURenderPassColorAttachment.clearValue - color may be cast to f32/i32/u32 depending on the texture format
  • GPURenderPassEncoder.setBlendConstant() - color is always cast to f32 (though I think the GPU may do blending on smaller types if the texture format is smaller than f32)
  • EDIT!: There is also the similar GPUProgrammableStage.constants values, which may get cast to bool/f32/i32/u32/f16.

In both cases, the f64 value always gets cast to some smaller type. In the case of clearValue we have an algorithm defining this. However:

  • clearValue handles out-of-range values on integer formats by generating a validation error. However, if the conversion target (in either case) is a float type, it may overflow into +/-Infinity.
    • In clearValue, our spec says: "Return the WGSL f32 value corresponding to" Infinity, with no error if out of bound, but infinities in WGSL are effectively indeterminate values. We're not actually going through WGSL, but it does seem likely to be device-dependent whether infinities are preserved, clamped to finite, indeterminate, etc.
      • Making this a validation error would be a breaking change, and anyway is probably not the expected behavior (since floats are narrowed more gracefully than integers). However since it's indeterminate anyway we could force it to be FLT_MAX.
      • ... And require infinities to be preserved if we have unrestricted floats (in which case we should also make GPUColor allow infinities at the WebIDL level).
    • In setBlendConstant(), we say nothing, but probably expect we're casting to f32 or similar. We don't invoke WGSL so we don't reach "indeterminate values", but in principle we should.
  • Also, setBlendConstant() does not define the conversion to f32 (or possibly smaller)

And finally should we really be disallowing Infinity at the WebIDL definition of GPUColor if we have to deal with this anyway?

Metadata

Metadata

Assignees

Labels

apiWebGPU API

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions