/*
	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License version 2 
	as published by the Free Software Foundation.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


	Copyright (C) 2006  Thierry Berger-Perrin <tbptbp@gmail.com>
*/
#ifndef MATH_CONSTANTS_H
#define MATH_CONSTANTS_H

#include "specifics.h"
#ifndef _XBOX
/*
#include "sse.h"
#include <xmmintrin.h>	// __m128
#include <emmintrin.h>	// __m128i
*/
#include <xmmintrin.h>	// __m128
#include <emmintrin.h>	// __m128i
#endif

namespace cst {
	/*
		We're trying to bundle constants contiguously into a R/O section,
		therefore we need them not to be constructed (at runtime that is).
		Note that we use an union (to avoid aliasing), and it's initialized with an array of 32bit integers;
		to that effect you'll find such array as the first field.
		Does the Right Thing[tm] on msvc8 & gcc 3.4/4.1/4.2.
	*/
	// can't make those fields private, so be kind
	// and use them through these properly typed operators
	union MM_ALIGN16 wrapper_t {
		struct { int32_t	i0,i1,i2,i3; };
		struct { float32_t	f0,f1,f2,f3; };
#ifndef  _XBOX
		__m128		ps;
		__m128i		pi;
#endif // _XBOX
		float32_t	s;
		float32_t	i;
#ifndef  _XBOX
		FINLINE operator const __m128 &()		const { return ps; }
		FINLINE operator const __m128i &()		const { return pi; }
#endif // _XBOX
		FINLINE operator const float &()		const { return s; }
	};
	/*
		They are ordered as likely used.
		4 x wrapper_t = 1 cache line.
	*/
	struct MM_ALIGN16 section_t {
		wrapper_t
			plus_inf,
			// mostly used for NR refinements.
			three,
			one,
			half,
		
			all_clear,	// allow for index with bool
			all_set,
			minus_inf,
			luminance_gain,

			sign_mask,
			indeterminate,
			// both are for the sampler.
			packet_pattern_mask_x,	// x / 0 / x / 0
			packet_pattern_mask_y,	// y / y / 0 / 0

			// masks for ray selection, or anything else.
			selection_single[4],		// only one masked
			selection_multiple[16];		// addressable masking
	};

	// see raytrace_constants.cpp
	extern const section_t section;

	extern const uint_t MM_ALIGN16 wald_modulo[];

	// play with NaNs & co (sNaN, qNan, +/-NaN, indeterminate...etc)
	NOINLINE void check_oddities();
}
#endif
