Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/sksl/SkSLSPIRVCodeGenerator.cpp

Issue 2187433003: added support for push_constant layout (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: rebased Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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, SpvId resultId) { 971 void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& layou t, 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)); 977 types.push_back(this->getType(*f.fType, layout));
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 = type.fields()[i].fType->size(); 986 size_t size = layout.size(*type.fields()[i].fType);
987 size_t alignment = type.fields()[i].fType->alignment(); 987 size_t alignment = layout.alignment(*type.fields()[i].fType);
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) type.fields()[i].fType->stride(), fDe corationBuffer); 1003 (SpvId) layout.stride(*type.fields()[i].fType ),
1004 fDecorationBuffer);
1004 } 1005 }
1005 offset += size; 1006 offset += size;
1006 Type::Kind kind = type.fields()[i].fType->kind(); 1007 Type::Kind kind = type.fields()[i].fType->kind();
1007 if ((kind == Type::kArray_Kind || kind == Type::kStruct_Kind) && offset % alignment != 0) { 1008 if ((kind == Type::kArray_Kind || kind == Type::kStruct_Kind) && offset % alignment != 0) {
1008 offset += alignment - offset % alignment; 1009 offset += alignment - offset % alignment;
1009 } 1010 }
1010 ASSERT(offset % alignment == 0); 1011 ASSERT(offset % alignment == 0);
1011 } 1012 }
1012 } 1013 }
1013 1014
1014 SpvId SPIRVCodeGenerator::getType(const Type& type) { 1015 SpvId SPIRVCodeGenerator::getType(const Type& type) {
1015 auto entry = fTypeMap.find(type.name()); 1016 return this->getType(type, fDefaultLayout);
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);
1016 if (entry == fTypeMap.end()) { 1022 if (entry == fTypeMap.end()) {
1017 SpvId result = this->nextId(); 1023 SpvId result = this->nextId();
1018 switch (type.kind()) { 1024 switch (type.kind()) {
1019 case Type::kScalar_Kind: 1025 case Type::kScalar_Kind:
1020 if (type == *fContext.fBool_Type) { 1026 if (type == *fContext.fBool_Type) {
1021 this->writeInstruction(SpvOpTypeBool, result, fConstantBuffe r); 1027 this->writeInstruction(SpvOpTypeBool, result, fConstantBuffe r);
1022 } else if (type == *fContext.fInt_Type) { 1028 } else if (type == *fContext.fInt_Type) {
1023 this->writeInstruction(SpvOpTypeInt, result, 32, 1, fConstan tBuffer); 1029 this->writeInstruction(SpvOpTypeInt, result, 32, 1, fConstan tBuffer);
1024 } else if (type == *fContext.fUInt_Type) { 1030 } else if (type == *fContext.fUInt_Type) {
1025 this->writeInstruction(SpvOpTypeInt, result, 32, 0, fConstan tBuffer); 1031 this->writeInstruction(SpvOpTypeInt, result, 32, 0, fConstan tBuffer);
1026 } else if (type == *fContext.fFloat_Type) { 1032 } else if (type == *fContext.fFloat_Type) {
1027 this->writeInstruction(SpvOpTypeFloat, result, 32, fConstant Buffer); 1033 this->writeInstruction(SpvOpTypeFloat, result, 32, fConstant Buffer);
1028 } else if (type == *fContext.fDouble_Type) { 1034 } else if (type == *fContext.fDouble_Type) {
1029 this->writeInstruction(SpvOpTypeFloat, result, 64, fConstant Buffer); 1035 this->writeInstruction(SpvOpTypeFloat, result, 64, fConstant Buffer);
1030 } else { 1036 } else {
1031 ASSERT(false); 1037 ASSERT(false);
1032 } 1038 }
1033 break; 1039 break;
1034 case Type::kVector_Kind: 1040 case Type::kVector_Kind:
1035 this->writeInstruction(SpvOpTypeVector, result, 1041 this->writeInstruction(SpvOpTypeVector, result,
1036 this->getType(type.componentType()), 1042 this->getType(type.componentType(), layou t),
1037 type.columns(), fConstantBuffer); 1043 type.columns(), fConstantBuffer);
1038 break; 1044 break;
1039 case Type::kMatrix_Kind: 1045 case Type::kMatrix_Kind:
1040 this->writeInstruction(SpvOpTypeMatrix, result, 1046 this->writeInstruction(SpvOpTypeMatrix, result,
1041 this->getType(index_type(fContext, type)) , 1047 this->getType(index_type(fContext, type), layout),
1042 type.columns(), fConstantBuffer); 1048 type.columns(), fConstantBuffer);
1043 break; 1049 break;
1044 case Type::kStruct_Kind: 1050 case Type::kStruct_Kind:
1045 this->writeStruct(type, result); 1051 this->writeStruct(type, layout, result);
1046 break; 1052 break;
1047 case Type::kArray_Kind: { 1053 case Type::kArray_Kind: {
1048 if (type.columns() > 0) { 1054 if (type.columns() > 0) {
1049 IntLiteral count(fContext, Position(), type.columns()); 1055 IntLiteral count(fContext, Position(), type.columns());
1050 this->writeInstruction(SpvOpTypeArray, result, 1056 this->writeInstruction(SpvOpTypeArray, result,
1051 this->getType(type.componentType()), 1057 this->getType(type.componentType(), l ayout),
1052 this->writeIntLiteral(count), fConsta ntBuffer); 1058 this->writeIntLiteral(count), fConsta ntBuffer);
1053 this->writeInstruction(SpvOpDecorate, result, SpvDecorationA rrayStride, 1059 this->writeInstruction(SpvOpDecorate, result, SpvDecorationA rrayStride,
1054 (int32_t) type.stride(), fDecorationB uffer); 1060 (int32_t) layout.stride(type),
1061 fDecorationBuffer);
1055 } else { 1062 } else {
1056 ABORT("runtime-sized arrays are not yet supported"); 1063 ABORT("runtime-sized arrays are not yet supported");
1057 this->writeInstruction(SpvOpTypeRuntimeArray, result, 1064 this->writeInstruction(SpvOpTypeRuntimeArray, result,
1058 this->getType(type.componentType()), fConstantBuffer); 1065 this->getType(type.componentType(), l ayout),
1066 fConstantBuffer);
1059 } 1067 }
1060 break; 1068 break;
1061 } 1069 }
1062 case Type::kSampler_Kind: { 1070 case Type::kSampler_Kind: {
1063 SpvId image = this->nextId(); 1071 SpvId image = this->nextId();
1064 this->writeInstruction(SpvOpTypeImage, image, this->getType(*fCo ntext.fFloat_Type), 1072 this->writeInstruction(SpvOpTypeImage, image,
1073 this->getType(*fContext.fFloat_Type, layo ut),
1065 type.dimensions(), type.isDepth(), type.i sArrayed(), 1074 type.dimensions(), type.isDepth(), type.i sArrayed(),
1066 type.isMultisampled(), type.isSampled(), 1075 type.isMultisampled(), type.isSampled(),
1067 SpvImageFormatUnknown, fConstantBuffer); 1076 SpvImageFormatUnknown, fConstantBuffer);
1068 this->writeInstruction(SpvOpTypeSampledImage, result, image, fCo nstantBuffer); 1077 this->writeInstruction(SpvOpTypeSampledImage, result, image, fCo nstantBuffer);
1069 break; 1078 break;
1070 } 1079 }
1071 default: 1080 default:
1072 if (type == *fContext.fVoid_Type) { 1081 if (type == *fContext.fVoid_Type) {
1073 this->writeInstruction(SpvOpTypeVoid, result, fConstantBuffe r); 1082 this->writeInstruction(SpvOpTypeVoid, result, fConstantBuffe r);
1074 } else { 1083 } else {
1075 ABORT("invalid type: %s", type.description().c_str()); 1084 ABORT("invalid type: %s", type.description().c_str());
1076 } 1085 }
1077 } 1086 }
1078 fTypeMap[type.name()] = result; 1087 fTypeMap[key] = result;
1079 return result; 1088 return result;
1080 } 1089 }
1081 return entry->second; 1090 return entry->second;
1082 } 1091 }
1083 1092
1084 SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { 1093 SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) {
1085 std::string key = function.fReturnType.description() + "("; 1094 std::string key = function.fReturnType.description() + "(";
1086 std::string separator = ""; 1095 std::string separator = "";
1087 for (size_t i = 0; i < function.fParameters.size(); i++) { 1096 for (size_t i = 0; i < function.fParameters.size(); i++) {
1088 key += separator; 1097 key += separator;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 this->writeWord(returnType, fConstantBuffer); 1140 this->writeWord(returnType, fConstantBuffer);
1132 for (SpvId id : parameterTypes) { 1141 for (SpvId id : parameterTypes) {
1133 this->writeWord(id, fConstantBuffer); 1142 this->writeWord(id, fConstantBuffer);
1134 } 1143 }
1135 fTypeMap[key] = result; 1144 fTypeMap[key] = result;
1136 return result; 1145 return result;
1137 } 1146 }
1138 return entry->second; 1147 return entry->second;
1139 } 1148 }
1140 1149
1141 SpvId SPIRVCodeGenerator::getPointerType(const Type& type, 1150 SpvId SPIRVCodeGenerator::getPointerType(const Type& type, SpvStorageClass_ stor ageClass) {
1151 return this->getPointerType(type, fDefaultLayout, storageClass);
1152 }
1153
1154 SpvId SPIRVCodeGenerator::getPointerType(const Type& type, const MemoryLayout& l ayout,
1142 SpvStorageClass_ storageClass) { 1155 SpvStorageClass_ storageClass) {
1143 std::string key = type.description() + "*" + to_string(storageClass); 1156 std::string key = type.description() + "*" + to_string(layout.fStd) + to_str ing(storageClass);
1144 auto entry = fTypeMap.find(key); 1157 auto entry = fTypeMap.find(key);
1145 if (entry == fTypeMap.end()) { 1158 if (entry == fTypeMap.end()) {
1146 SpvId result = this->nextId(); 1159 SpvId result = this->nextId();
1147 this->writeInstruction(SpvOpTypePointer, result, storageClass, 1160 this->writeInstruction(SpvOpTypePointer, result, storageClass,
1148 this->getType(type), fConstantBuffer); 1161 this->getType(type), fConstantBuffer);
1149 fTypeMap[key] = result; 1162 fTypeMap[key] = result;
1150 return result; 1163 return result;
1151 } 1164 }
1152 return entry->second; 1165 return entry->second;
1153 } 1166 }
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 return this->writeVectorConstructor(c, out); 1557 return this->writeVectorConstructor(c, out);
1545 case Type::kMatrix_Kind: 1558 case Type::kMatrix_Kind:
1546 return this->writeMatrixConstructor(c, out); 1559 return this->writeMatrixConstructor(c, out);
1547 default: 1560 default:
1548 ABORT("unsupported constructor: %s", c.description().c_str()); 1561 ABORT("unsupported constructor: %s", c.description().c_str());
1549 } 1562 }
1550 } 1563 }
1551 1564
1552 SpvStorageClass_ get_storage_class(const Modifiers& modifiers) { 1565 SpvStorageClass_ get_storage_class(const Modifiers& modifiers) {
1553 if (modifiers.fFlags & Modifiers::kIn_Flag) { 1566 if (modifiers.fFlags & Modifiers::kIn_Flag) {
1567 ASSERT(!modifiers.fLayout.fPushConstant);
1554 return SpvStorageClassInput; 1568 return SpvStorageClassInput;
1555 } else if (modifiers.fFlags & Modifiers::kOut_Flag) { 1569 } else if (modifiers.fFlags & Modifiers::kOut_Flag) {
1570 ASSERT(!modifiers.fLayout.fPushConstant);
1556 return SpvStorageClassOutput; 1571 return SpvStorageClassOutput;
1557 } else if (modifiers.fFlags & Modifiers::kUniform_Flag) { 1572 } else if (modifiers.fFlags & Modifiers::kUniform_Flag) {
1573 if (modifiers.fLayout.fPushConstant) {
1574 return SpvStorageClassPushConstant;
1575 }
1558 return SpvStorageClassUniform; 1576 return SpvStorageClassUniform;
1559 } else { 1577 } else {
1560 return SpvStorageClassFunction; 1578 return SpvStorageClassFunction;
1561 } 1579 }
1562 } 1580 }
1563 1581
1564 SpvStorageClass_ get_storage_class(const Expression& expr) { 1582 SpvStorageClass_ get_storage_class(const Expression& expr) {
1565 switch (expr.fKind) { 1583 switch (expr.fKind) {
1566 case Expression::kVariableReference_Kind: 1584 case Expression::kVariableReference_Kind:
1567 return get_storage_class(((VariableReference&) expr).fVariable.fModi fiers); 1585 return get_storage_class(((VariableReference&) expr).fVariable.fModi fiers);
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nDescriptorSet, 2369 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nDescriptorSet,
2352 layout.fSet, fDecorationBuffer); 2370 layout.fSet, fDecorationBuffer);
2353 } 2371 }
2354 if (layout.fBuiltin >= 0) { 2372 if (layout.fBuiltin >= 0) {
2355 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nBuiltIn, 2373 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nBuiltIn,
2356 layout.fBuiltin, fDecorationBuffer); 2374 layout.fBuiltin, fDecorationBuffer);
2357 } 2375 }
2358 } 2376 }
2359 2377
2360 SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { 2378 SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
2361 SpvId type = this->getType(intf.fVariable.fType); 2379 MemoryLayout layout = intf.fVariable.fModifiers.fLayout.fPushConstant ?
2380 MemoryLayout(MemoryLayout::k430_Standard) :
2381 fDefaultLayout;
2382 SpvId type = this->getType(intf.fVariable.fType, layout);
2362 SpvId result = this->nextId(); 2383 SpvId result = this->nextId();
2363 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB uffer); 2384 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB uffer);
2364 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers) ; 2385 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers) ;
2365 SpvId ptrType = this->nextId(); 2386 SpvId ptrType = this->nextId();
2366 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst antBuffer); 2387 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst antBuffer);
2367 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta ntBuffer); 2388 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta ntBuffer);
2368 this->writeLayout(intf.fVariable.fModifiers.fLayout, result); 2389 this->writeLayout(intf.fVariable.fModifiers.fLayout, result);
2369 fVariableMap[&intf.fVariable] = result; 2390 fVariableMap[&intf.fVariable] = result;
2370 return result; 2391 return result;
2371 } 2392 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2407 } 2428 }
2408 SpvId id = this->nextId(); 2429 SpvId id = this->nextId();
2409 fVariableMap[var] = id; 2430 fVariableMap[var] = id;
2410 SpvId type = this->getPointerType(var->fType, storageClass); 2431 SpvId type = this->getPointerType(var->fType, storageClass);
2411 this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantB uffer); 2432 this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantB uffer);
2412 this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer); 2433 this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
2413 if (var->fType.kind() == Type::kMatrix_Kind) { 2434 if (var->fType.kind() == Type::kMatrix_Kind) {
2414 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionColMajor, 2435 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionColMajor,
2415 fDecorationBuffer); 2436 fDecorationBuffer);
2416 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionMatrixStride, 2437 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionMatrixStride,
2417 (SpvId) var->fType.stride(), fDecorationBuffe r); 2438 (SpvId) fDefaultLayout.stride(var->fType),
egdaniel 2016/11/14 18:48:35 extra whitespace
2439 fDecorationBuffer);
2418 } 2440 }
2419 if (varDecl.fValue) { 2441 if (varDecl.fValue) {
2420 ASSERT(!fCurrentBlock); 2442 ASSERT(!fCurrentBlock);
2421 fCurrentBlock = -1; 2443 fCurrentBlock = -1;
2422 SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitiali zersBuffer); 2444 SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitiali zersBuffer);
2423 this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuf fer); 2445 this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuf fer);
2424 fCurrentBlock = 0; 2446 fCurrentBlock = 0;
2425 } 2447 }
2426 this->writeLayout(var->fModifiers.fLayout, id); 2448 this->writeLayout(var->fModifiers.fLayout, id);
2427 } 2449 }
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
2648 this->writeWord(SpvVersion, out); 2670 this->writeWord(SpvVersion, out);
2649 this->writeWord(SKSL_MAGIC, out); 2671 this->writeWord(SKSL_MAGIC, out);
2650 std::stringstream buffer; 2672 std::stringstream buffer;
2651 this->writeInstructions(program, buffer); 2673 this->writeInstructions(program, buffer);
2652 this->writeWord(fIdCount, out); 2674 this->writeWord(fIdCount, out);
2653 this->writeWord(0, out); // reserved, always zero 2675 this->writeWord(0, out); // reserved, always zero
2654 out << buffer.str(); 2676 out << buffer.str();
2655 } 2677 }
2656 2678
2657 } 2679 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698