From 131dbd053c445224530d9d7942755e6f69baf655 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 26 Aug 2018 14:25:59 -0300 Subject: [PATCH] Add some types --- include/sirit/sirit.h | 30 +++++++++- src/opcodes/type.cpp | 135 ++++++++++++++++++++++++++++++++++++++++++ tests/main.cpp | 19 ++++++ 3 files changed, 183 insertions(+), 1 deletion(-) diff --git a/include/sirit/sirit.h b/include/sirit/sirit.h index c38ba79..887bf17 100644 --- a/include/sirit/sirit.h +++ b/include/sirit/sirit.h @@ -16,6 +16,8 @@ namespace Sirit { static const std::uint32_t GeneratorMagicNumber = 0; +static const std::uint32_t Undefined = UINT32_MAX; + class Op; class Module { @@ -49,7 +51,7 @@ public: /** * Adds an instruction to module's code - * @param op Instruction to insert into code. Types must not be emitted + * @param op Instruction to insert into code. Types and constants must not be emitted. * @return Returns op. */ const Op* Emit(const Op* op); @@ -59,6 +61,32 @@ public: /// Returns type void. const Op* TypeVoid(); + /// Returns type bool. + const Op* TypeBool(); + + /// Returns type integer. + const Op* TypeInt(int width, bool is_signed); + + /// Returns type float. + const Op* TypeFloat(int width); + + /// Returns type vector. + const Op* TypeVector(const Op* component_type, int component_count); + + /// Returns type matrix. + const Op* TypeMatrix(const Op* column_type, int column_count); + + /// Returns type image. + const Op* TypeImage(const Op* sampled_type, spv::Dim dim, int depth, bool arrayed, bool ms, + int sampled, spv::ImageFormat image_format, + spv::AccessQualifier access_qualifier = static_cast(Undefined)); + + /// Returns type sampler. + const Op* TypeSampler(); + + /// Returns type sampled image. + const Op* TypeSampledImage(const Op* image_type); + /// Returns a function type. const Op* TypeFunction(const Op* return_type, const std::vector& arguments = {}); diff --git a/src/opcodes/type.cpp b/src/opcodes/type.cpp index 8c754ac..403213e 100644 --- a/src/opcodes/type.cpp +++ b/src/opcodes/type.cpp @@ -4,6 +4,7 @@ * General Public License version 2 or any later version. */ +#include #include "sirit/sirit.h" #include "opcodes.h" @@ -13,6 +14,140 @@ const Op* Module::TypeVoid() { return AddDeclaration(new Op(spv::Op::OpTypeVoid, bound)); } +const Op* Module::TypeBool() { + return AddDeclaration(new Op(spv::Op::OpTypeBool, bound)); +} + +const Op* Module::TypeInt(int width, bool is_signed) { + if (width == 8) { + AddCapability(spv::Capability::Int8); + } else if (width == 16) { + AddCapability(spv::Capability::Int16); + } else if (width == 64) { + AddCapability(spv::Capability::Int64); + } + Op* op{new Op(spv::Op::OpTypeInt, bound)}; + op->Add(width); + op->Add(is_signed ? 1 : 0); + return AddDeclaration(op); +} + +const Op* Module::TypeFloat(int width) { + if (width == 16) { + AddCapability(spv::Capability::Float16); + } else if (width == 64) { + AddCapability(spv::Capability::Float64); + } + Op* op{new Op(spv::Op::OpTypeFloat, bound)}; + op->Add(width); + return AddDeclaration(op); +} + +const Op* Module::TypeVector(const Op* component_type, int component_count) { + assert(component_count >= 2); + Op* op{new Op(spv::Op::OpTypeVector, bound)}; + op->Add(component_type); + op->Add(component_count); + return AddDeclaration(op); +} + +const Op* Module::TypeMatrix(const Op* column_type, int column_count) { + assert(column_count >= 2); + AddCapability(spv::Capability::Matrix); + Op* op{new Op(spv::Op::OpTypeMatrix, bound)}; + op->Add(column_type); + op->Add(column_count); + return AddDeclaration(op); +} + +const Op* Module::TypeImage(const Op* sampled_type, spv::Dim dim, int depth, bool arrayed, bool ms, + int sampled, spv::ImageFormat image_format, + spv::AccessQualifier access_qualifier) { + switch (dim) { + case spv::Dim::Dim1D: + AddCapability(spv::Capability::Sampled1D); + break; + case spv::Dim::Cube: + AddCapability(spv::Capability::Shader); + break; + case spv::Dim::Rect: + AddCapability(spv::Capability::SampledRect); + break; + case spv::Dim::Buffer: + AddCapability(spv::Capability::SampledBuffer); + break; + case spv::Dim::SubpassData: + AddCapability(spv::Capability::InputAttachment); + break; + } + switch (image_format) { + case spv::ImageFormat::Rgba32f: + case spv::ImageFormat::Rgba16f: + case spv::ImageFormat::R32f: + case spv::ImageFormat::Rgba8: + case spv::ImageFormat::Rgba8Snorm: + case spv::ImageFormat::Rgba32i: + case spv::ImageFormat::Rgba16i: + case spv::ImageFormat::Rgba8i: + case spv::ImageFormat::R32i: + case spv::ImageFormat::Rgba32ui: + case spv::ImageFormat::Rgba16ui: + case spv::ImageFormat::Rgba8ui: + case spv::ImageFormat::R32ui: + AddCapability(spv::Capability::Shader); + break; + case spv::ImageFormat::Rg32f: + case spv::ImageFormat::Rg16f: + case spv::ImageFormat::R11fG11fB10f: + case spv::ImageFormat::R16f: + case spv::ImageFormat::Rgba16: + case spv::ImageFormat::Rgb10A2: + case spv::ImageFormat::Rg16: + case spv::ImageFormat::Rg8: + case spv::ImageFormat::R16: + case spv::ImageFormat::R8: + case spv::ImageFormat::Rgba16Snorm: + case spv::ImageFormat::Rg16Snorm: + case spv::ImageFormat::Rg8Snorm: + case spv::ImageFormat::Rg32i: + case spv::ImageFormat::Rg16i: + case spv::ImageFormat::Rg8i: + case spv::ImageFormat::R16i: + case spv::ImageFormat::R8i: + case spv::ImageFormat::Rgb10a2ui: + case spv::ImageFormat::Rg32ui: + case spv::ImageFormat::Rg16ui: + case spv::ImageFormat::Rg8ui: + case spv::ImageFormat::R16ui: + case spv::ImageFormat::R8ui: + AddCapability(spv::Capability::StorageImageExtendedFormats); + break; + } + Op* op{new Op(spv::Op::OpTypeImage, bound)}; + op->Add(sampled_type); + op->Add(static_cast(dim)); + op->Add(depth); + op->Add(arrayed ? 1 : 0); + op->Add(ms ? 1 : 0); + op->Add(sampled); + op->Add(static_cast(image_format)); + if (static_cast(access_qualifier) != Undefined) { + AddCapability(spv::Capability::Kernel); + op->Add(static_cast(access_qualifier)); + } + return AddDeclaration(op); +} + +const Op* Module::TypeSampler() { + return AddDeclaration(new Op(spv::Op::OpTypeSampler, bound)); +} + +const Op* Module::TypeSampledImage(const Op* image_type) { + Op* op{new Op(spv::Op::OpTypeSampledImage, bound)}; + op->Add(image_type); + return AddDeclaration(op); +} + const Op* Module::TypeFunction(const Op* return_type, const std::vector& arguments) { Op* type_func{new Op(spv::Op::OpTypeFunction, bound)}; type_func->Add(return_type); diff --git a/tests/main.cpp b/tests/main.cpp index d96a4d1..e0a7de0 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -17,6 +17,25 @@ public: AddCapability(spv::Capability::Shader); SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450); + // Type testing + TypeBool(); + TypeBool(); + TypeInt(64, true); + TypeInt(64, false); + TypeInt(16, false); + TypeFloat(16); + TypeFloat(32); + TypeFloat(64); + TypeVector(TypeBool(), 4); + TypeVector(TypeBool(), 3); + TypeVector(TypeVector(TypeFloat(32), 4), 3); + TypeVector(TypeVector(TypeFloat(32), 4), 3); + TypeMatrix(TypeVector(TypeFloat(32), 4), 4); + TypeImage(TypeFloat(32), spv::Dim::Dim2D, 0, false, false, 0, + spv::ImageFormat::Rg32f, spv::AccessQualifier::ReadOnly); + TypeSampledImage(TypeImage(TypeFloat(32), spv::Dim::Rect, 0, false, false, 0, + spv::ImageFormat::Rg32f, spv::AccessQualifier::ReadOnly)); + auto main_type{TypeFunction(TypeVoid())}; auto main_func{Emit(Function(TypeVoid(), spv::FunctionControlMask::MaskNone, main_type))}; Emit(Label());