Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
yeetari committed Mar 17, 2024
1 parent eb218ff commit adbbeb4
Show file tree
Hide file tree
Showing 10 changed files with 407 additions and 15 deletions.
4 changes: 2 additions & 2 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ add_shader(shaders/depth_reduce.comp)
add_shader(shaders/draw_cull.comp)
add_shader(shaders/fst.vert)
add_shader(shaders/light_cull.comp)
add_shader(shaders/object.vsl)
#add_shader(shaders/object.vsl)
add_shader(shaders/shadow.vert)
add_shader(shaders/skybox.frag)
add_shader(shaders/skybox.vert)
Expand All @@ -40,7 +40,7 @@ function(vull_depend_builtin target)
${CMAKE_BINARY_DIR}/engine/shaders/draw_cull.comp.spv /shaders/draw_cull.comp
${CMAKE_BINARY_DIR}/engine/shaders/fst.vert.spv /shaders/fst.vert
${CMAKE_BINARY_DIR}/engine/shaders/light_cull.comp.spv /shaders/light_cull.comp
${CMAKE_BINARY_DIR}/engine/shaders/object.vsl.spv /shaders/object
#${CMAKE_BINARY_DIR}/engine/shaders/object.vsl.spv /shaders/object
${CMAKE_BINARY_DIR}/engine/shaders/shadow.vert.spv /shaders/shadow.vert
${CMAKE_BINARY_DIR}/engine/shaders/skybox.frag.spv /shaders/skybox.frag
${CMAKE_BINARY_DIR}/engine/shaders/skybox.vert.spv /shaders/skybox.vert
Expand Down
8 changes: 8 additions & 0 deletions engine/include/vull/core/main.hh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@
#include <vull/container/vector.hh>
#include <vull/support/string_view.hh>

namespace vull {

class ArgsParser;

void add_engine_args(ArgsParser &args_parser);

} // namespace vull

void vull_main(vull::Vector<vull::StringView> &&args);
27 changes: 27 additions & 0 deletions engine/include/vull/shaderc/hir.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <vull/container/vector.hh>
#include <vull/support/variant.hh>

#include <stdint.h>

namespace vull::shaderc::hir {

using ExprId = uint32_t;

class BinaryExpr {};

using Expr = Variant<BinaryExpr>;

class Root {
Vector<Expr, ExprId> m_expressions;

public:
template <typename T, typename... Args>
ExprId create_expr(Args &&... args) {
m_expressions.push(T(vull::forward<Args>(args)...));
return m_expressions.size() - 1;
}
};

} // namespace vull::shaderc::hir
118 changes: 118 additions & 0 deletions engine/include/vull/shaderc/spv_builder.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#pragma once

#include <vull/container/hash_set.hh>
#include <vull/container/vector.hh>
#include <vull/support/hash.hh>
#include <vull/support/string_view.hh>
#include <vull/support/unique_ptr.hh>
#include <vull/vulkan/spirv.hh>

namespace vull::shaderc::spv {

using namespace vull::vk::spv;

class Builder;

class Instruction {
const Op m_op;
const Id m_id;
const Id m_type;

// TODO(small-vector)
Vector<Word> m_operands;

public:
static bool constant_equals(const Instruction &lhs, const Instruction &rhs) { return lhs.constant_equals(rhs); }
static bool type_equals(const Instruction &lhs, const Instruction &rhs) { return lhs.type_equals(rhs); }
static hash_t constant_hash(const Instruction &inst) { return inst.constant_hash(); }
static hash_t type_hash(const Instruction &inst) { return inst.type_hash(); }

Instruction() : Instruction(Op::Nop) {}
Instruction(Op op, Id id = 0, Id type = 0) : m_op(op), m_id(id), m_type(type) {}

template <typename T>
void append_operand(T operand) requires(sizeof(T) <= sizeof(Word)) {
append_operand(static_cast<Word>(operand));
}

void append_operand(Word operand);
void append_operand(StringView operand);
void extend_operands(const Vector<Word> &operands);
Word operand(uint32_t index) const { return m_operands[index]; }
uint32_t operand_count() const { return m_operands.size(); }

bool constant_equals(const Instruction &other) const;
bool type_equals(const Instruction &other) const;
hash_t constant_hash() const;
hash_t type_hash() const;

Op op() const { return m_op; }
Id id() const { return m_id; }
Id type() const { return m_type; }
const Vector<Word> &operands() const { return m_operands; }
};

class Block {
Builder &m_builder;
Instruction m_label;
Vector<UniquePtr<Instruction>> m_instructions;

public:
explicit Block(Builder &builder);

Instruction &append(Op op, Id type = 0);

bool is_terminated() const;
};

class Builder {
Vector<Instruction> m_extension_imports;
Vector<Instruction> m_decorations;
HashSet<Instruction, &Instruction::type_hash, &Instruction::type_equals> m_types;
HashSet<Instruction, &Instruction::constant_hash, &Instruction::constant_equals> m_constants;
Id m_next_id{1};

Id ensure_constant(Instruction &&inst);
Id ensure_type(Instruction &&inst);

public:
template <typename... Literals>
void decorate(Id id, Decoration decoration, Literals... literals);
template <typename... Literals>
void decorate_member(Id struct_id, Word member, Decoration decoration, Literals... literals);

Id import_extension(StringView name);

Id scalar_constant(Id type, Word value);
Id composite_constant(Id type, Vector<Id> &&elements);

Id float_type(Word width);
Id function_type(Id return_type, const Vector<Id> &parameter_types);
Id int_type(Word width, bool is_signed);
Id matrix_type(Id column_type, Word column_count);
Id pointer_type(StorageClass storage_class, Id pointee_type);
Id struct_type(const Vector<Id> &member_types, bool is_block);
Id vector_type(Id component_type, Word component_count);
Id void_type();

Id make_id() { return m_next_id++; }
};

template <typename... Literals>
void Builder::decorate(Id id, Decoration decoration, Literals... literals) {
auto &inst = m_decorations.emplace(Op::Decorate);
inst.append_operand(id);
inst.append_operand(decoration);
(inst.append_operand(literals), ...);
}

template <typename... Literals>
void Builder::decorate_member(Id struct_id, Word member, Decoration decoration, Literals... literals) {
auto &inst = m_decorations.emplace(Op::MemberDecorate);
inst.append_operand(struct_id);
inst.append_operand(member);
inst.append_operand(decoration);
(inst.append_operand(literals), ...);
}

} // namespace vull::shaderc::spv
3 changes: 2 additions & 1 deletion engine/sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ target_sources(vull-script PRIVATE
target_sources(vull-shaderc PRIVATE
shaderc/ast.cc
shaderc/lexer.cc
shaderc/parser.cc)
shaderc/parser.cc
shaderc/spv_builder.cc)

target_sources(vull-ui PRIVATE
ui/layout/box_layout.cc
Expand Down
163 changes: 163 additions & 0 deletions engine/sources/shaderc/spv_builder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#include <vull/shaderc/spv_builder.hh>

namespace vull::shaderc::spv {

void Instruction::append_operand(Word operand) {
m_operands.push(operand);
}

void Instruction::append_operand(StringView operand) {
Word shift_amount = 0;
Word word = 0;
for (auto ch : operand) {
word |= static_cast<Word>(ch) << shift_amount;
if ((shift_amount += 8) == 32) {
append_operand(vull::exchange(word, 0u));
shift_amount = 0;
}
}
append_operand(word);
}

void Instruction::extend_operands(const Vector<Word> &operands) {
m_operands.extend(operands);
}

bool Instruction::constant_equals(const Instruction &other) const {
return type_equals(other) && m_type == other.m_type;
}

bool Instruction::type_equals(const Instruction &other) const {
if (m_op != other.m_op) {
return false;
}
if (m_operands.size() != other.m_operands.size()) {
return false;
}
for (uint32_t i = 0; i < m_operands.size(); i++) {
if (m_operands[i] != other.m_operands[i]) {
return false;
}
}
return true;
}

hash_t Instruction::constant_hash() const {
return vull::hash_combine(type_hash(), m_type);
}

hash_t Instruction::type_hash() const {
auto hash = vull::hash_of(m_op);
for (Word operand : m_operands) {
hash = vull::hash_combine(hash, operand);
}
return hash;
}

Block::Block(Builder &builder) : m_builder(builder), m_label(Op::Label, builder.make_id()) {}

static bool op_has_id(Op op) {
switch (op) {
case Op::Store:
case Op::Return:
case Op::ReturnValue:
return false;
default:
return true;
}
}

Instruction &Block::append(Op op, Id type) {
return *m_instructions.emplace(new Instruction(op, op_has_id(op) ? m_builder.make_id() : 0, type));
}

bool Block::is_terminated() const {
return !m_instructions.empty() && spv::is_terminator(m_instructions.last()->op());
}

Id Builder::import_extension(StringView name) {
auto &inst = m_extension_imports.emplace(Op::ExtInstImport, m_next_id++);
inst.append_operand(name);
return inst.id();
}

Id Builder::ensure_constant(Instruction &&inst) {
if (auto existing = m_constants.add(vull::move(inst))) {
return existing->id();
}
return m_next_id++;
}

Id Builder::scalar_constant(Id type, Word value) {
Instruction inst(Op::Constant, m_next_id, type);
inst.append_operand(value);
return ensure_constant(vull::move(inst));
}

Id Builder::composite_constant(Id type, Vector<Id> &&elements) {
Instruction inst(Op::ConstantComposite, m_next_id, type);
inst.extend_operands(elements);
return ensure_constant(vull::move(inst));
}

Id Builder::ensure_type(Instruction &&inst) {
if (auto existing = m_types.add(vull::move(inst))) {
return existing->id();
}
return m_next_id++;
}

Id Builder::float_type(Word width) {
Instruction inst(Op::TypeFloat, m_next_id);
inst.append_operand(width);
return ensure_type(vull::move(inst));
}

Id Builder::function_type(Id return_type, const Vector<Id> &parameter_types) {
Instruction inst(Op::TypeFunction, m_next_id);
inst.append_operand(return_type);
inst.extend_operands(parameter_types);
return ensure_type(vull::move(inst));
}

Id Builder::int_type(Word width, bool is_signed) {
Instruction inst(Op::TypeInt, m_next_id);
inst.append_operand(width);
inst.append_operand(is_signed ? 1 : 0);
return ensure_type(vull::move(inst));
}

Id Builder::matrix_type(Id column_type, Word column_count) {
Instruction inst(Op::TypeMatrix, m_next_id);
inst.append_operand(column_type);
inst.append_operand(column_count);
return ensure_type(vull::move(inst));
}

Id Builder::pointer_type(StorageClass storage_class, Id pointee_type) {
Instruction inst(Op::TypePointer, m_next_id);
inst.append_operand(static_cast<Word>(storage_class));
inst.append_operand(pointee_type);
return ensure_type(vull::move(inst));
}

Id Builder::struct_type(const Vector<Id> &member_types, bool is_block) {
VULL_ENSURE(!is_block);
Instruction inst(Op::TypeStruct, m_next_id);
inst.extend_operands(member_types);
return ensure_type(vull::move(inst));
}

Id Builder::vector_type(Id component_type, Word component_count) {
Instruction inst(Op::TypeVector, m_next_id);
inst.append_operand(component_type);
inst.append_operand(component_count);
return ensure_type(vull::move(inst));
}

Id Builder::void_type() {
Instruction inst(Op::TypeVoid, m_next_id);
return ensure_type(vull::move(inst));
}

} // namespace vull::shaderc::spv
13 changes: 2 additions & 11 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,5 @@ endif()
vull_executable(vsi vull::core vull::script)
target_sources(vsi PRIVATE vsi.cc)

vull_executable(vslc vull::core)
target_sources(vslc PRIVATE
vslc/spv/backend.cc
vslc/spv/builder.cc
vslc/ast.cc
vslc/char_stream.cc
vslc/legaliser.cc
vslc/lexer.cc
vslc/main.cc
vslc/parser.cc
vslc/token.cc)
vull_executable(vslc vull::core vull::shaderc)
target_sources(vslc PRIVATE vslc.cc)
Loading

0 comments on commit adbbeb4

Please sign in to comment.