Skip to content

Confusion regarding instance flags & validation #533

@lisyarus

Description

@lisyarus

I apologize in advance for asking several questions in one issue, but since they are all related, I figured that would be okay.

  1. Some of the instance flags available in gfx-rs/wgpu aren't exposed in wgpu.h, namely ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER, GPU_BASED_VALIDATION, VALIDATION_INDIRECT_CALL, and AUTOMATIC_TIMESTAMP_NORMALIZATION. I guess this is just a matter of updating the headers and the conversion code?

  2. The current instance flags mapping logic seems a bit flawed: when using WGPUInstanceFlag_Default, which has the value of zero, meaning no instance flag is present, instead of resolving to wgt::InstanceFlags::empty() it resolves to wgt::InstanceFlags::default(), which is not the same. So it seems that there is no reasonable way to actually disable all instance flags?

  3. In turn, wgt::InstanceFlags::default() invokes wgt::InstanceFlags::from_build_config(), which depends on whether debug_assertions are enabled. I'm not that proficient in Rust build system, so it's not clear whether they are enabled or not in wgpu-native builds. So my question here is: are they? :)

  4. wgt::InstanceFlags supports overriding the flags with environment variables, which can be very handy for troubleshooting problems on a remote machine (such as some player's/tester's machine when developing a game). Of course, this can be trivially implemented on the client-side, but it complicates upgrading to newer wgpu versions, and is in general a bit silly (since this code is already present in wgpu). Is there a possibility to expose this functionality in wgpu-native?

If my understanding of the above is correct, I propose changing WGPUInstanceFlags in the following way:

static const WGPUInstanceFlag WGPUInstanceFlag_Empty = 0x00000000;
static const WGPUInstanceFlag WGPUInstanceFlag_Debug = 1 << 0;
static const WGPUInstanceFlag WGPUInstanceFlag_Validation = 1 << 1;
// other actual flags ...
static const WGPUInstanceFlag WGPUInstanceFlag_Default = 1 << 48; // can be anything close to higher bits, I guess
static const WGPUInstanceFlag WGPUInstanceFlag_FromEnv = 1 << 49;
static const WGPUInstanceFlag WGPUInstanceFlag_Debugging = ...; // bitwise-or of some flags
static const WGPUInstanceFlag WGPUInstanceFlag_AdvancedDebugging = ...; // bitwise-or of some flags
static const WGPUInstanceFlag WGPUInstanceFlag_Force32 = 0x7FFFFFFF;

Here,

  • WGPUInstanceFlag_Empty maps to wgt::InstanceFlags::empty()
  • WGPUInstanceFlag_Default maps to wgt::InstanceFlags::default() (bitwise-or'd with any other present bits)
  • WGPUInstanceFlag_FromEnv maps to wgt::InstanceFlags::empty().with_env() (potentially overriding any other present bits)
  • WGPUInstanceFlag_Debugging corresponds to wgt::InstanceFlags::debugging()
  • WGPUInstanceFlag_AdvancedDebugging corresponds to wgt::InstanceFlags::advanced_debugging()

We could get rid of Default altogether, but it provides a sane default for many users. However, the proposed scheme changes the flags field of default-constructed InstanceExtras from Default to Empty, which is a breaking change.

I added Debugging and AdvancedDebugging mostly for completeness; I'm not sure how useful they are, but it might be handy for some users for, you know, debugging :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions