Commit 5f7e9117 by Ben Clayton

SpirvRoutine: Use SIMD::Pointers for pointers map.

The split of intermediate + base pointer in two maps was ugly. This is also required for tracking bounds on pointers, required for robustness tests. Change-Id: I782aeee8caab43ce58ba948dcca97afa2e07482c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29273 Presubmit-Ready: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 7dd3889f
...@@ -1155,10 +1155,10 @@ namespace sw ...@@ -1155,10 +1155,10 @@ namespace sw
{ {
case Object::Kind::NonDivergentPointer: case Object::Kind::NonDivergentPointer:
case Object::Kind::InterfaceVariable: case Object::Kind::InterfaceVariable:
return SIMD::Pointer(routine->getPointer(id)); return routine->getPointer(id);
case Object::Kind::DivergentPointer: case Object::Kind::DivergentPointer:
return SIMD::Pointer(routine->getPointer(id), routine->getIntermediate(id).Int(0)); return routine->getPointer(id);
case Object::Kind::DescriptorSet: case Object::Kind::DescriptorSet:
{ {
...@@ -1167,10 +1167,12 @@ namespace sw ...@@ -1167,10 +1167,12 @@ namespace sw
ASSERT(d.Binding >= 0); ASSERT(d.Binding >= 0);
auto set = routine->getPointer(id); auto set = routine->getPointer(id);
ASSERT(set.uniform);
auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
int bindingOffset = static_cast<int>(setLayout->getBindingOffset(d.Binding, arrayIndex)); int bindingOffset = static_cast<int>(setLayout->getBindingOffset(d.Binding, arrayIndex));
Pointer<Byte> bufferInfo = Pointer<Byte>(set + bindingOffset); // VkDescriptorBufferInfo* Pointer<Byte> bufferInfo = Pointer<Byte>(set.base) + bindingOffset; // VkDescriptorBufferInfo*
Pointer<Byte> buffer = *Pointer<Pointer<Byte>>(bufferInfo + OFFSET(VkDescriptorBufferInfo, buffer)); // vk::Buffer* Pointer<Byte> buffer = *Pointer<Pointer<Byte>>(bufferInfo + OFFSET(VkDescriptorBufferInfo, buffer)); // vk::Buffer*
Pointer<Byte> data = *Pointer<Pointer<Byte>>(buffer + vk::Buffer::DataOffset); // void* Pointer<Byte> data = *Pointer<Pointer<Byte>>(buffer + vk::Buffer::DataOffset); // void*
Int offset = *Pointer<Int>(bufferInfo + OFFSET(VkDescriptorBufferInfo, offset)); Int offset = *Pointer<Int>(bufferInfo + OFFSET(VkDescriptorBufferInfo, offset));
...@@ -1278,9 +1280,13 @@ namespace sw ...@@ -1278,9 +1280,13 @@ namespace sw
ASSERT(d.HasArrayStride); ASSERT(d.HasArrayStride);
auto & obj = getObject(indexIds[i]); auto & obj = getObject(indexIds[i]);
if (obj.kind == Object::Kind::Constant) if (obj.kind == Object::Kind::Constant)
{
constantOffset += d.ArrayStride/sizeof(float) * GetConstantInt(indexIds[i]); constantOffset += d.ArrayStride/sizeof(float) * GetConstantInt(indexIds[i]);
}
else else
ptr.offset += SIMD::Int(d.ArrayStride / sizeof(float)) * routine->getIntermediate(indexIds[i]).Int(0); {
ptr.addOffset(SIMD::Int(d.ArrayStride / sizeof(float)) * routine->getIntermediate(indexIds[i]).Int(0));
}
typeId = type.element; typeId = type.element;
break; break;
} }
...@@ -1292,9 +1298,13 @@ namespace sw ...@@ -1292,9 +1298,13 @@ namespace sw
auto columnStride = (d.HasRowMajor && d.RowMajor) ? 1 : d.MatrixStride/sizeof(float); auto columnStride = (d.HasRowMajor && d.RowMajor) ? 1 : d.MatrixStride/sizeof(float);
auto & obj = getObject(indexIds[i]); auto & obj = getObject(indexIds[i]);
if (obj.kind == Object::Kind::Constant) if (obj.kind == Object::Kind::Constant)
{
constantOffset += columnStride * GetConstantInt(indexIds[i]); constantOffset += columnStride * GetConstantInt(indexIds[i]);
}
else else
ptr.offset += SIMD::Int(columnStride) * routine->getIntermediate(indexIds[i]).Int(0); {
ptr.addOffset(SIMD::Int(columnStride) * routine->getIntermediate(indexIds[i]).Int(0));
}
typeId = type.element; typeId = type.element;
break; break;
} }
...@@ -1303,9 +1313,13 @@ namespace sw ...@@ -1303,9 +1313,13 @@ namespace sw
auto elemStride = (d.InsideMatrix && d.HasRowMajor && d.RowMajor) ? d.MatrixStride / sizeof(float) : 1; auto elemStride = (d.InsideMatrix && d.HasRowMajor && d.RowMajor) ? d.MatrixStride / sizeof(float) : 1;
auto & obj = getObject(indexIds[i]); auto & obj = getObject(indexIds[i]);
if (obj.kind == Object::Kind::Constant) if (obj.kind == Object::Kind::Constant)
{
constantOffset += elemStride * GetConstantInt(indexIds[i]); constantOffset += elemStride * GetConstantInt(indexIds[i]);
}
else else
ptr.offset += SIMD::Int(elemStride) * routine->getIntermediate(indexIds[i]).Int(0); {
ptr.addOffset(SIMD::Int(elemStride) * routine->getIntermediate(indexIds[i]).Int(0));
}
typeId = type.element; typeId = type.element;
break; break;
} }
...@@ -1314,27 +1328,23 @@ namespace sw ...@@ -1314,27 +1328,23 @@ namespace sw
} }
} }
ptr.offset += SIMD::Int(constantOffset); if (constantOffset != 0)
{
ptr.addOffset(constantOffset);
}
return ptr; return ptr;
} }
SIMD::Int SpirvShader::WalkAccessChain(Object::ID baseId, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const SIMD::Pointer SpirvShader::WalkAccessChain(Object::ID baseId, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const
{ {
// TODO: avoid doing per-lane work in some cases if we can? // TODO: avoid doing per-lane work in some cases if we can?
// Produce a *component* offset into location-oriented memory
int constantOffset = 0;
SIMD::Int dynamicOffset = SIMD::Int(0);
auto &baseObject = getObject(baseId); auto &baseObject = getObject(baseId);
Type::ID typeId = getType(baseObject.type).element; Type::ID typeId = getType(baseObject.type).element;
// The <base> operand is a divergent pointer itself. auto ptr = routine->getPointer(baseId);
// Start with its offset and build from there.
if (baseObject.kind == Object::Kind::DivergentPointer) int constantOffset = 0;
{
dynamicOffset += routine->getIntermediate(baseId).Int(0);
}
for (auto i = 0u; i < numIndexes; i++) for (auto i = 0u; i < numIndexes; i++)
{ {
...@@ -1363,9 +1373,13 @@ namespace sw ...@@ -1363,9 +1373,13 @@ namespace sw
auto stride = getType(type.element).sizeInComponents; auto stride = getType(type.element).sizeInComponents;
auto & obj = getObject(indexIds[i]); auto & obj = getObject(indexIds[i]);
if (obj.kind == Object::Kind::Constant) if (obj.kind == Object::Kind::Constant)
{
constantOffset += stride * GetConstantInt(indexIds[i]); constantOffset += stride * GetConstantInt(indexIds[i]);
}
else else
dynamicOffset += SIMD::Int(stride) * routine->getIntermediate(indexIds[i]).Int(0); {
ptr.addOffset(SIMD::Int(stride) * routine->getIntermediate(indexIds[i]).Int(0));
}
typeId = type.element; typeId = type.element;
break; break;
} }
...@@ -1375,7 +1389,11 @@ namespace sw ...@@ -1375,7 +1389,11 @@ namespace sw
} }
} }
return dynamicOffset + SIMD::Int(constantOffset); if (constantOffset != 0)
{
ptr.addOffset(SIMD::Int(constantOffset));
}
return ptr;
} }
uint32_t SpirvShader::WalkLiteralAccessChain(Type::ID typeId, uint32_t numIndexes, uint32_t const *indexes) const uint32_t SpirvShader::WalkLiteralAccessChain(Type::ID typeId, uint32_t numIndexes, uint32_t const *indexes) const
...@@ -2196,7 +2214,8 @@ namespace sw ...@@ -2196,7 +2214,8 @@ namespace sw
case spv::StorageClassPrivate: case spv::StorageClassPrivate:
case spv::StorageClassFunction: case spv::StorageClassFunction:
{ {
routine->createPointer(resultId, &routine->getVariable(resultId)[0]); auto base = &routine->getVariable(resultId)[0];
routine->createPointer(resultId, SIMD::Pointer(base));
break; break;
} }
case spv::StorageClassInput: case spv::StorageClassInput:
...@@ -2211,7 +2230,8 @@ namespace sw ...@@ -2211,7 +2230,8 @@ namespace sw
dst[offset++] = routine->inputs[scalarSlot]; dst[offset++] = routine->inputs[scalarSlot];
}); });
} }
routine->createPointer(resultId, &routine->getVariable(resultId)[0]); auto base = &routine->getVariable(resultId)[0];
routine->createPointer(resultId, SIMD::Pointer(base));
break; break;
} }
case spv::StorageClassUniformConstant: case spv::StorageClassUniformConstant:
...@@ -2224,8 +2244,8 @@ namespace sw ...@@ -2224,8 +2244,8 @@ namespace sw
auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex); size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex);
Pointer<Byte> set = routine->descriptorSets[d.DescriptorSet]; // DescriptorSet* Pointer<Byte> set = routine->descriptorSets[d.DescriptorSet]; // DescriptorSet*
Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset); // SampledImageDescriptor* Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset); // vk::SampledImageDescriptor*
routine->createPointer(resultId, binding); routine->createPointer(resultId, SIMD::Pointer(binding));
break; break;
} }
case spv::StorageClassUniform: case spv::StorageClassUniform:
...@@ -2234,12 +2254,12 @@ namespace sw ...@@ -2234,12 +2254,12 @@ namespace sw
const auto &d = descriptorDecorations.at(resultId); const auto &d = descriptorDecorations.at(resultId);
ASSERT(d.DescriptorSet >= 0 && d.DescriptorSet < vk::MAX_BOUND_DESCRIPTOR_SETS); ASSERT(d.DescriptorSet >= 0 && d.DescriptorSet < vk::MAX_BOUND_DESCRIPTOR_SETS);
routine->createPointer(resultId, routine->descriptorSets[d.DescriptorSet]); routine->createPointer(resultId, SIMD::Pointer(routine->descriptorSets[d.DescriptorSet]));
break; break;
} }
case spv::StorageClassPushConstant: case spv::StorageClassPushConstant:
{ {
routine->createPointer(resultId, routine->pushConstants); routine->createPointer(resultId, SIMD::Pointer(routine->pushConstants));
break; break;
} }
default: default:
...@@ -2469,14 +2489,12 @@ namespace sw ...@@ -2469,14 +2489,12 @@ namespace sw
type.storageClass == spv::StorageClassStorageBuffer) type.storageClass == spv::StorageClassStorageBuffer)
{ {
auto ptr = WalkExplicitLayoutAccessChain(baseId, numIndexes, indexes, routine); auto ptr = WalkExplicitLayoutAccessChain(baseId, numIndexes, indexes, routine);
routine->createPointer(resultId, ptr.base); routine->createPointer(resultId, ptr);
routine->createIntermediate(resultId, type.sizeInComponents).move(0, ptr.offset);
} }
else else
{ {
auto offset = WalkAccessChain(baseId, numIndexes, indexes, routine); auto ptr = WalkAccessChain(baseId, numIndexes, indexes, routine);
routine->createPointer(resultId, routine->getPointer(baseId)); routine->createPointer(resultId, ptr);
routine->createIntermediate(resultId, type.sizeInComponents).move(0, offset);
} }
return EmitResult::Continue; return EmitResult::Continue;
...@@ -4340,7 +4358,7 @@ namespace sw ...@@ -4340,7 +4358,7 @@ namespace sw
in[1] = coordinate.Float(1); in[1] = coordinate.Float(1);
Array<SIMD::Float> out(4); Array<SIMD::Float> out(4);
Call<ImageSampler>(samplerFunc, sampledImage, &in[0], &out[0]); Call<ImageSampler>(samplerFunc, sampledImage.base, &in[0], &out[0]);
for (int i = 0; i < 4; i++) { result.move(i, out[i]); } for (int i = 0; i < 4; i++) { result.move(i, out[i]); }
...@@ -4717,12 +4735,10 @@ namespace sw ...@@ -4717,12 +4735,10 @@ namespace sw
Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset); Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset);
Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr)); Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr));
state->routine->createPointer(resultId, imageBase); // TODO: texelOffset is in bytes - remove shift when SIMD::Pointer is offset by bytes.
// TODO: texelOffset is in bytes. get rid of shift once Ben's changes for DivergentPointer land
SIMD::Int texelOffset = GetTexelOffset(coordinate, imageType, binding, sizeof(uint32_t)) >> 2; SIMD::Int texelOffset = GetTexelOffset(coordinate, imageType, binding, sizeof(uint32_t)) >> 2;
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
dst.move(0, texelOffset); state->routine->createPointer(resultId, SIMD::Pointer(imageBase, texelOffset));
return EmitResult::Continue; return EmitResult::Continue;
} }
...@@ -4736,45 +4752,44 @@ namespace sw ...@@ -4736,45 +4752,44 @@ namespace sw
auto memoryOrder = MemoryOrder(memorySemantics); auto memoryOrder = MemoryOrder(memorySemantics);
auto value = GenericValue(this, state->routine, insn.word(6)); auto value = GenericValue(this, state->routine, insn.word(6));
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
auto ptr = Pointer<UInt>(state->routine->getPointer(insn.word(3))); auto ptr = state->routine->getPointer(insn.word(3));
auto offsets = state->routine->getIntermediate(insn.word(3)).UInt(0);
SIMD::UInt x; SIMD::UInt x;
for (int j = 0; j < SIMD::Width; j++) for (int j = 0; j < SIMD::Width; j++)
{ {
If(Extract(state->activeLaneMask(), j) != 0) If(Extract(state->activeLaneMask(), j) != 0)
{ {
auto offset = Extract(offsets, j); auto offset = Extract(ptr.offset, j);
auto laneValue = Extract(value.UInt(0), j); auto laneValue = Extract(value.UInt(0), j);
UInt v; UInt v;
switch (insn.opcode()) switch (insn.opcode())
{ {
case spv::OpAtomicIAdd: case spv::OpAtomicIAdd:
v = AddAtomic(&ptr[offset], laneValue, memoryOrder); v = AddAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
case spv::OpAtomicAnd: case spv::OpAtomicAnd:
v = AndAtomic(&ptr[offset], laneValue, memoryOrder); v = AndAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
case spv::OpAtomicOr: case spv::OpAtomicOr:
v = OrAtomic(&ptr[offset], laneValue, memoryOrder); v = OrAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
case spv::OpAtomicXor: case spv::OpAtomicXor:
v = XorAtomic(&ptr[offset], laneValue, memoryOrder); v = XorAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
case spv::OpAtomicSMin: case spv::OpAtomicSMin:
v = As<UInt>(MinAtomic(As<Pointer<Int>>(&ptr[offset]), As<Int>(laneValue), memoryOrder)); v = As<UInt>(MinAtomic(Pointer<Int>(&ptr.base[offset]), As<Int>(laneValue), memoryOrder));
break; break;
case spv::OpAtomicSMax: case spv::OpAtomicSMax:
v = As<UInt>(MaxAtomic(As<Pointer<Int>>(&ptr[offset]), As<Int>(laneValue), memoryOrder)); v = As<UInt>(MaxAtomic(Pointer<Int>(&ptr.base[offset]), As<Int>(laneValue), memoryOrder));
break; break;
case spv::OpAtomicUMin: case spv::OpAtomicUMin:
v = MinAtomic(&ptr[offset], laneValue, memoryOrder); v = MinAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
case spv::OpAtomicUMax: case spv::OpAtomicUMax:
v = MaxAtomic(&ptr[offset], laneValue, memoryOrder); v = MaxAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
case spv::OpAtomicExchange: case spv::OpAtomicExchange:
v = ExchangeAtomic(&ptr[offset], laneValue, memoryOrder); v = ExchangeAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
break; break;
default: default:
UNIMPLEMENTED("Atomic op", OpcodeName(insn.opcode()).c_str()); UNIMPLEMENTED("Atomic op", OpcodeName(insn.opcode()).c_str());
...@@ -4802,18 +4817,17 @@ namespace sw ...@@ -4802,18 +4817,17 @@ namespace sw
auto value = GenericValue(this, state->routine, insn.word(7)); auto value = GenericValue(this, state->routine, insn.word(7));
auto comparator = GenericValue(this, state->routine, insn.word(8)); auto comparator = GenericValue(this, state->routine, insn.word(8));
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
auto ptr = Pointer<UInt>(state->routine->getPointer(insn.word(3))); auto ptr = state->routine->getPointer(insn.word(3));
auto offsets = state->routine->getIntermediate(insn.word(3)).UInt(0);
SIMD::UInt x; SIMD::UInt x;
for (int j = 0; j < SIMD::Width; j++) for (int j = 0; j < SIMD::Width; j++)
{ {
If(Extract(state->activeLaneMask(), j) != 0) If(Extract(state->activeLaneMask(), j) != 0)
{ {
auto offset = Extract(offsets, j); auto offset = Extract(ptr.offset, j);
auto laneValue = Extract(value.UInt(0), j); auto laneValue = Extract(value.UInt(0), j);
auto laneComparator = Extract(comparator.UInt(0), j); auto laneComparator = Extract(comparator.UInt(0), j);
UInt v = CompareExchangeAtomic(&ptr[offset], laneValue, laneComparator, memoryOrderEqual, memoryOrderUnequal); UInt v = CompareExchangeAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, laneComparator, memoryOrderEqual, memoryOrderUnequal);
x = Insert(x, v, j); x = Insert(x, v, j);
} }
} }
......
...@@ -68,11 +68,13 @@ namespace sw ...@@ -68,11 +68,13 @@ namespace sw
Pointer(rr::Pointer<Byte> base) : base(base), offset(0), uniform(true) {} Pointer(rr::Pointer<Byte> base) : base(base), offset(0), uniform(true) {}
Pointer(rr::Pointer<Byte> base, SIMD::Int offset) : base(base), offset(offset), uniform(false) {} Pointer(rr::Pointer<Byte> base, SIMD::Int offset) : base(base), offset(offset), uniform(false) {}
inline void addOffset(Int delta) { offset += delta; uniform = false; }
// Base address for the pointer, common across all lanes. // Base address for the pointer, common across all lanes.
rr::Pointer<rr::Float> base; rr::Pointer<rr::Float> base;
// Per lane offsets from base. // Per lane offsets from base.
// If uniform is false, all offsets are considered zero. // If uniform is true, all offsets are considered zero.
Int offset; Int offset;
// True if all offsets are zero. // True if all offsets are zero.
...@@ -274,8 +276,7 @@ namespace sw ...@@ -274,8 +276,7 @@ namespace sw
Intermediate, Intermediate,
// DivergentPointer formed from a base pointer and per-lane offset. // DivergentPointer formed from a base pointer and per-lane offset.
// Base pointer held by SpirvRoutine::pointers // Pointer held by SpirvRoutine::pointers
// Per-lane offset held by SpirvRoutine::intermediates.
DivergentPointer, DivergentPointer,
// Pointer with uniform address across all lanes. // Pointer with uniform address across all lanes.
...@@ -287,6 +288,7 @@ namespace sw ...@@ -287,6 +288,7 @@ namespace sw
DescriptorSet, DescriptorSet,
// Pointer to an image/sampler descriptor. // Pointer to an image/sampler descriptor.
// Pointer held by SpirvRoutine::pointers.
SampledImage, SampledImage,
}; };
...@@ -621,7 +623,7 @@ namespace sw ...@@ -621,7 +623,7 @@ namespace sw
SIMD::Pointer GetPointerToData(Object::ID id, int arrayIndex, SpirvRoutine *routine) const; SIMD::Pointer GetPointerToData(Object::ID id, int arrayIndex, SpirvRoutine *routine) const;
SIMD::Pointer WalkExplicitLayoutAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const; SIMD::Pointer WalkExplicitLayoutAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const;
SIMD::Int WalkAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const; SIMD::Pointer WalkAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const;
uint32_t WalkLiteralAccessChain(Type::ID id, uint32_t numIndexes, uint32_t const *indexes) const; uint32_t WalkLiteralAccessChain(Type::ID id, uint32_t numIndexes, uint32_t const *indexes) const;
// EmitState holds control-flow state for the emit() pass. // EmitState holds control-flow state for the emit() pass.
...@@ -772,7 +774,7 @@ namespace sw ...@@ -772,7 +774,7 @@ namespace sw
std::unordered_map<SpirvShader::Object::ID, Intermediate> intermediates; std::unordered_map<SpirvShader::Object::ID, Intermediate> intermediates;
std::unordered_map<SpirvShader::Object::ID, Pointer<Byte> > pointers; std::unordered_map<SpirvShader::Object::ID, SIMD::Pointer> pointers;
Variable inputs = Variable{MAX_INTERFACE_COMPONENTS}; Variable inputs = Variable{MAX_INTERFACE_COMPONENTS};
Variable outputs = Variable{MAX_INTERFACE_COMPONENTS}; Variable outputs = Variable{MAX_INTERFACE_COMPONENTS};
...@@ -788,25 +790,12 @@ namespace sw ...@@ -788,25 +790,12 @@ namespace sw
ASSERT_MSG(added, "Variable %d created twice", id.value()); ASSERT_MSG(added, "Variable %d created twice", id.value());
} }
template <typename T> void createPointer(SpirvShader::Object::ID id, SIMD::Pointer ptr)
void createPointer(SpirvShader::Object::ID id, Pointer<T> ptrBase)
{ {
bool added = pointers.emplace(id, ptrBase).second; bool added = pointers.emplace(id, ptr).second;
ASSERT_MSG(added, "Pointer %d created twice", id.value()); ASSERT_MSG(added, "Pointer %d created twice", id.value());
} }
template <typename T>
void createPointer(SpirvShader::Object::ID id, RValue<Pointer<T>> ptrBase)
{
createPointer(id, Pointer<T>(ptrBase));
}
template <typename T>
void createPointer(SpirvShader::Object::ID id, Reference<Pointer<T>> ptrBase)
{
createPointer(id, Pointer<T>(ptrBase));
}
Intermediate& createIntermediate(SpirvShader::Object::ID id, uint32_t size) Intermediate& createIntermediate(SpirvShader::Object::ID id, uint32_t size)
{ {
auto it = intermediates.emplace(std::piecewise_construct, auto it = intermediates.emplace(std::piecewise_construct,
...@@ -830,7 +819,7 @@ namespace sw ...@@ -830,7 +819,7 @@ namespace sw
return it->second; return it->second;
} }
Pointer<Byte>& getPointer(SpirvShader::Object::ID id) SIMD::Pointer const& getPointer(SpirvShader::Object::ID id) const
{ {
auto it = pointers.find(id); auto it = pointers.find(id);
ASSERT_MSG(it != pointers.end(), "Unknown pointer %d", id.value()); ASSERT_MSG(it != pointers.end(), "Unknown pointer %d", id.value());
......
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