| 1 | <?php |
| 2 | namespace Std\Lib\Syntax; |
| 3 | |
| 4 | class Glsl extends Language { |
| 5 | protected bool $preprocessor = true; |
| 6 | protected array $headerDirectives = ['include']; |
| 7 | protected array $strings = ['"']; |
| 8 | protected string $digitSep = ''; |
| 9 | |
| 10 | protected array $tokens = [ |
| 11 | 'keyword' => [ |
| 12 | 'attribute', 'const', 'uniform', 'varying', 'buffer', 'shared', 'layout', 'centroid', 'flat', 'smooth', 'noperspective', |
| 13 | 'patch', 'sample', 'break', 'continue', 'do', 'for', 'while', 'switch', 'case', 'default', 'if', 'else', 'subroutine', |
| 14 | 'in', 'out', 'inout', 'invariant', 'precise', 'discard', 'return', 'struct', 'precision', 'highp', 'mediump', 'lowp', |
| 15 | 'coherent', 'volatile', 'restrict', 'readonly', 'writeonly', 'demote', 'terminateInvocation', 'rayPayloadEXT', 'hitAttributeEXT', |
| 16 | 'callableDataEXT', 'taskPayloadSharedEXT', 'perprimitiveEXT', |
| 17 | // layout()の中(「offset」「points」等、変数名にも使う単語は除く) |
| 18 | 'location', 'binding', 'set', 'push_constant', 'std140', 'std430', 'local_size_x', 'local_size_y', 'local_size_z', |
| 19 | 'input_attachment_index', 'constant_id', 'row_major', 'column_major', 'early_fragment_tests', 'max_vertices', |
| 20 | ], |
| 21 | 'constant' => [ |
| 22 | 'true', 'false', '__FILE__', '__LINE__', '__VERSION__', 'GL_ES', |
| 23 | ], |
| 24 | 'type' => [ |
| 25 | 'void', 'bool', 'int', 'uint', 'float', 'double', 'atomic_uint', 'genType', 'genIType', 'genUType', 'genBType', 'genDType', |
| 26 | 'int8_t', 'int16_t', 'int32_t', 'int64_t', 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t', 'float16_t', 'float32_t', 'float64_t', |
| 27 | 'accelerationStructureEXT', 'rayQueryEXT', |
| 28 | 'subpassInput', 'subpassInputMS', 'isubpassInput', 'isubpassInputMS', 'usubpassInput', 'usubpassInputMS', 'sampler', 'samplerShadow', |
| 29 | ], |
| 30 | 'builtin' => [ |
| 31 | // 角度・三角関数 |
| 32 | 'radians', 'degrees', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh', 'atanh', |
| 33 | // 指数 |
| 34 | 'pow', 'exp', 'log', 'exp2', 'log2', 'sqrt', 'inversesqrt', |
| 35 | // 共通 |
| 36 | 'abs', 'sign', 'floor', 'trunc', 'round', 'roundEven', 'ceil', 'fract', 'mod', 'modf', 'min', 'max', 'clamp', 'mix', 'step', 'smoothstep', |
| 37 | 'isnan', 'isinf', 'floatBitsToInt', 'floatBitsToUint', 'intBitsToFloat', 'uintBitsToFloat', 'fma', 'frexp', 'ldexp', |
| 38 | 'packUnorm2x16', 'packSnorm2x16', 'packUnorm4x8', 'packSnorm4x8', 'unpackUnorm2x16', 'unpackSnorm2x16', 'unpackUnorm4x8', 'unpackSnorm4x8', |
| 39 | 'packHalf2x16', 'unpackHalf2x16', 'packDouble2x32', 'unpackDouble2x32', |
| 40 | // 幾何 |
| 41 | 'length', 'distance', 'dot', 'cross', 'normalize', 'faceforward', 'reflect', 'refract', 'ftransform', |
| 42 | // 行列・ベクトル比較 |
| 43 | 'matrixCompMult', 'outerProduct', 'transpose', 'determinant', 'inverse', |
| 44 | 'lessThan', 'lessThanEqual', 'greaterThan', 'greaterThanEqual', 'equal', 'notEqual', 'any', 'all', 'not', |
| 45 | // 整数 |
| 46 | 'uaddCarry', 'usubBorrow', 'umulExtended', 'imulExtended', 'bitfieldExtract', 'bitfieldInsert', 'bitfieldReverse', 'bitCount', 'findLSB', 'findMSB', |
| 47 | // テクスチャ |
| 48 | 'textureSize', 'textureQueryLod', 'textureQueryLevels', 'textureSamples', 'texture', 'textureProj', 'textureLod', 'textureOffset', |
| 49 | 'texelFetch', 'texelFetchOffset', 'textureProjOffset', 'textureLodOffset', 'textureProjLod', 'textureProjLodOffset', |
| 50 | 'textureGrad', 'textureGradOffset', 'textureProjGrad', 'textureProjGradOffset', 'textureGather', 'textureGatherOffset', 'textureGatherOffsets', |
| 51 | 'texture1D', 'texture1DProj', 'texture1DLod', 'texture1DProjLod', 'texture2D', 'texture2DProj', 'texture2DLod', 'texture2DProjLod', |
| 52 | 'texture3D', 'texture3DProj', 'texture3DLod', 'texture3DProjLod', 'textureCube', 'textureCubeLod', |
| 53 | 'shadow1D', 'shadow1DProj', 'shadow1DLod', 'shadow1DProjLod', 'shadow2D', 'shadow2DProj', 'shadow2DLod', 'shadow2DProjLod', |
| 54 | // 原子操作・画像 |
| 55 | 'atomicCounterIncrement', 'atomicCounterDecrement', 'atomicCounter', 'atomicAdd', 'atomicMin', 'atomicMax', 'atomicAnd', 'atomicOr', |
| 56 | 'atomicXor', 'atomicExchange', 'atomicCompSwap', 'imageSize', 'imageSamples', 'imageLoad', 'imageStore', 'imageAtomicAdd', |
| 57 | 'imageAtomicMin', 'imageAtomicMax', 'imageAtomicAnd', 'imageAtomicOr', 'imageAtomicXor', 'imageAtomicExchange', 'imageAtomicCompSwap', |
| 58 | // 微分・補間・ジオメトリ・同期 |
| 59 | 'dFdx', 'dFdy', 'dFdxFine', 'dFdyFine', 'dFdxCoarse', 'dFdyCoarse', 'fwidth', 'fwidthFine', 'fwidthCoarse', |
| 60 | 'interpolateAtCentroid', 'interpolateAtSample', 'interpolateAtOffset', 'EmitStreamVertex', 'EndStreamPrimitive', 'EmitVertex', 'EndPrimitive', |
| 61 | 'barrier', 'memoryBarrier', 'memoryBarrierAtomicCounter', 'memoryBarrierBuffer', 'memoryBarrierShared', 'memoryBarrierImage', 'groupMemoryBarrier', |
| 62 | 'subpassLoad', 'noise1', 'noise2', 'noise3', 'noise4', |
| 63 | // サブグループ・レイトレーシング |
| 64 | 'subgroupBarrier', 'subgroupElect', 'subgroupAll', 'subgroupAny', 'subgroupBroadcast', 'subgroupBroadcastFirst', 'subgroupBallot', |
| 65 | 'subgroupAdd', 'subgroupMul', 'subgroupMin', 'subgroupMax', 'subgroupShuffle', 'subgroupShuffleXor', |
| 66 | 'traceRayEXT', 'reportIntersectionEXT', 'executeCallableEXT', 'ignoreIntersectionEXT', 'terminateRayEXT', 'EmitMeshTasksEXT', 'SetMeshOutputsEXT', |
| 67 | ], |
| 68 | ]; |
| 69 | |
| 70 | public function prepare(string $code): void { |
| 71 | $tokens = $this->tokens; |
| 72 | // ベクトル・行列 |
| 73 | foreach (['vec', 'ivec', 'uvec', 'bvec', 'dvec', 'i8vec', 'u8vec', 'i16vec', 'u16vec', 'i64vec', 'u64vec', 'f16vec', 'f64vec'] as $v) { |
| 74 | for ($i = 2; $i <= 4; $i++) $tokens['type'][] = "{$v}{$i}"; |
| 75 | } |
| 76 | foreach (['mat', 'dmat', 'f16mat', 'f64mat'] as $m) { |
| 77 | for ($i = 2; $i <= 4; $i++) { |
| 78 | $tokens['type'][] = "{$m}{$i}"; |
| 79 | for ($j = 2; $j <= 4; $j++) $tokens['type'][] = "{$m}{$i}x{$j}"; |
| 80 | } |
| 81 | } |
| 82 | // サンプラー・テクスチャ・画像 |
| 83 | $dims = ['1D', '2D', '3D', 'Cube', '2DRect', '1DArray', '2DArray', 'CubeArray', 'Buffer', '2DMS', '2DMSArray']; |
| 84 | foreach (['', 'i', 'u'] as $p) { |
| 85 | foreach ($dims as $d) { |
| 86 | $tokens['type'][] = "{$p}sampler{$d}"; |
| 87 | $tokens['type'][] = "{$p}texture{$d}"; |
| 88 | $tokens['type'][] = "{$p}image{$d}"; |
| 89 | } |
| 90 | } |
| 91 | foreach (['1D', '2D', 'Cube', '2DRect', '1DArray', '2DArray', 'CubeArray'] as $d) $tokens['type'][] = "sampler{$d}Shadow"; |
| 92 | $this->words = $this->buildWords($tokens); |
| 93 | } |
| 94 | |
| 95 | public function classify(string $word, array $ctx): ?string { |
| 96 | // 組み込み変数(gl_Position, gl_GlobalInvocationID等) |
| 97 | if (str_starts_with($word, 'gl_')) return 'variable'; |
| 98 | return parent::classify($word, $ctx); |
| 99 | } |
| 100 | } |