unsigned instance;
unsigned index_limit;
unsigned count;
+ unsigned fpstate = util_fpstate_get();
struct pipe_draw_info resolved_info;
+ /* Make sure that denorms are treated like zeros. This is
+ * the behavior required by D3D10. OpenGL doesn't care.
+ */
+ util_fpstate_set_denorms_to_zero(fpstate);
+
resolve_draw_info(info, &resolved_info);
info = &resolved_info;
if (index_limit == 0) {
/* one of the buffers is too small to do any valid drawing */
debug_warning("draw: VBO too small to draw anything\n");
+ util_fpstate_set(fpstate);
return;
}
}
if (draw->collect_statistics) {
draw->render->pipeline_statistics(draw->render, &draw->statistics);
}
+ util_fpstate_set(fpstate);
}
#include "util/u_math.h"
+#include "util/u_cpu_detect.h"
/** 2^x, for x in [-1.0, 1.0) */
}
}
+/**
+ * Fetches the contents of the fpstate (mxcsr on x86) register.
+ *
+ * On platforms without support for it just returns 0.
+ */
+unsigned
+util_fpstate_get(void)
+{
+ unsigned mxcsr = 0;
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if (util_cpu_caps.has_sse) {
+ mxcsr = __builtin_ia32_stmxcsr();
+ }
+#endif
+ return mxcsr;
+}
+
+/**
+ * Make sure that the fp treats the denormalized floating
+ * point numbers as zero.
+ *
+ * This is the behavior required by D3D10. OpenGL doesn't care.
+ */
+unsigned
+util_fpstate_set_denorms_to_zero(unsigned current_mxcsr)
+{
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+#define MXCSR_DAZ (1 << 6) /* Enable denormals are zero mode */
+#define MXCSR_FTZ (1 << 15) /* Enable flush to zero mode */
+ if (util_cpu_caps.has_sse) {
+ current_mxcsr |= MXCSR_FTZ;
+ if (util_cpu_caps.has_sse3) {
+ current_mxcsr |= MXCSR_DAZ;
+ }
+ util_fpstate_set(current_mxcsr);
+ }
+#endif
+ return current_mxcsr;
+}
+
+/**
+ * Set the state of the fpstate (mxcsr on x86) register.
+ *
+ * On platforms without support for it's a noop.
+ */
+void
+util_fpstate_set(unsigned mxcsr)
+{
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if (util_cpu_caps.has_sse) {
+ __builtin_ia32_ldmxcsr(mxcsr);
+ }
+#endif
+}
struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data;
struct lp_rasterizer *rast = task->rast;
boolean debug = false;
+ unsigned fpstate = util_fpstate_get();
+
+ /* Make sure that denorms are treated like zeros. This is
+ * the behavior required by D3D10. OpenGL doesn't care.
+ */
+ util_fpstate_set_denorms_to_zero(fpstate);
while (1) {
/* wait for work */