diff --git a/include/sirit/sirit.h b/include/sirit/sirit.h index c80555f..04f52d2 100644 --- a/include/sirit/sirit.h +++ b/include/sirit/sirit.h @@ -823,6 +823,52 @@ public: /// of the pixel specified by offset. Id OpInterpolateAtOffset(Id result_type, Id interpolant, Id offset); + // Derivatives + + /// Same result as either OpDPdxFine or OpDPdxCoarse on the input. + /// Selection of which one is based on external factors. + Id OpDPdx(Id result_type, Id operand); + + /// Same result as either OpDPdyFine or OpDPdyCoarse on the input. + /// Selection of which one is based on external factors. + Id OpDPdy(Id result_type, Id operand); + + /// Result is the same as computing the sum of the absolute values of OpDPdx and OpDPdy + /// on the input. + Id OpFwidth(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window x coordinate. + /// Uses local differencing based on the value of the input for the current fragment and + /// its immediate neighbor(s). + Id OpDPdxFine(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window y coordinate. + /// Uses local differencing based on the value of the input for the current fragment and + /// its immediate neighbor(s). + Id OpDPdyFine(Id result_type, Id operand); + + /// Result is the same as computing the sum of the absolute values of OpDPdxFine and OpDPdyFine + /// on the input. + Id OpFwidthFine(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window x coordinate. + /// Uses local differencing based on the value of the input for the current fragment's + /// neighbors, and possibly, but not necessarily, includes the value of the input for the + /// current fragment. That is, over a given area, the implementation can compute x derivatives + /// in fewer unique locations than would be allowed for OpDPdxFine. + Id OpDPdxCoarse(Id result_type, Id operand); + + /// Result is the partial derivative of the input with respect to the window y coordinate. + /// Uses local differencing based on the value of the input for the current fragment's + /// neighbors, and possibly, but not necessarily, includes the value of the input for the + /// current fragment. That is, over a given area, the implementation can compute y derivatives + /// in fewer unique locations than would be allowed for OpDPdyFine. + Id OpDPdyCoarse(Id result_type, Id operand); + + /// Result is the same as computing the sum of the absolute values of OpDPdxCoarse and + /// OpDPdyCoarse on the input. + Id OpFwidthCoarse(Id result_type, Id operand); + // Image /// Create a sampled image, containing both a sampler and an image. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64b50b2..c9bf093 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(sirit instructions/function.cpp instructions/flow.cpp instructions/debug.cpp + instructions/derivatives.cpp instructions/memory.cpp instructions/annotation.cpp instructions/misc.cpp diff --git a/src/instructions/derivatives.cpp b/src/instructions/derivatives.cpp new file mode 100644 index 0000000..c944e2a --- /dev/null +++ b/src/instructions/derivatives.cpp @@ -0,0 +1,29 @@ +/* This file is part of the sirit project. + * Copyright (c) 2021 sirit + * This software may be used and distributed according to the terms of the + * 3-Clause BSD License + */ + +#include "sirit/sirit.h" + +#include "stream.h" + +namespace Sirit { + +#define DEFINE_UNARY(funcname, opcode) \ + Id Module::funcname(Id result_type, Id operand) { \ + code->Reserve(4); \ + return *code << OpId{opcode, result_type} << operand << EndOp{}; \ + } + +DEFINE_UNARY(OpDPdx, spv::Op::OpDPdx) +DEFINE_UNARY(OpDPdy, spv::Op::OpDPdy) +DEFINE_UNARY(OpFwidth, spv::Op::OpFwidth) +DEFINE_UNARY(OpDPdxFine, spv::Op::OpDPdxFine) +DEFINE_UNARY(OpDPdyFine, spv::Op::OpDPdyFine) +DEFINE_UNARY(OpFwidthFine, spv::Op::OpFwidthFine) +DEFINE_UNARY(OpDPdxCoarse, spv::Op::OpDPdxCoarse) +DEFINE_UNARY(OpDPdyCoarse, spv::Op::OpDPdyCoarse) +DEFINE_UNARY(OpFwidthCoarse, spv::Op::OpFwidthCoarse) + +} // namespace Sirit