Commit d5aed490 by Chris Forbes

Start building up code generation

- Introduce (perhaps poorly named) SpirvRoutine type for routine-emit-time state (reactor objects). - Add SpirvShader::emitEarly (intended for definitions that are needed in shader preamble) and SpirvShader::emit (intended for general actual code generation) passes. - Wire up new passes to VertexProgram/VertexRoutine Change-Id: Iac42eae7dc04adfd4163fd74ba407b613551d14e Bug: b/120799499 Reviewed-on: https://swiftshader-review.googlesource.com/c/24375Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 2bb0864b
......@@ -517,4 +517,47 @@ namespace sw
assert(getType(insn.word(1)).definition.opcode() == spv::OpTypeInt);
return insn.word(3);
}
// emit-time
void SpirvShader::emitEarly(SpirvRoutine *routine) const
{
for (auto insn : *this)
{
switch (insn.opcode())
{
case spv::OpVariable:
{
auto &object = getObject(insn.word(2));
// Want to exclude: location-oriented interface variables; special things that consume zero slots.
// TODO: what to do about zero-slot objects?
if (object.kind != Object::Kind::InterfaceVariable && object.sizeInComponents > 0)
{
// any variable not in a location-oriented interface
routine->lvalues.emplace(insn.word(2), std::unique_ptr<Array<Float4>>(
new Array<Float4>(object.sizeInComponents)));
}
break;
}
default:
printf("emitEarly: ignoring opcode %d\n", insn.opcode());
break;
}
}
}
void SpirvShader::emit(SpirvRoutine *routine) const
{
(void) routine;
for (auto insn : *this)
{
switch (insn.opcode())
{
default:
printf("emit: ignoring opcode %d\n", insn.opcode());
break;
}
}
}
}
......@@ -17,16 +17,24 @@
#include "System/Types.hpp"
#include "Vulkan/VkDebug.hpp"
#include "ShaderCore.hpp"
#include <string>
#include <vector>
#include <unordered_map>
#include <cstdint>
#include <type_traits>
#include <memory>
#include <spirv/unified1/spirv.hpp>
namespace sw
{
class SpirvRoutine
{
public:
std::unordered_map<uint32_t, std::unique_ptr<Array<Float4>>> lvalues;
};
class SpirvShader
{
public:
......@@ -212,12 +220,9 @@ namespace sw
std::vector<InterfaceComponent> inputs;
std::vector<InterfaceComponent> outputs;
private:
const int serialID;
static volatile int serialCounter;
Modes modes;
std::unordered_map<uint32_t, Object> types;
std::unordered_map<uint32_t, Object> defs;
void emitEarly(SpirvRoutine *routine) const;
void emit(SpirvRoutine *routine) const;
using BuiltInHash = std::hash<std::underlying_type<spv::BuiltIn>::type>;
std::unordered_map<spv::BuiltIn, BuiltinMapping, BuiltInHash> inputBuiltins;
......@@ -230,12 +235,20 @@ namespace sw
return it->second;
}
Object const &getObject(uint32_t id) const {
Object const &getObject(uint32_t id) const
{
auto it = defs.find(id);
assert(it != defs.end());
return it->second;
}
private:
const int serialID;
static volatile int serialCounter;
Modes modes;
std::unordered_map<uint32_t, Object> types;
std::unordered_map<uint32_t, Object> defs;
void ProcessExecutionMode(InsnIterator it);
uint32_t ComputeTypeSize(InsnIterator insn);
......
......@@ -64,7 +64,7 @@ namespace sw
// }
//}
// Actually emit code here
spirvShader->emit(&routine);
if(currentLabel != -1)
{
......
......@@ -19,6 +19,7 @@
#include "Device/Renderer.hpp"
#include "System/Half.hpp"
#include "Vulkan/VkDebug.hpp"
#include "SpirvShader.hpp"
namespace sw
{
......@@ -28,6 +29,7 @@ namespace sw
state(state),
spirvShader(spirvShader)
{
spirvShader->emitEarly(&routine);
}
VertexRoutine::~VertexRoutine()
......
......@@ -50,6 +50,7 @@ namespace sw
RegisterArray<MAX_VERTEX_INPUTS> v; // Input registers
RegisterArray<MAX_VERTEX_OUTPUTS> o; // Output registers
SpirvRoutine routine;
const VertexProcessor::State &state;
SpirvShader const * const 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