Commit e8bfba47 by Ben Clayton

Move pointers and intermediates from SpirvRoutine to SpirvShader::EmitState.

These are only used during SpirvShader::emit(), and will require separate namespacing when functions are inlined. Bug: b/133213304 Change-Id: I8cf6cd76af35984f0f24109665a991492158bf16 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/33351 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent 59cd59b9
...@@ -1524,14 +1524,15 @@ namespace sw ...@@ -1524,14 +1524,15 @@ namespace sw
} }
} }
SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, SpirvRoutine *routine) const SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, EmitState const *state) const
{ {
auto routine = state->routine;
auto &object = getObject(id); auto &object = getObject(id);
switch (object.kind) switch (object.kind)
{ {
case Object::Kind::Pointer: case Object::Kind::Pointer:
case Object::Kind::InterfaceVariable: case Object::Kind::InterfaceVariable:
return routine->getPointer(id); return state->getPointer(id);
case Object::Kind::DescriptorSet: case Object::Kind::DescriptorSet:
{ {
...@@ -1539,7 +1540,7 @@ namespace sw ...@@ -1539,7 +1540,7 @@ namespace sw
ASSERT(d.DescriptorSet >= 0 && d.DescriptorSet < vk::MAX_BOUND_DESCRIPTOR_SETS); ASSERT(d.DescriptorSet >= 0 && d.DescriptorSet < vk::MAX_BOUND_DESCRIPTOR_SETS);
ASSERT(d.Binding >= 0); ASSERT(d.Binding >= 0);
auto set = routine->getPointer(id); auto set = state->getPointer(id);
auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
ASSERT_MSG(setLayout->hasBinding(d.Binding), "Descriptor set %d does not contain binding %d", int(d.DescriptorSet), int(d.Binding)); ASSERT_MSG(setLayout->hasBinding(d.Binding), "Descriptor set %d does not contain binding %d", int(d.DescriptorSet), int(d.Binding));
...@@ -1611,7 +1612,7 @@ namespace sw ...@@ -1611,7 +1612,7 @@ namespace sw
} }
} }
SIMD::Pointer SpirvShader::WalkExplicitLayoutAccessChain(Object::ID baseId, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const SIMD::Pointer SpirvShader::WalkExplicitLayoutAccessChain(Object::ID baseId, uint32_t numIndexes, uint32_t const *indexIds, EmitState const *state) const
{ {
// Produce a offset into external memory in sizeof(float) units // Produce a offset into external memory in sizeof(float) units
...@@ -1635,7 +1636,7 @@ namespace sw ...@@ -1635,7 +1636,7 @@ namespace sw
} }
} }
auto ptr = GetPointerToData(baseId, arrayIndex, routine); auto ptr = GetPointerToData(baseId, arrayIndex, state);
int constantOffset = 0; int constantOffset = 0;
...@@ -1667,7 +1668,7 @@ namespace sw ...@@ -1667,7 +1668,7 @@ namespace sw
} }
else else
{ {
ptr += SIMD::Int(d.ArrayStride) * routine->getIntermediate(indexIds[i]).Int(0); ptr += SIMD::Int(d.ArrayStride) * state->getIntermediate(indexIds[i]).Int(0);
} }
typeId = type.element; typeId = type.element;
break; break;
...@@ -1685,7 +1686,7 @@ namespace sw ...@@ -1685,7 +1686,7 @@ namespace sw
} }
else else
{ {
ptr += SIMD::Int(columnStride) * routine->getIntermediate(indexIds[i]).Int(0); ptr += SIMD::Int(columnStride) * state->getIntermediate(indexIds[i]).Int(0);
} }
typeId = type.element; typeId = type.element;
break; break;
...@@ -1700,7 +1701,7 @@ namespace sw ...@@ -1700,7 +1701,7 @@ namespace sw
} }
else else
{ {
ptr += SIMD::Int(elemStride) * routine->getIntermediate(indexIds[i]).Int(0); ptr += SIMD::Int(elemStride) * state->getIntermediate(indexIds[i]).Int(0);
} }
typeId = type.element; typeId = type.element;
break; break;
...@@ -1714,14 +1715,14 @@ namespace sw ...@@ -1714,14 +1715,14 @@ namespace sw
return ptr; return ptr;
} }
SIMD::Pointer 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, EmitState const *state) 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?
auto routine = state->routine;
auto &baseObject = getObject(baseId); auto &baseObject = getObject(baseId);
Type::ID typeId = getType(baseObject.type).element; Type::ID typeId = getType(baseObject.type).element;
auto ptr = routine->getPointer(baseId); auto ptr = state->getPointer(baseId);
int constantOffset = 0; int constantOffset = 0;
...@@ -1775,7 +1776,7 @@ namespace sw ...@@ -1775,7 +1776,7 @@ namespace sw
} }
else else
{ {
ptr += SIMD::Int(stride) * routine->getIntermediate(indexIds[i]).Int(0); ptr += SIMD::Int(stride) * state->getIntermediate(indexIds[i]).Int(0);
} }
} }
typeId = type.element; typeId = type.element;
...@@ -2698,7 +2699,7 @@ namespace sw ...@@ -2698,7 +2699,7 @@ namespace sw
auto base = &routine->getVariable(resultId)[0]; auto base = &routine->getVariable(resultId)[0];
auto elementTy = getType(objectTy.element); auto elementTy = getType(objectTy.element);
auto size = elementTy.sizeInComponents * static_cast<uint32_t>(sizeof(float)) * SIMD::Width; auto size = elementTy.sizeInComponents * static_cast<uint32_t>(sizeof(float)) * SIMD::Width;
routine->createPointer(resultId, SIMD::Pointer(base, size)); state->createPointer(resultId, SIMD::Pointer(base, size));
break; break;
} }
case spv::StorageClassWorkgroup: case spv::StorageClassWorkgroup:
...@@ -2706,7 +2707,7 @@ namespace sw ...@@ -2706,7 +2707,7 @@ namespace sw
ASSERT(objectTy.opcode() == spv::OpTypePointer); ASSERT(objectTy.opcode() == spv::OpTypePointer);
auto base = &routine->workgroupMemory[0]; auto base = &routine->workgroupMemory[0];
auto size = workgroupMemory.size(); auto size = workgroupMemory.size();
routine->createPointer(resultId, SIMD::Pointer(base, size, workgroupMemory.offsetOf(resultId))); state->createPointer(resultId, SIMD::Pointer(base, size, workgroupMemory.offsetOf(resultId)));
break; break;
} }
case spv::StorageClassInput: case spv::StorageClassInput:
...@@ -2725,7 +2726,7 @@ namespace sw ...@@ -2725,7 +2726,7 @@ namespace sw
auto base = &routine->getVariable(resultId)[0]; auto base = &routine->getVariable(resultId)[0];
auto elementTy = getType(objectTy.element); auto elementTy = getType(objectTy.element);
auto size = elementTy.sizeInComponents * static_cast<uint32_t>(sizeof(float)) * SIMD::Width; auto size = elementTy.sizeInComponents * static_cast<uint32_t>(sizeof(float)) * SIMD::Width;
routine->createPointer(resultId, SIMD::Pointer(base, size)); state->createPointer(resultId, SIMD::Pointer(base, size));
break; break;
} }
case spv::StorageClassUniformConstant: case spv::StorageClassUniformConstant:
...@@ -2742,7 +2743,7 @@ namespace sw ...@@ -2742,7 +2743,7 @@ namespace sw
Pointer<Byte> set = routine->descriptorSets[d.DescriptorSet]; // DescriptorSet* Pointer<Byte> set = routine->descriptorSets[d.DescriptorSet]; // DescriptorSet*
Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset); // vk::SampledImageDescriptor* Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset); // vk::SampledImageDescriptor*
auto size = 0; // Not required as this pointer is not directly used by SIMD::Read or SIMD::Write. auto size = 0; // Not required as this pointer is not directly used by SIMD::Read or SIMD::Write.
routine->createPointer(resultId, SIMD::Pointer(binding, size)); state->createPointer(resultId, SIMD::Pointer(binding, size));
} }
else else
{ {
...@@ -2758,12 +2759,12 @@ namespace sw ...@@ -2758,12 +2759,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);
auto size = 0; // Not required as this pointer is not directly used by SIMD::Read or SIMD::Write. auto size = 0; // Not required as this pointer is not directly used by SIMD::Read or SIMD::Write.
routine->createPointer(resultId, SIMD::Pointer(routine->descriptorSets[d.DescriptorSet], size)); state->createPointer(resultId, SIMD::Pointer(routine->descriptorSets[d.DescriptorSet], size));
break; break;
} }
case spv::StorageClassPushConstant: case spv::StorageClassPushConstant:
{ {
routine->createPointer(resultId, SIMD::Pointer(routine->pushConstants, vk::MAX_PUSH_CONSTANT_SIZE)); state->createPointer(resultId, SIMD::Pointer(routine->pushConstants, vk::MAX_PUSH_CONSTANT_SIZE));
break; break;
} }
default: default:
...@@ -2785,8 +2786,8 @@ namespace sw ...@@ -2785,8 +2786,8 @@ namespace sw
case spv::StorageClassFunction: case spv::StorageClassFunction:
{ {
bool interleavedByLane = IsStorageInterleavedByLane(objectTy.storageClass); bool interleavedByLane = IsStorageInterleavedByLane(objectTy.storageClass);
auto ptr = GetPointerToData(resultId, 0, routine); auto ptr = GetPointerToData(resultId, 0, state);
GenericValue initialValue(this, routine, initializerId); GenericValue initialValue(this, state, initializerId);
VisitMemoryObject(resultId, [&](uint32_t i, uint32_t offset) VisitMemoryObject(resultId, [&](uint32_t i, uint32_t offset)
{ {
auto p = ptr + offset; auto p = ptr + offset;
...@@ -2805,7 +2806,6 @@ namespace sw ...@@ -2805,7 +2806,6 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitLoad(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitLoad(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
bool atomic = (insn.opcode() == spv::OpAtomicLoad); bool atomic = (insn.opcode() == spv::OpAtomicLoad);
Object::ID resultId = insn.word(2); Object::ID resultId = insn.word(2);
Object::ID pointerId = insn.word(3); Object::ID pointerId = insn.word(3);
...@@ -2822,8 +2822,8 @@ namespace sw ...@@ -2822,8 +2822,8 @@ namespace sw
if(pointerTy.storageClass == spv::StorageClassUniformConstant) if(pointerTy.storageClass == spv::StorageClassUniformConstant)
{ {
// Just propagate the pointer. // Just propagate the pointer.
auto &ptr = routine->getPointer(pointerId); auto &ptr = state->getPointer(pointerId);
routine->createPointer(resultId, ptr); state->createPointer(resultId, ptr);
return EmitResult::Continue; return EmitResult::Continue;
} }
...@@ -2834,11 +2834,11 @@ namespace sw ...@@ -2834,11 +2834,11 @@ namespace sw
memoryOrder = MemoryOrder(memorySemantics); memoryOrder = MemoryOrder(memorySemantics);
} }
auto ptr = GetPointerToData(pointerId, 0, routine); auto ptr = GetPointerToData(pointerId, 0, state);
bool interleavedByLane = IsStorageInterleavedByLane(pointerTy.storageClass); bool interleavedByLane = IsStorageInterleavedByLane(pointerTy.storageClass);
auto &dst = routine->createIntermediate(resultId, resultTy.sizeInComponents); auto &dst = state->createIntermediate(resultId, resultTy.sizeInComponents);
VisitMemoryObject(pointerId, [&](uint32_t i, uint32_t offset) VisitMemoryObject(pointerId, [&](uint32_t i, uint32_t offset)
{ {
...@@ -2852,7 +2852,6 @@ namespace sw ...@@ -2852,7 +2852,6 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitStore(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
bool atomic = (insn.opcode() == spv::OpAtomicStore); bool atomic = (insn.opcode() == spv::OpAtomicStore);
Object::ID pointerId = insn.word(1); Object::ID pointerId = insn.word(1);
Object::ID objectId = insn.word(atomic ? 4 : 2); Object::ID objectId = insn.word(atomic ? 4 : 2);
...@@ -2871,7 +2870,7 @@ namespace sw ...@@ -2871,7 +2870,7 @@ namespace sw
ASSERT(!atomic || elementTy.opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer." ASSERT(!atomic || elementTy.opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer."
auto ptr = GetPointerToData(pointerId, 0, routine); auto ptr = GetPointerToData(pointerId, 0, state);
bool interleavedByLane = IsStorageInterleavedByLane(pointerTy.storageClass); bool interleavedByLane = IsStorageInterleavedByLane(pointerTy.storageClass);
if (object.kind == Object::Kind::Constant) if (object.kind == Object::Kind::Constant)
...@@ -2888,7 +2887,7 @@ namespace sw ...@@ -2888,7 +2887,7 @@ namespace sw
else else
{ {
// Intermediate source data. // Intermediate source data.
auto &src = routine->getIntermediate(objectId); auto &src = state->getIntermediate(objectId);
VisitMemoryObject(pointerId, [&](uint32_t i, uint32_t offset) VisitMemoryObject(pointerId, [&](uint32_t i, uint32_t offset)
{ {
auto p = ptr + offset; auto p = ptr + offset;
...@@ -2902,7 +2901,6 @@ namespace sw ...@@ -2902,7 +2901,6 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitAccessChain(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitAccessChain(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
Type::ID typeId = insn.word(1); Type::ID typeId = insn.word(1);
Object::ID resultId = insn.word(2); Object::ID resultId = insn.word(2);
Object::ID baseId = insn.word(3); Object::ID baseId = insn.word(3);
...@@ -2916,13 +2914,13 @@ namespace sw ...@@ -2916,13 +2914,13 @@ namespace sw
type.storageClass == spv::StorageClassUniform || type.storageClass == spv::StorageClassUniform ||
type.storageClass == spv::StorageClassStorageBuffer) type.storageClass == spv::StorageClassStorageBuffer)
{ {
auto ptr = WalkExplicitLayoutAccessChain(baseId, numIndexes, indexes, routine); auto ptr = WalkExplicitLayoutAccessChain(baseId, numIndexes, indexes, state);
routine->createPointer(resultId, ptr); state->createPointer(resultId, ptr);
} }
else else
{ {
auto ptr = WalkAccessChain(baseId, numIndexes, indexes, routine); auto ptr = WalkAccessChain(baseId, numIndexes, indexes, state);
routine->createPointer(resultId, ptr); state->createPointer(resultId, ptr);
} }
return EmitResult::Continue; return EmitResult::Continue;
...@@ -2930,9 +2928,8 @@ namespace sw ...@@ -2930,9 +2928,8 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitCompositeConstruct(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitCompositeConstruct(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto offset = 0u; auto offset = 0u;
for (auto i = 0u; i < insn.wordCount() - 3; i++) for (auto i = 0u; i < insn.wordCount() - 3; i++)
...@@ -2940,7 +2937,7 @@ namespace sw ...@@ -2940,7 +2937,7 @@ namespace sw
Object::ID srcObjectId = insn.word(3u + i); Object::ID srcObjectId = insn.word(3u + i);
auto & srcObject = getObject(srcObjectId); auto & srcObject = getObject(srcObjectId);
auto & srcObjectTy = getType(srcObject.type); auto & srcObjectTy = getType(srcObject.type);
GenericValue srcObjectAccess(this, routine, srcObjectId); GenericValue srcObjectAccess(this, state, srcObjectId);
for (auto j = 0u; j < srcObjectTy.sizeInComponents; j++) for (auto j = 0u; j < srcObjectTy.sizeInComponents; j++)
{ {
...@@ -2953,16 +2950,15 @@ namespace sw ...@@ -2953,16 +2950,15 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitCompositeInsert(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitCompositeInsert(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
Type::ID resultTypeId = insn.word(1); Type::ID resultTypeId = insn.word(1);
auto &type = getType(resultTypeId); auto &type = getType(resultTypeId);
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto &newPartObject = getObject(insn.word(3)); auto &newPartObject = getObject(insn.word(3));
auto &newPartObjectTy = getType(newPartObject.type); auto &newPartObjectTy = getType(newPartObject.type);
auto firstNewComponent = WalkLiteralAccessChain(resultTypeId, insn.wordCount() - 5, insn.wordPointer(5)); auto firstNewComponent = WalkLiteralAccessChain(resultTypeId, insn.wordCount() - 5, insn.wordPointer(5));
GenericValue srcObjectAccess(this, routine, insn.word(4)); GenericValue srcObjectAccess(this, state, insn.word(4));
GenericValue newPartObjectAccess(this, routine, insn.word(3)); GenericValue newPartObjectAccess(this, state, insn.word(3));
// old components before // old components before
for (auto i = 0u; i < firstNewComponent; i++) for (auto i = 0u; i < firstNewComponent; i++)
...@@ -2985,14 +2981,13 @@ namespace sw ...@@ -2985,14 +2981,13 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitCompositeExtract(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitCompositeExtract(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto &compositeObject = getObject(insn.word(3)); auto &compositeObject = getObject(insn.word(3));
Type::ID compositeTypeId = compositeObject.definition.word(1); Type::ID compositeTypeId = compositeObject.definition.word(1);
auto firstComponent = WalkLiteralAccessChain(compositeTypeId, insn.wordCount() - 4, insn.wordPointer(4)); auto firstComponent = WalkLiteralAccessChain(compositeTypeId, insn.wordCount() - 4, insn.wordPointer(4));
GenericValue compositeObjectAccess(this, routine, insn.word(3)); GenericValue compositeObjectAccess(this, state, insn.word(3));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, compositeObjectAccess.Float(firstComponent + i)); dst.move(i, compositeObjectAccess.Float(firstComponent + i));
...@@ -3003,16 +2998,15 @@ namespace sw ...@@ -3003,16 +2998,15 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitVectorShuffle(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitVectorShuffle(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
// Note: number of components in result type, first half type, and second // Note: number of components in result type, first half type, and second
// half type are all independent. // half type are all independent.
auto &firstHalfType = getType(getObject(insn.word(3)).type); auto &firstHalfType = getType(getObject(insn.word(3)).type);
GenericValue firstHalfAccess(this, routine, insn.word(3)); GenericValue firstHalfAccess(this, state, insn.word(3));
GenericValue secondHalfAccess(this, routine, insn.word(4)); GenericValue secondHalfAccess(this, state, insn.word(4));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
...@@ -3038,13 +3032,12 @@ namespace sw ...@@ -3038,13 +3032,12 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitVectorExtractDynamic(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitVectorExtractDynamic(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto &srcType = getType(getObject(insn.word(3)).type); auto &srcType = getType(getObject(insn.word(3)).type);
GenericValue src(this, routine, insn.word(3)); GenericValue src(this, state, insn.word(3));
GenericValue index(this, routine, insn.word(4)); GenericValue index(this, state, insn.word(4));
SIMD::UInt v = SIMD::UInt(0); SIMD::UInt v = SIMD::UInt(0);
...@@ -3059,13 +3052,12 @@ namespace sw ...@@ -3059,13 +3052,12 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitVectorInsertDynamic(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitVectorInsertDynamic(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
GenericValue src(this, routine, insn.word(3)); GenericValue src(this, state, insn.word(3));
GenericValue component(this, routine, insn.word(4)); GenericValue component(this, state, insn.word(4));
GenericValue index(this, routine, insn.word(5)); GenericValue index(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
...@@ -3077,11 +3069,10 @@ namespace sw ...@@ -3077,11 +3069,10 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitVectorTimesScalar(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitVectorTimesScalar(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto lhs = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, state, insn.word(3));
auto rhs = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, state, insn.word(4));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
...@@ -3093,11 +3084,10 @@ namespace sw ...@@ -3093,11 +3084,10 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitMatrixTimesVector(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitMatrixTimesVector(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto lhs = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, state, insn.word(3));
auto rhs = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, state, insn.word(4));
auto rhsType = getType(rhs.type); auto rhsType = getType(rhs.type);
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
...@@ -3115,11 +3105,10 @@ namespace sw ...@@ -3115,11 +3105,10 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitVectorTimesMatrix(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitVectorTimesMatrix(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto lhs = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, state, insn.word(3));
auto rhs = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, state, insn.word(4));
auto lhsType = getType(lhs.type); auto lhsType = getType(lhs.type);
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
...@@ -3137,11 +3126,10 @@ namespace sw ...@@ -3137,11 +3126,10 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitMatrixTimesMatrix(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitMatrixTimesMatrix(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto lhs = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, state, insn.word(3));
auto rhs = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, state, insn.word(4));
auto numColumns = type.definition.word(3); auto numColumns = type.definition.word(3);
auto numRows = getType(type.definition.word(2)).definition.word(3); auto numRows = getType(type.definition.word(2)).definition.word(3);
...@@ -3165,11 +3153,10 @@ namespace sw ...@@ -3165,11 +3153,10 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitOuterProduct(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitOuterProduct(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto lhs = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, state, insn.word(3));
auto rhs = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, state, insn.word(4));
auto &lhsType = getType(lhs.type); auto &lhsType = getType(lhs.type);
auto &rhsType = getType(rhs.type); auto &rhsType = getType(rhs.type);
...@@ -3195,10 +3182,9 @@ namespace sw ...@@ -3195,10 +3182,9 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitTranspose(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitTranspose(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto mat = GenericValue(this, routine, insn.word(3)); auto mat = GenericValue(this, state, insn.word(3));
auto numCols = type.definition.word(3); auto numCols = type.definition.word(3);
auto numRows = getType(type.definition.word(2)).sizeInComponents; auto numRows = getType(type.definition.word(2)).sizeInComponents;
...@@ -3216,10 +3202,9 @@ namespace sw ...@@ -3216,10 +3202,9 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitUnaryOp(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitUnaryOp(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto src = GenericValue(this, routine, insn.word(3)); auto src = GenericValue(this, state, insn.word(3));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
...@@ -3231,9 +3216,9 @@ namespace sw ...@@ -3231,9 +3216,9 @@ namespace sw
break; break;
case spv::OpBitFieldInsert: case spv::OpBitFieldInsert:
{ {
auto insert = GenericValue(this, routine, insn.word(4)).UInt(i); auto insert = GenericValue(this, state, insn.word(4)).UInt(i);
auto offset = GenericValue(this, routine, insn.word(5)).UInt(0); auto offset = GenericValue(this, state, insn.word(5)).UInt(0);
auto count = GenericValue(this, routine, insn.word(6)).UInt(0); auto count = GenericValue(this, state, insn.word(6)).UInt(0);
auto one = SIMD::UInt(1); auto one = SIMD::UInt(1);
auto v = src.UInt(i); auto v = src.UInt(i);
auto mask = Bitmask32(offset + count) ^ Bitmask32(offset); auto mask = Bitmask32(offset + count) ^ Bitmask32(offset);
...@@ -3243,8 +3228,8 @@ namespace sw ...@@ -3243,8 +3228,8 @@ namespace sw
case spv::OpBitFieldSExtract: case spv::OpBitFieldSExtract:
case spv::OpBitFieldUExtract: case spv::OpBitFieldUExtract:
{ {
auto offset = GenericValue(this, routine, insn.word(4)).UInt(0); auto offset = GenericValue(this, state, insn.word(4)).UInt(0);
auto count = GenericValue(this, routine, insn.word(5)).UInt(0); auto count = GenericValue(this, state, insn.word(5)).UInt(0);
auto one = SIMD::UInt(1); auto one = SIMD::UInt(1);
auto v = src.UInt(i); auto v = src.UInt(i);
SIMD::UInt out = (v >> offset) & Bitmask32(count); SIMD::UInt out = (v >> offset) & Bitmask32(count);
...@@ -3392,12 +3377,11 @@ namespace sw ...@@ -3392,12 +3377,11 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitBinaryOp(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitBinaryOp(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto &lhsType = getType(getObject(insn.word(3)).type); auto &lhsType = getType(getObject(insn.word(3)).type);
auto lhs = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, state, insn.word(3));
auto rhs = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, state, insn.word(4));
for (auto i = 0u; i < lhsType.sizeInComponents; i++) for (auto i = 0u; i < lhsType.sizeInComponents; i++)
{ {
...@@ -3596,13 +3580,12 @@ namespace sw ...@@ -3596,13 +3580,12 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitDot(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitDot(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
ASSERT(type.sizeInComponents == 1); ASSERT(type.sizeInComponents == 1);
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto &lhsType = getType(getObject(insn.word(3)).type); auto &lhsType = getType(getObject(insn.word(3)).type);
auto lhs = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, state, insn.word(3));
auto rhs = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, state, insn.word(4));
dst.move(0, Dot(lhsType.sizeInComponents, lhs, rhs)); dst.move(0, Dot(lhsType.sizeInComponents, lhs, rhs));
return EmitResult::Continue; return EmitResult::Continue;
...@@ -3610,13 +3593,12 @@ namespace sw ...@@ -3610,13 +3593,12 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitSelect(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitSelect(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto cond = GenericValue(this, routine, insn.word(3)); auto cond = GenericValue(this, state, insn.word(3));
auto condIsScalar = (getType(cond.type).sizeInComponents == 1); auto condIsScalar = (getType(cond.type).sizeInComponents == 1);
auto lhs = GenericValue(this, routine, insn.word(4)); auto lhs = GenericValue(this, state, insn.word(4));
auto rhs = GenericValue(this, routine, insn.word(5)); auto rhs = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
...@@ -3629,16 +3611,15 @@ namespace sw ...@@ -3629,16 +3611,15 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitExtendedInstruction(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitExtendedInstruction(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto extInstIndex = static_cast<GLSLstd450>(insn.word(4)); auto extInstIndex = static_cast<GLSLstd450>(insn.word(4));
switch (extInstIndex) switch (extInstIndex)
{ {
case GLSLstd450FAbs: case GLSLstd450FAbs:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Abs(src.Float(i))); dst.move(i, Abs(src.Float(i)));
...@@ -3647,7 +3628,7 @@ namespace sw ...@@ -3647,7 +3628,7 @@ namespace sw
} }
case GLSLstd450SAbs: case GLSLstd450SAbs:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Abs(src.Int(i))); dst.move(i, Abs(src.Int(i)));
...@@ -3656,8 +3637,8 @@ namespace sw ...@@ -3656,8 +3637,8 @@ namespace sw
} }
case GLSLstd450Cross: case GLSLstd450Cross:
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, state, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, state, insn.word(6));
dst.move(0, lhs.Float(1) * rhs.Float(2) - rhs.Float(1) * lhs.Float(2)); dst.move(0, lhs.Float(1) * rhs.Float(2) - rhs.Float(1) * lhs.Float(2));
dst.move(1, lhs.Float(2) * rhs.Float(0) - rhs.Float(2) * lhs.Float(0)); dst.move(1, lhs.Float(2) * rhs.Float(0) - rhs.Float(2) * lhs.Float(0));
dst.move(2, lhs.Float(0) * rhs.Float(1) - rhs.Float(0) * lhs.Float(1)); dst.move(2, lhs.Float(0) * rhs.Float(1) - rhs.Float(0) * lhs.Float(1));
...@@ -3665,7 +3646,7 @@ namespace sw ...@@ -3665,7 +3646,7 @@ namespace sw
} }
case GLSLstd450Floor: case GLSLstd450Floor:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Floor(src.Float(i))); dst.move(i, Floor(src.Float(i)));
...@@ -3674,7 +3655,7 @@ namespace sw ...@@ -3674,7 +3655,7 @@ namespace sw
} }
case GLSLstd450Trunc: case GLSLstd450Trunc:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Trunc(src.Float(i))); dst.move(i, Trunc(src.Float(i)));
...@@ -3683,7 +3664,7 @@ namespace sw ...@@ -3683,7 +3664,7 @@ namespace sw
} }
case GLSLstd450Ceil: case GLSLstd450Ceil:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Ceil(src.Float(i))); dst.move(i, Ceil(src.Float(i)));
...@@ -3692,7 +3673,7 @@ namespace sw ...@@ -3692,7 +3673,7 @@ namespace sw
} }
case GLSLstd450Fract: case GLSLstd450Fract:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Frac(src.Float(i))); dst.move(i, Frac(src.Float(i)));
...@@ -3701,7 +3682,7 @@ namespace sw ...@@ -3701,7 +3682,7 @@ namespace sw
} }
case GLSLstd450Round: case GLSLstd450Round:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Round(src.Float(i))); dst.move(i, Round(src.Float(i)));
...@@ -3710,7 +3691,7 @@ namespace sw ...@@ -3710,7 +3691,7 @@ namespace sw
} }
case GLSLstd450RoundEven: case GLSLstd450RoundEven:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto x = Round(src.Float(i)); auto x = Round(src.Float(i));
...@@ -3722,8 +3703,8 @@ namespace sw ...@@ -3722,8 +3703,8 @@ namespace sw
} }
case GLSLstd450FMin: case GLSLstd450FMin:
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, state, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Min(lhs.Float(i), rhs.Float(i))); dst.move(i, Min(lhs.Float(i), rhs.Float(i)));
...@@ -3732,8 +3713,8 @@ namespace sw ...@@ -3732,8 +3713,8 @@ namespace sw
} }
case GLSLstd450FMax: case GLSLstd450FMax:
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, state, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Max(lhs.Float(i), rhs.Float(i))); dst.move(i, Max(lhs.Float(i), rhs.Float(i)));
...@@ -3742,8 +3723,8 @@ namespace sw ...@@ -3742,8 +3723,8 @@ namespace sw
} }
case GLSLstd450SMin: case GLSLstd450SMin:
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, state, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Min(lhs.Int(i), rhs.Int(i))); dst.move(i, Min(lhs.Int(i), rhs.Int(i)));
...@@ -3752,8 +3733,8 @@ namespace sw ...@@ -3752,8 +3733,8 @@ namespace sw
} }
case GLSLstd450SMax: case GLSLstd450SMax:
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, state, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Max(lhs.Int(i), rhs.Int(i))); dst.move(i, Max(lhs.Int(i), rhs.Int(i)));
...@@ -3762,8 +3743,8 @@ namespace sw ...@@ -3762,8 +3743,8 @@ namespace sw
} }
case GLSLstd450UMin: case GLSLstd450UMin:
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, state, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Min(lhs.UInt(i), rhs.UInt(i))); dst.move(i, Min(lhs.UInt(i), rhs.UInt(i)));
...@@ -3772,8 +3753,8 @@ namespace sw ...@@ -3772,8 +3753,8 @@ namespace sw
} }
case GLSLstd450UMax: case GLSLstd450UMax:
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, state, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Max(lhs.UInt(i), rhs.UInt(i))); dst.move(i, Max(lhs.UInt(i), rhs.UInt(i)));
...@@ -3782,8 +3763,8 @@ namespace sw ...@@ -3782,8 +3763,8 @@ namespace sw
} }
case GLSLstd450Step: case GLSLstd450Step:
{ {
auto edge = GenericValue(this, routine, insn.word(5)); auto edge = GenericValue(this, state, insn.word(5));
auto x = GenericValue(this, routine, insn.word(6)); auto x = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, CmpNLT(x.Float(i), edge.Float(i)) & As<SIMD::Int>(SIMD::Float(1.0f))); dst.move(i, CmpNLT(x.Float(i), edge.Float(i)) & As<SIMD::Int>(SIMD::Float(1.0f)));
...@@ -3792,9 +3773,9 @@ namespace sw ...@@ -3792,9 +3773,9 @@ namespace sw
} }
case GLSLstd450SmoothStep: case GLSLstd450SmoothStep:
{ {
auto edge0 = GenericValue(this, routine, insn.word(5)); auto edge0 = GenericValue(this, state, insn.word(5));
auto edge1 = GenericValue(this, routine, insn.word(6)); auto edge1 = GenericValue(this, state, insn.word(6));
auto x = GenericValue(this, routine, insn.word(7)); auto x = GenericValue(this, state, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto tx = Min(Max((x.Float(i) - edge0.Float(i)) / auto tx = Min(Max((x.Float(i) - edge0.Float(i)) /
...@@ -3805,9 +3786,9 @@ namespace sw ...@@ -3805,9 +3786,9 @@ namespace sw
} }
case GLSLstd450FMix: case GLSLstd450FMix:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto y = GenericValue(this, routine, insn.word(6)); auto y = GenericValue(this, state, insn.word(6));
auto a = GenericValue(this, routine, insn.word(7)); auto a = GenericValue(this, state, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, a.Float(i) * (y.Float(i) - x.Float(i)) + x.Float(i)); dst.move(i, a.Float(i) * (y.Float(i) - x.Float(i)) + x.Float(i));
...@@ -3816,9 +3797,9 @@ namespace sw ...@@ -3816,9 +3797,9 @@ namespace sw
} }
case GLSLstd450FClamp: case GLSLstd450FClamp:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto minVal = GenericValue(this, routine, insn.word(6)); auto minVal = GenericValue(this, state, insn.word(6));
auto maxVal = GenericValue(this, routine, insn.word(7)); auto maxVal = GenericValue(this, state, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Min(Max(x.Float(i), minVal.Float(i)), maxVal.Float(i))); dst.move(i, Min(Max(x.Float(i), minVal.Float(i)), maxVal.Float(i)));
...@@ -3827,9 +3808,9 @@ namespace sw ...@@ -3827,9 +3808,9 @@ namespace sw
} }
case GLSLstd450SClamp: case GLSLstd450SClamp:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto minVal = GenericValue(this, routine, insn.word(6)); auto minVal = GenericValue(this, state, insn.word(6));
auto maxVal = GenericValue(this, routine, insn.word(7)); auto maxVal = GenericValue(this, state, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Min(Max(x.Int(i), minVal.Int(i)), maxVal.Int(i))); dst.move(i, Min(Max(x.Int(i), minVal.Int(i)), maxVal.Int(i)));
...@@ -3838,9 +3819,9 @@ namespace sw ...@@ -3838,9 +3819,9 @@ namespace sw
} }
case GLSLstd450UClamp: case GLSLstd450UClamp:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto minVal = GenericValue(this, routine, insn.word(6)); auto minVal = GenericValue(this, state, insn.word(6));
auto maxVal = GenericValue(this, routine, insn.word(7)); auto maxVal = GenericValue(this, state, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Min(Max(x.UInt(i), minVal.UInt(i)), maxVal.UInt(i))); dst.move(i, Min(Max(x.UInt(i), minVal.UInt(i)), maxVal.UInt(i)));
...@@ -3849,7 +3830,7 @@ namespace sw ...@@ -3849,7 +3830,7 @@ namespace sw
} }
case GLSLstd450FSign: case GLSLstd450FSign:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto neg = As<SIMD::Int>(CmpLT(src.Float(i), SIMD::Float(-0.0f))) & As<SIMD::Int>(SIMD::Float(-1.0f)); auto neg = As<SIMD::Int>(CmpLT(src.Float(i), SIMD::Float(-0.0f))) & As<SIMD::Int>(SIMD::Float(-1.0f));
...@@ -3860,7 +3841,7 @@ namespace sw ...@@ -3860,7 +3841,7 @@ namespace sw
} }
case GLSLstd450SSign: case GLSLstd450SSign:
{ {
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto neg = CmpLT(src.Int(i), SIMD::Int(0)) & SIMD::Int(-1); auto neg = CmpLT(src.Int(i), SIMD::Int(0)) & SIMD::Int(-1);
...@@ -3871,8 +3852,8 @@ namespace sw ...@@ -3871,8 +3852,8 @@ namespace sw
} }
case GLSLstd450Reflect: case GLSLstd450Reflect:
{ {
auto I = GenericValue(this, routine, insn.word(5)); auto I = GenericValue(this, state, insn.word(5));
auto N = GenericValue(this, routine, insn.word(6)); auto N = GenericValue(this, state, insn.word(6));
SIMD::Float d = Dot(type.sizeInComponents, I, N); SIMD::Float d = Dot(type.sizeInComponents, I, N);
...@@ -3884,9 +3865,9 @@ namespace sw ...@@ -3884,9 +3865,9 @@ namespace sw
} }
case GLSLstd450Refract: case GLSLstd450Refract:
{ {
auto I = GenericValue(this, routine, insn.word(5)); auto I = GenericValue(this, state, insn.word(5));
auto N = GenericValue(this, routine, insn.word(6)); auto N = GenericValue(this, state, insn.word(6));
auto eta = GenericValue(this, routine, insn.word(7)); auto eta = GenericValue(this, state, insn.word(7));
SIMD::Float d = Dot(type.sizeInComponents, I, N); SIMD::Float d = Dot(type.sizeInComponents, I, N);
SIMD::Float k = SIMD::Float(1.0f) - eta.Float(0) * eta.Float(0) * (SIMD::Float(1.0f) - d * d); SIMD::Float k = SIMD::Float(1.0f) - eta.Float(0) * eta.Float(0) * (SIMD::Float(1.0f) - d * d);
...@@ -3901,9 +3882,9 @@ namespace sw ...@@ -3901,9 +3882,9 @@ namespace sw
} }
case GLSLstd450FaceForward: case GLSLstd450FaceForward:
{ {
auto N = GenericValue(this, routine, insn.word(5)); auto N = GenericValue(this, state, insn.word(5));
auto I = GenericValue(this, routine, insn.word(6)); auto I = GenericValue(this, state, insn.word(6));
auto Nref = GenericValue(this, routine, insn.word(7)); auto Nref = GenericValue(this, state, insn.word(7));
SIMD::Float d = Dot(type.sizeInComponents, I, Nref); SIMD::Float d = Dot(type.sizeInComponents, I, Nref);
SIMD::Int neg = CmpLT(d, SIMD::Float(0.0f)); SIMD::Int neg = CmpLT(d, SIMD::Float(0.0f));
...@@ -3917,7 +3898,7 @@ namespace sw ...@@ -3917,7 +3898,7 @@ namespace sw
} }
case GLSLstd450Length: case GLSLstd450Length:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x); SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x);
dst.move(0, Sqrt(d)); dst.move(0, Sqrt(d));
...@@ -3925,7 +3906,7 @@ namespace sw ...@@ -3925,7 +3906,7 @@ namespace sw
} }
case GLSLstd450Normalize: case GLSLstd450Normalize:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x); SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x);
SIMD::Float invLength = SIMD::Float(1.0f) / Sqrt(d); SIMD::Float invLength = SIMD::Float(1.0f) / Sqrt(d);
...@@ -3937,8 +3918,8 @@ namespace sw ...@@ -3937,8 +3918,8 @@ namespace sw
} }
case GLSLstd450Distance: case GLSLstd450Distance:
{ {
auto p0 = GenericValue(this, routine, insn.word(5)); auto p0 = GenericValue(this, state, insn.word(5));
auto p1 = GenericValue(this, routine, insn.word(6)); auto p1 = GenericValue(this, state, insn.word(6));
auto p0Type = getType(p0.type); auto p0Type = getType(p0.type);
// sqrt(dot(p0-p1, p0-p1)) // sqrt(dot(p0-p1, p0-p1))
...@@ -3954,10 +3935,10 @@ namespace sw ...@@ -3954,10 +3935,10 @@ namespace sw
} }
case GLSLstd450Modf: case GLSLstd450Modf:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
auto ptrId = Object::ID(insn.word(6)); auto ptrId = Object::ID(insn.word(6));
auto ptrTy = getType(getObject(ptrId).type); auto ptrTy = getType(getObject(ptrId).type);
auto ptr = GetPointerToData(ptrId, 0, routine); auto ptr = GetPointerToData(ptrId, 0, state);
bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass); bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
...@@ -3973,7 +3954,7 @@ namespace sw ...@@ -3973,7 +3954,7 @@ namespace sw
} }
case GLSLstd450ModfStruct: case GLSLstd450ModfStruct:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
auto valTy = getType(val.type); auto valTy = getType(val.type);
for (auto i = 0u; i < valTy.sizeInComponents; i++) for (auto i = 0u; i < valTy.sizeInComponents; i++)
...@@ -3987,7 +3968,7 @@ namespace sw ...@@ -3987,7 +3968,7 @@ namespace sw
} }
case GLSLstd450PackSnorm4x8: case GLSLstd450PackSnorm4x8:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) & dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
SIMD::Int(0xFF)) | SIMD::Int(0xFF)) |
((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) & ((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
...@@ -4000,7 +3981,7 @@ namespace sw ...@@ -4000,7 +3981,7 @@ namespace sw
} }
case GLSLstd450PackUnorm4x8: case GLSLstd450PackUnorm4x8:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) | dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) |
((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 8) | ((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 8) |
((SIMD::UInt(Round(Min(Max(val.Float(2), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 16) | ((SIMD::UInt(Round(Min(Max(val.Float(2), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 16) |
...@@ -4009,7 +3990,7 @@ namespace sw ...@@ -4009,7 +3990,7 @@ namespace sw
} }
case GLSLstd450PackSnorm2x16: case GLSLstd450PackSnorm2x16:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) & dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) &
SIMD::Int(0xFFFF)) | SIMD::Int(0xFFFF)) |
((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) & ((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) &
...@@ -4018,7 +3999,7 @@ namespace sw ...@@ -4018,7 +3999,7 @@ namespace sw
} }
case GLSLstd450PackUnorm2x16: case GLSLstd450PackUnorm2x16:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) & dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) &
SIMD::UInt(0xFFFF)) | SIMD::UInt(0xFFFF)) |
((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) & ((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) &
...@@ -4027,13 +4008,13 @@ namespace sw ...@@ -4027,13 +4008,13 @@ namespace sw
} }
case GLSLstd450PackHalf2x16: case GLSLstd450PackHalf2x16:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, FloatToHalfBits(val.UInt(0), false) | FloatToHalfBits(val.UInt(1), true)); dst.move(0, FloatToHalfBits(val.UInt(0), false) | FloatToHalfBits(val.UInt(1), true));
break; break;
} }
case GLSLstd450UnpackSnorm4x8: case GLSLstd450UnpackSnorm4x8:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, Min(Max(SIMD::Float(((val.Int(0)<<24) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f))); dst.move(0, Min(Max(SIMD::Float(((val.Int(0)<<24) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
dst.move(1, Min(Max(SIMD::Float(((val.Int(0)<<16) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f))); dst.move(1, Min(Max(SIMD::Float(((val.Int(0)<<16) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
dst.move(2, Min(Max(SIMD::Float(((val.Int(0)<<8) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f))); dst.move(2, Min(Max(SIMD::Float(((val.Int(0)<<8) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
...@@ -4042,7 +4023,7 @@ namespace sw ...@@ -4042,7 +4023,7 @@ namespace sw
} }
case GLSLstd450UnpackUnorm4x8: case GLSLstd450UnpackUnorm4x8:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f)); dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
dst.move(1, SIMD::Float(((val.UInt(0)>>8) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f)); dst.move(1, SIMD::Float(((val.UInt(0)>>8) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
dst.move(2, SIMD::Float(((val.UInt(0)>>16) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f)); dst.move(2, SIMD::Float(((val.UInt(0)>>16) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
...@@ -4051,7 +4032,7 @@ namespace sw ...@@ -4051,7 +4032,7 @@ namespace sw
} }
case GLSLstd450UnpackSnorm2x16: case GLSLstd450UnpackSnorm2x16:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
// clamp(f / 32767.0, -1.0, 1.0) // clamp(f / 32767.0, -1.0, 1.0)
dst.move(0, Min(Max(SIMD::Float(As<SIMD::Int>((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16)) * dst.move(0, Min(Max(SIMD::Float(As<SIMD::Int>((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16)) *
SIMD::Float(1.0f / float(0x7FFF0000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f))); SIMD::Float(1.0f / float(0x7FFF0000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
...@@ -4061,7 +4042,7 @@ namespace sw ...@@ -4061,7 +4042,7 @@ namespace sw
} }
case GLSLstd450UnpackUnorm2x16: case GLSLstd450UnpackUnorm2x16:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
// f / 65535.0 // f / 65535.0
dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16) * SIMD::Float(1.0f / float(0xFFFF0000))); dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16) * SIMD::Float(1.0f / float(0xFFFF0000)));
dst.move(1, SIMD::Float(val.UInt(0) & SIMD::UInt(0xFFFF0000)) * SIMD::Float(1.0f / float(0xFFFF0000))); dst.move(1, SIMD::Float(val.UInt(0) & SIMD::UInt(0xFFFF0000)) * SIMD::Float(1.0f / float(0xFFFF0000)));
...@@ -4069,16 +4050,16 @@ namespace sw ...@@ -4069,16 +4050,16 @@ namespace sw
} }
case GLSLstd450UnpackHalf2x16: case GLSLstd450UnpackHalf2x16:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
dst.move(0, halfToFloatBits(val.UInt(0) & SIMD::UInt(0x0000FFFF))); dst.move(0, halfToFloatBits(val.UInt(0) & SIMD::UInt(0x0000FFFF)));
dst.move(1, halfToFloatBits((val.UInt(0) & SIMD::UInt(0xFFFF0000)) >> 16)); dst.move(1, halfToFloatBits((val.UInt(0) & SIMD::UInt(0xFFFF0000)) >> 16));
break; break;
} }
case GLSLstd450Fma: case GLSLstd450Fma:
{ {
auto a = GenericValue(this, routine, insn.word(5)); auto a = GenericValue(this, state, insn.word(5));
auto b = GenericValue(this, routine, insn.word(6)); auto b = GenericValue(this, state, insn.word(6));
auto c = GenericValue(this, routine, insn.word(7)); auto c = GenericValue(this, state, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, FMA(a.Float(i), b.Float(i), c.Float(i))); dst.move(i, FMA(a.Float(i), b.Float(i), c.Float(i)));
...@@ -4087,10 +4068,10 @@ namespace sw ...@@ -4087,10 +4068,10 @@ namespace sw
} }
case GLSLstd450Frexp: case GLSLstd450Frexp:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
auto ptrId = Object::ID(insn.word(6)); auto ptrId = Object::ID(insn.word(6));
auto ptrTy = getType(getObject(ptrId).type); auto ptrTy = getType(getObject(ptrId).type);
auto ptr = GetPointerToData(ptrId, 0, routine); auto ptr = GetPointerToData(ptrId, 0, state);
bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass); bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
...@@ -4109,7 +4090,7 @@ namespace sw ...@@ -4109,7 +4090,7 @@ namespace sw
} }
case GLSLstd450FrexpStruct: case GLSLstd450FrexpStruct:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
auto numComponents = getType(val.type).sizeInComponents; auto numComponents = getType(val.type).sizeInComponents;
for (auto i = 0u; i < numComponents; i++) for (auto i = 0u; i < numComponents; i++)
{ {
...@@ -4121,8 +4102,8 @@ namespace sw ...@@ -4121,8 +4102,8 @@ namespace sw
} }
case GLSLstd450Ldexp: case GLSLstd450Ldexp:
{ {
auto significand = GenericValue(this, routine, insn.word(5)); auto significand = GenericValue(this, state, insn.word(5));
auto exponent = GenericValue(this, routine, insn.word(6)); auto exponent = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
// Assumes IEEE 754 // Assumes IEEE 754
...@@ -4155,7 +4136,7 @@ namespace sw ...@@ -4155,7 +4136,7 @@ namespace sw
} }
case GLSLstd450Radians: case GLSLstd450Radians:
{ {
auto degrees = GenericValue(this, routine, insn.word(5)); auto degrees = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, degrees.Float(i) * SIMD::Float(PI / 180.0f)); dst.move(i, degrees.Float(i) * SIMD::Float(PI / 180.0f));
...@@ -4164,7 +4145,7 @@ namespace sw ...@@ -4164,7 +4145,7 @@ namespace sw
} }
case GLSLstd450Degrees: case GLSLstd450Degrees:
{ {
auto radians = GenericValue(this, routine, insn.word(5)); auto radians = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, radians.Float(i) * SIMD::Float(180.0f / PI)); dst.move(i, radians.Float(i) * SIMD::Float(180.0f / PI));
...@@ -4173,7 +4154,7 @@ namespace sw ...@@ -4173,7 +4154,7 @@ namespace sw
} }
case GLSLstd450Sin: case GLSLstd450Sin:
{ {
auto radians = GenericValue(this, routine, insn.word(5)); auto radians = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Sin(radians.Float(i))); dst.move(i, Sin(radians.Float(i)));
...@@ -4182,7 +4163,7 @@ namespace sw ...@@ -4182,7 +4163,7 @@ namespace sw
} }
case GLSLstd450Cos: case GLSLstd450Cos:
{ {
auto radians = GenericValue(this, routine, insn.word(5)); auto radians = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Cos(radians.Float(i))); dst.move(i, Cos(radians.Float(i)));
...@@ -4191,7 +4172,7 @@ namespace sw ...@@ -4191,7 +4172,7 @@ namespace sw
} }
case GLSLstd450Tan: case GLSLstd450Tan:
{ {
auto radians = GenericValue(this, routine, insn.word(5)); auto radians = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Tan(radians.Float(i))); dst.move(i, Tan(radians.Float(i)));
...@@ -4200,7 +4181,7 @@ namespace sw ...@@ -4200,7 +4181,7 @@ namespace sw
} }
case GLSLstd450Asin: case GLSLstd450Asin:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Asin(val.Float(i))); dst.move(i, Asin(val.Float(i)));
...@@ -4209,7 +4190,7 @@ namespace sw ...@@ -4209,7 +4190,7 @@ namespace sw
} }
case GLSLstd450Acos: case GLSLstd450Acos:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Acos(val.Float(i))); dst.move(i, Acos(val.Float(i)));
...@@ -4218,7 +4199,7 @@ namespace sw ...@@ -4218,7 +4199,7 @@ namespace sw
} }
case GLSLstd450Atan: case GLSLstd450Atan:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Atan(val.Float(i))); dst.move(i, Atan(val.Float(i)));
...@@ -4227,7 +4208,7 @@ namespace sw ...@@ -4227,7 +4208,7 @@ namespace sw
} }
case GLSLstd450Sinh: case GLSLstd450Sinh:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Sinh(val.Float(i))); dst.move(i, Sinh(val.Float(i)));
...@@ -4236,7 +4217,7 @@ namespace sw ...@@ -4236,7 +4217,7 @@ namespace sw
} }
case GLSLstd450Cosh: case GLSLstd450Cosh:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Cosh(val.Float(i))); dst.move(i, Cosh(val.Float(i)));
...@@ -4245,7 +4226,7 @@ namespace sw ...@@ -4245,7 +4226,7 @@ namespace sw
} }
case GLSLstd450Tanh: case GLSLstd450Tanh:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Tanh(val.Float(i))); dst.move(i, Tanh(val.Float(i)));
...@@ -4254,7 +4235,7 @@ namespace sw ...@@ -4254,7 +4235,7 @@ namespace sw
} }
case GLSLstd450Asinh: case GLSLstd450Asinh:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Asinh(val.Float(i))); dst.move(i, Asinh(val.Float(i)));
...@@ -4263,7 +4244,7 @@ namespace sw ...@@ -4263,7 +4244,7 @@ namespace sw
} }
case GLSLstd450Acosh: case GLSLstd450Acosh:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Acosh(val.Float(i))); dst.move(i, Acosh(val.Float(i)));
...@@ -4272,7 +4253,7 @@ namespace sw ...@@ -4272,7 +4253,7 @@ namespace sw
} }
case GLSLstd450Atanh: case GLSLstd450Atanh:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Atanh(val.Float(i))); dst.move(i, Atanh(val.Float(i)));
...@@ -4281,8 +4262,8 @@ namespace sw ...@@ -4281,8 +4262,8 @@ namespace sw
} }
case GLSLstd450Atan2: case GLSLstd450Atan2:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto y = GenericValue(this, routine, insn.word(6)); auto y = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Atan2(x.Float(i), y.Float(i))); dst.move(i, Atan2(x.Float(i), y.Float(i)));
...@@ -4291,8 +4272,8 @@ namespace sw ...@@ -4291,8 +4272,8 @@ namespace sw
} }
case GLSLstd450Pow: case GLSLstd450Pow:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto y = GenericValue(this, routine, insn.word(6)); auto y = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Pow(x.Float(i), y.Float(i))); dst.move(i, Pow(x.Float(i), y.Float(i)));
...@@ -4301,7 +4282,7 @@ namespace sw ...@@ -4301,7 +4282,7 @@ namespace sw
} }
case GLSLstd450Exp: case GLSLstd450Exp:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Exp(val.Float(i))); dst.move(i, Exp(val.Float(i)));
...@@ -4310,7 +4291,7 @@ namespace sw ...@@ -4310,7 +4291,7 @@ namespace sw
} }
case GLSLstd450Log: case GLSLstd450Log:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Log(val.Float(i))); dst.move(i, Log(val.Float(i)));
...@@ -4319,7 +4300,7 @@ namespace sw ...@@ -4319,7 +4300,7 @@ namespace sw
} }
case GLSLstd450Exp2: case GLSLstd450Exp2:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Exp2(val.Float(i))); dst.move(i, Exp2(val.Float(i)));
...@@ -4328,7 +4309,7 @@ namespace sw ...@@ -4328,7 +4309,7 @@ namespace sw
} }
case GLSLstd450Log2: case GLSLstd450Log2:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Log2(val.Float(i))); dst.move(i, Log2(val.Float(i)));
...@@ -4337,7 +4318,7 @@ namespace sw ...@@ -4337,7 +4318,7 @@ namespace sw
} }
case GLSLstd450Sqrt: case GLSLstd450Sqrt:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, Sqrt(val.Float(i))); dst.move(i, Sqrt(val.Float(i)));
...@@ -4346,7 +4327,7 @@ namespace sw ...@@ -4346,7 +4327,7 @@ namespace sw
} }
case GLSLstd450InverseSqrt: case GLSLstd450InverseSqrt:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
Decorations d; Decorations d;
ApplyDecorationsForId(&d, insn.word(5)); ApplyDecorationsForId(&d, insn.word(5));
if (d.RelaxedPrecision) if (d.RelaxedPrecision)
...@@ -4367,7 +4348,7 @@ namespace sw ...@@ -4367,7 +4348,7 @@ namespace sw
} }
case GLSLstd450Determinant: case GLSLstd450Determinant:
{ {
auto mat = GenericValue(this, routine, insn.word(5)); auto mat = GenericValue(this, state, insn.word(5));
auto numComponents = getType(mat.type).sizeInComponents; auto numComponents = getType(mat.type).sizeInComponents;
switch (numComponents) switch (numComponents)
{ {
...@@ -4396,7 +4377,7 @@ namespace sw ...@@ -4396,7 +4377,7 @@ namespace sw
} }
case GLSLstd450MatrixInverse: case GLSLstd450MatrixInverse:
{ {
auto mat = GenericValue(this, routine, insn.word(5)); auto mat = GenericValue(this, state, insn.word(5));
auto numComponents = getType(mat.type).sizeInComponents; auto numComponents = getType(mat.type).sizeInComponents;
switch (numComponents) switch (numComponents)
{ {
...@@ -4458,7 +4439,7 @@ namespace sw ...@@ -4458,7 +4439,7 @@ namespace sw
} }
case GLSLstd450FindILsb: case GLSLstd450FindILsb:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto v = val.UInt(i); auto v = val.UInt(i);
...@@ -4468,7 +4449,7 @@ namespace sw ...@@ -4468,7 +4449,7 @@ namespace sw
} }
case GLSLstd450FindSMsb: case GLSLstd450FindSMsb:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto v = val.UInt(i) ^ As<SIMD::UInt>(CmpLT(val.Int(i), SIMD::Int(0))); auto v = val.UInt(i) ^ As<SIMD::UInt>(CmpLT(val.Int(i), SIMD::Int(0)));
...@@ -4478,7 +4459,7 @@ namespace sw ...@@ -4478,7 +4459,7 @@ namespace sw
} }
case GLSLstd450FindUMsb: case GLSLstd450FindUMsb:
{ {
auto val = GenericValue(this, routine, insn.word(5)); auto val = GenericValue(this, state, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, SIMD::UInt(31) - Ctlz(val.UInt(i), false)); dst.move(i, SIMD::UInt(31) - Ctlz(val.UInt(i), false));
...@@ -4502,8 +4483,8 @@ namespace sw ...@@ -4502,8 +4483,8 @@ namespace sw
} }
case GLSLstd450NMin: case GLSLstd450NMin:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto y = GenericValue(this, routine, insn.word(6)); auto y = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, NMin(x.Float(i), y.Float(i))); dst.move(i, NMin(x.Float(i), y.Float(i)));
...@@ -4512,8 +4493,8 @@ namespace sw ...@@ -4512,8 +4493,8 @@ namespace sw
} }
case GLSLstd450NMax: case GLSLstd450NMax:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto y = GenericValue(this, routine, insn.word(6)); auto y = GenericValue(this, state, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.move(i, NMax(x.Float(i), y.Float(i))); dst.move(i, NMax(x.Float(i), y.Float(i)));
...@@ -4522,9 +4503,9 @@ namespace sw ...@@ -4522,9 +4503,9 @@ namespace sw
} }
case GLSLstd450NClamp: case GLSLstd450NClamp:
{ {
auto x = GenericValue(this, routine, insn.word(5)); auto x = GenericValue(this, state, insn.word(5));
auto minVal = GenericValue(this, routine, insn.word(6)); auto minVal = GenericValue(this, state, insn.word(6));
auto maxVal = GenericValue(this, routine, insn.word(7)); auto maxVal = GenericValue(this, state, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto clamp = NMin(NMax(x.Float(i), minVal.Float(i)), maxVal.Float(i)); auto clamp = NMin(NMax(x.Float(i), minVal.Float(i)), maxVal.Float(i));
...@@ -4612,12 +4593,11 @@ namespace sw ...@@ -4612,12 +4593,11 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitAny(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitAny(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
ASSERT(type.sizeInComponents == 1); ASSERT(type.sizeInComponents == 1);
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto &srcType = getType(getObject(insn.word(3)).type); auto &srcType = getType(getObject(insn.word(3)).type);
auto src = GenericValue(this, routine, insn.word(3)); auto src = GenericValue(this, state, insn.word(3));
SIMD::UInt result = src.UInt(0); SIMD::UInt result = src.UInt(0);
...@@ -4632,12 +4612,11 @@ namespace sw ...@@ -4632,12 +4612,11 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitAll(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitAll(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
ASSERT(type.sizeInComponents == 1); ASSERT(type.sizeInComponents == 1);
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
auto &srcType = getType(getObject(insn.word(3)).type); auto &srcType = getType(getObject(insn.word(3)).type);
auto src = GenericValue(this, routine, insn.word(3)); auto src = GenericValue(this, state, insn.word(3));
SIMD::UInt result = src.UInt(0); SIMD::UInt result = src.UInt(0);
...@@ -4666,7 +4645,7 @@ namespace sw ...@@ -4666,7 +4645,7 @@ namespace sw
auto trueBlockId = Block::ID(block.branchInstruction.word(2)); auto trueBlockId = Block::ID(block.branchInstruction.word(2));
auto falseBlockId = Block::ID(block.branchInstruction.word(3)); auto falseBlockId = Block::ID(block.branchInstruction.word(3));
auto cond = GenericValue(this, state->routine, condId); auto cond = GenericValue(this, state, condId);
ASSERT_MSG(getType(cond.type).sizeInComponents == 1, "Condition must be a Boolean type scalar"); ASSERT_MSG(getType(cond.type).sizeInComponents == 1, "Condition must be a Boolean type scalar");
// TODO: Optimize for case where all lanes take same path. // TODO: Optimize for case where all lanes take same path.
...@@ -4684,7 +4663,7 @@ namespace sw ...@@ -4684,7 +4663,7 @@ namespace sw
auto selId = Object::ID(block.branchInstruction.word(1)); auto selId = Object::ID(block.branchInstruction.word(1));
auto sel = GenericValue(this, state->routine, selId); auto sel = GenericValue(this, state, selId);
ASSERT_MSG(getType(sel.type).sizeInComponents == 1, "Selector must be a scalar"); ASSERT_MSG(getType(sel.type).sizeInComponents == 1, "Selector must be a scalar");
auto numCases = (block.branchInstruction.wordCount() - 3) / 2; auto numCases = (block.branchInstruction.wordCount() - 3) / 2;
...@@ -4747,7 +4726,6 @@ namespace sw ...@@ -4747,7 +4726,6 @@ namespace sw
void SpirvShader::LoadPhi(InsnIterator insn, EmitState *state) const void SpirvShader::LoadPhi(InsnIterator insn, EmitState *state) const
{ {
auto routine = state->routine;
auto typeId = Type::ID(insn.word(1)); auto typeId = Type::ID(insn.word(1));
auto type = getType(typeId); auto type = getType(typeId);
auto objectId = Object::ID(insn.word(2)); auto objectId = Object::ID(insn.word(2));
...@@ -4756,7 +4734,7 @@ namespace sw ...@@ -4756,7 +4734,7 @@ namespace sw
ASSERT(storageIt != state->routine->phis.end()); ASSERT(storageIt != state->routine->phis.end());
auto &storage = storageIt->second; auto &storage = storageIt->second;
auto &dst = routine->createIntermediate(objectId, type.sizeInComponents); auto &dst = state->createIntermediate(objectId, type.sizeInComponents);
for(uint32_t i = 0; i < type.sizeInComponents; i++) for(uint32_t i = 0; i < type.sizeInComponents; i++)
{ {
dst.move(i, storage[i]); dst.move(i, storage[i]);
...@@ -4765,7 +4743,6 @@ namespace sw ...@@ -4765,7 +4743,6 @@ namespace sw
void SpirvShader::StorePhi(Block::ID currentBlock, InsnIterator insn, EmitState *state, std::unordered_set<SpirvShader::Block::ID> const& filter) const void SpirvShader::StorePhi(Block::ID currentBlock, InsnIterator insn, EmitState *state, std::unordered_set<SpirvShader::Block::ID> const& filter) const
{ {
auto routine = state->routine;
auto typeId = Type::ID(insn.word(1)); auto typeId = Type::ID(insn.word(1));
auto type = getType(typeId); auto type = getType(typeId);
auto objectId = Object::ID(insn.word(2)); auto objectId = Object::ID(insn.word(2));
...@@ -4785,7 +4762,7 @@ namespace sw ...@@ -4785,7 +4762,7 @@ namespace sw
} }
auto mask = GetActiveLaneMaskEdge(state, blockId, currentBlock); auto mask = GetActiveLaneMaskEdge(state, blockId, currentBlock);
auto in = GenericValue(this, routine, varId); auto in = GenericValue(this, state, varId);
for (uint32_t i = 0; i < type.sizeInComponents; i++) for (uint32_t i = 0; i < type.sizeInComponents; i++)
{ {
...@@ -4838,15 +4815,15 @@ namespace sw ...@@ -4838,15 +4815,15 @@ namespace sw
Object::ID coordinateId = insn.word(4); Object::ID coordinateId = insn.word(4);
auto &resultType = getType(resultTypeId); auto &resultType = getType(resultTypeId);
auto &result = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &result = state->createIntermediate(resultId, resultType.sizeInComponents);
auto imageDescriptor = state->routine->getPointer(sampledImageId).base; // vk::SampledImageDescriptor* auto imageDescriptor = state->getPointer(sampledImageId).base; // vk::SampledImageDescriptor*
// If using a separate sampler, look through the OpSampledImage instruction to find the sampler descriptor // If using a separate sampler, look through the OpSampledImage instruction to find the sampler descriptor
auto &sampledImage = getObject(sampledImageId); auto &sampledImage = getObject(sampledImageId);
auto samplerDescriptor = (sampledImage.opcode() == spv::OpSampledImage) ? auto samplerDescriptor = (sampledImage.opcode() == spv::OpSampledImage) ?
state->routine->getPointer(sampledImage.definition.word(4)).base : imageDescriptor; state->getPointer(sampledImage.definition.word(4)).base : imageDescriptor;
auto coordinate = GenericValue(this, state->routine, coordinateId); auto coordinate = GenericValue(this, state, coordinateId);
auto &coordinateType = getType(coordinate.type); auto &coordinateType = getType(coordinate.type);
Pointer<Byte> sampler = samplerDescriptor + OFFSET(vk::SampledImageDescriptor, sampler); // vk::Sampler* Pointer<Byte> sampler = samplerDescriptor + OFFSET(vk::SampledImageDescriptor, sampler); // vk::Sampler*
...@@ -4942,7 +4919,7 @@ namespace sw ...@@ -4942,7 +4919,7 @@ namespace sw
if(instruction.isDref()) if(instruction.isDref())
{ {
auto drefValue = GenericValue(this, state->routine, insn.word(5)); auto drefValue = GenericValue(this, state, insn.word(5));
if(instruction.isProj()) if(instruction.isProj())
{ {
...@@ -4958,14 +4935,14 @@ namespace sw ...@@ -4958,14 +4935,14 @@ namespace sw
if(lodOrBias) if(lodOrBias)
{ {
auto lodValue = GenericValue(this, state->routine, lodOrBiasId); auto lodValue = GenericValue(this, state, lodOrBiasId);
in[i] = lodValue.Float(0); in[i] = lodValue.Float(0);
i++; i++;
} }
else if(grad) else if(grad)
{ {
auto dxValue = GenericValue(this, state->routine, gradDxId); auto dxValue = GenericValue(this, state, gradDxId);
auto dyValue = GenericValue(this, state->routine, gradDyId); auto dyValue = GenericValue(this, state, gradDyId);
auto &dxyType = getType(dxValue.type); auto &dxyType = getType(dxValue.type);
ASSERT(dxyType.sizeInComponents == getType(dyValue.type).sizeInComponents); ASSERT(dxyType.sizeInComponents == getType(dyValue.type).sizeInComponents);
...@@ -4992,7 +4969,7 @@ namespace sw ...@@ -4992,7 +4969,7 @@ namespace sw
if(constOffset) if(constOffset)
{ {
auto offsetValue = GenericValue(this, state->routine, offsetId); auto offsetValue = GenericValue(this, state, offsetId);
auto &offsetType = getType(offsetValue.type); auto &offsetType = getType(offsetValue.type);
instruction.offset = offsetType.sizeInComponents; instruction.offset = offsetType.sizeInComponents;
...@@ -5005,7 +4982,7 @@ namespace sw ...@@ -5005,7 +4982,7 @@ namespace sw
if(sample) if(sample)
{ {
auto sampleValue = GenericValue(this, state->routine, sampleId); auto sampleValue = GenericValue(this, state, sampleId);
in[i] = sampleValue.Float(0); in[i] = sampleValue.Float(0);
} }
...@@ -5026,8 +5003,8 @@ namespace sw ...@@ -5026,8 +5003,8 @@ namespace sw
auto imageId = Object::ID(insn.word(3)); auto imageId = Object::ID(insn.word(3));
auto lodId = Object::ID(insn.word(4)); auto lodId = Object::ID(insn.word(4));
auto &dst = state->routine->createIntermediate(resultId, resultTy.sizeInComponents); auto &dst = state->createIntermediate(resultId, resultTy.sizeInComponents);
GetImageDimensions(state->routine, resultTy, imageId, lodId, dst); GetImageDimensions(state, resultTy, imageId, lodId, dst);
return EmitResult::Continue; return EmitResult::Continue;
} }
...@@ -5039,8 +5016,8 @@ namespace sw ...@@ -5039,8 +5016,8 @@ namespace sw
auto imageId = Object::ID(insn.word(3)); auto imageId = Object::ID(insn.word(3));
auto lodId = Object::ID(0); auto lodId = Object::ID(0);
auto &dst = state->routine->createIntermediate(resultId, resultTy.sizeInComponents); auto &dst = state->createIntermediate(resultId, resultTy.sizeInComponents);
GetImageDimensions(state->routine, resultTy, imageId, lodId, dst); GetImageDimensions(state, resultTy, imageId, lodId, dst);
return EmitResult::Continue; return EmitResult::Continue;
} }
...@@ -5050,8 +5027,9 @@ namespace sw ...@@ -5050,8 +5027,9 @@ namespace sw
return EmitImageSample({None, Query}, insn, state); return EmitImageSample({None, Query}, insn, state);
} }
void SpirvShader::GetImageDimensions(SpirvRoutine const *routine, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const void SpirvShader::GetImageDimensions(EmitState const *state, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const
{ {
auto routine = state->routine;
auto &image = getObject(imageId); auto &image = getObject(imageId);
auto &imageType = getType(image.type); auto &imageType = getType(image.type);
...@@ -5063,7 +5041,7 @@ namespace sw ...@@ -5063,7 +5041,7 @@ namespace sw
auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
auto &bindingLayout = setLayout->getBindingLayout(d.Binding); auto &bindingLayout = setLayout->getBindingLayout(d.Binding);
Pointer<Byte> descriptor = routine->getPointer(imageId).base; Pointer<Byte> descriptor = state->getPointer(imageId).base;
Pointer<Int> extent; Pointer<Int> extent;
Int arrayLayers; Int arrayLayers;
...@@ -5093,7 +5071,7 @@ namespace sw ...@@ -5093,7 +5071,7 @@ namespace sw
std::vector<Int> out; std::vector<Int> out;
if (lodId != 0) if (lodId != 0)
{ {
auto lodVal = GenericValue(this, routine, lodId); auto lodVal = GenericValue(this, state, lodId);
ASSERT(getType(lodVal.type).sizeInComponents == 1); ASSERT(getType(lodVal.type).sizeInComponents == 1);
auto lod = lodVal.Int(0); auto lod = lodVal.Int(0);
auto one = SIMD::Int(1); auto one = SIMD::Int(1);
...@@ -5128,7 +5106,7 @@ namespace sw ...@@ -5128,7 +5106,7 @@ namespace sw
auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
auto &bindingLayout = setLayout->getBindingLayout(d.Binding); auto &bindingLayout = setLayout->getBindingLayout(d.Binding);
Pointer<Byte> descriptor = state->routine->getPointer(imageId).base; Pointer<Byte> descriptor = state->getPointer(imageId).base;
Int mipLevels = 0; Int mipLevels = 0;
switch (bindingLayout.descriptorType) switch (bindingLayout.descriptorType)
{ {
...@@ -5141,7 +5119,7 @@ namespace sw ...@@ -5141,7 +5119,7 @@ namespace sw
UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType)); UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
} }
auto &dst = state->routine->createIntermediate(resultId, 1); auto &dst = state->createIntermediate(resultId, 1);
dst.move(0, SIMD::Int(mipLevels)); dst.move(0, SIMD::Int(mipLevels));
return EmitResult::Continue; return EmitResult::Continue;
...@@ -5162,7 +5140,7 @@ namespace sw ...@@ -5162,7 +5140,7 @@ namespace sw
auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
auto &bindingLayout = setLayout->getBindingLayout(d.Binding); auto &bindingLayout = setLayout->getBindingLayout(d.Binding);
Pointer<Byte> descriptor = state->routine->getPointer(imageId).base; Pointer<Byte> descriptor = state->getPointer(imageId).base;
Int sampleCount = 0; Int sampleCount = 0;
switch (bindingLayout.descriptorType) switch (bindingLayout.descriptorType)
{ {
...@@ -5178,14 +5156,15 @@ namespace sw ...@@ -5178,14 +5156,15 @@ namespace sw
UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType)); UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
} }
auto &dst = state->routine->createIntermediate(resultId, 1); auto &dst = state->createIntermediate(resultId, 1);
dst.move(0, SIMD::Int(sampleCount)); dst.move(0, SIMD::Int(sampleCount));
return EmitResult::Continue; return EmitResult::Continue;
} }
SIMD::Pointer SpirvShader::GetTexelAddress(SpirvRoutine const *routine, SIMD::Pointer ptr, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const SIMD::Pointer SpirvShader::GetTexelAddress(EmitState const *state, SIMD::Pointer ptr, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const
{ {
auto routine = state->routine;
bool isArrayed = imageType.definition.word(5) != 0; bool isArrayed = imageType.definition.word(5) != 0;
auto dim = static_cast<spv::Dim>(imageType.definition.word(3)); auto dim = static_cast<spv::Dim>(imageType.definition.word(3));
int dims = getType(coordinate.type).sizeInComponents - (isArrayed ? 1 : 0); int dims = getType(coordinate.type).sizeInComponents - (isArrayed ? 1 : 0);
...@@ -5240,7 +5219,7 @@ namespace sw ...@@ -5240,7 +5219,7 @@ namespace sw
if (sampleId.value()) if (sampleId.value())
{ {
GenericValue sample{this, routine, sampleId}; GenericValue sample(this, state, sampleId);
ptr += sample.Int(0) * samplePitch; ptr += sample.Int(0) * samplePitch;
} }
...@@ -5279,7 +5258,7 @@ namespace sw ...@@ -5279,7 +5258,7 @@ namespace sw
ASSERT(imageType.definition.opcode() == spv::OpTypeImage); ASSERT(imageType.definition.opcode() == spv::OpTypeImage);
auto dim = static_cast<spv::Dim>(imageType.definition.word(3)); auto dim = static_cast<spv::Dim>(imageType.definition.word(3));
auto coordinate = GenericValue(this, state->routine, insn.word(4)); auto coordinate = GenericValue(this, state, insn.word(4));
const DescriptorDecorations &d = descriptorDecorations.at(imageId); const DescriptorDecorations &d = descriptorDecorations.at(imageId);
// For subpass data, format in the instruction is spv::ImageFormatUnknown. Get it from // For subpass data, format in the instruction is spv::ImageFormatUnknown. Get it from
...@@ -5298,7 +5277,7 @@ namespace sw ...@@ -5298,7 +5277,7 @@ namespace sw
vkFormat = VK_FORMAT_S8_UINT; vkFormat = VK_FORMAT_S8_UINT;
} }
auto pointer = state->routine->getPointer(imageId); auto pointer = state->getPointer(imageId);
Pointer<Byte> binding = pointer.base; Pointer<Byte> binding = pointer.base;
Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + (useStencilAspect Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + (useStencilAspect
? OFFSET(vk::StorageImageDescriptor, stencilPtr) ? OFFSET(vk::StorageImageDescriptor, stencilPtr)
...@@ -5306,11 +5285,11 @@ namespace sw ...@@ -5306,11 +5285,11 @@ namespace sw
auto imageSizeInBytes = *Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, sizeInBytes)); auto imageSizeInBytes = *Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, sizeInBytes));
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->createIntermediate(resultId, resultType.sizeInComponents);
auto texelSize = vk::Format(vkFormat).bytes(); auto texelSize = vk::Format(vkFormat).bytes();
auto basePtr = SIMD::Pointer(imageBase, imageSizeInBytes); auto basePtr = SIMD::Pointer(imageBase, imageSizeInBytes);
auto texelPtr = GetTexelAddress(state->routine, basePtr, coordinate, imageType, binding, texelSize, sampleId, useStencilAspect); auto texelPtr = GetTexelAddress(state, basePtr, coordinate, imageType, binding, texelSize, sampleId, useStencilAspect);
SIMD::Int packed[4]; SIMD::Int packed[4];
// Round up texel size: for formats smaller than 32 bits per texel, we will emit a bunch // Round up texel size: for formats smaller than 32 bits per texel, we will emit a bunch
...@@ -5545,10 +5524,10 @@ namespace sw ...@@ -5545,10 +5524,10 @@ namespace sw
// TODO(b/131171141): Not handling any image operands yet. // TODO(b/131171141): Not handling any image operands yet.
ASSERT(insn.wordCount() == 4); ASSERT(insn.wordCount() == 4);
auto coordinate = GenericValue(this, state->routine, insn.word(2)); auto coordinate = GenericValue(this, state, insn.word(2));
auto texel = GenericValue(this, state->routine, insn.word(3)); auto texel = GenericValue(this, state, insn.word(3));
Pointer<Byte> binding = state->routine->getPointer(imageId).base; Pointer<Byte> binding = state->getPointer(imageId).base;
Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr)); Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr));
auto imageSizeInBytes = *Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, sizeInBytes)); auto imageSizeInBytes = *Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, sizeInBytes));
...@@ -5652,7 +5631,7 @@ namespace sw ...@@ -5652,7 +5631,7 @@ namespace sw
} }
auto basePtr = SIMD::Pointer(imageBase, imageSizeInBytes); auto basePtr = SIMD::Pointer(imageBase, imageSizeInBytes);
auto texelPtr = GetTexelAddress(state->routine, basePtr, coordinate, imageType, binding, texelSize, 0, false); auto texelPtr = GetTexelAddress(state, basePtr, coordinate, imageType, binding, texelSize, 0, false);
for (auto i = 0u; i < numPackedElements; i++) for (auto i = 0u; i < numPackedElements; i++)
{ {
...@@ -5677,16 +5656,16 @@ namespace sw ...@@ -5677,16 +5656,16 @@ namespace sw
ASSERT(resultType.storageClass == spv::StorageClassImage); ASSERT(resultType.storageClass == spv::StorageClassImage);
ASSERT(getType(resultType.element).opcode() == spv::OpTypeInt); ASSERT(getType(resultType.element).opcode() == spv::OpTypeInt);
auto coordinate = GenericValue(this, state->routine, insn.word(4)); auto coordinate = GenericValue(this, state, insn.word(4));
Pointer<Byte> binding = state->routine->getPointer(imageId).base; Pointer<Byte> binding = state->getPointer(imageId).base;
Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr)); Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr));
auto imageSizeInBytes = *Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, sizeInBytes)); auto imageSizeInBytes = *Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, sizeInBytes));
auto basePtr = SIMD::Pointer(imageBase, imageSizeInBytes); auto basePtr = SIMD::Pointer(imageBase, imageSizeInBytes);
auto ptr = GetTexelAddress(state->routine, basePtr, coordinate, imageType, binding, sizeof(uint32_t), 0, false); auto ptr = GetTexelAddress(state, basePtr, coordinate, imageType, binding, sizeof(uint32_t), 0, false);
state->routine->createPointer(resultId, ptr); state->createPointer(resultId, ptr);
return EmitResult::Continue; return EmitResult::Continue;
} }
...@@ -5699,7 +5678,7 @@ namespace sw ...@@ -5699,7 +5678,7 @@ namespace sw
Object::ID resultId = insn.word(2); Object::ID resultId = insn.word(2);
Object::ID imageId = insn.word(3); Object::ID imageId = insn.word(3);
state->routine->createPointer(resultId, state->routine->getPointer(imageId)); state->createPointer(resultId, state->getPointer(imageId));
return EmitResult::Continue; return EmitResult::Continue;
} }
...@@ -5712,9 +5691,9 @@ namespace sw ...@@ -5712,9 +5691,9 @@ namespace sw
auto memorySemantics = static_cast<spv::MemorySemanticsMask>(getObject(semanticsId).constantValue[0]); auto memorySemantics = static_cast<spv::MemorySemanticsMask>(getObject(semanticsId).constantValue[0]);
auto memoryOrder = MemoryOrder(memorySemantics); auto memoryOrder = MemoryOrder(memorySemantics);
// Where no value is provided (increment/decrement) use an implicit value of 1. // Where no value is provided (increment/decrement) use an implicit value of 1.
auto value = (insn.wordCount() == 7) ? GenericValue(this, state->routine, insn.word(6)).UInt(0) : RValue<SIMD::UInt>(1); auto value = (insn.wordCount() == 7) ? GenericValue(this, state, insn.word(6)).UInt(0) : RValue<SIMD::UInt>(1);
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->createIntermediate(resultId, resultType.sizeInComponents);
auto ptr = state->routine->getPointer(insn.word(3)); auto ptr = state->getPointer(insn.word(3));
auto ptrOffsets = ptr.offsets(); auto ptrOffsets = ptr.offsets();
SIMD::UInt x; SIMD::UInt x;
...@@ -5782,10 +5761,10 @@ namespace sw ...@@ -5782,10 +5761,10 @@ namespace sw
auto memorySemanticsUnequal = static_cast<spv::MemorySemanticsMask>(getObject(insn.word(6)).constantValue[0]); auto memorySemanticsUnequal = static_cast<spv::MemorySemanticsMask>(getObject(insn.word(6)).constantValue[0]);
auto memoryOrderUnequal = MemoryOrder(memorySemanticsUnequal); auto memoryOrderUnequal = MemoryOrder(memorySemanticsUnequal);
auto value = GenericValue(this, state->routine, insn.word(7)); auto value = GenericValue(this, state, insn.word(7));
auto comparator = GenericValue(this, state->routine, insn.word(8)); auto comparator = GenericValue(this, state, insn.word(8));
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->createIntermediate(resultId, resultType.sizeInComponents);
auto ptr = state->routine->getPointer(insn.word(3)); auto ptr = state->getPointer(insn.word(3));
auto ptrOffsets = ptr.offsets(); auto ptrOffsets = ptr.offsets();
SIMD::UInt x; SIMD::UInt x;
...@@ -5808,8 +5787,8 @@ namespace sw ...@@ -5808,8 +5787,8 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitCopyObject(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitCopyObject(InsnIterator insn, EmitState *state) const
{ {
auto ty = getType(insn.word(1)); auto ty = getType(insn.word(1));
auto &dst = state->routine->createIntermediate(insn.word(2), ty.sizeInComponents); auto &dst = state->createIntermediate(insn.word(2), ty.sizeInComponents);
auto src = GenericValue(this, state->routine, insn.word(3)); auto src = GenericValue(this, state, insn.word(3));
for (uint32_t i = 0; i < ty.sizeInComponents; i++) for (uint32_t i = 0; i < ty.sizeInComponents; i++)
{ {
dst.move(i, src.Int(i)); dst.move(i, src.Int(i));
...@@ -5827,8 +5806,8 @@ namespace sw ...@@ -5827,8 +5806,8 @@ namespace sw
bool dstInterleavedByLane = IsStorageInterleavedByLane(dstPtrTy.storageClass); bool dstInterleavedByLane = IsStorageInterleavedByLane(dstPtrTy.storageClass);
bool srcInterleavedByLane = IsStorageInterleavedByLane(srcPtrTy.storageClass); bool srcInterleavedByLane = IsStorageInterleavedByLane(srcPtrTy.storageClass);
auto dstPtr = GetPointerToData(dstPtrId, 0, state->routine); auto dstPtr = GetPointerToData(dstPtrId, 0, state);
auto srcPtr = GetPointerToData(srcPtrId, 0, state->routine); auto srcPtr = GetPointerToData(srcPtrId, 0, state);
std::unordered_map<uint32_t, uint32_t> srcOffsets; std::unordered_map<uint32_t, uint32_t> srcOffsets;
...@@ -5899,7 +5878,7 @@ namespace sw ...@@ -5899,7 +5878,7 @@ namespace sw
auto scope = spv::Scope(GetConstScalarInt(insn.word(3))); auto scope = spv::Scope(GetConstScalarInt(insn.word(3)));
ASSERT_MSG(scope == spv::ScopeSubgroup, "Scope for Non Uniform Group Operations must be Subgroup for Vulkan 1.1"); ASSERT_MSG(scope == spv::ScopeSubgroup, "Scope for Non Uniform Group Operations must be Subgroup for Vulkan 1.1");
auto &dst = state->routine->createIntermediate(resultId, type.sizeInComponents); auto &dst = state->createIntermediate(resultId, type.sizeInComponents);
switch (insn.opcode()) switch (insn.opcode())
{ {
...@@ -5938,8 +5917,8 @@ namespace sw ...@@ -5938,8 +5917,8 @@ namespace sw
ASSERT(arrayTy.definition.opcode() == spv::OpTypeRuntimeArray); ASSERT(arrayTy.definition.opcode() == spv::OpTypeRuntimeArray);
auto &arrayElTy = getType(arrayTy.element); auto &arrayElTy = getType(arrayTy.element);
auto &result = state->routine->createIntermediate(resultId, 1); auto &result = state->createIntermediate(resultId, 1);
auto structBase = GetPointerToData(structPtrId, 0, state->routine); auto structBase = GetPointerToData(structPtrId, 0, state);
Decorations d = {}; Decorations d = {};
ApplyDecorationsForIdMember(&d, structPtrTy.element, arrayFieldIdx); ApplyDecorationsForIdMember(&d, structPtrTy.element, arrayFieldIdx);
...@@ -6283,12 +6262,10 @@ namespace sw ...@@ -6283,12 +6262,10 @@ namespace sw
} }
} }
// Clear all transient containers. This serves two purposes: // Clear phis that are no longer used. This serves two purposes:
// (1) All rr::Variables held in these containers are destructed, // (1) The phi rr::Variables are destructed, preventing pointless
// preventing pointless materialization. // materialization.
// (2) Frees memory that will never be used again. // (2) Frees memory that will never be used again.
routine->pointers.clear();
routine->intermediates.clear();
routine->phis.clear(); routine->phis.clear();
} }
...@@ -6458,9 +6435,9 @@ namespace sw ...@@ -6458,9 +6435,9 @@ namespace sw
} }
} }
SpirvShader::GenericValue::GenericValue(SpirvShader const *shader, SpirvRoutine const *routine, SpirvShader::Object::ID objId) : SpirvShader::GenericValue::GenericValue(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId) :
obj(shader->getObject(objId)), obj(shader->getObject(objId)),
intermediate(obj.kind == SpirvShader::Object::Kind::Intermediate ? &routine->getIntermediate(objId) : nullptr), intermediate(obj.kind == SpirvShader::Object::Kind::Intermediate ? &state->getIntermediate(objId) : nullptr),
type(obj.type) {} type(obj.type) {}
SpirvRoutine::SpirvRoutine(vk::PipelineLayout const *pipelineLayout) : SpirvRoutine::SpirvRoutine(vk::PipelineLayout const *pipelineLayout) :
......
...@@ -919,22 +919,6 @@ namespace sw ...@@ -919,22 +919,6 @@ namespace sw
void ProcessInterfaceVariable(Object &object); void ProcessInterfaceVariable(Object &object);
// Returns a SIMD::Pointer to the underlying data for the given pointer
// object.
// Handles objects of the following kinds:
// • DescriptorSet
// • DivergentPointer
// • InterfaceVariable
// • NonDivergentPointer
// Calling GetPointerToData with objects of any other kind will assert.
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 WalkAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, SpirvRoutine *routine) const;
// Returns the *component* offset in the literal for the given access chain.
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.
class EmitState class EmitState
{ {
...@@ -979,6 +963,38 @@ namespace sw ...@@ -979,6 +963,38 @@ namespace sw
const vk::DescriptorSet::Bindings &descriptorSets; const vk::DescriptorSet::Bindings &descriptorSets;
const bool robust = true; // Emit robustBufferAccess safe code. const bool robust = true; // Emit robustBufferAccess safe code.
Intermediate& createIntermediate(Object::ID id, uint32_t size)
{
auto it = intermediates.emplace(std::piecewise_construct,
std::forward_as_tuple(id),
std::forward_as_tuple(size));
ASSERT_MSG(it.second, "Intermediate %d created twice", id.value());
return it.first->second;
}
Intermediate const& getIntermediate(Object::ID id) const
{
auto it = intermediates.find(id);
ASSERT_MSG(it != intermediates.end(), "Unknown intermediate %d", id.value());
return it->second;
}
void createPointer(Object::ID id, SIMD::Pointer ptr)
{
bool added = pointers.emplace(id, ptr).second;
ASSERT_MSG(added, "Pointer %d created twice", id.value());
}
SIMD::Pointer const& getPointer(Object::ID id) const
{
auto it = pointers.find(id);
ASSERT_MSG(it != pointers.end(), "Unknown pointer %d", id.value());
return it->second;
}
private:
std::unordered_map<Object::ID, Intermediate> intermediates;
std::unordered_map<Object::ID, SIMD::Pointer> pointers;
}; };
// EmitResult is an enumerator of result values from the Emit functions. // EmitResult is an enumerator of result values from the Emit functions.
...@@ -998,7 +1014,7 @@ namespace sw ...@@ -998,7 +1014,7 @@ namespace sw
Intermediate const *intermediate; Intermediate const *intermediate;
public: public:
GenericValue(SpirvShader const *shader, SpirvRoutine const *routine, SpirvShader::Object::ID objId); GenericValue(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId);
RValue<SIMD::Float> Float(uint32_t i) const RValue<SIMD::Float> Float(uint32_t i) const
{ {
...@@ -1023,6 +1039,22 @@ namespace sw ...@@ -1023,6 +1039,22 @@ namespace sw
SpirvShader::Type::ID const type; SpirvShader::Type::ID const type;
}; };
// Returns a SIMD::Pointer to the underlying data for the given pointer
// object.
// Handles objects of the following kinds:
// • DescriptorSet
// • DivergentPointer
// • InterfaceVariable
// • NonDivergentPointer
// Calling GetPointerToData with objects of any other kind will assert.
SIMD::Pointer GetPointerToData(Object::ID id, int arrayIndex, EmitState const *state) const;
SIMD::Pointer WalkExplicitLayoutAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, EmitState const *state) const;
SIMD::Pointer WalkAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, EmitState const *state) const;
// Returns the *component* offset in the literal for the given access chain.
uint32_t WalkLiteralAccessChain(Type::ID id, uint32_t numIndexes, uint32_t const *indexes) const;
// existsPath returns true if there's a direct or indirect flow from // existsPath returns true if there's a direct or indirect flow from
// the 'from' block to the 'to' block that does not pass through // the 'from' block to the 'to' block that does not pass through
// notPassingThrough. // notPassingThrough.
...@@ -1101,8 +1133,8 @@ namespace sw ...@@ -1101,8 +1133,8 @@ namespace sw
EmitResult EmitGroupNonUniform(InsnIterator insn, EmitState *state) const; EmitResult EmitGroupNonUniform(InsnIterator insn, EmitState *state) const;
EmitResult EmitArrayLength(InsnIterator insn, EmitState *state) const; EmitResult EmitArrayLength(InsnIterator insn, EmitState *state) const;
void GetImageDimensions(SpirvRoutine const *routine, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const; void GetImageDimensions(EmitState const *state, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const;
SIMD::Pointer GetTexelAddress(SpirvRoutine const *routine, SIMD::Pointer base, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const; SIMD::Pointer GetTexelAddress(EmitState const *state, SIMD::Pointer base, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const;
uint32_t GetConstScalarInt(Object::ID id) const; uint32_t GetConstScalarInt(Object::ID id) const;
void EvalSpecConstantOp(InsnIterator insn); void EvalSpecConstantOp(InsnIterator insn);
void EvalSpecConstantUnaryOp(InsnIterator insn); void EvalSpecConstantUnaryOp(InsnIterator insn);
...@@ -1186,43 +1218,13 @@ namespace sw ...@@ -1186,43 +1218,13 @@ namespace sw
} }
private: private:
// The fields and accessors below are only accessible to SpirvShader // The phis are only accessible to SpirvShader as they are only used and
// as they are only used and exist between calls to // exist between calls to SpirvShader::emitProlog() and
// SpirvShader::emitProlog() and SpirvShader::emitEpilog(). // SpirvShader::emitEpilog().
friend class SpirvShader; friend class SpirvShader;
std::unordered_map<SpirvShader::Object::ID, Intermediate> intermediates;
std::unordered_map<SpirvShader::Object::ID, SIMD::Pointer> pointers;
std::unordered_map<SpirvShader::Object::ID, Variable> phis; std::unordered_map<SpirvShader::Object::ID, Variable> phis;
void createPointer(SpirvShader::Object::ID id, SIMD::Pointer ptr)
{
bool added = pointers.emplace(id, ptr).second;
ASSERT_MSG(added, "Pointer %d created twice", id.value());
}
Intermediate& createIntermediate(SpirvShader::Object::ID id, uint32_t size)
{
auto it = intermediates.emplace(std::piecewise_construct,
std::forward_as_tuple(id),
std::forward_as_tuple(size));
ASSERT_MSG(it.second, "Intermediate %d created twice", id.value());
return it.first->second;
}
Intermediate const& getIntermediate(SpirvShader::Object::ID id) const
{
auto it = intermediates.find(id);
ASSERT_MSG(it != intermediates.end(), "Unknown intermediate %d", id.value());
return it->second;
}
SIMD::Pointer const& getPointer(SpirvShader::Object::ID id) const
{
auto it = pointers.find(id);
ASSERT_MSG(it != pointers.end(), "Unknown pointer %d", id.value());
return it->second;
}
}; };
} }
......
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