diff --git a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp index 44a8286c35..35d6c18b6b 100644 --- a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp @@ -83,7 +83,6 @@ bool SPIRVCodeGenerator::Instruction::operator==(const SPIRVCodeGenerator::Instr return fOp == that.fOp && fResultKind == that.fResultKind && fWords == that.fWords; - } struct SPIRVCodeGenerator::Instruction::Hash { @@ -103,6 +102,7 @@ struct SPIRVCodeGenerator::Word { kNumber, kDefaultPrecisionResult, kRelaxedPrecisionResult, + kUncachedResult, }; Word(SpvId id) : fValue(id), fKind(Kind::kSpvId) {} @@ -122,6 +122,10 @@ struct SPIRVCodeGenerator::Word { return Word{(int32_t)NA, kind}; } + static Word UncachedResult() { + return Word{(int32_t)NA, kUncachedResult}; + } + static Word Result() { return Word{(int32_t)NA, kDefaultPrecisionResult}; } @@ -515,10 +519,9 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t this->writeWord(word8, out); } -SpvId SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, - const SkTArray& words, - OutputStream& out) { - // Build up an cache key for this word. +SPIRVCodeGenerator::Instruction SPIRVCodeGenerator::BuildInstructionKey( + SpvOp_ opCode, const SkTArray& words) { + // Assemble a cache key for this instruction. Instruction key; key.fOp = opCode; key.fWords.resize(words.count()); @@ -533,27 +536,52 @@ SpvId SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, } } + return key; +} + +SpvId SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, + const SkTArray& words, + OutputStream& out) { + // If this instruction exists in our op cache, return the cached SpvId. + Instruction key = BuildInstructionKey(opCode, words); + if (SpvId* cachedOp = fOpCache.find(key)) { + return *cachedOp; + } + SpvId result = NA; - if (key.fResultKind != Word::Kind::kNone) { - // If this instruction exists in our op cache, return the cached SpvId. - if (SpvId* cachedOp = fOpCache.find(key)) { - return *cachedOp; - } - // Consume a new SpvId and cache the instruction. - result = fIdCount++; - fOpCache.set(key, result); - fSpvIdCache.set(result, key); + switch (key.fResultKind) { + case Word::Kind::kUncachedResult: + // The instruction returns a SpvId, but we do not want caching or deduplication. + result = fIdCount++; + break; - // Globally-reachable ops are not subject to the whims of flow control. - if (!is_globally_reachable_op(opCode)) { - fReachableOps.push_back(result); - } - // If the result is relaxed-precision, add the requisite decoration. - if (key.fResultKind == Word::Kind::kRelaxedPrecisionResult) { - this->writeInstruction(SpvOpDecorate, result, SpvDecorationRelaxedPrecision, - fDecorationBuffer); - } + case Word::Kind::kNone: + // The instruction doesn't return a SpvId, but we can still cache and deduplicate it. + fOpCache.set(key, result); + break; + + case Word::Kind::kDefaultPrecisionResult: + case Word::Kind::kRelaxedPrecisionResult: + // Consume a new SpvId and cache the instruction. + result = fIdCount++; + fOpCache.set(key, result); + fSpvIdCache.set(result, key); + + // Globally-reachable ops are not subject to the whims of flow control. + if (!is_globally_reachable_op(opCode)) { + fReachableOps.push_back(result); + } + // If the result is relaxed-precision, add the requisite decoration. + if (key.fResultKind == Word::Kind::kRelaxedPrecisionResult) { + this->writeInstruction(SpvOpDecorate, result, SpvDecorationRelaxedPrecision, + fDecorationBuffer); + } + break; + + default: + SkDEBUGFAIL("unexpected result kind"); + break; } // Write the requested instruction. @@ -750,27 +778,30 @@ SpvId SPIRVCodeGenerator::nextId(Precision precision) { return fIdCount++; } -void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memoryLayout, - SpvId resultId) { - this->writeInstruction(SpvOpName, resultId, type.name(), 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 types; +SpvId SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memoryLayout) { + // If we've already written out this struct, return its existing SpvId. + if (SpvId* cachedStructId = fStructMap.find(&type)) { + return *cachedStructId; + } + + // Write all of the field types first, so we don't inadvertently write them while we're in the + // middle of writing the struct instruction. + Words words; + words.push_back(Word::UncachedResult()); for (const auto& f : type.fields()) { - types.push_back(this->getType(*f.fType, memoryLayout)); - } - this->writeOpCode(SpvOpTypeStruct, 2 + (int32_t) types.size(), fConstantBuffer); - this->writeWord(resultId, fConstantBuffer); - for (SpvId id : types) { - this->writeWord(id, fConstantBuffer); + words.push_back(this->getType(*f.fType, memoryLayout)); } + SpvId resultId = this->writeInstruction(SpvOpTypeStruct, words, fConstantBuffer); + this->writeInstruction(SpvOpName, resultId, type.name(), fNameBuffer); + fStructMap.set(&type, resultId); + size_t offset = 0; for (int32_t i = 0; i < (int32_t) type.fields().size(); i++) { const Type::Field& field = type.fields()[i]; if (!MemoryLayout::LayoutIsSupported(*field.fType)) { fContext.fErrors->error(type.fPosition, "type '" + field.fType->displayName() + - "' is not permitted here"); - return; + "' is not permitted here"); + return resultId; } size_t size = memoryLayout.size(*field.fType); size_t alignment = memoryLayout.alignment(*field.fType); @@ -782,8 +813,8 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor } if (fieldLayout.fOffset % alignment) { fContext.fErrors->error(field.fPosition, - "offset of field '" + std::string(field.fName) + - "' must be a multiple of " + std::to_string(alignment)); + "offset of field '" + std::string(field.fName) + + "' must be a multiple of " + std::to_string(alignment)); } offset = fieldLayout.fOffset; } else { @@ -814,6 +845,8 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor offset += alignment - offset % alignment; } } + + return resultId; } const Type& SPIRVCodeGenerator::getActualType(const Type& type) { @@ -845,132 +878,105 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) { } SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layout) { - const Type* type; - std::unique_ptr arrayType; - std::string arrayName; + const Type* type = &rawType; - if (rawType.isArray()) { - // For arrays, we need to synthesize a temporary Array type using the "actual" component - // type. That is, if `short[10]` is passed in, we need to synthesize a `int[10]` Type. - // Otherwise, we can end up with two different SpvIds for the same array type. - const Type& component = this->getActualType(rawType.componentType()); - arrayName = component.getArrayName(rawType.columns()); - arrayType = Type::MakeArrayType(arrayName, component, rawType.columns()); - type = arrayType.get(); - } else { - // For non-array types, we can simply look up the "actual" type and use it. - type = &this->getActualType(rawType); - } - - std::string key(type->name()); - if (type->isStruct() || type->isArray()) { - key += std::to_string(layout.fStd); -#ifdef SK_DEBUG - SkASSERT(layout.fStd == MemoryLayout::Standard::k140_Standard || - layout.fStd == MemoryLayout::Standard::k430_Standard); - MemoryLayout::Standard otherStd = layout.fStd == MemoryLayout::Standard::k140_Standard - ? MemoryLayout::Standard::k430_Standard - : MemoryLayout::Standard::k140_Standard; - std::string otherKey = type->displayName() + std::to_string(otherStd); - SkASSERT(!fTypeMap.find(otherKey)); -#endif - } - SpvId* entry = fTypeMap.find(key); - if (!entry) { - SpvId result = this->nextId(nullptr); - switch (type->typeKind()) { - case Type::TypeKind::kScalar: - if (type->isBoolean()) { - this->writeInstruction(SpvOpTypeBool, result, fConstantBuffer); - } else if (type->isSigned()) { - this->writeInstruction(SpvOpTypeInt, result, 32, 1, fConstantBuffer); - } else if (type->isUnsigned()) { - this->writeInstruction(SpvOpTypeInt, result, 32, 0, fConstantBuffer); - } else if (type->isFloat()) { - this->writeInstruction(SpvOpTypeFloat, result, 32, fConstantBuffer); - } else { - SkDEBUGFAILF("unrecognized scalar type '%s'", type->description().c_str()); - } - break; - case Type::TypeKind::kVector: - this->writeInstruction(SpvOpTypeVector, result, - this->getType(type->componentType(), layout), - type->columns(), fConstantBuffer); - break; - case Type::TypeKind::kMatrix: - this->writeInstruction( - SpvOpTypeMatrix, - result, - this->getType(IndexExpression::IndexType(fContext, *type), layout), - type->columns(), - fConstantBuffer); - break; - case Type::TypeKind::kStruct: - this->writeStruct(*type, layout, result); - break; - case Type::TypeKind::kArray: { - if (!MemoryLayout::LayoutIsSupported(*type)) { - fContext.fErrors->error(type->fPosition, "type '" + type->displayName() + - "' is not permitted here"); - return this->nextId(nullptr); - } - if (type->columns() > 0) { - SpvId typeId = this->getType(type->componentType(), layout); - SpvId countId = this->writeLiteral(type->columns(), *fContext.fTypes.fInt); - this->writeInstruction(SpvOpTypeArray, result, typeId, countId, - fConstantBuffer); - this->writeInstruction(SpvOpDecorate, result, SpvDecorationArrayStride, - (int32_t) layout.stride(*type), - fDecorationBuffer); - } else { - // We shouldn't have any runtime-sized arrays right now - fContext.fErrors->error(type->fPosition, - "runtime-sized arrays are not supported in SPIR-V"); - this->writeInstruction(SpvOpTypeRuntimeArray, result, - this->getType(type->componentType(), layout), - fConstantBuffer); - this->writeInstruction(SpvOpDecorate, result, SpvDecorationArrayStride, - (int32_t) layout.stride(*type), - fDecorationBuffer); - } - break; - } - case Type::TypeKind::kSampler: { - // Subpass inputs should use the Texture type, not a Sampler. - SkASSERT(type->dimensions() != SpvDimSubpassData); - if (type->dimensions() == SpvDimBuffer) { - fCapabilities |= 1ULL << SpvCapabilitySampledBuffer; - } - SpvId imageTypeId = this->getType(type->textureType(), layout); - this->writeInstruction(SpvOpTypeSampledImage, result, imageTypeId, - fConstantBuffer); - break; - } - case Type::TypeKind::kSeparateSampler: { - this->writeInstruction(SpvOpTypeSampler, result, fConstantBuffer); - break; - } - case Type::TypeKind::kTexture: { - this->writeInstruction(SpvOpTypeImage, result, - this->getType(*fContext.fTypes.fFloat, layout), - type->dimensions(), type->isDepth(), - type->isArrayedTexture(), type->isMultisampled(), - type->isSampled() ? 1 : 2, SpvImageFormatUnknown, - fConstantBuffer); - break; - } - default: - if (type->isVoid()) { - this->writeInstruction(SpvOpTypeVoid, result, fConstantBuffer); - } else { - SkDEBUGFAILF("invalid type: %s", type->description().c_str()); - } - break; + switch (type->typeKind()) { + case Type::TypeKind::kVoid: { + return this->writeInstruction(SpvOpTypeVoid, {Word::Result()}, fConstantBuffer); + } + case Type::TypeKind::kScalar: + case Type::TypeKind::kLiteral: { + if (type->isBoolean()) { + return this->writeInstruction(SpvOpTypeBool, {Word::Result()}, fConstantBuffer); + } + if (type->isSigned()) { + return this->writeInstruction(SpvOpTypeInt, + {Word::Result(), Word::Number(32), Word::Number(1)}, + fConstantBuffer); + } + if (type->isUnsigned()) { + return this->writeInstruction(SpvOpTypeInt, + {Word::Result(), Word::Number(32), Word::Number(0)}, + fConstantBuffer); + } + if (type->isFloat()) { + return this->writeInstruction(SpvOpTypeFloat, + {Word::Result(), Word::Number(32)}, + fConstantBuffer); + } + SkDEBUGFAILF("unrecognized scalar type '%s'", type->description().c_str()); + return (SpvId)-1; + } + case Type::TypeKind::kVector: { + SpvId scalarTypeId = this->getType(type->componentType(), layout); + return this->writeInstruction( + SpvOpTypeVector, + {Word::Result(), scalarTypeId, Word::Number(type->columns())}, + fConstantBuffer); + } + case Type::TypeKind::kMatrix: { + SpvId vectorTypeId = this->getType(IndexExpression::IndexType(fContext, *type), layout); + return this->writeInstruction( + SpvOpTypeMatrix, + {Word::Result(), vectorTypeId, Word::Number(type->columns())}, + fConstantBuffer); + } + case Type::TypeKind::kArray: { + if (!MemoryLayout::LayoutIsSupported(*type)) { + fContext.fErrors->error(type->fPosition, "type '" + type->displayName() + + "' is not permitted here"); + return NA; + } + if (type->columns() == 0) { + // We do not support runtime-sized arrays. + fContext.fErrors->error(type->fPosition, "runtime-sized arrays are not supported"); + return NA; + } + SpvId typeId = this->getType(type->componentType(), layout); + SpvId countId = this->writeLiteral(type->columns(), *fContext.fTypes.fInt); + SpvId result = this->writeInstruction(SpvOpTypeArray, {Word::Result(), typeId, countId}, + fConstantBuffer); + this->writeInstruction( + SpvOpDecorate, + {result, SpvDecorationArrayStride, Word::Number(layout.stride(*type))}, + fDecorationBuffer); + return result; + } + case Type::TypeKind::kStruct: { + return this->writeStruct(*type, layout); + } + case Type::TypeKind::kSeparateSampler: { + return this->writeInstruction(SpvOpTypeSampler, {Word::Result()}, fConstantBuffer); + } + case Type::TypeKind::kSampler: { + // Subpass inputs should use the Texture type, not a Sampler. + SkASSERT(type->dimensions() != SpvDimSubpassData); + if (SpvDimBuffer == type->dimensions()) { + fCapabilities |= 1ULL << SpvCapabilitySampledBuffer; + } + SpvId imageTypeId = this->getType(type->textureType(), layout); + return this->writeInstruction(SpvOpTypeSampledImage, + {Word::Result(), imageTypeId}, + fConstantBuffer); + } + case Type::TypeKind::kTexture: { + SpvId floatTypeId = this->getType(*fContext.fTypes.fFloat, layout); + return this->writeInstruction(SpvOpTypeImage, + {Word::Result(), + floatTypeId, + Word::Number(type->dimensions()), + Word::Number(type->isDepth()), + Word::Number(type->isArrayedTexture()), + Word::Number(type->isMultisampled()), + Word::Number(type->isSampled() ? 1 : 2), + SpvImageFormatUnknown}, + fConstantBuffer); + } + default: { + SkDEBUGFAILF("invalid type: %s", type->description().c_str()); + return NA; } - fTypeMap[key] = result; - return result; } - return *entry; } SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { diff --git a/src/sksl/codegen/SkSLSPIRVCodeGenerator.h b/src/sksl/codegen/SkSLSPIRVCodeGenerator.h index 2372079cea..84f7665416 100644 --- a/src/sksl/codegen/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/codegen/SkSLSPIRVCodeGenerator.h @@ -180,7 +180,7 @@ private: void writeFieldLayout(const Layout& layout, SpvId target, int member); - void writeStruct(const Type& type, const MemoryLayout& layout, SpvId resultId); + SpvId writeStruct(const Type& type, const MemoryLayout& memoryLayout); void writeProgramElement(const ProgramElement& pe, OutputStream& out); @@ -435,6 +435,8 @@ private: struct Hash; }; + static Instruction BuildInstructionKey(SpvOp_ opCode, const SkTArray& words); + // The writeOpXxxxx calls will simplify and deduplicate ops where possible. SpvId writeOpConstantTrue(const Type& type); SpvId writeOpConstantFalse(const Type& type); @@ -492,7 +494,7 @@ private: SkTHashMap fIntrinsicMap; SkTHashMap fFunctionMap; SkTHashMap fVariableMap; - SkTHashMap fTypeMap; + SkTHashMap fStructMap; StringStream fGlobalInitializersBuffer; StringStream fConstantBuffer; StringStream fVariableBuffer; diff --git a/tests/sksl/shared/ComplexDelete.asm.frag b/tests/sksl/shared/ComplexDelete.asm.frag index 42d8b5f88d..4bccf3f2ab 100644 --- a/tests/sksl/shared/ComplexDelete.asm.frag +++ b/tests/sksl/shared/ComplexDelete.asm.frag @@ -31,10 +31,10 @@ OpDecorate %24 RelaxedPrecision %bool = OpTypeBool %_ptr_Input_bool = OpTypePointer Input %bool %sk_Clockwise = OpVariable %_ptr_Input_bool Input -%12 = OpTypeImage %float 2D 0 0 0 1 Unknown -%11 = OpTypeSampledImage %12 -%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 -%s = OpVariable %_ptr_UniformConstant_11 UniformConstant +%11 = OpTypeImage %float 2D 0 0 0 1 Unknown +%12 = OpTypeSampledImage %11 +%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 +%s = OpVariable %_ptr_UniformConstant_12 UniformConstant %mat4v4float = OpTypeMatrix %v4float 4 %_UniformBuffer = OpTypeStruct %mat4v4float %_ptr_Uniform__UniformBuffer = OpTypePointer Uniform %_UniformBuffer @@ -61,7 +61,7 @@ OpDecorate %24 RelaxedPrecision %20 = OpLabel %tmpColor = OpVariable %_ptr_Function_v4float Function %55 = OpVariable %_ptr_Function_v4float Function -%24 = OpLoad %11 %s +%24 = OpLoad %12 %s %23 = OpImageSampleImplicitLod %v4float %24 %27 OpStore %tmpColor %23 %28 = OpAccessChain %_ptr_Uniform_mat4v4float %14 %int_0 diff --git a/tests/sksl/shared/GaussianBlur.asm.frag b/tests/sksl/shared/GaussianBlur.asm.frag index f33b5f7b00..8ef73e96b1 100644 --- a/tests/sksl/shared/GaussianBlur.asm.frag +++ b/tests/sksl/shared/GaussianBlur.asm.frag @@ -260,10 +260,10 @@ OpDecorate %527 RelaxedPrecision %bool = OpTypeBool %_ptr_Input_bool = OpTypePointer Input %bool %sk_Clockwise = OpVariable %_ptr_Input_bool Input -%22 = OpTypeImage %float 2D 0 0 0 1 Unknown -%21 = OpTypeSampledImage %22 -%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21 -%uTextureSampler_0_Stage1 = OpVariable %_ptr_UniformConstant_21 UniformConstant +%21 = OpTypeImage %float 2D 0 0 0 1 Unknown +%22 = OpTypeSampledImage %21 +%_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22 +%uTextureSampler_0_Stage1 = OpVariable %_ptr_UniformConstant_22 UniformConstant %_ptr_Input_v2float = OpTypePointer Input %v2float %vLocalCoord_Stage0 = OpVariable %_ptr_Input_v2float Input %_ptr_Function_v4float = OpTypePointer Function %v4float @@ -325,7 +325,7 @@ OpStore %54 %53 OpStore %59 %58 %62 = OpLoad %v2float %_2_subsetCoord OpStore %_3_clampedCoord %62 -%65 = OpLoad %21 %uTextureSampler_0_Stage1 +%65 = OpLoad %22 %uTextureSampler_0_Stage1 %66 = OpLoad %v2float %_3_clampedCoord %67 = OpAccessChain %_ptr_Uniform_v4float %4 %int_6 %68 = OpLoad %v4float %67 diff --git a/tests/sksl/shared/InterfaceBlockNamedArray.asm.frag b/tests/sksl/shared/InterfaceBlockNamedArray.asm.frag index 320f21c0c1..897568222e 100644 --- a/tests/sksl/shared/InterfaceBlockNamedArray.asm.frag +++ b/tests/sksl/shared/InterfaceBlockNamedArray.asm.frag @@ -1,6 +1,6 @@ ### Compilation failed: -error: SPIR-V validation error: Block decoration on target '4[%_arr_testBlock_int_2]' must be a structure type +error: SPIR-V validation error: Block decoration on target '8[%_arr_testBlock_int_2]' must be a structure type OpDecorate %_arr_testBlock_int_2 Block OpCapability Shader diff --git a/tests/sksl/shared/RectangleTexture.asm.frag b/tests/sksl/shared/RectangleTexture.asm.frag index cfd39fbed3..bf9be9e19b 100644 --- a/tests/sksl/shared/RectangleTexture.asm.frag +++ b/tests/sksl/shared/RectangleTexture.asm.frag @@ -28,11 +28,11 @@ OpDecorate %26 RelaxedPrecision %bool = OpTypeBool %_ptr_Input_bool = OpTypePointer Input %bool %sk_Clockwise = OpVariable %_ptr_Input_bool Input -%12 = OpTypeImage %float 2D 0 0 0 1 Unknown -%11 = OpTypeSampledImage %12 -%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 -%test2D = OpVariable %_ptr_UniformConstant_11 UniformConstant -%test2DRect = OpVariable %_ptr_UniformConstant_11 UniformConstant +%11 = OpTypeImage %float 2D 0 0 0 1 Unknown +%12 = OpTypeSampledImage %11 +%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 +%test2D = OpVariable %_ptr_UniformConstant_12 UniformConstant +%test2DRect = OpVariable %_ptr_UniformConstant_12 UniformConstant %void = OpTypeVoid %16 = OpTypeFunction %void %float_0_5 = OpConstant %float 0.5 @@ -42,13 +42,13 @@ OpDecorate %26 RelaxedPrecision %28 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5 %main = OpFunction %void None %16 %17 = OpLabel -%19 = OpLoad %11 %test2D +%19 = OpLoad %12 %test2D %18 = OpImageSampleImplicitLod %v4float %19 %22 OpStore %sk_FragColor %18 -%24 = OpLoad %11 %test2DRect +%24 = OpLoad %12 %test2DRect %23 = OpImageSampleImplicitLod %v4float %24 %22 OpStore %sk_FragColor %23 -%26 = OpLoad %11 %test2DRect +%26 = OpLoad %12 %test2DRect %25 = OpImageSampleProjImplicitLod %v4float %26 %28 OpStore %sk_FragColor %25 OpReturn diff --git a/tests/sksl/shared/Texture1D.asm.frag b/tests/sksl/shared/Texture1D.asm.frag index 344402d43b..b39615a23c 100644 --- a/tests/sksl/shared/Texture1D.asm.frag +++ b/tests/sksl/shared/Texture1D.asm.frag @@ -1,7 +1,7 @@ ### Compilation failed: error: SPIR-V validation error: Operand 3 of TypeImage requires one of these capabilities: Sampled1D Image1D - %12 = OpTypeImage %float 1D 0 0 0 1 Unknown + %11 = OpTypeImage %float 1D 0 0 0 1 Unknown OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -35,10 +35,10 @@ OpDecorate %35 RelaxedPrecision %bool = OpTypeBool %_ptr_Input_bool = OpTypePointer Input %bool %sk_Clockwise = OpVariable %_ptr_Input_bool Input -%12 = OpTypeImage %float 1D 0 0 0 1 Unknown -%11 = OpTypeSampledImage %12 -%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 -%tex = OpVariable %_ptr_UniformConstant_11 UniformConstant +%11 = OpTypeImage %float 1D 0 0 0 1 Unknown +%12 = OpTypeSampledImage %11 +%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 +%tex = OpVariable %_ptr_UniformConstant_12 UniformConstant %void = OpTypeVoid %15 = OpTypeFunction %void %_ptr_Function_v4float = OpTypePointer Function %v4float @@ -49,10 +49,10 @@ OpDecorate %35 RelaxedPrecision %16 = OpLabel %a = OpVariable %_ptr_Function_v4float Function %b = OpVariable %_ptr_Function_v4float Function -%20 = OpLoad %11 %tex +%20 = OpLoad %12 %tex %19 = OpImageSampleImplicitLod %v4float %20 %float_0 OpStore %a %19 -%24 = OpLoad %11 %tex +%24 = OpLoad %12 %tex %23 = OpImageSampleProjImplicitLod %v4float %24 %26 OpStore %b %23 %27 = OpLoad %v4float %a diff --git a/tests/sksl/shared/Texture2D.asm.frag b/tests/sksl/shared/Texture2D.asm.frag index f555e1f0a4..1a28579ef2 100644 --- a/tests/sksl/shared/Texture2D.asm.frag +++ b/tests/sksl/shared/Texture2D.asm.frag @@ -30,10 +30,10 @@ OpDecorate %37 RelaxedPrecision %bool = OpTypeBool %_ptr_Input_bool = OpTypePointer Input %bool %sk_Clockwise = OpVariable %_ptr_Input_bool Input -%12 = OpTypeImage %float 2D 0 0 0 1 Unknown -%11 = OpTypeSampledImage %12 -%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 -%tex = OpVariable %_ptr_UniformConstant_11 UniformConstant +%11 = OpTypeImage %float 2D 0 0 0 1 Unknown +%12 = OpTypeSampledImage %11 +%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 +%tex = OpVariable %_ptr_UniformConstant_12 UniformConstant %void = OpTypeVoid %15 = OpTypeFunction %void %_ptr_Function_v4float = OpTypePointer Function %v4float @@ -46,10 +46,10 @@ OpDecorate %37 RelaxedPrecision %16 = OpLabel %a = OpVariable %_ptr_Function_v4float Function %b = OpVariable %_ptr_Function_v4float Function -%20 = OpLoad %11 %tex +%20 = OpLoad %12 %tex %19 = OpImageSampleImplicitLod %v4float %20 %23 OpStore %a %19 -%26 = OpLoad %11 %tex +%26 = OpLoad %12 %tex %25 = OpImageSampleProjImplicitLod %v4float %26 %28 OpStore %b %25 %29 = OpLoad %v4float %a diff --git a/tests/sksl/shared/TextureSharpen.asm.frag b/tests/sksl/shared/TextureSharpen.asm.frag index 078b30c1ad..636cb56c0d 100644 --- a/tests/sksl/shared/TextureSharpen.asm.frag +++ b/tests/sksl/shared/TextureSharpen.asm.frag @@ -1,7 +1,7 @@ ### Compilation failed: error: SPIR-V validation error: Operand 3 of TypeImage requires one of these capabilities: Sampled1D Image1D - %12 = OpTypeImage %float 1D 0 0 0 1 Unknown + %11 = OpTypeImage %float 1D 0 0 0 1 Unknown OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -39,14 +39,14 @@ OpDecorate %48 RelaxedPrecision %bool = OpTypeBool %_ptr_Input_bool = OpTypePointer Input %bool %sk_Clockwise = OpVariable %_ptr_Input_bool Input -%12 = OpTypeImage %float 1D 0 0 0 1 Unknown -%11 = OpTypeSampledImage %12 -%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11 -%one = OpVariable %_ptr_UniformConstant_11 UniformConstant -%16 = OpTypeImage %float 2D 0 0 0 1 Unknown -%15 = OpTypeSampledImage %16 -%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15 -%two = OpVariable %_ptr_UniformConstant_15 UniformConstant +%11 = OpTypeImage %float 1D 0 0 0 1 Unknown +%12 = OpTypeSampledImage %11 +%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12 +%one = OpVariable %_ptr_UniformConstant_12 UniformConstant +%15 = OpTypeImage %float 2D 0 0 0 1 Unknown +%16 = OpTypeSampledImage %15 +%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16 +%two = OpVariable %_ptr_UniformConstant_16 UniformConstant %void = OpTypeVoid %19 = OpTypeFunction %void %_ptr_Function_v4float = OpTypePointer Function %v4float @@ -62,16 +62,16 @@ OpDecorate %48 RelaxedPrecision %b = OpVariable %_ptr_Function_v4float Function %c = OpVariable %_ptr_Function_v4float Function %d = OpVariable %_ptr_Function_v4float Function -%24 = OpLoad %11 %one +%24 = OpLoad %12 %one %23 = OpImageSampleImplicitLod %v4float %24 %float_0 Bias %float_n0_474999994 OpStore %a %23 -%29 = OpLoad %15 %two +%29 = OpLoad %16 %two %28 = OpImageSampleImplicitLod %v4float %29 %31 Bias %float_n0_474999994 OpStore %b %28 -%34 = OpLoad %11 %one +%34 = OpLoad %12 %one %33 = OpImageSampleProjImplicitLod %v4float %34 %31 Bias %float_n0_474999994 OpStore %c %33 -%37 = OpLoad %15 %two +%37 = OpLoad %16 %two %36 = OpImageSampleProjImplicitLod %v4float %37 %39 Bias %float_n0_474999994 OpStore %d %36 %40 = OpLoad %v4float %a