Commit 18c6a784 by Ben Clayton

SpirvShader: Use struct for MemoryVisitor callback.

Instead of calling a function with two uint32_t parameters, pass a MemoryElement structure that has named and documented fields. This structure includes the Type field, which will be used by the debugger for knowing how to interpret the value. Bug: b/145351270 Change-Id: I21e86b9ba117bcde21150b408d8a7552729203e2 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38911 Presubmit-Ready: Ben Clayton <bclayton@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 0f4359ff
...@@ -769,10 +769,23 @@ namespace sw ...@@ -769,10 +769,23 @@ namespace sw
int VisitInterfaceInner(Type::ID id, Decorations d, const InterfaceVisitor& v) const; int VisitInterfaceInner(Type::ID id, Decorations d, const InterfaceVisitor& v) const;
using MemoryVisitor = std::function<void(uint32_t index, uint32_t offset)>; // MemoryElement describes a scalar element within a structure, and is
// used by the callback function of VisitMemoryObject().
struct MemoryElement
{
uint32_t index; // index of the scalar element
uint32_t offset; // offset (in bytes) from the base of the object
const Type& type; // element type
};
using MemoryVisitor = std::function<void(const MemoryElement&)>;
// VisitMemoryObject() walks a type tree in an explicitly laid out
// storage class, calling the MemoryVisitor for each scalar element
// within the
void VisitMemoryObject(Object::ID id, const MemoryVisitor& v) const; void VisitMemoryObject(Object::ID id, const MemoryVisitor& v) const;
// VisitMemoryObjectInner() is internally called by VisitMemoryObject()
void VisitMemoryObjectInner(Type::ID id, Decorations d, uint32_t &index, uint32_t offset, const MemoryVisitor& v) const; void VisitMemoryObjectInner(Type::ID id, Decorations d, uint32_t &index, uint32_t offset, const MemoryVisitor& v) const;
Object& CreateConstant(InsnIterator it); Object& CreateConstant(InsnIterator it);
......
...@@ -57,11 +57,11 @@ SpirvShader::EmitResult SpirvShader::EmitLoad(InsnIterator insn, EmitState *stat ...@@ -57,11 +57,11 @@ SpirvShader::EmitResult SpirvShader::EmitLoad(InsnIterator insn, EmitState *stat
auto &dst = state->createIntermediate(resultId, resultTy.sizeInComponents); auto &dst = state->createIntermediate(resultId, resultTy.sizeInComponents);
auto robustness = state->getOutOfBoundsBehavior(pointerTy.storageClass); auto robustness = state->getOutOfBoundsBehavior(pointerTy.storageClass);
VisitMemoryObject(pointerId, [&](uint32_t i, uint32_t offset) VisitMemoryObject(pointerId, [&](const MemoryElement& el)
{ {
auto p = ptr + offset; auto p = ptr + el.offset;
if (interleavedByLane) { p = InterleaveByLane(p); } // TODO: Interleave once, then add offset? if (interleavedByLane) { p = InterleaveByLane(p); } // TODO: Interleave once, then add offset?
dst.move(i, p.Load<SIMD::Float>(robustness, state->activeLaneMask(), atomic, memoryOrder)); dst.move(el.index, p.Load<SIMD::Float>(robustness, state->activeLaneMask(), atomic, memoryOrder));
}); });
return EmitResult::Continue; return EmitResult::Continue;
...@@ -101,22 +101,22 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta ...@@ -101,22 +101,22 @@ SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *sta
{ {
// Constant source data. // Constant source data.
const uint32_t *src = object.constantValue.get(); const uint32_t *src = object.constantValue.get();
VisitMemoryObject(pointerId, [&](uint32_t i, uint32_t offset) VisitMemoryObject(pointerId, [&](const MemoryElement& el)
{ {
auto p = ptr + offset; auto p = ptr + el.offset;
if (interleavedByLane) { p = InterleaveByLane(p); } if (interleavedByLane) { p = InterleaveByLane(p); }
p.Store(SIMD::Int(src[i]), robustness, mask, atomic, memoryOrder); p.Store(SIMD::Int(src[el.index]), robustness, mask, atomic, memoryOrder);
}); });
} }
else else
{ {
// Intermediate source data. // Intermediate source data.
auto &src = state->getIntermediate(objectId); auto &src = state->getIntermediate(objectId);
VisitMemoryObject(pointerId, [&](uint32_t i, uint32_t offset) VisitMemoryObject(pointerId, [&](const MemoryElement& el)
{ {
auto p = ptr + offset; auto p = ptr + el.offset;
if (interleavedByLane) { p = InterleaveByLane(p); } if (interleavedByLane) { p = InterleaveByLane(p); }
p.Store(src.Float(i), robustness, mask, atomic, memoryOrder); p.Store(src.Float(el.index), robustness, mask, atomic, memoryOrder);
}); });
} }
...@@ -239,12 +239,12 @@ SpirvShader::EmitResult SpirvShader::EmitVariable(InsnIterator insn, EmitState * ...@@ -239,12 +239,12 @@ SpirvShader::EmitResult SpirvShader::EmitVariable(InsnIterator insn, EmitState *
bool interleavedByLane = IsStorageInterleavedByLane(objectTy.storageClass); bool interleavedByLane = IsStorageInterleavedByLane(objectTy.storageClass);
auto ptr = GetPointerToData(resultId, 0, state); auto ptr = GetPointerToData(resultId, 0, state);
GenericValue initialValue(this, state, initializerId); GenericValue initialValue(this, state, initializerId);
VisitMemoryObject(resultId, [&](uint32_t i, uint32_t offset) VisitMemoryObject(resultId, [&](const MemoryElement& el)
{ {
auto p = ptr + offset; auto p = ptr + el.offset;
if (interleavedByLane) { p = InterleaveByLane(p); } if (interleavedByLane) { p = InterleaveByLane(p); }
auto robustness = OutOfBoundsBehavior::UndefinedBehavior; // Local variables are always within bounds. auto robustness = OutOfBoundsBehavior::UndefinedBehavior; // Local variables are always within bounds.
p.Store(initialValue.Float(i), robustness, state->activeLaneMask()); p.Store(initialValue.Float(el.index), robustness, state->activeLaneMask());
}); });
break; break;
} }
...@@ -271,13 +271,14 @@ SpirvShader::EmitResult SpirvShader::EmitCopyMemory(InsnIterator insn, EmitState ...@@ -271,13 +271,14 @@ SpirvShader::EmitResult SpirvShader::EmitCopyMemory(InsnIterator insn, EmitState
std::unordered_map<uint32_t, uint32_t> srcOffsets; std::unordered_map<uint32_t, uint32_t> srcOffsets;
VisitMemoryObject(srcPtrId, [&](uint32_t i, uint32_t srcOffset) { srcOffsets[i] = srcOffset; }); VisitMemoryObject(srcPtrId, [&](const MemoryElement& el) { srcOffsets[el.index] = el.offset; });
VisitMemoryObject(dstPtrId, [&](uint32_t i, uint32_t dstOffset) VisitMemoryObject(dstPtrId, [&](const MemoryElement& el)
{ {
auto it = srcOffsets.find(i); auto it = srcOffsets.find(el.index);
ASSERT(it != srcOffsets.end()); ASSERT(it != srcOffsets.end());
auto srcOffset = it->second; auto srcOffset = it->second;
auto dstOffset = el.offset;
auto dst = dstPtr + dstOffset; auto dst = dstPtr + dstOffset;
auto src = srcPtr + srcOffset; auto src = srcPtr + srcOffset;
...@@ -302,15 +303,8 @@ SpirvShader::EmitResult SpirvShader::EmitMemoryBarrier(InsnIterator insn, EmitSt ...@@ -302,15 +303,8 @@ SpirvShader::EmitResult SpirvShader::EmitMemoryBarrier(InsnIterator insn, EmitSt
return EmitResult::Continue; return EmitResult::Continue;
} }
void SpirvShader::VisitMemoryObjectInner(sw::SpirvShader::Type::ID id, sw::SpirvShader::Decorations d, uint32_t& index, uint32_t offset, const MemoryVisitor &f) const void SpirvShader::VisitMemoryObjectInner(sw::SpirvShader::Type::ID id, sw::SpirvShader::Decorations d, uint32_t& index, uint32_t offset, const MemoryVisitor& f) const
{ {
// Walk a type tree in an explicitly laid out storage class, calling
// a functor for each scalar element within the object.
// The functor's first parameter is the index of the scalar element;
// the second parameter is the offset (in bytes) from the base of the
// object.
ApplyDecorationsForId(&d, id); ApplyDecorationsForId(&d, id);
auto const &type = getType(id); auto const &type = getType(id);
...@@ -327,7 +321,8 @@ void SpirvShader::VisitMemoryObjectInner(sw::SpirvShader::Type::ID id, sw::Spirv ...@@ -327,7 +321,8 @@ void SpirvShader::VisitMemoryObjectInner(sw::SpirvShader::Type::ID id, sw::Spirv
break; break;
case spv::OpTypeInt: case spv::OpTypeInt:
case spv::OpTypeFloat: case spv::OpTypeFloat:
f(index++, offset); case spv::OpTypeRuntimeArray:
f(MemoryElement{index++, offset, type});
break; break;
case spv::OpTypeVector: case spv::OpTypeVector:
{ {
...@@ -371,7 +366,7 @@ void SpirvShader::VisitMemoryObjectInner(sw::SpirvShader::Type::ID id, sw::Spirv ...@@ -371,7 +366,7 @@ void SpirvShader::VisitMemoryObjectInner(sw::SpirvShader::Type::ID id, sw::Spirv
} }
} }
void SpirvShader::VisitMemoryObject(sw::SpirvShader::Object::ID id, const MemoryVisitor &f) const void SpirvShader::VisitMemoryObject(sw::SpirvShader::Object::ID id, const MemoryVisitor& f) const
{ {
auto typeId = getObject(id).type; auto typeId = getObject(id).type;
auto const & type = getType(typeId); auto const & type = getType(typeId);
...@@ -385,9 +380,11 @@ void SpirvShader::VisitMemoryObject(sw::SpirvShader::Object::ID id, const Memory ...@@ -385,9 +380,11 @@ void SpirvShader::VisitMemoryObject(sw::SpirvShader::Object::ID id, const Memory
else else
{ {
// Objects without explicit layout are tightly packed. // Objects without explicit layout are tightly packed.
for (auto i = 0u; i < getType(type.element).sizeInComponents; i++) auto &elType = getType(type.element);
for (auto index = 0u; index < elType.sizeInComponents; index++)
{ {
f(i, i * sizeof(float)); auto offset = static_cast<uint32_t>(index * sizeof(float));
f({index, offset, elType});
} }
} }
} }
......
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