Commit b5a4546c by Ben Clayton

SpirvShader: Implement OpCopyMemory

Tests: dEQP-VK.spirv_assembly.instruction.compute.memory_access.* Change-Id: I5281798468651c67ec038bdd8688f99c67654cb1 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30215Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 139acaac
......@@ -857,6 +857,7 @@ namespace sw
case spv::OpStore:
case spv::OpAtomicStore:
case spv::OpImageWrite:
case spv::OpCopyMemory:
// Don't need to do anything during analysis pass
break;
......@@ -2432,6 +2433,9 @@ namespace sw
case spv::OpImage:
return EmitSampledImageCombineOrSplit(insn, state);
case spv::OpCopyMemory:
return EmitCopyMemory(insn, state);
default:
UNIMPLEMENTED("%s", OpcodeName(opcode).c_str());
break;
......@@ -5248,6 +5252,38 @@ namespace sw
return EmitResult::Continue;
}
SpirvShader::EmitResult SpirvShader::EmitCopyMemory(InsnIterator insn, EmitState *state) const
{
Object::ID dstPtrId = insn.word(1);
Object::ID srcPtrId = insn.word(2);
auto &dstPtrTy = getType(getObject(dstPtrId).type);
auto &srcPtrTy = getType(getObject(srcPtrId).type);
ASSERT(dstPtrTy.element == srcPtrTy.element);
bool dstInterleavedByLane = IsStorageInterleavedByLane(dstPtrTy.storageClass);
bool srcInterleavedByLane = IsStorageInterleavedByLane(srcPtrTy.storageClass);
auto dstPtr = state->routine->getPointer(dstPtrId);
auto srcPtr = state->routine->getPointer(srcPtrId);
std::unordered_map<uint32_t, uint32_t> srcOffsets;
VisitMemoryObject(srcPtrId, [&](uint32_t i, uint32_t srcOffset) { srcOffsets[i] = srcOffset; });
VisitMemoryObject(dstPtrId, [&](uint32_t i, uint32_t dstOffset)
{
auto it = srcOffsets.find(i);
ASSERT(it != srcOffsets.end());
auto srcOffset = it->second;
auto dst = dstPtr + dstOffset;
auto src = srcPtr + srcOffset;
if (dstInterleavedByLane) { dst = interleaveByLane(dst); }
if (srcInterleavedByLane) { src = interleaveByLane(src); }
SIMD::Store(dst, SIMD::Load<SIMD::Float>(src, state->activeLaneMask()), state->activeLaneMask());
});
return EmitResult::Continue;
}
void SpirvShader::emitEpilog(SpirvRoutine *routine) const
{
for (auto insn : *this)
......
......@@ -905,6 +905,7 @@ namespace sw
EmitResult EmitAtomicOp(InsnIterator insn, EmitState *state) const;
EmitResult EmitAtomicCompareExchange(InsnIterator insn, EmitState *state) const;
EmitResult EmitSampledImageCombineOrSplit(InsnIterator insn, EmitState *state) const;
EmitResult EmitCopyMemory(InsnIterator insn, EmitState *state) const;
SIMD::Pointer GetTexelAddress(SpirvRoutine const * routine, SIMD::Pointer base, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment