OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkSLSPIRVCodeGenerator.h" | 8 #include "SkSLSPIRVCodeGenerator.h" |
9 | 9 |
10 #include "string.h" | 10 #include "string.h" |
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 if (fCapabilities & bit) { | 961 if (fCapabilities & bit) { |
962 this->writeInstruction(SpvOpCapability, (SpvId) i, out); | 962 this->writeInstruction(SpvOpCapability, (SpvId) i, out); |
963 } | 963 } |
964 } | 964 } |
965 } | 965 } |
966 | 966 |
967 SpvId SPIRVCodeGenerator::nextId() { | 967 SpvId SPIRVCodeGenerator::nextId() { |
968 return fIdCount++; | 968 return fIdCount++; |
969 } | 969 } |
970 | 970 |
971 void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& layou
t, SpvId resultId) { | 971 void SPIRVCodeGenerator::writeStruct(const Type& type, SpvId resultId) { |
972 this->writeInstruction(SpvOpName, resultId, type.name().c_str(), fNameBuffer
); | 972 this->writeInstruction(SpvOpName, resultId, type.name().c_str(), fNameBuffer
); |
973 // go ahead and write all of the field types, so we don't inadvertently writ
e them while we're | 973 // go ahead and write all of the field types, so we don't inadvertently writ
e them while we're |
974 // in the middle of writing the struct instruction | 974 // in the middle of writing the struct instruction |
975 std::vector<SpvId> types; | 975 std::vector<SpvId> types; |
976 for (const auto& f : type.fields()) { | 976 for (const auto& f : type.fields()) { |
977 types.push_back(this->getType(*f.fType, layout)); | 977 types.push_back(this->getType(*f.fType)); |
978 } | 978 } |
979 this->writeOpCode(SpvOpTypeStruct, 2 + (int32_t) types.size(), fConstantBuff
er); | 979 this->writeOpCode(SpvOpTypeStruct, 2 + (int32_t) types.size(), fConstantBuff
er); |
980 this->writeWord(resultId, fConstantBuffer); | 980 this->writeWord(resultId, fConstantBuffer); |
981 for (SpvId id : types) { | 981 for (SpvId id : types) { |
982 this->writeWord(id, fConstantBuffer); | 982 this->writeWord(id, fConstantBuffer); |
983 } | 983 } |
984 size_t offset = 0; | 984 size_t offset = 0; |
985 for (int32_t i = 0; i < (int32_t) type.fields().size(); i++) { | 985 for (int32_t i = 0; i < (int32_t) type.fields().size(); i++) { |
986 size_t size = layout.size(*type.fields()[i].fType); | 986 size_t size = type.fields()[i].fType->size(); |
987 size_t alignment = layout.alignment(*type.fields()[i].fType); | 987 size_t alignment = type.fields()[i].fType->alignment(); |
988 size_t mod = offset % alignment; | 988 size_t mod = offset % alignment; |
989 if (mod != 0) { | 989 if (mod != 0) { |
990 offset += alignment - mod; | 990 offset += alignment - mod; |
991 } | 991 } |
992 this->writeInstruction(SpvOpMemberName, resultId, i, type.fields()[i].fN
ame.c_str(), | 992 this->writeInstruction(SpvOpMemberName, resultId, i, type.fields()[i].fN
ame.c_str(), |
993 fNameBuffer); | 993 fNameBuffer); |
994 this->writeLayout(type.fields()[i].fModifiers.fLayout, resultId, i); | 994 this->writeLayout(type.fields()[i].fModifiers.fLayout, resultId, i); |
995 if (type.fields()[i].fModifiers.fLayout.fBuiltin < 0) { | 995 if (type.fields()[i].fModifiers.fLayout.fBuiltin < 0) { |
996 this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, Spv
DecorationOffset, | 996 this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, Spv
DecorationOffset, |
997 (SpvId) offset, fDecorationBuffer); | 997 (SpvId) offset, fDecorationBuffer); |
998 } | 998 } |
999 if (type.fields()[i].fType->kind() == Type::kMatrix_Kind) { | 999 if (type.fields()[i].fType->kind() == Type::kMatrix_Kind) { |
1000 this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorati
onColMajor, | 1000 this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorati
onColMajor, |
1001 fDecorationBuffer); | 1001 fDecorationBuffer); |
1002 this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorati
onMatrixStride, | 1002 this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorati
onMatrixStride, |
1003 (SpvId) layout.stride(*type.fields()[i].fType
), | 1003 (SpvId) type.fields()[i].fType->stride(), fDe
corationBuffer); |
1004 fDecorationBuffer); | |
1005 } | 1004 } |
1006 offset += size; | 1005 offset += size; |
1007 Type::Kind kind = type.fields()[i].fType->kind(); | 1006 Type::Kind kind = type.fields()[i].fType->kind(); |
1008 if ((kind == Type::kArray_Kind || kind == Type::kStruct_Kind) && offset
% alignment != 0) { | 1007 if ((kind == Type::kArray_Kind || kind == Type::kStruct_Kind) && offset
% alignment != 0) { |
1009 offset += alignment - offset % alignment; | 1008 offset += alignment - offset % alignment; |
1010 } | 1009 } |
1011 ASSERT(offset % alignment == 0); | 1010 ASSERT(offset % alignment == 0); |
1012 } | 1011 } |
1013 } | 1012 } |
1014 | 1013 |
1015 SpvId SPIRVCodeGenerator::getType(const Type& type) { | 1014 SpvId SPIRVCodeGenerator::getType(const Type& type) { |
1016 return this->getType(type, fDefaultLayout); | 1015 auto entry = fTypeMap.find(type.name()); |
1017 } | |
1018 | |
1019 SpvId SPIRVCodeGenerator::getType(const Type& type, const MemoryLayout& layout)
{ | |
1020 std::string key = type.name() + to_string((int) layout.fStd); | |
1021 auto entry = fTypeMap.find(key); | |
1022 if (entry == fTypeMap.end()) { | 1016 if (entry == fTypeMap.end()) { |
1023 SpvId result = this->nextId(); | 1017 SpvId result = this->nextId(); |
1024 switch (type.kind()) { | 1018 switch (type.kind()) { |
1025 case Type::kScalar_Kind: | 1019 case Type::kScalar_Kind: |
1026 if (type == *fContext.fBool_Type) { | 1020 if (type == *fContext.fBool_Type) { |
1027 this->writeInstruction(SpvOpTypeBool, result, fConstantBuffe
r); | 1021 this->writeInstruction(SpvOpTypeBool, result, fConstantBuffe
r); |
1028 } else if (type == *fContext.fInt_Type) { | 1022 } else if (type == *fContext.fInt_Type) { |
1029 this->writeInstruction(SpvOpTypeInt, result, 32, 1, fConstan
tBuffer); | 1023 this->writeInstruction(SpvOpTypeInt, result, 32, 1, fConstan
tBuffer); |
1030 } else if (type == *fContext.fUInt_Type) { | 1024 } else if (type == *fContext.fUInt_Type) { |
1031 this->writeInstruction(SpvOpTypeInt, result, 32, 0, fConstan
tBuffer); | 1025 this->writeInstruction(SpvOpTypeInt, result, 32, 0, fConstan
tBuffer); |
1032 } else if (type == *fContext.fFloat_Type) { | 1026 } else if (type == *fContext.fFloat_Type) { |
1033 this->writeInstruction(SpvOpTypeFloat, result, 32, fConstant
Buffer); | 1027 this->writeInstruction(SpvOpTypeFloat, result, 32, fConstant
Buffer); |
1034 } else if (type == *fContext.fDouble_Type) { | 1028 } else if (type == *fContext.fDouble_Type) { |
1035 this->writeInstruction(SpvOpTypeFloat, result, 64, fConstant
Buffer); | 1029 this->writeInstruction(SpvOpTypeFloat, result, 64, fConstant
Buffer); |
1036 } else { | 1030 } else { |
1037 ASSERT(false); | 1031 ASSERT(false); |
1038 } | 1032 } |
1039 break; | 1033 break; |
1040 case Type::kVector_Kind: | 1034 case Type::kVector_Kind: |
1041 this->writeInstruction(SpvOpTypeVector, result, | 1035 this->writeInstruction(SpvOpTypeVector, result, |
1042 this->getType(type.componentType(), layou
t), | 1036 this->getType(type.componentType()), |
1043 type.columns(), fConstantBuffer); | 1037 type.columns(), fConstantBuffer); |
1044 break; | 1038 break; |
1045 case Type::kMatrix_Kind: | 1039 case Type::kMatrix_Kind: |
1046 this->writeInstruction(SpvOpTypeMatrix, result, | 1040 this->writeInstruction(SpvOpTypeMatrix, result, |
1047 this->getType(index_type(fContext, type),
layout), | 1041 this->getType(index_type(fContext, type))
, |
1048 type.columns(), fConstantBuffer); | 1042 type.columns(), fConstantBuffer); |
1049 break; | 1043 break; |
1050 case Type::kStruct_Kind: | 1044 case Type::kStruct_Kind: |
1051 this->writeStruct(type, layout, result); | 1045 this->writeStruct(type, result); |
1052 break; | 1046 break; |
1053 case Type::kArray_Kind: { | 1047 case Type::kArray_Kind: { |
1054 if (type.columns() > 0) { | 1048 if (type.columns() > 0) { |
1055 IntLiteral count(fContext, Position(), type.columns()); | 1049 IntLiteral count(fContext, Position(), type.columns()); |
1056 this->writeInstruction(SpvOpTypeArray, result, | 1050 this->writeInstruction(SpvOpTypeArray, result, |
1057 this->getType(type.componentType(), l
ayout), | 1051 this->getType(type.componentType()), |
1058 this->writeIntLiteral(count), fConsta
ntBuffer); | 1052 this->writeIntLiteral(count), fConsta
ntBuffer); |
1059 this->writeInstruction(SpvOpDecorate, result, SpvDecorationA
rrayStride, | 1053 this->writeInstruction(SpvOpDecorate, result, SpvDecorationA
rrayStride, |
1060 (int32_t) layout.stride(type), | 1054 (int32_t) type.stride(), fDecorationB
uffer); |
1061 fDecorationBuffer); | |
1062 } else { | 1055 } else { |
1063 ABORT("runtime-sized arrays are not yet supported"); | 1056 ABORT("runtime-sized arrays are not yet supported"); |
1064 this->writeInstruction(SpvOpTypeRuntimeArray, result, | 1057 this->writeInstruction(SpvOpTypeRuntimeArray, result, |
1065 this->getType(type.componentType(), l
ayout), | 1058 this->getType(type.componentType()),
fConstantBuffer); |
1066 fConstantBuffer); | |
1067 } | 1059 } |
1068 break; | 1060 break; |
1069 } | 1061 } |
1070 case Type::kSampler_Kind: { | 1062 case Type::kSampler_Kind: { |
1071 SpvId image = this->nextId(); | 1063 SpvId image = this->nextId(); |
1072 this->writeInstruction(SpvOpTypeImage, image, | 1064 this->writeInstruction(SpvOpTypeImage, image, this->getType(*fCo
ntext.fFloat_Type), |
1073 this->getType(*fContext.fFloat_Type, layo
ut), | |
1074 type.dimensions(), type.isDepth(), type.i
sArrayed(), | 1065 type.dimensions(), type.isDepth(), type.i
sArrayed(), |
1075 type.isMultisampled(), type.isSampled(), | 1066 type.isMultisampled(), type.isSampled(), |
1076 SpvImageFormatUnknown, fConstantBuffer); | 1067 SpvImageFormatUnknown, fConstantBuffer); |
1077 this->writeInstruction(SpvOpTypeSampledImage, result, image, fCo
nstantBuffer); | 1068 this->writeInstruction(SpvOpTypeSampledImage, result, image, fCo
nstantBuffer); |
1078 break; | 1069 break; |
1079 } | 1070 } |
1080 default: | 1071 default: |
1081 if (type == *fContext.fVoid_Type) { | 1072 if (type == *fContext.fVoid_Type) { |
1082 this->writeInstruction(SpvOpTypeVoid, result, fConstantBuffe
r); | 1073 this->writeInstruction(SpvOpTypeVoid, result, fConstantBuffe
r); |
1083 } else { | 1074 } else { |
1084 ABORT("invalid type: %s", type.description().c_str()); | 1075 ABORT("invalid type: %s", type.description().c_str()); |
1085 } | 1076 } |
1086 } | 1077 } |
1087 fTypeMap[key] = result; | 1078 fTypeMap[type.name()] = result; |
1088 return result; | 1079 return result; |
1089 } | 1080 } |
1090 return entry->second; | 1081 return entry->second; |
1091 } | 1082 } |
1092 | 1083 |
1093 SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { | 1084 SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { |
1094 std::string key = function.fReturnType.description() + "("; | 1085 std::string key = function.fReturnType.description() + "("; |
1095 std::string separator = ""; | 1086 std::string separator = ""; |
1096 for (size_t i = 0; i < function.fParameters.size(); i++) { | 1087 for (size_t i = 0; i < function.fParameters.size(); i++) { |
1097 key += separator; | 1088 key += separator; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 this->writeWord(returnType, fConstantBuffer); | 1131 this->writeWord(returnType, fConstantBuffer); |
1141 for (SpvId id : parameterTypes) { | 1132 for (SpvId id : parameterTypes) { |
1142 this->writeWord(id, fConstantBuffer); | 1133 this->writeWord(id, fConstantBuffer); |
1143 } | 1134 } |
1144 fTypeMap[key] = result; | 1135 fTypeMap[key] = result; |
1145 return result; | 1136 return result; |
1146 } | 1137 } |
1147 return entry->second; | 1138 return entry->second; |
1148 } | 1139 } |
1149 | 1140 |
1150 SpvId SPIRVCodeGenerator::getPointerType(const Type& type, SpvStorageClass_ stor
ageClass) { | 1141 SpvId SPIRVCodeGenerator::getPointerType(const Type& type, |
1151 return this->getPointerType(type, fDefaultLayout, storageClass); | |
1152 } | |
1153 | |
1154 SpvId SPIRVCodeGenerator::getPointerType(const Type& type, const MemoryLayout& l
ayout, | |
1155 SpvStorageClass_ storageClass) { | 1142 SpvStorageClass_ storageClass) { |
1156 std::string key = type.description() + "*" + to_string(layout.fStd) + to_str
ing(storageClass); | 1143 std::string key = type.description() + "*" + to_string(storageClass); |
1157 auto entry = fTypeMap.find(key); | 1144 auto entry = fTypeMap.find(key); |
1158 if (entry == fTypeMap.end()) { | 1145 if (entry == fTypeMap.end()) { |
1159 SpvId result = this->nextId(); | 1146 SpvId result = this->nextId(); |
1160 this->writeInstruction(SpvOpTypePointer, result, storageClass, | 1147 this->writeInstruction(SpvOpTypePointer, result, storageClass, |
1161 this->getType(type), fConstantBuffer); | 1148 this->getType(type), fConstantBuffer); |
1162 fTypeMap[key] = result; | 1149 fTypeMap[key] = result; |
1163 return result; | 1150 return result; |
1164 } | 1151 } |
1165 return entry->second; | 1152 return entry->second; |
1166 } | 1153 } |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 return this->writeVectorConstructor(c, out); | 1544 return this->writeVectorConstructor(c, out); |
1558 case Type::kMatrix_Kind: | 1545 case Type::kMatrix_Kind: |
1559 return this->writeMatrixConstructor(c, out); | 1546 return this->writeMatrixConstructor(c, out); |
1560 default: | 1547 default: |
1561 ABORT("unsupported constructor: %s", c.description().c_str()); | 1548 ABORT("unsupported constructor: %s", c.description().c_str()); |
1562 } | 1549 } |
1563 } | 1550 } |
1564 | 1551 |
1565 SpvStorageClass_ get_storage_class(const Modifiers& modifiers) { | 1552 SpvStorageClass_ get_storage_class(const Modifiers& modifiers) { |
1566 if (modifiers.fFlags & Modifiers::kIn_Flag) { | 1553 if (modifiers.fFlags & Modifiers::kIn_Flag) { |
1567 ASSERT(!modifiers.fLayout.fPushConstant); | |
1568 return SpvStorageClassInput; | 1554 return SpvStorageClassInput; |
1569 } else if (modifiers.fFlags & Modifiers::kOut_Flag) { | 1555 } else if (modifiers.fFlags & Modifiers::kOut_Flag) { |
1570 ASSERT(!modifiers.fLayout.fPushConstant); | |
1571 return SpvStorageClassOutput; | 1556 return SpvStorageClassOutput; |
1572 } else if (modifiers.fFlags & Modifiers::kUniform_Flag) { | 1557 } else if (modifiers.fFlags & Modifiers::kUniform_Flag) { |
1573 if (modifiers.fLayout.fPushConstant) { | |
1574 return SpvStorageClassPushConstant; | |
1575 } | |
1576 return SpvStorageClassUniform; | 1558 return SpvStorageClassUniform; |
1577 } else { | 1559 } else { |
1578 return SpvStorageClassFunction; | 1560 return SpvStorageClassFunction; |
1579 } | 1561 } |
1580 } | 1562 } |
1581 | 1563 |
1582 SpvStorageClass_ get_storage_class(const Expression& expr) { | 1564 SpvStorageClass_ get_storage_class(const Expression& expr) { |
1583 switch (expr.fKind) { | 1565 switch (expr.fKind) { |
1584 case Expression::kVariableReference_Kind: | 1566 case Expression::kVariableReference_Kind: |
1585 return get_storage_class(((VariableReference&) expr).fVariable.fModi
fiers); | 1567 return get_storage_class(((VariableReference&) expr).fVariable.fModi
fiers); |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2369 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio
nDescriptorSet, | 2351 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio
nDescriptorSet, |
2370 layout.fSet, fDecorationBuffer); | 2352 layout.fSet, fDecorationBuffer); |
2371 } | 2353 } |
2372 if (layout.fBuiltin >= 0) { | 2354 if (layout.fBuiltin >= 0) { |
2373 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio
nBuiltIn, | 2355 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio
nBuiltIn, |
2374 layout.fBuiltin, fDecorationBuffer); | 2356 layout.fBuiltin, fDecorationBuffer); |
2375 } | 2357 } |
2376 } | 2358 } |
2377 | 2359 |
2378 SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { | 2360 SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { |
2379 MemoryLayout layout = intf.fVariable.fModifiers.fLayout.fPushConstant ? | 2361 SpvId type = this->getType(intf.fVariable.fType); |
2380 MemoryLayout(MemoryLayout::k430_Standard) : | |
2381 fDefaultLayout; | |
2382 SpvId type = this->getType(intf.fVariable.fType, layout); | |
2383 SpvId result = this->nextId(); | 2362 SpvId result = this->nextId(); |
2384 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB
uffer); | 2363 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB
uffer); |
2385 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers)
; | 2364 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers)
; |
2386 SpvId ptrType = this->nextId(); | 2365 SpvId ptrType = this->nextId(); |
2387 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst
antBuffer); | 2366 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst
antBuffer); |
2388 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta
ntBuffer); | 2367 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta
ntBuffer); |
2389 this->writeLayout(intf.fVariable.fModifiers.fLayout, result); | 2368 this->writeLayout(intf.fVariable.fModifiers.fLayout, result); |
2390 fVariableMap[&intf.fVariable] = result; | 2369 fVariableMap[&intf.fVariable] = result; |
2391 return result; | 2370 return result; |
2392 } | 2371 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2425 } | 2404 } |
2426 } else { | 2405 } else { |
2427 storageClass = SpvStorageClassPrivate; | 2406 storageClass = SpvStorageClassPrivate; |
2428 } | 2407 } |
2429 SpvId id = this->nextId(); | 2408 SpvId id = this->nextId(); |
2430 fVariableMap[var] = id; | 2409 fVariableMap[var] = id; |
2431 SpvId type = this->getPointerType(var->fType, storageClass); | 2410 SpvId type = this->getPointerType(var->fType, storageClass); |
2432 this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantB
uffer); | 2411 this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantB
uffer); |
2433 this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer); | 2412 this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer); |
2434 if (var->fType.kind() == Type::kMatrix_Kind) { | 2413 if (var->fType.kind() == Type::kMatrix_Kind) { |
2435 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora
tionColMajor, | 2414 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora
tionColMajor, |
2436 fDecorationBuffer); | 2415 fDecorationBuffer); |
2437 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora
tionMatrixStride, | 2416 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora
tionMatrixStride, |
2438 (SpvId) fDefaultLayout.stride(var->fType), | 2417 (SpvId) var->fType.stride(), fDecorationBuffe
r); |
2439 fDecorationBuffer); | |
2440 } | 2418 } |
2441 if (varDecl.fValue) { | 2419 if (varDecl.fValue) { |
2442 ASSERT(!fCurrentBlock); | 2420 ASSERT(!fCurrentBlock); |
2443 fCurrentBlock = -1; | 2421 fCurrentBlock = -1; |
2444 SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitiali
zersBuffer); | 2422 SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitiali
zersBuffer); |
2445 this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuf
fer); | 2423 this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuf
fer); |
2446 fCurrentBlock = 0; | 2424 fCurrentBlock = 0; |
2447 } | 2425 } |
2448 this->writeLayout(var->fModifiers.fLayout, id); | 2426 this->writeLayout(var->fModifiers.fLayout, id); |
2449 } | 2427 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2670 this->writeWord(SpvVersion, out); | 2648 this->writeWord(SpvVersion, out); |
2671 this->writeWord(SKSL_MAGIC, out); | 2649 this->writeWord(SKSL_MAGIC, out); |
2672 std::stringstream buffer; | 2650 std::stringstream buffer; |
2673 this->writeInstructions(program, buffer); | 2651 this->writeInstructions(program, buffer); |
2674 this->writeWord(fIdCount, out); | 2652 this->writeWord(fIdCount, out); |
2675 this->writeWord(0, out); // reserved, always zero | 2653 this->writeWord(0, out); // reserved, always zero |
2676 out << buffer.str(); | 2654 out << buffer.str(); |
2677 } | 2655 } |
2678 | 2656 |
2679 } | 2657 } |
OLD | NEW |