Commit 9b62c5ea by Ben Clayton Committed by Ben Clayton

SpirvShader: Replace Intermediate::operator[] with typed getters.

Simplifies things throughout the cpp. Bug: b/128539387 Change-Id: I7abbe4731d82877204976d654859cba88d1a3047 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26531Tested-by: 's avatarBen Clayton <headlessclayton@gmail.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 093be46a
...@@ -697,7 +697,9 @@ namespace sw ...@@ -697,7 +697,9 @@ namespace sw
// The <base> operand is an intermediate value itself, ie produced by a previous OpAccessChain. // The <base> operand is an intermediate value itself, ie produced by a previous OpAccessChain.
// Start with its offset and build from there. // Start with its offset and build from there.
if (baseObject.kind == Object::Kind::Value) if (baseObject.kind == Object::Kind::Value)
dynamicOffset += As<SIMD::Int>(routine->getIntermediate(id)[0]); {
dynamicOffset += routine->getIntermediate(id).Int(0);
}
for (auto i = 0u; i < numIndexes; i++) for (auto i = 0u; i < numIndexes; i++)
{ {
...@@ -728,7 +730,7 @@ namespace sw ...@@ -728,7 +730,7 @@ namespace sw
if (obj.kind == Object::Kind::Constant) if (obj.kind == Object::Kind::Constant)
constantOffset += stride * GetConstantInt(indexIds[i]); constantOffset += stride * GetConstantInt(indexIds[i]);
else else
dynamicOffset += SIMD::Int(stride) * As<SIMD::Int>(routine->getIntermediate(indexIds[i])[0]); dynamicOffset += SIMD::Int(stride) * routine->getIntermediate(indexIds[i]).Int(0);
typeId = type.element; typeId = type.element;
break; break;
} }
...@@ -1216,7 +1218,7 @@ namespace sw ...@@ -1216,7 +1218,7 @@ namespace sw
if (pointer.kind == Object::Kind::Value) if (pointer.kind == Object::Kind::Value)
{ {
// Divergent offsets. // Divergent offsets.
auto offsets = As<SIMD::Int>(routine->getIntermediate(pointerId)[0]); auto offsets = routine->getIntermediate(pointerId).Int(0);
for (auto i = 0u; i < objectTy.sizeInComponents; i++) for (auto i = 0u; i < objectTy.sizeInComponents; i++)
{ {
// i wish i had a Float,Float,Float,Float constructor here.. // i wish i had a Float,Float,Float,Float constructor here..
...@@ -1297,7 +1299,7 @@ namespace sw ...@@ -1297,7 +1299,7 @@ namespace sw
if (pointer.kind == Object::Kind::Value) if (pointer.kind == Object::Kind::Value)
{ {
// Constant source data. Divergent offsets. // Constant source data. Divergent offsets.
auto offsets = As<SIMD::Int>(routine->getIntermediate(pointerId)[0]); auto offsets = routine->getIntermediate(pointerId).Int(0);
for (auto i = 0u; i < elementTy.sizeInComponents; i++) for (auto i = 0u; i < elementTy.sizeInComponents; i++)
{ {
for (int j = 0; j < SIMD::Width; j++) for (int j = 0; j < SIMD::Width; j++)
...@@ -1325,14 +1327,14 @@ namespace sw ...@@ -1325,14 +1327,14 @@ namespace sw
if (pointer.kind == Object::Kind::Value) if (pointer.kind == Object::Kind::Value)
{ {
// Intermediate source data. Divergent offsets. // Intermediate source data. Divergent offsets.
auto offsets = As<SIMD::Int>(routine->getIntermediate(pointerId)[0]); auto offsets = routine->getIntermediate(pointerId).Int(0);
for (auto i = 0u; i < elementTy.sizeInComponents; i++) for (auto i = 0u; i < elementTy.sizeInComponents; i++)
{ {
for (int j = 0; j < SIMD::Width; j++) for (int j = 0; j < SIMD::Width; j++)
{ {
Int offset = Int(i) + Extract(offsets, j); Int offset = Int(i) + Extract(offsets, j);
if (interleavedByLane) { offset = offset * SIMD::Width + j; } if (interleavedByLane) { offset = offset * SIMD::Width + j; }
ptrBase[offset] = Extract(src[i], j); ptrBase[offset] = Extract(src.Float(i), j);
} }
} }
} }
...@@ -1342,7 +1344,7 @@ namespace sw ...@@ -1342,7 +1344,7 @@ namespace sw
Pointer<SIMD::Float> dst = ptrBase; Pointer<SIMD::Float> dst = ptrBase;
for (auto i = 0u; i < elementTy.sizeInComponents; i++) for (auto i = 0u; i < elementTy.sizeInComponents; i++)
{ {
dst[i] = src[i]; dst[i] = src.Float(i);
} }
} }
else else
...@@ -1351,7 +1353,7 @@ namespace sw ...@@ -1351,7 +1353,7 @@ namespace sw
Pointer<SIMD::Float> dst = ptrBase; Pointer<SIMD::Float> dst = ptrBase;
for (auto i = 0u; i < elementTy.sizeInComponents; i++) for (auto i = 0u; i < elementTy.sizeInComponents; i++)
{ {
dst[i] = SIMD::Float(src[i]); dst[i] = SIMD::Float(src.Float(i));
} }
} }
} }
...@@ -1371,7 +1373,9 @@ namespace sw ...@@ -1371,7 +1373,9 @@ namespace sw
GenericValue srcObjectAccess(this, routine, srcObjectId); GenericValue srcObjectAccess(this, routine, srcObjectId);
for (auto j = 0u; j < srcObjectTy.sizeInComponents; j++) for (auto j = 0u; j < srcObjectTy.sizeInComponents; j++)
dst.emplace(offset++, srcObjectAccess[j]); {
dst.emplace(offset++, srcObjectAccess.Float(j));
}
} }
} }
...@@ -1390,17 +1394,17 @@ namespace sw ...@@ -1390,17 +1394,17 @@ namespace sw
// old components before // old components before
for (auto i = 0u; i < firstNewComponent; i++) for (auto i = 0u; i < firstNewComponent; i++)
{ {
dst.emplace(i, srcObjectAccess[i]); dst.emplace(i, srcObjectAccess.Float(i));
} }
// new part // new part
for (auto i = 0u; i < newPartObjectTy.sizeInComponents; i++) for (auto i = 0u; i < newPartObjectTy.sizeInComponents; i++)
{ {
dst.emplace(firstNewComponent + i, newPartObjectAccess[i]); dst.emplace(firstNewComponent + i, newPartObjectAccess.Float(i));
} }
// old components after // old components after
for (auto i = firstNewComponent + newPartObjectTy.sizeInComponents; i < type.sizeInComponents; i++) for (auto i = firstNewComponent + newPartObjectTy.sizeInComponents; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, srcObjectAccess[i]); dst.emplace(i, srcObjectAccess.Float(i));
} }
} }
...@@ -1415,7 +1419,7 @@ namespace sw ...@@ -1415,7 +1419,7 @@ namespace sw
GenericValue compositeObjectAccess(this, routine, insn.word(3)); GenericValue compositeObjectAccess(this, routine, insn.word(3));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, compositeObjectAccess[firstComponent + i]); dst.emplace(i, compositeObjectAccess.Float(firstComponent + i));
} }
} }
...@@ -1442,11 +1446,11 @@ namespace sw ...@@ -1442,11 +1446,11 @@ namespace sw
} }
else if (selector < firstHalfType.sizeInComponents) else if (selector < firstHalfType.sizeInComponents)
{ {
dst.emplace(i, firstHalfAccess[selector]); dst.emplace(i, firstHalfAccess.Float(selector));
} }
else else
{ {
dst.emplace(i, secondHalfAccess[selector - firstHalfType.sizeInComponents]); dst.emplace(i, secondHalfAccess.Float(selector - firstHalfType.sizeInComponents));
} }
} }
} }
...@@ -1455,12 +1459,12 @@ namespace sw ...@@ -1455,12 +1459,12 @@ namespace sw
{ {
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
auto srcLHS = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, routine, insn.word(3));
auto srcRHS = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, routine, insn.word(4));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, srcLHS[i] * srcRHS[0]); dst.emplace(i, lhs.Float(i) * rhs.Float(0));
} }
} }
...@@ -1472,40 +1476,38 @@ namespace sw ...@@ -1472,40 +1476,38 @@ namespace sw
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto val = src[i];
switch (insn.opcode()) switch (insn.opcode())
{ {
case spv::OpNot: case spv::OpNot:
case spv::OpLogicalNot: // logical not == bitwise not due to all-bits boolean representation case spv::OpLogicalNot: // logical not == bitwise not due to all-bits boolean representation
dst.emplace(i, ~As<SIMD::UInt>(val)); dst.emplace(i, ~src.UInt(i));
break; break;
case spv::OpSNegate: case spv::OpSNegate:
dst.emplace(i, -As<SIMD::Int>(val)); dst.emplace(i, -src.Int(i));
break; break;
case spv::OpFNegate: case spv::OpFNegate:
dst.emplace(i, -val); dst.emplace(i, -src.Float(i));
break; break;
case spv::OpConvertFToU: case spv::OpConvertFToU:
dst.emplace(i, SIMD::UInt(val)); dst.emplace(i, SIMD::UInt(src.Float(i)));
break; break;
case spv::OpConvertFToS: case spv::OpConvertFToS:
dst.emplace(i, SIMD::Int(val)); dst.emplace(i, SIMD::Int(src.Float(i)));
break; break;
case spv::OpConvertSToF: case spv::OpConvertSToF:
dst.emplace(i, SIMD::Float(As<SIMD::Int>(val))); dst.emplace(i, SIMD::Float(src.Int(i)));
break; break;
case spv::OpConvertUToF: case spv::OpConvertUToF:
dst.emplace(i, SIMD::Float(As<SIMD::UInt>(val))); dst.emplace(i, SIMD::Float(src.UInt(i)));
break; break;
case spv::OpBitcast: case spv::OpBitcast:
dst.emplace(i, val); dst.emplace(i, src.Float(i));
break; break;
case spv::OpIsInf: case spv::OpIsInf:
dst.emplace(i, IsInf(val)); dst.emplace(i, IsInf(src.Float(i)));
break; break;
case spv::OpIsNan: case spv::OpIsNan:
dst.emplace(i, IsNan(val)); dst.emplace(i, IsNan(src.Float(i)));
break; break;
default: default:
UNIMPLEMENTED("Unhandled unary operator %s", OpcodeName(insn.opcode()).c_str()); UNIMPLEMENTED("Unhandled unary operator %s", OpcodeName(insn.opcode()).c_str());
...@@ -1518,35 +1520,32 @@ namespace sw ...@@ -1518,35 +1520,32 @@ namespace sw
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
auto &lhsType = getType(getObject(insn.word(3)).type); auto &lhsType = getType(getObject(insn.word(3)).type);
auto srcLHS = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, routine, insn.word(3));
auto srcRHS = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, routine, insn.word(4));
for (auto i = 0u; i < lhsType.sizeInComponents; i++) for (auto i = 0u; i < lhsType.sizeInComponents; i++)
{ {
auto lhs = srcLHS[i];
auto rhs = srcRHS[i];
switch (insn.opcode()) switch (insn.opcode())
{ {
case spv::OpIAdd: case spv::OpIAdd:
dst.emplace(i, As<SIMD::Int>(lhs) + As<SIMD::Int>(rhs)); dst.emplace(i, lhs.Int(i) + rhs.Int(i));
break; break;
case spv::OpISub: case spv::OpISub:
dst.emplace(i, As<SIMD::Int>(lhs) - As<SIMD::Int>(rhs)); dst.emplace(i, lhs.Int(i) - rhs.Int(i));
break; break;
case spv::OpIMul: case spv::OpIMul:
dst.emplace(i, As<SIMD::Int>(lhs) * As<SIMD::Int>(rhs)); dst.emplace(i, lhs.Int(i) * rhs.Int(i));
break; break;
case spv::OpSDiv: case spv::OpSDiv:
dst.emplace(i, As<SIMD::Int>(lhs) / As<SIMD::Int>(rhs)); dst.emplace(i, lhs.Int(i) / rhs.Int(i));
break; break;
case spv::OpUDiv: case spv::OpUDiv:
dst.emplace(i, As<SIMD::UInt>(lhs) / As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) / rhs.UInt(i));
break; break;
case spv::OpSMod: case spv::OpSMod:
{ {
auto a = As<SIMD::Int>(lhs); auto a = lhs.Int(i);
auto b = As<SIMD::Int>(rhs); auto b = rhs.Int(i);
auto mod = a % b; auto mod = a % b;
// If a and b have opposite signs, the remainder operation takes // If a and b have opposite signs, the remainder operation takes
// the sign from a but OpSMod is supposed to take the sign of b. // the sign from a but OpSMod is supposed to take the sign of b.
...@@ -1560,118 +1559,118 @@ namespace sw ...@@ -1560,118 +1559,118 @@ namespace sw
break; break;
} }
case spv::OpUMod: case spv::OpUMod:
dst.emplace(i, As<SIMD::UInt>(lhs) % As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) % rhs.UInt(i));
break; break;
case spv::OpIEqual: case spv::OpIEqual:
case spv::OpLogicalEqual: case spv::OpLogicalEqual:
dst.emplace(i, CmpEQ(As<SIMD::Int>(lhs), As<SIMD::Int>(rhs))); dst.emplace(i, CmpEQ(lhs.Int(i), rhs.Int(i)));
break; break;
case spv::OpINotEqual: case spv::OpINotEqual:
case spv::OpLogicalNotEqual: case spv::OpLogicalNotEqual:
dst.emplace(i, CmpNEQ(As<SIMD::Int>(lhs), As<SIMD::Int>(rhs))); dst.emplace(i, CmpNEQ(lhs.Int(i), rhs.Int(i)));
break; break;
case spv::OpUGreaterThan: case spv::OpUGreaterThan:
dst.emplace(i, CmpGT(As<SIMD::UInt>(lhs), As<SIMD::UInt>(rhs))); dst.emplace(i, CmpGT(lhs.UInt(i), rhs.UInt(i)));
break; break;
case spv::OpSGreaterThan: case spv::OpSGreaterThan:
dst.emplace(i, CmpGT(As<SIMD::Int>(lhs), As<SIMD::Int>(rhs))); dst.emplace(i, CmpGT(lhs.Int(i), rhs.Int(i)));
break; break;
case spv::OpUGreaterThanEqual: case spv::OpUGreaterThanEqual:
dst.emplace(i, CmpGE(As<SIMD::UInt>(lhs), As<SIMD::UInt>(rhs))); dst.emplace(i, CmpGE(lhs.UInt(i), rhs.UInt(i)));
break; break;
case spv::OpSGreaterThanEqual: case spv::OpSGreaterThanEqual:
dst.emplace(i, CmpGE(As<SIMD::Int>(lhs), As<SIMD::Int>(rhs))); dst.emplace(i, CmpGE(lhs.Int(i), rhs.Int(i)));
break; break;
case spv::OpULessThan: case spv::OpULessThan:
dst.emplace(i, CmpLT(As<SIMD::UInt>(lhs), As<SIMD::UInt>(rhs))); dst.emplace(i, CmpLT(lhs.UInt(i), rhs.UInt(i)));
break; break;
case spv::OpSLessThan: case spv::OpSLessThan:
dst.emplace(i, CmpLT(As<SIMD::Int>(lhs), As<SIMD::Int>(rhs))); dst.emplace(i, CmpLT(lhs.Int(i), rhs.Int(i)));
break; break;
case spv::OpULessThanEqual: case spv::OpULessThanEqual:
dst.emplace(i, CmpLE(As<SIMD::UInt>(lhs), As<SIMD::UInt>(rhs))); dst.emplace(i, CmpLE(lhs.UInt(i), rhs.UInt(i)));
break; break;
case spv::OpSLessThanEqual: case spv::OpSLessThanEqual:
dst.emplace(i, CmpLE(As<SIMD::Int>(lhs), As<SIMD::Int>(rhs))); dst.emplace(i, CmpLE(lhs.Int(i), rhs.Int(i)));
break; break;
case spv::OpFAdd: case spv::OpFAdd:
dst.emplace(i, lhs + rhs); dst.emplace(i, lhs.Float(i) + rhs.Float(i));
break; break;
case spv::OpFSub: case spv::OpFSub:
dst.emplace(i, lhs - rhs); dst.emplace(i, lhs.Float(i) - rhs.Float(i));
break; break;
case spv::OpFMul: case spv::OpFMul:
dst.emplace(i, lhs * rhs); dst.emplace(i, lhs.Float(i) * rhs.Float(i));
break; break;
case spv::OpFDiv: case spv::OpFDiv:
dst.emplace(i, lhs / rhs); dst.emplace(i, lhs.Float(i) / rhs.Float(i));
break; break;
case spv::OpFOrdEqual: case spv::OpFOrdEqual:
dst.emplace(i, CmpEQ(lhs, rhs)); dst.emplace(i, CmpEQ(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFUnordEqual: case spv::OpFUnordEqual:
dst.emplace(i, CmpUEQ(lhs, rhs)); dst.emplace(i, CmpUEQ(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFOrdNotEqual: case spv::OpFOrdNotEqual:
dst.emplace(i, CmpNEQ(lhs, rhs)); dst.emplace(i, CmpNEQ(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFUnordNotEqual: case spv::OpFUnordNotEqual:
dst.emplace(i, CmpUNEQ(lhs, rhs)); dst.emplace(i, CmpUNEQ(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFOrdLessThan: case spv::OpFOrdLessThan:
dst.emplace(i, CmpLT(lhs, rhs)); dst.emplace(i, CmpLT(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFUnordLessThan: case spv::OpFUnordLessThan:
dst.emplace(i, CmpULT(lhs, rhs)); dst.emplace(i, CmpULT(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFOrdGreaterThan: case spv::OpFOrdGreaterThan:
dst.emplace(i, CmpGT(lhs, rhs)); dst.emplace(i, CmpGT(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFUnordGreaterThan: case spv::OpFUnordGreaterThan:
dst.emplace(i, CmpUGT(lhs, rhs)); dst.emplace(i, CmpUGT(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFOrdLessThanEqual: case spv::OpFOrdLessThanEqual:
dst.emplace(i, CmpLE(lhs, rhs)); dst.emplace(i, CmpLE(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFUnordLessThanEqual: case spv::OpFUnordLessThanEqual:
dst.emplace(i, CmpULE(lhs, rhs)); dst.emplace(i, CmpULE(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFOrdGreaterThanEqual: case spv::OpFOrdGreaterThanEqual:
dst.emplace(i, CmpGE(lhs, rhs)); dst.emplace(i, CmpGE(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpFUnordGreaterThanEqual: case spv::OpFUnordGreaterThanEqual:
dst.emplace(i, CmpUGE(lhs, rhs)); dst.emplace(i, CmpUGE(lhs.Float(i), rhs.Float(i)));
break; break;
case spv::OpShiftRightLogical: case spv::OpShiftRightLogical:
dst.emplace(i, As<SIMD::UInt>(lhs) >> As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) >> rhs.UInt(i));
break; break;
case spv::OpShiftRightArithmetic: case spv::OpShiftRightArithmetic:
dst.emplace(i, As<SIMD::Int>(lhs) >> As<SIMD::Int>(rhs)); dst.emplace(i, lhs.Int(i) >> rhs.Int(i));
break; break;
case spv::OpShiftLeftLogical: case spv::OpShiftLeftLogical:
dst.emplace(i, As<SIMD::UInt>(lhs) << As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) << rhs.UInt(i));
break; break;
case spv::OpBitwiseOr: case spv::OpBitwiseOr:
case spv::OpLogicalOr: case spv::OpLogicalOr:
dst.emplace(i, As<SIMD::UInt>(lhs) | As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) | rhs.UInt(i));
break; break;
case spv::OpBitwiseXor: case spv::OpBitwiseXor:
dst.emplace(i, As<SIMD::UInt>(lhs) ^ As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) ^ rhs.UInt(i));
break; break;
case spv::OpBitwiseAnd: case spv::OpBitwiseAnd:
case spv::OpLogicalAnd: case spv::OpLogicalAnd:
dst.emplace(i, As<SIMD::UInt>(lhs) & As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) & rhs.UInt(i));
break; break;
case spv::OpSMulExtended: case spv::OpSMulExtended:
// Extended ops: result is a structure containing two members of the same type as lhs & rhs. // Extended ops: result is a structure containing two members of the same type as lhs & rhs.
// In our flat view then, component i is the i'th component of the first member; // In our flat view then, component i is the i'th component of the first member;
// component i + N is the i'th component of the second member. // component i + N is the i'th component of the second member.
dst.emplace(i, As<SIMD::Int>(lhs) * As<SIMD::Int>(rhs)); dst.emplace(i, lhs.Int(i) * rhs.Int(i));
dst.emplace(i + lhsType.sizeInComponents, MulHigh(As<SIMD::Int>(lhs), As<SIMD::Int>(rhs))); dst.emplace(i + lhsType.sizeInComponents, MulHigh(lhs.Int(i), rhs.Int(i)));
break; break;
case spv::OpUMulExtended: case spv::OpUMulExtended:
dst.emplace(i, As<SIMD::UInt>(lhs) * As<SIMD::UInt>(rhs)); dst.emplace(i, lhs.UInt(i) * rhs.UInt(i));
dst.emplace(i + lhsType.sizeInComponents, MulHigh(As<SIMD::UInt>(lhs), As<SIMD::UInt>(rhs))); dst.emplace(i + lhsType.sizeInComponents, MulHigh(lhs.UInt(i), rhs.UInt(i)));
break; break;
default: default:
UNIMPLEMENTED("Unhandled binary operator %s", OpcodeName(insn.opcode()).c_str()); UNIMPLEMENTED("Unhandled binary operator %s", OpcodeName(insn.opcode()).c_str());
...@@ -1685,28 +1684,23 @@ namespace sw ...@@ -1685,28 +1684,23 @@ namespace sw
assert(type.sizeInComponents == 1); assert(type.sizeInComponents == 1);
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
auto &lhsType = getType(getObject(insn.word(3)).type); auto &lhsType = getType(getObject(insn.word(3)).type);
auto srcLHS = GenericValue(this, routine, insn.word(3)); auto lhs = GenericValue(this, routine, insn.word(3));
auto srcRHS = GenericValue(this, routine, insn.word(4)); auto rhs = GenericValue(this, routine, insn.word(4));
SIMD::Float result = Dot(lhsType.sizeInComponents, srcLHS, srcRHS); dst.emplace(0, Dot(lhsType.sizeInComponents, lhs, rhs));
dst.emplace(0, result);
} }
void SpirvShader::EmitSelect(InsnIterator insn, SpirvRoutine *routine) const void SpirvShader::EmitSelect(InsnIterator insn, SpirvRoutine *routine) const
{ {
auto &type = getType(insn.word(1)); auto &type = getType(insn.word(1));
auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents); auto &dst = routine->createIntermediate(insn.word(2), type.sizeInComponents);
auto srcCond = GenericValue(this, routine, insn.word(3)); auto cond = GenericValue(this, routine, insn.word(3));
auto srcLHS = GenericValue(this, routine, insn.word(4)); auto lhs = GenericValue(this, routine, insn.word(4));
auto srcRHS = GenericValue(this, routine, insn.word(5)); auto rhs = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto cond = As<SIMD::Int>(srcCond[i]); dst.emplace(i, (cond.Int(i) & lhs.Int(i)) | (~cond.Int(i) & rhs.Int(i))); // FIXME: IfThenElse()
auto lhs = srcLHS[i];
auto rhs = srcRHS[i];
auto out = (cond & As<Int4>(lhs)) | (~cond & As<Int4>(rhs)); // FIXME: IfThenElse()
dst.emplace(i, out);
} }
} }
...@@ -1723,7 +1717,7 @@ namespace sw ...@@ -1723,7 +1717,7 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Abs(src[i])); dst.emplace(i, Abs(src.Float(i)));
} }
break; break;
} }
...@@ -1732,7 +1726,7 @@ namespace sw ...@@ -1732,7 +1726,7 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Abs(As<SIMD::Int>(src[i]))); dst.emplace(i, Abs(src.Int(i)));
} }
break; break;
} }
...@@ -1740,9 +1734,9 @@ namespace sw ...@@ -1740,9 +1734,9 @@ namespace sw
{ {
auto lhs = GenericValue(this, routine, insn.word(5)); auto lhs = GenericValue(this, routine, insn.word(5));
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, routine, insn.word(6));
dst.emplace(0, lhs[1] * rhs[2] - rhs[1] * lhs[2]); dst.emplace(0, lhs.Float(1) * rhs.Float(2) - rhs.Float(1) * lhs.Float(2));
dst.emplace(1, lhs[2] * rhs[0] - rhs[2] * lhs[0]); dst.emplace(1, lhs.Float(2) * rhs.Float(0) - rhs.Float(2) * lhs.Float(0));
dst.emplace(2, lhs[0] * rhs[1] - rhs[0] * lhs[1]); dst.emplace(2, lhs.Float(0) * rhs.Float(1) - rhs.Float(0) * lhs.Float(1));
break; break;
} }
case GLSLstd450Floor: case GLSLstd450Floor:
...@@ -1750,7 +1744,7 @@ namespace sw ...@@ -1750,7 +1744,7 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Floor(src[i])); dst.emplace(i, Floor(src.Float(i)));
} }
break; break;
} }
...@@ -1759,7 +1753,7 @@ namespace sw ...@@ -1759,7 +1753,7 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Trunc(src[i])); dst.emplace(i, Trunc(src.Float(i)));
} }
break; break;
} }
...@@ -1768,7 +1762,7 @@ namespace sw ...@@ -1768,7 +1762,7 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Ceil(src[i])); dst.emplace(i, Ceil(src.Float(i)));
} }
break; break;
} }
...@@ -1777,7 +1771,7 @@ namespace sw ...@@ -1777,7 +1771,7 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Frac(src[i])); dst.emplace(i, Frac(src.Float(i)));
} }
break; break;
} }
...@@ -1786,7 +1780,7 @@ namespace sw ...@@ -1786,7 +1780,7 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Round(src[i])); dst.emplace(i, Round(src.Float(i)));
} }
break; break;
} }
...@@ -1795,10 +1789,10 @@ namespace sw ...@@ -1795,10 +1789,10 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto x = Round(src[i]); auto x = Round(src.Float(i));
// dst = round(src) + ((round(src) < src) * 2 - 1) * (fract(src) == 0.5) * isOdd(round(src)); // dst = round(src) + ((round(src) < src) * 2 - 1) * (fract(src) == 0.5) * isOdd(round(src));
dst.emplace(i, x + ((SIMD::Float(CmpLT(x, src[i]) & SIMD::Int(1)) * SIMD::Float(2.0f)) - SIMD::Float(1.0f)) * dst.emplace(i, x + ((SIMD::Float(CmpLT(x, src.Float(i)) & SIMD::Int(1)) * SIMD::Float(2.0f)) - SIMD::Float(1.0f)) *
SIMD::Float(CmpEQ(Frac(src[i]), SIMD::Float(0.5f)) & SIMD::Int(1)) * SIMD::Float(Int4(x) & SIMD::Int(1))); SIMD::Float(CmpEQ(Frac(src.Float(i)), SIMD::Float(0.5f)) & SIMD::Int(1)) * SIMD::Float(Int4(x) & SIMD::Int(1)));
} }
break; break;
} }
...@@ -1808,7 +1802,7 @@ namespace sw ...@@ -1808,7 +1802,7 @@ namespace sw
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, routine, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Min(lhs[i], rhs[i])); dst.emplace(i, Min(lhs.Float(i), rhs.Float(i)));
} }
break; break;
} }
...@@ -1818,7 +1812,7 @@ namespace sw ...@@ -1818,7 +1812,7 @@ namespace sw
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, routine, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Max(lhs[i], rhs[i])); dst.emplace(i, Max(lhs.Float(i), rhs.Float(i)));
} }
break; break;
} }
...@@ -1828,7 +1822,7 @@ namespace sw ...@@ -1828,7 +1822,7 @@ namespace sw
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, routine, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Min(As<SIMD::Int>(lhs[i]), As<SIMD::Int>(rhs[i]))); dst.emplace(i, Min(lhs.Int(i), rhs.Int(i)));
} }
break; break;
} }
...@@ -1838,7 +1832,7 @@ namespace sw ...@@ -1838,7 +1832,7 @@ namespace sw
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, routine, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Max(As<SIMD::Int>(lhs[i]), As<SIMD::Int>(rhs[i]))); dst.emplace(i, Max(lhs.Int(i), rhs.Int(i)));
} }
break; break;
} }
...@@ -1848,7 +1842,7 @@ namespace sw ...@@ -1848,7 +1842,7 @@ namespace sw
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, routine, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Min(As<SIMD::UInt>(lhs[i]), As<SIMD::UInt>(rhs[i]))); dst.emplace(i, Min(lhs.UInt(i), rhs.UInt(i)));
} }
break; break;
} }
...@@ -1858,7 +1852,7 @@ namespace sw ...@@ -1858,7 +1852,7 @@ namespace sw
auto rhs = GenericValue(this, routine, insn.word(6)); auto rhs = GenericValue(this, routine, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Max(As<SIMD::UInt>(lhs[i]), As<SIMD::UInt>(rhs[i]))); dst.emplace(i, Max(lhs.UInt(i), rhs.UInt(i)));
} }
break; break;
} }
...@@ -1868,7 +1862,7 @@ namespace sw ...@@ -1868,7 +1862,7 @@ namespace sw
auto x = GenericValue(this, routine, insn.word(6)); auto x = GenericValue(this, routine, insn.word(6));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, CmpNLT(x[i], edge[i]) & As<SIMD::Int>(SIMD::Float(1.0f))); dst.emplace(i, CmpNLT(x.Float(i), edge.Float(i)) & As<SIMD::Int>(SIMD::Float(1.0f)));
} }
break; break;
} }
...@@ -1879,7 +1873,8 @@ namespace sw ...@@ -1879,7 +1873,8 @@ namespace sw
auto x = GenericValue(this, routine, insn.word(7)); auto x = GenericValue(this, routine, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto tx = Min(Max((x[i] - edge0[i]) / (edge1[i] - edge0[i]), SIMD::Float(0.0f)), SIMD::Float(1.0f)); auto tx = Min(Max((x.Float(i) - edge0.Float(i)) /
(edge1.Float(i) - edge0.Float(i)), SIMD::Float(0.0f)), SIMD::Float(1.0f));
dst.emplace(i, tx * tx * (Float4(3.0f) - Float4(2.0f) * tx)); dst.emplace(i, tx * tx * (Float4(3.0f) - Float4(2.0f) * tx));
} }
break; break;
...@@ -1891,7 +1886,7 @@ namespace sw ...@@ -1891,7 +1886,7 @@ namespace sw
auto a = GenericValue(this, routine, insn.word(7)); auto a = GenericValue(this, routine, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, a[i] * (y[i] - x[i]) + x[i]); dst.emplace(i, a.Float(i) * (y.Float(i) - x.Float(i)) + x.Float(i));
} }
break; break;
} }
...@@ -1902,7 +1897,7 @@ namespace sw ...@@ -1902,7 +1897,7 @@ namespace sw
auto maxVal = GenericValue(this, routine, insn.word(7)); auto maxVal = GenericValue(this, routine, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Min(Max(x[i], minVal[i]), maxVal[i])); dst.emplace(i, Min(Max(x.Float(i), minVal.Float(i)), maxVal.Float(i)));
} }
break; break;
} }
...@@ -1913,7 +1908,7 @@ namespace sw ...@@ -1913,7 +1908,7 @@ namespace sw
auto maxVal = GenericValue(this, routine, insn.word(7)); auto maxVal = GenericValue(this, routine, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Min(Max(As<SIMD::Int>(x[i]), As<SIMD::Int>(minVal[i])), As<SIMD::Int>(maxVal[i]))); dst.emplace(i, Min(Max(x.Int(i), minVal.Int(i)), maxVal.Int(i)));
} }
break; break;
} }
...@@ -1924,7 +1919,7 @@ namespace sw ...@@ -1924,7 +1919,7 @@ namespace sw
auto maxVal = GenericValue(this, routine, insn.word(7)); auto maxVal = GenericValue(this, routine, insn.word(7));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, Min(Max(As<SIMD::UInt>(x[i]), As<SIMD::UInt>(minVal[i])), As<SIMD::UInt>(maxVal[i]))); dst.emplace(i, Min(Max(x.UInt(i), minVal.UInt(i)), maxVal.UInt(i)));
} }
break; break;
} }
...@@ -1933,8 +1928,8 @@ namespace sw ...@@ -1933,8 +1928,8 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, 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[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));
auto pos = As<SIMD::Int>(CmpNLE(src[i], SIMD::Float(+0.0f))) & As<SIMD::Int>(SIMD::Float(1.0f)); auto pos = As<SIMD::Int>(CmpNLE(src.Float(i), SIMD::Float(+0.0f))) & As<SIMD::Int>(SIMD::Float(1.0f));
dst.emplace(i, neg | pos); dst.emplace(i, neg | pos);
} }
break; break;
...@@ -1944,8 +1939,8 @@ namespace sw ...@@ -1944,8 +1939,8 @@ namespace sw
auto src = GenericValue(this, routine, insn.word(5)); auto src = GenericValue(this, routine, insn.word(5));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
auto neg = CmpLT(As<SIMD::Int>(src[i]), SIMD::Int(0)) & SIMD::Int(-1); auto neg = CmpLT(src.Int(i), SIMD::Int(0)) & SIMD::Int(-1);
auto pos = CmpNLE(As<SIMD::Int>(src[i]), SIMD::Int(0)) & SIMD::Int(1); auto pos = CmpNLE(src.Int(i), SIMD::Int(0)) & SIMD::Int(1);
dst.emplace(i, neg | pos); dst.emplace(i, neg | pos);
} }
break; break;
...@@ -1959,7 +1954,7 @@ namespace sw ...@@ -1959,7 +1954,7 @@ namespace sw
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, I[i] - SIMD::Float(2.0f) * d * N[i]); dst.emplace(i, I.Float(i) - SIMD::Float(2.0f) * d * N.Float(i));
} }
break; break;
} }
...@@ -1970,13 +1965,13 @@ namespace sw ...@@ -1970,13 +1965,13 @@ namespace sw
auto eta = GenericValue(this, routine, insn.word(7)); auto eta = GenericValue(this, routine, 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[0] * eta[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);
SIMD::Int pos = CmpNLT(k, SIMD::Float(0.0f)); SIMD::Int pos = CmpNLT(k, SIMD::Float(0.0f));
SIMD::Float t = (eta[0] * d + Sqrt(k)); SIMD::Float t = (eta.Float(0) * d + Sqrt(k));
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, As<SIMD::Float>(pos & As<SIMD::Int>(eta[0] * I[i] - t * N[i]))); dst.emplace(i, pos & As<SIMD::Int>(eta.Float(0) * I.Float(i) - t * N.Float(i)));
} }
break; break;
} }
...@@ -1991,7 +1986,8 @@ namespace sw ...@@ -1991,7 +1986,8 @@ namespace sw
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, As<SIMD::Float>((neg & As<SIMD::Int>(N[i])) | (~neg & As<SIMD::Int>(-N[i])))); auto n = N.Float(i);
dst.emplace(i, (neg & As<SIMD::Int>(n)) | (~neg & As<SIMD::Int>(-n)));
} }
break; break;
} }
...@@ -2011,7 +2007,7 @@ namespace sw ...@@ -2011,7 +2007,7 @@ namespace sw
for (auto i = 0u; i < type.sizeInComponents; i++) for (auto i = 0u; i < type.sizeInComponents; i++)
{ {
dst.emplace(i, invLength * x[i]); dst.emplace(i, invLength * x.Float(i));
} }
break; break;
} }
...@@ -2022,11 +2018,11 @@ namespace sw ...@@ -2022,11 +2018,11 @@ namespace sw
auto p0Type = getType(getObject(insn.word(5)).type); auto p0Type = getType(getObject(insn.word(5)).type);
// sqrt(dot(p0-p1, p0-p1)) // sqrt(dot(p0-p1, p0-p1))
SIMD::Float d = (p0[0] - p1[0]) * (p0[0] - p1[0]); SIMD::Float d = (p0.Float(0) - p1.Float(0)) * (p0.Float(0) - p1.Float(0));
for (auto i = 1u; i < p0Type.sizeInComponents; i++) for (auto i = 1u; i < p0Type.sizeInComponents; i++)
{ {
d += (p0[i] - p1[i]) * (p0[i] - p1[i]); d += (p0.Float(i) - p1.Float(i)) * (p0.Float(i) - p1.Float(i));
} }
dst.emplace(0, Sqrt(d)); dst.emplace(0, Sqrt(d));
...@@ -2039,11 +2035,11 @@ namespace sw ...@@ -2039,11 +2035,11 @@ namespace sw
SIMD::Float SpirvShader::Dot(unsigned numComponents, GenericValue const & x, GenericValue const & y) const SIMD::Float SpirvShader::Dot(unsigned numComponents, GenericValue const & x, GenericValue const & y) const
{ {
SIMD::Float d = x[0] * y[0]; SIMD::Float d = x.Float(0) * y.Float(0);
for (auto i = 1u; i < numComponents; i++) for (auto i = 1u; i < numComponents; i++)
{ {
d += x[i] * y[i]; d += x.Float(i) * y.Float(i);
} }
return d; return d;
...@@ -2057,11 +2053,11 @@ namespace sw ...@@ -2057,11 +2053,11 @@ namespace sw
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, routine, insn.word(3));
SIMD::UInt result = As<SIMD::UInt>(src[0]); SIMD::UInt result = src.UInt(0);
for (auto i = 1u; i < srcType.sizeInComponents; i++) for (auto i = 1u; i < srcType.sizeInComponents; i++)
{ {
result |= As<SIMD::UInt>(src[i]); result |= src.UInt(i);
} }
dst.emplace(0, result); dst.emplace(0, result);
...@@ -2075,11 +2071,11 @@ namespace sw ...@@ -2075,11 +2071,11 @@ namespace sw
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, routine, insn.word(3));
SIMD::UInt result = As<SIMD::UInt>(src[0]); SIMD::UInt result = src.UInt(0);
for (auto i = 1u; i < srcType.sizeInComponents; i++) for (auto i = 1u; i < srcType.sizeInComponents; i++)
{ {
result &= As<SIMD::UInt>(src[i]); result &= src.UInt(i);
} }
dst.emplace(0, result); dst.emplace(0, result);
......
...@@ -98,13 +98,16 @@ namespace sw ...@@ -98,13 +98,16 @@ namespace sw
void emplace(uint32_t n, const RValue<SIMD::Int>& value) { emplace(n, As<SIMD::Float>(value)); } void emplace(uint32_t n, const RValue<SIMD::Int>& value) { emplace(n, As<SIMD::Float>(value)); }
void emplace(uint32_t n, const RValue<SIMD::UInt>& value) { emplace(n, As<SIMD::Float>(value)); } void emplace(uint32_t n, const RValue<SIMD::UInt>& value) { emplace(n, As<SIMD::Float>(value)); }
Scalar const & operator[](uint32_t n) const // Value retrieval functions.
RValue<SIMD::Float> Float(uint32_t i) const
{ {
ASSERT(n < size); ASSERT(i < size);
auto scalar = reinterpret_cast<Scalar const *>(&contents[n]); auto scalar = reinterpret_cast<Scalar const *>(&contents[i]);
ASSERT(scalar->value != nullptr); ASSERT(scalar->value != nullptr);
return *scalar; return *scalar;
} }
RValue<SIMD::Int> Int(uint32_t i) const { return As<SIMD::Int>(Float(i)); }
RValue<SIMD::UInt> UInt(uint32_t i) const { return As<SIMD::UInt>(Float(i)); }
// No copy/move construction or assignment // No copy/move construction or assignment
Intermediate(Intermediate const &) = delete; Intermediate(Intermediate const &) = delete;
...@@ -536,14 +539,25 @@ namespace sw ...@@ -536,14 +539,25 @@ namespace sw
obj(shader->getObject(objId)), obj(shader->getObject(objId)),
intermediate(obj.kind == SpirvShader::Object::Kind::Value ? &routine->getIntermediate(objId) : nullptr) {} intermediate(obj.kind == SpirvShader::Object::Kind::Value ? &routine->getIntermediate(objId) : nullptr) {}
RValue<SIMD::Float> operator[](uint32_t i) const RValue<SIMD::Float> Float(uint32_t i) const
{ {
if (intermediate) if (intermediate != nullptr)
return (*intermediate)[i]; {
return intermediate->Float(i);
}
auto constantValue = reinterpret_cast<float *>(obj.constantValue.get()); auto constantValue = reinterpret_cast<float *>(obj.constantValue.get());
return RValue<SIMD::Float>(constantValue[i]); return RValue<SIMD::Float>(constantValue[i]);
} }
RValue<SIMD::Int> Int(uint32_t i) const
{
return As<SIMD::Int>(Float(i));
}
RValue<SIMD::UInt> UInt(uint32_t i) const
{
return As<SIMD::UInt>(Float(i));
}
}; };
} }
......
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