diff --git a/include/sirit/sirit.h b/include/sirit/sirit.h index b52c7d9..8f3f051 100644 --- a/include/sirit/sirit.h +++ b/include/sirit/sirit.h @@ -439,6 +439,86 @@ class Module { Id OpInterpolateAtOffset(Id result_type, Id interpolant, Id offset); + // Image + + Id OpSampledImage(Id result_type, Id image, Id sampler); + + Id OpImageSampleImplicitLod( + Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImageSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate, + spv::ImageOperandsMask image_operands, Id lod, + const std::vector& operands = {}); + + Id OpImageSampleDrefImplicitLod( + Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImageSampleDrefExplicitLod(Id result_type, Id sampled_image, + Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, + Id lod, + const std::vector& operands = {}); + + Id OpImageSampleProjImplicitLod( + Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImageSampleProjExplicitLod(Id result_type, Id sampled_image, + Id coordinate, + spv::ImageOperandsMask image_operands, + Id lod, + const std::vector& operands = {}); + + Id OpImageSampleProjDrefImplicitLod( + Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImageSampleProjDrefExplicitLod(Id result_type, Id sampled_image, + Id coordinate, Id dref, + spv::ImageOperandsMask image_operands, + Id lod, + const std::vector& operands = {}); + + Id OpImageFetch(Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImageGather(Id result_type, Id sampled_image, Id coordinate, + Id component, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id + OpImageDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImageRead(Id result_type, Id sampled_image, Id coordinate, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImageWrite(Id image, Id coordinate, Id texel, + std::optional image_operands = {}, + const std::vector& operands = {}); + + Id OpImage(Id result_type, Id sampled_image); + + Id OpImageQuerySizeLod(Id result_type, Id image, Id level_of_detail); + + Id OpImageQuerySize(Id result_type, Id image); + + Id OpImageQueryLod(Id result_type, Id image, Id coordinate); + + Id OpImageQueryLevels(Id result_type, Id image); + + Id OpImageQuerySamples(Id result_type, Id image); + private: Id AddCode(std::unique_ptr op); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eacfdbb..4f968e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,7 @@ add_library(sirit insts/bit.cpp insts/arithmetic.cpp insts/extension.cpp + insts/image.cpp ) target_include_directories(sirit PUBLIC ../include diff --git a/src/insts/image.cpp b/src/insts/image.cpp new file mode 100644 index 0000000..22b7f67 --- /dev/null +++ b/src/insts/image.cpp @@ -0,0 +1,138 @@ +/* This file is part of the sirit project. + * Copyright (c) 2018 ReinUsesLisp + * This software may be used and distributed according to the terms of the GNU + * Lesser General Public License version 2.1 or any later version. + */ + +#include "common_types.h" +#include "op.h" +#include "sirit/sirit.h" + +namespace Sirit { + +Id Module::OpSampledImage(Id result_type, Id image, Id sampler) { + auto op{ + std::make_unique(spv::Op::OpSampledImage, bound++, result_type)}; + op->Add(image); + op->Add(sampler); + return AddCode(std::move(op)); +} + +void AddImageOperands(Op* op, + std::optional image_operands, + const std::vector& operands) { + if (!image_operands) + return; + op->Add(static_cast(*image_operands)); + op->Add(operands); +} + +#define DEFINE_IMAGE_OP(funcname, opcode) \ + Id Module::funcname(Id result_type, Id sampled_image, Id coordinate, \ + std::optional image_operands, \ + const std::vector& operands) { \ + auto op{std::make_unique(opcode, bound++, result_type)}; \ + op->Add(sampled_image); \ + op->Add(coordinate); \ + AddImageOperands(op.get(), image_operands, operands); \ + return AddCode(std::move(op)); \ + } + +#define DEFINE_IMAGE_EXP_OP(funcname, opcode) \ + Id Module::funcname(Id result_type, Id sampled_image, Id coordinate, \ + spv::ImageOperandsMask image_operands, Id lod, \ + const std::vector& operands) { \ + auto op{std::make_unique(opcode, bound++, result_type)}; \ + op->Add(sampled_image); \ + op->Add(coordinate); \ + op->Add(static_cast(image_operands)); \ + op->Add(lod); \ + op->Add(operands); \ + return AddCode(std::move(op)); \ + } + +#define DEFINE_IMAGE_EXTRA_OP(funcname, opcode) \ + Id Module::funcname(Id result_type, Id sampled_image, Id coordinate, \ + Id extra, \ + std::optional image_operands, \ + const std::vector& operands) { \ + auto op{std::make_unique(opcode, bound++, result_type)}; \ + op->Add(sampled_image); \ + op->Add(coordinate); \ + op->Add(extra); \ + AddImageOperands(op.get(), image_operands, operands); \ + return AddCode(std::move(op)); \ + } + +#define DEFINE_IMAGE_EXTRA_EXP_OP(funcname, opcode) \ + Id Module::funcname(Id result_type, Id sampled_image, Id coordinate, \ + Id extra, spv::ImageOperandsMask image_operands, \ + Id lod, const std::vector& operands) { \ + auto op{std::make_unique(opcode, bound++, result_type)}; \ + op->Add(sampled_image); \ + op->Add(coordinate); \ + op->Add(extra); \ + op->Add(static_cast(image_operands)); \ + op->Add(lod); \ + op->Add(operands); \ + return AddCode(std::move(op)); \ + } + +DEFINE_IMAGE_OP(OpImageSampleImplicitLod, spv::Op::OpImageSampleImplicitLod) +DEFINE_IMAGE_EXP_OP(OpImageSampleExplicitLod, spv::Op::OpImageSampleExplicitLod) +DEFINE_IMAGE_EXTRA_OP(OpImageSampleDrefImplicitLod, + spv::Op::OpImageSampleDrefImplicitLod) +DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleDrefExplicitLod, + spv::Op::OpImageSampleDrefExplicitLod) +DEFINE_IMAGE_OP(OpImageSampleProjImplicitLod, + spv::Op::OpImageSampleProjImplicitLod) +DEFINE_IMAGE_EXP_OP(OpImageSampleProjExplicitLod, + spv::Op::OpImageSampleProjExplicitLod) +DEFINE_IMAGE_EXTRA_OP(OpImageSampleProjDrefImplicitLod, + spv::Op::OpImageSampleProjDrefImplicitLod) +DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleProjDrefExplicitLod, + spv::Op::OpImageSampleProjDrefExplicitLod) +DEFINE_IMAGE_OP(OpImageFetch, spv::Op::OpImageFetch) +DEFINE_IMAGE_EXTRA_OP(OpImageGather, spv::Op::OpImageGather) +DEFINE_IMAGE_EXTRA_OP(OpImageDrefGather, spv::Op::OpImageDrefGather) +DEFINE_IMAGE_OP(OpImageRead, spv::Op::OpImageRead) + +Id Module::OpImageWrite(Id image, Id coordinate, Id texel, + std::optional image_operands, + const std::vector& operands) { + auto op{std::make_unique(spv::Op::OpImageWrite)}; + op->Add(image); + op->Add(coordinate); + op->Add(texel); + AddImageOperands(op.get(), image_operands, operands); + return AddCode(std::move(op)); +} + +Id Module::OpImage(Id result_type, Id sampled_image) { + auto op{std::make_unique(spv::Op::OpImage, bound++, result_type)}; + op->Add(sampled_image); + return AddCode(std::move(op)); +} + +#define DEFINE_IMAGE_QUERY_OP(funcname, opcode) \ + Id Module::funcname(Id result_type, Id image) { \ + auto op{std::make_unique(opcode, bound++, result_type)}; \ + op->Add(image); \ + return AddCode(std::move(op)); \ + } + +#define DEFINE_IMAGE_QUERY_BIN_OP(funcname, opcode) \ + Id Module::funcname(Id result_type, Id image, Id extra) { \ + auto op{std::make_unique(opcode, bound++, result_type)}; \ + op->Add(image); \ + op->Add(extra); \ + return AddCode(std::move(op)); \ + } + +DEFINE_IMAGE_QUERY_BIN_OP(OpImageQuerySizeLod, spv::Op::OpImageQuerySizeLod) +DEFINE_IMAGE_QUERY_OP(OpImageQuerySize, spv::Op::OpImageQuerySize) +DEFINE_IMAGE_QUERY_BIN_OP(OpImageQueryLod, spv::Op::OpImageQueryLod) +DEFINE_IMAGE_QUERY_OP(OpImageQueryLevels, spv::Op::OpImageQueryLevels) +DEFINE_IMAGE_QUERY_OP(OpImageQuerySamples, spv::Op::OpImageQuerySamples) + +} // namespace Sirit