case spv::OpCompositeInsert:
case spv::OpCompositeExtract:
case spv::OpVectorShuffle:
+ case spv::OpVectorTimesScalar:
+ case spv::OpVectorExtractDynamic:
+ case spv::OpVectorInsertDynamic:
case spv::OpNot: // Unary ops
case spv::OpSNegate:
case spv::OpFNegate:
case spv::OpIsNan:
case spv::OpAny:
case spv::OpAll:
- case spv::OpVectorTimesScalar:
// Instructions that yield an intermediate value
{
Type::ID typeId = insn.word(1);
EmitVectorShuffle(insn, routine);
break;
+ case spv::OpVectorExtractDynamic:
+ EmitVectorExtractDynamic(insn, routine);
+ break;
+
+ case spv::OpVectorInsertDynamic:
+ EmitVectorInsertDynamic(insn, routine);
+ break;
+
case spv::OpVectorTimesScalar:
EmitVectorTimesScalar(insn, routine);
break;
}
}
+ void SpirvShader::EmitVectorExtractDynamic(sw::SpirvShader::InsnIterator insn, sw::SpirvRoutine *routine) const
+ {
+ auto &type = getType(insn.word(1));
+ auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
+ auto &srcType = getType(getObject(insn.word(3)).type);
+
+ GenericValue src(this, routine, insn.word(3));
+ GenericValue index(this, routine, insn.word(4));
+
+ SIMD::UInt v = SIMD::UInt(0);
+
+ for (auto i = 0u; i < srcType.sizeInComponents; i++)
+ {
+ v |= CmpEQ(index.UInt(0), SIMD::UInt(i)) & src.UInt(i);
+ }
+
+ dst.emplace(0, v);
+ }
+
+ void SpirvShader::EmitVectorInsertDynamic(sw::SpirvShader::InsnIterator insn, sw::SpirvRoutine *routine) const
+ {
+ auto &type = getType(insn.word(1));
+ auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
+
+ GenericValue src(this, routine, insn.word(3));
+ GenericValue component(this, routine, insn.word(4));
+ GenericValue index(this, routine, insn.word(5));
+
+ for (auto i = 0u; i < type.sizeInComponents; i++)
+ {
+ SIMD::UInt mask = CmpEQ(SIMD::UInt(i), index.UInt(0));
+ dst.emplace(i, (src.UInt(i) & ~mask) | (component.UInt(0) & mask));
+ }
+ }
+
void SpirvShader::EmitVectorTimesScalar(InsnIterator insn, SpirvRoutine *routine) const
{
auto &type = getType(insn.word(1));
void EmitCompositeExtract(InsnIterator insn, SpirvRoutine *routine) const;
void EmitVectorShuffle(InsnIterator insn, SpirvRoutine *routine) const;
void EmitVectorTimesScalar(InsnIterator insn, SpirvRoutine *routine) const;
+ void EmitVectorExtractDynamic(InsnIterator insn, SpirvRoutine *routine) const;
+ void EmitVectorInsertDynamic(InsnIterator insn, SpirvRoutine *routine) const;
void EmitUnaryOp(InsnIterator insn, SpirvRoutine *routine) const;
void EmitBinaryOp(InsnIterator insn, SpirvRoutine *routine) const;
void EmitDot(InsnIterator insn, SpirvRoutine *routine) const;