Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
fp_mode.h
Go to the documentation of this file.
1/*
2 This file is part of Ansel,
3 Copyright (C) 2026 Aurélien PIERRE.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with darktable. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifndef DT_SYSTEM_FP_MODE_H
20#define DT_SYSTEM_FP_MODE_H
21
22#include <math.h>
23
24#if defined(__x86_64__) || defined(__i386__)
25 #include <xmmintrin.h>
26#endif
27
28#if defined(__aarch64__)
29 #include <fenv.h>
30#endif
31
32#include <stdio.h>
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38typedef enum {
41 DT_FP_MODE_STRICT // debug/scientific
43
44
45static inline __attribute__((always_inline)) void set_fast_mode(void)
46{
47#if defined(__x86_64__) || defined(__i386__)
48 unsigned int mxcsr = _mm_getcsr();
49
50 // Flush denormals to zero
51 mxcsr |= _MM_FLUSH_ZERO_ON;
52
53 // (optional if available)
54#ifdef _MM_DENORMALS_ZERO_ON
55 mxcsr |= _MM_DENORMALS_ZERO_ON;
56#endif
57
58 _mm_setcsr(mxcsr);
59#endif
60
61#if defined(__aarch64__)
62 // Best-effort: ARM usually already fast for denormals in SIMD paths
63 fesetenv(FE_DFL_ENV);
64#endif
65}
66
67static inline __attribute__((always_inline)) void set_strict_mode(void)
68{
69#if defined(__x86_64__) || defined(__i386__)
70 unsigned int mxcsr = _mm_getcsr();
71
72 // Disable FTZ
73 mxcsr &= ~_MM_FLUSH_ZERO_ON;
74
75 _mm_setcsr(mxcsr);
76#endif
77
78#if defined(__aarch64__)
79 fesetenv(FE_DFL_ENV);
80#endif
81}
82
89static inline void __attribute__((always_inline)) dt_fp_init(const dt_cpu_fp_mode_t mode)
90{
91 switch(mode)
92 {
93 case DT_FP_MODE_FAST:
94 set_fast_mode();
95 break;
96
98 set_strict_mode();
99 break;
100
101 default:
102 // leave defaults unchanged
103 break;
104 }
105}
106
107static inline void dt_fp_print(const char *tag)
108{
109#if defined(__x86_64__) || defined(__i386__)
110 unsigned int mxcsr = _mm_getcsr();
111
112 fprintf(stdout, "[%s] MXCSR = 0x%08x\n", tag, mxcsr);
113
114 fprintf(stdout, " FTZ : %s\n", (mxcsr & _MM_FLUSH_ZERO_ON) ? "ON" : "OFF");
115
116#ifdef _MM_DENORMALS_ZERO_ON
117 fprintf(stdout, " DAZ : %s\n", (mxcsr & _MM_DENORMALS_ZERO_ON) ? "ON" : "OFF");
118#endif
119
120 fprintf(stdout, " exceptions mask: 0x%04x\n", (mxcsr >> 7) & 0x3f);
121#endif
122}
123
124#ifdef __cplusplus
125}
126#endif
127#endif // DT_SYSTEM_FP_MODE_H
dt_cpu_fp_mode_t
Definition fp_mode.h:38
@ DT_FP_MODE_FAST
Definition fp_mode.h:40
@ DT_FP_MODE_DEFAULT
Definition fp_mode.h:39
@ DT_FP_MODE_STRICT
Definition fp_mode.h:41
static void dt_fp_print(const char *tag)
Definition fp_mode.h:107
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Apply one channel's tone curve to each of the three colour channels, or pass the channel through unto...
Definition simd.h:55