| 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" |
| 11 | 11 |
| 12 #include "GLSL.std.450.h" | 12 #include "GLSL.std.450.h" |
| 13 | 13 |
| 14 #include "ir/SkSLExpressionStatement.h" | 14 #include "ir/SkSLExpressionStatement.h" |
| 15 #include "ir/SkSLExtension.h" | 15 #include "ir/SkSLExtension.h" |
| 16 #include "ir/SkSLIndexExpression.h" | 16 #include "ir/SkSLIndexExpression.h" |
| 17 #include "ir/SkSLVariableReference.h" | 17 #include "ir/SkSLVariableReference.h" |
| 18 #include "SkSLCompiler.h" |
| 18 | 19 |
| 19 namespace SkSL { | 20 namespace SkSL { |
| 20 | 21 |
| 21 #define SPIRV_DEBUG 0 | 22 #define SPIRV_DEBUG 0 |
| 22 | 23 |
| 23 static const int32_t SKSL_MAGIC = 0x0; // FIXME: we should probably register a
magic number | 24 static const int32_t SKSL_MAGIC = 0x0; // FIXME: we should probably register a
magic number |
| 24 | 25 |
| 25 void SPIRVCodeGenerator::setupIntrinsics() { | 26 void SPIRVCodeGenerator::setupIntrinsics() { |
| 26 #define ALL_GLSL(x) std::make_tuple(kGLSL_STD_450_IntrinsicKind, GLSLstd450 ## x
, GLSLstd450 ## x, \ | 27 #define ALL_GLSL(x) std::make_tuple(kGLSL_STD_450_IntrinsicKind, GLSLstd450 ## x
, GLSLstd450 ## x, \ |
| 27 GLSLstd450 ## x, GLSLstd450 ## x) | 28 GLSLstd450 ## x, GLSLstd450 ## x) |
| (...skipping 2127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2155 } | 2156 } |
| 2156 case Token::MINUSMINUS: { | 2157 case Token::MINUSMINUS: { |
| 2157 std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out); | 2158 std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out); |
| 2158 SpvId one = this->writeExpression(*create_literal_1(fContext, p.fTyp
e), out); | 2159 SpvId one = this->writeExpression(*create_literal_1(fContext, p.fTyp
e), out); |
| 2159 SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load
(out), one, | 2160 SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load
(out), one, |
| 2160 SpvOpFSub, SpvOpISub, SpvO
pISub, SpvOpUndef, | 2161 SpvOpFSub, SpvOpISub, SpvO
pISub, SpvOpUndef, |
| 2161 out); | 2162 out); |
| 2162 lv->store(result, out); | 2163 lv->store(result, out); |
| 2163 return result; | 2164 return result; |
| 2164 } | 2165 } |
| 2165 case Token::NOT: { | 2166 case Token::LOGICALNOT: { |
| 2166 ASSERT(p.fOperand->fType == *fContext.fBool_Type); | 2167 ASSERT(p.fOperand->fType == *fContext.fBool_Type); |
| 2167 SpvId result = this->nextId(); | 2168 SpvId result = this->nextId(); |
| 2168 this->writeInstruction(SpvOpLogicalNot, this->getType(p.fOperand->fT
ype), result, | 2169 this->writeInstruction(SpvOpLogicalNot, this->getType(p.fOperand->fT
ype), result, |
| 2169 this->writeExpression(*p.fOperand, out), out)
; | 2170 this->writeExpression(*p.fOperand, out), out)
; |
| 2170 return result; | 2171 return result; |
| 2171 } | 2172 } |
| 2173 case Token::BITWISENOT: { |
| 2174 SpvId result = this->nextId(); |
| 2175 this->writeInstruction(SpvOpNot, this->getType(p.fOperand->fType), r
esult, |
| 2176 this->writeExpression(*p.fOperand, out), out)
; |
| 2177 return result; |
| 2178 } |
| 2172 default: | 2179 default: |
| 2173 ABORT("unsupported prefix expression: %s", p.description().c_str()); | 2180 ABORT("unsupported prefix expression: %s", p.description().c_str()); |
| 2174 } | 2181 } |
| 2175 } | 2182 } |
| 2176 | 2183 |
| 2177 SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, std
::ostream& out) { | 2184 SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, std
::ostream& out) { |
| 2178 std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out); | 2185 std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out); |
| 2179 SpvId result = lv->load(out); | 2186 SpvId result = lv->load(out); |
| 2180 SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out)
; | 2187 SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out)
; |
| 2181 switch (p.fOperator) { | 2188 switch (p.fOperator) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 fDecorationBuffer); | 2321 fDecorationBuffer); |
| 2315 } | 2322 } |
| 2316 if (layout.fIndex >= 0) { | 2323 if (layout.fIndex >= 0) { |
| 2317 this->writeInstruction(SpvOpDecorate, target, SpvDecorationIndex, layout
.fIndex, | 2324 this->writeInstruction(SpvOpDecorate, target, SpvDecorationIndex, layout
.fIndex, |
| 2318 fDecorationBuffer); | 2325 fDecorationBuffer); |
| 2319 } | 2326 } |
| 2320 if (layout.fSet >= 0) { | 2327 if (layout.fSet >= 0) { |
| 2321 this->writeInstruction(SpvOpDecorate, target, SpvDecorationDescriptorSet
, layout.fSet, | 2328 this->writeInstruction(SpvOpDecorate, target, SpvDecorationDescriptorSet
, layout.fSet, |
| 2322 fDecorationBuffer); | 2329 fDecorationBuffer); |
| 2323 } | 2330 } |
| 2324 if (layout.fBuiltin >= 0) { | 2331 if (layout.fBuiltin >= 0 && layout.fBuiltin != SK_FRAGCOLOR_BUILTIN) { |
| 2325 this->writeInstruction(SpvOpDecorate, target, SpvDecorationBuiltIn, layo
ut.fBuiltin, | 2332 this->writeInstruction(SpvOpDecorate, target, SpvDecorationBuiltIn, layo
ut.fBuiltin, |
| 2326 fDecorationBuffer); | 2333 fDecorationBuffer); |
| 2327 } | 2334 } |
| 2328 } | 2335 } |
| 2329 | 2336 |
| 2330 void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target, int mem
ber) { | 2337 void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target, int mem
ber) { |
| 2331 if (layout.fLocation >= 0) { | 2338 if (layout.fLocation >= 0) { |
| 2332 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio
nLocation, | 2339 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio
nLocation, |
| 2333 layout.fLocation, fDecorationBuffer); | 2340 layout.fLocation, fDecorationBuffer); |
| 2334 } | 2341 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2356 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB
uffer); | 2363 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB
uffer); |
| 2357 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers)
; | 2364 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers)
; |
| 2358 SpvId ptrType = this->nextId(); | 2365 SpvId ptrType = this->nextId(); |
| 2359 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst
antBuffer); | 2366 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst
antBuffer); |
| 2360 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta
ntBuffer); | 2367 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta
ntBuffer); |
| 2361 this->writeLayout(intf.fVariable.fModifiers.fLayout, result); | 2368 this->writeLayout(intf.fVariable.fModifiers.fLayout, result); |
| 2362 fVariableMap[&intf.fVariable] = result; | 2369 fVariableMap[&intf.fVariable] = result; |
| 2363 return result; | 2370 return result; |
| 2364 } | 2371 } |
| 2365 | 2372 |
| 2366 void SPIRVCodeGenerator::writeGlobalVars(const VarDeclarations& decl, std::ostre
am& out) { | 2373 #define BUILTIN_IGNORE 9999 |
| 2374 void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio
ns& decl, |
| 2375 std::ostream& out) { |
| 2367 for (size_t i = 0; i < decl.fVars.size(); i++) { | 2376 for (size_t i = 0; i < decl.fVars.size(); i++) { |
| 2368 const VarDeclaration& varDecl = decl.fVars[i]; | 2377 const VarDeclaration& varDecl = decl.fVars[i]; |
| 2369 const Variable* var = varDecl.fVar; | 2378 const Variable* var = varDecl.fVar; |
| 2379 if (var->fModifiers.fLayout.fBuiltin == BUILTIN_IGNORE) { |
| 2380 continue; |
| 2381 } |
| 2382 if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN && |
| 2383 kind != Program::kFragment_Kind) { |
| 2384 continue; |
| 2385 } |
| 2370 if (!var->fIsReadFrom && !var->fIsWrittenTo && | 2386 if (!var->fIsReadFrom && !var->fIsWrittenTo && |
| 2371 !(var->fModifiers.fFlags & (Modifiers::kIn_Flag | | 2387 !(var->fModifiers.fFlags & (Modifiers::kIn_Flag | |
| 2372 Modifiers::kOut_Flag | | 2388 Modifiers::kOut_Flag | |
| 2373 Modifiers::kUniform_Flag))) { | 2389 Modifiers::kUniform_Flag))) { |
| 2374 // variable is dead and not an input / output var (the Vulkan debug
layers complain if | 2390 // variable is dead and not an input / output var (the Vulkan debug
layers complain if |
| 2375 // we elide an interface var, even if it's dead) | 2391 // we elide an interface var, even if it's dead) |
| 2376 continue; | 2392 continue; |
| 2377 } | 2393 } |
| 2378 SpvStorageClass_ storageClass; | 2394 SpvStorageClass_ storageClass; |
| 2379 if (var->fModifiers.fFlags & Modifiers::kIn_Flag) { | 2395 if (var->fModifiers.fFlags & Modifiers::kIn_Flag) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2555 InterfaceBlock& intf = (InterfaceBlock&) *program.fElements[i]; | 2571 InterfaceBlock& intf = (InterfaceBlock&) *program.fElements[i]; |
| 2556 SpvId id = this->writeInterfaceBlock(intf); | 2572 SpvId id = this->writeInterfaceBlock(intf); |
| 2557 if ((intf.fVariable.fModifiers.fFlags & Modifiers::kIn_Flag) || | 2573 if ((intf.fVariable.fModifiers.fFlags & Modifiers::kIn_Flag) || |
| 2558 (intf.fVariable.fModifiers.fFlags & Modifiers::kOut_Flag)) { | 2574 (intf.fVariable.fModifiers.fFlags & Modifiers::kOut_Flag)) { |
| 2559 interfaceVars.push_back(id); | 2575 interfaceVars.push_back(id); |
| 2560 } | 2576 } |
| 2561 } | 2577 } |
| 2562 } | 2578 } |
| 2563 for (size_t i = 0; i < program.fElements.size(); i++) { | 2579 for (size_t i = 0; i < program.fElements.size(); i++) { |
| 2564 if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) { | 2580 if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) { |
| 2565 this->writeGlobalVars(((VarDeclarations&) *program.fElements[i]), bo
dy); | 2581 this->writeGlobalVars(program.fKind, ((VarDeclarations&) *program.fE
lements[i]), |
| 2582 body); |
| 2566 } | 2583 } |
| 2567 } | 2584 } |
| 2568 for (size_t i = 0; i < program.fElements.size(); i++) { | 2585 for (size_t i = 0; i < program.fElements.size(); i++) { |
| 2569 if (program.fElements[i]->fKind == ProgramElement::kFunction_Kind) { | 2586 if (program.fElements[i]->fKind == ProgramElement::kFunction_Kind) { |
| 2570 this->writeFunction(((FunctionDefinition&) *program.fElements[i]), b
ody); | 2587 this->writeFunction(((FunctionDefinition&) *program.fElements[i]), b
ody); |
| 2571 } | 2588 } |
| 2572 } | 2589 } |
| 2573 const FunctionDeclaration* main = nullptr; | 2590 const FunctionDeclaration* main = nullptr; |
| 2574 for (auto entry : fFunctionMap) { | 2591 for (auto entry : fFunctionMap) { |
| 2575 if (entry.first->fName == "main") { | 2592 if (entry.first->fName == "main") { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2629 this->writeWord(SpvVersion, out); | 2646 this->writeWord(SpvVersion, out); |
| 2630 this->writeWord(SKSL_MAGIC, out); | 2647 this->writeWord(SKSL_MAGIC, out); |
| 2631 std::stringstream buffer; | 2648 std::stringstream buffer; |
| 2632 this->writeInstructions(program, buffer); | 2649 this->writeInstructions(program, buffer); |
| 2633 this->writeWord(fIdCount, out); | 2650 this->writeWord(fIdCount, out); |
| 2634 this->writeWord(0, out); // reserved, always zero | 2651 this->writeWord(0, out); // reserved, always zero |
| 2635 out << buffer.str(); | 2652 out << buffer.str(); |
| 2636 } | 2653 } |
| 2637 | 2654 |
| 2638 } | 2655 } |
| OLD | NEW |