Merge "Check texture buffer support in texture format tests."
authorMika Isojarvi <misojarvi@google.com>
Thu, 28 Jan 2016 22:20:22 +0000 (22:20 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Thu, 28 Jan 2016 22:20:22 +0000 (22:20 +0000)
14 files changed:
framework/egl/egluUtil.cpp
framework/egl/egluUtil.hpp
modules/egl/teglCreateContextExtTests.cpp
modules/egl/teglCreateSurfaceTests.cpp
modules/egl/teglGLES2SharedRenderingPerfTests.cpp
modules/egl/teglGetProcAddressTests.cpp
modules/egl/teglImageFormatTests.cpp
modules/egl/teglInfoTests.cpp
modules/gles3/performance/es3pBufferDataUploadTests.cpp
modules/gles31/functional/es31fLayoutBindingTests.cpp
modules/gles31/functional/es31fPrimitiveBoundingBoxTests.cpp
modules/gles31/functional/es31fSSBOLayoutCase.cpp
modules/glshared/glsVertexArrayTests.cpp
modules/glshared/glsVertexArrayTests.hpp

index da126cc..a774f47 100644 (file)
@@ -83,12 +83,12 @@ bool hasExtension (const Library& egl, EGLDisplay display, const string& str)
        return de::contains(extensions.begin(), extensions.end(), str);
 }
 
-vector<string> getPlatformExtensions (const Library& egl)
+vector<string> getClientExtensions (const Library& egl)
 {
        return getExtensions(egl, EGL_NO_DISPLAY);
 }
 
-vector<string> getClientExtensions (const Library& egl, EGLDisplay display)
+vector<string> getDisplayExtensions (const Library& egl, EGLDisplay display)
 {
        DE_ASSERT(display != EGL_NO_DISPLAY);
 
@@ -236,7 +236,7 @@ EGLDisplay getDisplay (NativeDisplay& nativeDisplay)
 
        if (supportsPlatformGetDisplay)
        {
-               const vector<string> platformExts = getPlatformExtensions(egl);
+               const vector<string> platformExts = getClientExtensions(egl);
                usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
                                                 de::contains(platformExts.begin(), platformExts.end(), string(nativeDisplay.getPlatformExtensionName()));
        }
@@ -289,7 +289,7 @@ EGLSurface createWindowSurface (NativeDisplay& nativeDisplay, NativeWindow& wind
 
        if (supportsPlatformCreate)
        {
-               const vector<string> platformExts = getPlatformExtensions(egl);
+               const vector<string> platformExts = getClientExtensions(egl);
                usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
                                                 de::contains(platformExts.begin(), platformExts.end(), string(nativeDisplay.getPlatformExtensionName()));
        }
@@ -330,7 +330,7 @@ EGLSurface createPixmapSurface (NativeDisplay& nativeDisplay, NativePixmap& pixm
 
        if (supportsPlatformCreate)
        {
-               const vector<string> platformExts = getPlatformExtensions(egl);
+               const vector<string> platformExts = getClientExtensions(egl);
                usePlatformExt = de::contains(platformExts.begin(), platformExts.end(), string("EGL_EXT_platform_base")) &&
                                                 de::contains(platformExts.begin(), platformExts.end(), string(nativeDisplay.getPlatformExtensionName()));
        }
index 8c5dd3d..1fe322a 100644 (file)
@@ -56,8 +56,8 @@ std::vector<eglw::EGLint>             attribMapToList                         (const AttribMap& map);
 
 Version                                                        getVersion                                      (const eglw::Library& egl, eglw::EGLDisplay display);
 
-std::vector<std::string>               getPlatformExtensions           (const eglw::Library& egl);
-std::vector<std::string>               getClientExtensions                     (const eglw::Library& egl, eglw::EGLDisplay display);
+std::vector<std::string>               getClientExtensions                     (const eglw::Library& egl);
+std::vector<std::string>               getDisplayExtensions            (const eglw::Library& egl, eglw::EGLDisplay display);
 bool                                                   hasExtension                            (const eglw::Library& egl, eglw::EGLDisplay display, const std::string& extName);
 
 std::vector<eglw::EGLConfig>   getConfigs                                      (const eglw::Library& egl, eglw::EGLDisplay display);
index 5253926..5153b41 100644 (file)
@@ -369,7 +369,7 @@ void CreateContextExtCase::checkRequiredExtensions (void)
 {
        bool                    isOk = true;
        set<string>             requiredExtensions;
-       vector<string>  extensions                      = eglu::getClientExtensions(m_eglTestCtx.getLibrary(), m_display);
+       vector<string>  extensions                      = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_display);
 
        {
                const EGLint* iter = &(m_attribList[0]);
index 49c2381..712d06d 100644 (file)
@@ -56,7 +56,7 @@ namespace
 
 void checkEGLPlatformSupport (const Library& egl, const char* platformExt)
 {
-       std::vector<std::string> extensions = eglu::getPlatformExtensions(egl);
+       std::vector<std::string> extensions = eglu::getClientExtensions(egl);
 
        if (!de::contains(extensions.begin(), extensions.end(), platformExt))
                throw tcu::NotSupportedError((std::string("Platform extension '") + platformExt + "' not supported").c_str(), "", __FILE__, __LINE__);
index 5e2dcc9..d5e2312 100644 (file)
@@ -495,7 +495,7 @@ TestContext::TestContext (EglTestContext& testCtx, EGLDisplay eglDisplay, EGLCon
                || m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE
                || m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE)
        {
-               const vector<string> extensions = eglu::getClientExtensions(egl, m_eglDisplay);
+               const vector<string> extensions = eglu::getDisplayExtensions(egl, m_eglDisplay);
 
                if (!de::contains(extensions.begin(), extensions.end(), "EGL_KHR_image_base") ||
                        !de::contains(extensions.begin(), extensions.end(), "EGL_KHR_gl_texture_2D_image"))
index 7fd18c9..4c620ca 100644 (file)
@@ -124,10 +124,25 @@ GetProcAddressCase::~GetProcAddressCase (void)
 
 void GetProcAddressCase::init (void)
 {
+       try
+       {
+               m_supported = eglu::getClientExtensions(m_eglTestCtx.getLibrary());
+       }
+       catch (const eglu::Error& error)
+       {
+               // EGL_BAD_DISPLAY is generated if client extensions are not supported.
+               if (error.getError() != EGL_BAD_DISPLAY)
+                       throw;
+       }
+
        DE_ASSERT(m_display == EGL_NO_DISPLAY);
 
-       m_display       = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
-       m_supported     = eglu::getClientExtensions(m_eglTestCtx.getLibrary(), m_display);
+       m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
+
+       {
+               const std::vector<std::string> displayExtensios = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_display);
+               m_supported.insert(m_supported.end(), displayExtensios.begin(), displayExtensios.end());
+       }
 
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
 }
index e7cf0f4..2d46751 100644 (file)
@@ -923,7 +923,7 @@ void ImageFormatCase::checkExtensions (void)
        const EGLDisplay                dpy             = m_display;
        set<string>                             exts;
        const vector<string>    glExts  = de::splitString((const char*) m_gl.getString(GL_EXTENSIONS));
-       const vector<string>    eglExts = eglu::getClientExtensions(egl, dpy);
+       const vector<string>    eglExts = eglu::getDisplayExtensions(egl, dpy);
 
        exts.insert(glExts.begin(), glExts.end());
        exts.insert(eglExts.begin(), eglExts.end());
index 8ed6daf..44fd58e 100644 (file)
@@ -149,7 +149,7 @@ public:
        IterateResult iterate (void)
        {
                const Library&  egl                     = m_eglTestCtx.getLibrary();
-               vector<string>  extensions      = eglu::getClientExtensions(egl, m_display);
+               vector<string>  extensions      = eglu::getDisplayExtensions(egl, m_display);
 
                for (vector<string>::const_iterator i = extensions.begin(); i != extensions.end(); i++)
                        m_testCtx.getLog() << tcu::TestLog::Message << *i << tcu::TestLog::EndMessage;
index cc82fd5..bcd79a5 100644 (file)
@@ -2334,7 +2334,7 @@ void BasicUploadCase<SampleType>::deinit (void)
                m_dummyBufferID = 0;
        }
 
-       m_zeroData.clear();
+       m_zeroData = std::vector<deUint8>();
 
        BasicBufferCase<SampleType>::deinit();
 }
@@ -2534,7 +2534,7 @@ void ReferenceMemcpyCase::init (void)
 
 void ReferenceMemcpyCase::deinit (void)
 {
-       m_dstBuf.clear();
+       m_dstBuf = std::vector<deUint8>();
        BasicUploadCase<SingleOperationDuration>::deinit();
 }
 
@@ -3246,7 +3246,7 @@ void ModifyAfterBasicCase<SampleType>::init (void)
 template <typename SampleType>
 void ModifyAfterBasicCase<SampleType>::deinit (void)
 {
-       m_zeroData.clear();
+       m_zeroData = std::vector<deUint8>();
 
        BasicBufferCase<SampleType>::deinit();
 }
index 9c6b557..f925deb 100644 (file)
@@ -201,8 +201,8 @@ class LayoutBindingRenderCase : public TestCase
 public:
        enum
        {
-               TEST_RENDER_WIDTH       = 256,
-               TEST_RENDER_HEIGHT      = 256,
+               MAX_TEST_RENDER_WIDTH   = 256,
+               MAX_TEST_RENDER_HEIGHT  = 256,
                TEST_TEXTURE_SIZE       = 1,
        };
 
@@ -221,6 +221,8 @@ public:
        virtual void                                            init                                                    (void);
        virtual void                                            deinit                                                  (void);
 
+       int                                                                     getRenderWidth                                  (void) const { return de::min((int)MAX_TEST_RENDER_WIDTH, m_context.getRenderTarget().getWidth()); }
+       int                                                                     getRenderHeight                                 (void) const { return de::min((int)MAX_TEST_RENDER_HEIGHT, m_context.getRenderTarget().getHeight()); }
 protected:
        virtual glu::ShaderProgram*                     generateShaders                                 (void) const = 0;
 
@@ -519,7 +521,7 @@ void LayoutBindingRenderCase::initRenderState (void)
        const glw::Functions& gl = m_context.getRenderContext().getFunctions();
 
        gl.useProgram(m_program->getProgram());
-       gl.viewport(0, 0, TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
+       gl.viewport(0, 0, getRenderWidth(), getRenderHeight());
        gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set render state");
 }
@@ -527,7 +529,7 @@ void LayoutBindingRenderCase::initRenderState (void)
 bool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor)
 {
        const glw::Functions&   gl                                      = m_context.getRenderContext().getFunctions();
-       tcu::Surface                    reference                       (TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
+       tcu::Surface                    reference                       (getRenderWidth(), getRenderHeight());
 
        // the point of these test is to check layout_binding. For this purpose, we can use quite
        // large thresholds.
@@ -544,7 +546,7 @@ bool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor)
        GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed");
 
        // Verify
-       tcu::Surface result(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
+       tcu::Surface result(getRenderWidth(), getRenderHeight());
        m_testCtx.getLog() << TestLog::Message << "Reading pixels" << TestLog::EndMessage;
        glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
        GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
index 4748b7f..1391878 100644 (file)
@@ -4461,6 +4461,9 @@ void ViewportCallOrderCase::init (void)
        if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_primitive_bounding_box"))
                throw tcu::NotSupportedError("Test requires GL_EXT_primitive_bounding_box extension");
 
+       if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
+               throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
+
        m_testCtx.getLog()
                << tcu::TestLog::Message
                << "Testing call order of state setting functions have no effect on the rendering.\n"
index b265614..226c9eb 100644 (file)
@@ -1641,7 +1641,7 @@ bool compareComponents (glu::DataType scalarType, const void* ref, const void* r
                        const float             refVal          = *((const float*)ref + ndx);
                        const float             resVal          = *((const float*)res + ndx);
 
-                       if (deFloatAbs(resVal - refVal) >= threshold)
+                       if (!(deFloatAbs(resVal - refVal) <= threshold))
                                return false;
                }
        }
index 54cb855..6509f6d 100644 (file)
@@ -1308,12 +1308,12 @@ class RandomArrayGenerator
 {
 public:
        static char*    generateArray                   (int seed, GLValue min, GLValue max, int count, int componentCount, int stride, Array::InputType type);
-       static char*    generateQuads                   (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max);
+       static char*    generateQuads                   (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize);
        static char*    generatePerQuad                 (int seed, int count, int componentCount, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max);
 
 private:
        template<typename T>
-       static char*    createQuads             (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max);
+       static char*    createQuads             (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize);
        template<typename T>
        static char*    createPerQuads  (int seed, int count, int componentCount, int stride, Array::Primitive primitive, T min, T max);
        static char*    createQuadsPacked (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive);
@@ -1413,50 +1413,50 @@ char* RandomArrayGenerator::generateArray (int seed, GLValue min, GLValue max, i
        return data;
 }
 
-char* RandomArrayGenerator::generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max)
+char* RandomArrayGenerator::generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize)
 {
        char* data = DE_NULL;
 
        switch (type)
        {
                case Array::INPUTTYPE_FLOAT:
-                       data = createQuads<GLValue::Float>(seed, count, componentCount, offset, stride, primitive, min.fl, max.fl);
+                       data = createQuads<GLValue::Float>(seed, count, componentCount, offset, stride, primitive, min.fl, max.fl, gridSize);
                        break;
 
                case Array::INPUTTYPE_FIXED:
-                       data = createQuads<GLValue::Fixed>(seed, count, componentCount, offset, stride, primitive, min.fi, max.fi);
+                       data = createQuads<GLValue::Fixed>(seed, count, componentCount, offset, stride, primitive, min.fi, max.fi, gridSize);
                        break;
 
                case Array::INPUTTYPE_DOUBLE:
-                       data = createQuads<GLValue::Double>(seed, count, componentCount, offset, stride, primitive, min.d, max.d);
+                       data = createQuads<GLValue::Double>(seed, count, componentCount, offset, stride, primitive, min.d, max.d, gridSize);
                        break;
 
                case Array::INPUTTYPE_BYTE:
-                       data = createQuads<GLValue::Byte>(seed, count, componentCount, offset, stride, primitive, min.b, max.b);
+                       data = createQuads<GLValue::Byte>(seed, count, componentCount, offset, stride, primitive, min.b, max.b, gridSize);
                        break;
 
                case Array::INPUTTYPE_SHORT:
-                       data = createQuads<GLValue::Short>(seed, count, componentCount, offset, stride, primitive, min.s, max.s);
+                       data = createQuads<GLValue::Short>(seed, count, componentCount, offset, stride, primitive, min.s, max.s, gridSize);
                        break;
 
                case Array::INPUTTYPE_UNSIGNED_BYTE:
-                       data = createQuads<GLValue::Ubyte>(seed, count, componentCount, offset, stride, primitive, min.ub, max.ub);
+                       data = createQuads<GLValue::Ubyte>(seed, count, componentCount, offset, stride, primitive, min.ub, max.ub, gridSize);
                        break;
 
                case Array::INPUTTYPE_UNSIGNED_SHORT:
-                       data = createQuads<GLValue::Ushort>(seed, count, componentCount, offset, stride, primitive, min.us, max.us);
+                       data = createQuads<GLValue::Ushort>(seed, count, componentCount, offset, stride, primitive, min.us, max.us, gridSize);
                        break;
 
                case Array::INPUTTYPE_UNSIGNED_INT:
-                       data = createQuads<GLValue::Uint>(seed, count, componentCount, offset, stride, primitive, min.ui, max.ui);
+                       data = createQuads<GLValue::Uint>(seed, count, componentCount, offset, stride, primitive, min.ui, max.ui, gridSize);
                        break;
 
                case Array::INPUTTYPE_INT:
-                       data = createQuads<GLValue::Int>(seed, count, componentCount, offset, stride, primitive, min.i, max.i);
+                       data = createQuads<GLValue::Int>(seed, count, componentCount, offset, stride, primitive, min.i, max.i, gridSize);
                        break;
 
                case Array::INPUTTYPE_HALF:
-                       data = createQuads<GLValue::Half>(seed, count, componentCount, offset, stride, primitive, min.h, max.h);
+                       data = createQuads<GLValue::Half>(seed, count, componentCount, offset, stride, primitive, min.h, max.h, gridSize);
                        break;
 
                case Array::INPUTTYPE_INT_2_10_10_10:
@@ -1545,13 +1545,20 @@ char* RandomArrayGenerator::createQuadsPacked (int seed, int count, int componen
 }
 
 template<typename T>
-char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max)
+T roundTo (const T& step, const T& value)
+{
+       return value - (value % step);
+}
+
+template<typename T>
+char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize)
 {
        int componentStride = sizeof(T);
        int quadStride = 0;
 
        if (stride == 0)
                stride = componentCount * componentStride;
+
        DE_ASSERT(stride >= componentCount * componentStride);
 
        switch (primitive)
@@ -1576,6 +1583,11 @@ char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount
        {
                case Array::PRIMITIVE_TRIANGLES:
                {
+                       const T minQuadSize     = T::fromFloat(deFloatAbs(max.template to<float>() - min.template to<float>()) * gridSize);
+                       const T minDiff         = minValue<T>() > minQuadSize
+                                                               ? minValue<T>()
+                                                               : minQuadSize;
+
                        for (int quadNdx = 0; quadNdx < count; ++quadNdx)
                        {
                                T x1, x2;
@@ -1585,22 +1597,22 @@ char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount
                                // attempt to find a good (i.e not extremely small) quad
                                for (int attemptNdx = 0; attemptNdx < 4; ++attemptNdx)
                                {
-                                       x1 = getRandom<T>(rnd, min, max);
-                                       x2 = getRandom<T>(rnd, minValue<T>(), abs<T>(max - x1));
+                                       x1 = roundTo(minDiff, getRandom<T>(rnd, min, max));
+                                       x2 = roundTo(minDiff, getRandom<T>(rnd, minDiff, abs<T>(max - x1)));
 
-                                       y1 = getRandom<T>(rnd, min, max);
-                                       y2 = getRandom<T>(rnd, minValue<T>(), abs<T>(max - y1));
+                                       y1 = roundTo(minDiff, getRandom<T>(rnd, min, max));
+                                       y2 = roundTo(minDiff, getRandom<T>(rnd, minDiff, abs<T>(max - y1)));
 
-                                       z = (componentCount > 2) ? (getRandom<T>(rnd, min, max)) : (T::create(0));
-                                       w = (componentCount > 3) ? (getRandom<T>(rnd, min, max)) : (T::create(1));
+                                       z = (componentCount > 2) ? roundTo(minDiff, (getRandom<T>(rnd, min, max))) : (T::create(0));
+                                       w = (componentCount > 3) ? roundTo(minDiff, (getRandom<T>(rnd, min, max))) : (T::create(1));
 
                                        // no additional components, all is good
                                        if (componentCount <= 2)
                                                break;
 
                                        // The result quad is too thin?
-                                       if ((deFloatAbs(x2.template to<float>() + z.template to<float>()) < minValue<T>().template to<float>()) ||
-                                               (deFloatAbs(y2.template to<float>() + w.template to<float>()) < minValue<T>().template to<float>()))
+                                       if ((deFloatAbs(x2.template to<float>() + z.template to<float>()) < minDiff.template to<float>()) ||
+                                               (deFloatAbs(y2.template to<float>() + w.template to<float>()) < minDiff.template to<float>()))
                                                continue;
 
                                        // all ok
@@ -2075,6 +2087,8 @@ MultiVertexArrayTest::IterateResult MultiVertexArrayTest::iterate (void)
                        const char*             data                    = DE_NULL;
                        const size_t    stride                  = (arraySpec.stride == 0) ? (arraySpec.componentCount * Array::inputTypeSize(arraySpec.inputType)) : (arraySpec.stride);
                        const size_t    bufferSize              = arraySpec.offset + stride * (m_spec.drawCount * primitiveSize - 1) + arraySpec.componentCount  * Array::inputTypeSize(arraySpec.inputType);
+                       // Snap values to at least 3x3 grid
+                       const float             gridSize                = 3.0f / (float)(de::min(m_renderCtx.getRenderTarget().getWidth(), m_renderCtx.getRenderTarget().getHeight()) - 1);
 
                        switch (m_spec.primitive)
                        {
@@ -2084,7 +2098,7 @@ MultiVertexArrayTest::IterateResult MultiVertexArrayTest::iterate (void)
                                case Array::PRIMITIVE_TRIANGLES:
                                        if (arrayNdx == 0)
                                        {
-                                               data = RandomArrayGenerator::generateQuads(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.offset, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max);
+                                               data = RandomArrayGenerator::generateQuads(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.offset, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max, gridSize);
                                        }
                                        else
                                        {
index 25a04a3..b7539d4 100644 (file)
@@ -31,6 +31,7 @@
 #include "tcuTestLog.hpp"
 #include "gluShaderProgram.hpp"
 #include "deFloat16.h"
+#include "deMath.h"
 #include "tcuFloat.hpp"
 #include "tcuPixelFormat.hpp"
 #include "sglrContext.hpp"
@@ -236,17 +237,18 @@ private:
 class GLValue
 {
 public:
-
        template<class Type>
        class WrappedType
        {
        public:
                static WrappedType<Type>        create                  (Type value)                                                    { WrappedType<Type> v; v.m_value = value; return v; }
+               static WrappedType<Type>        fromFloat               (float value)                                                   { WrappedType<Type> v; v.m_value = (Type)value; return v; }
                inline Type                                     getValue                (void) const                                                    { return m_value; }
 
                inline WrappedType<Type>        operator+               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value + other.getValue())); }
                inline WrappedType<Type>        operator*               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value * other.getValue())); }
                inline WrappedType<Type>        operator/               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value / other.getValue())); }
+               inline WrappedType<Type>        operator%               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value % other.getValue())); }
                inline WrappedType<Type>        operator-               (const WrappedType<Type>& other) const  { return WrappedType<Type>::create((Type)(m_value - other.getValue())); }
 
                inline WrappedType<Type>&       operator+=              (const WrappedType<Type>& other)                { m_value += other.getValue(); return *this; }
@@ -268,27 +270,62 @@ public:
                Type    m_value;
        };
 
-       typedef WrappedType<deInt16>    Short;
-       typedef WrappedType<deUint16>   Ushort;
+       template<class Type>
+       class WrappedFloatType
+       {
+       public:
+               static WrappedFloatType<Type>   create                  (Type value)                                                    { WrappedFloatType<Type> v; v.m_value = value; return v; }
+               static WrappedFloatType<Type>   fromFloat               (float value)                                                   { WrappedFloatType<Type> v; v.m_value = (Type)value; return v; }
+               inline Type                                             getValue                (void) const                                                    { return m_value; }
+
+               inline WrappedFloatType<Type>   operator+               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value + other.getValue())); }
+               inline WrappedFloatType<Type>   operator*               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value * other.getValue())); }
+               inline WrappedFloatType<Type>   operator/               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value / other.getValue())); }
+               inline WrappedFloatType<Type>   operator%               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(deMod(m_value, other.getValue()))); }
+               inline WrappedFloatType<Type>   operator-               (const WrappedFloatType<Type>& other) const     { return WrappedFloatType<Type>::create((Type)(m_value - other.getValue())); }
+
+               inline WrappedFloatType<Type>&  operator+=              (const WrappedFloatType<Type>& other)           { m_value += other.getValue(); return *this; }
+               inline WrappedFloatType<Type>&  operator*=              (const WrappedFloatType<Type>& other)           { m_value *= other.getValue(); return *this; }
+               inline WrappedFloatType<Type>&  operator/=              (const WrappedFloatType<Type>& other)           { m_value /= other.getValue(); return *this; }
+               inline WrappedFloatType<Type>&  operator-=              (const WrappedFloatType<Type>& other)           { m_value -= other.getValue(); return *this; }
+
+               inline bool                                             operator==              (const WrappedFloatType<Type>& other) const     { return m_value == other.m_value; }
+               inline bool                                             operator!=              (const WrappedFloatType<Type>& other) const     { return m_value != other.m_value; }
+               inline bool                                             operator<               (const WrappedFloatType<Type>& other) const     { return m_value < other.m_value; }
+               inline bool                                             operator>               (const WrappedFloatType<Type>& other) const     { return m_value > other.m_value; }
+               inline bool                                             operator<=              (const WrappedFloatType<Type>& other) const     { return m_value <= other.m_value; }
+               inline bool                                             operator>=              (const WrappedFloatType<Type>& other) const     { return m_value >= other.m_value; }
+
+               inline                                                  operator Type   (void) const                                                    { return m_value; }
+               template<class T>
+               inline T                                                to                              (void) const                                                    { return (T)m_value; }
+       private:
+               Type    m_value;
+       };
+
+       typedef WrappedType<deInt16>            Short;
+       typedef WrappedType<deUint16>           Ushort;
 
-       typedef WrappedType<deInt8>             Byte;
-       typedef WrappedType<deUint8>    Ubyte;
+       typedef WrappedType<deInt8>                     Byte;
+       typedef WrappedType<deUint8>            Ubyte;
 
-       typedef WrappedType<float>              Float;
-       typedef WrappedType<double>             Double;
+       typedef WrappedFloatType<float>         Float;
+       typedef WrappedFloatType<double>        Double;
 
-       typedef WrappedType<deInt32>    Int;
-       typedef WrappedType<deUint32>   Uint;
+       typedef WrappedType<deInt32>            Int;
+       typedef WrappedType<deUint32>           Uint;
 
        class Half
        {
        public:
                static Half                     create                  (float value)                           { Half h; h.m_value = floatToHalf(value); return h; }
+               static Half                     fromFloat               (float value)                           { Half h; h.m_value = floatToHalf(value); return h; }
                inline deFloat16        getValue                (void) const                            { return m_value; }
 
                inline Half                     operator+               (const Half& other) const       { return create(halfToFloat(m_value) + halfToFloat(other.getValue())); }
                inline Half                     operator*               (const Half& other) const       { return create(halfToFloat(m_value) * halfToFloat(other.getValue())); }
                inline Half                     operator/               (const Half& other) const       { return create(halfToFloat(m_value) / halfToFloat(other.getValue())); }
+               inline Half                     operator%               (const Half& other) const       { return create(deFloatMod(halfToFloat(m_value), halfToFloat(other.getValue()))); }
                inline Half                     operator-               (const Half& other) const       { return create(halfToFloat(m_value) - halfToFloat(other.getValue())); }
 
                inline Half&            operator+=              (const Half& other)                     { m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; }
@@ -316,11 +353,13 @@ public:
        {
        public:
                static Fixed            create                  (deInt32 value)                         { Fixed v; v.m_value = value; return v; }
+               static Fixed            fromFloat               (float value)                           { Fixed v; v.m_value = (deInt32)(value * 32768.0f); return v; }
                inline deInt32          getValue                (void) const                            { return m_value; }
 
                inline Fixed            operator+               (const Fixed& other) const      { return create(m_value + other.getValue()); }
                inline Fixed            operator*               (const Fixed& other) const      { return create(m_value * other.getValue()); }
                inline Fixed            operator/               (const Fixed& other) const      { return create(m_value / other.getValue()); }
+               inline Fixed            operator%               (const Fixed& other) const      { return create(m_value % other.getValue()); }
                inline Fixed            operator-               (const Fixed& other) const      { return create(m_value - other.getValue()); }
 
                inline Fixed&           operator+=              (const Fixed& other)            { m_value += other.getValue(); return *this; }