Skip to content

Commit

Permalink
wip shaderc
Browse files Browse the repository at this point in the history
  • Loading branch information
yeetari committed Mar 24, 2024
1 parent d9cd6e2 commit 52a23ff
Show file tree
Hide file tree
Showing 13 changed files with 527 additions and 24 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);
13 changes: 3 additions & 10 deletions engine/include/vull/shaderc/ast.hh
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,6 @@ enum class BinaryOp {
SubAssign,
MulAssign,
DivAssign,

// Parsed-generated Muls can be turned into these by the legaliser.
VectorTimesScalar,
MatrixTimesScalar,
VectorTimesMatrix,
MatrixTimesVector,
MatrixTimesMatrix,
};

class BinaryExpr final : public TypedNode {
Expand Down Expand Up @@ -220,9 +213,9 @@ public:
Root &operator=(const Root &) = delete;
Root &operator=(Root &&) = delete;

template <typename U, typename... Args>
U *allocate(Args &&...args) {
return m_arena.allocate<U>(vull::forward<Args>(args)...);
template <typename T, typename... Args>
T *allocate(Args &&...args) {
return m_arena.allocate<T>(vull::forward<Args>(args)...);
}

void append_top_level(Node *node);
Expand Down
105 changes: 105 additions & 0 deletions engine/include/vull/shaderc/hir.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#pragma once

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

#include <stdint.h>

namespace vull::shaderc::hir {

enum class NodeKind {
FunctionDecl,

BinaryExpr,
BuiltinExpr,
PipelineVar,
};

class Node {
const NodeKind m_kind;

public:
explicit Node(NodeKind kind) : m_kind(kind) {}

NodeKind kind() const { return m_kind; }
};

class Aggregate : public Node {
Vector<Node *> m_nodes;

public:
explicit Aggregate(NodeKind kind) : Node(kind) {}

void append_node(Node *node) { m_nodes.push(node); }
};

class Expr : public Node {
Type m_type;

public:
explicit Expr(NodeKind kind) : Node(kind) {}

void set_type(Type type) { m_type = type; }
Type type() const { return m_type; }
};

enum class BinaryOp {
Assign,

ScalarTimesScalar,
VectorTimesScalar,
MatrixTimesScalar,
VectorTimesMatrix,
MatrixTimesVector,
MatrixTimesMatrix,
};

class BinaryExpr : public Expr {
Expr *m_lhs;
Expr *m_rhs;
BinaryOp m_op;

public:
BinaryExpr(Expr *lhs, Expr *rhs) : Expr(NodeKind::BinaryExpr), m_lhs(lhs), m_rhs(rhs) {}

void set_op(BinaryOp op) { m_op = op; }
BinaryOp op() const { return m_op; }
};

enum class BuiltinFunction {
Dot,
Max,
};

class BuiltinExpr : public Expr {
BuiltinFunction m_function;

public:
BuiltinExpr(BuiltinFunction function) : Expr(NodeKind::BuiltinExpr), m_function(function) {}

BuiltinFunction function() const { return m_function; }
};

class FunctionDecl : public Node {
Type m_return_type;
Vector<Type> m_parameter_types;
};

class Root {
Arena m_arena;
Vector<Node *> m_top_level_nodes;

public:
template <typename T, typename... Args>
T *allocate(Args &&...args) {
return m_arena.allocate<T>(vull::forward<Args>(args)...);
}

void append_top_level(Node *node) {
m_top_level_nodes.push(node);
}
};

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

#include <vull/container/hash_map.hh>
#include <vull/shaderc/ast.hh>
#include <vull/shaderc/hir.hh>
#include <vull/support/result.hh>
#include <vull/support/tuple.hh>
#include <vull/support/unique_ptr.hh>

namespace vull::shaderc {

enum class LegaliseError {

};

class Legaliser {
class Scope;

private:
hir::Root m_root;
Scope *m_scope{nullptr};
UniquePtr<Scope> m_root_scope;
HashMap<StringView, Tuple<hir::BuiltinFunction, Type>> m_builtin_functions;

Result<hir::Expr *, LegaliseError> lower_binary_expr(const ast::BinaryExpr &);
Result<hir::Expr *, LegaliseError> lower_call_expr(const ast::CallExpr &);
Result<hir::Expr *, LegaliseError> lower_symbol(const ast::Symbol &);
Result<hir::Expr *, LegaliseError> lower_expr(const ast::Node &);

Result<hir::Node *, LegaliseError> lower_function_decl(const ast::FunctionDecl &);
Result<hir::Node *, LegaliseError> lower_pipeline_decl(const ast::PipelineDecl &);
Result<hir::Node *, LegaliseError> lower_top_level(const ast::Node &);

public:
Legaliser();
Legaliser(const Legaliser &) = delete;
Legaliser(Legaliser &&) = delete;
~Legaliser();

Legaliser &operator=(const Legaliser &) = delete;
Legaliser &operator=(Legaliser &&) = delete;

Result<hir::Root, LegaliseError> legalise(const ast::Root &);
};

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

namespace vull::shaderc::hir {

class Root;

} // namespace vull::shaderc::hir

namespace vull::shaderc::spv {

class Builder;

void build_spv(Builder &builder, const hir::Root &hir_root);

} // namespace vull::shaderc::spv
2 changes: 2 additions & 0 deletions engine/sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ target_sources(vull-script PRIVATE

target_sources(vull-shaderc PRIVATE
shaderc/ast.cc
shaderc/legaliser.cc
shaderc/lexer.cc
shaderc/parser.cc
shaderc/spv_backend.cc
shaderc/spv_builder.cc)

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

#include <vull/container/hash_map.hh>
#include <vull/support/string_view.hh>

namespace vull::shaderc {

class Legaliser::Scope {
Scope *&m_current;
Scope *m_parent;
HashMap<StringView, hir::Expr *> m_symbol_map;

public:
explicit Scope(Scope *&current);
Scope(const Scope &) = delete;
Scope(Scope &&) = delete;
~Scope();

Scope &operator=(const Scope &) = delete;
Scope &operator=(Scope &&) = delete;

Result<hir::Expr *, LegaliseError> lookup_symbol(StringView name) const;
Result<void, LegaliseError> put_symbol(StringView name, hir::Expr *expr);
};

Legaliser::Scope::Scope(Scope *&current) : m_current(current), m_parent(current) {
current = this;
}

Legaliser::Scope::~Scope() {
m_current = m_parent;
}

Result<hir::Expr *, LegaliseError> Legaliser::Scope::lookup_symbol(StringView name) const {
if (auto symbol = m_symbol_map.get(name)) {
return *symbol;
}
if (m_parent == nullptr) {
// TODO: Not found.
VULL_ENSURE_NOT_REACHED();
}
return m_parent->lookup_symbol(name);
}

Result<void, LegaliseError> Legaliser::Scope::put_symbol(StringView name, hir::Expr *expr) {
// TODO: Check for redeclaration.
m_symbol_map.set(name, expr);
return {};
}

Legaliser::Legaliser() : m_root_scope(new Scope(m_scope)) {}
Legaliser::~Legaliser() = default;

Result<hir::Expr *, LegaliseError> Legaliser::lower_binary_expr(const ast::BinaryExpr &ast_expr) {
auto *lhs = VULL_TRY(lower_expr(ast_expr.lhs()));
auto *rhs = VULL_TRY(lower_expr(ast_expr.rhs()));
auto *expr = m_root.allocate<hir::BinaryExpr>(lhs, rhs);

if (ast::is_assign_op(ast_expr.op())) {
// TODO: Handle other assigns.
VULL_ENSURE(ast_expr.op() == ast::BinaryOp::Assign);
expr->set_op(hir::BinaryOp::Assign);
expr->set_type(lhs->type());
return expr;
}

const auto &lhs_type = lhs->type();
const auto &rhs_type = rhs->type();
if ((lhs_type.is_vector() && rhs_type.is_scalar()) || (lhs_type.is_scalar() && rhs_type.is_vector())) {
expr->set_op(hir::BinaryOp::VectorTimesScalar);
expr->set_type(lhs_type.is_vector() ? lhs_type : rhs_type);
} else if ((lhs_type.is_matrix() && rhs_type.is_scalar()) || (lhs_type.is_scalar() && rhs_type.is_matrix())) {
expr->set_op(hir::BinaryOp::MatrixTimesScalar);
expr->set_type(lhs_type.is_matrix() ? lhs_type : rhs_type);
} else if (lhs_type.is_vector() && rhs_type.is_matrix()) {
expr->set_op(hir::BinaryOp::VectorTimesMatrix);
expr->set_type(Type(lhs_type.scalar_type(), rhs_type.matrix_cols()));
} else if (lhs_type.is_matrix() && rhs_type.is_vector()) {
expr->set_op(hir::BinaryOp::MatrixTimesVector);
expr->set_type(Type(lhs_type.scalar_type(), lhs_type.matrix_rows()));
} else if (lhs_type.is_matrix() && rhs_type.is_matrix()) {
expr->set_op(hir::BinaryOp::MatrixTimesMatrix);
expr->set_type(Type(lhs_type.scalar_type(), rhs_type.matrix_cols(), lhs_type.matrix_rows()));
} else if (lhs_type.is_scalar() && rhs_type.is_scalar()) {
expr->set_op(hir::BinaryOp::ScalarTimesScalar);
expr->set_type(lhs_type.scalar_type());
} else {
VULL_ENSURE_NOT_REACHED();
}
return expr;
}

Result<hir::Expr *, LegaliseError> Legaliser::lower_call_expr(const ast::CallExpr &ast_expr) {
if (auto builtin = m_builtin_functions.get(ast_expr.name())) {
// TODO: Need to check parameter types match.
auto *expr = m_root.allocate<hir::BuiltinExpr>(vull::get<0>(*builtin));
expr->set_type(vull::get<1>(*builtin));
return expr;
}
}

Result<hir::Expr *, LegaliseError> Legaliser::lower_symbol(const ast::Symbol &ast_symbol) {
return VULL_TRY(m_scope->lookup_symbol(ast_symbol.name()));
}

Result<hir::Expr *, LegaliseError> Legaliser::lower_expr(const ast::Node &) {}

Result<hir::Node *, LegaliseError> Legaliser::lower_function_decl(const ast::FunctionDecl &ast_decl) {
auto *function = m_root.allocate<hir::FunctionDecl>();

return function;
}

Result<hir::Node *, LegaliseError> Legaliser::lower_pipeline_decl(const ast::PipelineDecl &ast_decl) {
auto *expr = m_root.allocate<hir::Expr>(hir::NodeKind::PipelineVar);
expr->set_type(ast_decl.type());
VULL_TRY(m_scope->put_symbol(ast_decl.name(), expr));
return nullptr;
}

Result<hir::Node *, LegaliseError> Legaliser::lower_top_level(const ast::Node &) {

}

Result<hir::Root, LegaliseError> Legaliser::legalise(const ast::Root &ast_root) {
for (const auto *ast_node : ast_root.top_level_nodes()) {
if (auto *node = VULL_TRY(lower_top_level(*ast_node))) {
m_root.append_top_level(node);
}
}
return vull::move(m_root);
}

} // namespace vull::shaderc
Loading

0 comments on commit 52a23ff

Please sign in to comment.