Compare commits
177 Commits
wip/ebassi
...
wip/otte/s
Author | SHA1 | Date | |
---|---|---|---|
|
3680f0850f | ||
|
92fd8ccdee | ||
|
73ec3734bd | ||
|
39a277260f | ||
|
5bb7c2ecc3 | ||
|
651b5bb9b6 | ||
|
9f4da8c509 | ||
|
cb857e7231 | ||
|
a7dac28a3a | ||
|
ad53eed564 | ||
|
648cf099a8 | ||
|
ff05d6ca35 | ||
|
056cce93db | ||
|
0bc120414c | ||
|
2ce1bbacda | ||
|
ab91b013d5 | ||
|
30c040a87c | ||
|
b68aff252a | ||
|
c2773ef803 | ||
|
9275cec204 | ||
|
59f415dfe2 | ||
|
ac95c0606a | ||
|
e304738cfb | ||
|
6573df58e1 | ||
|
d33881e0ec | ||
|
7e9aa97fd5 | ||
|
38bc5f3d37 | ||
|
119f7fe74a | ||
|
516cd4b499 | ||
|
38a255d132 | ||
|
15cbfc8370 | ||
|
caaf1845c3 | ||
|
031a1812b8 | ||
|
d59333da9e | ||
|
fe4d17fee1 | ||
|
6a95433046 | ||
|
b5919bf848 | ||
|
41fd67263f | ||
|
5472458e6b | ||
|
8431b63b5d | ||
|
d17abee4eb | ||
|
8a59adedfc | ||
|
0b7b7a31b4 | ||
|
4f8a422410 | ||
|
f440e23bba | ||
|
8d5fce4c69 | ||
|
fd83132d76 | ||
|
fde721eda8 | ||
|
c546e64419 | ||
|
04dc25ed62 | ||
|
4d49471685 | ||
|
481cb8ffad | ||
|
97a80e9169 | ||
|
7445483691 | ||
|
2ee2457e82 | ||
|
9a0374f4fb | ||
|
4e61c71a5a | ||
|
d6c2c00a0a | ||
|
a7f11b5923 | ||
|
3124dffa37 | ||
|
bde7a1f51c | ||
|
fabb55524e | ||
|
97118140be | ||
|
1d5ac3b892 | ||
|
9aa73600f1 | ||
|
c4299a10c0 | ||
|
a0233d96e1 | ||
|
6f551adf10 | ||
|
53bc1a1d35 | ||
|
1a5615ed73 | ||
|
b63463f1a2 | ||
|
940c13c25c | ||
|
31db111ae5 | ||
|
88413ad585 | ||
|
bda72e2c23 | ||
|
115182d6e6 | ||
|
41a0ce4621 | ||
|
093e9194b9 | ||
|
cb975b4faa | ||
|
3482a7de13 | ||
|
c803f5e5e4 | ||
|
6d9a5feb43 | ||
|
17661af6da | ||
|
1455ef2c21 | ||
|
cccca8c2f0 | ||
|
a29a486442 | ||
|
807b63fded | ||
|
918ff3d58e | ||
|
bfdc7ad4ab | ||
|
c45e88f36a | ||
|
bc83778cd5 | ||
|
737bb72ccc | ||
|
9825d95857 | ||
|
6bdf46fbcf | ||
|
420fb00e1e | ||
|
764f6708f6 | ||
|
6e7c348654 | ||
|
0a9f758c36 | ||
|
0c567d6c28 | ||
|
a50d932150 | ||
|
6af46a0659 | ||
|
c624bae54c | ||
|
c5a1eaf1a1 | ||
|
35476639c4 | ||
|
e48be683c7 | ||
|
a07924c0d6 | ||
|
4927e229b3 | ||
|
deb3d26ff6 | ||
|
60add60236 | ||
|
19ae9c0f8e | ||
|
a3dec06d3f | ||
|
196ee554b4 | ||
|
7b416c9dc5 | ||
|
a05961d57a | ||
|
7e55c4760a | ||
|
e2d6d07c2a | ||
|
607b4b40a0 | ||
|
622dccd438 | ||
|
6247fae076 | ||
|
3279b11a99 | ||
|
6f80039428 | ||
|
11ab6f823b | ||
|
d3b452e303 | ||
|
88eac26f5a | ||
|
21fe62ec66 | ||
|
69b4834764 | ||
|
6fa6e9964c | ||
|
c22b36d2b5 | ||
|
fad4112d78 | ||
|
c30089a1cb | ||
|
4450d83cb9 | ||
|
500e6bc2bc | ||
|
8d6a332482 | ||
|
4d5cf80003 | ||
|
458a9e3e44 | ||
|
1d87210572 | ||
|
2a7f343714 | ||
|
a2aaf2b90e | ||
|
2bceaedd37 | ||
|
46c9a3aaaa | ||
|
13dd620828 | ||
|
c8f234971b | ||
|
0e284138e3 | ||
|
7e4d163f11 | ||
|
850c6d1116 | ||
|
ea45570850 | ||
|
3fc253c57d | ||
|
545ce13981 | ||
|
c2672540d9 | ||
|
a7fce5603a | ||
|
cf40318d9b | ||
|
4395675c58 | ||
|
b522801c5a | ||
|
eb12740151 | ||
|
7e8604372d | ||
|
4deaddeb70 | ||
|
935402e0aa | ||
|
67b60b54ac | ||
|
f8299719b4 | ||
|
eee9142397 | ||
|
d3511003cf | ||
|
9417507829 | ||
|
45ad50a61c | ||
|
447f52502a | ||
|
c7590f310f | ||
|
f607087201 | ||
|
36a61f0ad0 | ||
|
b6adb44dfd | ||
|
0e56c28725 | ||
|
0362778524 | ||
|
ad4b45639b | ||
|
dc519ad2a2 | ||
|
7a215a6b39 | ||
|
da5417def4 | ||
|
4e0def2806 | ||
|
bc5c3e1b56 | ||
|
3a298f8f9c |
@@ -5,6 +5,7 @@ private_headers = [
|
||||
'gskgldriverprivate.h',
|
||||
'gskglprofilerprivate.h',
|
||||
'gskglrendererprivate.h',
|
||||
'gskpixelshaderprivate.h',
|
||||
'gskprivate.h',
|
||||
'gskprofilerprivate.h',
|
||||
'gskrendererprivate.h',
|
||||
|
642
gsk/extinst.glsl.std.450.grammar.json
Normal file
642
gsk/extinst.glsl.std.450.grammar.json
Normal file
@@ -0,0 +1,642 @@
|
||||
{
|
||||
"copyright" : [
|
||||
"Copyright (c) 2014-2016 The Khronos Group Inc.",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining a copy",
|
||||
"of this software and/or associated documentation files (the \"Materials\"),",
|
||||
"to deal in the Materials without restriction, including without limitation",
|
||||
"the rights to use, copy, modify, merge, publish, distribute, sublicense,",
|
||||
"and/or sell copies of the Materials, and to permit persons to whom the",
|
||||
"Materials are furnished to do so, subject to the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be included in",
|
||||
"all copies or substantial portions of the Materials.",
|
||||
"",
|
||||
"MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS",
|
||||
"STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND",
|
||||
"HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ",
|
||||
"",
|
||||
"THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS",
|
||||
"OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
|
||||
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL",
|
||||
"THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
|
||||
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING",
|
||||
"FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS",
|
||||
"IN THE MATERIALS."
|
||||
],
|
||||
"version" : 100,
|
||||
"revision" : 2,
|
||||
"instructions" : [
|
||||
{
|
||||
"opname" : "Round",
|
||||
"opcode" : 1,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "RoundEven",
|
||||
"opcode" : 2,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Trunc",
|
||||
"opcode" : 3,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FAbs",
|
||||
"opcode" : 4,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "SAbs",
|
||||
"opcode" : 5,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FSign",
|
||||
"opcode" : 6,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "SSign",
|
||||
"opcode" : 7,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Floor",
|
||||
"opcode" : 8,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Ceil",
|
||||
"opcode" : 9,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Fract",
|
||||
"opcode" : 10,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Radians",
|
||||
"opcode" : 11,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'degrees'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Degrees",
|
||||
"opcode" : 12,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'radians'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Sin",
|
||||
"opcode" : 13,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Cos",
|
||||
"opcode" : 14,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Tan",
|
||||
"opcode" : 15,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Asin",
|
||||
"opcode" : 16,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Acos",
|
||||
"opcode" : 17,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Atan",
|
||||
"opcode" : 18,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'y_over_x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Sinh",
|
||||
"opcode" : 19,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Cosh",
|
||||
"opcode" : 20,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Tanh",
|
||||
"opcode" : 21,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Asinh",
|
||||
"opcode" : 22,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Acosh",
|
||||
"opcode" : 23,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Atanh",
|
||||
"opcode" : 24,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Atan2",
|
||||
"opcode" : 25,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'y'" },
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Pow",
|
||||
"opcode" : 26,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Exp",
|
||||
"opcode" : 27,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Log",
|
||||
"opcode" : 28,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Exp2",
|
||||
"opcode" : 29,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Log2",
|
||||
"opcode" : 30,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Sqrt",
|
||||
"opcode" : 31,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "InverseSqrt",
|
||||
"opcode" : 32,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Determinant",
|
||||
"opcode" : 33,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "MatrixInverse",
|
||||
"opcode" : 34,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Modf",
|
||||
"opcode" : 35,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'i'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "ModfStruct",
|
||||
"opcode" : 36,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FMin",
|
||||
"opcode" : 37,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UMin",
|
||||
"opcode" : 38,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "SMin",
|
||||
"opcode" : 39,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FMax",
|
||||
"opcode" : 40,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UMax",
|
||||
"opcode" : 41,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "SMax",
|
||||
"opcode" : 42,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FClamp",
|
||||
"opcode" : 43,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'minVal'" },
|
||||
{ "kind" : "IdRef", "name" : "'maxVal'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UClamp",
|
||||
"opcode" : 44,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'minVal'" },
|
||||
{ "kind" : "IdRef", "name" : "'maxVal'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "SClamp",
|
||||
"opcode" : 45,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'minVal'" },
|
||||
{ "kind" : "IdRef", "name" : "'maxVal'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FMix",
|
||||
"opcode" : 46,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" },
|
||||
{ "kind" : "IdRef", "name" : "'a'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "IMix",
|
||||
"opcode" : 47,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" },
|
||||
{ "kind" : "IdRef", "name" : "'a'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Step",
|
||||
"opcode" : 48,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'edge'" },
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "SmoothStep",
|
||||
"opcode" : 49,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'edge0'" },
|
||||
{ "kind" : "IdRef", "name" : "'edge1'" },
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Fma",
|
||||
"opcode" : 50,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'a'" },
|
||||
{ "kind" : "IdRef", "name" : "'b'" },
|
||||
{ "kind" : "IdRef", "name" : "'c'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Frexp",
|
||||
"opcode" : 51,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'exp'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FrexpStruct",
|
||||
"opcode" : 52,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Ldexp",
|
||||
"opcode" : 53,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'exp'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "PackSnorm4x8",
|
||||
"opcode" : 54,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "PackUnorm4x8",
|
||||
"opcode" : 55,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "PackSnorm2x16",
|
||||
"opcode" : 56,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "PackUnorm2x16",
|
||||
"opcode" : 57,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "PackHalf2x16",
|
||||
"opcode" : 58,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "PackDouble2x32",
|
||||
"opcode" : 59,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
],
|
||||
"capabilities" : [ "Float64" ]
|
||||
},
|
||||
{
|
||||
"opname" : "UnpackSnorm2x16",
|
||||
"opcode" : 60,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'p'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UnpackUnorm2x16",
|
||||
"opcode" : 61,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'p'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UnpackHalf2x16",
|
||||
"opcode" : 62,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UnpackSnorm4x8",
|
||||
"opcode" : 63,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'p'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UnpackUnorm4x8",
|
||||
"opcode" : 64,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'p'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "UnpackDouble2x32",
|
||||
"opcode" : 65,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'v'" }
|
||||
],
|
||||
"capabilities" : [ "Float64" ]
|
||||
},
|
||||
{
|
||||
"opname" : "Length",
|
||||
"opcode" : 66,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Distance",
|
||||
"opcode" : 67,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'p0'" },
|
||||
{ "kind" : "IdRef", "name" : "'p1'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Cross",
|
||||
"opcode" : 68,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Normalize",
|
||||
"opcode" : 69,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FaceForward",
|
||||
"opcode" : 70,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'N'" },
|
||||
{ "kind" : "IdRef", "name" : "'I'" },
|
||||
{ "kind" : "IdRef", "name" : "'Nref'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Reflect",
|
||||
"opcode" : 71,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'I'" },
|
||||
{ "kind" : "IdRef", "name" : "'N'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "Refract",
|
||||
"opcode" : 72,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'I'" },
|
||||
{ "kind" : "IdRef", "name" : "'N'" },
|
||||
{ "kind" : "IdRef", "name" : "'eta'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FindILsb",
|
||||
"opcode" : 73,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'Value'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FindSMsb",
|
||||
"opcode" : 74,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'Value'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "FindUMsb",
|
||||
"opcode" : 75,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'Value'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "InterpolateAtCentroid",
|
||||
"opcode" : 76,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'interpolant'" }
|
||||
],
|
||||
"capabilities" : [ "InterpolationFunction" ]
|
||||
},
|
||||
{
|
||||
"opname" : "InterpolateAtSample",
|
||||
"opcode" : 77,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'interpolant'" },
|
||||
{ "kind" : "IdRef", "name" : "'sample'" }
|
||||
],
|
||||
"capabilities" : [ "InterpolationFunction" ]
|
||||
},
|
||||
{
|
||||
"opname" : "InterpolateAtOffset",
|
||||
"opcode" : 78,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'interpolant'" },
|
||||
{ "kind" : "IdRef", "name" : "'offset'" }
|
||||
],
|
||||
"capabilities" : [ "InterpolationFunction" ]
|
||||
},
|
||||
{
|
||||
"opname" : "NMin",
|
||||
"opcode" : 79,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "NMax",
|
||||
"opcode" : 80,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'y'" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"opname" : "NClamp",
|
||||
"opcode" : 81,
|
||||
"operands" : [
|
||||
{ "kind" : "IdRef", "name" : "'x'" },
|
||||
{ "kind" : "IdRef", "name" : "'minVal'" },
|
||||
{ "kind" : "IdRef", "name" : "'maxVal'" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -20,10 +20,14 @@
|
||||
|
||||
#define __GSK_H_INSIDE__
|
||||
|
||||
#include <gsk/gskcodesource.h>
|
||||
#include <gsk/gskenums.h>
|
||||
#include <gsk/gskpixelshader.h>
|
||||
#include <gsk/gskrenderer.h>
|
||||
#include <gsk/gskrendernode.h>
|
||||
#include <gsk/gskroundedrect.h>
|
||||
#include <gsk/gskslcompiler.h>
|
||||
#include <gsk/gskslprogram.h>
|
||||
#include <gsk/gsktexture.h>
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
|
152
gsk/gskcodesource.c
Normal file
152
gsk/gskcodesource.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskcodesourceprivate.h"
|
||||
|
||||
struct _GskCodeSource {
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
GFile *file;
|
||||
|
||||
GBytes *bytes;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskCodeSource, gsk_code_source, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gsk_code_source_dispose (GObject *object)
|
||||
{
|
||||
GskCodeSource *source = GSK_CODE_SOURCE (object);
|
||||
|
||||
g_free (source->name);
|
||||
if (source->file)
|
||||
g_object_unref (source->file);
|
||||
if (source->bytes)
|
||||
g_bytes_unref (source->bytes);
|
||||
|
||||
G_OBJECT_CLASS (gsk_code_source_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_code_source_class_init (GskCodeSourceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsk_code_source_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_code_source_init (GskCodeSource *source)
|
||||
{
|
||||
}
|
||||
|
||||
const char *
|
||||
gsk_code_source_get_name (GskCodeSource *source)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_CODE_SOURCE (source), NULL);
|
||||
|
||||
return source->name;
|
||||
}
|
||||
|
||||
GFile *
|
||||
gsk_code_source_get_file (GskCodeSource *source)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_CODE_SOURCE (source), NULL);
|
||||
|
||||
return source->file;
|
||||
}
|
||||
|
||||
GskCodeSource *
|
||||
gsk_code_source_new_for_bytes (const char *name,
|
||||
GBytes *data)
|
||||
{
|
||||
GskCodeSource *result;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
g_return_val_if_fail (data != NULL, NULL);
|
||||
|
||||
result = g_object_new (GSK_TYPE_CODE_SOURCE, NULL);
|
||||
|
||||
result->name = g_strdup (name);
|
||||
result->bytes = g_bytes_ref (data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_name_for_file (GFile *file)
|
||||
{
|
||||
GFileInfo *info;
|
||||
char *result;
|
||||
|
||||
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, NULL);
|
||||
|
||||
if (info)
|
||||
{
|
||||
result = g_strdup (g_file_info_get_display_name (info));
|
||||
g_object_unref (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = g_strdup ("<broken file>");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GskCodeSource *
|
||||
gsk_code_source_new_for_file (GFile *file)
|
||||
{
|
||||
GskCodeSource *result;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
result = g_object_new (GSK_TYPE_CODE_SOURCE, NULL);
|
||||
|
||||
result->file = g_object_ref (file);
|
||||
result->name = get_name_for_file (file);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GBytes *
|
||||
gsk_code_source_load (GskCodeSource *source,
|
||||
GError **error)
|
||||
{
|
||||
gchar *data;
|
||||
gsize length;
|
||||
|
||||
if (source->bytes)
|
||||
return g_bytes_ref (source->bytes);
|
||||
|
||||
g_return_val_if_fail (source->file, NULL);
|
||||
|
||||
if (!g_file_load_contents (source->file,
|
||||
NULL,
|
||||
&data, &length,
|
||||
NULL,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
source->bytes = g_bytes_new_take (data, length);
|
||||
return g_bytes_ref (source->bytes);
|
||||
}
|
||||
|
41
gsk/gskcodesource.h
Normal file
41
gsk/gskcodesource.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_CODE_SOURCE_H__
|
||||
#define __GSK_CODE_SOURCE_H__
|
||||
|
||||
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
|
||||
#error "Only <gsk/gsk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_CODE_SOURCE (gsk_code_source_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GskCodeSource, gsk_code_source, GSK, CODE_SOURCE, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
const char * gsk_code_source_get_name (GskCodeSource *source);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GFile * gsk_code_source_get_file (GskCodeSource *source);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_CODE_SOURCE_H__ */
|
35
gsk/gskcodesourceprivate.h
Normal file
35
gsk/gskcodesourceprivate.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_CODE_SOURCE_PRIVATE_H__
|
||||
#define __GSK_CODE_SOURCE_PRIVATE_H__
|
||||
|
||||
#include "gsk/gskcodesource.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskCodeSource * gsk_code_source_new_for_bytes (const char *name,
|
||||
GBytes *data);
|
||||
GskCodeSource * gsk_code_source_new_for_file (GFile *file);
|
||||
|
||||
GBytes * gsk_code_source_load (GskCodeSource *source,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_CODE_SOURCE_PRIVATE_H__ */
|
@@ -175,4 +175,33 @@ typedef enum {
|
||||
GSK_SERIALIZATION_INVALID_DATA
|
||||
} GskSerializationError;
|
||||
|
||||
/**
|
||||
* GskSlProfile:
|
||||
* @GSK_SL_PROFILE_NONE: No profile has been selected. Behaves the same
|
||||
* as @GSK_SL_PROFILE_CORE.
|
||||
* @GSK_SL_PROFILE_CORE: The OpenGL core profile
|
||||
* @GSK_SL_PROFILE_COMPATIBILITY: The OpenGL compatibility profile
|
||||
* @GSK_SL_PROFILE_ES: The OpenGL-ES profile
|
||||
*
|
||||
* Profile to use for GLSL compilation.
|
||||
**/
|
||||
typedef enum {
|
||||
GSK_SL_PROFILE_NONE,
|
||||
GSK_SL_PROFILE_CORE,
|
||||
GSK_SL_PROFILE_COMPATIBILITY,
|
||||
GSK_SL_PROFILE_ES,
|
||||
} GskSlProfile;
|
||||
|
||||
/**
|
||||
* GskSlShaderStage:
|
||||
* @GSK_SL_SHADER_VERTEX: The vertex shader stage
|
||||
* @GSK_SL_SHADER_FRAGMENT: The fragment shader stage
|
||||
*
|
||||
* The shader stage associated with a GLSL program.
|
||||
*/
|
||||
typedef enum {
|
||||
GSK_SL_SHADER_VERTEX,
|
||||
GSK_SL_SHADER_FRAGMENT
|
||||
} GskSlShaderStage;
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
|
189
gsk/gskpixelshader.c
Normal file
189
gsk/gskpixelshader.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/* GSK - The GTK Scene Kit
|
||||
*
|
||||
* Copyright 2017 © Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:GskPixelShader
|
||||
* @Title: GskPixelShader
|
||||
* @Short_description: A pixel shader
|
||||
*
|
||||
* #GskPixelShader is the object used to create pixel shaders. The language
|
||||
* used is GLSL with a few extensions.
|
||||
*
|
||||
* #GskPixelShader is an immutable object: That means you cannot change
|
||||
* anything about it other than increasing the reference count via
|
||||
* g_object_ref().
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskpixelshaderprivate.h"
|
||||
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskslcompiler.h"
|
||||
#include "gskslprogram.h"
|
||||
|
||||
#include "gdk/gdkinternals.h"
|
||||
|
||||
/**
|
||||
* GskPixelShader:
|
||||
*
|
||||
* The `GskPixelShader` structure contains only private data.
|
||||
*
|
||||
* Since: 3.90
|
||||
*/
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_N_TEXTURES,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
G_DEFINE_TYPE (GskPixelShader, gsk_pixel_shader, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
/* GskPixelShader *self = GSK_PIXEL_SHADER (gobject); */
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GskPixelShader *self = GSK_PIXEL_SHADER (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_N_TEXTURES:
|
||||
g_value_set_uint (value, self->n_textures);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_dispose (GObject *object)
|
||||
{
|
||||
GskPixelShader *self = GSK_PIXEL_SHADER (object);
|
||||
|
||||
g_object_unref (self->program);
|
||||
|
||||
G_OBJECT_CLASS (gsk_pixel_shader_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_class_init (GskPixelShaderClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = gsk_pixel_shader_set_property;
|
||||
gobject_class->get_property = gsk_pixel_shader_get_property;
|
||||
gobject_class->dispose = gsk_pixel_shader_dispose;
|
||||
|
||||
/**
|
||||
* GskPixelShader:n-textures:
|
||||
*
|
||||
* The number of input textures to the shader.
|
||||
*
|
||||
* Since: 3.92
|
||||
*/
|
||||
properties[PROP_N_TEXTURES] =
|
||||
g_param_spec_uint ("n-textures",
|
||||
"n textures",
|
||||
"The number of input textures",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_init (GskPixelShader *self)
|
||||
{
|
||||
}
|
||||
|
||||
GskPixelShader *
|
||||
gsk_pixel_shader_new_for_data (GBytes *source,
|
||||
GskShaderErrorFunc error_func,
|
||||
gpointer error_data)
|
||||
{
|
||||
GskSlCompiler *compiler;
|
||||
GskPixelShader *shader;
|
||||
GskSlProgram *program;
|
||||
|
||||
g_return_val_if_fail (source != NULL, NULL);
|
||||
|
||||
compiler = gsk_sl_compiler_new ();
|
||||
program = gsk_sl_compiler_compile_bytes (compiler, GSK_SL_SHADER_FRAGMENT, source);
|
||||
g_object_unref (compiler);
|
||||
if (program == NULL)
|
||||
return NULL;
|
||||
|
||||
shader = g_object_new (GSK_TYPE_PIXEL_SHADER, NULL);
|
||||
|
||||
shader->program = program;
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_pixel_shader_print (GskPixelShader *shader,
|
||||
GString *string)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_PIXEL_SHADER (shader));
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
gsk_sl_program_print (shader->program, string);
|
||||
}
|
||||
|
||||
char *
|
||||
gsk_pixel_shader_to_string (GskPixelShader *shader)
|
||||
{
|
||||
GString *string;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_PIXEL_SHADER (shader), NULL);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
|
||||
gsk_pixel_shader_print (shader, string);
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
62
gsk/gskpixelshader.h
Normal file
62
gsk/gskpixelshader.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* GSK - The GTK Scene Kit
|
||||
*
|
||||
* Copyright 2017 © Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_PIXEL_SHADER_H__
|
||||
#define __GSK_PIXEL_SHADER_H__
|
||||
|
||||
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
|
||||
#error "Only <gsk/gsk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_PIXEL_SHADER (gsk_pixel_shader_get_type ())
|
||||
|
||||
#define GSK_PIXEL_SHADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_PIXEL_SHADER, GskPixelShader))
|
||||
#define GSK_IS_PIXEL_SHADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_PIXEL_SHADER))
|
||||
|
||||
typedef struct _GskPixelShaderClass GskPixelShaderClass;
|
||||
|
||||
typedef void (* GskShaderErrorFunc) (GskPixelShader *shader,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskPixelShader, g_object_unref)
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GType gsk_pixel_shader_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GskPixelShader * gsk_pixel_shader_new_for_data (GBytes *source,
|
||||
GskShaderErrorFunc error_func,
|
||||
gpointer error_data);
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
void gsk_pixel_shader_print (GskPixelShader *shader,
|
||||
GString *string);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
char * gsk_pixel_shader_to_string (GskPixelShader *shader);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_PIXEL_SHADER_H__ */
|
27
gsk/gskpixelshaderprivate.h
Normal file
27
gsk/gskpixelshaderprivate.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __GSK_PIXEL_SHADER_PRIVATE_H__
|
||||
#define __GSK_PIXEL_SHADER_PRIVATE_H__
|
||||
|
||||
#include "gskpixelshader.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_PIXEL_SHADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_TEXTURE, GskPixelShaderClass))
|
||||
#define GSK_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_TEXTURE))
|
||||
#define GSK_PIXEL_SHADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_TEXTURE, GskPixelShaderClass))
|
||||
|
||||
struct _GskPixelShader
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GskSlProgram *program;
|
||||
|
||||
guint n_textures;
|
||||
};
|
||||
|
||||
struct _GskPixelShaderClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_PIXEL_SHADER_PRIVATE_H__ */
|
2230
gsk/gskslbinary.c
Normal file
2230
gsk/gskslbinary.c
Normal file
File diff suppressed because it is too large
Load Diff
52
gsk/gskslbinaryprivate.h
Normal file
52
gsk/gskslbinaryprivate.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_BINARY_PRIVATE_H__
|
||||
#define __GSK_SL_BINARY_PRIVATE_H__
|
||||
|
||||
#include "gsk/gsksltypesprivate.h"
|
||||
#include "gsk/gsksltokenizerprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskSlBinary GskSlBinary;
|
||||
|
||||
const GskSlBinary * gsk_sl_binary_get_for_token (GskSlTokenType token);
|
||||
|
||||
const char * gsk_sl_binary_get_sign (const GskSlBinary *binary);
|
||||
|
||||
GskSlType * gsk_sl_binary_check_type (const GskSlBinary *binary,
|
||||
GskSlPreprocessor *stream,
|
||||
GskSlType *ltype,
|
||||
GskSlType *rtype);
|
||||
GskSlValue * gsk_sl_binary_get_constant (const GskSlBinary *binary,
|
||||
GskSlType *type,
|
||||
GskSlValue *lvalue,
|
||||
GskSlValue *rvalue);
|
||||
guint32 gsk_sl_binary_write_spv (const GskSlBinary *binary,
|
||||
GskSpvWriter *writer,
|
||||
GskSlType *type,
|
||||
GskSlType *ltype,
|
||||
guint32 left_id,
|
||||
GskSlType *rtype,
|
||||
guint32 right_id);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_BINARY_PRIVATE_H__ */
|
300
gsk/gskslcompiler.c
Normal file
300
gsk/gskslcompiler.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslcompilerprivate.h"
|
||||
|
||||
#include "gskcodesourceprivate.h"
|
||||
#include "gsksldefineprivate.h"
|
||||
#include "gskslenvironmentprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslprogramprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
|
||||
struct _GskSlCompiler {
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *defines;
|
||||
};
|
||||
|
||||
G_DEFINE_QUARK (gsk-sl-compiler-error-quark, gsk_sl_compiler_error)
|
||||
G_DEFINE_QUARK (gsk-sl-compiler-warning-quark, gsk_sl_compiler_warning)
|
||||
|
||||
G_DEFINE_TYPE (GskSlCompiler, gsk_sl_compiler, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gsk_sl_compiler_dispose (GObject *object)
|
||||
{
|
||||
GskSlCompiler *compiler = GSK_SL_COMPILER (object);
|
||||
|
||||
g_hash_table_destroy (compiler->defines);
|
||||
|
||||
G_OBJECT_CLASS (gsk_sl_compiler_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_compiler_class_init (GskSlCompilerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsk_sl_compiler_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_compiler_init (GskSlCompiler *compiler)
|
||||
{
|
||||
compiler->defines = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify) gsk_sl_define_unref);
|
||||
}
|
||||
|
||||
GskSlCompiler *
|
||||
gsk_sl_compiler_new (void)
|
||||
{
|
||||
return g_object_new (GSK_TYPE_SL_COMPILER, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_compiler_add_define_error_func (GskSlTokenizer *parser,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError **real_error = user_data;
|
||||
|
||||
if (!fatal)
|
||||
return;
|
||||
|
||||
if (*real_error)
|
||||
return;
|
||||
|
||||
*real_error = g_error_copy (error);
|
||||
g_prefix_error (real_error,
|
||||
"%3zu:%2zu: ",
|
||||
location->lines + 1,
|
||||
location->line_bytes);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_compiler_add_define (GskSlCompiler *compiler,
|
||||
const char *name,
|
||||
const char *definition,
|
||||
GError **error)
|
||||
{
|
||||
GskSlTokenizer *tokenizer;
|
||||
GskSlDefine *define;
|
||||
GskCodeLocation location;
|
||||
GskSlToken token = { 0, };
|
||||
GError *real_error = NULL;
|
||||
GskCodeSource *source;
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SL_COMPILER (compiler), FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (!gsk_sl_string_is_valid_identifier (name))
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Define name \"%s\" is not a valid identifier", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (definition == NULL)
|
||||
definition = "1";
|
||||
|
||||
define = gsk_sl_define_new (name, NULL);
|
||||
bytes = g_bytes_new_static (definition, strlen (definition));
|
||||
source = gsk_code_source_new_for_bytes ("<define>", bytes);
|
||||
tokenizer = gsk_sl_tokenizer_new (source,
|
||||
gsk_sl_compiler_add_define_error_func,
|
||||
&real_error,
|
||||
NULL);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
gsk_sl_token_clear (&token);
|
||||
location = *gsk_sl_tokenizer_get_location (tokenizer);
|
||||
gsk_sl_tokenizer_read_token (tokenizer, &token);
|
||||
}
|
||||
while (gsk_sl_token_is_skipped (&token));
|
||||
|
||||
if (gsk_sl_token_is (&token, GSK_SL_TOKEN_EOF))
|
||||
break;
|
||||
|
||||
gsk_sl_define_add_token (define, &location, &token);
|
||||
}
|
||||
|
||||
gsk_sl_token_clear (&token);
|
||||
gsk_sl_tokenizer_unref (tokenizer);
|
||||
g_bytes_unref (bytes);
|
||||
g_object_unref (source);
|
||||
|
||||
if (real_error == NULL)
|
||||
{
|
||||
g_hash_table_replace (compiler->defines, (gpointer) gsk_sl_define_get_name (define), define);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_define_unref (define);
|
||||
g_propagate_error (error, real_error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_compiler_remove_define (GskSlCompiler *compiler,
|
||||
const char *name)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SL_COMPILER (compiler));
|
||||
g_return_if_fail (name != NULL);
|
||||
|
||||
g_hash_table_remove (compiler->defines, name);
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
gsk_sl_compiler_copy_defines (GskSlCompiler *compiler)
|
||||
{
|
||||
GHashTable *copy;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
copy = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify) gsk_sl_define_unref);
|
||||
|
||||
g_hash_table_iter_init (&iter, compiler->defines);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
g_hash_table_replace (copy, key, gsk_sl_define_ref (value));
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
GskCodeSource *
|
||||
gsk_sl_compiler_resolve_include (GskSlCompiler *compiler,
|
||||
GskCodeSource *source,
|
||||
gboolean local,
|
||||
const char *name,
|
||||
GError **error)
|
||||
{
|
||||
GskCodeSource *result;
|
||||
GBytes *bytes;
|
||||
|
||||
if (local)
|
||||
{
|
||||
GFile *source_file = gsk_code_source_get_file (source);
|
||||
if (source_file)
|
||||
{
|
||||
GFile *parent, *file;
|
||||
|
||||
parent = g_file_get_parent (source_file);
|
||||
file = g_file_resolve_relative_path (parent, name);
|
||||
result = gsk_code_source_new_for_file (file);
|
||||
g_object_unref (parent);
|
||||
g_object_unref (file);
|
||||
bytes = gsk_code_source_load (result, error);
|
||||
if (bytes)
|
||||
{
|
||||
g_bytes_unref (bytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
g_object_unref (result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_EXIST,
|
||||
"Could not resolve \"%s\" in search path.", name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GskSlProgram *
|
||||
gsk_sl_compiler_compile (GskSlCompiler *compiler,
|
||||
GskSlShaderStage stage,
|
||||
GskCodeSource *source)
|
||||
{
|
||||
GskSlPreprocessor *preproc;
|
||||
GskSlEnvironment *environment;
|
||||
GskSlProgram *program;
|
||||
|
||||
program = g_object_new (GSK_TYPE_SL_PROGRAM, NULL);
|
||||
|
||||
environment = gsk_sl_environment_new (stage, GSK_SL_PROFILE_CORE, 150);
|
||||
preproc = gsk_sl_preprocessor_new (compiler, environment, source);
|
||||
gsk_sl_environment_unref (environment);
|
||||
|
||||
gsk_sl_program_parse (program, preproc);
|
||||
|
||||
if (gsk_sl_preprocessor_has_fatal_error (preproc))
|
||||
{
|
||||
g_object_unref (program);
|
||||
program = NULL;
|
||||
}
|
||||
|
||||
gsk_sl_preprocessor_unref (preproc);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
GskSlProgram *
|
||||
gsk_sl_compiler_compile_file (GskSlCompiler *compiler,
|
||||
GskSlShaderStage stage,
|
||||
GFile *file)
|
||||
{
|
||||
GskSlProgram *program;
|
||||
GskCodeSource *source;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SL_COMPILER (compiler), NULL);
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
source = gsk_code_source_new_for_file (file);
|
||||
|
||||
program = gsk_sl_compiler_compile (compiler, stage, source);
|
||||
|
||||
g_object_unref (source);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
GskSlProgram *
|
||||
gsk_sl_compiler_compile_bytes (GskSlCompiler *compiler,
|
||||
GskSlShaderStage stage,
|
||||
GBytes *bytes)
|
||||
{
|
||||
GskSlProgram *program;
|
||||
GskCodeSource *source;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SL_COMPILER (compiler), NULL);
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
|
||||
source = gsk_code_source_new_for_bytes ("<program>", bytes);
|
||||
|
||||
program = gsk_sl_compiler_compile (compiler, stage, source);
|
||||
|
||||
g_object_unref (source);
|
||||
|
||||
return program;
|
||||
}
|
88
gsk/gskslcompiler.h
Normal file
88
gsk/gskslcompiler.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_COMPILER_H__
|
||||
#define __GSK_SL_COMPILER_H__
|
||||
|
||||
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
|
||||
#error "Only <gsk/gsk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_COMPILER_ERROR_ARGUMENT_COUNT,
|
||||
GSK_SL_COMPILER_ERROR_CONSTANT,
|
||||
GSK_SL_COMPILER_ERROR_DECLARATION,
|
||||
GSK_SL_COMPILER_ERROR_PREPROCESSOR,
|
||||
GSK_SL_COMPILER_ERROR_RANGE,
|
||||
GSK_SL_COMPILER_ERROR_SCOPE,
|
||||
GSK_SL_COMPILER_ERROR_SYNTAX,
|
||||
GSK_SL_COMPILER_ERROR_TOKENIZER,
|
||||
GSK_SL_COMPILER_ERROR_TYPE_MISMATCH,
|
||||
GSK_SL_COMPILER_ERROR_UNIQUENESS,
|
||||
GSK_SL_COMPILER_ERROR_UNSUPPORTED,
|
||||
} GskSlCompilerError;
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_COMPILER_WARNING_ARRAY_OF_ARRAY,
|
||||
GSK_SL_COMPILER_WARNING_CONSTANT,
|
||||
GSK_SL_COMPILER_WARNING_DEAD_CODE,
|
||||
GSK_SL_COMPILER_WARNING_SHADOW,
|
||||
GSK_SL_COMPILER_WARNING_UNIMPLEMENTED,
|
||||
GSK_SL_COMPILER_WARNING_VERSION
|
||||
} GskSlCompilerWarning;
|
||||
|
||||
#define GSK_SL_COMPILER_ERROR (gsk_sl_compiler_error_quark ())
|
||||
#define GSK_SL_COMPILER_WARNING (gsk_sl_compiler_warning_quark ())
|
||||
|
||||
#define GSK_TYPE_SL_COMPILER (gsk_sl_compiler_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GskSlCompiler, gsk_sl_compiler, GSK, SL_COMPILER, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GQuark gsk_sl_compiler_error_quark (void);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GQuark gsk_sl_compiler_warning_quark (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GskSlCompiler * gsk_sl_compiler_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
gboolean gsk_sl_compiler_add_define (GskSlCompiler *compiler,
|
||||
const char *name,
|
||||
const char *definition,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
void gsk_sl_compiler_remove_define (GskSlCompiler *compiler,
|
||||
const char *name);
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GskSlProgram * gsk_sl_compiler_compile_file (GskSlCompiler *compiler,
|
||||
GskSlShaderStage stage,
|
||||
GFile *file);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GskSlProgram * gsk_sl_compiler_compile_bytes (GskSlCompiler *compiler,
|
||||
GskSlShaderStage stage,
|
||||
GBytes *bytes);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_COMPILER_H__ */
|
36
gsk/gskslcompilerprivate.h
Normal file
36
gsk/gskslcompilerprivate.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_COMPILER_PRIVATE_H__
|
||||
#define __GSK_SL_COMPILER_PRIVATE_H__
|
||||
|
||||
#include "gsk/gskslcompiler.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GHashTable * gsk_sl_compiler_copy_defines (GskSlCompiler *compiler);
|
||||
|
||||
GskCodeSource * gsk_sl_compiler_resolve_include (GskSlCompiler *compiler,
|
||||
GskCodeSource *source,
|
||||
gboolean local,
|
||||
const char *name,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_COMPILER_PRIVATE_H__ */
|
549
gsk/gsksldeclaration.c
Normal file
549
gsk/gsksldeclaration.c
Normal file
@@ -0,0 +1,549 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsksldeclarationprivate.h"
|
||||
|
||||
#include "gskslexpressionprivate.h"
|
||||
#include "gskslfunctionprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslprinterprivate.h"
|
||||
#include "gskslscopeprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslqualifierprivate.h"
|
||||
#include "gskslvalueprivate.h"
|
||||
#include "gskslvariableprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
typedef struct _GskSlDeclarationClass GskSlDeclarationClass;
|
||||
|
||||
struct _GskSlDeclaration {
|
||||
const GskSlDeclarationClass *class;
|
||||
guint ref_count;
|
||||
};
|
||||
|
||||
struct _GskSlDeclarationClass {
|
||||
gsize element_size;
|
||||
void (* finalize) (GskSlDeclaration *declaration);
|
||||
|
||||
void (* print) (const GskSlDeclaration *declaration,
|
||||
GskSlPrinter *printer);
|
||||
void (* write_initializer_spv) (const GskSlDeclaration *declaration,
|
||||
GskSpvWriter *writer);
|
||||
};
|
||||
|
||||
static gpointer
|
||||
gsk_sl_declaration_new (const GskSlDeclarationClass *klass)
|
||||
{
|
||||
GskSlDeclaration *declaration;
|
||||
|
||||
declaration = g_slice_alloc0 (klass->element_size);
|
||||
|
||||
declaration->class = klass;
|
||||
declaration->ref_count = 1;
|
||||
|
||||
return declaration;
|
||||
}
|
||||
|
||||
/* VARIABLE */
|
||||
|
||||
typedef struct _GskSlDeclarationVariable GskSlDeclarationVariable;
|
||||
|
||||
struct _GskSlDeclarationVariable {
|
||||
GskSlDeclaration parent;
|
||||
|
||||
GskSlVariable *variable;
|
||||
GskSlExpression *initial;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_variable_finalize (GskSlDeclaration *declaration)
|
||||
{
|
||||
GskSlDeclarationVariable *variable = (GskSlDeclarationVariable *) declaration;
|
||||
|
||||
gsk_sl_variable_unref (variable->variable);
|
||||
if (variable->initial)
|
||||
gsk_sl_expression_unref (variable->initial);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_variable_print (const GskSlDeclaration *declaration,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
GskSlDeclarationVariable *variable = (GskSlDeclarationVariable *) declaration;
|
||||
|
||||
gsk_sl_variable_print (variable->variable, printer);
|
||||
if (variable->initial)
|
||||
{
|
||||
gsk_sl_printer_append (printer, " = ");
|
||||
gsk_sl_expression_print (variable->initial, printer);
|
||||
}
|
||||
gsk_sl_printer_append (printer, ";");
|
||||
gsk_sl_printer_newline (printer);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_variable_write_initializer_spv (const GskSlDeclaration *declaration,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
GskSlDeclarationVariable *variable = (GskSlDeclarationVariable *) declaration;
|
||||
|
||||
/* make sure it's written */
|
||||
gsk_spv_writer_get_id_for_variable (writer, variable->variable);
|
||||
|
||||
if (variable->initial && ! gsk_sl_variable_get_initial_value (variable->variable))
|
||||
{
|
||||
GskSpvAccessChain *chain = gsk_sl_variable_get_access_chain (variable->variable, writer);
|
||||
|
||||
g_assert (chain); /* code further up should make sure this never happens */
|
||||
gsk_spv_access_chain_store (chain,
|
||||
gsk_sl_expression_write_spv (variable->initial,
|
||||
writer,
|
||||
gsk_sl_variable_get_type (variable->variable)));
|
||||
gsk_spv_access_chain_free (chain);
|
||||
}
|
||||
}
|
||||
|
||||
static const GskSlDeclarationClass GSK_SL_DECLARATION_VARIABLE = {
|
||||
sizeof (GskSlDeclarationVariable),
|
||||
gsk_sl_declaration_variable_finalize,
|
||||
gsk_sl_declaration_variable_print,
|
||||
gsk_sl_declaration_variable_write_initializer_spv
|
||||
};
|
||||
|
||||
/* TYPE */
|
||||
|
||||
typedef struct _GskSlDeclarationType GskSlDeclarationType;
|
||||
|
||||
struct _GskSlDeclarationType {
|
||||
GskSlDeclaration parent;
|
||||
|
||||
GskSlQualifier qualifier;
|
||||
GskSlType *type;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_type_finalize (GskSlDeclaration *declaration)
|
||||
{
|
||||
GskSlDeclarationType *type = (GskSlDeclarationType *) declaration;
|
||||
|
||||
gsk_sl_type_unref (type->type);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_type_print (const GskSlDeclaration *declaration,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
GskSlDeclarationType *type = (GskSlDeclarationType *) declaration;
|
||||
|
||||
if (gsk_sl_qualifier_print (&type->qualifier, printer))
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_name (type->type));
|
||||
gsk_sl_printer_append (printer, ";");
|
||||
gsk_sl_printer_newline (printer);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_type_write_initializer_spv (const GskSlDeclaration *declaration,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
/* This declaration is only relevant for printing as it just declares a type */
|
||||
}
|
||||
|
||||
static const GskSlDeclarationClass GSK_SL_DECLARATION_TYPE = {
|
||||
sizeof (GskSlDeclarationType),
|
||||
gsk_sl_declaration_type_finalize,
|
||||
gsk_sl_declaration_type_print,
|
||||
gsk_sl_declaration_type_write_initializer_spv
|
||||
};
|
||||
|
||||
/* FUNCTION */
|
||||
|
||||
typedef struct _GskSlDeclarationFunction GskSlDeclarationFunction;
|
||||
|
||||
struct _GskSlDeclarationFunction {
|
||||
GskSlDeclaration parent;
|
||||
|
||||
GskSlFunction *function;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_function_free (GskSlDeclaration *declaration)
|
||||
{
|
||||
GskSlDeclarationFunction *function = (GskSlDeclarationFunction *) declaration;
|
||||
|
||||
gsk_sl_function_unref (function->function);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_function_print (const GskSlDeclaration *declaration,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
GskSlDeclarationFunction *function = (GskSlDeclarationFunction *) declaration;
|
||||
|
||||
gsk_sl_function_print (function->function, printer);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_declaration_function_write_initializer_spv (const GskSlDeclaration *declaration,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
/* functions are written out as-needed, so no need to force it */
|
||||
}
|
||||
|
||||
static const GskSlDeclarationClass GSK_SL_DECLARATION_FUNCTION = {
|
||||
sizeof (GskSlDeclarationFunction),
|
||||
gsk_sl_declaration_function_free,
|
||||
gsk_sl_declaration_function_print,
|
||||
gsk_sl_declaration_function_write_initializer_spv
|
||||
};
|
||||
|
||||
/* API */
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_declaration_parse_block_type (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlType *type;
|
||||
const GskSlToken *token;
|
||||
GskSlTypeBuilder *builder;
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
builder = gsk_sl_type_builder_new_block (token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected block name.");
|
||||
return gsk_sl_type_ref (gsk_sl_type_get_scalar (GSK_SL_FLOAT));
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected opening \"{\" after block declaration.");
|
||||
goto out;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
for (token = gsk_sl_preprocessor_get (preproc);
|
||||
!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE) && !gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
|
||||
token = gsk_sl_preprocessor_get (preproc))
|
||||
{
|
||||
type = gsk_sl_type_new_parse (scope, preproc);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected identifier for type name.");
|
||||
break;
|
||||
}
|
||||
if (gsk_sl_type_builder_has_member (builder, token->str))
|
||||
gsk_sl_preprocessor_error (preproc, DECLARATION, "Duplicate block member name \"%s\".", token->str);
|
||||
else
|
||||
gsk_sl_type_builder_add_member (builder, type, token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
|
||||
break;
|
||||
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
gsk_sl_type_unref (type);
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected semicolon after block member declaration.");
|
||||
else
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \"}\" after block declaration.");
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_BRACE);
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
out:
|
||||
return gsk_sl_type_builder_free (builder);
|
||||
}
|
||||
|
||||
static GskSlDeclaration *
|
||||
gsk_sl_declaration_parse_block (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
const GskSlQualifier *qualifier)
|
||||
{
|
||||
GskSlDeclarationVariable *variable;
|
||||
const GskSlToken *token;
|
||||
GskSlType *type;
|
||||
|
||||
type = gsk_sl_declaration_parse_block_type (scope, preproc);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = g_strdup (token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
type = gsk_sl_type_parse_array (type, scope, preproc);
|
||||
gsk_sl_qualifier_check_type (qualifier, preproc, type);
|
||||
|
||||
variable = gsk_sl_declaration_new (&GSK_SL_DECLARATION_VARIABLE);
|
||||
variable->variable = gsk_sl_variable_new (name, type, qualifier, NULL);
|
||||
gsk_sl_scope_try_add_variable (scope, preproc, variable->variable);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsize i;
|
||||
|
||||
gsk_sl_qualifier_check_type (qualifier, preproc, type);
|
||||
|
||||
variable = gsk_sl_declaration_new (&GSK_SL_DECLARATION_VARIABLE);
|
||||
variable->variable = gsk_sl_variable_new (NULL, type, qualifier, NULL);
|
||||
|
||||
for (i = 0; i < gsk_sl_type_get_n_members (type); i++)
|
||||
{
|
||||
GskSlVariable *sub;
|
||||
|
||||
sub = gsk_sl_variable_new_block_member (variable->variable, i);
|
||||
gsk_sl_scope_try_add_variable (scope, preproc, sub);
|
||||
gsk_sl_variable_unref (sub);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of variable declaration.");
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_SEMICOLON);
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
return &variable->parent;
|
||||
}
|
||||
|
||||
static GskSlDeclaration *
|
||||
gsk_sl_declaration_parse_variable (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
const GskSlQualifier *qualifier,
|
||||
GskSlType *base_type,
|
||||
const char *name)
|
||||
{
|
||||
GskSlDeclarationVariable *variable;
|
||||
GskSlValue *initial_value = NULL;
|
||||
GskSlExpression *initial = NULL;
|
||||
GskSlType *type;
|
||||
const GskSlToken *token;
|
||||
|
||||
type = gsk_sl_type_ref (base_type);
|
||||
type = gsk_sl_type_parse_array (type, scope, preproc);
|
||||
|
||||
gsk_sl_qualifier_check_type (qualifier, preproc, type);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
initial = gsk_sl_expression_parse_initializer (scope, preproc, type);
|
||||
|
||||
if (!gsk_sl_type_can_convert (type, gsk_sl_expression_get_return_type (initial)))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH,
|
||||
"Cannot convert from initializer type %s to variable type %s",
|
||||
gsk_sl_type_get_name (gsk_sl_expression_get_return_type (initial)),
|
||||
gsk_sl_type_get_name (type));
|
||||
gsk_sl_expression_unref (initial);
|
||||
initial = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
GskSlValue *unconverted = gsk_sl_expression_get_constant (initial);
|
||||
if (unconverted)
|
||||
{
|
||||
initial_value = gsk_sl_value_new_convert (unconverted, type);
|
||||
gsk_sl_value_free (unconverted);
|
||||
}
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of variable declaration.");
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_SEMICOLON);
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
if (qualifier->storage == GSK_SL_STORAGE_GLOBAL_CONST &&
|
||||
initial_value == NULL)
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, DECLARATION, "Variables with \"const\" qualifier must be initialized with a constant value.");
|
||||
initial_value = gsk_sl_value_new (type);
|
||||
}
|
||||
|
||||
variable = gsk_sl_declaration_new (&GSK_SL_DECLARATION_VARIABLE);
|
||||
variable->variable = gsk_sl_variable_new (name, type, qualifier, initial_value);
|
||||
variable->initial = initial;
|
||||
gsk_sl_scope_try_add_variable (scope, preproc, variable->variable);
|
||||
|
||||
gsk_sl_type_unref (type);
|
||||
|
||||
return &variable->parent;
|
||||
}
|
||||
|
||||
GskSlDeclaration *
|
||||
gsk_sl_declaration_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlDeclaration *result;
|
||||
GskSlType *type;
|
||||
const GskSlToken *token;
|
||||
GskSlQualifier qualifier;
|
||||
char *name;
|
||||
|
||||
gsk_sl_qualifier_parse (&qualifier, scope, preproc, GSK_SL_QUALIFIER_GLOBAL);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
type = gsk_sl_scope_lookup_type (scope, token->str);
|
||||
if (type == NULL)
|
||||
return gsk_sl_declaration_parse_block (scope, preproc, &qualifier);
|
||||
gsk_sl_type_ref (type);
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = gsk_sl_type_new_parse (scope, preproc);
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
GskSlDeclarationType *type_decl = gsk_sl_declaration_new (&GSK_SL_DECLARATION_TYPE);
|
||||
|
||||
type_decl->qualifier = qualifier;
|
||||
type_decl->type = type;
|
||||
gsk_sl_preprocessor_consume (preproc, type_decl);
|
||||
return &type_decl->parent;
|
||||
}
|
||||
else if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected a variable name");
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
gsk_sl_type_unref (type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = g_strdup (token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
GskSlFunctionMatcher matcher;
|
||||
GskSlDeclarationFunction *function;
|
||||
|
||||
function = gsk_sl_declaration_new (&GSK_SL_DECLARATION_FUNCTION);
|
||||
function->function = gsk_sl_function_new_parse (scope,
|
||||
preproc,
|
||||
type,
|
||||
name);
|
||||
gsk_sl_scope_match_function (scope, &matcher, gsk_sl_function_get_name (function->function));
|
||||
gsk_sl_function_matcher_match_function (&matcher, function->function);
|
||||
if (gsk_sl_function_matcher_has_matches (&matcher))
|
||||
gsk_sl_preprocessor_error (preproc, DECLARATION, "A function with the same prototype has already been defined.");
|
||||
else
|
||||
gsk_sl_scope_add_function (scope, function->function);
|
||||
gsk_sl_function_matcher_finish (&matcher);
|
||||
result = &function->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = gsk_sl_declaration_parse_variable (scope, preproc, &qualifier, type, name);
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
gsk_sl_type_unref (type);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GskSlDeclaration *
|
||||
gsk_sl_declaration_ref (GskSlDeclaration *declaration)
|
||||
{
|
||||
g_return_val_if_fail (declaration != NULL, NULL);
|
||||
|
||||
declaration->ref_count += 1;
|
||||
|
||||
return declaration;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_declaration_unref (GskSlDeclaration *declaration)
|
||||
{
|
||||
if (declaration == NULL)
|
||||
return;
|
||||
|
||||
declaration->ref_count -= 1;
|
||||
if (declaration->ref_count > 0)
|
||||
return;
|
||||
|
||||
declaration->class->finalize (declaration);
|
||||
|
||||
g_slice_free1 (declaration->class->element_size, declaration);
|
||||
}
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_declaration_get_function (GskSlDeclaration *declaration)
|
||||
{
|
||||
if (declaration->class != &GSK_SL_DECLARATION_FUNCTION)
|
||||
return NULL;
|
||||
|
||||
return ((GskSlDeclarationFunction *) declaration)->function;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_declaration_print (const GskSlDeclaration *declaration,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
declaration->class->print (declaration, printer);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_declaration_write_initializer_spv (const GskSlDeclaration *declaration,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
declaration->class->write_initializer_spv (declaration, writer);
|
||||
}
|
||||
|
44
gsk/gsksldeclarationprivate.h
Normal file
44
gsk/gsksldeclarationprivate.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_DECLARATION_PRIVATE_H__
|
||||
#define __GSK_SL_DECLARATION_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsk/gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlDeclaration * gsk_sl_declaration_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc);
|
||||
|
||||
GskSlDeclaration * gsk_sl_declaration_ref (GskSlDeclaration *declaration);
|
||||
void gsk_sl_declaration_unref (GskSlDeclaration *declaration);
|
||||
|
||||
GskSlFunction * gsk_sl_declaration_get_function (GskSlDeclaration *declaration);
|
||||
|
||||
void gsk_sl_declaration_print (const GskSlDeclaration *declaration,
|
||||
GskSlPrinter *printer);
|
||||
|
||||
void gsk_sl_declaration_write_initializer_spv(const GskSlDeclaration *declaration,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_DECLARATION_PRIVATE_H__ */
|
132
gsk/gsksldefine.c
Normal file
132
gsk/gsksldefine.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsksldefineprivate.h"
|
||||
|
||||
typedef struct _GskSlDefineToken GskSlDefineToken;
|
||||
|
||||
struct _GskSlDefineToken {
|
||||
GskCodeLocation location;
|
||||
GskSlToken token;
|
||||
};
|
||||
|
||||
struct _GskSlDefine {
|
||||
int ref_count;
|
||||
|
||||
char *name;
|
||||
GFile *source_file;
|
||||
|
||||
GArray *tokens;
|
||||
};
|
||||
|
||||
GskSlDefine *
|
||||
gsk_sl_define_new (const char *name,
|
||||
GFile *source_file)
|
||||
{
|
||||
GskSlDefine *result;
|
||||
|
||||
result = g_slice_new0 (GskSlDefine);
|
||||
|
||||
result->ref_count = 1;
|
||||
result->name = g_strdup (name);
|
||||
if (source_file)
|
||||
result->source_file = g_object_ref (source_file);
|
||||
result->tokens = g_array_new (FALSE, FALSE, sizeof (GskSlDefineToken));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GskSlDefine *
|
||||
gsk_sl_define_ref (GskSlDefine *define)
|
||||
{
|
||||
g_return_val_if_fail (define != NULL, NULL);
|
||||
|
||||
define->ref_count += 1;
|
||||
|
||||
return define;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_define_unref (GskSlDefine *define)
|
||||
{
|
||||
if (define == NULL)
|
||||
return;
|
||||
|
||||
define->ref_count -= 1;
|
||||
if (define->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_array_free (define->tokens, TRUE);
|
||||
|
||||
if (define->source_file)
|
||||
g_object_unref (define->source_file);
|
||||
g_free (define->name);
|
||||
|
||||
g_slice_free (GskSlDefine, define);
|
||||
}
|
||||
|
||||
const char *
|
||||
gsk_sl_define_get_name (GskSlDefine *define)
|
||||
{
|
||||
return define->name;
|
||||
}
|
||||
|
||||
GFile *
|
||||
gsk_sl_define_get_source_file (GskSlDefine *define)
|
||||
{
|
||||
return define->source_file;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_define_get_n_tokens (GskSlDefine *define)
|
||||
{
|
||||
return define->tokens->len;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_define_get_token (GskSlDefine *define,
|
||||
guint i,
|
||||
GskCodeLocation *location,
|
||||
GskSlToken *token)
|
||||
{
|
||||
GskSlDefineToken *dt;
|
||||
|
||||
dt = &g_array_index (define->tokens, GskSlDefineToken, i);
|
||||
|
||||
if (location)
|
||||
*location = dt->location;
|
||||
if (token)
|
||||
gsk_sl_token_copy (token, &dt->token);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_define_add_token (GskSlDefine *define,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token)
|
||||
{
|
||||
GskSlDefineToken dt;
|
||||
|
||||
dt.location = *location;
|
||||
gsk_sl_token_copy (&dt.token, token);
|
||||
|
||||
g_array_append_val (define->tokens, dt);
|
||||
}
|
||||
|
||||
|
51
gsk/gsksldefineprivate.h
Normal file
51
gsk/gsksldefineprivate.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_DEFINE_PRIVATE_H__
|
||||
#define __GSK_SL_DEFINE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskSlDefine GskSlDefine;
|
||||
|
||||
GskSlDefine * gsk_sl_define_new (const char *name,
|
||||
GFile *source_file);
|
||||
|
||||
GskSlDefine * gsk_sl_define_ref (GskSlDefine *define);
|
||||
void gsk_sl_define_unref (GskSlDefine *define);
|
||||
|
||||
const char * gsk_sl_define_get_name (GskSlDefine *define);
|
||||
GFile * gsk_sl_define_get_source_file (GskSlDefine *define);
|
||||
guint gsk_sl_define_get_n_tokens (GskSlDefine *define);
|
||||
void gsk_sl_define_get_token (GskSlDefine *define,
|
||||
guint i,
|
||||
GskCodeLocation *location,
|
||||
GskSlToken *token);
|
||||
|
||||
void gsk_sl_define_add_token (GskSlDefine *define,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_DEFINE_PRIVATE_H__ */
|
119
gsk/gskslenvironment.c
Normal file
119
gsk/gskslenvironment.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslenvironmentprivate.h"
|
||||
|
||||
#include "gskslnativefunctionprivate.h"
|
||||
#include "gskslnativevariableprivate.h"
|
||||
#include "gskslscopeprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct _GskSlEnvironment
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlShaderStage stage;
|
||||
GskSlProfile profile;
|
||||
guint version;
|
||||
};
|
||||
|
||||
GskSlEnvironment *
|
||||
gsk_sl_environment_new (GskSlShaderStage stage,
|
||||
GskSlProfile profile,
|
||||
guint version)
|
||||
{
|
||||
GskSlEnvironment *environment;
|
||||
|
||||
environment = g_slice_new0 (GskSlEnvironment);
|
||||
environment->ref_count = 1;
|
||||
|
||||
environment->stage = stage;
|
||||
environment->profile = profile;
|
||||
environment->version = version;
|
||||
|
||||
return environment;
|
||||
}
|
||||
|
||||
GskSlEnvironment *
|
||||
gsk_sl_environment_new_similar (GskSlEnvironment *environment,
|
||||
GskSlProfile profile,
|
||||
guint version,
|
||||
GError **error)
|
||||
{
|
||||
return gsk_sl_environment_new (environment->stage,
|
||||
profile == GSK_SL_PROFILE_NONE ? environment->profile : profile,
|
||||
version);
|
||||
}
|
||||
|
||||
GskSlEnvironment *
|
||||
gsk_sl_environment_ref (GskSlEnvironment *environment)
|
||||
{
|
||||
g_return_val_if_fail (environment != NULL, NULL);
|
||||
|
||||
environment->ref_count += 1;
|
||||
|
||||
return environment;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_environment_unref (GskSlEnvironment *environment)
|
||||
{
|
||||
if (environment == NULL)
|
||||
return;
|
||||
|
||||
environment->ref_count -= 1;
|
||||
if (environment->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_slice_free (GskSlEnvironment, environment);
|
||||
}
|
||||
|
||||
GskSlShaderStage
|
||||
gsk_sl_environment_get_stage (GskSlEnvironment *environment)
|
||||
{
|
||||
return environment->stage;
|
||||
}
|
||||
|
||||
GskSlProfile
|
||||
gsk_sl_environment_get_profile (GskSlEnvironment *environment)
|
||||
{
|
||||
return environment->profile;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_environment_get_version (GskSlEnvironment *environment)
|
||||
{
|
||||
return environment->version;
|
||||
}
|
||||
|
||||
GskSlScope *
|
||||
gsk_sl_environment_create_scope (GskSlEnvironment *environment)
|
||||
{
|
||||
GskSlScope *scope;
|
||||
|
||||
scope = gsk_sl_scope_new (NULL, NULL);
|
||||
|
||||
gsk_sl_native_functions_add (scope, environment);
|
||||
gsk_sl_native_variables_add (scope, environment);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
47
gsk/gskslenvironmentprivate.h
Normal file
47
gsk/gskslenvironmentprivate.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_ENVIRONMENT_PRIVATE_H__
|
||||
#define __GSK_SL_ENVIRONMENT_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlEnvironment * gsk_sl_environment_new (GskSlShaderStage stage,
|
||||
GskSlProfile profile,
|
||||
guint version);
|
||||
GskSlEnvironment * gsk_sl_environment_new_similar (GskSlEnvironment *environment,
|
||||
GskSlProfile profile,
|
||||
guint version,
|
||||
GError **error);
|
||||
|
||||
GskSlEnvironment * gsk_sl_environment_ref (GskSlEnvironment *environment);
|
||||
void gsk_sl_environment_unref (GskSlEnvironment *environment);
|
||||
|
||||
GskSlShaderStage gsk_sl_environment_get_stage (GskSlEnvironment *environment);
|
||||
GskSlProfile gsk_sl_environment_get_profile (GskSlEnvironment *environment);
|
||||
guint gsk_sl_environment_get_version (GskSlEnvironment *environment);
|
||||
|
||||
GskSlScope * gsk_sl_environment_create_scope (GskSlEnvironment *environment);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_ENVIRONMENT_PRIVATE_H__ */
|
3955
gsk/gskslexpression.c
Normal file
3955
gsk/gskslexpression.c
Normal file
File diff suppressed because it is too large
Load Diff
60
gsk/gskslexpressionprivate.h
Normal file
60
gsk/gskslexpressionprivate.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_EXPRESSION_PRIVATE_H__
|
||||
#define __GSK_SL_EXPRESSION_PRIVATE_H__
|
||||
|
||||
#include "gsk/gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlExpression * gsk_sl_expression_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream);
|
||||
GskSlExpression * gsk_sl_expression_parse_initializer (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlType *type);
|
||||
GskSlExpression * gsk_sl_expression_parse_constant (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream);
|
||||
gint32 gsk_sl_expression_parse_integral_constant (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
gint32 minimum,
|
||||
guint32 maximum);
|
||||
GskSlExpression * gsk_sl_expression_parse_constructor (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream,
|
||||
GskSlType *type);
|
||||
GskSlExpression * gsk_sl_expression_parse_function_call (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream,
|
||||
GskSlFunctionMatcher *matcher);
|
||||
|
||||
GskSlExpression * gsk_sl_expression_ref (GskSlExpression *expression);
|
||||
void gsk_sl_expression_unref (GskSlExpression *expression);
|
||||
|
||||
void gsk_sl_expression_print (const GskSlExpression *expression,
|
||||
GskSlPrinter *printer);
|
||||
gboolean gsk_sl_expression_is_assignable (const GskSlExpression *expression,
|
||||
GError **error);
|
||||
GskSlType * gsk_sl_expression_get_return_type (const GskSlExpression *expression);
|
||||
GskSlValue * gsk_sl_expression_get_constant (const GskSlExpression *expression);
|
||||
|
||||
guint32 gsk_sl_expression_write_spv (const GskSlExpression *expression,
|
||||
GskSpvWriter *writer,
|
||||
GskSlType *result_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_EXPRESSION_PRIVATE_H__ */
|
921
gsk/gskslfunction.c
Normal file
921
gsk/gskslfunction.c
Normal file
@@ -0,0 +1,921 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslfunctionprivate.h"
|
||||
|
||||
#include "gskslfunctiontypeprivate.h"
|
||||
#include "gskslnativefunctionprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslprinterprivate.h"
|
||||
#include "gskslqualifierprivate.h"
|
||||
#include "gskslscopeprivate.h"
|
||||
#include "gskslstatementprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslvalueprivate.h"
|
||||
#include "gskslvariableprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
typedef struct _GskSlFunctionClass GskSlFunctionClass;
|
||||
|
||||
struct _GskSlFunction
|
||||
{
|
||||
const GskSlFunctionClass *class;
|
||||
|
||||
int ref_count;
|
||||
};
|
||||
|
||||
struct _GskSlFunctionClass {
|
||||
void (* free) (GskSlFunction *function);
|
||||
|
||||
GskSlType * (* get_return_type) (const GskSlFunction *function);
|
||||
const char * (* get_name) (const GskSlFunction *function);
|
||||
gsize (* get_n_arguments) (const GskSlFunction *function);
|
||||
GskSlType * (* get_argument_type) (const GskSlFunction *function,
|
||||
gsize i);
|
||||
GskSlValue * (* get_constant) (const GskSlFunction *function,
|
||||
GskSlValue **values,
|
||||
gsize n_values);
|
||||
void (* print) (const GskSlFunction *function,
|
||||
GskSlPrinter *printer);
|
||||
guint32 (* write_spv) (const GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data);
|
||||
guint32 (* write_call_spv) (GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
guint32 *arguments);
|
||||
};
|
||||
|
||||
static GskSlFunction *
|
||||
gsk_sl_function_alloc (const GskSlFunctionClass *klass,
|
||||
gsize size)
|
||||
{
|
||||
GskSlFunction *function;
|
||||
|
||||
function = g_slice_alloc0 (size);
|
||||
|
||||
function->class = klass;
|
||||
function->ref_count = 1;
|
||||
|
||||
return function;
|
||||
}
|
||||
#define gsk_sl_function_new(_name, _klass) ((_name *) gsk_sl_function_alloc ((_klass), sizeof (_name)))
|
||||
|
||||
/* CONSTRUCTOR */
|
||||
|
||||
typedef struct _GskSlFunctionConstructor GskSlFunctionConstructor;
|
||||
|
||||
struct _GskSlFunctionConstructor {
|
||||
GskSlFunction parent;
|
||||
|
||||
GskSlType *type;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_function_constructor_free (GskSlFunction *function)
|
||||
{
|
||||
GskSlFunctionConstructor *constructor = (GskSlFunctionConstructor *) function;
|
||||
|
||||
gsk_sl_type_unref (constructor->type);
|
||||
|
||||
g_slice_free (GskSlFunctionConstructor, constructor);
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_constructor_get_return_type (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
|
||||
return constructor->type;
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_function_constructor_get_name (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
|
||||
return gsk_sl_type_get_name (constructor->type);
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_sl_function_constructor_get_n_arguments (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
|
||||
return gsk_sl_type_get_n_members (constructor->type);
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_constructor_get_argument_type (const GskSlFunction *function,
|
||||
gsize i)
|
||||
{
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
|
||||
return gsk_sl_type_get_member_type (constructor->type, i);
|
||||
}
|
||||
|
||||
static GskSlValue *
|
||||
gsk_sl_function_constructor_get_constant (const GskSlFunction *function,
|
||||
GskSlValue **values,
|
||||
gsize n_values)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_function_constructor_print (const GskSlFunction *function,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_constructor_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data)
|
||||
{
|
||||
g_assert (initializer == NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_constructor_write_call_spv (GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
guint32 *arguments)
|
||||
{
|
||||
const GskSlFunctionConstructor *constructor = (const GskSlFunctionConstructor *) function;
|
||||
|
||||
return gsk_spv_writer_composite_construct (writer,
|
||||
constructor->type,
|
||||
arguments,
|
||||
gsk_sl_type_get_n_members (constructor->type));
|
||||
}
|
||||
|
||||
static const GskSlFunctionClass GSK_SL_FUNCTION_CONSTRUCTOR = {
|
||||
gsk_sl_function_constructor_free,
|
||||
gsk_sl_function_constructor_get_return_type,
|
||||
gsk_sl_function_constructor_get_name,
|
||||
gsk_sl_function_constructor_get_n_arguments,
|
||||
gsk_sl_function_constructor_get_argument_type,
|
||||
gsk_sl_function_constructor_get_constant,
|
||||
gsk_sl_function_constructor_print,
|
||||
gsk_sl_function_constructor_write_spv,
|
||||
gsk_sl_function_constructor_write_call_spv
|
||||
};
|
||||
|
||||
/* NATIVE */
|
||||
|
||||
typedef struct _GskSlFunctionNative GskSlFunctionNative;
|
||||
|
||||
struct _GskSlFunctionNative {
|
||||
GskSlFunction parent;
|
||||
|
||||
char *name;
|
||||
GskSlFunctionType *type;
|
||||
void (* get_constant) (gpointer *retval, gpointer *arguments, gpointer user_data);
|
||||
guint32 (* write_spv) (GskSpvWriter *writer, guint32 *arguments, gpointer user_data);
|
||||
gpointer user_data;
|
||||
GDestroyNotify destroy;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_function_native_free (GskSlFunction *function)
|
||||
{
|
||||
GskSlFunctionNative *native = (GskSlFunctionNative *) function;
|
||||
|
||||
if (native->destroy)
|
||||
native->destroy (native->user_data);
|
||||
|
||||
gsk_sl_function_type_unref (native->type);
|
||||
g_free (native->name);
|
||||
|
||||
g_slice_free (GskSlFunctionNative, native);
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_native_get_return_type (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionNative *native = (const GskSlFunctionNative *) function;
|
||||
|
||||
return gsk_sl_function_type_get_return_type (native->type);
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_function_native_get_name (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionNative *native = (const GskSlFunctionNative *) function;
|
||||
|
||||
return native->name;
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_sl_function_native_get_n_arguments (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionNative *native = (const GskSlFunctionNative *) function;
|
||||
|
||||
return gsk_sl_function_type_get_n_arguments (native->type);
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_native_get_argument_type (const GskSlFunction *function,
|
||||
gsize i)
|
||||
{
|
||||
const GskSlFunctionNative *native = (const GskSlFunctionNative *) function;
|
||||
|
||||
return gsk_sl_function_type_get_argument_type (native->type, i);
|
||||
}
|
||||
|
||||
static GskSlValue *
|
||||
gsk_sl_function_native_get_constant (const GskSlFunction *function,
|
||||
GskSlValue **values,
|
||||
gsize n_values)
|
||||
{
|
||||
const GskSlFunctionNative *native = (const GskSlFunctionNative *) function;
|
||||
gpointer data[gsk_sl_function_type_get_n_arguments (native->type)];
|
||||
GskSlValue *result;
|
||||
gsize i;
|
||||
|
||||
if (native->get_constant == NULL)
|
||||
return NULL;
|
||||
|
||||
result = gsk_sl_value_new (gsk_sl_function_type_get_return_type (native->type));
|
||||
|
||||
for (i = 0; i < n_values; i++)
|
||||
{
|
||||
data[i] = gsk_sl_value_get_data (values[i]);
|
||||
}
|
||||
|
||||
native->get_constant (gsk_sl_value_get_data (result),
|
||||
data,
|
||||
native->user_data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_function_native_print (const GskSlFunction *function,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_native_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data)
|
||||
{
|
||||
g_assert (initializer == NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_native_write_call_spv (GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
guint32 *arguments)
|
||||
{
|
||||
const GskSlFunctionNative *native = (const GskSlFunctionNative *) function;
|
||||
|
||||
return native->write_spv (writer, arguments, native->user_data);
|
||||
}
|
||||
|
||||
static const GskSlFunctionClass GSK_SL_FUNCTION_NATIVE = {
|
||||
gsk_sl_function_native_free,
|
||||
gsk_sl_function_native_get_return_type,
|
||||
gsk_sl_function_native_get_name,
|
||||
gsk_sl_function_native_get_n_arguments,
|
||||
gsk_sl_function_native_get_argument_type,
|
||||
gsk_sl_function_native_get_constant,
|
||||
gsk_sl_function_native_print,
|
||||
gsk_sl_function_native_write_spv,
|
||||
gsk_sl_function_native_write_call_spv
|
||||
};
|
||||
|
||||
/* DECLARED */
|
||||
|
||||
typedef struct _GskSlFunctionDeclared GskSlFunctionDeclared;
|
||||
|
||||
struct _GskSlFunctionDeclared {
|
||||
GskSlFunction parent;
|
||||
|
||||
GskSlScope *scope;
|
||||
char *name;
|
||||
GskSlFunctionType *function_type;
|
||||
GskSlVariable **arguments;
|
||||
GskSlStatement *statement;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_function_declared_free (GskSlFunction *function)
|
||||
{
|
||||
GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < gsk_sl_function_type_get_n_arguments (declared->function_type); i++)
|
||||
gsk_sl_variable_unref (declared->arguments[i]);
|
||||
g_free (declared->arguments);
|
||||
if (declared->scope)
|
||||
gsk_sl_scope_unref (declared->scope);
|
||||
gsk_sl_function_type_unref (declared->function_type);
|
||||
g_free (declared->name);
|
||||
if (declared->statement)
|
||||
gsk_sl_statement_unref (declared->statement);
|
||||
|
||||
g_slice_free (GskSlFunctionDeclared, declared);
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_declared_get_return_type (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
|
||||
return gsk_sl_function_type_get_return_type (declared->function_type);
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_function_declared_get_name (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
|
||||
return declared->name;
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_sl_function_declared_get_n_arguments (const GskSlFunction *function)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
|
||||
return gsk_sl_function_type_get_n_arguments (declared->function_type);
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_function_declared_get_argument_type (const GskSlFunction *function,
|
||||
gsize i)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
|
||||
return gsk_sl_function_type_get_argument_type (declared->function_type, i);
|
||||
}
|
||||
|
||||
static GskSlValue *
|
||||
gsk_sl_function_declared_get_constant (const GskSlFunction *function,
|
||||
GskSlValue **values,
|
||||
gsize n_values)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_function_declared_print (const GskSlFunction *function,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
const GskSlFunctionDeclared *declared = (const GskSlFunctionDeclared *) function;
|
||||
guint i;
|
||||
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_name (gsk_sl_function_type_get_return_type (declared->function_type)));
|
||||
gsk_sl_printer_newline (printer);
|
||||
|
||||
gsk_sl_printer_append (printer, declared->name);
|
||||
gsk_sl_printer_append (printer, " (");
|
||||
for (i = 0; i < gsk_sl_function_type_get_n_arguments (declared->function_type); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
gsk_sl_printer_append (printer, ", ");
|
||||
gsk_sl_variable_print (declared->arguments[i], printer);
|
||||
}
|
||||
gsk_sl_printer_append (printer, ")");
|
||||
|
||||
if (declared->statement)
|
||||
{
|
||||
gsk_sl_printer_newline (printer);
|
||||
gsk_sl_statement_print (declared->statement, printer);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_printer_append (printer, ";");
|
||||
}
|
||||
|
||||
gsk_sl_printer_newline (printer);
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_declared_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data)
|
||||
{
|
||||
GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
|
||||
guint32 function_type_id, function_id, label_id;
|
||||
GskSlType *return_type;
|
||||
gsize i;
|
||||
|
||||
if (declared->statement == NULL)
|
||||
return 0;
|
||||
|
||||
return_type = gsk_sl_function_type_get_return_type (declared->function_type);
|
||||
|
||||
/* declare type of function */
|
||||
function_type_id = gsk_spv_writer_get_id_for_function_type (writer, declared->function_type);
|
||||
|
||||
function_id = gsk_spv_writer_function (writer, return_type, 0, function_type_id);
|
||||
/* add function header */
|
||||
for (i = 0; i < gsk_sl_function_type_get_n_arguments (declared->function_type); i++)
|
||||
{
|
||||
gsk_spv_writer_get_id_for_variable (writer, declared->arguments[i]);
|
||||
}
|
||||
|
||||
/* add debug info */
|
||||
gsk_spv_writer_name (writer, function_id, declared->name);
|
||||
|
||||
/* add function body */
|
||||
label_id = gsk_spv_writer_make_id (writer);
|
||||
gsk_spv_writer_start_code_block (writer, label_id, 0, 0);
|
||||
gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_DECLARE, label_id);
|
||||
|
||||
if (initializer)
|
||||
initializer (writer, initializer_data);
|
||||
|
||||
if (!gsk_sl_statement_write_spv (declared->statement, writer))
|
||||
gsk_spv_writer_return (writer);
|
||||
|
||||
gsk_spv_writer_function_end (writer);
|
||||
|
||||
return function_id;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_function_declared_write_call_spv (GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
guint32 *arguments)
|
||||
{
|
||||
GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
|
||||
gsize n = gsk_sl_function_type_get_n_arguments (declared->function_type);
|
||||
guint32 real_args[n];
|
||||
guint32 result;
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < gsk_sl_function_type_get_n_arguments (declared->function_type); i++)
|
||||
{
|
||||
if (gsk_sl_function_type_is_argument_const (declared->function_type, i))
|
||||
{
|
||||
real_args[i] = arguments[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
real_args[i] = gsk_spv_writer_variable (writer,
|
||||
GSK_SPV_WRITER_SECTION_DECLARE,
|
||||
gsk_sl_function_type_get_argument_type (declared->function_type, i),
|
||||
GSK_SPV_STORAGE_CLASS_FUNCTION,
|
||||
GSK_SPV_STORAGE_CLASS_FUNCTION,
|
||||
0);
|
||||
if (gsk_sl_function_type_is_argument_in (declared->function_type, i))
|
||||
{
|
||||
gsk_spv_writer_store (writer, real_args[i], arguments[i], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = gsk_spv_writer_function_call (writer,
|
||||
gsk_sl_function_type_get_return_type (declared->function_type),
|
||||
gsk_spv_writer_get_id_for_function (writer, function),
|
||||
real_args,
|
||||
gsk_sl_function_type_get_n_arguments (declared->function_type));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const GskSlFunctionClass GSK_SL_FUNCTION_DECLARED = {
|
||||
gsk_sl_function_declared_free,
|
||||
gsk_sl_function_declared_get_return_type,
|
||||
gsk_sl_function_declared_get_name,
|
||||
gsk_sl_function_declared_get_n_arguments,
|
||||
gsk_sl_function_declared_get_argument_type,
|
||||
gsk_sl_function_declared_get_constant,
|
||||
gsk_sl_function_declared_print,
|
||||
gsk_sl_function_declared_write_spv,
|
||||
gsk_sl_function_declared_write_call_spv
|
||||
};
|
||||
|
||||
/* API */
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_function_new_constructor (GskSlType *type)
|
||||
{
|
||||
if (gsk_sl_type_is_struct (type))
|
||||
{
|
||||
GskSlFunctionConstructor *constructor;
|
||||
|
||||
constructor = gsk_sl_function_new (GskSlFunctionConstructor, &GSK_SL_FUNCTION_CONSTRUCTOR);
|
||||
constructor->type = gsk_sl_type_ref (type);
|
||||
|
||||
return &constructor->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_function_new_native (const char *name,
|
||||
GskSlFunctionType *type,
|
||||
void (* get_constant) (gpointer *retval, gpointer *arguments, gpointer user_data),
|
||||
guint32 (* write_spv) (GskSpvWriter *writer, guint32 *arguments, gpointer user_data),
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
GskSlFunctionNative *function;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
g_return_val_if_fail (write_spv != NULL, NULL);
|
||||
|
||||
function = gsk_sl_function_new (GskSlFunctionNative, &GSK_SL_FUNCTION_NATIVE);
|
||||
|
||||
function->name = g_strdup (name);
|
||||
function->type = gsk_sl_function_type_ref (type);
|
||||
function->get_constant = get_constant;
|
||||
function->write_spv = write_spv;
|
||||
function->user_data = user_data;
|
||||
function->destroy = destroy;
|
||||
|
||||
return &function->parent;
|
||||
}
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_function_new_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlType *return_type,
|
||||
const char *name)
|
||||
{
|
||||
GskSlFunctionDeclared *function;
|
||||
const GskSlToken *token;
|
||||
|
||||
function = gsk_sl_function_new (GskSlFunctionDeclared, &GSK_SL_FUNCTION_DECLARED);
|
||||
function->function_type = gsk_sl_function_type_new (return_type);
|
||||
function->name = g_strdup (name);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected an openening \"(\"");
|
||||
return (GskSlFunction *) function;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlStatement *) function);
|
||||
|
||||
function->scope = gsk_sl_scope_new (scope, return_type);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
GPtrArray *arguments = g_ptr_array_new ();
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
GskSlQualifier qualifier;
|
||||
GskSlType *type;
|
||||
GskSlVariable *variable;
|
||||
|
||||
gsk_sl_qualifier_parse (&qualifier, scope, preproc, GSK_SL_QUALIFIER_PARAMETER);
|
||||
|
||||
type = gsk_sl_type_new_parse (scope, preproc);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = g_strdup (token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlStatement *) function);
|
||||
|
||||
type = gsk_sl_type_parse_array (type, scope, preproc);
|
||||
|
||||
variable = gsk_sl_variable_new (name, type, &qualifier, NULL);
|
||||
function->function_type = gsk_sl_function_type_add_argument (function->function_type,
|
||||
qualifier.storage,
|
||||
type);
|
||||
g_ptr_array_add (arguments, variable);
|
||||
|
||||
gsk_sl_scope_try_add_variable (function->scope, preproc, variable);
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected an identifier as the variable name.");
|
||||
}
|
||||
|
||||
gsk_sl_type_unref (type);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
|
||||
break;
|
||||
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlStatement *) function);
|
||||
}
|
||||
|
||||
g_assert (gsk_sl_function_type_get_n_arguments (function->function_type) == arguments->len);
|
||||
function->arguments = (GskSlVariable **) g_ptr_array_free (arguments, FALSE);
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected a closing \")\"");
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN);
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlStatement *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, (GskSlStatement *) function);
|
||||
return (GskSlFunction *) function;
|
||||
}
|
||||
|
||||
function->statement = gsk_sl_statement_parse_compound (function->scope, preproc, FALSE);
|
||||
|
||||
if (!gsk_sl_type_is_void (return_type) &&
|
||||
gsk_sl_statement_get_jump (function->statement) < GSK_SL_JUMP_RETURN)
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Function does not return a value.");
|
||||
}
|
||||
|
||||
return (GskSlFunction *) function;
|
||||
}
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_function_ref (GskSlFunction *function)
|
||||
{
|
||||
g_return_val_if_fail (function != NULL, NULL);
|
||||
|
||||
function->ref_count += 1;
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_unref (GskSlFunction *function)
|
||||
{
|
||||
if (function == NULL)
|
||||
return;
|
||||
|
||||
function->ref_count -= 1;
|
||||
if (function->ref_count > 0)
|
||||
return;
|
||||
|
||||
function->class->free (function);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_function_get_return_type (const GskSlFunction *function)
|
||||
{
|
||||
return function->class->get_return_type (function);
|
||||
}
|
||||
|
||||
const char *
|
||||
gsk_sl_function_get_name (const GskSlFunction *function)
|
||||
{
|
||||
return function->class->get_name (function);
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_sl_function_get_n_arguments (const GskSlFunction *function)
|
||||
{
|
||||
return function->class->get_n_arguments (function);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_function_get_argument_type (const GskSlFunction *function,
|
||||
gsize i)
|
||||
{
|
||||
return function->class->get_argument_type (function, i);
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_function_get_constant (const GskSlFunction *function,
|
||||
GskSlValue **values,
|
||||
gsize n_values)
|
||||
{
|
||||
return function->class->get_constant (function, values, n_values);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_print (const GskSlFunction *function,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
function->class->print (function, printer);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_function_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data)
|
||||
{
|
||||
return function->class->write_spv (function, writer, initializer, initializer_data);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_function_write_call_spv (GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
guint32 *arguments)
|
||||
{
|
||||
return function->class->write_call_spv (function, writer, arguments);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_matcher_init (GskSlFunctionMatcher *matcher,
|
||||
GList *list)
|
||||
{
|
||||
matcher->best_matches = list;
|
||||
matcher->matches = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_matcher_finish (GskSlFunctionMatcher *matcher)
|
||||
{
|
||||
g_list_free (matcher->best_matches);
|
||||
g_list_free (matcher->matches);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_function_matcher_has_matches (GskSlFunctionMatcher *matcher)
|
||||
{
|
||||
return matcher->best_matches || matcher->matches;
|
||||
}
|
||||
|
||||
GskSlFunction *
|
||||
gsk_sl_function_matcher_get_match (GskSlFunctionMatcher *matcher)
|
||||
{
|
||||
if (matcher->best_matches == NULL)
|
||||
return NULL;
|
||||
|
||||
if (matcher->best_matches->next != NULL)
|
||||
return NULL;
|
||||
|
||||
return matcher->best_matches->data;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_matcher_match_n_arguments (GskSlFunctionMatcher *matcher,
|
||||
gsize n_arguments)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = matcher->best_matches; l; l = l->next)
|
||||
{
|
||||
if (gsk_sl_function_get_n_arguments (l->data) != n_arguments)
|
||||
matcher->best_matches = g_list_delete_link (matcher->best_matches, l);
|
||||
}
|
||||
for (l = matcher->matches; l; l = l->next)
|
||||
{
|
||||
if (gsk_sl_function_get_n_arguments (l->data) != n_arguments)
|
||||
matcher->matches = g_list_delete_link (matcher->matches, l);
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
MATCH_NONE,
|
||||
MATCH_CONVERT_TO_DOUBLE,
|
||||
MATCH_CONVERT,
|
||||
MATCH_EXACT
|
||||
} GskSlFunctionMatch;
|
||||
|
||||
static GskSlFunctionMatch
|
||||
gsk_sl_function_matcher_match_types (const GskSlType *function_type,
|
||||
const GskSlType *argument_type)
|
||||
{
|
||||
if (!gsk_sl_type_can_convert (function_type, argument_type))
|
||||
return MATCH_NONE;
|
||||
|
||||
if (gsk_sl_type_equal (function_type, argument_type))
|
||||
return MATCH_EXACT;
|
||||
|
||||
if (gsk_sl_type_get_scalar_type (function_type))
|
||||
return MATCH_CONVERT_TO_DOUBLE;
|
||||
|
||||
return MATCH_CONVERT;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_matcher_match_argument (GskSlFunctionMatcher *matcher,
|
||||
gsize n,
|
||||
const GskSlType *argument_type)
|
||||
{
|
||||
GList *best_matches = NULL, *matches = NULL, *l;
|
||||
GskSlFunctionMatch best = MATCH_NONE, function_match;
|
||||
|
||||
for (l = matcher->best_matches; l; l = l->next)
|
||||
{
|
||||
GskSlType *function_type;
|
||||
GskSlFunctionMatch function_match;
|
||||
|
||||
if (gsk_sl_function_get_n_arguments (l->data) <= n)
|
||||
continue;
|
||||
|
||||
function_type = gsk_sl_function_get_argument_type (l->data, n);
|
||||
function_match = gsk_sl_function_matcher_match_types (function_type, argument_type);
|
||||
if (function_match == MATCH_NONE)
|
||||
continue;
|
||||
|
||||
if (function_match == best)
|
||||
{
|
||||
best_matches = g_list_prepend (best_matches, l->data);
|
||||
best = function_match;
|
||||
}
|
||||
else if (function_match > best)
|
||||
{
|
||||
matches = g_list_concat (matches, best_matches);
|
||||
best_matches = g_list_prepend (NULL, l->data);
|
||||
best = function_match;
|
||||
}
|
||||
else
|
||||
{
|
||||
matches = g_list_prepend (matches, l->data);
|
||||
}
|
||||
}
|
||||
|
||||
for (l = matcher->matches; l; l = l->next)
|
||||
{
|
||||
GskSlType *function_type;
|
||||
|
||||
if (gsk_sl_function_get_n_arguments (l->data) <= n)
|
||||
continue;
|
||||
|
||||
function_type = gsk_sl_function_get_argument_type (l->data, n);
|
||||
function_match = gsk_sl_function_matcher_match_types (function_type, argument_type);
|
||||
if (function_match == MATCH_NONE)
|
||||
continue;
|
||||
|
||||
if (function_match > best)
|
||||
{
|
||||
matches = g_list_concat (matches, best_matches);
|
||||
best_matches = NULL;
|
||||
best = function_match;
|
||||
}
|
||||
matches = g_list_prepend (matches, l->data);
|
||||
}
|
||||
|
||||
g_list_free (matcher->best_matches);
|
||||
g_list_free (matcher->matches);
|
||||
matcher->best_matches = best_matches;
|
||||
matcher->matches = matches;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_matcher_match_function (GskSlFunctionMatcher *matcher,
|
||||
const GskSlFunction *function)
|
||||
{
|
||||
GList *l;
|
||||
gsize i, n;
|
||||
|
||||
n = gsk_sl_function_get_n_arguments (function);
|
||||
|
||||
for (l = matcher->best_matches; l; l = l->next)
|
||||
{
|
||||
GskSlFunction *f = l->data;
|
||||
|
||||
if (gsk_sl_function_get_n_arguments (f) != n)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (!gsk_sl_type_equal (gsk_sl_function_get_argument_type (f, i),
|
||||
gsk_sl_function_get_argument_type (function, i)))
|
||||
break;
|
||||
}
|
||||
if (i == n)
|
||||
{
|
||||
g_list_free (matcher->best_matches);
|
||||
g_list_free (matcher->matches);
|
||||
matcher->best_matches = g_list_prepend (NULL, f);
|
||||
matcher->matches = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (matcher->best_matches);
|
||||
g_list_free (matcher->matches);
|
||||
matcher->best_matches = NULL;
|
||||
matcher->matches = NULL;
|
||||
}
|
85
gsk/gskslfunctionprivate.h
Normal file
85
gsk/gskslfunctionprivate.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_FUNCTION_PRIVATE_H__
|
||||
#define __GSK_SL_FUNCTION_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlFunction * gsk_sl_function_new_constructor (GskSlType *type);
|
||||
GskSlFunction * gsk_sl_function_new_native (const char *name,
|
||||
GskSlFunctionType *type,
|
||||
void (* get_constant) (gpointer *retval, gpointer *arguments, gpointer user_data),
|
||||
guint32 (* write_spv) (GskSpvWriter *writer, guint32 *arguments, gpointer user_data),
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy);
|
||||
GskSlFunction * gsk_sl_function_new_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *stream,
|
||||
GskSlType *return_type,
|
||||
const char *name);
|
||||
|
||||
GskSlFunction * gsk_sl_function_ref (GskSlFunction *function);
|
||||
void gsk_sl_function_unref (GskSlFunction *function);
|
||||
|
||||
void gsk_sl_function_print (const GskSlFunction *function,
|
||||
GskSlPrinter *printer);
|
||||
|
||||
const char * gsk_sl_function_get_name (const GskSlFunction *function);
|
||||
GskSlType * gsk_sl_function_get_return_type (const GskSlFunction *function);
|
||||
gsize gsk_sl_function_get_n_arguments (const GskSlFunction *function);
|
||||
GskSlType * gsk_sl_function_get_argument_type (const GskSlFunction *function,
|
||||
gsize i);
|
||||
GskSlValue * gsk_sl_function_get_constant (const GskSlFunction *function,
|
||||
GskSlValue **values,
|
||||
gsize n_values);
|
||||
guint32 gsk_sl_function_write_spv (const GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data);
|
||||
guint32 gsk_sl_function_write_call_spv (GskSlFunction *function,
|
||||
GskSpvWriter *writer,
|
||||
guint32 *arguments);
|
||||
|
||||
struct _GskSlFunctionMatcher
|
||||
{
|
||||
GList *best_matches;
|
||||
GList *matches;
|
||||
};
|
||||
|
||||
void gsk_sl_function_matcher_init (GskSlFunctionMatcher *matcher,
|
||||
GList *list);
|
||||
void gsk_sl_function_matcher_finish (GskSlFunctionMatcher *matcher);
|
||||
|
||||
gboolean gsk_sl_function_matcher_has_matches (GskSlFunctionMatcher *matcher);
|
||||
GskSlFunction * gsk_sl_function_matcher_get_match (GskSlFunctionMatcher *matcher);
|
||||
|
||||
void gsk_sl_function_matcher_match_n_arguments (GskSlFunctionMatcher *matcher,
|
||||
gsize n_arguments);
|
||||
void gsk_sl_function_matcher_match_argument (GskSlFunctionMatcher *matcher,
|
||||
gsize n,
|
||||
const GskSlType *argument_type);
|
||||
void gsk_sl_function_matcher_match_function (GskSlFunctionMatcher *matcher,
|
||||
const GskSlFunction *function);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_FUNCTION_PRIVATE_H__ */
|
242
gsk/gskslfunctiontype.c
Normal file
242
gsk/gskslfunctiontype.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslfunctiontypeprivate.h"
|
||||
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
typedef struct _GskSlArgument GskSlArgument;
|
||||
|
||||
struct _GskSlArgument
|
||||
{
|
||||
GskSlStorage storage;
|
||||
GskSlType *type;
|
||||
};
|
||||
|
||||
struct _GskSlFunctionType
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlType *return_type;
|
||||
gsize n_arguments;
|
||||
GskSlArgument arguments[0];
|
||||
};
|
||||
|
||||
static GskSlFunctionType *
|
||||
gsk_sl_function_type_alloc (gsize n_arguments)
|
||||
{
|
||||
GskSlFunctionType *function_type;
|
||||
|
||||
function_type = g_slice_alloc0 (sizeof (GskSlFunctionType) + n_arguments * sizeof (GskSlArgument));
|
||||
|
||||
function_type->ref_count = 1;
|
||||
function_type->n_arguments = n_arguments;
|
||||
|
||||
return function_type;
|
||||
}
|
||||
|
||||
GskSlFunctionType *
|
||||
gsk_sl_function_type_new (GskSlType *return_type)
|
||||
{
|
||||
GskSlFunctionType *function_type;
|
||||
|
||||
function_type = gsk_sl_function_type_alloc (0);
|
||||
function_type->return_type = gsk_sl_type_ref (return_type);
|
||||
|
||||
return function_type;
|
||||
}
|
||||
|
||||
GskSlFunctionType *
|
||||
gsk_sl_function_type_add_argument (GskSlFunctionType *function_type,
|
||||
GskSlStorage argument_storage,
|
||||
GskSlType *argument_type)
|
||||
{
|
||||
GskSlFunctionType *result_type;
|
||||
gsize i;
|
||||
|
||||
g_assert (argument_storage >= GSK_SL_STORAGE_PARAMETER_IN && argument_storage <= GSK_SL_STORAGE_PARAMETER_CONST);
|
||||
|
||||
result_type = gsk_sl_function_type_alloc (function_type->n_arguments + 1);
|
||||
result_type->return_type = gsk_sl_type_ref (function_type->return_type);
|
||||
|
||||
for (i = 0; i < function_type->n_arguments; i++)
|
||||
{
|
||||
result_type->arguments[i].type = gsk_sl_type_ref (function_type->arguments[i].type);
|
||||
result_type->arguments[i].storage = function_type->arguments[i].storage;
|
||||
}
|
||||
|
||||
result_type->arguments[i].type = gsk_sl_type_ref (argument_type);
|
||||
result_type->arguments[i].storage = argument_storage;
|
||||
|
||||
gsk_sl_function_type_unref (function_type);
|
||||
|
||||
return result_type;
|
||||
}
|
||||
|
||||
GskSlFunctionType *
|
||||
gsk_sl_function_type_ref (GskSlFunctionType *function_type)
|
||||
{
|
||||
g_return_val_if_fail (function_type != NULL, NULL);
|
||||
|
||||
function_type->ref_count += 1;
|
||||
|
||||
return function_type;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_function_type_unref (GskSlFunctionType *function_type)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
if (function_type == NULL)
|
||||
return;
|
||||
|
||||
function_type->ref_count -= 1;
|
||||
if (function_type->ref_count > 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < function_type->n_arguments; i++)
|
||||
{
|
||||
gsk_sl_type_unref (function_type->arguments[i].type);
|
||||
}
|
||||
gsk_sl_type_unref (function_type->return_type);
|
||||
|
||||
g_slice_free1 (sizeof (GskSlFunctionType) + function_type->n_arguments * sizeof (GskSlArgument), function_type);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_function_type_get_return_type (const GskSlFunctionType *function_type)
|
||||
{
|
||||
return function_type->return_type;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_sl_function_type_get_n_arguments (const GskSlFunctionType *function_type)
|
||||
{
|
||||
return function_type->n_arguments;
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_function_type_get_argument_type (const GskSlFunctionType *function_type,
|
||||
gsize i)
|
||||
{
|
||||
return function_type->arguments[i].type;
|
||||
}
|
||||
|
||||
GskSlStorage
|
||||
gsk_sl_function_type_get_argument_storage (const GskSlFunctionType *function_type,
|
||||
gsize i)
|
||||
{
|
||||
return function_type->arguments[i].storage;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_function_type_is_argument_const (const GskSlFunctionType *function_type,
|
||||
gsize i)
|
||||
{
|
||||
return function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_CONST;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_function_type_is_argument_in (const GskSlFunctionType *function_type,
|
||||
gsize i)
|
||||
{
|
||||
return function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_IN
|
||||
|| function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_INOUT;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_function_type_is_argument_out (const GskSlFunctionType *function_type,
|
||||
gsize i)
|
||||
{
|
||||
return function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_OUT
|
||||
|| function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_INOUT;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_function_type_write_spv (const GskSlFunctionType *function_type,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
guint32 argument_types[function_type->n_arguments], return_type_id;
|
||||
gsize i;
|
||||
|
||||
return_type_id = gsk_spv_writer_get_id_for_type (writer, function_type->return_type);
|
||||
for (i = 0; i < function_type->n_arguments; i++)
|
||||
{
|
||||
if (function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_CONST)
|
||||
{
|
||||
argument_types[i] = gsk_spv_writer_get_id_for_type (writer,
|
||||
function_type->arguments[i].type);
|
||||
}
|
||||
else
|
||||
{
|
||||
argument_types[i] = gsk_spv_writer_get_id_for_pointer_type (writer,
|
||||
function_type->arguments[i].type,
|
||||
GSK_SPV_STORAGE_CLASS_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
return gsk_spv_writer_type_function (writer, return_type_id, argument_types, function_type->n_arguments);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_function_type_equal (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const GskSlFunctionType *function_type_a = a;
|
||||
const GskSlFunctionType *function_type_b = b;
|
||||
gsize i;
|
||||
|
||||
if (function_type_a->n_arguments != function_type_b->n_arguments)
|
||||
return FALSE;
|
||||
|
||||
if (!gsk_sl_type_equal (function_type_a->return_type, function_type_b->return_type))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < function_type_a->n_arguments; i++)
|
||||
{
|
||||
if (function_type_a->arguments[i].storage != function_type_b->arguments[i].storage ||
|
||||
!gsk_sl_type_equal (function_type_a->arguments[i].type, function_type_b->arguments[i].type))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_function_type_hash (gconstpointer value)
|
||||
{
|
||||
const GskSlFunctionType *function_type = value;
|
||||
guint hash;
|
||||
gsize i;
|
||||
|
||||
hash = gsk_sl_type_hash (function_type->return_type);
|
||||
|
||||
for (i = 0; i < function_type->n_arguments; i++)
|
||||
{
|
||||
hash <<= 5;
|
||||
hash ^= gsk_sl_type_hash (function_type->arguments[i].type);
|
||||
hash ^= function_type->arguments[i].storage;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
58
gsk/gskslfunctiontypeprivate.h
Normal file
58
gsk/gskslfunctiontypeprivate.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_FUNCTION_TYPE_PRIVATE_H__
|
||||
#define __GSK_SL_FUNCTION_TYPE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlFunctionType * gsk_sl_function_type_new (GskSlType *return_type);
|
||||
GskSlFunctionType * gsk_sl_function_type_add_argument (GskSlFunctionType *function_type,
|
||||
GskSlStorage argument_storage,
|
||||
GskSlType *argument_type);
|
||||
|
||||
GskSlFunctionType * gsk_sl_function_type_ref (GskSlFunctionType *function_type);
|
||||
void gsk_sl_function_type_unref (GskSlFunctionType *function_type);
|
||||
|
||||
GskSlType * gsk_sl_function_type_get_return_type (const GskSlFunctionType*function_type);
|
||||
gsize gsk_sl_function_type_get_n_arguments (const GskSlFunctionType*function_type);
|
||||
GskSlType * gsk_sl_function_type_get_argument_type (const GskSlFunctionType*function_type,
|
||||
gsize i);
|
||||
GskSlStorage gsk_sl_function_type_get_argument_storage (const GskSlFunctionType*function_type,
|
||||
gsize i);
|
||||
gboolean gsk_sl_function_type_is_argument_const (const GskSlFunctionType*function_type,
|
||||
gsize i);
|
||||
gboolean gsk_sl_function_type_is_argument_in (const GskSlFunctionType*function_type,
|
||||
gsize i);
|
||||
gboolean gsk_sl_function_type_is_argument_out (const GskSlFunctionType*function_type,
|
||||
gsize i);
|
||||
|
||||
guint32 gsk_sl_function_type_write_spv (const GskSlFunctionType*function_type,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
gboolean gsk_sl_function_type_equal (gconstpointer a,
|
||||
gconstpointer b);
|
||||
guint gsk_sl_function_type_hash (gconstpointer value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_FUNCTION_TYPE_PRIVATE_H__ */
|
268
gsk/gskslimagetype.c
Normal file
268
gsk/gskslimagetype.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslimagetypeprivate.h"
|
||||
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_supports_projection (const GskSlImageType *type,
|
||||
gboolean extra_dim)
|
||||
{
|
||||
if (type->arrayed)
|
||||
return FALSE;
|
||||
|
||||
if (type->multisampled)
|
||||
return FALSE;
|
||||
|
||||
if (extra_dim && type->shadow)
|
||||
return FALSE;
|
||||
|
||||
switch (type->dim)
|
||||
{
|
||||
case GSK_SPV_DIM_1_D:
|
||||
case GSK_SPV_DIM_2_D:
|
||||
case GSK_SPV_DIM_RECT:
|
||||
return TRUE;
|
||||
case GSK_SPV_DIM_3_D:
|
||||
return !extra_dim;
|
||||
case GSK_SPV_DIM_CUBE:
|
||||
case GSK_SPV_DIM_BUFFER:
|
||||
case GSK_SPV_DIM_SUBPASS_DATA:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_supports_lod (const GskSlImageType *type)
|
||||
{
|
||||
if (type->multisampled)
|
||||
return FALSE;
|
||||
|
||||
switch (type->dim)
|
||||
{
|
||||
case GSK_SPV_DIM_1_D:
|
||||
return TRUE;
|
||||
case GSK_SPV_DIM_2_D:
|
||||
case GSK_SPV_DIM_3_D:
|
||||
return !type->arrayed || !type->shadow;
|
||||
case GSK_SPV_DIM_CUBE:
|
||||
return !type->shadow;
|
||||
case GSK_SPV_DIM_RECT:
|
||||
case GSK_SPV_DIM_BUFFER:
|
||||
case GSK_SPV_DIM_SUBPASS_DATA:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_supports_bias (const GskSlImageType *type)
|
||||
{
|
||||
if (type->multisampled)
|
||||
return FALSE;
|
||||
|
||||
switch (type->dim)
|
||||
{
|
||||
case GSK_SPV_DIM_1_D:
|
||||
case GSK_SPV_DIM_3_D:
|
||||
case GSK_SPV_DIM_CUBE:
|
||||
return TRUE;
|
||||
case GSK_SPV_DIM_2_D:
|
||||
return !type->arrayed || !type->shadow;
|
||||
case GSK_SPV_DIM_RECT:
|
||||
case GSK_SPV_DIM_BUFFER:
|
||||
case GSK_SPV_DIM_SUBPASS_DATA:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_supports_offset (const GskSlImageType *type)
|
||||
{
|
||||
if (type->multisampled)
|
||||
return FALSE;
|
||||
|
||||
switch (type->dim)
|
||||
{
|
||||
case GSK_SPV_DIM_1_D:
|
||||
case GSK_SPV_DIM_2_D:
|
||||
case GSK_SPV_DIM_3_D:
|
||||
case GSK_SPV_DIM_RECT:
|
||||
return TRUE;
|
||||
case GSK_SPV_DIM_CUBE:
|
||||
case GSK_SPV_DIM_BUFFER:
|
||||
case GSK_SPV_DIM_SUBPASS_DATA:
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_supports_gradient (const GskSlImageType *type)
|
||||
{
|
||||
if (type->multisampled)
|
||||
return FALSE;
|
||||
|
||||
if (type->dim == GSK_SPV_DIM_BUFFER)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_supports_texel_fetch (const GskSlImageType *type)
|
||||
{
|
||||
if (type->shadow)
|
||||
return FALSE;
|
||||
|
||||
if (type->dim == GSK_SPV_DIM_CUBE)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_supports_texture (const GskSlImageType *type)
|
||||
{
|
||||
if (type->multisampled)
|
||||
return FALSE;
|
||||
|
||||
if (type->dim == GSK_SPV_DIM_BUFFER)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_needs_lod_argument (const GskSlImageType *type,
|
||||
gboolean texel_fetch)
|
||||
{
|
||||
if (type->multisampled)
|
||||
return TRUE;
|
||||
|
||||
return type->dim != GSK_SPV_DIM_RECT
|
||||
&& type->dim != GSK_SPV_DIM_BUFFER;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_image_type_get_dimensions (const GskSlImageType *type)
|
||||
{
|
||||
switch (type->dim)
|
||||
{
|
||||
case GSK_SPV_DIM_1_D:
|
||||
case GSK_SPV_DIM_BUFFER:
|
||||
return 1;
|
||||
|
||||
case GSK_SPV_DIM_2_D:
|
||||
case GSK_SPV_DIM_RECT:
|
||||
case GSK_SPV_DIM_SUBPASS_DATA:
|
||||
return 2;
|
||||
|
||||
case GSK_SPV_DIM_3_D:
|
||||
case GSK_SPV_DIM_CUBE:
|
||||
return 3;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_image_type_get_lookup_dimensions (const GskSlImageType *type,
|
||||
gboolean projection)
|
||||
{
|
||||
guint result = gsk_sl_image_type_get_dimensions (type);
|
||||
|
||||
if (type->arrayed)
|
||||
result++;
|
||||
|
||||
if (type->shadow)
|
||||
{
|
||||
/* because GLSL is GLSL */
|
||||
result = MAX (result, 2);
|
||||
result++;
|
||||
}
|
||||
|
||||
if (projection)
|
||||
result++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_image_type_get_pixel_type (const GskSlImageType *type)
|
||||
{
|
||||
if (type->shadow)
|
||||
return gsk_sl_type_get_scalar (type->sampled_type);
|
||||
else
|
||||
return gsk_sl_type_get_vector (type->sampled_type, 4);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_image_type_write_spv (const GskSlImageType *type,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
guint32 sampled_type_id;
|
||||
|
||||
sampled_type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (type->sampled_type));
|
||||
return gsk_spv_writer_type_image (writer,
|
||||
sampled_type_id,
|
||||
type->dim,
|
||||
type->shadow,
|
||||
type->arrayed,
|
||||
type->multisampled,
|
||||
2 - type->sampler,
|
||||
GSK_SPV_IMAGE_FORMAT_UNKNOWN,
|
||||
-1);
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_image_type_hash (gconstpointer type)
|
||||
{
|
||||
const GskSlImageType *image = type;
|
||||
|
||||
return image->sampled_type
|
||||
| (image->dim << 8)
|
||||
| (image->shadow << 16)
|
||||
| (image->arrayed << 17)
|
||||
| (image->multisampled << 18)
|
||||
| (image->sampler << 19);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_image_type_equal (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const GskSlImageType *ia = a;
|
||||
const GskSlImageType *ib = b;
|
||||
|
||||
return ia->sampled_type == ib->sampled_type
|
||||
&& ia->dim == ib->dim
|
||||
&& ia->shadow == ib->shadow
|
||||
&& ia->arrayed == ib->arrayed
|
||||
&& ia->multisampled == ib->multisampled
|
||||
&& ia->sampler == ib->sampler;
|
||||
}
|
||||
|
65
gsk/gskslimagetypeprivate.h
Normal file
65
gsk/gskslimagetypeprivate.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_IMAGE_TYPE_PRIVATE_H__
|
||||
#define __GSK_SL_IMAGE_TYPE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
#include "gskspvenumsprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GskSlImageType
|
||||
{
|
||||
GskSlScalarType sampled_type;
|
||||
GskSpvDim dim;
|
||||
guint shadow :1;
|
||||
guint arrayed :1;
|
||||
guint multisampled :1;
|
||||
guint sampler :1;
|
||||
};
|
||||
|
||||
gboolean gsk_sl_image_type_supports_projection (const GskSlImageType *type,
|
||||
gboolean extra_dim);
|
||||
gboolean gsk_sl_image_type_supports_lod (const GskSlImageType *type);
|
||||
gboolean gsk_sl_image_type_supports_bias (const GskSlImageType *type);
|
||||
gboolean gsk_sl_image_type_supports_offset (const GskSlImageType *type);
|
||||
gboolean gsk_sl_image_type_supports_gradient (const GskSlImageType *type);
|
||||
gboolean gsk_sl_image_type_supports_texture (const GskSlImageType *type);
|
||||
gboolean gsk_sl_image_type_supports_texel_fetch (const GskSlImageType *type);
|
||||
gboolean gsk_sl_image_type_needs_lod_argument (const GskSlImageType *type,
|
||||
gboolean texel_fetch);
|
||||
|
||||
guint gsk_sl_image_type_get_dimensions (const GskSlImageType *type);
|
||||
guint gsk_sl_image_type_get_lookup_dimensions (const GskSlImageType *type,
|
||||
gboolean projection);
|
||||
|
||||
GskSlType * gsk_sl_image_type_get_pixel_type (const GskSlImageType *type);
|
||||
|
||||
guint32 gsk_sl_image_type_write_spv (const GskSlImageType *type,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
guint gsk_sl_image_type_hash (gconstpointer type);
|
||||
gboolean gsk_sl_image_type_equal (gconstpointer a,
|
||||
gconstpointer b);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_IMAGE_TYPE_PRIVATE_H__ */
|
1830
gsk/gskslnativefunction.c
Normal file
1830
gsk/gskslnativefunction.c
Normal file
File diff suppressed because it is too large
Load Diff
33
gsk/gskslnativefunctionprivate.h
Normal file
33
gsk/gskslnativefunctionprivate.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_NATIVE_FUNCTION_PRIVATE_H__
|
||||
#define __GSK_SL_NATIVE_FUNCTION_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_sl_native_functions_add (GskSlScope *scope,
|
||||
GskSlEnvironment *environment);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_NATIVE_FUNCTION_PRIVATE_H__ */
|
140
gsk/gskslnativevariable.c
Normal file
140
gsk/gskslnativevariable.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslnativevariableprivate.h"
|
||||
|
||||
#include "gskslenvironmentprivate.h"
|
||||
#include "gskslqualifierprivate.h"
|
||||
#include "gskslscopeprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslvariableprivate.h"
|
||||
|
||||
typedef struct _NativeVariable NativeVariable;
|
||||
struct _NativeVariable {
|
||||
const char *name;
|
||||
GskSlType *type;
|
||||
GskSpvBuiltIn builtin;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_native_variable_add_block (GskSlScope *scope,
|
||||
const char *block_name,
|
||||
const char *block_instance_name,
|
||||
GskSlStorage storage,
|
||||
const NativeVariable *variables,
|
||||
gsize n_variables)
|
||||
{
|
||||
GskSlQualifier qualifier;
|
||||
GskSlVariable *variable;
|
||||
GskSlTypeBuilder *builder;
|
||||
GskSlType *type;
|
||||
gsize i;
|
||||
|
||||
gsk_sl_qualifier_init (&qualifier);
|
||||
qualifier.storage = storage;
|
||||
|
||||
builder = gsk_sl_type_builder_new_block (block_name);
|
||||
for (i = 0; i < n_variables; i++)
|
||||
{
|
||||
gsk_sl_type_builder_add_builtin_member (builder,
|
||||
variables[i].type,
|
||||
variables[i].name,
|
||||
variables[i].builtin);
|
||||
}
|
||||
type = gsk_sl_type_builder_free (builder);
|
||||
|
||||
variable = gsk_sl_variable_new (block_instance_name,
|
||||
type,
|
||||
&qualifier,
|
||||
NULL);
|
||||
if (block_instance_name)
|
||||
{
|
||||
gsk_sl_scope_add_variable (scope, variable);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < n_variables; i++)
|
||||
{
|
||||
GskSlVariable *sub;
|
||||
|
||||
sub = gsk_sl_variable_new_block_member (variable, i);
|
||||
gsk_sl_scope_add_variable (scope, sub);
|
||||
gsk_sl_variable_unref (sub);
|
||||
}
|
||||
}
|
||||
gsk_sl_variable_unref (variable);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_native_variable_add (GskSlScope *scope,
|
||||
const char *name,
|
||||
GskSlStorage storage,
|
||||
GskSlType *type,
|
||||
GskSpvBuiltIn builtin)
|
||||
{
|
||||
GskSlQualifier qualifier;
|
||||
GskSlVariable *variable;
|
||||
|
||||
gsk_sl_qualifier_init (&qualifier);
|
||||
qualifier.storage = storage;
|
||||
|
||||
variable = gsk_sl_variable_new_builtin (name,
|
||||
type,
|
||||
&qualifier,
|
||||
builtin);
|
||||
gsk_sl_scope_add_variable (scope, variable);
|
||||
gsk_sl_variable_unref (variable);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_native_variable_add_simple (GskSlScope *scope,
|
||||
const char *name,
|
||||
GskSlScalarType scalar,
|
||||
GskSpvBuiltIn builtin)
|
||||
{
|
||||
gsk_sl_native_variable_add (scope, name, GSK_SL_STORAGE_GLOBAL_IN, gsk_sl_type_get_scalar (scalar), builtin);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_native_variables_add (GskSlScope *scope,
|
||||
GskSlEnvironment *environment)
|
||||
{
|
||||
if (gsk_sl_environment_get_stage (environment) == GSK_SL_SHADER_VERTEX)
|
||||
{
|
||||
gsk_sl_native_variable_add_simple (scope, "gl_VertexIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_VERTEX_INDEX);
|
||||
gsk_sl_native_variable_add_simple (scope, "gl_InstanceIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_INSTANCE_INDEX);
|
||||
if (gsk_sl_environment_get_version (environment) >= 150)
|
||||
{
|
||||
gsk_sl_native_variable_add_block (scope,
|
||||
"gl_PerVertex", NULL,
|
||||
GSK_SL_STORAGE_GLOBAL_OUT,
|
||||
(NativeVariable[2]) {
|
||||
{ "gl_Position", gsk_sl_type_get_vector (GSK_SL_FLOAT, 4), GSK_SPV_BUILT_IN_POSITION },
|
||||
{ "gl_PointSize", gsk_sl_type_get_scalar (GSK_SL_FLOAT), GSK_SPV_BUILT_IN_POINT_SIZE }
|
||||
}, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_native_variable_add (scope, "gl_Position", GSK_SL_STORAGE_GLOBAL_OUT, gsk_sl_type_get_vector (GSK_SL_FLOAT, 4), GSK_SPV_BUILT_IN_POSITION);
|
||||
gsk_sl_native_variable_add (scope, "gl_PointSize", GSK_SL_STORAGE_GLOBAL_OUT, gsk_sl_type_get_scalar (GSK_SL_FLOAT), GSK_SPV_BUILT_IN_POINT_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
gsk/gskslnativevariableprivate.h
Normal file
31
gsk/gskslnativevariableprivate.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_NATIVE_VARIABLE_PRIVATE_H__
|
||||
#define __GSK_SL_NATIVE_VARIABLE_PRIVATE_H__
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_sl_native_variables_add (GskSlScope *scope,
|
||||
GskSlEnvironment *environment);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_NATIVE_VARIABLE_PRIVATE_H__ */
|
948
gsk/gskslpreprocessor.c
Normal file
948
gsk/gskslpreprocessor.c
Normal file
@@ -0,0 +1,948 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
|
||||
#include "gskcodesource.h"
|
||||
#include "gskslcompilerprivate.h"
|
||||
#include "gsksldefineprivate.h"
|
||||
#include "gskslenvironmentprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
|
||||
typedef struct _GskSlPpToken GskSlPpToken;
|
||||
|
||||
struct _GskSlPpToken {
|
||||
GskCodeLocation location;
|
||||
GskSlToken token;
|
||||
};
|
||||
|
||||
struct _GskSlPreprocessor
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlCompiler *compiler;
|
||||
GskSlEnvironment *environment;
|
||||
GskSlTokenizer *tokenizer;
|
||||
GSList *pending_tokenizers;
|
||||
GArray *tokens;
|
||||
GHashTable *defines;
|
||||
gboolean fatal_error;
|
||||
GSList *conditionals;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
/* ignore this part, the last conditional check didn't match */
|
||||
GSK_COND_IGNORE = (1 << 0),
|
||||
/* we're inside the else block, so no more elif */
|
||||
GSK_COND_ELSE = (1 << 1),
|
||||
/* we've had a match in one of the previous blocks (or this one matches) */
|
||||
GSK_COND_MATCH = (1 << 2)
|
||||
} GskConditional;
|
||||
|
||||
/* API */
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_error_func (GskSlTokenizer *parser,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
gsk_sl_preprocessor_emit_error (user_data, TRUE, location, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_clear_token (gpointer data)
|
||||
{
|
||||
GskSlPpToken *pp = data;
|
||||
|
||||
gsk_sl_token_clear (&pp->token);
|
||||
}
|
||||
|
||||
GskSlPreprocessor *
|
||||
gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc)
|
||||
{
|
||||
g_return_val_if_fail (preproc != NULL, NULL);
|
||||
|
||||
preproc->ref_count += 1;
|
||||
|
||||
return preproc;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc)
|
||||
{
|
||||
if (preproc == NULL)
|
||||
return;
|
||||
|
||||
preproc->ref_count -= 1;
|
||||
if (preproc->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_slist_free (preproc->conditionals);
|
||||
g_hash_table_destroy (preproc->defines);
|
||||
g_slist_free_full (preproc->pending_tokenizers, (GDestroyNotify) gsk_sl_tokenizer_unref);
|
||||
gsk_sl_tokenizer_unref (preproc->tokenizer);
|
||||
gsk_sl_environment_unref (preproc->environment);
|
||||
g_object_unref (preproc->compiler);
|
||||
g_array_free (preproc->tokens, TRUE);
|
||||
|
||||
g_slice_free (GskSlPreprocessor, preproc);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc)
|
||||
{
|
||||
return preproc->fatal_error;
|
||||
}
|
||||
|
||||
GskSlEnvironment *
|
||||
gsk_sl_preprocessor_get_environment (GskSlPreprocessor *preproc)
|
||||
{
|
||||
return preproc->environment;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_push_conditional (GskSlPreprocessor *preproc,
|
||||
GskConditional cond)
|
||||
{
|
||||
preproc->conditionals = g_slist_prepend (preproc->conditionals, GUINT_TO_POINTER (cond));
|
||||
}
|
||||
|
||||
static GskConditional
|
||||
gsk_sl_preprocessor_pop_conditional (GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskConditional cond = GPOINTER_TO_UINT (preproc->conditionals->data);
|
||||
|
||||
preproc->conditionals = g_slist_remove (preproc->conditionals, preproc->conditionals->data);
|
||||
|
||||
return cond;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_preprocessor_has_conditional (GskSlPreprocessor *preproc)
|
||||
{
|
||||
return preproc->conditionals != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_preprocessor_in_ignored_conditional (GskSlPreprocessor *preproc)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = preproc->conditionals; l; l = l->next)
|
||||
{
|
||||
if (GPOINTER_TO_UINT (l->data) & GSK_COND_IGNORE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_handle_version (GskSlPreprocessor *preproc,
|
||||
GskCodeLocation *location,
|
||||
int version,
|
||||
const char *profile_name,
|
||||
gboolean first_token_ever)
|
||||
{
|
||||
GskSlEnvironment *new_environment;
|
||||
GskSlProfile profile;
|
||||
GError *error = NULL;
|
||||
|
||||
if (version <= 0)
|
||||
{
|
||||
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location, "version must be a positive number.");
|
||||
return;
|
||||
}
|
||||
if (profile_name == NULL)
|
||||
profile = GSK_SL_PROFILE_NONE;
|
||||
else if (g_str_equal (profile_name, "core"))
|
||||
profile = GSK_SL_PROFILE_CORE;
|
||||
else if (g_str_equal (profile_name, "compatibility"))
|
||||
profile = GSK_SL_PROFILE_COMPATIBILITY;
|
||||
else if (g_str_equal (profile_name, "es"))
|
||||
profile = GSK_SL_PROFILE_ES;
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location, "Unknown #version profile \"%s\".", profile_name);
|
||||
return;
|
||||
}
|
||||
if (!first_token_ever)
|
||||
{
|
||||
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location, "#version directive must be first in compilation.");
|
||||
return;
|
||||
}
|
||||
|
||||
new_environment = gsk_sl_environment_new_similar (preproc->environment, profile, version, &error);
|
||||
if (new_environment == NULL)
|
||||
{
|
||||
gsk_sl_preprocessor_emit_error (preproc, TRUE, location, error);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_environment_unref (preproc->environment);
|
||||
preproc->environment = new_environment;
|
||||
}
|
||||
}
|
||||
|
||||
#define token_array_get_token(array, i) (&g_array_index ((array), GskSlPpToken, (i)).token)
|
||||
#define token_array_get_location(array, i) (&g_array_index ((array), GskSlPpToken, (i)).location)
|
||||
#define token_array_error(preproc, array, i, ...) gsk_sl_preprocessor_error_full ((preproc), PREPROCESSOR, token_array_get_location (array, i), __VA_ARGS__)
|
||||
|
||||
static int
|
||||
gsk_sl_preprocessor_handle_defined_expression (GskSlPreprocessor *preproc,
|
||||
GArray *tokens,
|
||||
gint *index)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
gboolean paren = FALSE;
|
||||
int result;
|
||||
|
||||
(*index)++;
|
||||
|
||||
if (*index >= tokens->len)
|
||||
{
|
||||
token_array_error (preproc, tokens, tokens->len - 1, "\"defined\" without argument.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
token = token_array_get_token (tokens, *index);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
paren = TRUE;
|
||||
(*index)++;
|
||||
if (*index >= tokens->len)
|
||||
{
|
||||
token_array_error (preproc, tokens, tokens->len - 1, "\"defined()\" without argument.");
|
||||
return 0;
|
||||
}
|
||||
token = token_array_get_token (tokens, *index);
|
||||
}
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
(*index)++;
|
||||
if (g_hash_table_lookup (preproc->defines, token->str))
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, *index, "Expected identifier after \"defined\".");
|
||||
}
|
||||
if (paren)
|
||||
{
|
||||
if (*index >= tokens->len ||
|
||||
!gsk_sl_token_is (token_array_get_token (tokens, *index), GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
token_array_error (preproc, tokens, *index, "Expected closing \")\" for \"defined()\".");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*index)++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
gsk_sl_preprocessor_handle_primary_expression (GskSlPreprocessor *preproc,
|
||||
GArray *tokens,
|
||||
gint *index)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
|
||||
if (*index >= tokens->len)
|
||||
{
|
||||
token_array_error (preproc, tokens, tokens->len - 1, "Expected value.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
token = token_array_get_token (tokens, (*index));
|
||||
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
if (g_str_equal (token->str, "defined"))
|
||||
{
|
||||
return gsk_sl_preprocessor_handle_defined_expression (preproc, tokens, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, *index, "Unexpected identifier \"%s\".", token->str);
|
||||
(*index)++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (gsk_sl_token_is (token, GSK_SL_TOKEN_INTCONSTANT))
|
||||
{
|
||||
(*index)++;
|
||||
return token->i32;
|
||||
}
|
||||
else if (gsk_sl_token_is (token, GSK_SL_TOKEN_UINTCONSTANT))
|
||||
{
|
||||
(*index)++;
|
||||
return token->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, *index, "Unexpected token in #if statement.");
|
||||
(*index)++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gsk_sl_preprocessor_handle_expression (GskSlPreprocessor *preproc,
|
||||
GArray *tokens,
|
||||
gint *index)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = gsk_sl_preprocessor_handle_primary_expression (preproc, tokens, index);
|
||||
|
||||
if (*index < tokens->len)
|
||||
{
|
||||
token_array_error (preproc, tokens, *index, "Expected newline after expression.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc,
|
||||
GskSlPpToken *pp,
|
||||
gboolean *last_was_newline)
|
||||
{
|
||||
gboolean contained_newline = FALSE;
|
||||
|
||||
pp->token = (GskSlToken) { 0, };
|
||||
|
||||
do
|
||||
{
|
||||
pp->location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
|
||||
*last_was_newline = gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_NEWLINE);
|
||||
contained_newline |= gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_NEWLINE);
|
||||
gsk_sl_tokenizer_read_token (preproc->tokenizer, &pp->token);
|
||||
}
|
||||
while (gsk_sl_token_is_skipped (&pp->token));
|
||||
|
||||
return contained_newline || gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_EOF);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
|
||||
GskSlPpToken *pp,
|
||||
gboolean was_newline,
|
||||
gboolean was_start_of_document);
|
||||
|
||||
static gboolean
|
||||
gsk_sl_preprocessor_include (GskSlPreprocessor *preproc,
|
||||
GArray *tokens,
|
||||
gboolean include_local)
|
||||
{
|
||||
GskCodeSource *source;
|
||||
GError *error = NULL;
|
||||
|
||||
source = gsk_sl_compiler_resolve_include (preproc->compiler,
|
||||
gsk_sl_tokenizer_get_location (preproc->tokenizer)->source,
|
||||
include_local,
|
||||
token_array_get_token (tokens, 1)->str,
|
||||
&error);
|
||||
if (source == NULL)
|
||||
{
|
||||
gsk_sl_preprocessor_emit_error (preproc, TRUE, token_array_get_location (tokens, 1), error);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_slist_length (preproc->pending_tokenizers) > 20)
|
||||
{
|
||||
token_array_error (preproc, tokens, 1, "#include nested too deeply.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (tokens->len > 2)
|
||||
{
|
||||
token_array_error (preproc, tokens, 2, "Extra content after #include directive");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
preproc->pending_tokenizers = g_slist_prepend (preproc->pending_tokenizers, preproc->tokenizer);
|
||||
preproc->tokenizer = gsk_sl_tokenizer_new (source,
|
||||
gsk_sl_preprocessor_error_func,
|
||||
preproc,
|
||||
NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_append_token (GskSlPreprocessor *preproc,
|
||||
GskSlPpToken *pp,
|
||||
GSList *used_defines)
|
||||
{
|
||||
if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_EOF) &&
|
||||
preproc->pending_tokenizers)
|
||||
{
|
||||
gboolean was_newline;
|
||||
gsk_sl_tokenizer_unref (preproc->tokenizer);
|
||||
preproc->tokenizer = preproc->pending_tokenizers->data;
|
||||
preproc->pending_tokenizers = g_slist_remove (preproc->pending_tokenizers, preproc->tokenizer);
|
||||
gsk_sl_preprocessor_clear_token (pp);
|
||||
gsk_sl_preprocessor_next_token (preproc, pp, &was_newline);
|
||||
gsk_sl_preprocessor_handle_token (preproc, pp, TRUE, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_EOF))
|
||||
{
|
||||
while (gsk_sl_preprocessor_has_conditional (preproc))
|
||||
{
|
||||
gsk_sl_preprocessor_pop_conditional (preproc);
|
||||
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp->location, "Missing #endif.");
|
||||
}
|
||||
}
|
||||
|
||||
if (gsk_sl_preprocessor_in_ignored_conditional (preproc))
|
||||
{
|
||||
gsk_sl_preprocessor_clear_token (pp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
GskSlDefine *define;
|
||||
char *ident = pp->token.str;
|
||||
|
||||
define = g_hash_table_lookup (preproc->defines, ident);
|
||||
if (define &&
|
||||
!g_slist_find (used_defines, define))
|
||||
{
|
||||
GSList new_defines = { define, used_defines };
|
||||
GskSlPpToken dpp;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < gsk_sl_define_get_n_tokens (define); i++)
|
||||
{
|
||||
gsk_sl_define_get_token (define, i, &dpp.location, &dpp.token);
|
||||
gsk_sl_preprocessor_append_token (preproc, &dpp, &new_defines);
|
||||
}
|
||||
|
||||
gsk_sl_preprocessor_clear_token (pp);
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_sl_token_init_from_identifier (&pp->token, ident);
|
||||
g_free (ident);
|
||||
}
|
||||
else if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_STRING))
|
||||
{
|
||||
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp->location, "Unexpected string.");
|
||||
gsk_sl_preprocessor_clear_token (pp);
|
||||
return;
|
||||
}
|
||||
|
||||
g_array_append_val (preproc->tokens, *pp);
|
||||
}
|
||||
|
||||
static GArray *
|
||||
gsk_sl_preprocessor_read_line (GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlPpToken pp;
|
||||
GArray *tokens;
|
||||
|
||||
tokens = g_array_new (FALSE, FALSE, sizeof (GskSlPpToken));
|
||||
g_array_set_clear_func (tokens, gsk_sl_preprocessor_clear_token);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
pp.location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
|
||||
gsk_sl_tokenizer_read_token (preproc->tokenizer, &pp.token);
|
||||
if (gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_EOF) ||
|
||||
gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_NEWLINE))
|
||||
break;
|
||||
if (!gsk_sl_token_is_skipped (&pp.token))
|
||||
g_array_append_val (tokens, pp);
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc,
|
||||
gboolean first_token_ever)
|
||||
{
|
||||
GskSlPpToken pp;
|
||||
const GskSlToken *token;
|
||||
gboolean was_newline;
|
||||
GArray *tokens;
|
||||
|
||||
tokens = gsk_sl_preprocessor_read_line (preproc);
|
||||
|
||||
if (tokens->len == 0)
|
||||
/* empty # line */
|
||||
goto out;
|
||||
|
||||
token = &g_array_index (tokens, GskSlPpToken, 0).token;
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "Missing identifier for preprocessor directive.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_str_equal (token->str, "else"))
|
||||
{
|
||||
if (gsk_sl_preprocessor_has_conditional (preproc))
|
||||
{
|
||||
GskConditional cond = gsk_sl_preprocessor_pop_conditional (preproc);
|
||||
|
||||
if (cond & GSK_COND_ELSE)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "#else after #else.");
|
||||
cond |= GSK_COND_IGNORE;
|
||||
}
|
||||
else if (cond & GSK_COND_MATCH)
|
||||
cond |= GSK_COND_IGNORE;
|
||||
else
|
||||
cond &= ~GSK_COND_IGNORE;
|
||||
|
||||
cond |= GSK_COND_ELSE | GSK_COND_MATCH;
|
||||
|
||||
gsk_sl_preprocessor_push_conditional (preproc, cond);
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "#else without #if.");
|
||||
}
|
||||
|
||||
if (tokens->len > 1)
|
||||
token_array_error (preproc, tokens, 1, "Expected newline after #else.");
|
||||
}
|
||||
else if (g_str_equal (token->str, "elif"))
|
||||
{
|
||||
if (gsk_sl_preprocessor_has_conditional (preproc))
|
||||
{
|
||||
GskConditional cond = gsk_sl_preprocessor_pop_conditional (preproc);
|
||||
|
||||
if (cond & GSK_COND_ELSE)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "#elif after #else.");
|
||||
cond |= GSK_COND_IGNORE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int expr, index;
|
||||
|
||||
index = 1;
|
||||
expr = gsk_sl_preprocessor_handle_expression (preproc, tokens, &index);
|
||||
|
||||
if (cond & GSK_COND_MATCH)
|
||||
{
|
||||
cond |= GSK_COND_IGNORE;
|
||||
}
|
||||
else if (expr)
|
||||
{
|
||||
cond &= ~GSK_COND_IGNORE;
|
||||
cond |= GSK_COND_MATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cond |= GSK_COND_IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
gsk_sl_preprocessor_push_conditional (preproc, cond);
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "#elif without #if.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (g_str_equal (token->str, "endif"))
|
||||
{
|
||||
if (gsk_sl_preprocessor_has_conditional (preproc))
|
||||
{
|
||||
gsk_sl_preprocessor_pop_conditional (preproc);
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "#endif without #if.");
|
||||
}
|
||||
|
||||
if (tokens->len > 1)
|
||||
token_array_error (preproc, tokens, 1, "Expected newline after #endif.");
|
||||
}
|
||||
else if (g_str_equal (token->str, "if"))
|
||||
{
|
||||
int expr, index;
|
||||
|
||||
index = 1;
|
||||
expr = gsk_sl_preprocessor_handle_expression (preproc, tokens, &index);
|
||||
if (expr)
|
||||
gsk_sl_preprocessor_push_conditional (preproc, GSK_COND_MATCH);
|
||||
else
|
||||
gsk_sl_preprocessor_push_conditional (preproc, GSK_COND_IGNORE);
|
||||
}
|
||||
else if (g_str_equal (token->str, "ifdef"))
|
||||
{
|
||||
if (tokens->len == 1)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "No variable after #ifdef.");
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_array_get_token (tokens, 1);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
token_array_error (preproc, tokens, 1, "Expected identifier after #ifdef.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_hash_table_lookup (preproc->defines, token->str))
|
||||
{
|
||||
gsk_sl_preprocessor_push_conditional (preproc, GSK_COND_MATCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_push_conditional (preproc, GSK_COND_IGNORE);
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens->len > 2)
|
||||
token_array_error (preproc, tokens, 2, "Expected newline after #ifdef.");
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (token->str, "ifndef"))
|
||||
{
|
||||
if (tokens->len == 1)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "No variable after #ifdef.");
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_array_get_token (tokens, 1);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
token_array_error (preproc, tokens, 1, "Expected identifier after #ifndef.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_hash_table_lookup (preproc->defines, token->str))
|
||||
{
|
||||
gsk_sl_preprocessor_push_conditional (preproc, GSK_COND_IGNORE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_push_conditional (preproc, GSK_COND_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens->len > 2)
|
||||
token_array_error (preproc, tokens, 2, "Expected newline after #ifndef.");
|
||||
}
|
||||
}
|
||||
else if (gsk_sl_preprocessor_in_ignored_conditional (preproc))
|
||||
{
|
||||
/* All checks above are for preprocessor directives that are checked even in
|
||||
* ignored parts of code */
|
||||
|
||||
/* Everything below has no effect in ignored parts of the code */
|
||||
}
|
||||
else if (g_str_equal (token->str, "define"))
|
||||
{
|
||||
if (tokens->len == 1)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "No variable after #define.");
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_array_get_token (tokens, 1);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
token_array_error (preproc, tokens, 1, "Expected identifier after #define.");
|
||||
}
|
||||
else
|
||||
{
|
||||
GskSlDefine *define;
|
||||
guint i;
|
||||
|
||||
if (g_hash_table_lookup (preproc->defines, token->str))
|
||||
token_array_error (preproc, tokens, 1, "\"%s\" redefined.", token->str);
|
||||
|
||||
define = gsk_sl_define_new (token->str, NULL);
|
||||
|
||||
for (i = 2; i < tokens->len; i++)
|
||||
{
|
||||
gsk_sl_define_add_token (define,
|
||||
token_array_get_location (tokens, i),
|
||||
token_array_get_token (tokens, i));
|
||||
}
|
||||
|
||||
g_hash_table_replace (preproc->defines, (gpointer) gsk_sl_define_get_name (define), define);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (token->str, "include"))
|
||||
{
|
||||
if (tokens->len == 1)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "No filename after #include.");
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_array_get_token (tokens, 1);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_STRING))
|
||||
{
|
||||
gsk_sl_preprocessor_include (preproc, tokens, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, 1, "Expected filename after #include.");
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (g_str_equal (token->str, "line"))
|
||||
{
|
||||
}
|
||||
else if (g_str_equal (token->str, "pragma"))
|
||||
{
|
||||
}
|
||||
else if (g_str_equal (token->str, "error"))
|
||||
{
|
||||
}
|
||||
else if (g_str_equal (token->str, "extension"))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
else if (g_str_equal (token->str, "undef"))
|
||||
{
|
||||
if (tokens->len == 1)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "No variable after #undef.");
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_array_get_token (tokens, 1);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
token_array_error (preproc, tokens, 1, "Expected identifier after #undef.");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_remove (preproc->defines, token->str);
|
||||
}
|
||||
|
||||
if (tokens->len > 2)
|
||||
token_array_error (preproc, tokens, 2, "Expected newline after #undef.");
|
||||
}
|
||||
}
|
||||
else if (g_str_equal (token->str, "version"))
|
||||
{
|
||||
if (tokens->len == 1)
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "No version specified after #version.");
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_array_get_token (tokens, 1);
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_INTCONSTANT))
|
||||
{
|
||||
token_array_error (preproc, tokens, 1, "Expected version number.");
|
||||
}
|
||||
else
|
||||
{
|
||||
gint version = token->i32;
|
||||
|
||||
if (tokens->len == 2)
|
||||
{
|
||||
gsk_sl_preprocessor_handle_version (preproc, token_array_get_location (tokens, 1), version, NULL, first_token_ever);
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_array_get_token (tokens, 2);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
gsk_sl_preprocessor_handle_version (preproc, token_array_get_location (tokens, 1), version, token->str, first_token_ever);
|
||||
else
|
||||
token_array_error (preproc, tokens, 2, "Expected newline after #version.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
token_array_error (preproc, tokens, 0, "Unknown preprocessor directive #%s.", token->str);
|
||||
}
|
||||
|
||||
out:
|
||||
g_array_free (tokens, TRUE);
|
||||
|
||||
/* process first token, so we can ensure it assumes a newline */
|
||||
gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline);
|
||||
gsk_sl_preprocessor_handle_token (preproc, &pp, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
|
||||
GskSlPpToken *pp,
|
||||
gboolean was_newline,
|
||||
gboolean start_of_document)
|
||||
{
|
||||
if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_HASH))
|
||||
{
|
||||
if (!was_newline)
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Unexpected \"#\" - preprocessor directives must be at start of line.");
|
||||
gsk_sl_preprocessor_clear_token (pp);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_clear_token (pp);
|
||||
gsk_sl_preprocessor_handle_preprocessor_directive (preproc, start_of_document);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_append_token (preproc, pp, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
GskSlPreprocessor *
|
||||
gsk_sl_preprocessor_new (GskSlCompiler *compiler,
|
||||
GskSlEnvironment *environment,
|
||||
GskCodeSource *source)
|
||||
{
|
||||
GskSlPreprocessor *preproc;
|
||||
GskSlPpToken pp;
|
||||
gboolean was_newline;
|
||||
|
||||
preproc = g_slice_new0 (GskSlPreprocessor);
|
||||
|
||||
preproc->ref_count = 1;
|
||||
preproc->compiler = g_object_ref (compiler);
|
||||
if (environment)
|
||||
preproc->environment = gsk_sl_environment_ref (environment);
|
||||
preproc->tokenizer = gsk_sl_tokenizer_new (source,
|
||||
gsk_sl_preprocessor_error_func,
|
||||
preproc,
|
||||
NULL);
|
||||
preproc->tokens = g_array_new (FALSE, FALSE, sizeof (GskSlPpToken));
|
||||
g_array_set_clear_func (preproc->tokens, gsk_sl_preprocessor_clear_token);
|
||||
preproc->defines = gsk_sl_compiler_copy_defines (compiler);
|
||||
|
||||
/* process the first token, so we can parse #version */
|
||||
gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline);
|
||||
gsk_sl_preprocessor_handle_token (preproc, &pp, TRUE, TRUE);
|
||||
|
||||
return preproc;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_ensure (GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlPpToken pp;
|
||||
gboolean was_newline = FALSE;
|
||||
|
||||
while (preproc->tokens->len <= 0)
|
||||
{
|
||||
gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline);
|
||||
|
||||
gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
const GskSlToken *
|
||||
gsk_sl_preprocessor_get (GskSlPreprocessor *preproc)
|
||||
{
|
||||
gsk_sl_preprocessor_ensure (preproc);
|
||||
|
||||
return &g_array_index (preproc->tokens, GskSlPpToken, 0).token;
|
||||
}
|
||||
|
||||
const GskCodeLocation *
|
||||
gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc)
|
||||
{
|
||||
gsk_sl_preprocessor_ensure (preproc);
|
||||
|
||||
return &g_array_index (preproc->tokens, GskSlPpToken, 0).location;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc,
|
||||
gpointer consumer)
|
||||
{
|
||||
gsk_sl_preprocessor_ensure (preproc);
|
||||
|
||||
g_array_remove_index (preproc->tokens, 0);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_preprocessor_sync (GskSlPreprocessor *preproc,
|
||||
GskSlTokenType token_type)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
|
||||
for (token = gsk_sl_preprocessor_get (preproc);
|
||||
!gsk_sl_token_is (token, GSK_SL_TOKEN_EOF) && !gsk_sl_token_is (token, token_type);
|
||||
token = gsk_sl_preprocessor_get (preproc))
|
||||
{
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_BRACE);
|
||||
}
|
||||
else if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACKET))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_BRACKET);
|
||||
}
|
||||
else if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_preprocessor_emit_error (GskSlPreprocessor *preproc,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GError *error)
|
||||
{
|
||||
preproc->fatal_error |= fatal;
|
||||
|
||||
g_printerr ("%s:%zu:%zu: %s: %s\n",
|
||||
gsk_code_source_get_name (location->source),
|
||||
location->lines + 1, location->line_bytes,
|
||||
fatal ? "error" : "warn",
|
||||
error->message);
|
||||
}
|
||||
|
89
gsk/gskslpreprocessorprivate.h
Normal file
89
gsk/gskslpreprocessorprivate.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_PREPROCESSOR_PRIVATE_H__
|
||||
#define __GSK_SL_PREPROCESSOR_PRIVATE_H__
|
||||
|
||||
#include "gskslcompilerprivate.h"
|
||||
#include "gskslenvironmentprivate.h"
|
||||
#include "gsksltypesprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlPreprocessor * gsk_sl_preprocessor_new (GskSlCompiler *compiler,
|
||||
GskSlEnvironment *environment,
|
||||
GskCodeSource *source);
|
||||
|
||||
GskSlPreprocessor * gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc);
|
||||
void gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc);
|
||||
|
||||
gboolean gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc);
|
||||
GskSlEnvironment * gsk_sl_preprocessor_get_environment (GskSlPreprocessor *preproc);
|
||||
const GskSlToken * gsk_sl_preprocessor_get (GskSlPreprocessor *preproc);
|
||||
const GskCodeLocation * gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc);
|
||||
void gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc,
|
||||
gpointer consumer);
|
||||
#define gsk_sl_preprocessor_is_stage(preproc,stage) (gsk_sl_environment_get_stage (gsk_sl_preprocessor_get_environment (preproc)) == (stage))
|
||||
|
||||
void gsk_sl_preprocessor_sync (GskSlPreprocessor *preproc,
|
||||
GskSlTokenType token);
|
||||
void gsk_sl_preprocessor_emit_error (GskSlPreprocessor *preproc,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GError *error);
|
||||
|
||||
#define gsk_sl_preprocessor_error(preproc, type, ...) \
|
||||
gsk_sl_preprocessor_error_full (preproc, type, gsk_sl_preprocessor_get_location (preproc), __VA_ARGS__)
|
||||
|
||||
#define gsk_sl_preprocessor_error_full(preproc, type, location, ...) G_STMT_START{\
|
||||
GError *error; \
|
||||
\
|
||||
error = g_error_new (GSK_SL_COMPILER_ERROR, \
|
||||
GSK_SL_COMPILER_ERROR_ ## type, \
|
||||
__VA_ARGS__); \
|
||||
\
|
||||
gsk_sl_preprocessor_emit_error (preproc, \
|
||||
TRUE, \
|
||||
location, \
|
||||
error); \
|
||||
\
|
||||
g_error_free (error);\
|
||||
}G_STMT_END
|
||||
|
||||
#define gsk_sl_preprocessor_warn(preproc, type, ...) \
|
||||
gsk_sl_preprocessor_warn_full (preproc, type, gsk_sl_preprocessor_get_location (preproc), __VA_ARGS__)
|
||||
|
||||
#define gsk_sl_preprocessor_warn_full(preproc, type, location, ...) G_STMT_START{\
|
||||
GError *error; \
|
||||
\
|
||||
error = g_error_new (GSK_SL_COMPILER_WARNING, \
|
||||
GSK_SL_COMPILER_WARNING_ ## type, \
|
||||
__VA_ARGS__); \
|
||||
\
|
||||
gsk_sl_preprocessor_emit_error (preproc, \
|
||||
FALSE, \
|
||||
location, \
|
||||
error); \
|
||||
\
|
||||
g_error_free (error);\
|
||||
}G_STMT_END
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_PREPROCESSOR_PRIVATE_H__ */
|
185
gsk/gskslprinter.c
Normal file
185
gsk/gskslprinter.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslprinterprivate.h"
|
||||
|
||||
struct _GskSlPrinter
|
||||
{
|
||||
guint ref_count;
|
||||
|
||||
GString *string;
|
||||
|
||||
guint indentation;
|
||||
};
|
||||
|
||||
GskSlPrinter *
|
||||
gsk_sl_printer_new (void)
|
||||
{
|
||||
GskSlPrinter *printer;
|
||||
|
||||
printer = g_slice_new0 (GskSlPrinter);
|
||||
|
||||
printer->ref_count = 1;
|
||||
|
||||
printer->string = g_string_new (NULL);
|
||||
|
||||
return printer;
|
||||
}
|
||||
|
||||
GskSlPrinter *
|
||||
gsk_sl_printer_ref (GskSlPrinter *printer)
|
||||
{
|
||||
g_return_val_if_fail (printer != NULL, NULL);
|
||||
|
||||
printer->ref_count += 1;
|
||||
|
||||
return printer;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_unref (GskSlPrinter *printer)
|
||||
{
|
||||
if (printer == NULL)
|
||||
return;
|
||||
|
||||
printer->ref_count -= 1;
|
||||
if (printer->ref_count > 0)
|
||||
return;
|
||||
|
||||
if (printer->indentation > 0)
|
||||
{
|
||||
g_warning ("Missing call to gsk_sl_printer_pop_indentation().");
|
||||
}
|
||||
|
||||
g_string_free (printer->string, TRUE);
|
||||
|
||||
g_slice_free (GskSlPrinter, printer);
|
||||
}
|
||||
|
||||
char *
|
||||
gsk_sl_printer_write_to_string (GskSlPrinter *printer)
|
||||
{
|
||||
return g_strdup (printer->string->str);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_push_indentation (GskSlPrinter *printer)
|
||||
{
|
||||
printer->indentation++;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_pop_indentation (GskSlPrinter *printer)
|
||||
{
|
||||
if (printer->indentation == 0)
|
||||
{
|
||||
g_warning ("Calling gsk_sl_printer_pop_indentation() without preceding call to gsk_sl_printer_push_indentation()");
|
||||
return;
|
||||
}
|
||||
|
||||
printer->indentation--;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gsk_sl_printer_append (GskSlPrinter *printer,
|
||||
const char *str)
|
||||
{
|
||||
g_string_append (printer->string, str);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_append_c (GskSlPrinter *printer,
|
||||
char c)
|
||||
{
|
||||
g_string_append_c (printer->string, c);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_append_int (GskSlPrinter *printer,
|
||||
int i)
|
||||
{
|
||||
g_string_append_printf (printer->string, "%d", i);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_append_uint (GskSlPrinter *printer,
|
||||
guint u)
|
||||
{
|
||||
g_string_append_printf (printer->string, "%u", u);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_append_float (GskSlPrinter *printer,
|
||||
float f)
|
||||
{
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
if (isnanf (f))
|
||||
g_string_append (printer->string, "(0.0 / 0.0)");
|
||||
else if (isinff (f) > 0)
|
||||
g_string_append (printer->string, "(1.0 / 0.0)");
|
||||
else if (isinff (f) < 0)
|
||||
g_string_append (printer->string, "(-1.0 / 0.0)");
|
||||
else
|
||||
{
|
||||
g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, f);
|
||||
g_string_append (printer->string, buf);
|
||||
if (strchr (buf, '.') == NULL)
|
||||
g_string_append (printer->string, ".0");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_append_double (GskSlPrinter *printer,
|
||||
double d)
|
||||
{
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
if (isnan (d))
|
||||
g_string_append (printer->string, "(0.0lf / 0.0lf)");
|
||||
else if (isinf (d) > 0)
|
||||
g_string_append (printer->string, "(1.0lf / 0.0lf)");
|
||||
else if (isinf (d) < 0)
|
||||
g_string_append (printer->string, "(-1.0lf / 0.0lf)");
|
||||
else
|
||||
{
|
||||
g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, d);
|
||||
g_string_append (printer->string, buf);
|
||||
if (strchr (buf, '.') == NULL)
|
||||
g_string_append (printer->string, ".0lf");
|
||||
else
|
||||
g_string_append (printer->string, "lf");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_printer_newline (GskSlPrinter *printer)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_string_append_c (printer->string, '\n');
|
||||
|
||||
for (i = 0; i < printer->indentation; i++)
|
||||
{
|
||||
g_string_append (printer->string, " ");
|
||||
}
|
||||
}
|
||||
|
54
gsk/gskslprinterprivate.h
Normal file
54
gsk/gskslprinterprivate.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_PRINTER_PRIVATE_H__
|
||||
#define __GSK_SL_PRINTER_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlPrinter * gsk_sl_printer_new (void);
|
||||
|
||||
GskSlPrinter * gsk_sl_printer_ref (GskSlPrinter *printer);
|
||||
void gsk_sl_printer_unref (GskSlPrinter *printer);
|
||||
|
||||
char * gsk_sl_printer_write_to_string (GskSlPrinter *printer);
|
||||
|
||||
void gsk_sl_printer_push_indentation (GskSlPrinter *printer);
|
||||
void gsk_sl_printer_pop_indentation (GskSlPrinter *printer);
|
||||
|
||||
void gsk_sl_printer_append (GskSlPrinter *printer,
|
||||
const char *str);
|
||||
void gsk_sl_printer_append_c (GskSlPrinter *printer,
|
||||
char c);
|
||||
void gsk_sl_printer_append_int (GskSlPrinter *printer,
|
||||
int i);
|
||||
void gsk_sl_printer_append_uint (GskSlPrinter *printer,
|
||||
guint u);
|
||||
void gsk_sl_printer_append_float (GskSlPrinter *printer,
|
||||
float f);
|
||||
void gsk_sl_printer_append_double (GskSlPrinter *printer,
|
||||
double d);
|
||||
void gsk_sl_printer_newline (GskSlPrinter *printer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_PRINTER_PRIVATE_H__ */
|
168
gsk/gskslprogram.c
Normal file
168
gsk/gskslprogram.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslprogramprivate.h"
|
||||
|
||||
#include "gsksldeclarationprivate.h"
|
||||
#include "gskslenvironmentprivate.h"
|
||||
#include "gskslfunctionprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslprinterprivate.h"
|
||||
#include "gskslscopeprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
struct _GskSlProgram {
|
||||
GObject parent_instance;
|
||||
|
||||
GskSlShaderStage stage;
|
||||
GskSlScope *scope;
|
||||
GSList *declarations;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskSlProgram, gsk_sl_program, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gsk_sl_program_dispose (GObject *object)
|
||||
{
|
||||
GskSlProgram *program = GSK_SL_PROGRAM (object);
|
||||
|
||||
g_slist_free_full (program->declarations, (GDestroyNotify) gsk_sl_declaration_unref);
|
||||
g_clear_pointer (&program->scope, gsk_sl_scope_unref);
|
||||
|
||||
G_OBJECT_CLASS (gsk_sl_program_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_program_class_init (GskSlProgramClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsk_sl_program_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_program_init (GskSlProgram *program)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_program_parse (GskSlProgram *program,
|
||||
GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlDeclaration *declaration;
|
||||
const GskSlToken *token;
|
||||
|
||||
program->stage = gsk_sl_environment_get_stage (gsk_sl_preprocessor_get_environment (preproc));
|
||||
program->scope = gsk_sl_environment_create_scope (gsk_sl_preprocessor_get_environment (preproc));
|
||||
|
||||
for (token = gsk_sl_preprocessor_get (preproc);
|
||||
!gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
|
||||
token = gsk_sl_preprocessor_get (preproc))
|
||||
{
|
||||
declaration = gsk_sl_declaration_parse (program->scope, preproc);
|
||||
if (declaration)
|
||||
program->declarations = g_slist_prepend (program->declarations, declaration);
|
||||
}
|
||||
|
||||
program->declarations = g_slist_reverse (program->declarations);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_program_print (GskSlProgram *program,
|
||||
GString *string)
|
||||
{
|
||||
GskSlPrinter *printer;
|
||||
GskSlFunction *function;
|
||||
gboolean need_newline = FALSE;
|
||||
GSList *l;
|
||||
char *str;
|
||||
|
||||
g_return_if_fail (GSK_IS_SL_PROGRAM (program));
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
printer = gsk_sl_printer_new ();
|
||||
|
||||
for (l = program->declarations; l; l = l->next)
|
||||
{
|
||||
function = gsk_sl_declaration_get_function (l->data);
|
||||
|
||||
if ((function || need_newline) && l != program->declarations)
|
||||
gsk_sl_printer_newline (printer);
|
||||
|
||||
gsk_sl_declaration_print (l->data, printer);
|
||||
|
||||
need_newline = function != NULL;
|
||||
}
|
||||
|
||||
str = gsk_sl_printer_write_to_string (printer);
|
||||
g_string_append (string, str);
|
||||
g_free (str);
|
||||
|
||||
gsk_sl_printer_unref (printer);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_program_write_spv_initializer (GskSpvWriter *writer,
|
||||
gpointer data)
|
||||
{
|
||||
GskSlProgram *program = data;
|
||||
GSList *l;
|
||||
|
||||
for (l = program->declarations; l; l = l->next)
|
||||
gsk_sl_declaration_write_initializer_spv (l->data, writer);
|
||||
}
|
||||
|
||||
static GskSlFunction *
|
||||
gsk_sl_program_get_entry_point (GskSlProgram *program)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = program->declarations; l; l = l->next)
|
||||
{
|
||||
GskSlFunction *function = gsk_sl_declaration_get_function (l->data);
|
||||
|
||||
if (function && g_str_equal (gsk_sl_function_get_name (function), "main"))
|
||||
return function;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GBytes *
|
||||
gsk_sl_program_to_spirv (GskSlProgram *program)
|
||||
{
|
||||
GskSpvWriter *writer;
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SL_PROGRAM (program), NULL);
|
||||
|
||||
writer = gsk_spv_writer_new (program->stage);
|
||||
|
||||
bytes = gsk_spv_writer_write (writer,
|
||||
gsk_sl_program_get_entry_point (program),
|
||||
gsk_sl_program_write_spv_initializer,
|
||||
program);
|
||||
|
||||
gsk_spv_writer_unref (writer);
|
||||
|
||||
return bytes;
|
||||
}
|
43
gsk/gskslprogram.h
Normal file
43
gsk/gskslprogram.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_PROGRAM_H__
|
||||
#define __GSK_SL_PROGRAM_H__
|
||||
|
||||
#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
|
||||
#error "Only <gsk/gsk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_SL_PROGRAM (gsk_sl_program_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GskSlProgram, gsk_sl_program, GSK, SL_PROGRAM, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
void gsk_sl_program_print (GskSlProgram *program,
|
||||
GString *string);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GBytes * gsk_sl_program_to_spirv (GskSlProgram *program);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_PROGRAM_H__ */
|
32
gsk/gskslprogramprivate.h
Normal file
32
gsk/gskslprogramprivate.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_PROGRAM_PRIVATE_H__
|
||||
#define __GSK_SL_PROGRAM_PRIVATE_H__
|
||||
|
||||
#include "gsk/gskslprogram.h"
|
||||
#include "gsk/gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_sl_program_parse (GskSlProgram *program,
|
||||
GskSlPreprocessor *preproc);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_PROGRAM_PRIVATE_H__ */
|
723
gsk/gskslqualifier.c
Normal file
723
gsk/gskslqualifier.c
Normal file
@@ -0,0 +1,723 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslqualifierprivate.h"
|
||||
|
||||
#include "gskslexpressionprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslprinterprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslvalueprivate.h"
|
||||
|
||||
void
|
||||
gsk_sl_qualifier_init (GskSlQualifier *qualifier)
|
||||
{
|
||||
*qualifier = (GskSlQualifier) { .storage = GSK_SL_STORAGE_DEFAULT,
|
||||
.layout = { -1, -1, -1, -1 },
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_qualifier_parse_layout_assignment (GskSlPreprocessor *preproc,
|
||||
GskSlScope *scope,
|
||||
int *target)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected \"=\" sign to assign a value.");
|
||||
return;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
*target = gsk_sl_expression_parse_integral_constant (scope, preproc, 0, G_MAXINT);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_qualifier_parse_layout (GskSlQualifier *qualifier,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlScope *scope)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
|
||||
break;
|
||||
}
|
||||
else if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
if (g_str_equal (token->str, "location"))
|
||||
gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.location);
|
||||
else if (g_str_equal (token->str, "component"))
|
||||
gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.component);
|
||||
else if (g_str_equal (token->str, "binding"))
|
||||
gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.binding);
|
||||
else if (g_str_equal (token->str, "set"))
|
||||
gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.set);
|
||||
else if (g_str_equal (token->str, "push_constant"))
|
||||
{
|
||||
qualifier->layout.push_constant = TRUE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, UNSUPPORTED, "Unknown layout identifier.");
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
|
||||
break;
|
||||
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_storage_get_name (GskSlStorage storage)
|
||||
{
|
||||
switch (storage)
|
||||
{
|
||||
default:
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
g_assert_not_reached ();
|
||||
return "???";
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
return "";
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
return "const";
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
return "in";
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
return "out";
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
return "inout";
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
return "uniform";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_interpolation_get_name (GskSlInterpolation interp)
|
||||
{
|
||||
switch (interp)
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_SL_INTERPOLATE_DEFAULT:
|
||||
return "";
|
||||
case GSK_SL_INTERPOLATE_SMOOTH:
|
||||
return "smooth";
|
||||
case GSK_SL_INTERPOLATE_FLAT:
|
||||
return "flat";
|
||||
case GSK_SL_INTERPOLATE_NO_PERSPECTIVE:
|
||||
return "noperspective";
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_storage_allows_const (GskSlStorage storage)
|
||||
{
|
||||
switch (storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
return FALSE;
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_qualifier_parse (GskSlQualifier *qualifier,
|
||||
GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlQualifierLocation location)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
gboolean seen_const = FALSE;
|
||||
|
||||
gsk_sl_qualifier_init (qualifier);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
switch ((guint) token->type)
|
||||
{
|
||||
case GSK_SL_TOKEN_CONST:
|
||||
if (seen_const)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"const\" qualifier.");
|
||||
if (!gsk_sl_storage_allows_const (qualifier->storage))
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "\"%s\" qualifier cannot be const.", gsk_sl_storage_get_name (qualifier->storage));
|
||||
else
|
||||
seen_const = TRUE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_IN:
|
||||
if (qualifier->storage == GSK_SL_STORAGE_DEFAULT)
|
||||
{
|
||||
if (location == GSK_SL_QUALIFIER_LOCAL)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Local variables cannot have \"in\" qualifier.");
|
||||
else
|
||||
qualifier->storage = location == GSK_SL_QUALIFIER_GLOBAL ? GSK_SL_STORAGE_GLOBAL_IN
|
||||
: GSK_SL_STORAGE_PARAMETER_IN;
|
||||
}
|
||||
else if (qualifier->storage == GSK_SL_STORAGE_PARAMETER_OUT)
|
||||
qualifier->storage = GSK_SL_STORAGE_PARAMETER_INOUT;
|
||||
else
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Qualifiers \"%s\" and \"in\" cannot be combined.", gsk_sl_storage_get_name (qualifier->storage));
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_OUT:
|
||||
if (seen_const)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Const variables cannot have \"out\" qualifier.");
|
||||
else if (qualifier->storage == GSK_SL_STORAGE_DEFAULT)
|
||||
{
|
||||
if (location == GSK_SL_QUALIFIER_LOCAL)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Local variables cannot have \"out\" qualifier.");
|
||||
else
|
||||
qualifier->storage = location == GSK_SL_QUALIFIER_GLOBAL ? GSK_SL_STORAGE_GLOBAL_OUT
|
||||
: GSK_SL_STORAGE_PARAMETER_OUT;
|
||||
}
|
||||
else if (qualifier->storage == GSK_SL_STORAGE_PARAMETER_IN)
|
||||
qualifier->storage = GSK_SL_STORAGE_PARAMETER_INOUT;
|
||||
else
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Qualifiers \"%s\" and \"out\" cannot be combined.", gsk_sl_storage_get_name (qualifier->storage));
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_INOUT:
|
||||
if (seen_const)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Const variables cannot have \"inout\" qualifier.");
|
||||
else if (qualifier->storage == GSK_SL_STORAGE_DEFAULT)
|
||||
{
|
||||
if (location != GSK_SL_QUALIFIER_PARAMETER)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "\"inout\" can only be used on parameters.");
|
||||
else
|
||||
qualifier->storage = GSK_SL_STORAGE_PARAMETER_INOUT;
|
||||
}
|
||||
else
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Qualifiers \"%s\" and \"inout\" cannot be combined.", gsk_sl_storage_get_name (qualifier->storage));
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_UNIFORM:
|
||||
if (seen_const)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Const variables cannot have \"uniform\" qualifier.");
|
||||
else if (qualifier->storage == GSK_SL_STORAGE_DEFAULT)
|
||||
{
|
||||
if (location != GSK_SL_QUALIFIER_GLOBAL)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "\"uniform\" can only be used on globals.");
|
||||
else
|
||||
qualifier->storage = GSK_SL_STORAGE_GLOBAL_UNIFORM;
|
||||
}
|
||||
else
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Qualifiers \"%s\" and \"uniform\" cannot be combined.", gsk_sl_storage_get_name (qualifier->storage));
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_SMOOTH:
|
||||
if (qualifier->interpolation != GSK_SL_INTERPOLATE_DEFAULT)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX,
|
||||
"Duplicate interpolation qualifiers: \"%s\" and \"smooth\".",
|
||||
gsk_sl_interpolation_get_name (qualifier->interpolation));
|
||||
else
|
||||
qualifier->interpolation = GSK_SL_INTERPOLATE_SMOOTH;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_FLAT:
|
||||
if (qualifier->interpolation != GSK_SL_INTERPOLATE_DEFAULT)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX,
|
||||
"Duplicate interpolation qualifiers: \"%s\" and \"flat\".",
|
||||
gsk_sl_interpolation_get_name (qualifier->interpolation));
|
||||
else
|
||||
qualifier->interpolation = GSK_SL_INTERPOLATE_FLAT;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_NOPERSPECTIVE:
|
||||
if (qualifier->interpolation != GSK_SL_INTERPOLATE_DEFAULT)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX,
|
||||
"Duplicate interpolation qualifiers: \"%s\" and \"noperspective\".",
|
||||
gsk_sl_interpolation_get_name (qualifier->interpolation));
|
||||
else
|
||||
qualifier->interpolation = GSK_SL_INTERPOLATE_NO_PERSPECTIVE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_INVARIANT:
|
||||
if (qualifier->invariant)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"invariant\" qualifier.");
|
||||
qualifier->invariant = TRUE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_COHERENT:
|
||||
if (qualifier->coherent)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"coherent\" qualifier.");
|
||||
qualifier->coherent = TRUE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_VOLATILE:
|
||||
if (qualifier->volatile_)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"volatile\" qualifier.");
|
||||
qualifier->volatile_ = TRUE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_RESTRICT:
|
||||
if (qualifier->restrict_)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"restrict\" qualifier.");
|
||||
qualifier->restrict_ = TRUE;
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_READONLY:
|
||||
if (qualifier->readonly)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"readonly\" qualifier.");
|
||||
qualifier->readonly = TRUE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_WRITEONLY:
|
||||
if (qualifier->writeonly)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"writeonly\" qualifier.");
|
||||
qualifier->writeonly = TRUE;
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_LAYOUT:
|
||||
if (location != GSK_SL_QUALIFIER_GLOBAL)
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Only global variables can have layout qualifiers.");
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected opening \"(\" after layout specifier");
|
||||
break;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
gsk_sl_qualifier_parse_layout (qualifier, preproc, scope);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \")\" at end of layout specifier");
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN);
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/* fixup storage qualifier */
|
||||
switch (qualifier->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
if (location == GSK_SL_QUALIFIER_GLOBAL)
|
||||
qualifier->storage = seen_const ? GSK_SL_STORAGE_GLOBAL_CONST : GSK_SL_STORAGE_GLOBAL;
|
||||
else if (location == GSK_SL_QUALIFIER_LOCAL)
|
||||
qualifier->storage = seen_const ? GSK_SL_STORAGE_LOCAL_CONST : GSK_SL_STORAGE_LOCAL;
|
||||
else if (location == GSK_SL_QUALIFIER_PARAMETER)
|
||||
qualifier->storage = seen_const ? GSK_SL_STORAGE_PARAMETER_CONST : GSK_SL_STORAGE_PARAMETER_IN;
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
if (seen_const)
|
||||
qualifier->storage = GSK_SL_STORAGE_GLOBAL_CONST;
|
||||
break;
|
||||
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
if (seen_const)
|
||||
qualifier->storage = GSK_SL_STORAGE_LOCAL_CONST;
|
||||
break;
|
||||
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
if (seen_const)
|
||||
qualifier->storage = GSK_SL_STORAGE_PARAMETER_CONST;
|
||||
break;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
g_assert (!seen_const);
|
||||
break;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_qualifier_has_layout (const GskSlQualifier *qualifier)
|
||||
{
|
||||
return qualifier->layout.set >= 0
|
||||
|| qualifier->layout.binding >= 0
|
||||
|| qualifier->layout.location >= 0
|
||||
|| qualifier->layout.component >= 0
|
||||
|| qualifier->layout.push_constant;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
print_qualifier (GskSlPrinter *printer,
|
||||
const char *name,
|
||||
gint value,
|
||||
gboolean needs_comma)
|
||||
{
|
||||
if (value < 0)
|
||||
return needs_comma;
|
||||
|
||||
if (needs_comma)
|
||||
gsk_sl_printer_append (printer, ", ");
|
||||
gsk_sl_printer_append (printer, name);
|
||||
gsk_sl_printer_append (printer, "=");
|
||||
gsk_sl_printer_append_uint (printer, value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
append_with_space (GskSlPrinter *printer,
|
||||
const char *s,
|
||||
gboolean need_space)
|
||||
{
|
||||
if (s[0] == '\0')
|
||||
return need_space;
|
||||
|
||||
if (need_space)
|
||||
gsk_sl_printer_append_c (printer, ' ');
|
||||
gsk_sl_printer_append (printer, s);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_qualifier_print (const GskSlQualifier *qualifier,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
gboolean need_space = FALSE;
|
||||
|
||||
if (qualifier->invariant)
|
||||
need_space = append_with_space (printer, "invariant ", need_space);
|
||||
if (qualifier->volatile_)
|
||||
need_space = append_with_space (printer, "volatile ", need_space);
|
||||
if (qualifier->restrict_)
|
||||
need_space = append_with_space (printer, "restrict ", need_space);
|
||||
if (qualifier->coherent)
|
||||
need_space = append_with_space (printer, "coherent ", need_space);
|
||||
if (qualifier->readonly)
|
||||
need_space = append_with_space (printer, "readonly ", need_space);
|
||||
if (qualifier->writeonly)
|
||||
need_space = append_with_space (printer, "writeonly ", need_space);
|
||||
|
||||
if (gsk_sl_qualifier_has_layout (qualifier))
|
||||
{
|
||||
gboolean had_value;
|
||||
gsk_sl_printer_append (printer, "layout(");
|
||||
had_value = print_qualifier (printer, "set", qualifier->layout.set, FALSE);
|
||||
had_value = print_qualifier (printer, "binding", qualifier->layout.binding, had_value);
|
||||
had_value = print_qualifier (printer, "location", qualifier->layout.location, had_value);
|
||||
had_value = print_qualifier (printer, "component", qualifier->layout.component, had_value);
|
||||
if (qualifier->layout.push_constant)
|
||||
{
|
||||
if (had_value)
|
||||
gsk_sl_printer_append (printer, ", ");
|
||||
gsk_sl_printer_append (printer, "push_constant");
|
||||
}
|
||||
gsk_sl_printer_append (printer, ")");
|
||||
need_space = TRUE;
|
||||
}
|
||||
|
||||
need_space = append_with_space (printer, gsk_sl_interpolation_get_name (qualifier->interpolation), need_space);
|
||||
need_space = append_with_space (printer, gsk_sl_storage_get_name (qualifier->storage), need_space);
|
||||
|
||||
return need_space;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_qualifier_is_constant (const GskSlQualifier *qualifier)
|
||||
{
|
||||
switch (qualifier->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return TRUE;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GskSlQualifierLocation
|
||||
gsk_sl_qualifier_get_location (const GskSlQualifier *qualifier)
|
||||
{
|
||||
switch (qualifier->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return GSK_SL_QUALIFIER_GLOBAL;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
return GSK_SL_QUALIFIER_GLOBAL;
|
||||
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
return GSK_SL_QUALIFIER_LOCAL;
|
||||
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
return GSK_SL_QUALIFIER_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
GskSpvStorageClass
|
||||
gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier,
|
||||
const GskSlType *type)
|
||||
{
|
||||
switch (qualifier->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return GSK_SPV_STORAGE_CLASS_FUNCTION;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
return GSK_SPV_STORAGE_CLASS_PRIVATE;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
return GSK_SPV_STORAGE_CLASS_INPUT;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
return GSK_SPV_STORAGE_CLASS_OUTPUT;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
if (qualifier->layout.push_constant)
|
||||
return GSK_SPV_STORAGE_CLASS_PUSH_CONSTANT;
|
||||
else if (gsk_sl_type_contains_opaque (type))
|
||||
return GSK_SPV_STORAGE_CLASS_UNIFORM_CONSTANT;
|
||||
else
|
||||
return GSK_SPV_STORAGE_CLASS_UNIFORM;
|
||||
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
return GSK_SPV_STORAGE_CLASS_FUNCTION;
|
||||
}
|
||||
}
|
||||
|
||||
#define ERROR(...) G_STMT_START{\
|
||||
gsk_sl_preprocessor_error (preproc, DECLARATION, __VA_ARGS__); \
|
||||
result = FALSE; \
|
||||
}G_STMT_END
|
||||
|
||||
static gboolean
|
||||
gsk_sl_qualifier_check_type_for_input (const GskSlQualifier *qualifier,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlType *type)
|
||||
{
|
||||
gboolean result = TRUE;
|
||||
gsize i;
|
||||
|
||||
if (gsk_sl_type_is_struct (type) &&
|
||||
gsk_sl_preprocessor_is_stage (preproc, GSK_SL_SHADER_VERTEX))
|
||||
ERROR ("In variables in vertex shaders must not contain structs");
|
||||
if (gsk_sl_type_is_opaque (type) &&
|
||||
gsk_sl_preprocessor_is_stage (preproc, GSK_SL_SHADER_VERTEX))
|
||||
ERROR ("In variables must not contain opaque types");
|
||||
if (gsk_sl_type_get_scalar_type (type) == GSK_SL_BOOL)
|
||||
ERROR ("In variables must not contain boolean types");
|
||||
if (gsk_sl_type_get_scalar_type (type) != GSK_SL_FLOAT &&
|
||||
gsk_sl_preprocessor_is_stage (preproc, GSK_SL_SHADER_FRAGMENT) &&
|
||||
qualifier->interpolation != GSK_SL_INTERPOLATE_FLAT)
|
||||
ERROR ("Non-float in variables in fragment shader must be qualified as \"flat\".");
|
||||
|
||||
for (i = 0; i < gsk_sl_type_get_n_members (type); i++)
|
||||
{
|
||||
result &= gsk_sl_qualifier_check_type_for_input (qualifier,
|
||||
preproc,
|
||||
gsk_sl_type_get_member_type (type, i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_qualifier_check_type (const GskSlQualifier *qualifier,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlType *type)
|
||||
{
|
||||
switch (qualifier->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
return gsk_sl_qualifier_check_type_for_input (qualifier, preproc, type);
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_qualifier_write_inout_decorations (const GskSlQualifier *qualifier,
|
||||
GskSpvWriter *writer,
|
||||
guint32 value_id)
|
||||
{
|
||||
switch (qualifier->interpolation)
|
||||
{
|
||||
case GSK_SL_INTERPOLATE_FLAT:
|
||||
gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_FLAT, NULL, 0);
|
||||
break;
|
||||
|
||||
case GSK_SL_INTERPOLATE_NO_PERSPECTIVE:
|
||||
gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_NO_PERSPECTIVE, NULL, 0);
|
||||
break;
|
||||
|
||||
case GSK_SL_INTERPOLATE_DEFAULT:
|
||||
case GSK_SL_INTERPOLATE_SMOOTH:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (qualifier->layout.set >= 0)
|
||||
gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.set }, 1);
|
||||
if (qualifier->layout.binding >= 0)
|
||||
gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.binding }, 1);
|
||||
if (qualifier->layout.location >= 0)
|
||||
gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.location }, 1);
|
||||
if (qualifier->layout.component >= 0)
|
||||
gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.component }, 1);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_qualifier_write_spv_decorations (const GskSlQualifier *qualifier,
|
||||
GskSpvWriter *writer,
|
||||
guint32 value_id)
|
||||
{
|
||||
switch (qualifier->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
return;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
gsk_sl_qualifier_write_inout_decorations (qualifier, writer, value_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
87
gsk/gskslqualifierprivate.h
Normal file
87
gsk/gskslqualifierprivate.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_QUALIFIER_PRIVATE_H__
|
||||
#define __GSK_SL_QUALIFIER_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
#include "gskslqualifierprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_QUALIFIER_GLOBAL,
|
||||
GSK_SL_QUALIFIER_PARAMETER,
|
||||
GSK_SL_QUALIFIER_LOCAL
|
||||
} GskSlQualifierLocation;
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_INTERPOLATE_DEFAULT,
|
||||
GSK_SL_INTERPOLATE_SMOOTH,
|
||||
GSK_SL_INTERPOLATE_FLAT,
|
||||
GSK_SL_INTERPOLATE_NO_PERSPECTIVE
|
||||
} GskSlInterpolation;
|
||||
|
||||
struct _GskSlQualifier
|
||||
{
|
||||
GskSlStorage storage;
|
||||
GskSlInterpolation interpolation;
|
||||
|
||||
struct {
|
||||
gint set;
|
||||
gint binding;
|
||||
gint location;
|
||||
gint component;
|
||||
guint push_constant :1;
|
||||
} layout;
|
||||
|
||||
guint invariant :1;
|
||||
guint volatile_ :1;
|
||||
guint restrict_ :1;
|
||||
guint coherent :1;
|
||||
guint readonly :1;
|
||||
guint writeonly :1;
|
||||
};
|
||||
|
||||
void gsk_sl_qualifier_init (GskSlQualifier *qualifier);
|
||||
void gsk_sl_qualifier_parse (GskSlQualifier *qualifier,
|
||||
GskSlScope *scope,
|
||||
GskSlPreprocessor *stream,
|
||||
GskSlQualifierLocation location);
|
||||
|
||||
gboolean gsk_sl_qualifier_print (const GskSlQualifier *qualifier,
|
||||
GskSlPrinter *printer);
|
||||
|
||||
gboolean gsk_sl_qualifier_is_constant (const GskSlQualifier *qualifier);
|
||||
GskSlQualifierLocation gsk_sl_qualifier_get_location (const GskSlQualifier *qualifier);
|
||||
GskSpvStorageClass gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier,
|
||||
const GskSlType *type);
|
||||
|
||||
gboolean gsk_sl_qualifier_check_type (const GskSlQualifier *qualifier,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlType *type);
|
||||
void gsk_sl_qualifier_write_spv_decorations (const GskSlQualifier *qualifier,
|
||||
GskSpvWriter *writer,
|
||||
guint32 value_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_QUALIFIER_PRIVATE_H__ */
|
283
gsk/gskslscope.c
Normal file
283
gsk/gskslscope.c
Normal file
@@ -0,0 +1,283 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslscopeprivate.h"
|
||||
|
||||
#include "gskslfunctionprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslqualifierprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslvariableprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct _GskSlScope
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlScope *parent;
|
||||
GSList *children;
|
||||
GskSlType *return_type;
|
||||
|
||||
GHashTable *variables;
|
||||
GHashTable *functions;
|
||||
GHashTable *types;
|
||||
|
||||
guint can_break :1;
|
||||
guint can_continue :1;
|
||||
};
|
||||
|
||||
static void
|
||||
free_function_list (gpointer data)
|
||||
{
|
||||
g_list_free_full (data, (GDestroyNotify) gsk_sl_function_unref);
|
||||
}
|
||||
|
||||
GskSlScope *
|
||||
gsk_sl_scope_new (GskSlScope *parent,
|
||||
GskSlType *return_type)
|
||||
{
|
||||
if (parent)
|
||||
return gsk_sl_scope_new_full (parent, return_type, parent->can_break, parent->can_continue);
|
||||
else
|
||||
return gsk_sl_scope_new_full (parent, return_type, FALSE, FALSE);
|
||||
}
|
||||
|
||||
GskSlScope *
|
||||
gsk_sl_scope_new_full (GskSlScope *parent,
|
||||
GskSlType *return_type,
|
||||
gboolean can_break,
|
||||
gboolean can_continue)
|
||||
{
|
||||
GskSlScope *scope;
|
||||
|
||||
scope = g_slice_new0 (GskSlScope);
|
||||
scope->ref_count = 1;
|
||||
|
||||
if (parent)
|
||||
{
|
||||
scope->parent = parent;
|
||||
parent->children = g_slist_prepend (parent->children, scope);
|
||||
}
|
||||
if (return_type)
|
||||
scope->return_type = gsk_sl_type_ref (return_type);
|
||||
scope->can_break = can_break;
|
||||
scope->can_continue = can_continue;
|
||||
scope->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gsk_sl_variable_unref);
|
||||
scope->functions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) free_function_list);
|
||||
scope->types = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gsk_sl_type_unref);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
GskSlScope *
|
||||
gsk_sl_scope_ref (GskSlScope *scope)
|
||||
{
|
||||
g_return_val_if_fail (scope != NULL, NULL);
|
||||
|
||||
scope->ref_count += 1;
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_scope_unref (GskSlScope *scope)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (scope == NULL)
|
||||
return;
|
||||
|
||||
scope->ref_count -= 1;
|
||||
if (scope->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_hash_table_unref (scope->variables);
|
||||
g_hash_table_unref (scope->functions);
|
||||
g_hash_table_unref (scope->types);
|
||||
|
||||
if (scope->parent)
|
||||
scope->parent->children = g_slist_remove (scope->parent->children, scope);
|
||||
for (l = scope->children; l; l = l->next)
|
||||
((GskSlScope *) l->data)->parent = NULL;
|
||||
g_slist_free (scope->children);
|
||||
if (scope->return_type)
|
||||
gsk_sl_type_unref (scope->return_type);
|
||||
|
||||
g_slice_free (GskSlScope, scope);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_scope_get_return_type (const GskSlScope *scope)
|
||||
{
|
||||
return scope->return_type;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_scope_can_break (const GskSlScope *scope)
|
||||
{
|
||||
return scope->can_break;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_scope_can_continue (const GskSlScope *scope)
|
||||
{
|
||||
return scope->can_continue;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_scope_is_global (const GskSlScope *scope)
|
||||
{
|
||||
return scope->parent == NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_scope_add_variable (GskSlScope *scope,
|
||||
GskSlVariable *variable)
|
||||
{
|
||||
g_hash_table_replace (scope->variables, (gpointer) gsk_sl_variable_get_name (variable), gsk_sl_variable_ref (variable));
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_scope_describe_variable (GskSlVariable *variable)
|
||||
{
|
||||
switch (gsk_sl_qualifier_get_location (gsk_sl_variable_get_qualifier (variable)))
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GSK_SL_QUALIFIER_GLOBAL:
|
||||
return "global variable";
|
||||
case GSK_SL_QUALIFIER_PARAMETER:
|
||||
return "function parameter";
|
||||
case GSK_SL_QUALIFIER_LOCAL:
|
||||
return "local variable";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_scope_try_add_variable (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlVariable *variable)
|
||||
{
|
||||
GskSlVariable *shadow;
|
||||
|
||||
/* only look in current scope for error */
|
||||
shadow = g_hash_table_lookup (scope->variables, gsk_sl_variable_get_name (variable));
|
||||
if (shadow)
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, DECLARATION,
|
||||
"Redefinition of %s \"%s\".",
|
||||
gsk_sl_scope_describe_variable (shadow),
|
||||
gsk_sl_variable_get_name (variable));
|
||||
return;
|
||||
}
|
||||
|
||||
if (scope->parent)
|
||||
{
|
||||
shadow = gsk_sl_scope_lookup_variable (scope->parent, gsk_sl_variable_get_name (variable));
|
||||
if (shadow)
|
||||
{
|
||||
gsk_sl_preprocessor_warn (preproc, SHADOW,
|
||||
"Name \"%s\" shadows %s of same name.",
|
||||
gsk_sl_variable_get_name (variable),
|
||||
gsk_sl_scope_describe_variable (shadow));
|
||||
}
|
||||
}
|
||||
|
||||
gsk_sl_scope_add_variable (scope, variable);
|
||||
}
|
||||
|
||||
GskSlVariable *
|
||||
gsk_sl_scope_lookup_variable (GskSlScope *scope,
|
||||
const char *name)
|
||||
{
|
||||
GskSlVariable *result;
|
||||
|
||||
for (;
|
||||
scope != NULL;
|
||||
scope = scope->parent)
|
||||
{
|
||||
result = g_hash_table_lookup (scope->variables, name);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_scope_add_function (GskSlScope *scope,
|
||||
GskSlFunction *function)
|
||||
{
|
||||
GList *functions;
|
||||
const char *name;
|
||||
|
||||
name = gsk_sl_function_get_name (function);
|
||||
|
||||
functions = g_hash_table_lookup (scope->functions, name);
|
||||
gsk_sl_function_ref (function);
|
||||
if (functions)
|
||||
functions = g_list_append (functions, function);
|
||||
else
|
||||
g_hash_table_insert (scope->functions, (gpointer) name, g_list_prepend (NULL, function));
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_scope_match_function (GskSlScope *scope,
|
||||
GskSlFunctionMatcher *matcher,
|
||||
const char *name)
|
||||
{
|
||||
GList *result = NULL, *lookup;
|
||||
|
||||
for (;
|
||||
scope != NULL;
|
||||
scope = scope->parent)
|
||||
{
|
||||
lookup = g_hash_table_lookup (scope->functions, name);
|
||||
result = g_list_concat (result, g_list_copy (lookup));
|
||||
}
|
||||
|
||||
gsk_sl_function_matcher_init (matcher, result);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_scope_add_type (GskSlScope *scope,
|
||||
GskSlType *type)
|
||||
{
|
||||
g_hash_table_replace (scope->types, (gpointer) gsk_sl_type_get_name (type), gsk_sl_type_ref (type));
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_scope_lookup_type (GskSlScope *scope,
|
||||
const char *name)
|
||||
{
|
||||
GskSlType *result;
|
||||
|
||||
for (;
|
||||
scope != NULL;
|
||||
scope = scope->parent)
|
||||
{
|
||||
result = g_hash_table_lookup (scope->types, name);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
62
gsk/gskslscopeprivate.h
Normal file
62
gsk/gskslscopeprivate.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_SCOPE_PRIVATE_H__
|
||||
#define __GSK_SL_SCOPE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlScope * gsk_sl_scope_new (GskSlScope *parent,
|
||||
GskSlType *return_type);
|
||||
GskSlScope * gsk_sl_scope_new_full (GskSlScope *parent,
|
||||
GskSlType *return_type,
|
||||
gboolean can_break,
|
||||
gboolean can_continue);
|
||||
|
||||
GskSlScope * gsk_sl_scope_ref (GskSlScope *scope);
|
||||
void gsk_sl_scope_unref (GskSlScope *scope);
|
||||
|
||||
GskSlType * gsk_sl_scope_get_return_type (const GskSlScope *scope);
|
||||
gboolean gsk_sl_scope_can_break (const GskSlScope *scope);
|
||||
gboolean gsk_sl_scope_can_continue (const GskSlScope *scope);
|
||||
gboolean gsk_sl_scope_is_global (const GskSlScope *scope);
|
||||
|
||||
void gsk_sl_scope_add_variable (GskSlScope *scope,
|
||||
GskSlVariable *variable);
|
||||
void gsk_sl_scope_try_add_variable (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
GskSlVariable *variable);
|
||||
GskSlVariable * gsk_sl_scope_lookup_variable (GskSlScope *scope,
|
||||
const char *name);
|
||||
void gsk_sl_scope_add_function (GskSlScope *scope,
|
||||
GskSlFunction *function);
|
||||
void gsk_sl_scope_match_function (GskSlScope *scope,
|
||||
GskSlFunctionMatcher *matcher,
|
||||
const char *name);
|
||||
void gsk_sl_scope_add_type (GskSlScope *scope,
|
||||
GskSlType *type);
|
||||
GskSlType * gsk_sl_scope_lookup_type (GskSlScope *scope,
|
||||
const char *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_SCOPE_PRIVATE_H__ */
|
1675
gsk/gskslstatement.c
Normal file
1675
gsk/gskslstatement.c
Normal file
File diff suppressed because it is too large
Load Diff
56
gsk/gskslstatementprivate.h
Normal file
56
gsk/gskslstatementprivate.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_STATEMENT_PRIVATE_H__
|
||||
#define __GSK_SL_STATEMENT_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsk/gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_JUMP_NONE,
|
||||
GSK_SL_JUMP_BREAK,
|
||||
GSK_SL_JUMP_CONTINUE,
|
||||
GSK_SL_JUMP_RETURN,
|
||||
GSK_SL_JUMP_DISCARD
|
||||
} GskSlJump;
|
||||
|
||||
GskSlStatement * gsk_sl_statement_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
gboolean parse_everything);
|
||||
GskSlStatement * gsk_sl_statement_parse_compound (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc,
|
||||
gboolean new_scope);
|
||||
|
||||
GskSlStatement * gsk_sl_statement_ref (GskSlStatement *statement);
|
||||
void gsk_sl_statement_unref (GskSlStatement *statement);
|
||||
|
||||
void gsk_sl_statement_print (const GskSlStatement *statement,
|
||||
GskSlPrinter *printer);
|
||||
|
||||
GskSlJump gsk_sl_statement_get_jump (const GskSlStatement *statement);
|
||||
|
||||
gboolean gsk_sl_statement_write_spv (const GskSlStatement *statement,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_STATEMENT_PRIVATE_H__ */
|
2197
gsk/gsksltokenizer.c
Normal file
2197
gsk/gsksltokenizer.c
Normal file
File diff suppressed because it is too large
Load Diff
302
gsk/gsksltokenizerprivate.h
Normal file
302
gsk/gsksltokenizerprivate.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_TOKENIZER_PRIVATE_H__
|
||||
#define __GSK_SL_TOKENIZER_PRIVATE_H__
|
||||
|
||||
#include <gsktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_TOKEN_EOF = 0,
|
||||
GSK_SL_TOKEN_ERROR,
|
||||
GSK_SL_TOKEN_NEWLINE,
|
||||
GSK_SL_TOKEN_WHITESPACE,
|
||||
GSK_SL_TOKEN_COMMENT,
|
||||
GSK_SL_TOKEN_SINGLE_LINE_COMMENT,
|
||||
GSK_SL_TOKEN_STRING,
|
||||
/* real tokens */
|
||||
GSK_SL_TOKEN_CONST,
|
||||
GSK_SL_TOKEN_BOOL,
|
||||
GSK_SL_TOKEN_FLOAT,
|
||||
GSK_SL_TOKEN_DOUBLE,
|
||||
GSK_SL_TOKEN_INT,
|
||||
GSK_SL_TOKEN_UINT,
|
||||
GSK_SL_TOKEN_BREAK,
|
||||
GSK_SL_TOKEN_CONTINUE,
|
||||
GSK_SL_TOKEN_DO,
|
||||
GSK_SL_TOKEN_ELSE,
|
||||
GSK_SL_TOKEN_FOR,
|
||||
GSK_SL_TOKEN_IF,
|
||||
GSK_SL_TOKEN_DISCARD,
|
||||
GSK_SL_TOKEN_RETURN,
|
||||
GSK_SL_TOKEN_SWITCH,
|
||||
GSK_SL_TOKEN_CASE,
|
||||
GSK_SL_TOKEN_DEFAULT,
|
||||
GSK_SL_TOKEN_SUBROUTINE,
|
||||
GSK_SL_TOKEN_BVEC2,
|
||||
GSK_SL_TOKEN_BVEC3,
|
||||
GSK_SL_TOKEN_BVEC4,
|
||||
GSK_SL_TOKEN_IVEC2,
|
||||
GSK_SL_TOKEN_IVEC3,
|
||||
GSK_SL_TOKEN_IVEC4,
|
||||
GSK_SL_TOKEN_UVEC2,
|
||||
GSK_SL_TOKEN_UVEC3,
|
||||
GSK_SL_TOKEN_UVEC4,
|
||||
GSK_SL_TOKEN_VEC2,
|
||||
GSK_SL_TOKEN_VEC3,
|
||||
GSK_SL_TOKEN_VEC4,
|
||||
GSK_SL_TOKEN_MAT2,
|
||||
GSK_SL_TOKEN_MAT3,
|
||||
GSK_SL_TOKEN_MAT4,
|
||||
GSK_SL_TOKEN_CENTROID,
|
||||
GSK_SL_TOKEN_IN,
|
||||
GSK_SL_TOKEN_OUT,
|
||||
GSK_SL_TOKEN_INOUT,
|
||||
GSK_SL_TOKEN_UNIFORM,
|
||||
GSK_SL_TOKEN_PATCH,
|
||||
GSK_SL_TOKEN_SAMPLE,
|
||||
GSK_SL_TOKEN_BUFFER,
|
||||
GSK_SL_TOKEN_SHARED,
|
||||
GSK_SL_TOKEN_COHERENT,
|
||||
GSK_SL_TOKEN_VOLATILE,
|
||||
GSK_SL_TOKEN_RESTRICT,
|
||||
GSK_SL_TOKEN_READONLY,
|
||||
GSK_SL_TOKEN_WRITEONLY,
|
||||
GSK_SL_TOKEN_DVEC2,
|
||||
GSK_SL_TOKEN_DVEC3,
|
||||
GSK_SL_TOKEN_DVEC4,
|
||||
GSK_SL_TOKEN_DMAT2,
|
||||
GSK_SL_TOKEN_DMAT3,
|
||||
GSK_SL_TOKEN_DMAT4,
|
||||
GSK_SL_TOKEN_NOPERSPECTIVE,
|
||||
GSK_SL_TOKEN_FLAT,
|
||||
GSK_SL_TOKEN_SMOOTH,
|
||||
GSK_SL_TOKEN_LAYOUT,
|
||||
GSK_SL_TOKEN_MAT2X2,
|
||||
GSK_SL_TOKEN_MAT2X3,
|
||||
GSK_SL_TOKEN_MAT2X4,
|
||||
GSK_SL_TOKEN_MAT3X2,
|
||||
GSK_SL_TOKEN_MAT3X3,
|
||||
GSK_SL_TOKEN_MAT3X4,
|
||||
GSK_SL_TOKEN_MAT4X2,
|
||||
GSK_SL_TOKEN_MAT4X3,
|
||||
GSK_SL_TOKEN_MAT4X4,
|
||||
GSK_SL_TOKEN_DMAT2X2,
|
||||
GSK_SL_TOKEN_DMAT2X3,
|
||||
GSK_SL_TOKEN_DMAT2X4,
|
||||
GSK_SL_TOKEN_DMAT3X2,
|
||||
GSK_SL_TOKEN_DMAT3X3,
|
||||
GSK_SL_TOKEN_DMAT3X4,
|
||||
GSK_SL_TOKEN_DMAT4X2,
|
||||
GSK_SL_TOKEN_DMAT4X3,
|
||||
GSK_SL_TOKEN_DMAT4X4,
|
||||
GSK_SL_TOKEN_ATOMIC_UINT,
|
||||
GSK_SL_TOKEN_SAMPLER1D,
|
||||
GSK_SL_TOKEN_SAMPLER2D,
|
||||
GSK_SL_TOKEN_SAMPLER3D,
|
||||
GSK_SL_TOKEN_SAMPLERCUBE,
|
||||
GSK_SL_TOKEN_SAMPLER1DSHADOW,
|
||||
GSK_SL_TOKEN_SAMPLER2DSHADOW,
|
||||
GSK_SL_TOKEN_SAMPLERCUBESHADOW,
|
||||
GSK_SL_TOKEN_SAMPLER1DARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER2DARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER1DARRAYSHADOW,
|
||||
GSK_SL_TOKEN_SAMPLER2DARRAYSHADOW,
|
||||
GSK_SL_TOKEN_ISAMPLER1D,
|
||||
GSK_SL_TOKEN_ISAMPLER2D,
|
||||
GSK_SL_TOKEN_ISAMPLER3D,
|
||||
GSK_SL_TOKEN_ISAMPLERCUBE,
|
||||
GSK_SL_TOKEN_ISAMPLER1DARRAY,
|
||||
GSK_SL_TOKEN_ISAMPLER2DARRAY,
|
||||
GSK_SL_TOKEN_USAMPLER1D,
|
||||
GSK_SL_TOKEN_USAMPLER2D,
|
||||
GSK_SL_TOKEN_USAMPLER3D,
|
||||
GSK_SL_TOKEN_USAMPLERCUBE,
|
||||
GSK_SL_TOKEN_USAMPLER1DARRAY,
|
||||
GSK_SL_TOKEN_USAMPLER2DARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER2DRECT,
|
||||
GSK_SL_TOKEN_SAMPLER2DRECTSHADOW,
|
||||
GSK_SL_TOKEN_ISAMPLER2DRECT,
|
||||
GSK_SL_TOKEN_USAMPLER2DRECT,
|
||||
GSK_SL_TOKEN_SAMPLERBUFFER,
|
||||
GSK_SL_TOKEN_ISAMPLERBUFFER,
|
||||
GSK_SL_TOKEN_USAMPLERBUFFER,
|
||||
GSK_SL_TOKEN_SAMPLERCUBEARRAY,
|
||||
GSK_SL_TOKEN_SAMPLERCUBEARRAYSHADOW,
|
||||
GSK_SL_TOKEN_ISAMPLERCUBEARRAY,
|
||||
GSK_SL_TOKEN_USAMPLERCUBEARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER2DMS,
|
||||
GSK_SL_TOKEN_ISAMPLER2DMS,
|
||||
GSK_SL_TOKEN_USAMPLER2DMS,
|
||||
GSK_SL_TOKEN_SAMPLER2DMSARRAY,
|
||||
GSK_SL_TOKEN_ISAMPLER2DMSARRAY,
|
||||
GSK_SL_TOKEN_USAMPLER2DMSARRAY,
|
||||
GSK_SL_TOKEN_IMAGE1D,
|
||||
GSK_SL_TOKEN_IIMAGE1D,
|
||||
GSK_SL_TOKEN_UIMAGE1D,
|
||||
GSK_SL_TOKEN_IMAGE2D,
|
||||
GSK_SL_TOKEN_IIMAGE2D,
|
||||
GSK_SL_TOKEN_UIMAGE2D,
|
||||
GSK_SL_TOKEN_IMAGE3D,
|
||||
GSK_SL_TOKEN_IIMAGE3D,
|
||||
GSK_SL_TOKEN_UIMAGE3D,
|
||||
GSK_SL_TOKEN_IMAGE2DRECT,
|
||||
GSK_SL_TOKEN_IIMAGE2DRECT,
|
||||
GSK_SL_TOKEN_UIMAGE2DRECT,
|
||||
GSK_SL_TOKEN_IMAGECUBE,
|
||||
GSK_SL_TOKEN_IIMAGECUBE,
|
||||
GSK_SL_TOKEN_UIMAGECUBE,
|
||||
GSK_SL_TOKEN_IMAGEBUFFER,
|
||||
GSK_SL_TOKEN_IIMAGEBUFFER,
|
||||
GSK_SL_TOKEN_UIMAGEBUFFER,
|
||||
GSK_SL_TOKEN_IMAGE1DARRAY,
|
||||
GSK_SL_TOKEN_IIMAGE1DARRAY,
|
||||
GSK_SL_TOKEN_UIMAGE1DARRAY,
|
||||
GSK_SL_TOKEN_IMAGE2DARRAY,
|
||||
GSK_SL_TOKEN_IIMAGE2DARRAY,
|
||||
GSK_SL_TOKEN_UIMAGE2DARRAY,
|
||||
GSK_SL_TOKEN_IMAGECUBEARRAY,
|
||||
GSK_SL_TOKEN_IIMAGECUBEARRAY,
|
||||
GSK_SL_TOKEN_UIMAGECUBEARRAY,
|
||||
GSK_SL_TOKEN_IMAGE2DMS,
|
||||
GSK_SL_TOKEN_IIMAGE2DMS,
|
||||
GSK_SL_TOKEN_UIMAGE2DMS,
|
||||
GSK_SL_TOKEN_IMAGE2DMSARRAY,
|
||||
GSK_SL_TOKEN_IIMAGE2DMSARRAY,
|
||||
GSK_SL_TOKEN_UIMAGE2DMSARRAY,
|
||||
GSK_SL_TOKEN_STRUCT,
|
||||
GSK_SL_TOKEN_VOID,
|
||||
GSK_SL_TOKEN_WHILE,
|
||||
GSK_SL_TOKEN_IDENTIFIER,
|
||||
GSK_SL_TOKEN_FLOATCONSTANT,
|
||||
GSK_SL_TOKEN_DOUBLECONSTANT,
|
||||
GSK_SL_TOKEN_INTCONSTANT,
|
||||
GSK_SL_TOKEN_UINTCONSTANT,
|
||||
GSK_SL_TOKEN_BOOLCONSTANT,
|
||||
GSK_SL_TOKEN_LEFT_OP,
|
||||
GSK_SL_TOKEN_RIGHT_OP,
|
||||
GSK_SL_TOKEN_INC_OP,
|
||||
GSK_SL_TOKEN_DEC_OP,
|
||||
GSK_SL_TOKEN_LE_OP,
|
||||
GSK_SL_TOKEN_GE_OP,
|
||||
GSK_SL_TOKEN_EQ_OP,
|
||||
GSK_SL_TOKEN_NE_OP,
|
||||
GSK_SL_TOKEN_AND_OP,
|
||||
GSK_SL_TOKEN_OR_OP,
|
||||
GSK_SL_TOKEN_XOR_OP,
|
||||
GSK_SL_TOKEN_MUL_ASSIGN,
|
||||
GSK_SL_TOKEN_DIV_ASSIGN,
|
||||
GSK_SL_TOKEN_ADD_ASSIGN,
|
||||
GSK_SL_TOKEN_MOD_ASSIGN,
|
||||
GSK_SL_TOKEN_LEFT_ASSIGN,
|
||||
GSK_SL_TOKEN_RIGHT_ASSIGN,
|
||||
GSK_SL_TOKEN_AND_ASSIGN,
|
||||
GSK_SL_TOKEN_XOR_ASSIGN,
|
||||
GSK_SL_TOKEN_OR_ASSIGN,
|
||||
GSK_SL_TOKEN_SUB_ASSIGN,
|
||||
GSK_SL_TOKEN_LEFT_PAREN,
|
||||
GSK_SL_TOKEN_RIGHT_PAREN,
|
||||
GSK_SL_TOKEN_LEFT_BRACKET,
|
||||
GSK_SL_TOKEN_RIGHT_BRACKET,
|
||||
GSK_SL_TOKEN_LEFT_BRACE,
|
||||
GSK_SL_TOKEN_RIGHT_BRACE,
|
||||
GSK_SL_TOKEN_DOT,
|
||||
GSK_SL_TOKEN_COMMA,
|
||||
GSK_SL_TOKEN_COLON,
|
||||
GSK_SL_TOKEN_EQUAL,
|
||||
GSK_SL_TOKEN_SEMICOLON,
|
||||
GSK_SL_TOKEN_BANG,
|
||||
GSK_SL_TOKEN_DASH,
|
||||
GSK_SL_TOKEN_TILDE,
|
||||
GSK_SL_TOKEN_PLUS,
|
||||
GSK_SL_TOKEN_STAR,
|
||||
GSK_SL_TOKEN_SLASH,
|
||||
GSK_SL_TOKEN_PERCENT,
|
||||
GSK_SL_TOKEN_LEFT_ANGLE,
|
||||
GSK_SL_TOKEN_RIGHT_ANGLE,
|
||||
GSK_SL_TOKEN_VERTICAL_BAR,
|
||||
GSK_SL_TOKEN_CARET,
|
||||
GSK_SL_TOKEN_AMPERSAND,
|
||||
GSK_SL_TOKEN_QUESTION,
|
||||
GSK_SL_TOKEN_HASH,
|
||||
GSK_SL_TOKEN_INVARIANT,
|
||||
GSK_SL_TOKEN_PRECISE,
|
||||
GSK_SL_TOKEN_HIGH_PRECISION,
|
||||
GSK_SL_TOKEN_MEDIUM_PRECISION,
|
||||
GSK_SL_TOKEN_LOW_PRECISION,
|
||||
GSK_SL_TOKEN_PRECISION
|
||||
} GskSlTokenType;
|
||||
|
||||
typedef struct _GskSlToken GskSlToken;
|
||||
typedef struct _GskSlTokenizer GskSlTokenizer;
|
||||
|
||||
typedef void (* GskSlTokenizerErrorFunc) (GskSlTokenizer *parser,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token,
|
||||
const GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
struct _GskSlToken {
|
||||
GskSlTokenType type;
|
||||
union {
|
||||
gint32 i32;
|
||||
guint32 u32;
|
||||
float f;
|
||||
double d;
|
||||
gboolean b;
|
||||
char *str;
|
||||
};
|
||||
};
|
||||
|
||||
void gsk_sl_token_clear (GskSlToken *token);
|
||||
void gsk_sl_token_copy (GskSlToken *dest,
|
||||
const GskSlToken *src);
|
||||
|
||||
gboolean gsk_sl_string_is_valid_identifier (const char *ident);
|
||||
void gsk_sl_token_init_from_identifier (GskSlToken *token,
|
||||
const char *ident);
|
||||
|
||||
gboolean gsk_sl_token_is_skipped (const GskSlToken *token);
|
||||
#define gsk_sl_token_is(token, _type) ((token)->type == (_type))
|
||||
gboolean gsk_sl_token_is_ident (const GskSlToken *token,
|
||||
const char *ident);
|
||||
gboolean gsk_sl_token_is_function (const GskSlToken *token,
|
||||
const char *ident);
|
||||
|
||||
void gsk_sl_token_print (const GskSlToken *token,
|
||||
GString *string);
|
||||
char * gsk_sl_token_to_string (const GskSlToken *token);
|
||||
|
||||
GskSlTokenizer * gsk_sl_tokenizer_new (GskCodeSource *source,
|
||||
GskSlTokenizerErrorFunc func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy);
|
||||
|
||||
GskSlTokenizer * gsk_sl_tokenizer_ref (GskSlTokenizer *tokenizer);
|
||||
void gsk_sl_tokenizer_unref (GskSlTokenizer *tokenizer);
|
||||
|
||||
const GskCodeLocation * gsk_sl_tokenizer_get_location (GskSlTokenizer *tokenizer);
|
||||
|
||||
void gsk_sl_tokenizer_read_token (GskSlTokenizer *tokenizer,
|
||||
GskSlToken *token);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_TOKENIZER_PRIVATE_H__ */
|
3093
gsk/gsksltype.c
Normal file
3093
gsk/gsksltype.c
Normal file
File diff suppressed because it is too large
Load Diff
128
gsk/gsksltypeprivate.h
Normal file
128
gsk/gsksltypeprivate.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_TYPE_PRIVATE_H__
|
||||
#define __GSK_SL_TYPE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
#include "gskspvenumsprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskSlTypeBuilder GskSlTypeBuilder;
|
||||
|
||||
gsize gsk_sl_scalar_type_get_size (GskSlScalarType type);
|
||||
|
||||
GskSlType * gsk_sl_type_new_array (GskSlType *type,
|
||||
gsize length);
|
||||
GskSlType * gsk_sl_type_new_parse (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc);
|
||||
GskSlType * gsk_sl_type_parse_array (GskSlType *type,
|
||||
GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc);
|
||||
|
||||
GskSlType * gsk_sl_type_get_void (void);
|
||||
GskSlType * gsk_sl_type_get_scalar (GskSlScalarType scalar);
|
||||
GskSlType * gsk_sl_type_get_vector (GskSlScalarType scalar,
|
||||
guint length);
|
||||
GskSlType * gsk_sl_type_get_matrix (GskSlScalarType scalar,
|
||||
guint columns,
|
||||
guint rows);
|
||||
GskSlType * gsk_sl_type_get_sampler (GskSlSamplerType sampler);
|
||||
GskSlType * gsk_sl_type_get_matching (GskSlType *type,
|
||||
GskSlScalarType scalar);
|
||||
|
||||
GskSlType * gsk_sl_type_ref (GskSlType *type);
|
||||
void gsk_sl_type_unref (GskSlType *type);
|
||||
|
||||
gboolean gsk_sl_type_is_void (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_scalar (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_vector (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_matrix (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_basic (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_array (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_struct (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_block (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_sampler (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_opaque (const GskSlType *type);
|
||||
gboolean gsk_sl_type_contains_opaque (const GskSlType *type);
|
||||
|
||||
const char * gsk_sl_type_get_name (const GskSlType *type);
|
||||
GskSlScalarType gsk_sl_type_get_scalar_type (const GskSlType *type);
|
||||
const GskSlImageType * gsk_sl_type_get_image_type (const GskSlType *type);
|
||||
GskSlType * gsk_sl_type_get_index_type (const GskSlType *type);
|
||||
gsize gsk_sl_type_get_index_stride (const GskSlType *type);
|
||||
guint gsk_sl_type_get_length (const GskSlType *type);
|
||||
gsize gsk_sl_type_get_size (const GskSlType *type);
|
||||
gsize gsk_sl_type_get_n_components (const GskSlType *type);
|
||||
guint gsk_sl_type_get_n_members (const GskSlType *type);
|
||||
GskSlType * gsk_sl_type_get_member_type (const GskSlType *type,
|
||||
guint n);
|
||||
const char * gsk_sl_type_get_member_name (const GskSlType *type,
|
||||
guint n);
|
||||
gsize gsk_sl_type_get_member_offset (const GskSlType *type,
|
||||
guint n);
|
||||
gboolean gsk_sl_type_find_member (const GskSlType *type,
|
||||
const char *name,
|
||||
guint *out_index,
|
||||
GskSlType **out_type,
|
||||
gsize *out_offset);
|
||||
gboolean gsk_sl_scalar_type_can_convert (GskSlScalarType target,
|
||||
GskSlScalarType source);
|
||||
gboolean gsk_sl_type_can_convert (const GskSlType *target,
|
||||
const GskSlType *source);
|
||||
|
||||
gboolean gsk_sl_type_equal (gconstpointer a,
|
||||
gconstpointer b);
|
||||
guint gsk_sl_type_hash (gconstpointer type);
|
||||
|
||||
guint32 gsk_sl_type_write_spv (GskSlType *type,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
void gsk_sl_type_print_value (const GskSlType *type,
|
||||
GskSlPrinter *printer,
|
||||
gconstpointer value);
|
||||
gboolean gsk_sl_type_value_equal (const GskSlType *type,
|
||||
gconstpointer a,
|
||||
gconstpointer b);
|
||||
guint32 gsk_sl_type_write_value_spv (GskSlType *type,
|
||||
GskSpvWriter *writer,
|
||||
gconstpointer value);
|
||||
void gsk_sl_scalar_type_convert_value (GskSlScalarType target_type,
|
||||
gpointer target_value,
|
||||
GskSlScalarType source_type,
|
||||
gconstpointer source_value);
|
||||
|
||||
GskSlTypeBuilder * gsk_sl_type_builder_new_struct (const char *name);
|
||||
GskSlTypeBuilder * gsk_sl_type_builder_new_block (const char *name);
|
||||
GskSlType * gsk_sl_type_builder_free (GskSlTypeBuilder *builder);
|
||||
void gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder,
|
||||
GskSlType *type,
|
||||
const char *name);
|
||||
void gsk_sl_type_builder_add_builtin_member (GskSlTypeBuilder *builder,
|
||||
GskSlType *type,
|
||||
const char *name,
|
||||
GskSpvBuiltIn builtin);
|
||||
gboolean gsk_sl_type_builder_has_member (GskSlTypeBuilder *builder,
|
||||
const char *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_TYPE_PRIVATE_H__ */
|
118
gsk/gsksltypesprivate.h
Normal file
118
gsk/gsksltypesprivate.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/* GSK - The GTK Scene Kit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_TYPES_H__
|
||||
#define __GSK_SL_TYPES_H__
|
||||
|
||||
#include <gsk/gsktypes.h>
|
||||
|
||||
typedef struct _GskSlDeclaration GskSlDeclaration;
|
||||
typedef struct _GskSlEnvironment GskSlEnvironment;
|
||||
typedef struct _GskSlExpression GskSlExpression;
|
||||
typedef struct _GskSlFunction GskSlFunction;
|
||||
typedef struct _GskSlFunctionMatcher GskSlFunctionMatcher;
|
||||
typedef struct _GskSlFunctionType GskSlFunctionType;
|
||||
typedef struct _GskSlImageType GskSlImageType;
|
||||
typedef struct _GskSlNativeFunction GskSlNativeFunction;
|
||||
typedef struct _GskSlPreprocessor GskSlPreprocessor;
|
||||
typedef struct _GskSlPointerType GskSlPointerType;
|
||||
typedef struct _GskSlPrinter GskSlPrinter;
|
||||
typedef struct _GskSlQualifier GskSlQualifier;
|
||||
typedef struct _GskSlScope GskSlScope;
|
||||
typedef struct _GskSlStatement GskSlStatement;
|
||||
typedef struct _GskSlToken GskSlToken;
|
||||
typedef struct _GskSlType GskSlType;
|
||||
typedef struct _GskSlValue GskSlValue;
|
||||
typedef struct _GskSlVariable GskSlVariable;
|
||||
|
||||
typedef struct _GskSpvAccessChain GskSpvAccessChain;
|
||||
typedef struct _GskSpvWriter GskSpvWriter;
|
||||
typedef void (* GskSpvWriterFunc) (GskSpvWriter *, gpointer);
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_VOID,
|
||||
GSK_SL_FLOAT,
|
||||
GSK_SL_DOUBLE,
|
||||
GSK_SL_INT,
|
||||
GSK_SL_UINT,
|
||||
GSK_SL_BOOL
|
||||
} GskSlScalarType;
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_SAMPLER_1D,
|
||||
GSK_SL_SAMPLER_1D_INT,
|
||||
GSK_SL_SAMPLER_1D_UINT,
|
||||
GSK_SL_SAMPLER_1D_SHADOW,
|
||||
GSK_SL_SAMPLER_2D,
|
||||
GSK_SL_SAMPLER_2D_INT,
|
||||
GSK_SL_SAMPLER_2D_UINT,
|
||||
GSK_SL_SAMPLER_2D_SHADOW,
|
||||
GSK_SL_SAMPLER_3D,
|
||||
GSK_SL_SAMPLER_3D_INT,
|
||||
GSK_SL_SAMPLER_3D_UINT,
|
||||
GSK_SL_SAMPLER_CUBE,
|
||||
GSK_SL_SAMPLER_CUBE_INT,
|
||||
GSK_SL_SAMPLER_CUBE_UINT,
|
||||
GSK_SL_SAMPLER_CUBE_SHADOW,
|
||||
GSK_SL_SAMPLER_2D_RECT,
|
||||
GSK_SL_SAMPLER_2D_RECT_INT,
|
||||
GSK_SL_SAMPLER_2D_RECT_UINT,
|
||||
GSK_SL_SAMPLER_2D_RECT_SHADOW,
|
||||
GSK_SL_SAMPLER_1D_ARRAY,
|
||||
GSK_SL_SAMPLER_1D_ARRAY_INT,
|
||||
GSK_SL_SAMPLER_1D_ARRAY_UINT,
|
||||
GSK_SL_SAMPLER_1D_ARRAY_SHADOW,
|
||||
GSK_SL_SAMPLER_2D_ARRAY,
|
||||
GSK_SL_SAMPLER_2D_ARRAY_INT,
|
||||
GSK_SL_SAMPLER_2D_ARRAY_UINT,
|
||||
GSK_SL_SAMPLER_2D_ARRAY_SHADOW,
|
||||
GSK_SL_SAMPLER_CUBE_ARRAY,
|
||||
GSK_SL_SAMPLER_CUBE_ARRAY_INT,
|
||||
GSK_SL_SAMPLER_CUBE_ARRAY_UINT,
|
||||
GSK_SL_SAMPLER_CUBE_ARRAY_SHADOW,
|
||||
GSK_SL_SAMPLER_BUFFER,
|
||||
GSK_SL_SAMPLER_BUFFER_INT,
|
||||
GSK_SL_SAMPLER_BUFFER_UINT,
|
||||
GSK_SL_SAMPLER_2DMS,
|
||||
GSK_SL_SAMPLER_2DMS_INT,
|
||||
GSK_SL_SAMPLER_2DMS_UINT,
|
||||
GSK_SL_SAMPLER_2DMS_ARRAY,
|
||||
GSK_SL_SAMPLER_2DMS_ARRAY_INT,
|
||||
GSK_SL_SAMPLER_2DMS_ARRAY_UINT,
|
||||
GSK_SL_N_SAMPLER_TYPES
|
||||
} GskSlSamplerType;
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_STORAGE_DEFAULT,
|
||||
|
||||
GSK_SL_STORAGE_GLOBAL,
|
||||
GSK_SL_STORAGE_GLOBAL_CONST,
|
||||
GSK_SL_STORAGE_GLOBAL_IN,
|
||||
GSK_SL_STORAGE_GLOBAL_OUT,
|
||||
GSK_SL_STORAGE_GLOBAL_UNIFORM,
|
||||
|
||||
GSK_SL_STORAGE_LOCAL,
|
||||
GSK_SL_STORAGE_LOCAL_CONST,
|
||||
|
||||
GSK_SL_STORAGE_PARAMETER_IN,
|
||||
GSK_SL_STORAGE_PARAMETER_OUT,
|
||||
GSK_SL_STORAGE_PARAMETER_INOUT,
|
||||
GSK_SL_STORAGE_PARAMETER_CONST
|
||||
} GskSlStorage;
|
||||
|
||||
#endif /* __GSK_SL_TYPES_H__ */
|
348
gsk/gskslvalue.c
Normal file
348
gsk/gskslvalue.c
Normal file
@@ -0,0 +1,348 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslvalueprivate.h"
|
||||
|
||||
#include "gskslprinterprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
struct _GskSlValue {
|
||||
GskSlType *type;
|
||||
|
||||
gpointer data;
|
||||
GDestroyNotify free_func;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_value_new (GskSlType *type)
|
||||
{
|
||||
gpointer data;
|
||||
|
||||
g_return_val_if_fail (gsk_sl_type_get_size (type) > 0, NULL);
|
||||
|
||||
data = g_malloc0 (gsk_sl_type_get_size (type));
|
||||
|
||||
return gsk_sl_value_new_for_data (type, data, g_free, data);
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_value_new_for_data (GskSlType *type,
|
||||
gpointer data,
|
||||
GDestroyNotify free_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
GskSlValue *value;
|
||||
|
||||
g_return_val_if_fail (gsk_sl_type_get_size (type) > 0, NULL);
|
||||
g_return_val_if_fail (data != NULL, NULL);
|
||||
|
||||
value = g_slice_new0 (GskSlValue);
|
||||
|
||||
value->type = gsk_sl_type_ref (type);
|
||||
value->data = data;
|
||||
value->free_func = free_func;
|
||||
value->user_data = user_data;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_sl_value_new_convert:
|
||||
* @source: value to convert
|
||||
* @new_type: type to convert to
|
||||
*
|
||||
* Converts @source into the @new_type. This function uses the extended
|
||||
* conversion rules for constructors. If you want to restrict yourself
|
||||
* to the usual conversion rules, call this function after checking
|
||||
* for compatibility via gsk_sl_type_can_convert().
|
||||
*
|
||||
* Returns: a new value containing the converted @source or %NULL
|
||||
* if the source cannot be converted to @type.
|
||||
**/
|
||||
GskSlValue *
|
||||
gsk_sl_value_new_convert (GskSlValue *source,
|
||||
GskSlType *new_type)
|
||||
{
|
||||
GskSlValue *result;
|
||||
|
||||
if (gsk_sl_type_equal (source->type, new_type))
|
||||
{
|
||||
return gsk_sl_value_copy (source);
|
||||
}
|
||||
else if (gsk_sl_type_is_scalar (source->type))
|
||||
{
|
||||
if (!gsk_sl_type_is_scalar (new_type))
|
||||
return NULL;
|
||||
|
||||
result = gsk_sl_value_new (new_type);
|
||||
gsk_sl_scalar_type_convert_value (gsk_sl_type_get_scalar_type (new_type),
|
||||
result->data,
|
||||
gsk_sl_type_get_scalar_type (source->type),
|
||||
source->data);
|
||||
return result;
|
||||
}
|
||||
else if (gsk_sl_type_is_vector (source->type))
|
||||
{
|
||||
guchar *sdata, *ddata;
|
||||
gsize sstride, dstride;
|
||||
guint i, n;
|
||||
|
||||
if (!gsk_sl_type_is_vector (new_type) ||
|
||||
gsk_sl_type_get_length (new_type) != gsk_sl_type_get_length (source->type))
|
||||
return NULL;
|
||||
|
||||
n = gsk_sl_type_get_length (new_type);
|
||||
result = gsk_sl_value_new (new_type);
|
||||
sdata = source->data;
|
||||
ddata = result->data;
|
||||
sstride = gsk_sl_type_get_index_stride (source->type);
|
||||
dstride = gsk_sl_type_get_index_stride (new_type);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
gsk_sl_scalar_type_convert_value (gsk_sl_type_get_scalar_type (new_type),
|
||||
ddata + i * dstride,
|
||||
gsk_sl_type_get_scalar_type (source->type),
|
||||
sdata + i * sstride);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else if (gsk_sl_type_is_matrix (source->type))
|
||||
{
|
||||
guchar *sdata, *ddata;
|
||||
gsize sstride, dstride;
|
||||
guint i, n;
|
||||
|
||||
if (!gsk_sl_type_is_matrix (new_type) ||
|
||||
gsk_sl_type_get_length (new_type) != gsk_sl_type_get_length (source->type) ||
|
||||
gsk_sl_type_get_length (gsk_sl_type_get_index_type (new_type)) != gsk_sl_type_get_length (gsk_sl_type_get_index_type (source->type)))
|
||||
return NULL;
|
||||
|
||||
n = gsk_sl_type_get_length (new_type) * gsk_sl_type_get_length (gsk_sl_type_get_index_type (source->type));
|
||||
result = gsk_sl_value_new (new_type);
|
||||
sdata = source->data;
|
||||
ddata = result->data;
|
||||
sstride = gsk_sl_type_get_size (source->type) / n;
|
||||
dstride = gsk_sl_type_get_size (new_type) / n;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
gsk_sl_scalar_type_convert_value (gsk_sl_type_get_scalar_type (new_type),
|
||||
ddata + i * dstride,
|
||||
gsk_sl_type_get_scalar_type (source->type),
|
||||
sdata + i * sstride);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_value_new_index (GskSlValue *value,
|
||||
gsize n)
|
||||
{
|
||||
GskSlType *index_type;
|
||||
gpointer data;
|
||||
|
||||
if (n >= gsk_sl_type_get_length (value->type))
|
||||
return NULL;
|
||||
|
||||
index_type = gsk_sl_type_get_index_type (value->type);
|
||||
|
||||
data = g_memdup ((guchar *) value->data + gsk_sl_type_get_index_stride (value->type) * n,
|
||||
gsk_sl_type_get_size (index_type));
|
||||
|
||||
return gsk_sl_value_new_for_data (index_type, data, g_free, data);
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_value_new_member (GskSlValue *value,
|
||||
guint n)
|
||||
{
|
||||
GskSlType *member_type;
|
||||
gpointer data;
|
||||
|
||||
member_type = gsk_sl_type_get_member_type (value->type, n);
|
||||
|
||||
data = g_memdup ((guchar *) value->data + gsk_sl_type_get_member_offset (value->type, n),
|
||||
gsk_sl_type_get_size (member_type));
|
||||
|
||||
return gsk_sl_value_new_for_data (member_type, data, g_free, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_sl_value_convert_components:
|
||||
* @source: (transfer full): value to convert
|
||||
* @scalar: new scalar type to convert to
|
||||
*
|
||||
* Converts the scalar components of @source into the @scalar.
|
||||
* This function uses the extended conversion rules for constructors.
|
||||
*
|
||||
* Returns: A value containing the converted values. This may or may not
|
||||
* be the original @source.
|
||||
**/
|
||||
GskSlValue *
|
||||
gsk_sl_value_convert_components (GskSlValue *source,
|
||||
GskSlScalarType scalar)
|
||||
{
|
||||
GskSlValue *result;
|
||||
GskSlType *result_type;
|
||||
guchar *sdata, *ddata;
|
||||
gsize sstride, dstride;
|
||||
gsize i, n;
|
||||
GskSlScalarType sscalar;
|
||||
|
||||
sscalar = gsk_sl_type_get_scalar_type (source->type);
|
||||
if (sscalar == scalar)
|
||||
return source;
|
||||
|
||||
result_type = gsk_sl_type_get_matching (source->type, scalar);
|
||||
|
||||
result = gsk_sl_value_new (result_type);
|
||||
|
||||
n = gsk_sl_type_get_n_components (result_type);
|
||||
sdata = gsk_sl_value_get_data (source);
|
||||
sstride = gsk_sl_scalar_type_get_size (sscalar);
|
||||
ddata = gsk_sl_value_get_data (result);
|
||||
dstride = gsk_sl_scalar_type_get_size (scalar);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
gsk_sl_scalar_type_convert_value (scalar,
|
||||
ddata + i * dstride,
|
||||
sscalar,
|
||||
sdata + i * sstride);
|
||||
}
|
||||
|
||||
gsk_sl_value_free (source);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_value_copy (const GskSlValue *source)
|
||||
{
|
||||
gpointer data;
|
||||
|
||||
data = g_memdup (source->data, gsk_sl_type_get_size (source->type));
|
||||
|
||||
return gsk_sl_value_new_for_data (source->type, data, g_free, data);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_value_free (GskSlValue *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return;
|
||||
|
||||
if (value->free_func)
|
||||
value->free_func (value->user_data);
|
||||
|
||||
gsk_sl_type_unref (value->type);
|
||||
|
||||
g_slice_free (GskSlValue, value);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_value_componentwise (GskSlValue *value,
|
||||
void (* func) (gpointer, gpointer),
|
||||
gpointer user_data)
|
||||
{
|
||||
gsize stride;
|
||||
gsize i, n;
|
||||
|
||||
g_return_if_fail (gsk_sl_type_get_n_components (value->type) > 0);
|
||||
|
||||
stride = gsk_sl_scalar_type_get_size (gsk_sl_type_get_scalar_type (value->type));
|
||||
n = gsk_sl_type_get_n_components (value->type);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
func ((guchar *) value->data + stride * i, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_value_print (const GskSlValue *value,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
gsk_sl_type_print_value (value->type, printer, value->data);
|
||||
}
|
||||
|
||||
char *
|
||||
gsk_sl_value_to_string (const GskSlValue *value)
|
||||
{
|
||||
GskSlPrinter *printer;
|
||||
char *s;
|
||||
|
||||
printer = gsk_sl_printer_new ();
|
||||
|
||||
gsk_sl_value_print (value, printer);
|
||||
|
||||
s = gsk_sl_printer_write_to_string (printer);
|
||||
gsk_sl_printer_unref (printer);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_value_get_type (const GskSlValue *value)
|
||||
{
|
||||
return value->type;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gsk_sl_value_get_data (const GskSlValue *value)
|
||||
{
|
||||
return value->data;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_value_equal (gconstpointer a_,
|
||||
gconstpointer b_)
|
||||
{
|
||||
const GskSlValue *a = a_;
|
||||
const GskSlValue *b = b_;
|
||||
|
||||
if (!gsk_sl_type_equal (a->type, b->type))
|
||||
return FALSE;
|
||||
|
||||
return gsk_sl_type_value_equal (a->type, a->data, b->data);
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_value_hash (gconstpointer value_)
|
||||
{
|
||||
const GskSlValue *value = value_;
|
||||
|
||||
/* XXX: We definitely want to hash the data here ! */
|
||||
return gsk_sl_type_hash (value->type);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_value_write_spv (const GskSlValue *value,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return gsk_sl_type_write_value_spv (value->type, writer, value->data);
|
||||
}
|
61
gsk/gskslvalueprivate.h
Normal file
61
gsk/gskslvalueprivate.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_VALUE_PRIVATE_H__
|
||||
#define __GSK_SL_VALUE_PRIVATE_H__
|
||||
|
||||
#include "gsk/gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlValue * gsk_sl_value_new (GskSlType *type);
|
||||
GskSlValue * gsk_sl_value_new_for_data (GskSlType *type,
|
||||
gpointer data,
|
||||
GDestroyNotify free_func,
|
||||
gpointer user_data);
|
||||
GskSlValue * gsk_sl_value_new_convert (GskSlValue *source,
|
||||
GskSlType *new_type);
|
||||
GskSlValue * gsk_sl_value_new_index (GskSlValue *value,
|
||||
gsize n);
|
||||
GskSlValue * gsk_sl_value_new_member (GskSlValue *value,
|
||||
guint n);
|
||||
GskSlValue * gsk_sl_value_copy (const GskSlValue *source);
|
||||
void gsk_sl_value_free (GskSlValue *value);
|
||||
|
||||
GskSlValue * gsk_sl_value_convert_components (GskSlValue *source,
|
||||
GskSlScalarType scalar);
|
||||
void gsk_sl_value_componentwise (GskSlValue *value,
|
||||
void (* func) (gpointer, gpointer),
|
||||
gpointer user_data);
|
||||
void gsk_sl_value_print (const GskSlValue *value,
|
||||
GskSlPrinter *printer);
|
||||
char * gsk_sl_value_to_string (const GskSlValue *value);
|
||||
|
||||
GskSlType * gsk_sl_value_get_type (const GskSlValue *value);
|
||||
gpointer gsk_sl_value_get_data (const GskSlValue *value);
|
||||
|
||||
gboolean gsk_sl_value_equal (gconstpointer a,
|
||||
gconstpointer b);
|
||||
guint gsk_sl_value_hash (gconstpointer type);
|
||||
|
||||
guint32 gsk_sl_value_write_spv (const GskSlValue *value,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_VALUE_PRIVATE_H__ */
|
844
gsk/gskslvariable.c
Normal file
844
gsk/gskslvariable.c
Normal file
@@ -0,0 +1,844 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslvariableprivate.h"
|
||||
|
||||
#include "gskslexpressionprivate.h"
|
||||
#include "gskslprinterprivate.h"
|
||||
#include "gskslqualifierprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslvalueprivate.h"
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
typedef struct _GskSlVariableClass GskSlVariableClass;
|
||||
|
||||
struct _GskSlVariable {
|
||||
const GskSlVariableClass *class;
|
||||
|
||||
guint ref_count;
|
||||
|
||||
char *name;
|
||||
GskSlType *type;
|
||||
GskSlQualifier qualifier;
|
||||
};
|
||||
|
||||
struct _GskSlVariableClass
|
||||
{
|
||||
gsize size;
|
||||
|
||||
void (* free) (GskSlVariable *variable);
|
||||
|
||||
GskSlValue * (* get_initial_value) (const GskSlVariable *variable);
|
||||
GskSpvAccessChain * (* get_access_chain) (GskSlVariable *variable,
|
||||
GskSpvWriter *writer);
|
||||
guint32 (* write_spv) (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer);
|
||||
guint32 (* load_spv) (GskSlVariable *variable,
|
||||
GskSpvWriter *writer);
|
||||
};
|
||||
|
||||
static gpointer
|
||||
gsk_sl_variable_alloc (const GskSlVariableClass *klass,
|
||||
const char *name,
|
||||
const GskSlQualifier *qualifier,
|
||||
GskSlType *type)
|
||||
{
|
||||
GskSlVariable *variable;
|
||||
|
||||
variable = g_slice_alloc0 (klass->size);
|
||||
|
||||
variable->class = klass;
|
||||
variable->ref_count = 1;
|
||||
|
||||
variable->name = g_strdup (name);
|
||||
variable->qualifier = *qualifier;
|
||||
variable->type = gsk_sl_type_ref (type);
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_variable_free (GskSlVariable *variable)
|
||||
{
|
||||
gsk_sl_type_unref (variable->type);
|
||||
g_free (variable->name);
|
||||
|
||||
g_slice_free1 (variable->class->size, variable);
|
||||
}
|
||||
|
||||
static GskSlValue *
|
||||
gsk_sl_variable_default_get_initial_value (const GskSlVariable *variable)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GskSpvAccessChain *
|
||||
gsk_spv_access_chain_new (GskSlVariable *variable,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
static GskSpvAccessChain *
|
||||
gsk_sl_variable_default_get_access_chain (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return gsk_spv_access_chain_new (variable, writer);
|
||||
}
|
||||
|
||||
static GskSpvAccessChain *
|
||||
gsk_sl_variable_default_get_no_access_chain (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_default_load_spv (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return gsk_spv_writer_load (writer,
|
||||
variable->type,
|
||||
gsk_spv_writer_get_id_for_variable (writer, variable),
|
||||
0);
|
||||
}
|
||||
|
||||
/* STANDARD */
|
||||
|
||||
typedef struct _GskSlVariableStandard GskSlVariableStandard;
|
||||
|
||||
struct _GskSlVariableStandard {
|
||||
GskSlVariable parent;
|
||||
|
||||
GskSlValue *initial_value;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_variable_standard_free (GskSlVariable *variable)
|
||||
{
|
||||
const GskSlVariableStandard *standard = (const GskSlVariableStandard *) variable;
|
||||
|
||||
if (standard->initial_value)
|
||||
gsk_sl_value_free (standard->initial_value);
|
||||
|
||||
gsk_sl_variable_free (variable);
|
||||
}
|
||||
|
||||
static GskSlValue *
|
||||
gsk_sl_variable_standard_get_initial_value (const GskSlVariable *variable)
|
||||
{
|
||||
const GskSlVariableStandard *standard = (const GskSlVariableStandard *) variable;
|
||||
|
||||
return standard->initial_value;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_standard_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
const GskSlVariableStandard *standard = (const GskSlVariableStandard *) variable;
|
||||
guint32 result_id;
|
||||
guint32 value_id;
|
||||
GskSlQualifierLocation location;
|
||||
GskSpvStorageClass storage_class;
|
||||
|
||||
location = gsk_sl_qualifier_get_location (&variable->qualifier);
|
||||
|
||||
if (standard->initial_value)
|
||||
value_id = gsk_spv_writer_get_id_for_value (writer, standard->initial_value);
|
||||
else
|
||||
value_id = 0;
|
||||
|
||||
storage_class = gsk_sl_qualifier_get_storage_class (&variable->qualifier, variable->type);
|
||||
result_id = gsk_spv_writer_variable (writer,
|
||||
location == GSK_SL_QUALIFIER_GLOBAL ? GSK_SPV_WRITER_SECTION_DEFINE : GSK_SPV_WRITER_SECTION_DECLARE,
|
||||
variable->type,
|
||||
storage_class,
|
||||
storage_class,
|
||||
value_id);
|
||||
|
||||
if (variable->name)
|
||||
gsk_spv_writer_name (writer, result_id, variable->name);
|
||||
|
||||
gsk_sl_qualifier_write_spv_decorations (&variable->qualifier, writer, result_id);
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
static const GskSlVariableClass GSK_SL_VARIABLE_STANDARD = {
|
||||
sizeof (GskSlVariableStandard),
|
||||
gsk_sl_variable_standard_free,
|
||||
gsk_sl_variable_standard_get_initial_value,
|
||||
gsk_sl_variable_default_get_access_chain,
|
||||
gsk_sl_variable_standard_write_spv,
|
||||
gsk_sl_variable_default_load_spv
|
||||
};
|
||||
|
||||
/* BUILTIN */
|
||||
|
||||
typedef struct _GskSlVariableBuiltin GskSlVariableBuiltin;
|
||||
|
||||
struct _GskSlVariableBuiltin {
|
||||
GskSlVariable parent;
|
||||
|
||||
GskSpvBuiltIn builtin;
|
||||
};
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_builtin_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
const GskSlVariableBuiltin *builtin = (const GskSlVariableBuiltin *) variable;
|
||||
guint32 result_id;
|
||||
GskSpvStorageClass storage_class;
|
||||
|
||||
storage_class = gsk_sl_qualifier_get_storage_class (&variable->qualifier, variable->type);
|
||||
result_id = gsk_spv_writer_variable (writer,
|
||||
GSK_SPV_WRITER_SECTION_DEFINE,
|
||||
variable->type,
|
||||
storage_class,
|
||||
storage_class,
|
||||
0);
|
||||
|
||||
if (variable->name)
|
||||
gsk_spv_writer_name (writer, result_id, variable->name);
|
||||
|
||||
gsk_sl_qualifier_write_spv_decorations (&variable->qualifier, writer, result_id);
|
||||
|
||||
gsk_spv_writer_decorate (writer, result_id, GSK_SPV_DECORATION_BUILT_IN, (guint32[1]) { builtin->builtin }, 1);
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
static const GskSlVariableClass GSK_SL_VARIABLE_BUILTIN = {
|
||||
sizeof (GskSlVariableBuiltin),
|
||||
gsk_sl_variable_free,
|
||||
gsk_sl_variable_default_get_initial_value,
|
||||
gsk_sl_variable_default_get_access_chain,
|
||||
gsk_sl_variable_builtin_write_spv,
|
||||
gsk_sl_variable_default_load_spv
|
||||
};
|
||||
|
||||
/* CONSTANT */
|
||||
|
||||
typedef struct _GskSlVariableConstant GskSlVariableConstant;
|
||||
|
||||
struct _GskSlVariableConstant {
|
||||
GskSlVariable parent;
|
||||
|
||||
GskSlValue *value;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_variable_constant_free (GskSlVariable *variable)
|
||||
{
|
||||
const GskSlVariableConstant *constant = (const GskSlVariableConstant *) variable;
|
||||
|
||||
gsk_sl_value_free (constant->value);
|
||||
|
||||
gsk_sl_variable_free (variable);
|
||||
}
|
||||
|
||||
static GskSlValue *
|
||||
gsk_sl_variable_constant_get_initial_value (const GskSlVariable *variable)
|
||||
{
|
||||
const GskSlVariableConstant *constant = (const GskSlVariableConstant *) variable;
|
||||
|
||||
return constant->value;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_constant_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_constant_load_spv (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
const GskSlVariableConstant *constant = (const GskSlVariableConstant *) variable;
|
||||
|
||||
return gsk_spv_writer_get_id_for_value (writer, constant->value);
|
||||
}
|
||||
|
||||
static const GskSlVariableClass GSK_SL_VARIABLE_CONSTANT = {
|
||||
sizeof (GskSlVariableConstant),
|
||||
gsk_sl_variable_constant_free,
|
||||
gsk_sl_variable_constant_get_initial_value,
|
||||
gsk_sl_variable_default_get_no_access_chain,
|
||||
gsk_sl_variable_constant_write_spv,
|
||||
gsk_sl_variable_constant_load_spv
|
||||
};
|
||||
|
||||
/* PARAMETER */
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_parameter_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
guint32 type_id, result_id;
|
||||
|
||||
type_id = gsk_spv_writer_get_id_for_pointer_type (writer,
|
||||
variable->type,
|
||||
GSK_SPV_STORAGE_CLASS_FUNCTION);
|
||||
result_id = gsk_spv_writer_function_parameter (writer, type_id);
|
||||
|
||||
gsk_spv_writer_name (writer, result_id, variable->name);
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
static const GskSlVariableClass GSK_SL_VARIABLE_PARAMETER = {
|
||||
sizeof (GskSlVariable),
|
||||
gsk_sl_variable_free,
|
||||
gsk_sl_variable_default_get_initial_value,
|
||||
gsk_sl_variable_default_get_access_chain,
|
||||
gsk_sl_variable_parameter_write_spv,
|
||||
gsk_sl_variable_default_load_spv
|
||||
};
|
||||
|
||||
/* CONST_PARAMETER */
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_const_parameter_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
guint32 result_id, type_id;
|
||||
|
||||
type_id = gsk_spv_writer_get_id_for_type (writer, variable->type);
|
||||
result_id = gsk_spv_writer_function_parameter (writer, type_id);
|
||||
|
||||
gsk_spv_writer_name (writer, result_id, variable->name);
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_const_parameter_load_spv (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return gsk_spv_writer_get_id_for_variable (writer, variable);
|
||||
}
|
||||
|
||||
static const GskSlVariableClass GSK_SL_VARIABLE_CONST_PARAMETER = {
|
||||
sizeof (GskSlVariable),
|
||||
gsk_sl_variable_free,
|
||||
gsk_sl_variable_default_get_initial_value,
|
||||
gsk_sl_variable_default_get_no_access_chain,
|
||||
gsk_sl_variable_const_parameter_write_spv,
|
||||
gsk_sl_variable_const_parameter_load_spv
|
||||
};
|
||||
|
||||
/* MEMBER */
|
||||
|
||||
typedef struct _GskSlVariableMember GskSlVariableMember;
|
||||
|
||||
struct _GskSlVariableMember {
|
||||
GskSlVariable parent;
|
||||
|
||||
GskSlVariable *block;
|
||||
gsize member_id;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_variable_member_free (GskSlVariable *variable)
|
||||
{
|
||||
const GskSlVariableMember *member = (const GskSlVariableMember *) variable;
|
||||
|
||||
gsk_sl_variable_unref (member->block);
|
||||
|
||||
gsk_sl_variable_free (variable);
|
||||
}
|
||||
|
||||
static GskSpvAccessChain *
|
||||
gsk_sl_variable_member_get_access_chain (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
const GskSlVariableMember *member = (const GskSlVariableMember *) variable;
|
||||
GskSpvAccessChain *chain;
|
||||
GskSlValue *value;
|
||||
|
||||
chain = gsk_sl_variable_get_access_chain (member->block, writer);
|
||||
value = gsk_sl_value_new_for_data (gsk_sl_type_get_scalar (GSK_SL_INT), &(gint32) { member->member_id }, NULL, NULL);
|
||||
gsk_spv_access_chain_add_index (chain,
|
||||
variable->type,
|
||||
gsk_spv_writer_get_id_for_value (writer, value));
|
||||
gsk_sl_value_free (value);
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_variable_member_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
const GskSlVariableMember *member = (const GskSlVariableMember *) variable;
|
||||
|
||||
return gsk_spv_writer_get_id_for_variable (writer, member->block);
|
||||
}
|
||||
|
||||
static const GskSlVariableClass GSK_SL_VARIABLE_MEMBER = {
|
||||
sizeof (GskSlVariableMember),
|
||||
gsk_sl_variable_member_free,
|
||||
gsk_sl_variable_default_get_initial_value,
|
||||
gsk_sl_variable_member_get_access_chain,
|
||||
gsk_sl_variable_member_write_spv,
|
||||
gsk_sl_variable_default_load_spv
|
||||
};
|
||||
|
||||
/* API */
|
||||
|
||||
GskSlVariable *
|
||||
gsk_sl_variable_new (const char *name,
|
||||
GskSlType *type,
|
||||
const GskSlQualifier *qualifier,
|
||||
GskSlValue *initial_value)
|
||||
{
|
||||
g_return_val_if_fail (initial_value == NULL || gsk_sl_type_equal (type, gsk_sl_value_get_type (initial_value)), NULL);
|
||||
|
||||
switch (qualifier->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
g_assert (initial_value != NULL);
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
if (initial_value)
|
||||
{
|
||||
GskSlVariableConstant *constant = gsk_sl_variable_alloc (&GSK_SL_VARIABLE_CONSTANT, name, qualifier, type);
|
||||
constant->value = initial_value;
|
||||
return &constant->parent;
|
||||
}
|
||||
/* else fall through */
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
{
|
||||
GskSlVariableStandard *standard = gsk_sl_variable_alloc (&GSK_SL_VARIABLE_STANDARD, name, qualifier, type);
|
||||
standard->initial_value = initial_value;
|
||||
return &standard->parent;
|
||||
}
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
g_assert (initial_value == NULL);
|
||||
return gsk_sl_variable_alloc (&GSK_SL_VARIABLE_PARAMETER, name, qualifier, type);
|
||||
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
g_assert (initial_value == NULL);
|
||||
return gsk_sl_variable_alloc (&GSK_SL_VARIABLE_CONST_PARAMETER, name, qualifier, type);
|
||||
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GskSlVariable *
|
||||
gsk_sl_variable_new_block_member (GskSlVariable *block,
|
||||
guint member_id)
|
||||
{
|
||||
GskSlVariableMember *member;
|
||||
|
||||
g_return_val_if_fail (block != NULL, NULL);
|
||||
g_return_val_if_fail (gsk_sl_type_is_block (block->type), NULL);
|
||||
g_return_val_if_fail (member_id < gsk_sl_type_get_n_members (block->type), NULL);
|
||||
|
||||
member = gsk_sl_variable_alloc (&GSK_SL_VARIABLE_MEMBER,
|
||||
gsk_sl_type_get_member_name (block->type, member_id),
|
||||
&block->qualifier,
|
||||
gsk_sl_type_get_member_type (block->type, member_id));
|
||||
member->block = gsk_sl_variable_ref (block);
|
||||
member->member_id = member_id;
|
||||
|
||||
return &member->parent;
|
||||
}
|
||||
|
||||
GskSlVariable *
|
||||
gsk_sl_variable_new_builtin (const char *name,
|
||||
GskSlType *type,
|
||||
const GskSlQualifier *qualifier,
|
||||
GskSpvBuiltIn builtin)
|
||||
{
|
||||
GskSlVariableBuiltin *builtin_var;
|
||||
|
||||
builtin_var = gsk_sl_variable_alloc (&GSK_SL_VARIABLE_BUILTIN, name, qualifier, type);
|
||||
|
||||
builtin_var->builtin = builtin;
|
||||
|
||||
return &builtin_var->parent;
|
||||
}
|
||||
|
||||
GskSlVariable *
|
||||
gsk_sl_variable_ref (GskSlVariable *variable)
|
||||
{
|
||||
g_return_val_if_fail (variable != NULL, NULL);
|
||||
|
||||
variable->ref_count += 1;
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_variable_unref (GskSlVariable *variable)
|
||||
{
|
||||
if (variable == NULL)
|
||||
return;
|
||||
|
||||
variable->ref_count -= 1;
|
||||
if (variable->ref_count > 0)
|
||||
return;
|
||||
|
||||
variable->class->free (variable);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_variable_print (const GskSlVariable *variable,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
if (gsk_sl_qualifier_print (&variable->qualifier, printer))
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_name (variable->type));
|
||||
if (gsk_sl_type_is_block (variable->type))
|
||||
{
|
||||
guint i, n;
|
||||
|
||||
gsk_sl_printer_append (printer, " {");
|
||||
gsk_sl_printer_push_indentation (printer);
|
||||
n = gsk_sl_type_get_n_members (variable->type);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
gsk_sl_printer_newline (printer);
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_name (gsk_sl_type_get_member_type (variable->type, i)));
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_member_name (variable->type, i));
|
||||
gsk_sl_printer_append (printer, ";");
|
||||
}
|
||||
gsk_sl_printer_pop_indentation (printer);
|
||||
gsk_sl_printer_newline (printer);
|
||||
gsk_sl_printer_append (printer, "}");
|
||||
}
|
||||
if (variable->name)
|
||||
{
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
gsk_sl_printer_append (printer, variable->name);
|
||||
}
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_variable_get_type (const GskSlVariable *variable)
|
||||
{
|
||||
return variable->type;
|
||||
}
|
||||
|
||||
const GskSlQualifier *
|
||||
gsk_sl_variable_get_qualifier (const GskSlVariable *variable)
|
||||
{
|
||||
return &variable->qualifier;
|
||||
}
|
||||
|
||||
const char *
|
||||
gsk_sl_variable_get_name (const GskSlVariable *variable)
|
||||
{
|
||||
return variable->name;
|
||||
}
|
||||
|
||||
const GskSlValue *
|
||||
gsk_sl_variable_get_initial_value (const GskSlVariable *variable)
|
||||
{
|
||||
return variable->class->get_initial_value (variable);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_variable_is_constant (const GskSlVariable *variable)
|
||||
{
|
||||
return gsk_sl_qualifier_is_constant (&variable->qualifier);
|
||||
}
|
||||
|
||||
GskSpvAccessChain *
|
||||
gsk_sl_variable_get_access_chain (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return variable->class->get_access_chain (variable, writer);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_variable_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return variable->class->write_spv (variable, writer);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_sl_variable_load_spv (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
return variable->class->load_spv (variable, writer);
|
||||
}
|
||||
|
||||
/* ACCESS CHAIN */
|
||||
|
||||
struct _GskSpvAccessChain
|
||||
{
|
||||
GskSpvWriter *writer;
|
||||
GskSlVariable *variable;
|
||||
GskSlType *type;
|
||||
GArray *chain;
|
||||
GSList *pending_indexes;
|
||||
guint32 swizzle[4];
|
||||
guint swizzle_length;
|
||||
};
|
||||
|
||||
static GskSpvAccessChain *
|
||||
gsk_spv_access_chain_new (GskSlVariable *variable,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
GskSpvAccessChain *chain;
|
||||
|
||||
chain = g_slice_new0 (GskSpvAccessChain);
|
||||
|
||||
chain->writer = gsk_spv_writer_ref (writer);
|
||||
chain->variable = gsk_sl_variable_ref (variable);
|
||||
chain->type = gsk_sl_type_ref (gsk_sl_variable_get_type (variable));
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_spv_access_chain_free (GskSpvAccessChain *chain)
|
||||
{
|
||||
if (chain->chain)
|
||||
g_array_free (chain->chain, TRUE);
|
||||
g_slist_free_full (chain->pending_indexes, (GDestroyNotify) gsk_sl_expression_unref);
|
||||
gsk_sl_type_unref (chain->type);
|
||||
gsk_sl_variable_unref (chain->variable);
|
||||
gsk_spv_writer_unref (chain->writer);
|
||||
|
||||
g_slice_free (GskSpvAccessChain, chain);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_spv_access_chain_add_index (GskSpvAccessChain *chain,
|
||||
GskSlType *type,
|
||||
guint32 index_id)
|
||||
{
|
||||
g_assert (!gsk_spv_access_chain_has_swizzle (chain));
|
||||
|
||||
if (chain->chain == NULL)
|
||||
chain->chain = g_array_new (FALSE, FALSE, sizeof (guint32));
|
||||
gsk_sl_type_unref (chain->type);
|
||||
chain->type = gsk_sl_type_ref (type);
|
||||
|
||||
g_array_append_val (chain->chain, index_id);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_spv_access_chain_add_dynamic_index (GskSpvAccessChain *chain,
|
||||
GskSlType *type,
|
||||
GskSlExpression *expr)
|
||||
{
|
||||
gsk_spv_access_chain_add_index (chain, type, 0);
|
||||
|
||||
chain->pending_indexes = g_slist_prepend (chain->pending_indexes, gsk_sl_expression_ref (expr));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_spv_access_chain_has_swizzle (GskSpvAccessChain *chain)
|
||||
{
|
||||
return chain->swizzle_length > 0;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_spv_access_chain_swizzle (GskSpvAccessChain *chain,
|
||||
const guint *indexes,
|
||||
guint length)
|
||||
{
|
||||
guint tmp[4];
|
||||
guint i;
|
||||
|
||||
if (length == 1)
|
||||
{
|
||||
GskSlValue *value;
|
||||
guint32 new_index;
|
||||
|
||||
if (chain->swizzle_length != 0)
|
||||
new_index = chain->swizzle[indexes[0]];
|
||||
else
|
||||
new_index = indexes[0];
|
||||
chain->swizzle_length = 0;
|
||||
|
||||
value = gsk_sl_value_new_for_data (gsk_sl_type_get_scalar (GSK_SL_UINT),
|
||||
&new_index,
|
||||
NULL, NULL);
|
||||
gsk_spv_access_chain_add_index (chain,
|
||||
gsk_sl_type_get_index_type (chain->type),
|
||||
gsk_spv_writer_get_id_for_value (chain->writer, value));
|
||||
gsk_sl_value_free (value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chain->swizzle_length != 0)
|
||||
{
|
||||
g_assert (length <= chain->swizzle_length);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
tmp[i] = chain->swizzle[indexes[i]];
|
||||
}
|
||||
indexes = tmp;
|
||||
}
|
||||
|
||||
/* Mean trick to do optimization: We only assign a swizzle_length
|
||||
* If something is actually swizzled. If we're doing an identity
|
||||
* swizzle, ignore it.
|
||||
*/
|
||||
if (length < gsk_sl_type_get_n_components (chain->type))
|
||||
chain->swizzle_length = length;
|
||||
else
|
||||
chain->swizzle_length = 0;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
chain->swizzle[i] = indexes[i];
|
||||
if (indexes[i] != i)
|
||||
chain->swizzle_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_spv_access_resolve_pending (GskSpvAccessChain *chain)
|
||||
{
|
||||
GSList *l;
|
||||
guint i;
|
||||
|
||||
if (chain->pending_indexes == NULL)
|
||||
return;
|
||||
|
||||
i = chain->chain->len;
|
||||
l = chain->pending_indexes;
|
||||
while (i-- > 0)
|
||||
{
|
||||
if (g_array_index (chain->chain, guint32, i) != 0)
|
||||
continue;
|
||||
|
||||
g_array_index (chain->chain, guint32, i) = gsk_sl_expression_write_spv (l->data, chain->writer, NULL);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
g_slist_free_full (chain->pending_indexes, (GDestroyNotify) gsk_sl_expression_unref);
|
||||
chain->pending_indexes = NULL;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_spv_access_get_variable (GskSpvAccessChain *chain)
|
||||
{
|
||||
guint32 variable_id;
|
||||
|
||||
gsk_spv_access_resolve_pending (chain);
|
||||
|
||||
variable_id = gsk_spv_writer_get_id_for_variable (chain->writer,
|
||||
chain->variable);
|
||||
|
||||
if (chain->chain)
|
||||
variable_id = gsk_spv_writer_access_chain (chain->writer,
|
||||
chain->type,
|
||||
gsk_sl_qualifier_get_storage_class (gsk_sl_variable_get_qualifier (chain->variable),
|
||||
gsk_sl_variable_get_type (chain->variable)),
|
||||
variable_id,
|
||||
(guint32 *) chain->chain->data,
|
||||
chain->chain->len);
|
||||
|
||||
return variable_id;
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_spv_access_chain_get_swizzle_type (GskSpvAccessChain *chain)
|
||||
{
|
||||
g_assert (chain->swizzle_length != 0);
|
||||
|
||||
if (chain->swizzle_length == 1)
|
||||
return gsk_sl_type_get_scalar (gsk_sl_type_get_scalar_type (chain->type));
|
||||
else
|
||||
return gsk_sl_type_get_vector (gsk_sl_type_get_scalar_type (chain->type), chain->swizzle_length);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_access_chain_load (GskSpvAccessChain *chain)
|
||||
{
|
||||
guint result_id;
|
||||
|
||||
result_id = gsk_spv_writer_load (chain->writer,
|
||||
chain->type,
|
||||
gsk_spv_access_get_variable (chain),
|
||||
0);
|
||||
|
||||
if (chain->swizzle_length)
|
||||
result_id = gsk_spv_writer_vector_shuffle (chain->writer,
|
||||
gsk_spv_access_chain_get_swizzle_type (chain),
|
||||
result_id,
|
||||
result_id,
|
||||
chain->swizzle,
|
||||
chain->swizzle_length);
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_spv_access_chain_store (GskSpvAccessChain *chain,
|
||||
guint32 value)
|
||||
{
|
||||
guint32 chain_id;
|
||||
|
||||
chain_id = gsk_spv_access_get_variable (chain);
|
||||
|
||||
if (chain->swizzle_length)
|
||||
{
|
||||
guint32 indexes[4] = { 0, };
|
||||
guint32 merge;
|
||||
guint i, n;
|
||||
|
||||
merge = gsk_spv_writer_load (chain->writer,
|
||||
chain->type,
|
||||
chain_id,
|
||||
0);
|
||||
|
||||
n = gsk_sl_type_get_n_components (chain->type);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (i < chain->swizzle_length)
|
||||
indexes[chain->swizzle[i]] = n + i;
|
||||
if (indexes[i] == 0)
|
||||
indexes[i] = i;
|
||||
}
|
||||
|
||||
value = gsk_spv_writer_vector_shuffle (chain->writer,
|
||||
chain->type,
|
||||
merge,
|
||||
value,
|
||||
indexes,
|
||||
n);
|
||||
}
|
||||
|
||||
gsk_spv_writer_store (chain->writer,
|
||||
chain_id,
|
||||
value,
|
||||
0);
|
||||
}
|
||||
|
77
gsk/gskslvariableprivate.h
Normal file
77
gsk/gskslvariableprivate.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SL_VARIABLE_PRIVATE_H__
|
||||
#define __GSK_SL_VARIABLE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsk/gsksltypesprivate.h"
|
||||
#include "gsk/gskspvenumsprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskSlVariable * gsk_sl_variable_new (const char *name,
|
||||
GskSlType *type,
|
||||
const GskSlQualifier *qualifier,
|
||||
GskSlValue *initial_value);
|
||||
GskSlVariable * gsk_sl_variable_new_block_member (GskSlVariable *block,
|
||||
guint member_id);
|
||||
GskSlVariable * gsk_sl_variable_new_builtin (const char *name,
|
||||
GskSlType *type,
|
||||
const GskSlQualifier *qualifier,
|
||||
GskSpvBuiltIn builtin);
|
||||
|
||||
GskSlVariable * gsk_sl_variable_ref (GskSlVariable *variable);
|
||||
void gsk_sl_variable_unref (GskSlVariable *variable);
|
||||
|
||||
void gsk_sl_variable_print (const GskSlVariable *variable,
|
||||
GskSlPrinter *printer);
|
||||
|
||||
GskSlType * gsk_sl_variable_get_type (const GskSlVariable *variable);
|
||||
const GskSlQualifier * gsk_sl_variable_get_qualifier (const GskSlVariable *variable);
|
||||
const char * gsk_sl_variable_get_name (const GskSlVariable *variable);
|
||||
const GskSlValue * gsk_sl_variable_get_initial_value (const GskSlVariable *variable);
|
||||
gboolean gsk_sl_variable_is_constant (const GskSlVariable *variable);
|
||||
|
||||
GskSpvAccessChain * gsk_sl_variable_get_access_chain (GskSlVariable *variable,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
guint32 gsk_sl_variable_write_spv (const GskSlVariable *variable,
|
||||
GskSpvWriter *writer);
|
||||
guint32 gsk_sl_variable_load_spv (GskSlVariable *variable,
|
||||
GskSpvWriter *writer);
|
||||
|
||||
void gsk_spv_access_chain_free (GskSpvAccessChain *chain);
|
||||
void gsk_spv_access_chain_add_index (GskSpvAccessChain *chain,
|
||||
GskSlType *type,
|
||||
guint32 index_id);
|
||||
void gsk_spv_access_chain_add_dynamic_index (GskSpvAccessChain *chain,
|
||||
GskSlType *type,
|
||||
GskSlExpression *expr);
|
||||
void gsk_spv_access_chain_swizzle (GskSpvAccessChain *chain,
|
||||
const guint *indexes,
|
||||
guint n_indexes);
|
||||
gboolean gsk_spv_access_chain_has_swizzle (GskSpvAccessChain *chain);
|
||||
guint32 gsk_spv_access_chain_load (GskSpvAccessChain *chain);
|
||||
void gsk_spv_access_chain_store (GskSpvAccessChain *chain,
|
||||
guint32 value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_VARIABLE_PRIVATE_H__ */
|
114
gsk/gskspvenumsglslprivate.h
Normal file
114
gsk/gskspvenumsglslprivate.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* !!! THIS FILE WAS AUTOGENERATED !!!
|
||||
*
|
||||
* This file was created using the command
|
||||
* gjs spirv.js Glsl-enums extinst.glsl.std.450.grammar.json
|
||||
* Apply any changes to those files and then regenerate using above command.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SPV_GLSL_ENUMS_H__
|
||||
#define __GSK_SPV_GLSL_ENUMS_H__
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_OP_GLSL_ROUND = 1,
|
||||
GSK_SPV_OP_GLSL_ROUND_EVEN = 2,
|
||||
GSK_SPV_OP_GLSL_TRUNC = 3,
|
||||
GSK_SPV_OP_GLSL_F_ABS = 4,
|
||||
GSK_SPV_OP_GLSL_S_ABS = 5,
|
||||
GSK_SPV_OP_GLSL_F_SIGN = 6,
|
||||
GSK_SPV_OP_GLSL_S_SIGN = 7,
|
||||
GSK_SPV_OP_GLSL_FLOOR = 8,
|
||||
GSK_SPV_OP_GLSL_CEIL = 9,
|
||||
GSK_SPV_OP_GLSL_FRACT = 10,
|
||||
GSK_SPV_OP_GLSL_RADIANS = 11,
|
||||
GSK_SPV_OP_GLSL_DEGREES = 12,
|
||||
GSK_SPV_OP_GLSL_SIN = 13,
|
||||
GSK_SPV_OP_GLSL_COS = 14,
|
||||
GSK_SPV_OP_GLSL_TAN = 15,
|
||||
GSK_SPV_OP_GLSL_ASIN = 16,
|
||||
GSK_SPV_OP_GLSL_ACOS = 17,
|
||||
GSK_SPV_OP_GLSL_ATAN = 18,
|
||||
GSK_SPV_OP_GLSL_SINH = 19,
|
||||
GSK_SPV_OP_GLSL_COSH = 20,
|
||||
GSK_SPV_OP_GLSL_TANH = 21,
|
||||
GSK_SPV_OP_GLSL_ASINH = 22,
|
||||
GSK_SPV_OP_GLSL_ACOSH = 23,
|
||||
GSK_SPV_OP_GLSL_ATANH = 24,
|
||||
GSK_SPV_OP_GLSL_ATAN2 = 25,
|
||||
GSK_SPV_OP_GLSL_POW = 26,
|
||||
GSK_SPV_OP_GLSL_EXP = 27,
|
||||
GSK_SPV_OP_GLSL_LOG = 28,
|
||||
GSK_SPV_OP_GLSL_EXP2 = 29,
|
||||
GSK_SPV_OP_GLSL_LOG2 = 30,
|
||||
GSK_SPV_OP_GLSL_SQRT = 31,
|
||||
GSK_SPV_OP_GLSL_INVERSE_SQRT = 32,
|
||||
GSK_SPV_OP_GLSL_DETERMINANT = 33,
|
||||
GSK_SPV_OP_GLSL_MATRIX_INVERSE = 34,
|
||||
GSK_SPV_OP_GLSL_MODF = 35,
|
||||
GSK_SPV_OP_GLSL_MODF_STRUCT = 36,
|
||||
GSK_SPV_OP_GLSL_F_MIN = 37,
|
||||
GSK_SPV_OP_GLSL_U_MIN = 38,
|
||||
GSK_SPV_OP_GLSL_S_MIN = 39,
|
||||
GSK_SPV_OP_GLSL_F_MAX = 40,
|
||||
GSK_SPV_OP_GLSL_U_MAX = 41,
|
||||
GSK_SPV_OP_GLSL_S_MAX = 42,
|
||||
GSK_SPV_OP_GLSL_F_CLAMP = 43,
|
||||
GSK_SPV_OP_GLSL_U_CLAMP = 44,
|
||||
GSK_SPV_OP_GLSL_S_CLAMP = 45,
|
||||
GSK_SPV_OP_GLSL_F_MIX = 46,
|
||||
GSK_SPV_OP_GLSL_I_MIX = 47,
|
||||
GSK_SPV_OP_GLSL_STEP = 48,
|
||||
GSK_SPV_OP_GLSL_SMOOTH_STEP = 49,
|
||||
GSK_SPV_OP_GLSL_FMA = 50,
|
||||
GSK_SPV_OP_GLSL_FREXP = 51,
|
||||
GSK_SPV_OP_GLSL_FREXP_STRUCT = 52,
|
||||
GSK_SPV_OP_GLSL_LDEXP = 53,
|
||||
GSK_SPV_OP_GLSL_PACK_SNORM4X8 = 54,
|
||||
GSK_SPV_OP_GLSL_PACK_UNORM4X8 = 55,
|
||||
GSK_SPV_OP_GLSL_PACK_SNORM2X16 = 56,
|
||||
GSK_SPV_OP_GLSL_PACK_UNORM2X16 = 57,
|
||||
GSK_SPV_OP_GLSL_PACK_HALF2X16 = 58,
|
||||
GSK_SPV_OP_GLSL_PACK_DOUBLE2X32 = 59,
|
||||
GSK_SPV_OP_GLSL_UNPACK_SNORM2X16 = 60,
|
||||
GSK_SPV_OP_GLSL_UNPACK_UNORM2X16 = 61,
|
||||
GSK_SPV_OP_GLSL_UNPACK_HALF2X16 = 62,
|
||||
GSK_SPV_OP_GLSL_UNPACK_SNORM4X8 = 63,
|
||||
GSK_SPV_OP_GLSL_UNPACK_UNORM4X8 = 64,
|
||||
GSK_SPV_OP_GLSL_UNPACK_DOUBLE2X32 = 65,
|
||||
GSK_SPV_OP_GLSL_LENGTH = 66,
|
||||
GSK_SPV_OP_GLSL_DISTANCE = 67,
|
||||
GSK_SPV_OP_GLSL_CROSS = 68,
|
||||
GSK_SPV_OP_GLSL_NORMALIZE = 69,
|
||||
GSK_SPV_OP_GLSL_FACE_FORWARD = 70,
|
||||
GSK_SPV_OP_GLSL_REFLECT = 71,
|
||||
GSK_SPV_OP_GLSL_REFRACT = 72,
|
||||
GSK_SPV_OP_GLSL_FIND_I_LSB = 73,
|
||||
GSK_SPV_OP_GLSL_FIND_S_MSB = 74,
|
||||
GSK_SPV_OP_GLSL_FIND_U_MSB = 75,
|
||||
GSK_SPV_OP_GLSL_INTERPOLATE_AT_CENTROID = 76,
|
||||
GSK_SPV_OP_GLSL_INTERPOLATE_AT_SAMPLE = 77,
|
||||
GSK_SPV_OP_GLSL_INTERPOLATE_AT_OFFSET = 78,
|
||||
GSK_SPV_OP_GLSL_N_MIN = 79,
|
||||
GSK_SPV_OP_GLSL_N_MAX = 80,
|
||||
GSK_SPV_OP_GLSL_N_CLAMP = 81
|
||||
} GskSpvOpcodeGlsl;
|
||||
|
||||
#endif /* __GSK_SPV_GLSL_ENUMS_H__ */
|
855
gsk/gskspvenumsprivate.h
Normal file
855
gsk/gskspvenumsprivate.h
Normal file
@@ -0,0 +1,855 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* !!! THIS FILE WAS AUTOGENERATED !!!
|
||||
*
|
||||
* This file was created using the command
|
||||
* gjs spirv.js enums spirv.core.grammar.json
|
||||
* Apply any changes to those files and then regenerate using above command.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SPV_ENUMS_H__
|
||||
#define __GSK_SPV_ENUMS_H__
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_IMAGE_OPERANDS_NONE = 0x0000,
|
||||
GSK_SPV_IMAGE_OPERANDS_BIAS = 0x0001,
|
||||
GSK_SPV_IMAGE_OPERANDS_LOD = 0x0002,
|
||||
GSK_SPV_IMAGE_OPERANDS_GRAD = 0x0004,
|
||||
GSK_SPV_IMAGE_OPERANDS_CONST_OFFSET = 0x0008,
|
||||
GSK_SPV_IMAGE_OPERANDS_OFFSET = 0x0010,
|
||||
GSK_SPV_IMAGE_OPERANDS_CONST_OFFSETS = 0x0020,
|
||||
GSK_SPV_IMAGE_OPERANDS_SAMPLE = 0x0040,
|
||||
GSK_SPV_IMAGE_OPERANDS_MIN_LOD = 0x0080
|
||||
} GskSpvImageOperands;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_FP_FAST_MATH_MODE_NONE = 0x0000,
|
||||
GSK_SPV_FP_FAST_MATH_MODE_NOT_NA_N = 0x0001,
|
||||
GSK_SPV_FP_FAST_MATH_MODE_NOT_INF = 0x0002,
|
||||
GSK_SPV_FP_FAST_MATH_MODE_NSZ = 0x0004,
|
||||
GSK_SPV_FP_FAST_MATH_MODE_ALLOW_RECIP = 0x0008,
|
||||
GSK_SPV_FP_FAST_MATH_MODE_FAST = 0x0010
|
||||
} GskSpvFPFastMathMode;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_SELECTION_CONTROL_NONE = 0x0000,
|
||||
GSK_SPV_SELECTION_CONTROL_FLATTEN = 0x0001,
|
||||
GSK_SPV_SELECTION_CONTROL_DONT_FLATTEN = 0x0002
|
||||
} GskSpvSelectionControl;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_LOOP_CONTROL_NONE = 0x0000,
|
||||
GSK_SPV_LOOP_CONTROL_UNROLL = 0x0001,
|
||||
GSK_SPV_LOOP_CONTROL_DONT_UNROLL = 0x0002
|
||||
} GskSpvLoopControl;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_FUNCTION_CONTROL_NONE = 0x0000,
|
||||
GSK_SPV_FUNCTION_CONTROL_INLINE = 0x0001,
|
||||
GSK_SPV_FUNCTION_CONTROL_DONT_INLINE = 0x0002,
|
||||
GSK_SPV_FUNCTION_CONTROL_PURE = 0x0004,
|
||||
GSK_SPV_FUNCTION_CONTROL_CONST = 0x0008
|
||||
} GskSpvFunctionControl;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_MEMORY_SEMANTICS_RELAXED = 0x0000,
|
||||
GSK_SPV_MEMORY_SEMANTICS_NONE = 0x0000,
|
||||
GSK_SPV_MEMORY_SEMANTICS_ACQUIRE = 0x0002,
|
||||
GSK_SPV_MEMORY_SEMANTICS_RELEASE = 0x0004,
|
||||
GSK_SPV_MEMORY_SEMANTICS_ACQUIRE_RELEASE = 0x0008,
|
||||
GSK_SPV_MEMORY_SEMANTICS_SEQUENTIALLY_CONSISTENT = 0x0010,
|
||||
GSK_SPV_MEMORY_SEMANTICS_UNIFORM_MEMORY = 0x0040,
|
||||
GSK_SPV_MEMORY_SEMANTICS_SUBGROUP_MEMORY = 0x0080,
|
||||
GSK_SPV_MEMORY_SEMANTICS_WORKGROUP_MEMORY = 0x0100,
|
||||
GSK_SPV_MEMORY_SEMANTICS_CROSS_WORKGROUP_MEMORY = 0x0200,
|
||||
GSK_SPV_MEMORY_SEMANTICS_ATOMIC_COUNTER_MEMORY = 0x0400,
|
||||
GSK_SPV_MEMORY_SEMANTICS_IMAGE_MEMORY = 0x0800
|
||||
} GskSpvMemorySemantics;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_MEMORY_ACCESS_NONE = 0x0000,
|
||||
GSK_SPV_MEMORY_ACCESS_VOLATILE = 0x0001,
|
||||
GSK_SPV_MEMORY_ACCESS_ALIGNED = 0x0002,
|
||||
GSK_SPV_MEMORY_ACCESS_NONTEMPORAL = 0x0004
|
||||
} GskSpvMemoryAccess;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_KERNEL_PROFILING_INFO_NONE = 0x0000,
|
||||
GSK_SPV_KERNEL_PROFILING_INFO_CMD_EXEC_TIME = 0x0001
|
||||
} GskSpvKernelProfilingInfo;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_SOURCE_LANGUAGE_UNKNOWN = 0,
|
||||
GSK_SPV_SOURCE_LANGUAGE_ESSL = 1,
|
||||
GSK_SPV_SOURCE_LANGUAGE_GLSL = 2,
|
||||
GSK_SPV_SOURCE_LANGUAGE_OPEN_CL_C = 3,
|
||||
GSK_SPV_SOURCE_LANGUAGE_OPEN_CL_CPP = 4,
|
||||
GSK_SPV_SOURCE_LANGUAGE_HLSL = 5
|
||||
} GskSpvSourceLanguage;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_EXECUTION_MODEL_VERTEX = 0,
|
||||
GSK_SPV_EXECUTION_MODEL_TESSELLATION_CONTROL = 1,
|
||||
GSK_SPV_EXECUTION_MODEL_TESSELLATION_EVALUATION = 2,
|
||||
GSK_SPV_EXECUTION_MODEL_GEOMETRY = 3,
|
||||
GSK_SPV_EXECUTION_MODEL_FRAGMENT = 4,
|
||||
GSK_SPV_EXECUTION_MODEL_GL_COMPUTE = 5,
|
||||
GSK_SPV_EXECUTION_MODEL_KERNEL = 6
|
||||
} GskSpvExecutionModel;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_ADDRESSING_MODEL_LOGICAL = 0,
|
||||
GSK_SPV_ADDRESSING_MODEL_PHYSICAL32 = 1,
|
||||
GSK_SPV_ADDRESSING_MODEL_PHYSICAL64 = 2
|
||||
} GskSpvAddressingModel;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_MEMORY_MODEL_SIMPLE = 0,
|
||||
GSK_SPV_MEMORY_MODEL_GLSL450 = 1,
|
||||
GSK_SPV_MEMORY_MODEL_OPEN_CL = 2
|
||||
} GskSpvMemoryModel;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_EXECUTION_MODE_INVOCATIONS = 0,
|
||||
GSK_SPV_EXECUTION_MODE_SPACING_EQUAL = 1,
|
||||
GSK_SPV_EXECUTION_MODE_SPACING_FRACTIONAL_EVEN = 2,
|
||||
GSK_SPV_EXECUTION_MODE_SPACING_FRACTIONAL_ODD = 3,
|
||||
GSK_SPV_EXECUTION_MODE_VERTEX_ORDER_CW = 4,
|
||||
GSK_SPV_EXECUTION_MODE_VERTEX_ORDER_CCW = 5,
|
||||
GSK_SPV_EXECUTION_MODE_PIXEL_CENTER_INTEGER = 6,
|
||||
GSK_SPV_EXECUTION_MODE_ORIGIN_UPPER_LEFT = 7,
|
||||
GSK_SPV_EXECUTION_MODE_ORIGIN_LOWER_LEFT = 8,
|
||||
GSK_SPV_EXECUTION_MODE_EARLY_FRAGMENT_TESTS = 9,
|
||||
GSK_SPV_EXECUTION_MODE_POINT_MODE = 10,
|
||||
GSK_SPV_EXECUTION_MODE_XFB = 11,
|
||||
GSK_SPV_EXECUTION_MODE_DEPTH_REPLACING = 12,
|
||||
GSK_SPV_EXECUTION_MODE_DEPTH_GREATER = 14,
|
||||
GSK_SPV_EXECUTION_MODE_DEPTH_LESS = 15,
|
||||
GSK_SPV_EXECUTION_MODE_DEPTH_UNCHANGED = 16,
|
||||
GSK_SPV_EXECUTION_MODE_LOCAL_SIZE = 17,
|
||||
GSK_SPV_EXECUTION_MODE_LOCAL_SIZE_HINT = 18,
|
||||
GSK_SPV_EXECUTION_MODE_INPUT_POINTS = 19,
|
||||
GSK_SPV_EXECUTION_MODE_INPUT_LINES = 20,
|
||||
GSK_SPV_EXECUTION_MODE_INPUT_LINES_ADJACENCY = 21,
|
||||
GSK_SPV_EXECUTION_MODE_TRIANGLES = 22,
|
||||
GSK_SPV_EXECUTION_MODE_INPUT_TRIANGLES_ADJACENCY = 23,
|
||||
GSK_SPV_EXECUTION_MODE_QUADS = 24,
|
||||
GSK_SPV_EXECUTION_MODE_ISOLINES = 25,
|
||||
GSK_SPV_EXECUTION_MODE_OUTPUT_VERTICES = 26,
|
||||
GSK_SPV_EXECUTION_MODE_OUTPUT_POINTS = 27,
|
||||
GSK_SPV_EXECUTION_MODE_OUTPUT_LINE_STRIP = 28,
|
||||
GSK_SPV_EXECUTION_MODE_OUTPUT_TRIANGLE_STRIP = 29,
|
||||
GSK_SPV_EXECUTION_MODE_VEC_TYPE_HINT = 30,
|
||||
GSK_SPV_EXECUTION_MODE_CONTRACTION_OFF = 31,
|
||||
GSK_SPV_EXECUTION_MODE_POST_DEPTH_COVERAGE = 4446,
|
||||
GSK_SPV_EXECUTION_MODE_STENCIL_REF_REPLACING_EXT = 5027
|
||||
} GskSpvExecutionMode;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_STORAGE_CLASS_UNIFORM_CONSTANT = 0,
|
||||
GSK_SPV_STORAGE_CLASS_INPUT = 1,
|
||||
GSK_SPV_STORAGE_CLASS_UNIFORM = 2,
|
||||
GSK_SPV_STORAGE_CLASS_OUTPUT = 3,
|
||||
GSK_SPV_STORAGE_CLASS_WORKGROUP = 4,
|
||||
GSK_SPV_STORAGE_CLASS_CROSS_WORKGROUP = 5,
|
||||
GSK_SPV_STORAGE_CLASS_PRIVATE = 6,
|
||||
GSK_SPV_STORAGE_CLASS_FUNCTION = 7,
|
||||
GSK_SPV_STORAGE_CLASS_GENERIC = 8,
|
||||
GSK_SPV_STORAGE_CLASS_PUSH_CONSTANT = 9,
|
||||
GSK_SPV_STORAGE_CLASS_ATOMIC_COUNTER = 10,
|
||||
GSK_SPV_STORAGE_CLASS_IMAGE = 11,
|
||||
GSK_SPV_STORAGE_CLASS_STORAGE_BUFFER = 12
|
||||
} GskSpvStorageClass;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_DIM_1_D = 0,
|
||||
GSK_SPV_DIM_2_D = 1,
|
||||
GSK_SPV_DIM_3_D = 2,
|
||||
GSK_SPV_DIM_CUBE = 3,
|
||||
GSK_SPV_DIM_RECT = 4,
|
||||
GSK_SPV_DIM_BUFFER = 5,
|
||||
GSK_SPV_DIM_SUBPASS_DATA = 6
|
||||
} GskSpvDim;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_SAMPLER_ADDRESSING_MODE_NONE = 0,
|
||||
GSK_SPV_SAMPLER_ADDRESSING_MODE_CLAMP_TO_EDGE = 1,
|
||||
GSK_SPV_SAMPLER_ADDRESSING_MODE_CLAMP = 2,
|
||||
GSK_SPV_SAMPLER_ADDRESSING_MODE_REPEAT = 3,
|
||||
GSK_SPV_SAMPLER_ADDRESSING_MODE_REPEAT_MIRRORED = 4
|
||||
} GskSpvSamplerAddressingMode;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_SAMPLER_FILTER_MODE_NEAREST = 0,
|
||||
GSK_SPV_SAMPLER_FILTER_MODE_LINEAR = 1
|
||||
} GskSpvSamplerFilterMode;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_IMAGE_FORMAT_UNKNOWN = 0,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA32F = 1,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA16F = 2,
|
||||
GSK_SPV_IMAGE_FORMAT_R32F = 3,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA8 = 4,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA8_SNORM = 5,
|
||||
GSK_SPV_IMAGE_FORMAT_RG32F = 6,
|
||||
GSK_SPV_IMAGE_FORMAT_RG16F = 7,
|
||||
GSK_SPV_IMAGE_FORMAT_R11F_G11F_B10F = 8,
|
||||
GSK_SPV_IMAGE_FORMAT_R16F = 9,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA16 = 10,
|
||||
GSK_SPV_IMAGE_FORMAT_RGB10_A2 = 11,
|
||||
GSK_SPV_IMAGE_FORMAT_RG16 = 12,
|
||||
GSK_SPV_IMAGE_FORMAT_RG8 = 13,
|
||||
GSK_SPV_IMAGE_FORMAT_R16 = 14,
|
||||
GSK_SPV_IMAGE_FORMAT_R8 = 15,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA16_SNORM = 16,
|
||||
GSK_SPV_IMAGE_FORMAT_RG16_SNORM = 17,
|
||||
GSK_SPV_IMAGE_FORMAT_RG8_SNORM = 18,
|
||||
GSK_SPV_IMAGE_FORMAT_R16_SNORM = 19,
|
||||
GSK_SPV_IMAGE_FORMAT_R8_SNORM = 20,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA32I = 21,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA16I = 22,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA8I = 23,
|
||||
GSK_SPV_IMAGE_FORMAT_R32I = 24,
|
||||
GSK_SPV_IMAGE_FORMAT_RG32I = 25,
|
||||
GSK_SPV_IMAGE_FORMAT_RG16I = 26,
|
||||
GSK_SPV_IMAGE_FORMAT_RG8I = 27,
|
||||
GSK_SPV_IMAGE_FORMAT_R16I = 28,
|
||||
GSK_SPV_IMAGE_FORMAT_R8I = 29,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA32UI = 30,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA16UI = 31,
|
||||
GSK_SPV_IMAGE_FORMAT_RGBA8UI = 32,
|
||||
GSK_SPV_IMAGE_FORMAT_R32UI = 33,
|
||||
GSK_SPV_IMAGE_FORMAT_RGB10A2UI = 34,
|
||||
GSK_SPV_IMAGE_FORMAT_RG32UI = 35,
|
||||
GSK_SPV_IMAGE_FORMAT_RG16UI = 36,
|
||||
GSK_SPV_IMAGE_FORMAT_RG8UI = 37,
|
||||
GSK_SPV_IMAGE_FORMAT_R16UI = 38,
|
||||
GSK_SPV_IMAGE_FORMAT_R8UI = 39
|
||||
} GskSpvImageFormat;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_R = 0,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_A = 1,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_RG = 2,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_RA = 3,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_RGB = 4,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_RGBA = 5,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_BGRA = 6,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_ARGB = 7,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_INTENSITY = 8,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_LUMINANCE = 9,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_RX = 10,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_R_GX = 11,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_RG_BX = 12,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_DEPTH = 13,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL = 14,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_S_RGB = 15,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_S_RG_BX = 16,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_S_RGBA = 17,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_S_BGRA = 18,
|
||||
GSK_SPV_IMAGE_CHANNEL_ORDER_ABGR = 19
|
||||
} GskSpvImageChannelOrder;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_SNORM_INT8 = 0,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_SNORM_INT16 = 1,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNORM_INT8 = 2,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNORM_INT16 = 3,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNORM_SHORT565 = 4,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNORM_SHORT555 = 5,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNORM_INT101010 = 6,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_SIGNED_INT8 = 7,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_SIGNED_INT16 = 8,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_SIGNED_INT32 = 9,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNSIGNED_INT8 = 10,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNSIGNED_INT16 = 11,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNSIGNED_INT32 = 12,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_HALF_FLOAT = 13,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_FLOAT = 14,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNORM_INT24 = 15,
|
||||
GSK_SPV_IMAGE_CHANNEL_DATA_TYPE_UNORM_INT101010_2 = 16
|
||||
} GskSpvImageChannelDataType;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_FP_ROUNDING_MODE_RTE = 0,
|
||||
GSK_SPV_FP_ROUNDING_MODE_RTZ = 1,
|
||||
GSK_SPV_FP_ROUNDING_MODE_RTP = 2,
|
||||
GSK_SPV_FP_ROUNDING_MODE_RTN = 3
|
||||
} GskSpvFPRoundingMode;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_LINKAGE_TYPE_EXPORT = 0,
|
||||
GSK_SPV_LINKAGE_TYPE_IMPORT = 1
|
||||
} GskSpvLinkageType;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_ACCESS_QUALIFIER_READ_ONLY = 0,
|
||||
GSK_SPV_ACCESS_QUALIFIER_WRITE_ONLY = 1,
|
||||
GSK_SPV_ACCESS_QUALIFIER_READ_WRITE = 2
|
||||
} GskSpvAccessQualifier;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_ZEXT = 0,
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_SEXT = 1,
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_BY_VAL = 2,
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_SRET = 3,
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_NO_ALIAS = 4,
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_NO_CAPTURE = 5,
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_NO_WRITE = 6,
|
||||
GSK_SPV_FUNCTION_PARAMETER_ATTRIBUTE_NO_READ_WRITE = 7
|
||||
} GskSpvFunctionParameterAttribute;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_DECORATION_RELAXED_PRECISION = 0,
|
||||
GSK_SPV_DECORATION_SPEC_ID = 1,
|
||||
GSK_SPV_DECORATION_BLOCK = 2,
|
||||
GSK_SPV_DECORATION_BUFFER_BLOCK = 3,
|
||||
GSK_SPV_DECORATION_ROW_MAJOR = 4,
|
||||
GSK_SPV_DECORATION_COL_MAJOR = 5,
|
||||
GSK_SPV_DECORATION_ARRAY_STRIDE = 6,
|
||||
GSK_SPV_DECORATION_MATRIX_STRIDE = 7,
|
||||
GSK_SPV_DECORATION_GLSL_SHARED = 8,
|
||||
GSK_SPV_DECORATION_GLSL_PACKED = 9,
|
||||
GSK_SPV_DECORATION_C_PACKED = 10,
|
||||
GSK_SPV_DECORATION_BUILT_IN = 11,
|
||||
GSK_SPV_DECORATION_NO_PERSPECTIVE = 13,
|
||||
GSK_SPV_DECORATION_FLAT = 14,
|
||||
GSK_SPV_DECORATION_PATCH = 15,
|
||||
GSK_SPV_DECORATION_CENTROID = 16,
|
||||
GSK_SPV_DECORATION_SAMPLE = 17,
|
||||
GSK_SPV_DECORATION_INVARIANT = 18,
|
||||
GSK_SPV_DECORATION_RESTRICT = 19,
|
||||
GSK_SPV_DECORATION_ALIASED = 20,
|
||||
GSK_SPV_DECORATION_VOLATILE = 21,
|
||||
GSK_SPV_DECORATION_CONSTANT = 22,
|
||||
GSK_SPV_DECORATION_COHERENT = 23,
|
||||
GSK_SPV_DECORATION_NON_WRITABLE = 24,
|
||||
GSK_SPV_DECORATION_NON_READABLE = 25,
|
||||
GSK_SPV_DECORATION_UNIFORM = 26,
|
||||
GSK_SPV_DECORATION_SATURATED_CONVERSION = 28,
|
||||
GSK_SPV_DECORATION_STREAM = 29,
|
||||
GSK_SPV_DECORATION_LOCATION = 30,
|
||||
GSK_SPV_DECORATION_COMPONENT = 31,
|
||||
GSK_SPV_DECORATION_INDEX = 32,
|
||||
GSK_SPV_DECORATION_BINDING = 33,
|
||||
GSK_SPV_DECORATION_DESCRIPTOR_SET = 34,
|
||||
GSK_SPV_DECORATION_OFFSET = 35,
|
||||
GSK_SPV_DECORATION_XFB_BUFFER = 36,
|
||||
GSK_SPV_DECORATION_XFB_STRIDE = 37,
|
||||
GSK_SPV_DECORATION_FUNC_PARAM_ATTR = 38,
|
||||
GSK_SPV_DECORATION_FP_ROUNDING_MODE = 39,
|
||||
GSK_SPV_DECORATION_FP_FAST_MATH_MODE = 40,
|
||||
GSK_SPV_DECORATION_LINKAGE_ATTRIBUTES = 41,
|
||||
GSK_SPV_DECORATION_NO_CONTRACTION = 42,
|
||||
GSK_SPV_DECORATION_INPUT_ATTACHMENT_INDEX = 43,
|
||||
GSK_SPV_DECORATION_ALIGNMENT = 44,
|
||||
GSK_SPV_DECORATION_EXPLICIT_INTERP_AMD = 4999,
|
||||
GSK_SPV_DECORATION_OVERRIDE_COVERAGE_NV = 5248,
|
||||
GSK_SPV_DECORATION_PASSTHROUGH_NV = 5250,
|
||||
GSK_SPV_DECORATION_VIEWPORT_RELATIVE_NV = 5252,
|
||||
GSK_SPV_DECORATION_SECONDARY_VIEWPORT_RELATIVE_NV = 5256
|
||||
} GskSpvDecoration;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_BUILT_IN_POSITION = 0,
|
||||
GSK_SPV_BUILT_IN_POINT_SIZE = 1,
|
||||
GSK_SPV_BUILT_IN_CLIP_DISTANCE = 3,
|
||||
GSK_SPV_BUILT_IN_CULL_DISTANCE = 4,
|
||||
GSK_SPV_BUILT_IN_VERTEX_ID = 5,
|
||||
GSK_SPV_BUILT_IN_INSTANCE_ID = 6,
|
||||
GSK_SPV_BUILT_IN_PRIMITIVE_ID = 7,
|
||||
GSK_SPV_BUILT_IN_INVOCATION_ID = 8,
|
||||
GSK_SPV_BUILT_IN_LAYER = 9,
|
||||
GSK_SPV_BUILT_IN_VIEWPORT_INDEX = 10,
|
||||
GSK_SPV_BUILT_IN_TESS_LEVEL_OUTER = 11,
|
||||
GSK_SPV_BUILT_IN_TESS_LEVEL_INNER = 12,
|
||||
GSK_SPV_BUILT_IN_TESS_COORD = 13,
|
||||
GSK_SPV_BUILT_IN_PATCH_VERTICES = 14,
|
||||
GSK_SPV_BUILT_IN_FRAG_COORD = 15,
|
||||
GSK_SPV_BUILT_IN_POINT_COORD = 16,
|
||||
GSK_SPV_BUILT_IN_FRONT_FACING = 17,
|
||||
GSK_SPV_BUILT_IN_SAMPLE_ID = 18,
|
||||
GSK_SPV_BUILT_IN_SAMPLE_POSITION = 19,
|
||||
GSK_SPV_BUILT_IN_SAMPLE_MASK = 20,
|
||||
GSK_SPV_BUILT_IN_FRAG_DEPTH = 22,
|
||||
GSK_SPV_BUILT_IN_HELPER_INVOCATION = 23,
|
||||
GSK_SPV_BUILT_IN_NUM_WORKGROUPS = 24,
|
||||
GSK_SPV_BUILT_IN_WORKGROUP_SIZE = 25,
|
||||
GSK_SPV_BUILT_IN_WORKGROUP_ID = 26,
|
||||
GSK_SPV_BUILT_IN_LOCAL_INVOCATION_ID = 27,
|
||||
GSK_SPV_BUILT_IN_GLOBAL_INVOCATION_ID = 28,
|
||||
GSK_SPV_BUILT_IN_LOCAL_INVOCATION_INDEX = 29,
|
||||
GSK_SPV_BUILT_IN_WORK_DIM = 30,
|
||||
GSK_SPV_BUILT_IN_GLOBAL_SIZE = 31,
|
||||
GSK_SPV_BUILT_IN_ENQUEUED_WORKGROUP_SIZE = 32,
|
||||
GSK_SPV_BUILT_IN_GLOBAL_OFFSET = 33,
|
||||
GSK_SPV_BUILT_IN_GLOBAL_LINEAR_ID = 34,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_SIZE = 36,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_MAX_SIZE = 37,
|
||||
GSK_SPV_BUILT_IN_NUM_SUBGROUPS = 38,
|
||||
GSK_SPV_BUILT_IN_NUM_ENQUEUED_SUBGROUPS = 39,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_ID = 40,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_LOCAL_INVOCATION_ID = 41,
|
||||
GSK_SPV_BUILT_IN_VERTEX_INDEX = 42,
|
||||
GSK_SPV_BUILT_IN_INSTANCE_INDEX = 43,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_EQ_MASK_KHR = 4416,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_GE_MASK_KHR = 4417,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_GT_MASK_KHR = 4418,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_LE_MASK_KHR = 4419,
|
||||
GSK_SPV_BUILT_IN_SUBGROUP_LT_MASK_KHR = 4420,
|
||||
GSK_SPV_BUILT_IN_BASE_VERTEX = 4424,
|
||||
GSK_SPV_BUILT_IN_BASE_INSTANCE = 4425,
|
||||
GSK_SPV_BUILT_IN_DRAW_INDEX = 4426,
|
||||
GSK_SPV_BUILT_IN_DEVICE_INDEX = 4438,
|
||||
GSK_SPV_BUILT_IN_VIEW_INDEX = 4440,
|
||||
GSK_SPV_BUILT_IN_BARY_COORD_NO_PERSP_AMD = 4992,
|
||||
GSK_SPV_BUILT_IN_BARY_COORD_NO_PERSP_CENTROID_AMD = 4993,
|
||||
GSK_SPV_BUILT_IN_BARY_COORD_NO_PERSP_SAMPLE_AMD = 4994,
|
||||
GSK_SPV_BUILT_IN_BARY_COORD_SMOOTH_AMD = 4995,
|
||||
GSK_SPV_BUILT_IN_BARY_COORD_SMOOTH_CENTROID_AMD = 4996,
|
||||
GSK_SPV_BUILT_IN_BARY_COORD_SMOOTH_SAMPLE_AMD = 4997,
|
||||
GSK_SPV_BUILT_IN_BARY_COORD_PULL_MODEL_AMD = 4998,
|
||||
GSK_SPV_BUILT_IN_FRAG_STENCIL_REF_EXT = 5014,
|
||||
GSK_SPV_BUILT_IN_VIEWPORT_MASK_NV = 5253,
|
||||
GSK_SPV_BUILT_IN_SECONDARY_POSITION_NV = 5257,
|
||||
GSK_SPV_BUILT_IN_SECONDARY_VIEWPORT_MASK_NV = 5258,
|
||||
GSK_SPV_BUILT_IN_POSITION_PER_VIEW_NV = 5261,
|
||||
GSK_SPV_BUILT_IN_VIEWPORT_MASK_PER_VIEW_NV = 5262
|
||||
} GskSpvBuiltIn;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_SCOPE_CROSS_DEVICE = 0,
|
||||
GSK_SPV_SCOPE_DEVICE = 1,
|
||||
GSK_SPV_SCOPE_WORKGROUP = 2,
|
||||
GSK_SPV_SCOPE_SUBGROUP = 3,
|
||||
GSK_SPV_SCOPE_INVOCATION = 4
|
||||
} GskSpvScope;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_GROUP_OPERATION_REDUCE = 0,
|
||||
GSK_SPV_GROUP_OPERATION_INCLUSIVE_SCAN = 1,
|
||||
GSK_SPV_GROUP_OPERATION_EXCLUSIVE_SCAN = 2
|
||||
} GskSpvGroupOperation;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_KERNEL_ENQUEUE_FLAGS_NO_WAIT = 0,
|
||||
GSK_SPV_KERNEL_ENQUEUE_FLAGS_WAIT_KERNEL = 1,
|
||||
GSK_SPV_KERNEL_ENQUEUE_FLAGS_WAIT_WORK_GROUP = 2
|
||||
} GskSpvKernelEnqueueFlags;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_CAPABILITY_MATRIX = 0,
|
||||
GSK_SPV_CAPABILITY_SHADER = 1,
|
||||
GSK_SPV_CAPABILITY_GEOMETRY = 2,
|
||||
GSK_SPV_CAPABILITY_TESSELLATION = 3,
|
||||
GSK_SPV_CAPABILITY_ADDRESSES = 4,
|
||||
GSK_SPV_CAPABILITY_LINKAGE = 5,
|
||||
GSK_SPV_CAPABILITY_KERNEL = 6,
|
||||
GSK_SPV_CAPABILITY_VECTOR16 = 7,
|
||||
GSK_SPV_CAPABILITY_FLOAT16_BUFFER = 8,
|
||||
GSK_SPV_CAPABILITY_FLOAT16 = 9,
|
||||
GSK_SPV_CAPABILITY_FLOAT64 = 10,
|
||||
GSK_SPV_CAPABILITY_INT64 = 11,
|
||||
GSK_SPV_CAPABILITY_INT64_ATOMICS = 12,
|
||||
GSK_SPV_CAPABILITY_IMAGE_BASIC = 13,
|
||||
GSK_SPV_CAPABILITY_IMAGE_READ_WRITE = 14,
|
||||
GSK_SPV_CAPABILITY_IMAGE_MIPMAP = 15,
|
||||
GSK_SPV_CAPABILITY_PIPES = 17,
|
||||
GSK_SPV_CAPABILITY_GROUPS = 18,
|
||||
GSK_SPV_CAPABILITY_DEVICE_ENQUEUE = 19,
|
||||
GSK_SPV_CAPABILITY_LITERAL_SAMPLER = 20,
|
||||
GSK_SPV_CAPABILITY_ATOMIC_STORAGE = 21,
|
||||
GSK_SPV_CAPABILITY_INT16 = 22,
|
||||
GSK_SPV_CAPABILITY_TESSELLATION_POINT_SIZE = 23,
|
||||
GSK_SPV_CAPABILITY_GEOMETRY_POINT_SIZE = 24,
|
||||
GSK_SPV_CAPABILITY_IMAGE_GATHER_EXTENDED = 25,
|
||||
GSK_SPV_CAPABILITY_STORAGE_IMAGE_MULTISAMPLE = 27,
|
||||
GSK_SPV_CAPABILITY_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING = 28,
|
||||
GSK_SPV_CAPABILITY_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING = 29,
|
||||
GSK_SPV_CAPABILITY_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING = 30,
|
||||
GSK_SPV_CAPABILITY_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING = 31,
|
||||
GSK_SPV_CAPABILITY_CLIP_DISTANCE = 32,
|
||||
GSK_SPV_CAPABILITY_CULL_DISTANCE = 33,
|
||||
GSK_SPV_CAPABILITY_IMAGE_CUBE_ARRAY = 34,
|
||||
GSK_SPV_CAPABILITY_SAMPLE_RATE_SHADING = 35,
|
||||
GSK_SPV_CAPABILITY_IMAGE_RECT = 36,
|
||||
GSK_SPV_CAPABILITY_SAMPLED_RECT = 37,
|
||||
GSK_SPV_CAPABILITY_GENERIC_POINTER = 38,
|
||||
GSK_SPV_CAPABILITY_INT8 = 39,
|
||||
GSK_SPV_CAPABILITY_INPUT_ATTACHMENT = 40,
|
||||
GSK_SPV_CAPABILITY_SPARSE_RESIDENCY = 41,
|
||||
GSK_SPV_CAPABILITY_MIN_LOD = 42,
|
||||
GSK_SPV_CAPABILITY_SAMPLED1_D = 43,
|
||||
GSK_SPV_CAPABILITY_IMAGE1_D = 44,
|
||||
GSK_SPV_CAPABILITY_SAMPLED_CUBE_ARRAY = 45,
|
||||
GSK_SPV_CAPABILITY_SAMPLED_BUFFER = 46,
|
||||
GSK_SPV_CAPABILITY_IMAGE_BUFFER = 47,
|
||||
GSK_SPV_CAPABILITY_IMAGE_MS_ARRAY = 48,
|
||||
GSK_SPV_CAPABILITY_STORAGE_IMAGE_EXTENDED_FORMATS = 49,
|
||||
GSK_SPV_CAPABILITY_IMAGE_QUERY = 50,
|
||||
GSK_SPV_CAPABILITY_DERIVATIVE_CONTROL = 51,
|
||||
GSK_SPV_CAPABILITY_INTERPOLATION_FUNCTION = 52,
|
||||
GSK_SPV_CAPABILITY_TRANSFORM_FEEDBACK = 53,
|
||||
GSK_SPV_CAPABILITY_GEOMETRY_STREAMS = 54,
|
||||
GSK_SPV_CAPABILITY_STORAGE_IMAGE_READ_WITHOUT_FORMAT = 55,
|
||||
GSK_SPV_CAPABILITY_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT = 56,
|
||||
GSK_SPV_CAPABILITY_MULTI_VIEWPORT = 57,
|
||||
GSK_SPV_CAPABILITY_SUBGROUP_BALLOT_KHR = 4423,
|
||||
GSK_SPV_CAPABILITY_DRAW_PARAMETERS = 4427,
|
||||
GSK_SPV_CAPABILITY_SUBGROUP_VOTE_KHR = 4431,
|
||||
GSK_SPV_CAPABILITY_STORAGE_BUFFER16_BIT_ACCESS = 4433,
|
||||
GSK_SPV_CAPABILITY_STORAGE_UNIFORM_BUFFER_BLOCK16 = 4433,
|
||||
GSK_SPV_CAPABILITY_UNIFORM_AND_STORAGE_BUFFER16_BIT_ACCESS = 4434,
|
||||
GSK_SPV_CAPABILITY_STORAGE_UNIFORM16 = 4434,
|
||||
GSK_SPV_CAPABILITY_STORAGE_PUSH_CONSTANT16 = 4435,
|
||||
GSK_SPV_CAPABILITY_STORAGE_INPUT_OUTPUT16 = 4436,
|
||||
GSK_SPV_CAPABILITY_DEVICE_GROUP = 4437,
|
||||
GSK_SPV_CAPABILITY_MULTI_VIEW = 4439,
|
||||
GSK_SPV_CAPABILITY_VARIABLE_POINTERS_STORAGE_BUFFER = 4441,
|
||||
GSK_SPV_CAPABILITY_VARIABLE_POINTERS = 4442,
|
||||
GSK_SPV_CAPABILITY_ATOMIC_STORAGE_OPS = 4445,
|
||||
GSK_SPV_CAPABILITY_SAMPLE_MASK_POST_DEPTH_COVERAGE = 4447,
|
||||
GSK_SPV_CAPABILITY_IMAGE_GATHER_BIAS_LOD_AMD = 5009,
|
||||
GSK_SPV_CAPABILITY_FRAGMENT_MASK_AMD = 5010,
|
||||
GSK_SPV_CAPABILITY_STENCIL_EXPORT_EXT = 5013,
|
||||
GSK_SPV_CAPABILITY_IMAGE_READ_WRITE_LOD_AMD = 5015,
|
||||
GSK_SPV_CAPABILITY_SAMPLE_MASK_OVERRIDE_COVERAGE_NV = 5249,
|
||||
GSK_SPV_CAPABILITY_GEOMETRY_SHADER_PASSTHROUGH_NV = 5251,
|
||||
GSK_SPV_CAPABILITY_SHADER_VIEWPORT_INDEX_LAYER_EXT = 5254,
|
||||
GSK_SPV_CAPABILITY_SHADER_VIEWPORT_INDEX_LAYER_NV = 5254,
|
||||
GSK_SPV_CAPABILITY_SHADER_VIEWPORT_MASK_NV = 5255,
|
||||
GSK_SPV_CAPABILITY_SHADER_STEREO_VIEW_NV = 5259,
|
||||
GSK_SPV_CAPABILITY_PER_VIEW_ATTRIBUTES_NV = 5260
|
||||
} GskSpvCapability;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_OP_NOP = 0,
|
||||
GSK_SPV_OP_UNDEF = 1,
|
||||
GSK_SPV_OP_SOURCE_CONTINUED = 2,
|
||||
GSK_SPV_OP_SOURCE = 3,
|
||||
GSK_SPV_OP_SOURCE_EXTENSION = 4,
|
||||
GSK_SPV_OP_NAME = 5,
|
||||
GSK_SPV_OP_MEMBER_NAME = 6,
|
||||
GSK_SPV_OP_STRING = 7,
|
||||
GSK_SPV_OP_LINE = 8,
|
||||
GSK_SPV_OP_EXTENSION = 10,
|
||||
GSK_SPV_OP_EXT_INST_IMPORT = 11,
|
||||
GSK_SPV_OP_EXT_INST = 12,
|
||||
GSK_SPV_OP_MEMORY_MODEL = 14,
|
||||
GSK_SPV_OP_ENTRY_POINT = 15,
|
||||
GSK_SPV_OP_EXECUTION_MODE = 16,
|
||||
GSK_SPV_OP_CAPABILITY = 17,
|
||||
GSK_SPV_OP_TYPE_VOID = 19,
|
||||
GSK_SPV_OP_TYPE_BOOL = 20,
|
||||
GSK_SPV_OP_TYPE_INT = 21,
|
||||
GSK_SPV_OP_TYPE_FLOAT = 22,
|
||||
GSK_SPV_OP_TYPE_VECTOR = 23,
|
||||
GSK_SPV_OP_TYPE_MATRIX = 24,
|
||||
GSK_SPV_OP_TYPE_IMAGE = 25,
|
||||
GSK_SPV_OP_TYPE_SAMPLER = 26,
|
||||
GSK_SPV_OP_TYPE_SAMPLED_IMAGE = 27,
|
||||
GSK_SPV_OP_TYPE_ARRAY = 28,
|
||||
GSK_SPV_OP_TYPE_RUNTIME_ARRAY = 29,
|
||||
GSK_SPV_OP_TYPE_STRUCT = 30,
|
||||
GSK_SPV_OP_TYPE_OPAQUE = 31,
|
||||
GSK_SPV_OP_TYPE_POINTER = 32,
|
||||
GSK_SPV_OP_TYPE_FUNCTION = 33,
|
||||
GSK_SPV_OP_TYPE_EVENT = 34,
|
||||
GSK_SPV_OP_TYPE_DEVICE_EVENT = 35,
|
||||
GSK_SPV_OP_TYPE_RESERVE_ID = 36,
|
||||
GSK_SPV_OP_TYPE_QUEUE = 37,
|
||||
GSK_SPV_OP_TYPE_PIPE = 38,
|
||||
GSK_SPV_OP_TYPE_FORWARD_POINTER = 39,
|
||||
GSK_SPV_OP_CONSTANT_TRUE = 41,
|
||||
GSK_SPV_OP_CONSTANT_FALSE = 42,
|
||||
GSK_SPV_OP_CONSTANT = 43,
|
||||
GSK_SPV_OP_CONSTANT_COMPOSITE = 44,
|
||||
GSK_SPV_OP_CONSTANT_SAMPLER = 45,
|
||||
GSK_SPV_OP_CONSTANT_NULL = 46,
|
||||
GSK_SPV_OP_SPEC_CONSTANT_TRUE = 48,
|
||||
GSK_SPV_OP_SPEC_CONSTANT_FALSE = 49,
|
||||
GSK_SPV_OP_SPEC_CONSTANT = 50,
|
||||
GSK_SPV_OP_SPEC_CONSTANT_COMPOSITE = 51,
|
||||
GSK_SPV_OP_SPEC_CONSTANT_OP = 52,
|
||||
GSK_SPV_OP_FUNCTION = 54,
|
||||
GSK_SPV_OP_FUNCTION_PARAMETER = 55,
|
||||
GSK_SPV_OP_FUNCTION_END = 56,
|
||||
GSK_SPV_OP_FUNCTION_CALL = 57,
|
||||
GSK_SPV_OP_VARIABLE = 59,
|
||||
GSK_SPV_OP_IMAGE_TEXEL_POINTER = 60,
|
||||
GSK_SPV_OP_LOAD = 61,
|
||||
GSK_SPV_OP_STORE = 62,
|
||||
GSK_SPV_OP_COPY_MEMORY = 63,
|
||||
GSK_SPV_OP_COPY_MEMORY_SIZED = 64,
|
||||
GSK_SPV_OP_ACCESS_CHAIN = 65,
|
||||
GSK_SPV_OP_IN_BOUNDS_ACCESS_CHAIN = 66,
|
||||
GSK_SPV_OP_PTR_ACCESS_CHAIN = 67,
|
||||
GSK_SPV_OP_ARRAY_LENGTH = 68,
|
||||
GSK_SPV_OP_GENERIC_PTR_MEM_SEMANTICS = 69,
|
||||
GSK_SPV_OP_IN_BOUNDS_PTR_ACCESS_CHAIN = 70,
|
||||
GSK_SPV_OP_DECORATE = 71,
|
||||
GSK_SPV_OP_MEMBER_DECORATE = 72,
|
||||
GSK_SPV_OP_DECORATION_GROUP = 73,
|
||||
GSK_SPV_OP_GROUP_DECORATE = 74,
|
||||
GSK_SPV_OP_GROUP_MEMBER_DECORATE = 75,
|
||||
GSK_SPV_OP_VECTOR_EXTRACT_DYNAMIC = 77,
|
||||
GSK_SPV_OP_VECTOR_INSERT_DYNAMIC = 78,
|
||||
GSK_SPV_OP_VECTOR_SHUFFLE = 79,
|
||||
GSK_SPV_OP_COMPOSITE_CONSTRUCT = 80,
|
||||
GSK_SPV_OP_COMPOSITE_EXTRACT = 81,
|
||||
GSK_SPV_OP_COMPOSITE_INSERT = 82,
|
||||
GSK_SPV_OP_COPY_OBJECT = 83,
|
||||
GSK_SPV_OP_TRANSPOSE = 84,
|
||||
GSK_SPV_OP_SAMPLED_IMAGE = 86,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_IMPLICIT_LOD = 87,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_EXPLICIT_LOD = 88,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_DREF_IMPLICIT_LOD = 89,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_DREF_EXPLICIT_LOD = 90,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_PROJ_IMPLICIT_LOD = 91,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_PROJ_EXPLICIT_LOD = 92,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_PROJ_DREF_IMPLICIT_LOD = 93,
|
||||
GSK_SPV_OP_IMAGE_SAMPLE_PROJ_DREF_EXPLICIT_LOD = 94,
|
||||
GSK_SPV_OP_IMAGE_FETCH = 95,
|
||||
GSK_SPV_OP_IMAGE_GATHER = 96,
|
||||
GSK_SPV_OP_IMAGE_DREF_GATHER = 97,
|
||||
GSK_SPV_OP_IMAGE_READ = 98,
|
||||
GSK_SPV_OP_IMAGE_WRITE = 99,
|
||||
GSK_SPV_OP_IMAGE = 100,
|
||||
GSK_SPV_OP_IMAGE_QUERY_FORMAT = 101,
|
||||
GSK_SPV_OP_IMAGE_QUERY_ORDER = 102,
|
||||
GSK_SPV_OP_IMAGE_QUERY_SIZE_LOD = 103,
|
||||
GSK_SPV_OP_IMAGE_QUERY_SIZE = 104,
|
||||
GSK_SPV_OP_IMAGE_QUERY_LOD = 105,
|
||||
GSK_SPV_OP_IMAGE_QUERY_LEVELS = 106,
|
||||
GSK_SPV_OP_IMAGE_QUERY_SAMPLES = 107,
|
||||
GSK_SPV_OP_CONVERT_F_TO_U = 109,
|
||||
GSK_SPV_OP_CONVERT_F_TO_S = 110,
|
||||
GSK_SPV_OP_CONVERT_S_TO_F = 111,
|
||||
GSK_SPV_OP_CONVERT_U_TO_F = 112,
|
||||
GSK_SPV_OP_U_CONVERT = 113,
|
||||
GSK_SPV_OP_S_CONVERT = 114,
|
||||
GSK_SPV_OP_F_CONVERT = 115,
|
||||
GSK_SPV_OP_QUANTIZE_TO_F16 = 116,
|
||||
GSK_SPV_OP_CONVERT_PTR_TO_U = 117,
|
||||
GSK_SPV_OP_SAT_CONVERT_S_TO_U = 118,
|
||||
GSK_SPV_OP_SAT_CONVERT_U_TO_S = 119,
|
||||
GSK_SPV_OP_CONVERT_U_TO_PTR = 120,
|
||||
GSK_SPV_OP_PTR_CAST_TO_GENERIC = 121,
|
||||
GSK_SPV_OP_GENERIC_CAST_TO_PTR = 122,
|
||||
GSK_SPV_OP_GENERIC_CAST_TO_PTR_EXPLICIT = 123,
|
||||
GSK_SPV_OP_BITCAST = 124,
|
||||
GSK_SPV_OP_S_NEGATE = 126,
|
||||
GSK_SPV_OP_F_NEGATE = 127,
|
||||
GSK_SPV_OP_I_ADD = 128,
|
||||
GSK_SPV_OP_F_ADD = 129,
|
||||
GSK_SPV_OP_I_SUB = 130,
|
||||
GSK_SPV_OP_F_SUB = 131,
|
||||
GSK_SPV_OP_I_MUL = 132,
|
||||
GSK_SPV_OP_F_MUL = 133,
|
||||
GSK_SPV_OP_U_DIV = 134,
|
||||
GSK_SPV_OP_S_DIV = 135,
|
||||
GSK_SPV_OP_F_DIV = 136,
|
||||
GSK_SPV_OP_U_MOD = 137,
|
||||
GSK_SPV_OP_S_REM = 138,
|
||||
GSK_SPV_OP_S_MOD = 139,
|
||||
GSK_SPV_OP_F_REM = 140,
|
||||
GSK_SPV_OP_F_MOD = 141,
|
||||
GSK_SPV_OP_VECTOR_TIMES_SCALAR = 142,
|
||||
GSK_SPV_OP_MATRIX_TIMES_SCALAR = 143,
|
||||
GSK_SPV_OP_VECTOR_TIMES_MATRIX = 144,
|
||||
GSK_SPV_OP_MATRIX_TIMES_VECTOR = 145,
|
||||
GSK_SPV_OP_MATRIX_TIMES_MATRIX = 146,
|
||||
GSK_SPV_OP_OUTER_PRODUCT = 147,
|
||||
GSK_SPV_OP_DOT = 148,
|
||||
GSK_SPV_OP_I_ADD_CARRY = 149,
|
||||
GSK_SPV_OP_I_SUB_BORROW = 150,
|
||||
GSK_SPV_OP_U_MUL_EXTENDED = 151,
|
||||
GSK_SPV_OP_S_MUL_EXTENDED = 152,
|
||||
GSK_SPV_OP_ANY = 154,
|
||||
GSK_SPV_OP_ALL = 155,
|
||||
GSK_SPV_OP_IS_NAN = 156,
|
||||
GSK_SPV_OP_IS_INF = 157,
|
||||
GSK_SPV_OP_IS_FINITE = 158,
|
||||
GSK_SPV_OP_IS_NORMAL = 159,
|
||||
GSK_SPV_OP_SIGN_BIT_SET = 160,
|
||||
GSK_SPV_OP_LESS_OR_GREATER = 161,
|
||||
GSK_SPV_OP_ORDERED = 162,
|
||||
GSK_SPV_OP_UNORDERED = 163,
|
||||
GSK_SPV_OP_LOGICAL_EQUAL = 164,
|
||||
GSK_SPV_OP_LOGICAL_NOT_EQUAL = 165,
|
||||
GSK_SPV_OP_LOGICAL_OR = 166,
|
||||
GSK_SPV_OP_LOGICAL_AND = 167,
|
||||
GSK_SPV_OP_LOGICAL_NOT = 168,
|
||||
GSK_SPV_OP_SELECT = 169,
|
||||
GSK_SPV_OP_I_EQUAL = 170,
|
||||
GSK_SPV_OP_I_NOT_EQUAL = 171,
|
||||
GSK_SPV_OP_U_GREATER_THAN = 172,
|
||||
GSK_SPV_OP_S_GREATER_THAN = 173,
|
||||
GSK_SPV_OP_U_GREATER_THAN_EQUAL = 174,
|
||||
GSK_SPV_OP_S_GREATER_THAN_EQUAL = 175,
|
||||
GSK_SPV_OP_U_LESS_THAN = 176,
|
||||
GSK_SPV_OP_S_LESS_THAN = 177,
|
||||
GSK_SPV_OP_U_LESS_THAN_EQUAL = 178,
|
||||
GSK_SPV_OP_S_LESS_THAN_EQUAL = 179,
|
||||
GSK_SPV_OP_F_ORD_EQUAL = 180,
|
||||
GSK_SPV_OP_F_UNORD_EQUAL = 181,
|
||||
GSK_SPV_OP_F_ORD_NOT_EQUAL = 182,
|
||||
GSK_SPV_OP_F_UNORD_NOT_EQUAL = 183,
|
||||
GSK_SPV_OP_F_ORD_LESS_THAN = 184,
|
||||
GSK_SPV_OP_F_UNORD_LESS_THAN = 185,
|
||||
GSK_SPV_OP_F_ORD_GREATER_THAN = 186,
|
||||
GSK_SPV_OP_F_UNORD_GREATER_THAN = 187,
|
||||
GSK_SPV_OP_F_ORD_LESS_THAN_EQUAL = 188,
|
||||
GSK_SPV_OP_F_UNORD_LESS_THAN_EQUAL = 189,
|
||||
GSK_SPV_OP_F_ORD_GREATER_THAN_EQUAL = 190,
|
||||
GSK_SPV_OP_F_UNORD_GREATER_THAN_EQUAL = 191,
|
||||
GSK_SPV_OP_SHIFT_RIGHT_LOGICAL = 194,
|
||||
GSK_SPV_OP_SHIFT_RIGHT_ARITHMETIC = 195,
|
||||
GSK_SPV_OP_SHIFT_LEFT_LOGICAL = 196,
|
||||
GSK_SPV_OP_BITWISE_OR = 197,
|
||||
GSK_SPV_OP_BITWISE_XOR = 198,
|
||||
GSK_SPV_OP_BITWISE_AND = 199,
|
||||
GSK_SPV_OP_NOT = 200,
|
||||
GSK_SPV_OP_BIT_FIELD_INSERT = 201,
|
||||
GSK_SPV_OP_BIT_FIELD_S_EXTRACT = 202,
|
||||
GSK_SPV_OP_BIT_FIELD_U_EXTRACT = 203,
|
||||
GSK_SPV_OP_BIT_REVERSE = 204,
|
||||
GSK_SPV_OP_BIT_COUNT = 205,
|
||||
GSK_SPV_OP_D_PDX = 207,
|
||||
GSK_SPV_OP_D_PDY = 208,
|
||||
GSK_SPV_OP_FWIDTH = 209,
|
||||
GSK_SPV_OP_D_PDX_FINE = 210,
|
||||
GSK_SPV_OP_D_PDY_FINE = 211,
|
||||
GSK_SPV_OP_FWIDTH_FINE = 212,
|
||||
GSK_SPV_OP_D_PDX_COARSE = 213,
|
||||
GSK_SPV_OP_D_PDY_COARSE = 214,
|
||||
GSK_SPV_OP_FWIDTH_COARSE = 215,
|
||||
GSK_SPV_OP_EMIT_VERTEX = 218,
|
||||
GSK_SPV_OP_END_PRIMITIVE = 219,
|
||||
GSK_SPV_OP_EMIT_STREAM_VERTEX = 220,
|
||||
GSK_SPV_OP_END_STREAM_PRIMITIVE = 221,
|
||||
GSK_SPV_OP_CONTROL_BARRIER = 224,
|
||||
GSK_SPV_OP_MEMORY_BARRIER = 225,
|
||||
GSK_SPV_OP_ATOMIC_LOAD = 227,
|
||||
GSK_SPV_OP_ATOMIC_STORE = 228,
|
||||
GSK_SPV_OP_ATOMIC_EXCHANGE = 229,
|
||||
GSK_SPV_OP_ATOMIC_COMPARE_EXCHANGE = 230,
|
||||
GSK_SPV_OP_ATOMIC_COMPARE_EXCHANGE_WEAK = 231,
|
||||
GSK_SPV_OP_ATOMIC_I_INCREMENT = 232,
|
||||
GSK_SPV_OP_ATOMIC_I_DECREMENT = 233,
|
||||
GSK_SPV_OP_ATOMIC_I_ADD = 234,
|
||||
GSK_SPV_OP_ATOMIC_I_SUB = 235,
|
||||
GSK_SPV_OP_ATOMIC_S_MIN = 236,
|
||||
GSK_SPV_OP_ATOMIC_U_MIN = 237,
|
||||
GSK_SPV_OP_ATOMIC_S_MAX = 238,
|
||||
GSK_SPV_OP_ATOMIC_U_MAX = 239,
|
||||
GSK_SPV_OP_ATOMIC_AND = 240,
|
||||
GSK_SPV_OP_ATOMIC_OR = 241,
|
||||
GSK_SPV_OP_ATOMIC_XOR = 242,
|
||||
GSK_SPV_OP_PHI = 245,
|
||||
GSK_SPV_OP_LOOP_MERGE = 246,
|
||||
GSK_SPV_OP_SELECTION_MERGE = 247,
|
||||
GSK_SPV_OP_LABEL = 248,
|
||||
GSK_SPV_OP_BRANCH = 249,
|
||||
GSK_SPV_OP_BRANCH_CONDITIONAL = 250,
|
||||
GSK_SPV_OP_SWITCH = 251,
|
||||
GSK_SPV_OP_KILL = 252,
|
||||
GSK_SPV_OP_RETURN = 253,
|
||||
GSK_SPV_OP_RETURN_VALUE = 254,
|
||||
GSK_SPV_OP_UNREACHABLE = 255,
|
||||
GSK_SPV_OP_LIFETIME_START = 256,
|
||||
GSK_SPV_OP_LIFETIME_STOP = 257,
|
||||
GSK_SPV_OP_GROUP_ASYNC_COPY = 259,
|
||||
GSK_SPV_OP_GROUP_WAIT_EVENTS = 260,
|
||||
GSK_SPV_OP_GROUP_ALL = 261,
|
||||
GSK_SPV_OP_GROUP_ANY = 262,
|
||||
GSK_SPV_OP_GROUP_BROADCAST = 263,
|
||||
GSK_SPV_OP_GROUP_I_ADD = 264,
|
||||
GSK_SPV_OP_GROUP_F_ADD = 265,
|
||||
GSK_SPV_OP_GROUP_F_MIN = 266,
|
||||
GSK_SPV_OP_GROUP_U_MIN = 267,
|
||||
GSK_SPV_OP_GROUP_S_MIN = 268,
|
||||
GSK_SPV_OP_GROUP_F_MAX = 269,
|
||||
GSK_SPV_OP_GROUP_U_MAX = 270,
|
||||
GSK_SPV_OP_GROUP_S_MAX = 271,
|
||||
GSK_SPV_OP_READ_PIPE = 274,
|
||||
GSK_SPV_OP_WRITE_PIPE = 275,
|
||||
GSK_SPV_OP_RESERVED_READ_PIPE = 276,
|
||||
GSK_SPV_OP_RESERVED_WRITE_PIPE = 277,
|
||||
GSK_SPV_OP_RESERVE_READ_PIPE_PACKETS = 278,
|
||||
GSK_SPV_OP_RESERVE_WRITE_PIPE_PACKETS = 279,
|
||||
GSK_SPV_OP_COMMIT_READ_PIPE = 280,
|
||||
GSK_SPV_OP_COMMIT_WRITE_PIPE = 281,
|
||||
GSK_SPV_OP_IS_VALID_RESERVE_ID = 282,
|
||||
GSK_SPV_OP_GET_NUM_PIPE_PACKETS = 283,
|
||||
GSK_SPV_OP_GET_MAX_PIPE_PACKETS = 284,
|
||||
GSK_SPV_OP_GROUP_RESERVE_READ_PIPE_PACKETS = 285,
|
||||
GSK_SPV_OP_GROUP_RESERVE_WRITE_PIPE_PACKETS = 286,
|
||||
GSK_SPV_OP_GROUP_COMMIT_READ_PIPE = 287,
|
||||
GSK_SPV_OP_GROUP_COMMIT_WRITE_PIPE = 288,
|
||||
GSK_SPV_OP_ENQUEUE_MARKER = 291,
|
||||
GSK_SPV_OP_ENQUEUE_KERNEL = 292,
|
||||
GSK_SPV_OP_GET_KERNEL_N_DRANGE_SUB_GROUP_COUNT = 293,
|
||||
GSK_SPV_OP_GET_KERNEL_N_DRANGE_MAX_SUB_GROUP_SIZE = 294,
|
||||
GSK_SPV_OP_GET_KERNEL_WORK_GROUP_SIZE = 295,
|
||||
GSK_SPV_OP_GET_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE = 296,
|
||||
GSK_SPV_OP_RETAIN_EVENT = 297,
|
||||
GSK_SPV_OP_RELEASE_EVENT = 298,
|
||||
GSK_SPV_OP_CREATE_USER_EVENT = 299,
|
||||
GSK_SPV_OP_IS_VALID_EVENT = 300,
|
||||
GSK_SPV_OP_SET_USER_EVENT_STATUS = 301,
|
||||
GSK_SPV_OP_CAPTURE_EVENT_PROFILING_INFO = 302,
|
||||
GSK_SPV_OP_GET_DEFAULT_QUEUE = 303,
|
||||
GSK_SPV_OP_BUILD_ND_RANGE = 304,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_IMPLICIT_LOD = 305,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_EXPLICIT_LOD = 306,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_DREF_IMPLICIT_LOD = 307,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_DREF_EXPLICIT_LOD = 308,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_PROJ_IMPLICIT_LOD = 309,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_PROJ_EXPLICIT_LOD = 310,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_PROJ_DREF_IMPLICIT_LOD = 311,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_SAMPLE_PROJ_DREF_EXPLICIT_LOD = 312,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_FETCH = 313,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_GATHER = 314,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_DREF_GATHER = 315,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_TEXELS_RESIDENT = 316,
|
||||
GSK_SPV_OP_NO_LINE = 317,
|
||||
GSK_SPV_OP_ATOMIC_FLAG_TEST_AND_SET = 318,
|
||||
GSK_SPV_OP_ATOMIC_FLAG_CLEAR = 319,
|
||||
GSK_SPV_OP_IMAGE_SPARSE_READ = 320,
|
||||
GSK_SPV_OP_SUBGROUP_BALLOT_KHR = 4421,
|
||||
GSK_SPV_OP_SUBGROUP_FIRST_INVOCATION_KHR = 4422,
|
||||
GSK_SPV_OP_SUBGROUP_ALL_KHR = 4428,
|
||||
GSK_SPV_OP_SUBGROUP_ANY_KHR = 4429,
|
||||
GSK_SPV_OP_SUBGROUP_ALL_EQUAL_KHR = 4430,
|
||||
GSK_SPV_OP_SUBGROUP_READ_INVOCATION_KHR = 4432,
|
||||
GSK_SPV_OP_GROUP_I_ADD_NON_UNIFORM_AMD = 5000,
|
||||
GSK_SPV_OP_GROUP_F_ADD_NON_UNIFORM_AMD = 5001,
|
||||
GSK_SPV_OP_GROUP_F_MIN_NON_UNIFORM_AMD = 5002,
|
||||
GSK_SPV_OP_GROUP_U_MIN_NON_UNIFORM_AMD = 5003,
|
||||
GSK_SPV_OP_GROUP_S_MIN_NON_UNIFORM_AMD = 5004,
|
||||
GSK_SPV_OP_GROUP_F_MAX_NON_UNIFORM_AMD = 5005,
|
||||
GSK_SPV_OP_GROUP_U_MAX_NON_UNIFORM_AMD = 5006,
|
||||
GSK_SPV_OP_GROUP_S_MAX_NON_UNIFORM_AMD = 5007,
|
||||
GSK_SPV_OP_FRAGMENT_MASK_FETCH_AMD = 5011,
|
||||
GSK_SPV_OP_FRAGMENT_FETCH_AMD = 5012
|
||||
} GskSpvOpcode;
|
||||
|
||||
#endif /* __GSK_SPV_ENUMS_H__ */
|
809
gsk/gskspvwriter.c
Normal file
809
gsk/gskspvwriter.c
Normal file
@@ -0,0 +1,809 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskspvwriterprivate.h"
|
||||
|
||||
#include "gskslfunctionprivate.h"
|
||||
#include "gskslfunctiontypeprivate.h"
|
||||
#include "gskslimagetypeprivate.h"
|
||||
#include "gskslqualifierprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
#include "gskslvalueprivate.h"
|
||||
#include "gskslvariableprivate.h"
|
||||
|
||||
typedef struct _GskSpvCodeBlock GskSpvCodeBlock;
|
||||
typedef struct _GskSpvPointerType GskSpvPointerType;
|
||||
|
||||
struct _GskSpvPointerType
|
||||
{
|
||||
GskSlType *type;
|
||||
GskSpvStorageClass storage;
|
||||
};
|
||||
|
||||
struct _GskSpvCodeBlock
|
||||
{
|
||||
GArray *code[GSK_SPV_WRITER_N_BLOCK_SECTIONS];
|
||||
|
||||
guint32 label_id;
|
||||
guint32 continue_id;
|
||||
guint32 break_id;
|
||||
};
|
||||
|
||||
struct _GskSpvWriter
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlShaderStage stage;
|
||||
|
||||
guint32 last_id;
|
||||
guint extended_instructions_id;
|
||||
GArray *code[GSK_SPV_WRITER_N_GLOBAL_SECTIONS];
|
||||
GSList *blocks;
|
||||
GSList *pending_blocks;
|
||||
|
||||
GHashTable *types;
|
||||
GHashTable *image_types;
|
||||
GHashTable *pointer_types;
|
||||
GHashTable *values;
|
||||
GHashTable *variables;
|
||||
GHashTable *functions;
|
||||
GHashTable *function_types;
|
||||
};
|
||||
|
||||
static GskSpvCodeBlock *
|
||||
gsk_spv_code_block_new (void)
|
||||
{
|
||||
GskSpvCodeBlock *block;
|
||||
guint i;
|
||||
|
||||
block = g_slice_new0 (GskSpvCodeBlock);
|
||||
for (i = 0; i < GSK_SPV_WRITER_N_BLOCK_SECTIONS; i++)
|
||||
{
|
||||
block->code[i] = g_array_new (FALSE, TRUE, sizeof (guint32));
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_spv_code_block_free (GskSpvCodeBlock *block)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < GSK_SPV_WRITER_N_BLOCK_SECTIONS; i++)
|
||||
g_array_free (block->code[i], TRUE);
|
||||
|
||||
g_slice_free (GskSpvCodeBlock, block);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pointer_type_equal (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const GskSpvPointerType *typea = a;
|
||||
const GskSpvPointerType *typeb = b;
|
||||
|
||||
if (!gsk_sl_type_equal (typea->type, typeb->type))
|
||||
return FALSE;
|
||||
|
||||
return typea->storage == typeb->storage;
|
||||
}
|
||||
|
||||
static guint
|
||||
pointer_type_hash (gconstpointer t)
|
||||
{
|
||||
const GskSpvPointerType *type = t;
|
||||
|
||||
return gsk_sl_type_hash (type->type)
|
||||
^ type->storage;
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_type_free (gpointer data)
|
||||
{
|
||||
GskSpvPointerType *pointer_type = data;
|
||||
|
||||
gsk_sl_type_unref (pointer_type->type);
|
||||
|
||||
g_free (pointer_type);
|
||||
}
|
||||
|
||||
GskSpvWriter *
|
||||
gsk_spv_writer_new (GskSlShaderStage stage)
|
||||
{
|
||||
GskSpvWriter *writer;
|
||||
guint i;
|
||||
|
||||
writer = g_slice_new0 (GskSpvWriter);
|
||||
writer->ref_count = 1;
|
||||
writer->stage = stage;
|
||||
|
||||
for (i = 0; i < GSK_SPV_WRITER_N_GLOBAL_SECTIONS; i++)
|
||||
{
|
||||
writer->code[i] = g_array_new (FALSE, TRUE, sizeof (guint32));
|
||||
}
|
||||
|
||||
writer->types = g_hash_table_new_full (gsk_sl_type_hash, gsk_sl_type_equal,
|
||||
(GDestroyNotify) gsk_sl_type_unref, NULL);
|
||||
writer->image_types = g_hash_table_new_full (gsk_sl_image_type_hash, gsk_sl_image_type_equal,
|
||||
NULL, NULL);
|
||||
writer->pointer_types = g_hash_table_new_full (pointer_type_hash, pointer_type_equal,
|
||||
pointer_type_free, NULL);
|
||||
writer->values = g_hash_table_new_full (gsk_sl_value_hash, gsk_sl_value_equal,
|
||||
(GDestroyNotify) gsk_sl_value_free, NULL);
|
||||
writer->variables = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
(GDestroyNotify) gsk_sl_variable_unref, NULL);
|
||||
writer->functions = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
(GDestroyNotify) gsk_sl_function_unref, NULL);
|
||||
writer->function_types = g_hash_table_new_full (gsk_sl_function_type_hash, gsk_sl_function_type_equal,
|
||||
(GDestroyNotify) gsk_sl_function_type_unref, NULL);
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
GskSpvWriter *
|
||||
gsk_spv_writer_ref (GskSpvWriter *writer)
|
||||
{
|
||||
g_return_val_if_fail (writer != NULL, NULL);
|
||||
|
||||
writer->ref_count += 1;
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_spv_writer_unref (GskSpvWriter *writer)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (writer == NULL)
|
||||
return;
|
||||
|
||||
writer->ref_count -= 1;
|
||||
if (writer->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_slist_free_full (writer->pending_blocks, (GDestroyNotify) gsk_spv_code_block_free);
|
||||
|
||||
for (i = 0; i < GSK_SPV_WRITER_N_GLOBAL_SECTIONS; i++)
|
||||
{
|
||||
g_array_free (writer->code[i], TRUE);
|
||||
}
|
||||
|
||||
g_hash_table_destroy (writer->pointer_types);
|
||||
g_hash_table_destroy (writer->types);
|
||||
g_hash_table_destroy (writer->image_types);
|
||||
g_hash_table_destroy (writer->values);
|
||||
g_hash_table_destroy (writer->variables);
|
||||
g_hash_table_destroy (writer->functions);
|
||||
g_hash_table_destroy (writer->function_types);
|
||||
|
||||
g_slice_free (GskSpvWriter, writer);
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_spv_writer_write_function (GskSpvWriter *writer,
|
||||
GskSlFunction *function,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data)
|
||||
{
|
||||
GskSpvCodeBlock *block;
|
||||
guint32 result;
|
||||
|
||||
g_assert (g_hash_table_lookup (writer->functions, function) == NULL);
|
||||
|
||||
block = gsk_spv_code_block_new ();
|
||||
writer->blocks = g_slist_prepend (writer->blocks, block);
|
||||
result = gsk_sl_function_write_spv (function, writer, initializer, initializer_data);
|
||||
g_hash_table_insert (writer->functions, gsk_sl_function_ref (function), GUINT_TO_POINTER (result));
|
||||
g_assert (writer->blocks->data == block);
|
||||
writer->blocks = g_slist_remove (writer->blocks, block);
|
||||
writer->pending_blocks = g_slist_prepend (writer->pending_blocks, block);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_guint32 (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
guint32 ua = *(const guint32 *) a;
|
||||
guint32 ub = *(const guint32 *) b;
|
||||
|
||||
return ua - ub;
|
||||
}
|
||||
|
||||
static guint32 *
|
||||
gsk_spv_writer_collect_entry_point_interfaces (GskSpvWriter *writer,
|
||||
gsize *n_interfaces)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GArray *interfaces;
|
||||
gpointer variable, id;
|
||||
|
||||
interfaces = g_array_new (FALSE, FALSE, sizeof (guint32));
|
||||
|
||||
g_hash_table_iter_init (&iter, writer->variables);
|
||||
while (g_hash_table_iter_next (&iter, &variable, &id))
|
||||
{
|
||||
switch (gsk_sl_variable_get_qualifier (variable)->storage)
|
||||
{
|
||||
case GSK_SL_STORAGE_DEFAULT:
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
case GSK_SL_STORAGE_GLOBAL:
|
||||
case GSK_SL_STORAGE_GLOBAL_CONST:
|
||||
case GSK_SL_STORAGE_LOCAL:
|
||||
case GSK_SL_STORAGE_LOCAL_CONST:
|
||||
case GSK_SL_STORAGE_PARAMETER_IN:
|
||||
case GSK_SL_STORAGE_PARAMETER_OUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_INOUT:
|
||||
case GSK_SL_STORAGE_PARAMETER_CONST:
|
||||
case GSK_SL_STORAGE_GLOBAL_UNIFORM:
|
||||
continue;
|
||||
|
||||
case GSK_SL_STORAGE_GLOBAL_IN:
|
||||
case GSK_SL_STORAGE_GLOBAL_OUT:
|
||||
break;
|
||||
}
|
||||
|
||||
g_array_append_val (interfaces, (guint32) { GPOINTER_TO_UINT (id) });
|
||||
}
|
||||
|
||||
/* Try to be like glslang */
|
||||
g_array_sort (interfaces, compare_guint32);
|
||||
|
||||
*n_interfaces = interfaces->len;
|
||||
return (guint32 *) g_array_free (interfaces, FALSE);
|
||||
}
|
||||
|
||||
static GskSpvExecutionModel
|
||||
gsk_spv_writer_get_execution_model (GskSpvWriter *writer)
|
||||
{
|
||||
switch (writer->stage)
|
||||
{
|
||||
case GSK_SL_SHADER_VERTEX:
|
||||
return GSK_SPV_EXECUTION_MODEL_VERTEX;
|
||||
case GSK_SL_SHADER_FRAGMENT:
|
||||
return GSK_SPV_EXECUTION_MODEL_FRAGMENT;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return GSK_SPV_EXECUTION_MODEL_FRAGMENT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_spv_writer_do_write (GskSpvWriter *writer,
|
||||
GskSlFunction *entry_point,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data)
|
||||
{
|
||||
guint32 *interfaces;
|
||||
gsize n_interfaces;
|
||||
guint32 entry_point_id;
|
||||
|
||||
gsk_spv_writer_capability (writer, GSK_SPV_CAPABILITY_SHADER);
|
||||
writer->extended_instructions_id = gsk_spv_writer_ext_inst_import (writer,
|
||||
"GLSL.std.450");
|
||||
gsk_spv_writer_source (writer,
|
||||
GSK_SPV_SOURCE_LANGUAGE_GLSL,
|
||||
440,
|
||||
0,
|
||||
NULL);
|
||||
gsk_spv_writer_source_extension (writer, "GL_GOOGLE_cpp_style_line_directive");
|
||||
gsk_spv_writer_source_extension (writer, "GL_GOOGLE_include_directive");
|
||||
gsk_spv_writer_memory_model (writer,
|
||||
GSK_SPV_ADDRESSING_MODEL_LOGICAL,
|
||||
GSK_SPV_MEMORY_MODEL_GLSL450);
|
||||
|
||||
entry_point_id = gsk_spv_writer_write_function (writer, entry_point, initializer, initializer_data);
|
||||
|
||||
interfaces = gsk_spv_writer_collect_entry_point_interfaces (writer,
|
||||
&n_interfaces);
|
||||
gsk_spv_writer_entry_point (writer,
|
||||
gsk_spv_writer_get_execution_model (writer),
|
||||
entry_point_id,
|
||||
"main",
|
||||
interfaces,
|
||||
n_interfaces);
|
||||
g_free (interfaces);
|
||||
|
||||
if (writer->stage == GSK_SL_SHADER_FRAGMENT)
|
||||
gsk_spv_writer_execution_mode (writer,
|
||||
entry_point_id,
|
||||
GSK_SPV_EXECUTION_MODE_ORIGIN_UPPER_LEFT);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_spv_writer_clear (GskSpvWriter *writer)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_slist_free_full (writer->pending_blocks, (GDestroyNotify) gsk_spv_code_block_free);
|
||||
writer->pending_blocks = NULL;
|
||||
writer->extended_instructions_id = 0;
|
||||
|
||||
for (i = 0; i < GSK_SPV_WRITER_N_GLOBAL_SECTIONS; i++)
|
||||
{
|
||||
g_array_set_size (writer->code[i], 0);
|
||||
}
|
||||
|
||||
g_hash_table_remove_all (writer->pointer_types);
|
||||
g_hash_table_remove_all (writer->types);
|
||||
g_hash_table_remove_all (writer->image_types);
|
||||
g_hash_table_remove_all (writer->values);
|
||||
g_hash_table_remove_all (writer->variables);
|
||||
g_hash_table_remove_all (writer->functions);
|
||||
g_hash_table_remove_all (writer->function_types);
|
||||
}
|
||||
|
||||
GBytes *
|
||||
gsk_spv_writer_write (GskSpvWriter *writer,
|
||||
GskSlFunction *entry_point,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data)
|
||||
{
|
||||
GArray *array;
|
||||
gsize size;
|
||||
GSList *l;
|
||||
guint i;
|
||||
|
||||
gsk_spv_writer_do_write (writer, entry_point, initializer, initializer_data);
|
||||
|
||||
array = g_array_new (FALSE, FALSE, sizeof (guint32));
|
||||
|
||||
g_array_append_val (array, (guint32) { GSK_SPV_MAGIC_NUMBER });
|
||||
g_array_append_val (array, (guint32) { (GSK_SPV_VERSION_MAJOR << 16) | (GSK_SPV_VERSION_MINOR << 8) });
|
||||
g_array_append_val (array, (guint32) { GSK_SPV_GENERATOR });
|
||||
g_array_append_val (array, (guint32) { writer->last_id + 1 });
|
||||
g_array_append_val (array, (guint32) { 0 });
|
||||
|
||||
for (i = 0; i < GSK_SPV_WRITER_N_GLOBAL_SECTIONS; i++)
|
||||
{
|
||||
g_array_append_vals (array, writer->code[i]->data, writer->code[i]->len);
|
||||
}
|
||||
|
||||
for (l = writer->pending_blocks; l; l = l->next)
|
||||
{
|
||||
GskSpvCodeBlock *block = l->data;
|
||||
|
||||
for (i = 0; i < GSK_SPV_WRITER_N_BLOCK_SECTIONS; i++)
|
||||
{
|
||||
g_array_append_vals (array, block->code[i]->data, block->code[i]->len);
|
||||
}
|
||||
}
|
||||
|
||||
gsk_spv_writer_clear (writer);
|
||||
|
||||
size = array->len * sizeof (guint32);
|
||||
return g_bytes_new_take (g_array_free (array, FALSE), size);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_extended_instructions (GskSpvWriter *writer)
|
||||
{
|
||||
return writer->extended_instructions_id;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_type (GskSpvWriter *writer,
|
||||
GskSlType *type)
|
||||
{
|
||||
guint32 result;
|
||||
|
||||
result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->types, type));
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = gsk_sl_type_write_spv (type, writer);
|
||||
g_hash_table_insert (writer->types, gsk_sl_type_ref (type), GUINT_TO_POINTER (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_image_type (GskSpvWriter *writer,
|
||||
const GskSlImageType *type)
|
||||
{
|
||||
guint32 result;
|
||||
|
||||
result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->image_types, type));
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = gsk_sl_image_type_write_spv (type, writer);
|
||||
g_hash_table_insert (writer->image_types, (gpointer) type, GUINT_TO_POINTER (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_pointer_type (GskSpvWriter *writer,
|
||||
GskSlType *type,
|
||||
GskSpvStorageClass storage)
|
||||
{
|
||||
GskSpvPointerType pointer_type = { type, storage };
|
||||
guint32 result;
|
||||
|
||||
result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->pointer_types, &pointer_type));
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = gsk_spv_writer_type_pointer (writer,
|
||||
storage,
|
||||
gsk_spv_writer_get_id_for_type (writer, type));
|
||||
gsk_sl_type_ref (type);
|
||||
g_hash_table_insert (writer->pointer_types, g_memdup (&pointer_type, sizeof (GskSpvPointerType)), GUINT_TO_POINTER (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_value (GskSpvWriter *writer,
|
||||
GskSlValue *value)
|
||||
{
|
||||
guint32 result;
|
||||
|
||||
result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->values, value));
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = gsk_sl_value_write_spv (value, writer);
|
||||
g_hash_table_insert (writer->values, gsk_sl_value_copy (value), GUINT_TO_POINTER (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_spv_writer_get_value_for_id (GskSpvWriter *writer,
|
||||
guint32 id)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer value, value_id;
|
||||
|
||||
g_hash_table_iter_init (&iter, writer->values);
|
||||
while (g_hash_table_iter_next (&iter, &value, &value_id))
|
||||
{
|
||||
if (GPOINTER_TO_UINT (value_id) == id)
|
||||
return value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_zero (GskSpvWriter *writer,
|
||||
GskSlType *type)
|
||||
{
|
||||
GskSlValue *value;
|
||||
guint32 result_id;
|
||||
|
||||
g_return_val_if_fail (gsk_sl_type_is_basic (type), 0);
|
||||
|
||||
value = gsk_sl_value_new (type);
|
||||
result_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
gsk_sl_value_free (value);
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_one (GskSpvWriter *writer,
|
||||
GskSlType *type)
|
||||
{
|
||||
GskSlValue *value;
|
||||
guint32 result_id;
|
||||
gpointer data;
|
||||
gsize i;
|
||||
|
||||
g_return_val_if_fail (gsk_sl_type_is_basic (type), 0);
|
||||
|
||||
value = gsk_sl_value_new (type);
|
||||
data = gsk_sl_value_get_data (value);
|
||||
|
||||
for (i = 0; i < gsk_sl_type_get_n_components (type); i++)
|
||||
{
|
||||
switch (gsk_sl_type_get_scalar_type (type))
|
||||
{
|
||||
case GSK_SL_INT:
|
||||
((gint32 *) data)[i] = 1;
|
||||
break;
|
||||
|
||||
case GSK_SL_UINT:
|
||||
((guint32 *) data)[i] = 1;
|
||||
break;
|
||||
|
||||
case GSK_SL_FLOAT:
|
||||
((float *) data)[i] = 1;
|
||||
break;
|
||||
|
||||
case GSK_SL_DOUBLE:
|
||||
((double *) data)[i] = 1;
|
||||
break;
|
||||
|
||||
case GSK_SL_BOOL:
|
||||
((guint32 *) data)[i] = 1;
|
||||
break;
|
||||
|
||||
case GSK_SL_VOID:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
gsk_sl_value_free (value);
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_variable (GskSpvWriter *writer,
|
||||
GskSlVariable *variable)
|
||||
{
|
||||
guint32 result;
|
||||
|
||||
result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->variables, variable));
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = gsk_sl_variable_write_spv (variable, writer);
|
||||
g_hash_table_insert (writer->variables, gsk_sl_variable_ref (variable), GUINT_TO_POINTER (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_function (GskSpvWriter *writer,
|
||||
GskSlFunction *function)
|
||||
{
|
||||
guint32 result;
|
||||
|
||||
result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->functions, function));
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
return gsk_spv_writer_write_function (writer, function, NULL, NULL);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_id_for_function_type (GskSpvWriter *writer,
|
||||
GskSlFunctionType *function_type)
|
||||
{
|
||||
guint32 result;
|
||||
|
||||
result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->function_types, function_type));
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = gsk_sl_function_type_write_spv (function_type, writer);
|
||||
g_hash_table_insert (writer->function_types, gsk_sl_function_type_ref (function_type), GUINT_TO_POINTER (result));
|
||||
return result;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_make_id (GskSpvWriter *writer)
|
||||
{
|
||||
writer->last_id++;
|
||||
|
||||
return writer->last_id;
|
||||
}
|
||||
|
||||
GArray *
|
||||
gsk_spv_writer_get_bytes (GskSpvWriter *writer,
|
||||
GskSpvWriterSection section)
|
||||
{
|
||||
if (section < GSK_SPV_WRITER_SECTION_BLOCK_FIRST)
|
||||
return writer->code[section];
|
||||
|
||||
return ((GskSpvCodeBlock *) writer->blocks->data)->code[section - GSK_SPV_WRITER_SECTION_BLOCK_FIRST];
|
||||
}
|
||||
|
||||
void
|
||||
gsk_spv_writer_start_code_block (GskSpvWriter *writer,
|
||||
guint32 label_id,
|
||||
guint32 continue_id,
|
||||
guint32 break_id)
|
||||
{
|
||||
GskSpvCodeBlock *block;
|
||||
|
||||
block = writer->blocks->data;
|
||||
|
||||
block->label_id = label_id;
|
||||
if (continue_id != 0)
|
||||
block->continue_id = continue_id;
|
||||
if (break_id != 0)
|
||||
block->break_id = break_id;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_label_id (GskSpvWriter *writer)
|
||||
{
|
||||
GskSpvCodeBlock *block = writer->blocks->data;
|
||||
|
||||
return block->label_id;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_continue_id (GskSpvWriter *writer)
|
||||
{
|
||||
GskSpvCodeBlock *block = writer->blocks->data;
|
||||
|
||||
return block->continue_id;
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_get_break_id (GskSpvWriter *writer)
|
||||
{
|
||||
GskSpvCodeBlock *block = writer->blocks->data;
|
||||
|
||||
return block->break_id;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_4_bytes (gpointer dest, gpointer src)
|
||||
{
|
||||
memcpy (dest, src, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_8_bytes (gpointer dest, gpointer src)
|
||||
{
|
||||
memcpy (dest, src, 8);
|
||||
}
|
||||
|
||||
guint32
|
||||
gsk_spv_writer_convert (GskSpvWriter *writer,
|
||||
guint32 id,
|
||||
GskSlType *type,
|
||||
GskSlType *new_type)
|
||||
{
|
||||
GskSlScalarType scalar = gsk_sl_type_get_scalar_type (type);
|
||||
GskSlScalarType new_scalar = gsk_sl_type_get_scalar_type (new_type);
|
||||
|
||||
if (scalar == new_scalar)
|
||||
return id;
|
||||
|
||||
if (gsk_sl_type_is_scalar (type) ||
|
||||
gsk_sl_type_is_vector (type))
|
||||
{
|
||||
GskSlValue *value;
|
||||
guint32 true_id, false_id, zero_id;
|
||||
|
||||
switch (new_scalar)
|
||||
{
|
||||
case GSK_SL_VOID:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return id;
|
||||
|
||||
case GSK_SL_INT:
|
||||
case GSK_SL_UINT:
|
||||
switch (scalar)
|
||||
{
|
||||
case GSK_SL_INT:
|
||||
case GSK_SL_UINT:
|
||||
return gsk_spv_writer_bitcast (writer, new_type, id);
|
||||
|
||||
case GSK_SL_FLOAT:
|
||||
case GSK_SL_DOUBLE:
|
||||
if (new_scalar == GSK_SL_UINT)
|
||||
return gsk_spv_writer_convert_f_to_u (writer, new_type, id);
|
||||
else
|
||||
return gsk_spv_writer_convert_f_to_s (writer, new_type, id);
|
||||
|
||||
case GSK_SL_BOOL:
|
||||
value = gsk_sl_value_new (new_type);
|
||||
false_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
gsk_sl_value_componentwise (value, copy_4_bytes, &(gint32) { 1 });
|
||||
true_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
gsk_sl_value_free (value);
|
||||
return gsk_spv_writer_select (writer, new_type, id, true_id, false_id);
|
||||
|
||||
case GSK_SL_VOID:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return id;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
|
||||
case GSK_SL_FLOAT:
|
||||
case GSK_SL_DOUBLE:
|
||||
switch (scalar)
|
||||
{
|
||||
case GSK_SL_INT:
|
||||
return gsk_spv_writer_convert_s_to_f (writer, new_type, id);
|
||||
|
||||
case GSK_SL_UINT:
|
||||
return gsk_spv_writer_convert_u_to_f (writer, new_type, id);
|
||||
|
||||
case GSK_SL_FLOAT:
|
||||
case GSK_SL_DOUBLE:
|
||||
return gsk_spv_writer_f_convert (writer, new_type, id);
|
||||
|
||||
case GSK_SL_BOOL:
|
||||
value = gsk_sl_value_new (new_type);
|
||||
false_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
if (scalar == GSK_SL_DOUBLE)
|
||||
gsk_sl_value_componentwise (value, copy_8_bytes, &(double) { 1 });
|
||||
else
|
||||
gsk_sl_value_componentwise (value, copy_4_bytes, &(float) { 1 });
|
||||
true_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
gsk_sl_value_free (value);
|
||||
return gsk_spv_writer_select (writer,
|
||||
new_type,
|
||||
id,
|
||||
true_id,
|
||||
false_id);
|
||||
|
||||
case GSK_SL_VOID:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return id;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
|
||||
case GSK_SL_BOOL:
|
||||
switch (scalar)
|
||||
{
|
||||
case GSK_SL_INT:
|
||||
case GSK_SL_UINT:
|
||||
value = gsk_sl_value_new (new_type);
|
||||
zero_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
gsk_sl_value_free (value);
|
||||
return gsk_spv_writer_i_not_equal (writer, new_type, id, zero_id);
|
||||
|
||||
case GSK_SL_FLOAT:
|
||||
case GSK_SL_DOUBLE:
|
||||
value = gsk_sl_value_new (new_type);
|
||||
zero_id = gsk_spv_writer_get_id_for_value (writer, value);
|
||||
gsk_sl_value_free (value);
|
||||
return gsk_spv_writer_f_ord_not_equal (writer, new_type, id, zero_id);
|
||||
|
||||
case GSK_SL_BOOL:
|
||||
case GSK_SL_VOID:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return id;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
|
||||
}
|
||||
}
|
||||
else if (gsk_sl_type_is_matrix (type))
|
||||
{
|
||||
GskSlType *row_type, *new_row_type;
|
||||
guint i, n = gsk_sl_type_get_length (type);
|
||||
guint32 ids[n];
|
||||
|
||||
row_type = gsk_sl_type_get_index_type (type);
|
||||
new_row_type = gsk_sl_type_get_index_type (new_type);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
ids[i] = gsk_spv_writer_composite_extract (writer, row_type, id, (guint32[1]) { i }, 1);
|
||||
ids[i] = gsk_spv_writer_convert (writer, ids[i], row_type, new_row_type);
|
||||
}
|
||||
|
||||
return gsk_spv_writer_composite_construct (writer, new_type, ids, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_return_val_if_reached (id);
|
||||
}
|
||||
}
|
||||
|
1820
gsk/gskspvwritergeneratedglslprivate.h
Normal file
1820
gsk/gskspvwritergeneratedglslprivate.h
Normal file
File diff suppressed because it is too large
Load Diff
6375
gsk/gskspvwritergeneratedprivate.h
Normal file
6375
gsk/gskspvwritergeneratedprivate.h
Normal file
File diff suppressed because it is too large
Load Diff
107
gsk/gskspvwriterprivate.h
Normal file
107
gsk/gskspvwriterprivate.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GSK_SPV_WRITER_PRIVATE_H__
|
||||
#define __GSK_SPV_WRITER_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltypesprivate.h"
|
||||
#include "gskspvenumsprivate.h"
|
||||
#include "gskspvenumsglslprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_SPV_MAGIC_NUMBER 0x07230203
|
||||
#define GSK_SPV_VERSION_MAJOR 1
|
||||
#define GSK_SPV_VERSION_MINOR 0
|
||||
#define GSK_SPV_GENERATOR 0
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_WRITER_SECTION_HEADER,
|
||||
GSK_SPV_WRITER_SECTION_DEBUG,
|
||||
GSK_SPV_WRITER_SECTION_DECORATE,
|
||||
GSK_SPV_WRITER_SECTION_DEFINE,
|
||||
GSK_SPV_WRITER_SECTION_DECLARE,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
/* add more */
|
||||
GSK_SPV_WRITER_N_SECTIONS
|
||||
} GskSpvWriterSection;
|
||||
|
||||
#define GSK_SPV_WRITER_SECTION_BLOCK_FIRST GSK_SPV_WRITER_SECTION_DECLARE
|
||||
#define GSK_SPV_WRITER_N_GLOBAL_SECTIONS GSK_SPV_WRITER_SECTION_BLOCK_FIRST
|
||||
#define GSK_SPV_WRITER_N_BLOCK_SECTIONS (GSK_SPV_WRITER_N_SECTIONS - GSK_SPV_WRITER_N_GLOBAL_SECTIONS)
|
||||
|
||||
GskSpvWriter * gsk_spv_writer_new (GskSlShaderStage stage);
|
||||
|
||||
GskSpvWriter * gsk_spv_writer_ref (GskSpvWriter *writer);
|
||||
void gsk_spv_writer_unref (GskSpvWriter *writer);
|
||||
|
||||
GBytes * gsk_spv_writer_write (GskSpvWriter *writer,
|
||||
GskSlFunction *entry_point,
|
||||
GskSpvWriterFunc initializer,
|
||||
gpointer initializer_data);
|
||||
|
||||
guint32 gsk_spv_writer_get_id_for_extended_instructions
|
||||
(GskSpvWriter *writer);
|
||||
guint32 gsk_spv_writer_get_id_for_type (GskSpvWriter *writer,
|
||||
GskSlType *type);
|
||||
guint32 gsk_spv_writer_get_id_for_image_type (GskSpvWriter *writer,
|
||||
const GskSlImageType *type);
|
||||
guint32 gsk_spv_writer_get_id_for_pointer_type (GskSpvWriter *writer,
|
||||
GskSlType *type,
|
||||
GskSpvStorageClass storage);
|
||||
guint32 gsk_spv_writer_get_id_for_value (GskSpvWriter *writer,
|
||||
GskSlValue *value);
|
||||
GskSlValue * gsk_spv_writer_get_value_for_id (GskSpvWriter *writer,
|
||||
guint32 id);
|
||||
guint32 gsk_spv_writer_get_id_for_zero (GskSpvWriter *writer,
|
||||
GskSlType *type);
|
||||
guint32 gsk_spv_writer_get_id_for_one (GskSpvWriter *writer,
|
||||
GskSlType *type);
|
||||
guint32 gsk_spv_writer_get_id_for_variable (GskSpvWriter *writer,
|
||||
GskSlVariable *variable);
|
||||
guint32 gsk_spv_writer_get_id_for_function (GskSpvWriter *writer,
|
||||
GskSlFunction *function);
|
||||
guint32 gsk_spv_writer_get_id_for_function_type (GskSpvWriter *writer,
|
||||
GskSlFunctionType *function_type);
|
||||
|
||||
guint32 gsk_spv_writer_make_id (GskSpvWriter *writer);
|
||||
GArray * gsk_spv_writer_get_bytes (GskSpvWriter *writer,
|
||||
GskSpvWriterSection section);
|
||||
|
||||
guint32 gsk_spv_writer_convert (GskSpvWriter *writer,
|
||||
guint32 id,
|
||||
GskSlType *type,
|
||||
GskSlType *new_type);
|
||||
|
||||
guint32 gsk_spv_writer_get_label_id (GskSpvWriter *writer);
|
||||
guint32 gsk_spv_writer_get_continue_id (GskSpvWriter *writer);
|
||||
guint32 gsk_spv_writer_get_break_id (GskSpvWriter *writer);
|
||||
void gsk_spv_writer_start_code_block (GskSpvWriter *writer,
|
||||
guint32 label_id,
|
||||
guint32 continue_id,
|
||||
guint32 break_id);
|
||||
|
||||
|
||||
#include "gskspvwritergeneratedprivate.h"
|
||||
#include "gskspvwritergeneratedglslprivate.h"
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SPV_WRITER_PRIVATE_H__ */
|
@@ -26,7 +26,22 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <gsk/gskenums.h>
|
||||
|
||||
typedef struct _GskCodeLocation GskCodeLocation;
|
||||
typedef struct _GskCodeSource GskCodeSource;
|
||||
typedef struct _GskPixelShader GskPixelShader;
|
||||
typedef struct _GskRenderer GskRenderer;
|
||||
typedef struct _GskSlCompiler GskSlCompiler;
|
||||
typedef struct _GskSlProgram GskSlProgram;
|
||||
typedef struct _GskTexture GskTexture;
|
||||
|
||||
struct _GskCodeLocation
|
||||
{
|
||||
GskCodeSource *source;
|
||||
gsize bytes;
|
||||
gsize chars;
|
||||
gsize lines;
|
||||
gsize line_bytes;
|
||||
gsize line_chars;
|
||||
};
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
|
@@ -14,10 +14,14 @@ gsk_private_source_shaders = [
|
||||
]
|
||||
|
||||
gsk_public_sources = files([
|
||||
'gskcodesource.c',
|
||||
'gskpixelshader.c',
|
||||
'gskrenderer.c',
|
||||
'gskrendernode.c',
|
||||
'gskrendernodeimpl.c',
|
||||
'gskroundedrect.c',
|
||||
'gskslcompiler.c',
|
||||
'gskslprogram.c',
|
||||
'gsktexture.c',
|
||||
])
|
||||
|
||||
@@ -31,10 +35,31 @@ gsk_private_sources = files([
|
||||
'gskprivate.c',
|
||||
'gskprofiler.c',
|
||||
'gskshaderbuilder.c',
|
||||
'gskslbinary.c',
|
||||
'gsksldeclaration.c',
|
||||
'gsksldefine.c',
|
||||
'gskslenvironment.c',
|
||||
'gskslexpression.c',
|
||||
'gskslfunction.c',
|
||||
'gskslfunctiontype.c',
|
||||
'gskslimagetype.c',
|
||||
'gskslnativefunction.c',
|
||||
'gskslnativevariable.c',
|
||||
'gskslpreprocessor.c',
|
||||
'gskslprinter.c',
|
||||
'gskslqualifier.c',
|
||||
'gskslscope.c',
|
||||
'gskslstatement.c',
|
||||
'gsksltokenizer.c',
|
||||
'gsksltype.c',
|
||||
'gskslvalue.c',
|
||||
'gskslvariable.c',
|
||||
'gskspvwriter.c'
|
||||
])
|
||||
|
||||
gsk_public_headers = files([
|
||||
'gskenums.h',
|
||||
'gskpixelshader.h',
|
||||
'gskrenderer.h',
|
||||
'gskrendernode.h',
|
||||
'gskroundedrect.h',
|
||||
@@ -42,6 +67,11 @@ gsk_public_headers = files([
|
||||
'gsktypes.h',
|
||||
])
|
||||
|
||||
gsk_private_headers = files([
|
||||
'gskspvenumsprivate.h',
|
||||
'gskspvwritergeneratedprivate.h'
|
||||
])
|
||||
|
||||
install_headers(gsk_public_headers, 'gsk.h', subdir: 'gtk-4.0/gsk')
|
||||
|
||||
gsk_private_vulkan_shaders = []
|
||||
|
5630
gsk/spirv.core.grammar.json
Normal file
5630
gsk/spirv.core.grammar.json
Normal file
File diff suppressed because it is too large
Load Diff
757
gsk/spirv.js
Normal file
757
gsk/spirv.js
Normal file
@@ -0,0 +1,757 @@
|
||||
function usage()
|
||||
{
|
||||
print ("usage: gjs spirv.js enums|functions SPIRV_GRAMMAR_FILE");
|
||||
}
|
||||
|
||||
if (ARGV.length != 2)
|
||||
{
|
||||
usage();
|
||||
throw new SyntaxError ("Script needs 2 arguments but got " + ARGV.length);
|
||||
}
|
||||
|
||||
var command = ARGV[0];
|
||||
var extinst = "";
|
||||
if (ARGV[0].indexOf("-") > 0)
|
||||
{
|
||||
extinst = ARGV[0].substr (0, ARGV[0].indexOf("-"));
|
||||
command = ARGV[0].substr (extinst.length + 1);
|
||||
}
|
||||
|
||||
var contents = imports.gi.Gio.File.new_for_path(ARGV[1]).load_contents(null);
|
||||
var spirv = JSON.parse(contents[1]);
|
||||
|
||||
if (!String.prototype.format) {
|
||||
String.prototype.format = function() {
|
||||
var args = arguments;
|
||||
return this.replace(/{(\d+)}/g, function(match, number) {
|
||||
return typeof args[number] != 'undefined'
|
||||
? args[number]
|
||||
: match
|
||||
;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function all_lower(s)
|
||||
{
|
||||
let result = "";
|
||||
let needs_underscore = false;
|
||||
let had_caps = false;
|
||||
for (let i = 0; i < s.length; i++)
|
||||
{
|
||||
if (s[i] >= 'a' && s[i] <= 'z')
|
||||
{
|
||||
needs_underscore = true;
|
||||
had_caps = false;
|
||||
result += s[i];
|
||||
}
|
||||
else if (s[i] >= "A" && s[i] <= "Z")
|
||||
{
|
||||
if (needs_underscore)
|
||||
result += "_";
|
||||
else if (s[i+1] && s[i+1] >= "a" && s[i+1] <= "z" && had_caps)
|
||||
result += "_";
|
||||
needs_underscore = false;
|
||||
had_caps = true;
|
||||
result += s[i].toLowerCase();
|
||||
}
|
||||
else if (s[i] >= '0' && s[i] <= '9')
|
||||
{
|
||||
needs_underscore = true
|
||||
had_caps = false;
|
||||
result += s[i]
|
||||
}
|
||||
else
|
||||
{
|
||||
needs_underscore = false
|
||||
had_caps = false;
|
||||
result += "_";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function all_upper(s)
|
||||
{
|
||||
return all_lower(s).toUpperCase();
|
||||
}
|
||||
|
||||
function sanitize_name (name)
|
||||
{
|
||||
name = name.substr(1);
|
||||
return all_lower(name.substr(0, name.indexOf("'")));
|
||||
}
|
||||
|
||||
var SpecialTypes = {
|
||||
"OpVariable": { "result_type": "IdResultPointerType" },
|
||||
"OpImageTexelPointer": { "result_type": "IdResultPointerType" },
|
||||
"OpAccessChain": { "result_type": "IdResultPointerType" },
|
||||
"OpInBoundsAccessChain": { "result_type": "IdResultPointerType" },
|
||||
"OpConvertUToPtr": { "result_type": "IdResultPointerType" },
|
||||
"OpPtrCastToGeneric": { "result_type": "IdResultPointerType" },
|
||||
"OpGenericCastToPtr": { "result_type": "IdResultPointerType" },
|
||||
"OpGenericCastToPtrExplicit": { "result_type": "IdResultPointerType" },
|
||||
"OpFunctionParameter": { "result_type": "IdRef" },
|
||||
"OpLabel": { "result": "IdRef" },
|
||||
"OpImage": { "result_type": "IdRef" }
|
||||
};
|
||||
|
||||
var ExtraOperands = {
|
||||
"OpDecorate": [ { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } ],
|
||||
"OpMemberDecorate": [ { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } ]
|
||||
};
|
||||
|
||||
/* maps opcodes to section in file they appear in */
|
||||
var Sections = {
|
||||
"OpNop": "",
|
||||
"OpUndef": "",
|
||||
"OpSourceContinued": "",
|
||||
"OpSource": "debug",
|
||||
"OpSourceExtension": "debug",
|
||||
"OpName": "debug",
|
||||
"OpMemberName": "debug",
|
||||
"OpString": "",
|
||||
"OpLine": "",
|
||||
"OpExtension": "header",
|
||||
"OpExtInstImport": "header",
|
||||
"OpExtInst": "",
|
||||
"OpMemoryModel": "header",
|
||||
"OpEntryPoint": "header",
|
||||
"OpExecutionMode": "header",
|
||||
"OpCapability": "header",
|
||||
"OpTypeVoid": "define",
|
||||
"OpTypeBool": "define",
|
||||
"OpTypeInt": "define",
|
||||
"OpTypeFloat": "define",
|
||||
"OpTypeVector": "define",
|
||||
"OpTypeMatrix": "define",
|
||||
"OpTypeImage": "define",
|
||||
"OpTypeSampler": "define",
|
||||
"OpTypeSampledImage": "define",
|
||||
"OpTypeArray": "define",
|
||||
"OpTypeRuntimeArray": "define",
|
||||
"OpTypeStruct": "define",
|
||||
"OpTypeOpaque": "define",
|
||||
"OpTypePointer": "define",
|
||||
"OpTypeFunction": "define",
|
||||
"OpTypeEvent": "define",
|
||||
"OpTypeDeviceEvent": "define",
|
||||
"OpTypeReserveId": "define",
|
||||
"OpTypeQueue": "define",
|
||||
"OpTypePipe": "define",
|
||||
"OpTypeForwardPointer": "define",
|
||||
"OpConstantTrue": "define",
|
||||
"OpConstantFalse": "define",
|
||||
"OpConstant": "define",
|
||||
"OpConstantComposite": "define",
|
||||
"OpConstantSampler": "define",
|
||||
"OpConstantNull": "define",
|
||||
"OpSpecConstantTrue": "define",
|
||||
"OpSpecConstantFalse": "define",
|
||||
"OpSpecConstant": "define",
|
||||
"OpSpecConstantComposite": "define",
|
||||
"OpSpecConstantOp": "define",
|
||||
"OpFunction": "declare",
|
||||
"OpFunctionParameter": "declare",
|
||||
"OpFunctionEnd": "code",
|
||||
"OpFunctionCall": "code",
|
||||
"OpVariable": "",
|
||||
"OpImageTexelPointer": "code",
|
||||
"OpLoad": "code",
|
||||
"OpStore": "code",
|
||||
"OpCopyMemory": "code",
|
||||
"OpCopyMemorySized": "code",
|
||||
"OpAccessChain": "code",
|
||||
"OpInBoundsAccessChain": "code",
|
||||
"OpPtrAccessChain": "code",
|
||||
"OpArrayLength": "code",
|
||||
"OpGenericPtrMemSemantics": "",
|
||||
"OpInBoundsPtrAccessChain": "code",
|
||||
"OpDecorate": "decorate",
|
||||
"OpMemberDecorate": "decorate",
|
||||
"OpDecorationGroup": "decorate",
|
||||
"OpGroupDecorate": "decorate",
|
||||
"OpGroupMemberDecorate": "decorate",
|
||||
"OpVectorExtractDynamic": "code",
|
||||
"OpVectorInsertDynamic": "code",
|
||||
"OpVectorShuffle": "code",
|
||||
"OpCompositeConstruct": "code",
|
||||
"OpCompositeExtract": "code",
|
||||
"OpCompositeInsert": "code",
|
||||
"OpCopyObject": "",
|
||||
"OpTranspose": "code",
|
||||
"OpSampledImage": "",
|
||||
"OpImageSampleImplicitLod": "code",
|
||||
"OpImageSampleExplicitLod": "code",
|
||||
"OpImageSampleDrefImplicitLod": "code",
|
||||
"OpImageSampleDrefExplicitLod": "code",
|
||||
"OpImageSampleProjImplicitLod": "code",
|
||||
"OpImageSampleProjExplicitLod": "code",
|
||||
"OpImageSampleProjDrefImplicitLod": "code",
|
||||
"OpImageSampleProjDrefExplicitLod": "code",
|
||||
"OpImageFetch": "code",
|
||||
"OpImageGather": "code",
|
||||
"OpImageDrefGather": "code",
|
||||
"OpImageRead": "code",
|
||||
"OpImageWrite": "code",
|
||||
"OpImage": "code",
|
||||
"OpImageQueryFormat": "code",
|
||||
"OpImageQueryOrder": "code",
|
||||
"OpImageQuerySizeLod": "code",
|
||||
"OpImageQuerySize": "code",
|
||||
"OpImageQueryLod": "code",
|
||||
"OpImageQueryLevels": "code",
|
||||
"OpImageQuerySamples": "code",
|
||||
"OpConvertFToU": "code",
|
||||
"OpConvertFToS": "code",
|
||||
"OpConvertSToF": "code",
|
||||
"OpConvertUToF": "code",
|
||||
"OpUConvert": "code",
|
||||
"OpSConvert": "code",
|
||||
"OpFConvert": "code",
|
||||
"OpQuantizeToF16": "code",
|
||||
"OpConvertPtrToU": "code",
|
||||
"OpSatConvertSToU": "code",
|
||||
"OpSatConvertUToS": "code",
|
||||
"OpConvertUToPtr": "code",
|
||||
"OpPtrCastToGeneric": "code",
|
||||
"OpGenericCastToPtr": "code",
|
||||
"OpGenericCastToPtrExplicit": "code",
|
||||
"OpBitcast": "code",
|
||||
"OpSNegate": "code",
|
||||
"OpFNegate": "code",
|
||||
"OpIAdd": "code",
|
||||
"OpFAdd": "code",
|
||||
"OpISub": "code",
|
||||
"OpFSub": "code",
|
||||
"OpIMul": "code",
|
||||
"OpFMul": "code",
|
||||
"OpUDiv": "code",
|
||||
"OpSDiv": "code",
|
||||
"OpFDiv": "code",
|
||||
"OpUMod": "code",
|
||||
"OpSRem": "code",
|
||||
"OpSMod": "code",
|
||||
"OpFRem": "code",
|
||||
"OpFMod": "code",
|
||||
"OpVectorTimesScalar": "code",
|
||||
"OpMatrixTimesScalar": "code",
|
||||
"OpVectorTimesMatrix": "code",
|
||||
"OpMatrixTimesVector": "code",
|
||||
"OpMatrixTimesMatrix": "code",
|
||||
"OpOuterProduct": "code",
|
||||
"OpDot": "code",
|
||||
"OpIAddCarry": "code",
|
||||
"OpISubBorrow": "code",
|
||||
"OpUMulExtended": "code",
|
||||
"OpSMulExtended": "code",
|
||||
"OpAny": "code",
|
||||
"OpAll": "code",
|
||||
"OpIsNan": "code",
|
||||
"OpIsInf": "code",
|
||||
"OpIsFinite": "code",
|
||||
"OpIsNormal": "code",
|
||||
"OpSignBitSet": "code",
|
||||
"OpLessOrGreater": "code",
|
||||
"OpOrdered": "code",
|
||||
"OpUnordered": "code",
|
||||
"OpLogicalEqual": "code",
|
||||
"OpLogicalNotEqual": "code",
|
||||
"OpLogicalOr": "code",
|
||||
"OpLogicalAnd": "code",
|
||||
"OpLogicalNot": "code",
|
||||
"OpSelect": "code",
|
||||
"OpIEqual": "code",
|
||||
"OpINotEqual": "code",
|
||||
"OpUGreaterThan": "code",
|
||||
"OpSGreaterThan": "code",
|
||||
"OpUGreaterThanEqual": "code",
|
||||
"OpSGreaterThanEqual": "code",
|
||||
"OpULessThan": "code",
|
||||
"OpSLessThan": "code",
|
||||
"OpULessThanEqual": "code",
|
||||
"OpSLessThanEqual": "code",
|
||||
"OpFOrdEqual": "code",
|
||||
"OpFUnordEqual": "code",
|
||||
"OpFOrdNotEqual": "code",
|
||||
"OpFUnordNotEqual": "code",
|
||||
"OpFOrdLessThan": "code",
|
||||
"OpFUnordLessThan": "code",
|
||||
"OpFOrdGreaterThan": "code",
|
||||
"OpFUnordGreaterThan": "code",
|
||||
"OpFOrdLessThanEqual": "code",
|
||||
"OpFUnordLessThanEqual": "code",
|
||||
"OpFOrdGreaterThanEqual": "code",
|
||||
"OpFUnordGreaterThanEqual": "code",
|
||||
"OpShiftRightLogical": "code",
|
||||
"OpShiftRightArithmetic": "code",
|
||||
"OpShiftLeftLogical": "code",
|
||||
"OpBitwiseOr": "code",
|
||||
"OpBitwiseXor": "code",
|
||||
"OpBitwiseAnd": "code",
|
||||
"OpNot": "code",
|
||||
"OpBitFieldInsert": "code",
|
||||
"OpBitFieldSExtract": "code",
|
||||
"OpBitFieldUExtract": "code",
|
||||
"OpBitReverse": "code",
|
||||
"OpBitCount": "code",
|
||||
"OpDPdx": "code",
|
||||
"OpDPdy": "code",
|
||||
"OpFwidth": "code",
|
||||
"OpDPdxFine": "code",
|
||||
"OpDPdyFine": "code",
|
||||
"OpFwidthFine": "code",
|
||||
"OpDPdxCoarse": "code",
|
||||
"OpDPdyCoarse": "code",
|
||||
"OpFwidthCoarse": "code",
|
||||
"OpEmitVertex": "code",
|
||||
"OpEndPrimitive": "code",
|
||||
"OpEmitStreamVertex": "code",
|
||||
"OpEndStreamPrimitive": "code",
|
||||
"OpControlBarrier": "code",
|
||||
"OpMemoryBarrier": "code",
|
||||
"OpAtomicLoad": "code",
|
||||
"OpAtomicStore": "code",
|
||||
"OpAtomicExchange": "code",
|
||||
"OpAtomicCompareExchange": "code",
|
||||
"OpAtomicCompareExchangeWeak": "code",
|
||||
"OpAtomicIIncrement": "code",
|
||||
"OpAtomicIDecrement": "code",
|
||||
"OpAtomicIAdd": "code",
|
||||
"OpAtomicISub": "code",
|
||||
"OpAtomicSMin": "code",
|
||||
"OpAtomicUMin": "code",
|
||||
"OpAtomicSMax": "code",
|
||||
"OpAtomicUMax": "code",
|
||||
"OpAtomicAnd": "code",
|
||||
"OpAtomicOr": "code",
|
||||
"OpAtomicXor": "code",
|
||||
"OpPhi": "code",
|
||||
"OpLoopMerge": "code",
|
||||
"OpSelectionMerge": "code",
|
||||
"OpLabel": "",
|
||||
"OpBranch": "code",
|
||||
"OpBranchConditional": "code",
|
||||
"OpSwitch": "code",
|
||||
"OpKill": "code",
|
||||
"OpReturn": "code",
|
||||
"OpReturnValue": "code",
|
||||
"OpUnreachable": "",
|
||||
"OpLifetimeStart": "",
|
||||
"OpLifetimeStop": "",
|
||||
"OpGroupAsyncCopy": "",
|
||||
"OpGroupWaitEvents": "",
|
||||
"OpGroupAll": "",
|
||||
"OpGroupAny": "",
|
||||
"OpGroupBroadcast": "",
|
||||
"OpGroupIAdd": "",
|
||||
"OpGroupFAdd": "",
|
||||
"OpGroupFMin": "",
|
||||
"OpGroupUMin": "",
|
||||
"OpGroupSMin": "",
|
||||
"OpGroupFMax": "",
|
||||
"OpGroupUMax": "",
|
||||
"OpGroupSMax": "",
|
||||
"OpReadPipe": "",
|
||||
"OpWritePipe": "",
|
||||
"OpReservedReadPipe": "",
|
||||
"OpReservedWritePipe": "",
|
||||
"OpReserveReadPipePackets": "",
|
||||
"OpReserveWritePipePackets": "",
|
||||
"OpCommitReadPipe": "",
|
||||
"OpCommitWritePipe": "",
|
||||
"OpIsValidReserveId": "",
|
||||
"OpGetNumPipePackets": "",
|
||||
"OpGetMaxPipePackets": "",
|
||||
"OpGroupReserveReadPipePackets": "",
|
||||
"OpGroupReserveWritePipePackets": "",
|
||||
"OpGroupCommitReadPipe": "",
|
||||
"OpGroupCommitWritePipe": "",
|
||||
"OpEnqueueMarker": "",
|
||||
"OpEnqueueKernel": "",
|
||||
"OpGetKernelNDrangeSubGroupCount": "",
|
||||
"OpGetKernelNDrangeMaxSubGroupSize": "",
|
||||
"OpGetKernelWorkGroupSize": "",
|
||||
"OpGetKernelPreferredWorkGroupSizeMultiple": "",
|
||||
"OpRetainEvent": "",
|
||||
"OpReleaseEvent": "",
|
||||
"OpCreateUserEvent": "",
|
||||
"OpIsValidEvent": "",
|
||||
"OpSetUserEventStatus": "",
|
||||
"OpCaptureEventProfilingInfo": "",
|
||||
"OpGetDefaultQueue": "",
|
||||
"OpBuildNDRange": "",
|
||||
"OpImageSparseSampleImplicitLod": "",
|
||||
"OpImageSparseSampleExplicitLod": "",
|
||||
"OpImageSparseSampleDrefImplicitLod": "",
|
||||
"OpImageSparseSampleDrefExplicitLod": "",
|
||||
"OpImageSparseSampleProjImplicitLod": "",
|
||||
"OpImageSparseSampleProjExplicitLod": "",
|
||||
"OpImageSparseSampleProjDrefImplicitLod": "",
|
||||
"OpImageSparseSampleProjDrefExplicitLod": "",
|
||||
"OpImageSparseFetch": "",
|
||||
"OpImageSparseGather": "",
|
||||
"OpImageSparseDrefGather": "",
|
||||
"OpImageSparseTexelsResident": "",
|
||||
"OpNoLine": "",
|
||||
"OpAtomicFlagTestAndSet": "",
|
||||
"OpAtomicFlagClear": "",
|
||||
"OpImageSparseRead": "",
|
||||
"OpSubgroupBallotKHR": "",
|
||||
"OpSubgroupFirstInvocationKHR": "",
|
||||
"OpSubgroupAllKHR": "",
|
||||
"OpSubgroupAnyKHR": "",
|
||||
"OpSubgroupAllEqualKHR": "",
|
||||
"OpSubgroupReadInvocationKHR": "",
|
||||
"OpGroupIAddNonUniformAMD": "",
|
||||
"OpGroupFAddNonUniformAMD": "",
|
||||
"OpGroupFMinNonUniformAMD": "",
|
||||
"OpGroupUMinNonUniformAMD": "",
|
||||
"OpGroupSMinNonUniformAMD": "",
|
||||
"OpGroupFMaxNonUniformAMD": "",
|
||||
"OpGroupUMaxNonUniformAMD": "",
|
||||
"OpGroupSMaxNonUniformAMD": "",
|
||||
"OpFragmentMaskFetchAMD": "",
|
||||
"OpFragmentFetchAMD": ""
|
||||
};
|
||||
|
||||
var Operands = {
|
||||
"IdMemorySemantics": { ctype: "guint32 {0}",
|
||||
optional_unset: "0",
|
||||
append_many: "g_array_append_vals ({0}, {1}, {2})",
|
||||
append_one: "g_array_append_val ({0}, {1})" },
|
||||
"IdRef": { ctype: "guint32 {0}",
|
||||
optional_unset: "0",
|
||||
append_many: "g_array_append_vals ({0}, {1}, {2})",
|
||||
append_one: "g_array_append_val ({0}, {1})" },
|
||||
"IdResult": { ctype: "guint32 {0}",
|
||||
optional_unset: "0",
|
||||
declare_local: "guint32 {0}_id = gsk_spv_writer_make_id (writer);",
|
||||
append_one: "g_array_append_val ({0}, {1}_id)" },
|
||||
"IdResultType": { ctype: "GskSlType *{0}",
|
||||
optional_unset: "NULL",
|
||||
declare_local: "guint32 {0}_id = gsk_spv_writer_get_id_for_type (writer, {0});",
|
||||
append_one: "g_array_append_val ({0}, {1}_id)" },
|
||||
"IdResultPointerType" : { ctype: "GskSlType *{0}, GskSpvStorageClass {0}_storage",
|
||||
optional_unset: "NULL",
|
||||
declare_local: "guint32 {0}_id = gsk_spv_writer_get_id_for_pointer_type (writer, {0}, {0}_storage);",
|
||||
append_one: "g_array_append_val ({0}, {1}_id)" },
|
||||
"IdScope": { ctype: "guint32 {0}",
|
||||
optional_unset: "0",
|
||||
append_many: "g_array_append_vals ({0}, {1}, {2})",
|
||||
append_one: "g_array_append_val ({0}, {1})" },
|
||||
"LiteralContextDependentNumber": { ctype: "guint32 {0}",
|
||||
is_many: true,
|
||||
append_many: "g_array_append_vals ({0}, {1}, {2})" },
|
||||
"LiteralExtInstInteger": { ctype: "guint32 {0}",
|
||||
append_many: "g_array_append_vals ({0}, {1}, {2})",
|
||||
append_one: "g_array_append_val ({0}, {1})" },
|
||||
"LiteralInteger": { ctype: "guint32 {0}",
|
||||
append_many: "g_array_append_vals ({0}, {1}, {2})",
|
||||
append_one: "g_array_append_val ({0}, {1})" },
|
||||
"LiteralString": { ctype: "const char *{0}",
|
||||
optional_unset: "NULL",
|
||||
append_one: "append_string ({0}, {1})" },
|
||||
"LiteralSpecConstantOpInteger": { ctype: "guint32 {0}",
|
||||
is_many: true,
|
||||
append_many: "g_array_append_vals ({0}, {1}, {2})" },
|
||||
"PairIdRefLiteralInteger": { ctype: "guint32 {0}[2]",
|
||||
append_many: "g_array_append_vals ({0}, {1}, 2 * {2})",
|
||||
append_one: "g_array_append_vals ({0}, {1}, 2)" },
|
||||
"PairIdRefIdRef": { ctype: "guint32 {0}[2]",
|
||||
append_many: "g_array_append_vals ({0}, {1}, 2 * {2})",
|
||||
append_one: "g_array_append_vals ({0}, {1}, 2)" },
|
||||
"PairLiteralIntegerIdRef": { ctype: "guint32 {0}[2]",
|
||||
append_many: "g_array_append_vals ({0}, {1}, 2 * {2})",
|
||||
append_one: "g_array_append_vals ({0}, {1}, 2)" },
|
||||
"ImageOperands" : { ctype: "GskSpvImageOperands {0}, guint32 *{0}_args, gsize n_{0}_args",
|
||||
optional_unset: "0",
|
||||
append_one: "G_STMT_START{ g_array_append_val ({0}, (guint32) { {1} }); g_array_append_vals ({0}, {1}_args, n_{1}_args); }G_STMT_END" }
|
||||
|
||||
};
|
||||
|
||||
for (let kind in spirv.operand_kinds)
|
||||
{
|
||||
kind = spirv.operand_kinds[kind];
|
||||
if ((kind.category == "BitEnum" ||
|
||||
kind.category == "ValueEnum") &&
|
||||
!Operands[kind.kind])
|
||||
{
|
||||
Operands[kind.kind] = { ctype: "GskSpv" + kind.kind + " {0}",
|
||||
append_one: "g_array_append_val ({0}, (guint32) { {1} })" };
|
||||
if (kind.category == "BitEnum")
|
||||
Operands[kind.kind].optional_unset = "0";
|
||||
if (kind.kind == "AccessQualifier")
|
||||
Operands[kind.kind].optional_unset = "-1";
|
||||
}
|
||||
}
|
||||
|
||||
function fix_operand (ins, o)
|
||||
{
|
||||
if (o.name)
|
||||
{
|
||||
if (o.name == "The name of the opaque type.")
|
||||
o.varname = "name"
|
||||
else
|
||||
o.varname = sanitize_name (o.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (o.kind == "IdResultType")
|
||||
o.varname = "result_type"
|
||||
else if (o.kind == "IdResult")
|
||||
o.varname = "result"
|
||||
else if (Operands[o.kind])
|
||||
o.varname = all_lower (o.kind);
|
||||
}
|
||||
if (!o.varname)
|
||||
throw new TypeError (o.name + " of type " + o.kind + " has no variable name");
|
||||
let operand;
|
||||
if (SpecialTypes[ins.opname] &&
|
||||
SpecialTypes[ins.opname][o.varname])
|
||||
o.kind = SpecialTypes[ins.opname][o.varname];
|
||||
operand = Operands[o.kind];
|
||||
|
||||
if (o.varname == "default")
|
||||
o.varname += "_";
|
||||
if (o.kind == "IdResult")
|
||||
ins.result = true;
|
||||
|
||||
o.ctype = operand.ctype;
|
||||
if (operand.append_one)
|
||||
o.append_one = operand.append_one;
|
||||
if (operand.append_many)
|
||||
o.append_many = operand.append_many;
|
||||
if (operand.declare_local)
|
||||
o.declare_local = operand.declare_local;
|
||||
if (operand.is_many)
|
||||
{
|
||||
if (o.quantifier)
|
||||
throw new SyntaxError ("Can't deal with lists of " + o.kind);
|
||||
else
|
||||
o.quantifier = "*";
|
||||
}
|
||||
if (!o.quantifier)
|
||||
o.quantifier = "";
|
||||
if (o.quantifier == "?")
|
||||
{
|
||||
o.varname = "opt_" + o.varname;
|
||||
if (operand.optional_unset)
|
||||
o.unset = operand.optional_unset;
|
||||
}
|
||||
if (o.quantifier == "*")
|
||||
{
|
||||
if (o.varname[o.varname.length - 1] == "1")
|
||||
o.varname = o.varname.substr(0, o.varname.length - 2);
|
||||
if (o.varname[o.varname.length - 1] != "s")
|
||||
o.varname += "s";
|
||||
}
|
||||
}
|
||||
|
||||
for (let i in spirv.instructions)
|
||||
{
|
||||
let ins = spirv.instructions[i];
|
||||
ins.result = false;
|
||||
ins.enum_value = "GSK_SPV_OP_" + (extinst ? all_upper(extinst) + "_" + all_upper (ins.opname) : all_upper (ins.opname.substr(2)));
|
||||
if (!ins.operands)
|
||||
ins.operands = [];
|
||||
if (ExtraOperands[ins.opname])
|
||||
ins.operands = ins.operands.concat (ExtraOperands[ins.opname]);
|
||||
if (extinst)
|
||||
{
|
||||
ins.operands.unshift (
|
||||
{ "kind" : "IdResultType" },
|
||||
{ "kind" : "IdResult" }
|
||||
);
|
||||
}
|
||||
for (let o in ins.operands)
|
||||
{
|
||||
o = ins.operands[o];
|
||||
fix_operand (ins, o);
|
||||
}
|
||||
if (extinst)
|
||||
{
|
||||
ins.section = "code";
|
||||
ins.section_enum = "GSK_SPV_WRITER_SECTION_CODE";
|
||||
}
|
||||
else if (Sections[ins.opname])
|
||||
{
|
||||
ins.section = Sections[ins.opname];
|
||||
ins.section_enum = "GSK_SPV_WRITER_SECTION_" + ins.section.toUpperCase();
|
||||
}
|
||||
if (!extinst)
|
||||
ins.opname = ins.opname.substr(2);
|
||||
}
|
||||
|
||||
function header()
|
||||
{
|
||||
print ("/* GTK - The GIMP Toolkit");
|
||||
print (" * ");
|
||||
print (" * Copyright © 2017 Benjamin Otte <otte@gnome.org>");
|
||||
print (" *");
|
||||
print (" * This library is free software; you can redistribute it and/or");
|
||||
print (" * modify it under the terms of the GNU Lesser General Public");
|
||||
print (" * License as published by the Free Software Foundation; either");
|
||||
print (" * version 2 of the License, or (at your option) any later version.");
|
||||
print (" *");
|
||||
print (" * This library is distributed in the hope that it will be useful,");
|
||||
print (" * but WITHOUT ANY WARRANTY; without even the implied warranty of");
|
||||
print (" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU");
|
||||
print (" * Lesser General Public License for more details.");
|
||||
print (" *");
|
||||
print (" * You should have received a copy of the GNU Lesser General Public");
|
||||
print (" * License along with this library. If not, see <http://www.gnu.org/licenses/>.");
|
||||
print (" */");
|
||||
print ("");
|
||||
print ("/*");
|
||||
print (" * !!! THIS FILE WAS AUTOGENERATED !!!");
|
||||
print (" * ");
|
||||
print (" * This file was created using the command");
|
||||
print (" * gjs spirv.js " + ARGV.join (" "));
|
||||
print (" * Apply any changes to those files and then regenerate using above command.");
|
||||
print (" */");
|
||||
print ();
|
||||
}
|
||||
|
||||
if (command == "enums")
|
||||
{
|
||||
header ();
|
||||
print ("#ifndef __GSK_SPV_" + (extinst ? all_upper (extinst) + "_" : "") + "ENUMS_H__");
|
||||
print ("#define __GSK_SPV_" + (extinst ? all_upper (extinst) + "_" : "") + "ENUMS_H__");
|
||||
print ();
|
||||
|
||||
for (let kind in spirv.operand_kinds)
|
||||
{
|
||||
kind = spirv.operand_kinds[kind];
|
||||
if (kind.category == "BitEnum" ||
|
||||
kind.category == "ValueEnum")
|
||||
{
|
||||
print ("typedef enum {");
|
||||
for (let i = 0; i < kind.enumerants.length; i++)
|
||||
{
|
||||
let e = kind.enumerants[i];
|
||||
//print (Object.keys(e));
|
||||
print (" GSK_SPV_" + all_upper(kind.kind) + "_" + all_upper (e.enumerant) + " = " + e.value + (i + 1 < kind.enumerants.length ? "," : ""));
|
||||
}
|
||||
print ("} GskSpv" + kind.kind + ";");
|
||||
print ();
|
||||
}
|
||||
}
|
||||
|
||||
print ("typedef enum {");
|
||||
for (let i =0; i < spirv.instructions.length; i++)
|
||||
{
|
||||
let ins = spirv.instructions[i];
|
||||
print (" " + ins.enum_value + " = " + ins.opcode + (i + 1 < spirv.instructions.length ? "," : ""));
|
||||
}
|
||||
print ("} GskSpvOpcode" + extinst + ";");
|
||||
print ();
|
||||
print ("#endif /* __GSK_SPV_" + (extinst ? all_upper (extinst) + "_" : "") + "ENUMS_H__ */");
|
||||
}
|
||||
else if (command == "functions")
|
||||
{
|
||||
header ();
|
||||
print ("#include <string.h>");
|
||||
print ();
|
||||
print ("#ifndef __GSK_SPV_SEEN_AUTOGENERATED_FUNCTIONS__");
|
||||
print ("#define __GSK_SPV_SEEN_AUTOGENERATED_FUNCTIONS__");
|
||||
print ("static inline void");
|
||||
print ("append_string (GArray *bytes,");
|
||||
print (" const char *str)");
|
||||
print ("{");
|
||||
print (" gsize len = strlen (str);");
|
||||
print (" guint size = bytes->len;");
|
||||
print (" g_array_set_size (bytes, size + len / 4 + 1);");
|
||||
print (" memcpy (&g_array_index (bytes, guint32, size), str, len);");
|
||||
print ("}");
|
||||
print ("#endif /* __GSK_SPV_SEEN_AUTOGENERATED_FUNCTIONS__ */");
|
||||
print ();
|
||||
for (let i in spirv.instructions)
|
||||
{
|
||||
let ins = spirv.instructions[i];
|
||||
let prefix = "gsk_spv_writer_" + all_lower(ins.opname) + " (";
|
||||
let len = prefix.length;
|
||||
if (ins.result)
|
||||
print ("static inline guint32");
|
||||
else
|
||||
print ("static inline void");
|
||||
if (ins.operands.length > 1 ||
|
||||
ins.operands.length == 1 && !ins.result)
|
||||
{
|
||||
let seen_result = !ins.result;
|
||||
print (prefix + "GskSpvWriter *writer,");
|
||||
if (!ins.section)
|
||||
print (Array(len+1).join(" ") + "GskSpvWriterSection section,");
|
||||
for (let i = 0; i < ins.operands.length; i++)
|
||||
{
|
||||
let o = ins.operands[i];
|
||||
if (o.kind == "IdResult")
|
||||
{
|
||||
seen_result = true;
|
||||
continue;
|
||||
}
|
||||
if (o.quantifier == "*")
|
||||
{
|
||||
print (Array(len+1).join(" ") + o.ctype.format ("*" + o.varname) + ",");
|
||||
print (Array(len+1).join(" ") + "gsize n_" + o.varname + (i + 2 - seen_result < ins.operands.length ? "," : ")"));
|
||||
}
|
||||
else
|
||||
{
|
||||
print (Array(len+1).join(" ") + o.ctype.format (o.varname) + (i + 2 - seen_result < ins.operands.length ? "," : ")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ins.section)
|
||||
print ("gsk_spv_writer_" + all_lower(ins.opname) + " (GskSpvWriter *writer)");
|
||||
else
|
||||
{
|
||||
print ("gsk_spv_writer_" + all_lower(ins.opname) + " (GskSpvWriter *writer,");
|
||||
print (Array(len+1).join(" ") + "GskSpvWriterSection section)");
|
||||
}
|
||||
}
|
||||
print ("{");
|
||||
print (" GArray *bytes = gsk_spv_writer_get_bytes (writer, " + (ins.section_enum ? ins.section_enum : "section" ) + ");");
|
||||
for (let i = 0; i < ins.operands.length; i++)
|
||||
{
|
||||
let o = ins.operands[i];
|
||||
if (o.declare_local)
|
||||
print (" " + o.declare_local.format (o.varname));
|
||||
}
|
||||
print (" guint start_index = bytes->len;");
|
||||
print ("");
|
||||
print (" g_array_append_val (bytes, (guint32) { 0 });");
|
||||
for (let i = 0; i < ins.operands.length; i++)
|
||||
{
|
||||
let o = ins.operands[i];
|
||||
let indent = " ";
|
||||
if (o.unset)
|
||||
{
|
||||
print (indent + "if (" + o.varname + " != " + o.unset + ")");
|
||||
indent += " ";
|
||||
}
|
||||
if (o.quantifier == "*")
|
||||
print (indent + o.append_many.format ("bytes", o.varname, "n_" + o.varname) + ";");
|
||||
else
|
||||
print (indent + o.append_one.format ("bytes", o.varname) + ";");
|
||||
if (i == 1 && extinst)
|
||||
{
|
||||
print (" g_array_append_val (bytes, (guint32) { gsk_spv_writer_get_id_for_extended_instructions (writer) });");
|
||||
print (" g_array_append_val (bytes, (guint32) { " + ins.enum_value + " });");
|
||||
}
|
||||
}
|
||||
print (" g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | " + (extinst ? "GSK_SPV_OP_EXT_INST" : ins.enum_value) + ";");
|
||||
if (ins.result)
|
||||
{
|
||||
print ("");
|
||||
print (" return result_id;");
|
||||
}
|
||||
print ("}");
|
||||
print ("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usage ()
|
||||
}
|
290
gtk/glsl.c
Normal file
290
gtk/glsl.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright © 2017 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* GTK+ is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* GLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with GTK+; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#ifdef G_IO_WIN32
|
||||
#include <gio/gwin32outputstream.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
compile (GskSlCompiler *compiler,
|
||||
GOutputStream *output,
|
||||
const char *filename)
|
||||
{
|
||||
GBytes *bytes;
|
||||
GskSlProgram *program;
|
||||
GError *error = NULL;
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_commandline_arg (filename);
|
||||
|
||||
program = gsk_sl_compiler_compile_file (compiler,
|
||||
GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (compiler), "shader-stage")),
|
||||
file);
|
||||
g_object_unref (file);
|
||||
if (program == NULL)
|
||||
return FALSE;
|
||||
|
||||
bytes = gsk_sl_program_to_spirv (program);
|
||||
if (!g_output_stream_write_all (output, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL, NULL, &error))
|
||||
{
|
||||
g_print (error->message);
|
||||
g_error_free (error);
|
||||
g_bytes_unref (bytes);
|
||||
g_object_unref (program);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
g_object_unref (program);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dump (GskSlCompiler *compiler,
|
||||
GOutputStream *output,
|
||||
const char *filename)
|
||||
{
|
||||
GString *string;
|
||||
GskSlProgram *program;
|
||||
GError *error = NULL;
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_commandline_arg (filename);
|
||||
|
||||
program = gsk_sl_compiler_compile_file (compiler,
|
||||
GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (compiler), "shader-stage")),
|
||||
file);
|
||||
g_object_unref (file);
|
||||
if (program == NULL)
|
||||
return FALSE;
|
||||
|
||||
string = g_string_new (NULL);
|
||||
gsk_sl_program_print (program, string);
|
||||
if (!g_output_stream_write_all (output, string->str, string->len, NULL, NULL, &error))
|
||||
{
|
||||
g_print (error->message);
|
||||
g_error_free (error);
|
||||
g_string_free (string, TRUE);
|
||||
g_object_unref (program);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_string_free (string, TRUE);
|
||||
g_object_unref (program);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
usage (GOptionContext *ctx)
|
||||
{
|
||||
char *help = g_option_context_get_help (ctx, TRUE, NULL);
|
||||
|
||||
g_print ("%s", help);
|
||||
g_free (help);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
define (const gchar *option_name,
|
||||
const gchar *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
GskSlCompiler *compiler = data;
|
||||
char **tokens;
|
||||
gboolean result;
|
||||
|
||||
tokens = g_strsplit (value, "=", 2);
|
||||
|
||||
result = gsk_sl_compiler_add_define (compiler,
|
||||
tokens[0],
|
||||
tokens[1],
|
||||
error);
|
||||
|
||||
g_strfreev (tokens);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
undefine (const gchar *option_name,
|
||||
const gchar *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
GskSlCompiler *compiler = data;
|
||||
|
||||
gsk_sl_compiler_remove_define (compiler, value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stage (const gchar *option_name,
|
||||
const gchar *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
GskSlShaderStage stage;
|
||||
} stage_names[] = {
|
||||
{ "f", GSK_SL_SHADER_FRAGMENT },
|
||||
{ "frag", GSK_SL_SHADER_FRAGMENT },
|
||||
{ "fragment", GSK_SL_SHADER_FRAGMENT },
|
||||
{ "v", GSK_SL_SHADER_VERTEX },
|
||||
{ "vert", GSK_SL_SHADER_VERTEX },
|
||||
{ "vertex", GSK_SL_SHADER_VERTEX }
|
||||
};
|
||||
GskSlCompiler *compiler = data;
|
||||
GString *str;
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (stage_names); i++)
|
||||
{
|
||||
if (g_ascii_strcasecmp (stage_names[i].name, value) == 0)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (compiler), "shader-stage", GUINT_TO_POINTER (stage_names[i].stage));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
str = g_string_new ("");
|
||||
for (i = 0; i < G_N_ELEMENTS (stage_names); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append (str, ", ");
|
||||
g_string_append (str, stage_names[i].name);
|
||||
}
|
||||
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||
"Unknown value given for shader stage. Valid options are: %s",
|
||||
str->str);
|
||||
g_string_free (str, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GOptionContext *ctx;
|
||||
char **filenames = NULL;
|
||||
char *output_file = NULL;
|
||||
gboolean print = FALSE;
|
||||
const GOptionEntry entries[] = {
|
||||
{ "define", 'D', 0, G_OPTION_ARG_CALLBACK, define, "Add a preprocssor definition", "NAME[=VALUE]" },
|
||||
{ "undef", 'U', 0, G_OPTION_ARG_CALLBACK, undefine, "Cancel previous preprocessor definition", "NAME" },
|
||||
{ "print", 'p', 0, G_OPTION_ARG_NONE, &print, "Print instead of compiling", NULL },
|
||||
{ "stage", 's', 0, G_OPTION_ARG_CALLBACK, stage, "Set the shader stage", "STAGE" },
|
||||
{ "output", 'o', 0, G_OPTION_ARG_FILENAME, &output_file, "Output filename", "FILE" },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, "List of input files", "FILE [FILE...]" },
|
||||
{ NULL, }
|
||||
};
|
||||
GskSlCompiler *compiler;
|
||||
GOptionGroup *group;
|
||||
GError *error = NULL;
|
||||
GOutputStream *output;
|
||||
gboolean success = TRUE;
|
||||
guint i;
|
||||
|
||||
g_set_prgname ("gtk-glsl");
|
||||
|
||||
gtk_init ();
|
||||
|
||||
compiler = gsk_sl_compiler_new ();
|
||||
g_object_set_data (G_OBJECT (compiler), "shader-stage", GUINT_TO_POINTER (GSK_SL_SHADER_FRAGMENT));
|
||||
ctx = g_option_context_new (NULL);
|
||||
group = g_option_group_new (NULL, NULL, NULL, g_object_ref (compiler), g_object_unref);
|
||||
g_option_group_add_entries (group, entries);
|
||||
g_option_context_set_main_group (ctx, group);
|
||||
|
||||
if (!g_option_context_parse (ctx, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (filenames == NULL)
|
||||
usage (ctx);
|
||||
|
||||
g_option_context_free (ctx);
|
||||
|
||||
if (output_file == NULL)
|
||||
{
|
||||
#ifdef G_IO_WIN32
|
||||
HANDLE handle;
|
||||
handle = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
if (handle == NULL)
|
||||
{
|
||||
g_printerr ("No standard output. Use -o/--ouput to write to file\n");
|
||||
exit (1);
|
||||
}
|
||||
output = g_win32_output_stream_new (handle, FALSE);
|
||||
#else
|
||||
output = g_unix_output_stream_new (STDOUT_FILENO, FALSE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file = g_file_new_for_path (output_file);
|
||||
output = G_OUTPUT_STREAM (g_file_replace (file,
|
||||
NULL, FALSE,
|
||||
G_FILE_CREATE_REPLACE_DESTINATION,
|
||||
NULL,
|
||||
&error));
|
||||
g_object_unref (file);
|
||||
if (output == NULL)
|
||||
{
|
||||
g_printerr ("Error creating output file: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; success && filenames[i] != NULL; i++)
|
||||
{
|
||||
if (print)
|
||||
success = dump (compiler, output, filenames[i]);
|
||||
else
|
||||
success = compile (compiler, output, filenames[i]);
|
||||
}
|
||||
|
||||
if (!g_output_stream_close (output, NULL, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
g_object_unref (output);
|
||||
g_object_unref (compiler);
|
||||
g_strfreev (filenames);
|
||||
|
||||
return success ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
@@ -60,6 +60,8 @@ gtk_inspector_init (void)
|
||||
|
||||
g_type_ensure (G_TYPE_LIST_STORE);
|
||||
|
||||
g_type_ensure (GSK_TYPE_PIXEL_SHADER);
|
||||
|
||||
g_type_ensure (GTK_TYPE_CELL_RENDERER_GRAPH);
|
||||
g_type_ensure (GTK_TYPE_GRAPH_DATA);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_ACTIONS);
|
||||
|
@@ -1024,6 +1024,7 @@ gtk_tools = [
|
||||
['gtk4-update-icon-cache', ['updateiconcache.c']],
|
||||
['gtk4-encode-symbolic-svg', ['encodesymbolic.c']],
|
||||
['gtk4-query-immodules', ['queryimmodules.c', 'gtkutils.c']],
|
||||
['gtk4-glsl', ['glsl.c']],
|
||||
]
|
||||
|
||||
if os_unix
|
||||
|
8
testsuite/gsksl/errors/array-index-out-of-range.glsl
Normal file
8
testsuite/gsksl/errors/array-index-out-of-range.glsl
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
int x[10];
|
||||
|
||||
int y = x[10];
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
void
|
||||
main ()
|
||||
{
|
||||
float[2][3] x;
|
||||
float[2] y;
|
||||
|
||||
bool b = x[1] == y;
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
uniform Foo {
|
||||
int x;
|
||||
} x[2][3][4];
|
||||
|
||||
void main()
|
||||
{
|
||||
bool t = x[1] == x[0];
|
||||
}
|
5
testsuite/gsksl/errors/break-without-loop-or-switch.glsl
Normal file
5
testsuite/gsksl/errors/break-without-loop-or-switch.glsl
Normal file
@@ -0,0 +1,5 @@
|
||||
void
|
||||
main ()
|
||||
{
|
||||
break;
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
int b;
|
||||
int y = b ? 1 : 0;
|
||||
}
|
6
testsuite/gsksl/errors/discard.vert
Normal file
6
testsuite/gsksl/errors/discard.vert
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
discard;
|
||||
}
|
7
testsuite/gsksl/errors/double-increment.frag
Normal file
7
testsuite/gsksl/errors/double-increment.frag
Normal file
@@ -0,0 +1,7 @@
|
||||
void
|
||||
main ()
|
||||
{
|
||||
int i;
|
||||
|
||||
++++i;
|
||||
}
|
7
testsuite/gsksl/errors/double-post-decrement.vert
Normal file
7
testsuite/gsksl/errors/double-post-decrement.vert
Normal file
@@ -0,0 +1,7 @@
|
||||
void
|
||||
main ()
|
||||
{
|
||||
int i;
|
||||
|
||||
i----;
|
||||
}
|
8
testsuite/gsksl/errors/duplicate-block-member-name.glsl
Normal file
8
testsuite/gsksl/errors/duplicate-block-member-name.glsl
Normal file
@@ -0,0 +1,8 @@
|
||||
uniform Foo {
|
||||
int x;
|
||||
int x;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
10
testsuite/gsksl/errors/duplicate-function-parameter.glsl
Normal file
10
testsuite/gsksl/errors/duplicate-function-parameter.glsl
Normal file
@@ -0,0 +1,10 @@
|
||||
void
|
||||
foo (int x, int x)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
foo (4, 2);
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
in flat noperspective int i;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
6
testsuite/gsksl/errors/if-defined-empty.glsl
Normal file
6
testsuite/gsksl/errors/if-defined-empty.glsl
Normal file
@@ -0,0 +1,6 @@
|
||||
#if defined
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
6
testsuite/gsksl/errors/if-defined-paren-empty.glsl
Normal file
6
testsuite/gsksl/errors/if-defined-paren-empty.glsl
Normal file
@@ -0,0 +1,6 @@
|
||||
#if defined (
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
6
testsuite/gsksl/errors/if-defined-paren-no-contents.glsl
Normal file
6
testsuite/gsksl/errors/if-defined-paren-no-contents.glsl
Normal file
@@ -0,0 +1,6 @@
|
||||
#if defined ()
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
bool b;
|
||||
int y = b ? 1 : true;
|
||||
}
|
6
testsuite/gsksl/errors/initialize-global-const.frag
Normal file
6
testsuite/gsksl/errors/initialize-global-const.frag
Normal file
@@ -0,0 +1,6 @@
|
||||
const int x;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
5
testsuite/gsksl/errors/initialize-local-const.frag
Normal file
5
testsuite/gsksl/errors/initialize-local-const.frag
Normal file
@@ -0,0 +1,5 @@
|
||||
void
|
||||
main ()
|
||||
{
|
||||
const int x;
|
||||
}
|
6
testsuite/gsksl/errors/int-qualifier.frag
Normal file
6
testsuite/gsksl/errors/int-qualifier.frag
Normal file
@@ -0,0 +1,6 @@
|
||||
in int i;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
11
testsuite/gsksl/errors/invalid-return-type.glsl
Normal file
11
testsuite/gsksl/errors/invalid-return-type.glsl
Normal file
@@ -0,0 +1,11 @@
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
return vec3(0);
|
||||
}
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
float f = foo();
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
|
||||
void
|
||||
foo (int x)
|
||||
{
|
||||
int x;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
foo (1);
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
void main()
|
||||
{
|
||||
int x;
|
||||
int x;
|
||||
}
|
7
testsuite/gsksl/errors/missing-colon-in-conditional.glsl
Normal file
7
testsuite/gsksl/errors/missing-colon-in-conditional.glsl
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
bool b;
|
||||
int y = b ? 1;
|
||||
}
|
6
testsuite/gsksl/errors/missing-endif-after-if-0.glsl
Normal file
6
testsuite/gsksl/errors/missing-endif-after-if-0.glsl
Normal file
@@ -0,0 +1,6 @@
|
||||
#if 0
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
6
testsuite/gsksl/errors/missing-endif-after-if-1.glsl
Normal file
6
testsuite/gsksl/errors/missing-endif-after-if-1.glsl
Normal file
@@ -0,0 +1,6 @@
|
||||
#if 1
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
8
testsuite/gsksl/errors/negative-array-index.glsl
Normal file
8
testsuite/gsksl/errors/negative-array-index.glsl
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
int x[10];
|
||||
|
||||
int y = x[-3];
|
||||
}
|
6
testsuite/gsksl/errors/no-bool-in-variables.frag
Normal file
6
testsuite/gsksl/errors/no-bool-in-variables.frag
Normal file
@@ -0,0 +1,6 @@
|
||||
in bool b;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
6
testsuite/gsksl/errors/no-sampler-in-variables.frag
Normal file
6
testsuite/gsksl/errors/no-sampler-in-variables.frag
Normal file
@@ -0,0 +1,6 @@
|
||||
in sampler2D t;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
in struct {int x; int y; } s;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
|
||||
#123
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
int x = 1;
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
int x;
|
||||
uniform Block {
|
||||
int x;
|
||||
};
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
int x;
|
||||
int x;
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
}
|
11
testsuite/gsksl/errors/returning-no-value.glsl
Normal file
11
testsuite/gsksl/errors/returning-no-value.glsl
Normal file
@@ -0,0 +1,11 @@
|
||||
float
|
||||
foo ()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
main ()
|
||||
{
|
||||
float f = foo();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user