Commit e9f8f5b1 by Chris Forbes

Implement some common forms of OpLoad

Bug: b/124388146 Change-Id: I79b4c3bc59631332f4748394a166612ad5d975de Reviewed-on: https://swiftshader-review.googlesource.com/c/24600Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent b8fb08a7
...@@ -166,6 +166,7 @@ namespace sw ...@@ -166,6 +166,7 @@ namespace sw
// OpVariable's "size" is the size of the allocation required (the size of the pointee) // OpVariable's "size" is the size of the allocation required (the size of the pointee)
object.sizeInComponents = pointeeType.sizeInComponents; object.sizeInComponents = pointeeType.sizeInComponents;
object.isBuiltInBlock = type.isBuiltInBlock; object.isBuiltInBlock = type.isBuiltInBlock;
object.pointerBase = insn.word(2); // base is itself
// Register builtins // Register builtins
...@@ -233,7 +234,7 @@ namespace sw ...@@ -233,7 +234,7 @@ namespace sw
// interior ptr has two parts: // interior ptr has two parts:
// - logical base ptr, common across all lanes and known at compile time // - logical base ptr, common across all lanes and known at compile time
// - per-lane offset // - per-lane offset
object.pointerBase = insn.word(3); object.pointerBase = getObject(insn.word(3)).pointerBase;
} }
break; break;
} }
...@@ -597,13 +598,12 @@ namespace sw ...@@ -597,13 +598,12 @@ namespace sw
if (object.kind != Object::Kind::InterfaceVariable && object.sizeInComponents > 0) if (object.kind != Object::Kind::InterfaceVariable && object.sizeInComponents > 0)
{ {
// any variable not in a location-oriented interface // any variable not in a location-oriented interface
routine->lvalues.emplace(insn.word(2), std::unique_ptr<Array<Float4>>( routine->createLvalue(insn.word(2), object.sizeInComponents);
new Array<Float4>(object.sizeInComponents)));
} }
break; break;
} }
default: default:
printf("emitEarly: ignoring opcode %d\n", insn.opcode()); // Nothing else produces interface variables, so can all be safely ignored.
break; break;
} }
} }
...@@ -611,12 +611,55 @@ namespace sw ...@@ -611,12 +611,55 @@ namespace sw
void SpirvShader::emit(SpirvRoutine *routine) const void SpirvShader::emit(SpirvRoutine *routine) const
{ {
(void) routine;
for (auto insn : *this) for (auto insn : *this)
{ {
switch (insn.opcode()) switch (insn.opcode())
{ {
case spv::OpLoad:
{
auto &object = getObject(insn.word(2));
auto &type = getType(insn.word(1));
auto &pointer = getObject(insn.word(3));
routine->createLvalue(insn.word(2), type.sizeInComponents); // TODO: this should be an ssavalue!
auto &pointerBase = getObject(pointer.pointerBase);
if (pointerBase.kind == Object::Kind::InterfaceVariable)
{
UNIMPLEMENTED("Location-based load not yet implemented");
}
if (pointerBase.storageClass == spv::StorageClassImage ||
pointerBase.storageClass == spv::StorageClassUniform ||
pointerBase.storageClass == spv::StorageClassUniformConstant)
{
UNIMPLEMENTED("Descriptor-backed load not yet implemented");
}
SpirvRoutine::Value& ptrBase = *(routine->lvalues)[pointer.pointerBase];
auto & dst = *(routine->lvalues)[insn.word(2)];
if (pointer.kind == Object::Kind::Value)
{
auto offsets = As<Int4>(*(routine->lvalues)[insn.word(3)]);
for (auto i = 0u; i < object.sizeInComponents; i++)
{
// i wish i had a Float,Float,Float,Float constructor here..
Float4 v;
for (int j = 0; j < 4; j++)
v = Insert(v, Extract(ptrBase[Int(i) + Extract(offsets, j)], j), j);
dst[i] = v;
}
}
else
{
// no divergent offsets to worry about
for (auto i = 0u; i < object.sizeInComponents; i++)
{
dst[i] = ptrBase[i];
}
}
break;
}
default: default:
printf("emit: ignoring opcode %d\n", insn.opcode()); printf("emit: ignoring opcode %d\n", insn.opcode());
break; break;
......
...@@ -33,9 +33,15 @@ namespace sw ...@@ -33,9 +33,15 @@ namespace sw
class SpirvRoutine class SpirvRoutine
{ {
public: public:
std::unordered_map<uint32_t, std::unique_ptr<Array<Float4>>> lvalues; using Value = Array<Float4>;
std::unique_ptr<Array<Float4>> inputs = std::unique_ptr<Array<Float4>>(new Array<Float4>(MAX_INTERFACE_COMPONENTS)); std::unordered_map<uint32_t, std::unique_ptr<Value>> lvalues;
std::unique_ptr<Array<Float4>> outputs = std::unique_ptr<Array<Float4>>(new Array<Float4>(MAX_INTERFACE_COMPONENTS)); std::unique_ptr<Value> inputs = std::unique_ptr<Value>(new Value(MAX_INTERFACE_COMPONENTS));
std::unique_ptr<Value> outputs = std::unique_ptr<Value>(new Value(MAX_INTERFACE_COMPONENTS));
void createLvalue(uint32_t id, uint32_t size)
{
lvalues.emplace(id, std::unique_ptr<Value>(new Value(size)));
}
}; };
class SpirvShader class SpirvShader
......
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