Index: src/sksl/SkSLSPIRVCodeGenerator.cpp |
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp |
index 300d3c5d663dd06c8b0e29eec4ba1554ed6f092b..ecde11509daa185fc78cf14420b62633f571571a 100644 |
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp |
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp |
@@ -975,13 +975,13 @@ SpvId SPIRVCodeGenerator::nextId() { |
return fIdCount++; |
} |
-void SPIRVCodeGenerator::writeStruct(const Type& type, SpvId resultId) { |
+void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& layout, SpvId resultId) { |
this->writeInstruction(SpvOpName, resultId, type.name().c_str(), fNameBuffer); |
// go ahead and write all of the field types, so we don't inadvertently write them while we're |
// in the middle of writing the struct instruction |
std::vector<SpvId> types; |
for (const auto& f : type.fields()) { |
- types.push_back(this->getType(*f.fType)); |
+ types.push_back(this->getType(*f.fType, layout)); |
} |
this->writeOpCode(SpvOpTypeStruct, 2 + (int32_t) types.size(), fConstantBuffer); |
this->writeWord(resultId, fConstantBuffer); |
@@ -990,8 +990,8 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, SpvId resultId) { |
} |
size_t offset = 0; |
for (int32_t i = 0; i < (int32_t) type.fields().size(); i++) { |
- size_t size = type.fields()[i].fType->size(); |
- size_t alignment = type.fields()[i].fType->alignment(); |
+ size_t size = layout.size(*type.fields()[i].fType); |
+ size_t alignment = layout.alignment(*type.fields()[i].fType); |
size_t mod = offset % alignment; |
if (mod != 0) { |
offset += alignment - mod; |
@@ -1007,7 +1007,8 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, SpvId resultId) { |
this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationColMajor, |
fDecorationBuffer); |
this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationMatrixStride, |
- (SpvId) type.fields()[i].fType->stride(), fDecorationBuffer); |
+ (SpvId) layout.stride(*type.fields()[i].fType), |
+ fDecorationBuffer); |
} |
offset += size; |
Type::Kind kind = type.fields()[i].fType->kind(); |
@@ -1018,7 +1019,12 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, SpvId resultId) { |
} |
SpvId SPIRVCodeGenerator::getType(const Type& type) { |
- auto entry = fTypeMap.find(type.name()); |
+ return this->getType(type, fDefaultLayout); |
+} |
+ |
+SpvId SPIRVCodeGenerator::getType(const Type& type, const MemoryLayout& layout) { |
+ SkString key = type.name() + to_string((int) layout.fStd); |
+ auto entry = fTypeMap.find(key); |
if (entry == fTypeMap.end()) { |
SpvId result = this->nextId(); |
switch (type.kind()) { |
@@ -1039,29 +1045,31 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) { |
break; |
case Type::kVector_Kind: |
this->writeInstruction(SpvOpTypeVector, result, |
- this->getType(type.componentType()), |
+ this->getType(type.componentType(), layout), |
type.columns(), fConstantBuffer); |
break; |
case Type::kMatrix_Kind: |
this->writeInstruction(SpvOpTypeMatrix, result, |
- this->getType(index_type(fContext, type)), |
+ this->getType(index_type(fContext, type), layout), |
type.columns(), fConstantBuffer); |
break; |
case Type::kStruct_Kind: |
- this->writeStruct(type, result); |
+ this->writeStruct(type, layout, result); |
break; |
case Type::kArray_Kind: { |
if (type.columns() > 0) { |
IntLiteral count(fContext, Position(), type.columns()); |
this->writeInstruction(SpvOpTypeArray, result, |
- this->getType(type.componentType()), |
+ this->getType(type.componentType(), layout), |
this->writeIntLiteral(count), fConstantBuffer); |
this->writeInstruction(SpvOpDecorate, result, SpvDecorationArrayStride, |
- (int32_t) type.stride(), fDecorationBuffer); |
+ (int32_t) layout.stride(type), |
+ fDecorationBuffer); |
} else { |
ABORT("runtime-sized arrays are not yet supported"); |
this->writeInstruction(SpvOpTypeRuntimeArray, result, |
- this->getType(type.componentType()), fConstantBuffer); |
+ this->getType(type.componentType(), layout), |
+ fConstantBuffer); |
} |
break; |
} |
@@ -1070,7 +1078,8 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) { |
if (SpvDimSubpassData != type.dimensions()) { |
image = this->nextId(); |
} |
- this->writeInstruction(SpvOpTypeImage, image, this->getType(*fContext.fFloat_Type), |
+ this->writeInstruction(SpvOpTypeImage, image, |
+ this->getType(*fContext.fFloat_Type, layout), |
type.dimensions(), type.isDepth(), type.isArrayed(), |
type.isMultisampled(), type.isSampled() ? 1 : 2, |
SpvImageFormatUnknown, fConstantBuffer); |
@@ -1086,7 +1095,7 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) { |
ABORT("invalid type: %s", type.description().c_str()); |
} |
} |
- fTypeMap[type.name()] = result; |
+ fTypeMap[key] = result; |
return result; |
} |
return entry->second; |
@@ -1149,9 +1158,13 @@ SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { |
return entry->second; |
} |
-SpvId SPIRVCodeGenerator::getPointerType(const Type& type, |
+SpvId SPIRVCodeGenerator::getPointerType(const Type& type, SpvStorageClass_ storageClass) { |
+ return this->getPointerType(type, fDefaultLayout, storageClass); |
+} |
+ |
+SpvId SPIRVCodeGenerator::getPointerType(const Type& type, const MemoryLayout& layout, |
SpvStorageClass_ storageClass) { |
- SkString key = type.description() + "*" + to_string(storageClass); |
+ SkString key = type.description() + "*" + to_string(layout.fStd) + to_string(storageClass); |
auto entry = fTypeMap.find(key); |
if (entry == fTypeMap.end()) { |
SpvId result = this->nextId(); |
@@ -1590,10 +1603,15 @@ SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, SkWStream& out) |
SpvStorageClass_ get_storage_class(const Modifiers& modifiers) { |
if (modifiers.fFlags & Modifiers::kIn_Flag) { |
+ ASSERT(!modifiers.fLayout.fPushConstant); |
return SpvStorageClassInput; |
} else if (modifiers.fFlags & Modifiers::kOut_Flag) { |
+ ASSERT(!modifiers.fLayout.fPushConstant); |
return SpvStorageClassOutput; |
} else if (modifiers.fFlags & Modifiers::kUniform_Flag) { |
+ if (modifiers.fLayout.fPushConstant) { |
+ return SpvStorageClassPushConstant; |
+ } |
return SpvStorageClassUniform; |
} else { |
return SpvStorageClassFunction; |
@@ -2404,7 +2422,10 @@ void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target, int mem |
} |
SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { |
- SpvId type = this->getType(intf.fVariable.fType); |
+ MemoryLayout layout = intf.fVariable.fModifiers.fLayout.fPushConstant ? |
+ MemoryLayout(MemoryLayout::k430_Standard) : |
+ fDefaultLayout; |
+ SpvId type = this->getType(intf.fVariable.fType, layout); |
SpvId result = this->nextId(); |
this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationBuffer); |
SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers); |
@@ -2460,7 +2481,7 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio |
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor, |
fDecorationBuffer); |
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationMatrixStride, |
- (SpvId) var->fType.stride(), fDecorationBuffer); |
+ (SpvId) fDefaultLayout.stride(var->fType), fDecorationBuffer); |
} |
if (varDecl.fValue) { |
ASSERT(!fCurrentBlock); |