Beatmup
Beatmup::NNets::SpatialFilteringMixin Class Reference

Generates GLSL fragment shader code sampling a local neighborhood around the current texture coordinates for further filtering. More...

#include <operation.h>

Inheritance diagram for Beatmup::NNets::SpatialFilteringMixin:
Beatmup::NNets::Conv2D Beatmup::NNets::Pooling2D

Protected Member Functions

 SpatialFilteringMixin (const int nbSizeX, const int nbSizeY)
 Initializes spatial filtering mixin. More...
 
 ~SpatialFilteringMixin ()
 
void writeHeader (StringBuilder &code, bool useUniformShift)
 Writes out the very GLSL fragment shader header required for spatial neighborhood sampling. More...
 
void declare (StringBuilder &code, const char *datatype, bool inlineSampling=false)
 Declares GLSL fragment shader main(..) code part required for spatial neighborhood sampling. More...
 
void sample (StringBuilder &code, const char *inputName, const int inputIndex, const Point &shift, const bool isFirstSample=true, const char *suffix="")
 Samples a neighborhood of a given texture. More...
 
void sampleInline (StringBuilder &code, const char *inputName, const int inputIndex, const IntPoint &position, const Point &shift, const char *suffix="")
 
void setup (const int width, const int height)
 Prepares the spatial filtering operation execution. More...
 
void setUniformShift (GL::Program &program, const IntPoint &shift, const IntPoint &inputSize)
 Applies an offset to the sampling position at runtime. More...
 
void setupProgram (GL::Program &program)
 Prepares a given program for spatial filtering. More...
 
IntRectangle getSamplingArea (const IntPoint &size, const IntPoint &stride, const Size::Padding padding) const
 Implements common padding policies by computing a rectangular area of positions the sampling kernel takes in order to get the result with the required padding. More...
 
IntRectangle getSamplingArea (const Storage::View &storage, const int channel, const IntPoint &stride, const Size::Padding padding) const
 Computes area in pixels to sample a given storage according to specific stride and padding. More...
 
Rectangle getTextureCoordinates (const Storage::View &storage, const int channel, const IntPoint &stride, const Size::Padding padding, const IntPoint &outputSize) const
 Computes texture coordinates sampling a specific storage channel for given stride, padding and output size. More...
 
std::string getInputSamplingPos () const
 Retrieves input sampling point position for the current fragment. More...
 
bool isUniformShiftUsed () const
 

Static Protected Attributes

static const char * SAMPLE_ID_PREFIX = "i"
 prefix of variables declaring a neighbor sample More...
 

Private Member Functions

int getDeltasSize () const
 

Private Attributes

const int nbSizeX
 
const int nbSizeY
 
Point shift
 current static shift of the sampling position More...
 
float * deltas
 array storing pixel position differences for neighborhood sampling More...
 
bool useUniformShift
 if true, the sampling position can be shifted dynamically at every run More...
 

Detailed Description

Generates GLSL fragment shader code sampling a local neighborhood around the current texture coordinates for further filtering.

Definition at line 272 of file operation.h.

Constructor & Destructor Documentation

◆ SpatialFilteringMixin()

SpatialFilteringMixin::SpatialFilteringMixin ( const int  nbSizeX,
const int  nbSizeY 
)
protected

Initializes spatial filtering mixin.

Parameters
[in]nbSizeXNeighborhood width in samples
[in]nbSizeYNeighborhood height in samples

Definition at line 98 of file operation.cpp.

98  :
100 {
101  deltas = new float[2 * getDeltasSize()];
102 }
bool useUniformShift
if true, the sampling position can be shifted dynamically at every run
Definition: operation.h:277
float * deltas
array storing pixel position differences for neighborhood sampling
Definition: operation.h:276

◆ ~SpatialFilteringMixin()

SpatialFilteringMixin::~SpatialFilteringMixin ( )
protected

Definition at line 105 of file operation.cpp.

105  {
106  delete[] deltas;
107 }

Member Function Documentation

◆ getDeltasSize()

int Beatmup::NNets::SpatialFilteringMixin::getDeltasSize ( ) const
inlineprivate
Returns
number of 2D delta-vectors stored in a uniform variable in the fragment shader

Definition at line 282 of file operation.h.

282 { return std::max(1, std::max(nbSizeX, nbSizeY) / 2); }
CustomPoint< numeric > max(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:728

◆ writeHeader()

void SpatialFilteringMixin::writeHeader ( StringBuilder code,
bool  useUniformShift 
)
protected

Writes out the very GLSL fragment shader header required for spatial neighborhood sampling.

Parameters
[in,out]codeThe GLSL code storage
[in]useUniformShiftIf true, the sampling position can be shifted dynamically at every run

Definition at line 110 of file operation.cpp.

110  {
111  if (nbSizeX > 1 || nbSizeY > 1)
112  code.printf("uniform highp vec2 %s[%d];\n", UNIFORM_DELTA, getDeltasSize());
113  if (useUniformShift)
114  code.printf("uniform highp vec2 %s;\n", UNIFORM_SHIFT);
116 }
StringBuilder & printf(const char *format,...)
static const char * UNIFORM_SHIFT
uniform variable specifying an offset to apply to the sampling position in SpatialFilteringMixin
Definition: operation.cpp:28
static const char * UNIFORM_DELTA
uniform variable storing spatial deltas for SpatialFilteringMixin
Definition: operation.cpp:27

◆ declare()

void SpatialFilteringMixin::declare ( StringBuilder code,
const char *  datatype,
bool  inlineSampling = false 
)
protected

Declares GLSL fragment shader main(..) code part required for spatial neighborhood sampling.

Parameters
[in,out]codeThe GLSL code storage
[in]datatypeThe neighborhood samples datatype
[in]inlineSamplingIf true, sampled values are not stored in intermediate variables (sampleInline() can only be used, not sample())

Definition at line 119 of file operation.cpp.

119  {
120  // declaring neighborhood samples
121  const int nbSize = std::max(nbSizeX, nbSizeY);
122  code.printf("%s i00", datatype);
123  for (int i = 1; i < nbSize * nbSize; ++i)
124  code.printf(", %s%d%d", SAMPLE_ID_PREFIX, i % nbSize, i / nbSize);
125  code.line(";");
126 
127  // declaring/computing neighborhood positions
128  const int mid = (nbSize - 1) / 2;
129  code.printf("highp vec2 p%d = %s", mid, GL::RenderingPrograms::TEXTURE_COORDINATES_ID);
130  if (useUniformShift)
131  code.printf(" + %s", UNIFORM_SHIFT);
132  for (int i = 0; i < nbSize; ++i) {
133  if (i != mid) code(", ");
134  if (i < mid)
135  code.printf("p%d = p%d - %s[%d]", i, mid, UNIFORM_DELTA, mid - i - 1);
136  else if (i > mid)
137  code.printf("p%d = p%d + %s[%d]", i, mid, UNIFORM_DELTA, i - mid - 1);
138  }
139 
140  // declaring neighborhood positions shifted for a current input channel
141  if (!inlineSampling) {
142  code(", cp0");
143  for (int i = 1; i < nbSize; ++i)
144  code.printf(", cp%d", i);
145  }
146  code.line(";");
147 }
static const char * TEXTURE_COORDINATES_ID
Texture coordinates shader variable name in vertex shader.
static const char * SAMPLE_ID_PREFIX
prefix of variables declaring a neighbor sample
Definition: operation.h:285
StringBuilder & line(const std::string &append)

◆ sample()

void SpatialFilteringMixin::sample ( StringBuilder code,
const char *  inputName,
const int  inputIndex,
const Point shift,
const bool  isFirstSample = true,
const char *  suffix = "" 
)
protected

Samples a neighborhood of a given texture.

Parameters
[in,out]codeThe GLSL code storage
[in]inputNameThe texture sampler array variable name
[in]inputIndexIndex of the texture in the array
[in]shiftSampling position shift
[in]isFirstSampleIf true, this is a very first sampling operation. A required initial setup will be run.
[in]suffixSampling operation suffix, e.g. ".rgb" to sample 3 values only

Definition at line 150 of file operation.cpp.

150  {
151  // shift neighborhood positions to the channel origin
152  if (isFirstSample || this->shift != shift) {
153  const int nbSize = std::max(nbSizeX, nbSizeY);
154  for (int i = 0; i < nbSize; ++i)
155  if (shift == Point::ZERO)
156  code.printf("cp%d = p%d;\n", i, i);
157  else
158  code.printf("cp%d = p%d + vec2(" POS_FMT ", " POS_FMT ");\n", i, i, shift.x, shift.y);
159  this->shift = shift;
160  }
161 
162  // sample input
163  for (int y = 0; y < nbSizeY; ++y)
164  for (int x = 0; x < nbSizeX; ++x)
165  if (x == y)
166  code.printf("%s%d%d = texture2D(%s[%d], cp%d)%s;\n",
167  SAMPLE_ID_PREFIX, x, y, inputName, inputIndex, x, suffix);
168  else
169  code.printf("%s%d%d = texture2D(%s[%d], vec2(cp%d.x, cp%d.y))%s;\n",
170  SAMPLE_ID_PREFIX, x, y, inputName, inputIndex, x, y, suffix);
171 }
static const CustomPoint ZERO
Definition: geometry.h:122
Point shift
current static shift of the sampling position
Definition: operation.h:275
#define POS_FMT
Definition: operation.cpp:21
jobject jlong jint jint y
jobject jlong jint x

◆ sampleInline()

void SpatialFilteringMixin::sampleInline ( StringBuilder code,
const char *  inputName,
const int  inputIndex,
const IntPoint position,
const Point shift,
const char *  suffix = "" 
)
protected

Definition at line 174 of file operation.cpp.

174  {
175 #ifdef BEATMUP_DEBUG
176  OutOfRange::check(position.x, 0, nbSizeX - 1, "neighbor X coordinate is out of range: %d");
177  OutOfRange::check(position.y, 0, nbSizeY - 1, "neighbor X coordinate is out of range: %d");
178 #endif
179 
180  // begin texture sampling statement
181  code.printf("texture2D(%s[%d], ", inputName, inputIndex);
182 
183  // print out texture coordinate
184  if (position.x == position.y)
185  code.printf("p%d", position.x);
186  else
187  code.printf("vec2(p%d.x, p%d.y)", position.x, position.y);
188 
189  if (shift != Point::ZERO)
190  code.printf(" + vec2(" POS_FMT ", " POS_FMT ")", shift.x, shift.y);
191 
192  // print the remainder
193  code.printf(")%s", suffix);
194 }
static void check(const datatype value, const datatype min, const datatype max, const char *message)
Definition: exception.h:86

◆ setup()

void SpatialFilteringMixin::setup ( const int  width,
const int  height 
)
protected

Prepares the spatial filtering operation execution.

Parameters
[in]widthInput texture width in pixels
[in]heightInput texture height in pixels

Definition at line 197 of file operation.cpp.

197  {
198  if (nbSizeX > 1 || nbSizeY > 1) {
199  const int deltaSize = getDeltasSize();
200  for (int i = 0; i < deltaSize; ++i) {
201  const float f = (float)(i + 1);
202  deltas[2*i ] = f / width;
203  deltas[2*i+1] = f / height;
204  }
205  }
206 }
jlong jint width
jlong jint jint height

◆ setUniformShift()

void SpatialFilteringMixin::setUniformShift ( GL::Program program,
const IntPoint shift,
const IntPoint inputSize 
)
protected

Applies an offset to the sampling position at runtime.

Only used if the uniform shift is enabled when writing out the header code.

Parameters
[in,out]programThe program
[in]shiftThe shift in pixels
[in]inputSizeSize of the sampled input texture in pixels

Definition at line 209 of file operation.cpp.

209  {
210 #ifdef BEATMUP_DEBUG
211  DebugAssertion::check(useUniformShift, "Uniform shift is not enabled");
212 #endif
213  program.setVector2(UNIFORM_SHIFT, (float)shift.x / inputSize.x, (float)shift.y / inputSize.y);
214 }
void setVector2(const std::string &name, const float x, const float y)
Definition: program.cpp:362

◆ setupProgram()

void SpatialFilteringMixin::setupProgram ( GL::Program program)
protected

Prepares a given program for spatial filtering.

Parameters
[in,out]programThe program

Definition at line 217 of file operation.cpp.

217  {
218  if (nbSizeX > 1 || nbSizeY > 1)
220 }
void setVec2Array(const std::string &name, const float *xy, const int length)
Definition: program.cpp:458

◆ getSamplingArea() [1/2]

IntRectangle SpatialFilteringMixin::getSamplingArea ( const IntPoint size,
const IntPoint stride,
const Size::Padding  padding 
) const
protected

Implements common padding policies by computing a rectangular area of positions the sampling kernel takes in order to get the result with the required padding.

Parameters
[in]sizeThe input size in pixels
[in]strideThe stride
[in]paddingThe padding policy
Returns
kernel center point positions in pixels.

Definition at line 223 of file operation.cpp.

223  {
224  const IntPoint halfKernel((nbSizeX - 1) / 2, (nbSizeY - 1) / 2);
225 
226  if (padding == Size::Padding::VALID) {
227  const IntPoint
228  // number of times the kernel is applied
229  n((size - IntPoint(nbSizeX, nbSizeY)) / stride + 1);
230 
231  return IntRectangle(halfKernel, halfKernel + (n - 1) * stride);
232  }
233 
234  else {
235  const IntPoint
236  // number of times the kernel is applied
237  n(ceili(size, stride)),
238 
239  // pixels participating in all the kernels applications (distance from border to border)
240  coverage = (n - 1) * stride + IntPoint(nbSizeX, nbSizeX),
241 
242  // excessive pixels to be padded on one side
243  ledge = (coverage - size) / 2,
244 
245  // the ledge part covered by kernel
246  kernelShift = std::min(halfKernel, halfKernel - ledge);
247 
248  return IntRectangle(kernelShift, kernelShift + (n - 1) * stride);
249  }
250 }
CustomRectangle< int > IntRectangle
Definition: geometry.h:630
CustomPoint< int > IntPoint
Definition: geometry.h:629
CustomPoint< numeric > min(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:724
#define ceili(x, y)
integer division x/y with ceiling
Definition: utils.hpp:21
jlong jobject size
int n

◆ getSamplingArea() [2/2]

IntRectangle SpatialFilteringMixin::getSamplingArea ( const Storage::View storage,
const int  channel,
const IntPoint stride,
const Size::Padding  padding 
) const
protected

Computes area in pixels to sample a given storage according to specific stride and padding.

Parameters
[in]storageThe input storage to sample
[in]channelNumber of the channel to sample
[in]strideThe stride
[in]paddingThe padding policy
Returns
kernel center point positions in pixels.

Definition at line 253 of file operation.cpp.

253  {
254  return getSamplingArea(
255  IntPoint(storage.getWidth(), storage.getHeight()),
256  stride, padding
257  ).translated(storage.getChannelOrigin(channel));
258 }
CustomRectangle translated(numeric x, numeric y) const
Returns a translated box.
Definition: geometry.h:235
IntRectangle getSamplingArea(const IntPoint &size, const IntPoint &stride, const Size::Padding padding) const
Implements common padding policies by computing a rectangular area of positions the sampling kernel t...
Definition: operation.cpp:223
IntPoint getChannelOrigin(int channel) const
Returns origin in pixels of a given channel within the texture containing it.
Definition: storage.cpp:509

◆ getTextureCoordinates()

Rectangle SpatialFilteringMixin::getTextureCoordinates ( const Storage::View storage,
const int  channel,
const IntPoint stride,
const Size::Padding  padding,
const IntPoint outputSize 
) const
protected

Computes texture coordinates sampling a specific storage channel for given stride, padding and output size.

Parameters
[in]storageThe storage to sample
[in]channelThe channel number in the storage to sample
[in]strideThe stride
[in]paddingThe padding
[in]outputSizeSize of output texture in pixels
Returns
rectangle containing texture coordinates.

Definition at line 261 of file operation.cpp.

267  {
269  getSamplingArea(storage, channel, stride, padding),
270  IntPoint(storage.getTextureWidth(), storage.getTextureHeight()),
271  outputSize
272  );
273 }
static Rectangle getTextureCoordinates(const Rectangle &area, const IntPoint &size, const IntPoint &sampling)
Computes floating-point texture coordinates for pixel-accurate sampling: a texture gets sampled exact...
Definition: pipeline.cpp:976
int getTextureHeight() const
Returns height in pixels of all the textures.
Definition: storage.h:375
int getTextureWidth() const
Returns width in pixels of all the textures.
Definition: storage.h:370

◆ getInputSamplingPos()

std::string SpatialFilteringMixin::getInputSamplingPos ( ) const
protected

Retrieves input sampling point position for the current fragment.

Defined after declare() is called.

Returns
the GLSL expression of the sampling position.

Definition at line 276 of file operation.cpp.

276  {
277  const int mid = (std::max(nbSizeX, nbSizeY) - 1) / 2;
278  return "p" + std::to_string(mid);
279 }
std::string to_string(Beatmup::NNets::ActivationFunction function)

◆ isUniformShiftUsed()

bool Beatmup::NNets::SpatialFilteringMixin::isUniformShiftUsed ( ) const
inlineprotected

Definition at line 394 of file operation.h.

394 { return useUniformShift; }

Member Data Documentation

◆ nbSizeX

const int Beatmup::NNets::SpatialFilteringMixin::nbSizeX
private

Definition at line 274 of file operation.h.

◆ nbSizeY

const int Beatmup::NNets::SpatialFilteringMixin::nbSizeY
private

Definition at line 274 of file operation.h.

◆ shift

Point Beatmup::NNets::SpatialFilteringMixin::shift
private

current static shift of the sampling position

Definition at line 275 of file operation.h.

◆ deltas

float* Beatmup::NNets::SpatialFilteringMixin::deltas
private

array storing pixel position differences for neighborhood sampling

Definition at line 276 of file operation.h.

◆ useUniformShift

bool Beatmup::NNets::SpatialFilteringMixin::useUniformShift
private

if true, the sampling position can be shifted dynamically at every run

Definition at line 277 of file operation.h.

◆ SAMPLE_ID_PREFIX

const char * SpatialFilteringMixin::SAMPLE_ID_PREFIX = "i"
staticprotected

prefix of variables declaring a neighbor sample

Definition at line 285 of file operation.h.


The documentation for this class was generated from the following files: