wgslSectionDocument function

String wgslSectionDocument({
  1. required Map<String, PackedStage> vertex,
  2. required Map<String, PackedStage> fragment,
})

The section document for vertex and fragment, as JSON text.

The caller writes it as UTF-8; ShaderBundle carries bytes and this file deliberately stops at the text, so a test can read what was written.

Throws a StageAgreementException when a vertex stage and the fragment stage its name pairs it with (pairedFragmentStage) disagree, read from the GLSL each was prepared from, and a WgslSectionException naming the stage and the count when one binds more than MaterialStageBudget allows.

Implementation

String wgslSectionDocument({
  required Map<String, PackedStage> vertex,
  required Map<String, PackedStage> fragment,
}) {
  // A texture of the material language is a texture and a sampler here.
  // Mutation: count blocks against the texture budget, and a stage of
  // thirteen blocks is let through.
  for (final MapEntry(:key, :value) in <MapEntry<String, PackedStage>>[
    ...vertex.entries,
    ...fragment.entries,
  ]) {
    final textures = value.prepared.samplers.length;
    if (MaterialStageBudget.problem(
          key,
          textures: textures,
          samplers: textures,
          uniformBlocks: value.prepared.blocks.length,
        )
        case final problem?) {
      throw WgslSectionException(problem);
    }
  }
  requireBundleAgreement(
    vertex: <String, String>{
      for (final MapEntry(:key, :value) in vertex.entries)
        key: value.prepared.glsl,
    },
    fragment: <String, String>{
      for (final MapEntry(:key, :value) in fragment.entries)
        key: value.prepared.glsl,
    },
  );
  return jsonEncode(<String, Object>{
    'version': sectionVersion,
    'vertex': <String, Object>{
      for (final entry in vertex.entries) entry.key: _stageJson(entry.value),
    },
    'fragment': <String, Object>{
      for (final entry in fragment.entries) entry.key: _stageJson(entry.value),
    },
  });
}