onnxruntime

Форк
0
/
glsl-definitions.ts 
138 строк · 3.8 Кб
1
// Copyright (c) Microsoft Corporation. All rights reserved.
2
// Licensed under the MIT License.
3

4
import { ProgramInfo, TextureLayout } from './types';
5
import { WebGLContext } from './webgl-context';
6

7
/* eslint-disable @typescript-eslint/naming-convention */
8
export enum FunctionType {
9
  ValueBased,
10
  Positional,
11
}
12
export interface GlslFunction<T extends FunctionType> {
13
  body: string;
14
  name: string;
15
  type: T;
16
}
17
export type GlslValueFunction = GlslFunction<FunctionType.ValueBased>;
18
export interface GlslPositionalFunction extends GlslFunction<FunctionType.Positional> {
19
  inputShape: readonly number[];
20
  outputShape: readonly number[];
21
}
22

23
export class GlslContext {
24
  constructor(
25
    public glContext: WebGLContext,
26
    public programInfo: ProgramInfo,
27
    public inputTextureLayouts: TextureLayout[],
28
    public outputTextureLayout: TextureLayout,
29
  ) {}
30
}
31
export abstract class GlslLib {
32
  constructor(public context: GlslContext) {}
33
  abstract getFunctions(): { [name: string]: GlslLibRoutine };
34
  abstract getCustomTypes(): { [name: string]: string };
35
}
36

37
// abstraction to represent a GLSL library routine and it's dependencies
38
export class GlslLibRoutine {
39
  constructor(
40
    public routineBody: string,
41
    public dependencies?: string[],
42
  ) {}
43
}
44

45
// abstraction to represent a GLSL library routine and it's dependencies AS GRAPH Nodes
46
// this level of abstraction is used to topologically sort routines before fragment shade inclusion
47
export class GlslLibRoutineNode {
48
  dependencies: GlslLibRoutineNode[];
49
  routineBody: string;
50
  constructor(
51
    public name: string,
52
    routineBody?: string,
53
    dependencies?: GlslLibRoutineNode[],
54
  ) {
55
    if (dependencies) {
56
      this.dependencies = dependencies;
57
    } else {
58
      this.dependencies = [];
59
    }
60

61
    if (routineBody) {
62
      this.routineBody = routineBody;
63
    }
64
  }
65
  addDependency(node: GlslLibRoutineNode) {
66
    if (node) {
67
      this.dependencies.push(node);
68
    }
69
  }
70
}
71

72
// topologically sort GLSL library routines (graph nodes abstraction) before shader script inclusion
73
export class TopologicalSortGlslRoutines {
74
  static returnOrderedNodes(nodes: GlslLibRoutineNode[]): GlslLibRoutineNode[] {
75
    if (!nodes || nodes.length === 0) {
76
      return [];
77
    }
78

79
    if (nodes.length === 1) {
80
      return nodes;
81
    }
82

83
    const cycleCheck = new Set<string>();
84
    const alreadyTraversed = new Set<string>();
85
    const result = new Array<GlslLibRoutineNode>();
86

87
    this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result);
88
    return result;
89
  }
90

91
  private static createOrderedNodes(
92
    graphNodes: GlslLibRoutineNode[],
93
    cycleCheck: Set<string>,
94
    alreadyTraversed: Set<string>,
95
    result: GlslLibRoutineNode[],
96
  ) {
97
    for (let i = 0; i < graphNodes.length; ++i) {
98
      this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result);
99
    }
100
  }
101

102
  private static dfsTraverse(
103
    root: GlslLibRoutineNode,
104
    cycleCheck: Set<string>,
105
    alreadyTraversed: Set<string>,
106
    result: GlslLibRoutineNode[],
107
  ) {
108
    // if this root has already been traversed return
109
    if (!root || alreadyTraversed.has(root.name)) {
110
      return;
111
    }
112

113
    // cyclic dependency has been detected
114
    if (cycleCheck.has(root.name)) {
115
      throw new Error("Cyclic dependency detected. Can't topologically sort routines needed for shader.");
116
    }
117

118
    // hold this node to detect cycles if any
119
    cycleCheck.add(root.name);
120

121
    // traverse children in a dfs fashion
122
    const dependencies = root.dependencies;
123
    if (dependencies && dependencies.length > 0) {
124
      for (let i = 0; i < dependencies.length; ++i) {
125
        this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result);
126
      }
127
    }
128

129
    // add to result holder
130
    result.push(root);
131

132
    // mark this node as traversed so that we don't traverse from this again
133
    alreadyTraversed.add(root.name);
134

135
    // release the hold
136
    cycleCheck.delete(root.name);
137
  }
138
}
139

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.