@@ -200,7 +200,7 @@ CoordT<ImgT, Dims> DelinearizeToCoord(size_t Idx, range<Dims> ImageRange,
200200 } else if constexpr (Dims == 2 ) {
201201 Out = CoordT<ImgT, Dims>{Idx % ImageRange[0 ], Idx / ImageRange[0 ]};
202202 } else {
203- Out = CoordT<ImgT, Dims>{Idx % ImageRange[0 ] % ImageRange[ 1 ] ,
203+ Out = CoordT<ImgT, Dims>{Idx % ImageRange[0 ],
204204 Idx / ImageRange[0 ] % ImageRange[1 ],
205205 Idx / ImageRange[0 ] / ImageRange[1 ], 0 };
206206 }
@@ -328,3 +328,119 @@ ApplyAddressingMode(CoordT<ImageType::Sampled, Dims> Coord,
328328 }
329329 }
330330}
331+
332+ template <image_format Format> static constexpr size_t getMaxInt () {
333+ using rep_elem_type = typename FormatTraits<Format>::rep_elem_type;
334+ return static_cast <size_t >(std::numeric_limits<rep_elem_type>::max ());
335+ }
336+
337+ template <image_format Format>
338+ typename FormatTraits<Format>::pixel_type PickNewColor (size_t I,
339+ size_t AccSize) {
340+ using PixelType = typename FormatTraits<Format>::pixel_type;
341+ size_t Idx = I * 4 ;
342+
343+ // Pick a new color. Make sure it isn't too big for the data type.
344+ PixelType NewColor{Idx, Idx + 1 , Idx + 2 , Idx + 3 };
345+ NewColor = sycl::min (NewColor, PixelType{getMaxInt<Format>()});
346+ if constexpr (FormatTraits<Format>::Normalized)
347+ NewColor /= AccSize * 4 ;
348+ return NewColor;
349+ }
350+
351+ // Implemented as specified by the OpenCL 1.2 specification for
352+ // CLK_FILTER_NEAREST.
353+ template <image_format Format, addressing_mode AddrMode, int Dims>
354+ typename FormatTraits<Format>::pixel_type
355+ ReadNearest (typename FormatTraits<Format>::rep_elem_type *RefData,
356+ CoordT<ImageType::Sampled, Dims> Coord, range<2 > ImagePitch,
357+ range<Dims> ImageRange, bool Normalized) {
358+ CoordT<ImageType::Sampled, Dims> AdjCoord = Coord;
359+ if constexpr (AddrMode == addressing_mode::repeat) {
360+ assert (Normalized);
361+ AdjCoord -= sycl::floor (AdjCoord);
362+ AdjCoord *= RangeToCoord<ImageType::Sampled, Dims>(ImageRange);
363+ AdjCoord = sycl::floor (AdjCoord);
364+ } else if constexpr (AddrMode == addressing_mode::mirrored_repeat) {
365+ assert (Normalized);
366+ AdjCoord = 2 .0f * sycl::rint (0 .5f * Coord);
367+ AdjCoord = sycl::fabs (Coord - AdjCoord);
368+ AdjCoord *= RangeToCoord<ImageType::Sampled, Dims>(ImageRange);
369+ AdjCoord = sycl::floor (AdjCoord);
370+ } else {
371+ if (Normalized)
372+ AdjCoord *= RangeToCoord<ImageType::Sampled, Dims>(ImageRange);
373+ AdjCoord = sycl::floor (AdjCoord);
374+ }
375+ AdjCoord = ApplyAddressingMode<AddrMode>(AdjCoord, ImageRange);
376+ return SimulateRead<Format, ImageType::Sampled>(RefData, AdjCoord, ImagePitch,
377+ ImageRange, false );
378+ }
379+
380+ // Implemented as specified by the OpenCL 1.2 specification for
381+ // CLK_FILTER_LINEAR.
382+ template <image_format Format, addressing_mode AddrMode, int Dims>
383+ float4 CalcLinearRead (typename FormatTraits<Format>::rep_elem_type *RefData,
384+ CoordT<ImageType::Sampled, Dims> Coord,
385+ range<2 > ImagePitch, range<Dims> ImageRange,
386+ bool Normalized) {
387+ using UpscaledCoordT = CoordT<ImageType::Sampled, 3 >;
388+
389+ auto Read = [&](UpscaledCoordT UpCoord) {
390+ auto DownCoord = DownscaleCoord<Dims>(UpCoord);
391+ return SimulateRead<Format, ImageType::Sampled>(
392+ RefData, DownCoord, ImagePitch, ImageRange, false );
393+ };
394+
395+ CoordT<ImageType::Sampled, Dims> AdjCoord = Coord;
396+ if constexpr (AddrMode == addressing_mode::repeat) {
397+ assert (Normalized);
398+ AdjCoord -= floor (AdjCoord);
399+ AdjCoord *= RangeToCoord<ImageType::Sampled, Dims>(ImageRange);
400+ } else if constexpr (AddrMode == addressing_mode::mirrored_repeat) {
401+ assert (Normalized);
402+ AdjCoord = 2 .0f * sycl::rint (0 .5f * Coord);
403+ AdjCoord = sycl::fabs (Coord - AdjCoord);
404+ AdjCoord *= RangeToCoord<ImageType::Sampled, Dims>(ImageRange);
405+ } else {
406+ if (Normalized)
407+ AdjCoord *= RangeToCoord<ImageType::Sampled, Dims>(ImageRange);
408+ }
409+
410+ auto Prev = sycl::floor (AdjCoord - 0 .5f );
411+ auto Next = Prev + 1 ;
412+ auto CA = (AdjCoord - 0 .5f ) - Prev;
413+
414+ Prev = ApplyAddressingMode<AddrMode>(Prev, ImageRange);
415+ Next = ApplyAddressingMode<AddrMode>(Next, ImageRange);
416+
417+ auto UPrev = UpscaleCoord<Dims>(Prev);
418+ auto UNext = UpscaleCoord<Dims>(Next);
419+ auto UCA = UpscaleCoord<Dims>(CA, 1 );
420+
421+ auto CA000 = Read (UpscaledCoordT{UPrev[0 ], UPrev[1 ], UPrev[2 ], 0 })
422+ .template convert <float >() *
423+ (1 - UCA[0 ]) * (1 - UCA[1 ]) * (1 - UCA[2 ]);
424+ auto CA100 = Read (UpscaledCoordT{UNext[0 ], UPrev[1 ], UPrev[2 ], 0 })
425+ .template convert <float >() *
426+ UCA[0 ] * (1 - UCA[1 ]) * (1 - UCA[2 ]);
427+ auto CA010 = Read (UpscaledCoordT{UPrev[0 ], UNext[1 ], UPrev[2 ], 0 })
428+ .template convert <float >() *
429+ (1 - UCA[0 ]) * UCA[1 ] * (1 - UCA[2 ]);
430+ auto CA110 = Read (UpscaledCoordT{UNext[0 ], UNext[1 ], UPrev[2 ], 0 })
431+ .template convert <float >() *
432+ UCA[0 ] * UCA[1 ] * (1 - UCA[2 ]);
433+ auto CA001 = Read (UpscaledCoordT{UPrev[0 ], UPrev[1 ], UNext[2 ], 0 })
434+ .template convert <float >() *
435+ (1 - UCA[0 ]) * (1 - UCA[1 ]) * UCA[2 ];
436+ auto CA101 = Read (UpscaledCoordT{UNext[0 ], UPrev[1 ], UNext[2 ], 0 })
437+ .template convert <float >() *
438+ UCA[0 ] * (1 - UCA[1 ]) * UCA[2 ];
439+ auto CA011 = Read (UpscaledCoordT{UPrev[0 ], UNext[1 ], UNext[2 ], 0 })
440+ .template convert <float >() *
441+ (1 - UCA[0 ]) * UCA[1 ] * UCA[2 ];
442+ auto CA111 = Read (UpscaledCoordT{UNext[0 ], UNext[1 ], UNext[2 ], 0 })
443+ .template convert <float >() *
444+ UCA[0 ] * UCA[1 ] * UCA[2 ];
445+ return CA000 + CA100 + CA010 + CA110 + CA001 + CA101 + CA011 + CA111;
446+ }
0 commit comments