diff options
34 files changed, 3574 insertions, 171 deletions
diff --git a/3rdparty/bgfx/3rdparty/iqa/LICENSE b/3rdparty/bgfx/3rdparty/iqa/LICENSE new file mode 100644 index 00000000000..ff67944bfde --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/LICENSE @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/3rdparty/bgfx/3rdparty/iqa/README.txt b/3rdparty/bgfx/3rdparty/iqa/README.txt new file mode 100644 index 00000000000..0a95346fe8a --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/README.txt @@ -0,0 +1,36 @@ +Doxygen documentation can be found at: http://tdistler.com/iqa + +BUILD: + + All build artifacts end up in build/<configuration>, where <configuration> is + 'debug' or 'release'. + + Windows: + - Open iqa.sln, select 'Debug' or 'Release', and build. The output is a + static library 'iqa.lib'. + - To run the tests under the debugger, first right-click the 'test' project, + select Properties -> Configuration Properties -> Debugging and set + 'Working Directory' to '$(OutDir)'. Then start the application. + + Linux: + - Change directories into the root of the IQA branch you want to build. + - Type `make` for a debug build, or `make RELEASE=1` for a release build. + The output is a static library 'libiqa.a'. + - Type `make test` (or `make test RELEASE=1`) to build the unit tests. + - Type `make clean` (or `make clean RELEASE=1`) to delete all build + artifacts. + - To run the tests, `cd` to the build/<configuration> directory and type + `./test`. + + +USE: + + - Include 'iqa.h' in your source file. + - Call iqa_* methods. + - Link against the IQA library. + + +HELP & SUPPORT: + + Further help can be found at: https://sourceforge.net/projects/iqa/support + diff --git a/3rdparty/bgfx/3rdparty/iqa/include/convolve.h b/3rdparty/bgfx/3rdparty/iqa/include/convolve.h new file mode 100644 index 00000000000..a5e2e71a211 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/include/convolve.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _CONVOLVE_H_ +#define _CONVOLVE_H_ + +typedef float (*_iqa_get_pixel)(const float *img, int w, int h, int x, int y, float bnd_const); + +/** Out-of-bounds array values are a mirrored reflection of the border values*/ +float KBND_SYMMETRIC(const float *img, int w, int h, int x, int y, float bnd_const); +/** Out-of-bounds array values are set to the nearest border value */ +float KBND_REPLICATE(const float *img, int w, int h, int x, int y, float bnd_const); +/** Out-of-bounds array values are set to 'bnd_const' */ +float KBND_CONSTANT(const float *img, int w, int h, int x, int y, float bnd_const); + + +/** Defines a convolution kernel */ +struct _kernel { + float *kernel; /**< Pointer to the kernel values */ + int w; /**< The kernel width */ + int h; /**< The kernel height */ + int normalized; /**< 1 if the kernel values add up to 1. 0 otherwise */ + _iqa_get_pixel bnd_opt; /**< Defines how out-of-bounds image values are handled */ + float bnd_const; /**< If 'bnd_opt' is KBND_CONSTANT, this specifies the out-of-bounds value */ +}; + +/** + * @brief Applies the specified kernel to the image. + * The kernel will be applied to all areas where it fits completely within + * the image. The resulting image will be smaller by half the kernel width + * and height (w - kw/2 and h - kh/2). + * + * @param img Image to modify + * @param w Image width + * @param h Image height + * @param k The kernel to apply + * @param result Buffer to hold the resulting image ((w-kw)*(h-kh), where kw + * and kh are the kernel width and height). If 0, the result + * will be written to the original image buffer. + * @param rw Optional. The width of the resulting image will be stored here. + * @param rh Optional. The height of the resulting image will be stored here. + */ +void _iqa_convolve(float *img, int w, int h, const struct _kernel *k, float *result, int *rw, int *rh); + +/** + * The same as _iqa_convolve() except the kernel is applied to the entire image. + * In other words, the kernel is applied to all areas where the top-left corner + * of the kernel is in the image. Out-of-bound pixel value (off the right and + * bottom edges) are chosen based on the 'bnd_opt' and 'bnd_const' members of + * the kernel structure. The resulting array is the same size as the input + * image. + * + * @param img Image to modify + * @param w Image width + * @param h Image height + * @param k The kernel to apply + * @param result Buffer to hold the resulting image ((w-kw)*(h-kh), where kw + * and kh are the kernel width and height). If 0, the result + * will be written to the original image buffer. + * @return 0 if successful. Non-zero otherwise. + */ +int _iqa_img_filter(float *img, int w, int h, const struct _kernel *k, float *result); + +/** + * Returns the filtered version of the specified pixel. If no kernel is given, + * the raw pixel value is returned. + * + * @param img Source image + * @param w Image width + * @param h Image height + * @param x The x location of the pixel to filter + * @param y The y location of the pixel to filter + * @param k Optional. The convolution kernel to apply to the pixel. + * @param kscale The scale of the kernel (for normalization). 1 for normalized + * kernels. Required if 'k' is not null. + * @return The filtered pixel value. + */ +float _iqa_filter_pixel(const float *img, int w, int h, int x, int y, const struct _kernel *k, const float kscale); + + +#endif /*_CONVOLVE_H_*/ diff --git a/3rdparty/bgfx/3rdparty/iqa/include/decimate.h b/3rdparty/bgfx/3rdparty/iqa/include/decimate.h new file mode 100644 index 00000000000..40f1a8c04e5 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/include/decimate.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _DECIMATE_H_ +#define _DECIMATE_H_ + +#include "convolve.h" + +/** + * @brief Downsamples (decimates) an image. + * + * @param img Image to modify + * @param w Image width + * @param h Image height + * @param factor Decimation factor + * @param k The kernel to apply (e.g. low-pass filter). Can be 0. + * @param result Buffer to hold the resulting image (w/factor*h/factor). If 0, + * the result will be written to the original image buffer. + * @param rw Optional. The width of the resulting image will be stored here. + * @param rh Optional. The height of the resulting image will be stored here. + * @return 0 on success. + */ +int _iqa_decimate(float *img, int w, int h, int factor, const struct _kernel *k, float *result, int *rw, int *rh); + +#endif /*_DECIMATE_H_*/ diff --git a/3rdparty/bgfx/3rdparty/iqa/include/iqa.h b/3rdparty/bgfx/3rdparty/iqa/include/iqa.h new file mode 100644 index 00000000000..408675e5abe --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/include/iqa.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _IQA_H_ +#define _IQA_H_ + +#include "iqa_os.h" + +/** + * Allows fine-grain control of the SSIM algorithm. + */ +struct iqa_ssim_args { + float alpha; /**< luminance exponent */ + float beta; /**< contrast exponent */ + float gamma; /**< structure exponent */ + int L; /**< dynamic range (2^8 - 1)*/ + float K1; /**< stabilization constant 1 */ + float K2; /**< stabilization constant 2 */ + int f; /**< scale factor. 0=default scaling, 1=no scaling */ +}; + +/** + * Allows fine-grain control of the MS-SSIM algorithm. + */ +struct iqa_ms_ssim_args { + int wang; /**< 1=original algorithm by Wang, et al. 0=MS-SSIM* by Rouse/Hemami (default). */ + int gaussian; /**< 1=11x11 Gaussian window (default). 0=8x8 linear window. */ + int scales; /**< Number of scaled images to use. Default is 5. */ + const float *alphas; /**< Pointer to array of alpha values for each scale. Required if 'scales' isn't 5. */ + const float *betas; /**< Pointer to array of beta values for each scale. Required if 'scales' isn't 5. */ + const float *gammas; /**< Pointer to array of gamma values for each scale. Required if 'scales' isn't 5. */ +}; + +/** + * Calculates the Mean Squared Error between 2 equal-sized 8-bit images. + * @note The images must have the same width, height, and stride. + * @param ref Original reference image + * @param cmp Distorted image + * @param w Width of the images + * @param h Height of the images + * @param stride The length (in bytes) of each horizontal line in the image. + * This may be different from the image width. + * @return The MSE. + */ +float iqa_mse(const unsigned char *ref, const unsigned char *cmp, int w, int h, int stride); + +/** + * Calculates the Peak Signal-to-Noise-Ratio between 2 equal-sized 8-bit + * images. + * @note The images must have the same width, height, and stride. + * @param ref Original reference image + * @param cmp Distorted image + * @param w Width of the images + * @param h Height of the images + * @param stride The length (in bytes) of each horizontal line in the image. + * This may be different from the image width. + * @return The PSNR. + */ +float iqa_psnr(const unsigned char *ref, const unsigned char *cmp, int w, int h, int stride); + +/** + * Calculates the Structural SIMilarity between 2 equal-sized 8-bit images. + * + * See https://ece.uwaterloo.ca/~z70wang/publications/ssim.html + * @note The images must have the same width, height, and stride. + * @param ref Original reference image + * @param cmp Distorted image + * @param w Width of the images + * @param h Height of the images + * @param stride The length (in bytes) of each horizontal line in the image. + * This may be different from the image width. + * @param gaussian 0 = 8x8 square window, 1 = 11x11 circular-symmetric Gaussian + * weighting. + * @param args Optional SSIM arguments for fine control of the algorithm. 0 for + * defaults. Defaults are a=b=g=1.0, L=255, K1=0.01, K2=0.03 + * @return The mean SSIM over the entire image (MSSIM), or INFINITY if error. + */ +float iqa_ssim(const unsigned char *ref, const unsigned char *cmp, int w, int h, int stride, + int gaussian, const struct iqa_ssim_args *args); + +/** + * Calculates the Multi-Scale Structural SIMilarity between 2 equal-sized 8-bit + * images. The default algorithm is MS-SSIM* proposed by Rouse/Hemami 2008. + * + * See https://ece.uwaterloo.ca/~z70wang/publications/msssim.pdf and + * http://foulard.ece.cornell.edu/publications/dmr_hvei2008_paper.pdf + * + * @note 1. The images must have the same width, height, and stride. + * @note 2. The minimum image width or height is 2^(scales-1) * filter, where 'filter' is 11 + * if a Gaussian window is being used, or 9 otherwise. + * @param ref Original reference image + * @param cmp Distorted image + * @param w Width of the images. + * @param h Height of the images. + * @param stride The length (in bytes) of each horizontal line in the image. + * This may be different from the image width. + * @param args Optional MS-SSIM arguments for fine control of the algorithm. 0 + * for defaults. Defaults are wang=0, scales=5, gaussian=1. + * @return The mean MS-SSIM over the entire image, or INFINITY if error. + */ +float iqa_ms_ssim(const unsigned char *ref, const unsigned char *cmp, int w, int h, int stride, + const struct iqa_ms_ssim_args *args); + +#endif /*_IQA_H_*/ diff --git a/3rdparty/bgfx/3rdparty/iqa/include/iqa_os.h b/3rdparty/bgfx/3rdparty/iqa/include/iqa_os.h new file mode 100644 index 00000000000..52e0be0169a --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/include/iqa_os.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _OS_H_ +#define _OS_H_ + +/* Microsoft tends to implement features early, but they have a high legacy + * cost because they won't break existing implementations. As such, certain + * features we take for granted on other platforms (like C99) aren't fully + * implemented. This file is meant to rectify that. + */ + +#ifdef WIN32 + +#include <windows.h> +#include <math.h> + +#define IQA_INLINE __inline + +#ifndef INFINITY + #define INFINITY (float)HUGE_VAL /**< Defined in C99 (Windows is C89) */ +#endif /*INFINITY*/ + +#ifndef NAN + static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; + #define NAN (*(const float *) __nan) /**< Defined in C99 (Windows is C99) */ +#endif + +#define IQA_EXPORT __declspec(dllexport) + +#else /* !Windows */ + +#define IQA_INLINE inline +#define IQA_EXPORT + +#endif + +#endif /* _OS_H_ */ diff --git a/3rdparty/bgfx/3rdparty/iqa/include/math_utils.h b/3rdparty/bgfx/3rdparty/iqa/include/math_utils.h new file mode 100644 index 00000000000..0445caa42ed --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/include/math_utils.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MATH_UTILS_H_ +#define _MATH_UTILS_H_ + +#include "iqa_os.h" +#include <math.h> + +/** + * Rounds a float to the nearest integer. + */ +IQA_EXPORT IQA_INLINE int _round(float a); + +IQA_EXPORT IQA_INLINE int _max(int x, int y); + +IQA_EXPORT IQA_INLINE int _min(int x, int y); + + +/** + * Compares 2 floats to the specified digit of precision. + * @return 0 if equal, 1 otherwise. + */ +IQA_EXPORT IQA_INLINE int _cmp_float(float a, float b, int digits); + + +/** + * Compares 2 matrices with the specified precision. 'b' is assumed to be the + * same size as 'a' or smaller. + * @return 0 if equal, 1 otherwise + */ +IQA_EXPORT IQA_INLINE int _matrix_cmp(const float *a, const float *b, int w, int h, int digits); + +#endif /*_MATH_UTILS_H_*/ diff --git a/3rdparty/bgfx/3rdparty/iqa/include/ssim.h b/3rdparty/bgfx/3rdparty/iqa/include/ssim.h new file mode 100644 index 00000000000..5653afe8064 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/include/ssim.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SSIM_H_ +#define _SSIM_H_ + +#include "convolve.h" + +/* + * Circular-symmetric Gaussian weighting. + * h(x,y) = hg(x,y)/SUM(SUM(hg)) , for normalization to 1.0 + * hg(x,y) = e^( -0.5*( (x^2+y^2)/sigma^2 ) ) , where sigma was 1.5 + */ +#define GAUSSIAN_LEN 11 +static const float g_gaussian_window[GAUSSIAN_LEN][GAUSSIAN_LEN] = { + {0.000001f, 0.000008f, 0.000037f, 0.000112f, 0.000219f, 0.000274f, 0.000219f, 0.000112f, 0.000037f, 0.000008f, 0.000001f}, + {0.000008f, 0.000058f, 0.000274f, 0.000831f, 0.001619f, 0.002021f, 0.001619f, 0.000831f, 0.000274f, 0.000058f, 0.000008f}, + {0.000037f, 0.000274f, 0.001296f, 0.003937f, 0.007668f, 0.009577f, 0.007668f, 0.003937f, 0.001296f, 0.000274f, 0.000037f}, + {0.000112f, 0.000831f, 0.003937f, 0.011960f, 0.023294f, 0.029091f, 0.023294f, 0.011960f, 0.003937f, 0.000831f, 0.000112f}, + {0.000219f, 0.001619f, 0.007668f, 0.023294f, 0.045371f, 0.056662f, 0.045371f, 0.023294f, 0.007668f, 0.001619f, 0.000219f}, + {0.000274f, 0.002021f, 0.009577f, 0.029091f, 0.056662f, 0.070762f, 0.056662f, 0.029091f, 0.009577f, 0.002021f, 0.000274f}, + {0.000219f, 0.001619f, 0.007668f, 0.023294f, 0.045371f, 0.056662f, 0.045371f, 0.023294f, 0.007668f, 0.001619f, 0.000219f}, + {0.000112f, 0.000831f, 0.003937f, 0.011960f, 0.023294f, 0.029091f, 0.023294f, 0.011960f, 0.003937f, 0.000831f, 0.000112f}, + {0.000037f, 0.000274f, 0.001296f, 0.003937f, 0.007668f, 0.009577f, 0.007668f, 0.003937f, 0.001296f, 0.000274f, 0.000037f}, + {0.000008f, 0.000058f, 0.000274f, 0.000831f, 0.001619f, 0.002021f, 0.001619f, 0.000831f, 0.000274f, 0.000058f, 0.000008f}, + {0.000001f, 0.000008f, 0.000037f, 0.000112f, 0.000219f, 0.000274f, 0.000219f, 0.000112f, 0.000037f, 0.000008f, 0.000001f}, +}; + +/* + * Equal weight square window. + * Each pixel is equally weighted (1/64) so that SUM(x) = 1.0 + */ +#define SQUARE_LEN 8 +static const float g_square_window[SQUARE_LEN][SQUARE_LEN] = { + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, + {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f}, +}; + +/* Holds intermediate SSIM values for map-reduce operation. */ +struct _ssim_int { + double l; + double c; + double s; +}; + +/* Defines the pointers to the map-reduce functions. */ +typedef int (*_map)(const struct _ssim_int *, void *); +typedef float (*_reduce)(int, int, void *); + +/* Arguments for map-reduce. The 'context' is user-defined. */ +struct _map_reduce { + _map map; + _reduce reduce; + void *context; +}; + +/** + * Private method that calculates the SSIM value on a pre-processed image. + * + * The input images must have stride==width. This method does not scale. + * + * @note Image buffers are modified. + * + * Map-reduce is used for doing the final SSIM calculation. The map function is + * called for every pixel, and the reduce is called at the end. The context is + * caller-defined and *not* modified by this method. + * + * @param ref Original reference image + * @param cmp Distorted image + * @param w Width of the images + * @param h Height of the images + * @param k The kernel used as the window function + * @param mr Optional map-reduce functions to use to calculate SSIM. Required + * if 'args' is not null. Ignored if 'args' is null. + * @param args Optional SSIM arguments for fine control of the algorithm. 0 for defaults. + * Defaults are a=b=g=1.0, L=255, K1=0.01, K2=0.03 + * @return The mean SSIM over the entire image (MSSIM), or INFINITY if error. + */ +float _iqa_ssim(float *ref, float *cmp, int w, int h, const struct _kernel *k, const struct _map_reduce *mr, const struct iqa_ssim_args *args); + +#endif /* _SSIM_H_ */ diff --git a/3rdparty/bgfx/3rdparty/iqa/source/convolve.c b/3rdparty/bgfx/3rdparty/iqa/source/convolve.c new file mode 100644 index 00000000000..c9159070fd5 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/source/convolve.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "convolve.h" +#include <stdlib.h> + +float KBND_SYMMETRIC(const float *img, int w, int h, int x, int y, float bnd_const) +{ + (void)bnd_const; + if (x<0) x=-1-x; + else if (x>=w) x=(w-(x-w))-1; + if (y<0) y=-1-y; + else if (y>=h) y=(h-(y-h))-1; + return img[y*w + x]; +} + +float KBND_REPLICATE(const float *img, int w, int h, int x, int y, float bnd_const) +{ + (void)bnd_const; + if (x<0) x=0; + if (x>=w) x=w-1; + if (y<0) y=0; + if (y>=h) y=h-1; + return img[y*w + x]; +} + +float KBND_CONSTANT(const float *img, int w, int h, int x, int y, float bnd_const) +{ + if (x<0) x=0; + if (y<0) y=0; + if (x>=w || y>=h) + return bnd_const; + return img[y*w + x]; +} + +static float _calc_scale(const struct _kernel *k) +{ + int ii,k_len; + double sum=0.0; + + if (k->normalized) + return 1.0f; + else { + k_len = k->w * k->h; + for (ii=0; ii<k_len; ++ii) + sum += k->kernel[ii]; + if (sum != 0.0) + return (float)(1.0 / sum); + return 1.0f; + } +} + +void _iqa_convolve(float *img, int w, int h, const struct _kernel *k, float *result, int *rw, int *rh) +{ + int x,y,kx,ky,u,v; + int uc = k->w/2; + int vc = k->h/2; + int kw_even = (k->w&1)?0:1; + int kh_even = (k->h&1)?0:1; + int dst_w = w - k->w + 1; + int dst_h = h - k->h + 1; + int img_offset,k_offset; + double sum; + float scale, *dst=result; + + if (!dst) + dst = img; /* Convolve in-place */ + + /* Kernel is applied to all positions where the kernel is fully contained + * in the image */ + scale = _calc_scale(k); + for (y=0; y < dst_h; ++y) { + for (x=0; x < dst_w; ++x) { + sum = 0.0; + k_offset = 0; + ky = y+vc; + kx = x+uc; + for (v=-vc; v <= vc-kh_even; ++v) { + img_offset = (ky+v)*w + kx; + for (u=-uc; u <= uc-kw_even; ++u, ++k_offset) { + sum += img[img_offset+u] * k->kernel[k_offset]; + } + } + dst[y*dst_w + x] = (float)(sum * scale); + } + } + + if (rw) *rw = dst_w; + if (rh) *rh = dst_h; +} + +int _iqa_img_filter(float *img, int w, int h, const struct _kernel *k, float *result) +{ + int x,y; + int img_offset; + float scale, *dst=result; + + if (!k || !k->bnd_opt) + return 1; + + if (!dst) { + dst = (float*)malloc(w*h*sizeof(float)); + if (!dst) + return 2; + } + + scale = _calc_scale(k); + + /* Kernel is applied to all positions where top-left corner is in the image */ + for (y=0; y < h; ++y) { + for (x=0; x < w; ++x) { + dst[y*w + x] = _iqa_filter_pixel(img, w, h, x, y, k, scale); + } + } + + /* If no result buffer given, copy results to image buffer */ + if (!result) { + for (y=0; y<h; ++y) { + img_offset = y*w; + for (x=0; x<w; ++x, ++img_offset) { + img[img_offset] = dst[img_offset]; + } + } + free(dst); + } + return 0; +} + +float _iqa_filter_pixel(const float *img, int w, int h, int x, int y, const struct _kernel *k, const float kscale) +{ + int u,v,uc,vc; + int kw_even,kh_even; + int x_edge_left,x_edge_right,y_edge_top,y_edge_bottom; + int edge,img_offset,k_offset; + double sum; + + if (!k) + return img[y*w + x]; + + uc = k->w/2; + vc = k->h/2; + kw_even = (k->w&1)?0:1; + kh_even = (k->h&1)?0:1; + x_edge_left = uc; + x_edge_right = w-uc; + y_edge_top = vc; + y_edge_bottom = h-vc; + + edge = 0; + if (x < x_edge_left || y < y_edge_top || x >= x_edge_right || y >= y_edge_bottom) + edge = 1; + + sum = 0.0; + k_offset = 0; + for (v=-vc; v <= vc-kh_even; ++v) { + img_offset = (y+v)*w + x; + for (u=-uc; u <= uc-kw_even; ++u, ++k_offset) { + if (!edge) + sum += img[img_offset+u] * k->kernel[k_offset]; + else + sum += k->bnd_opt(img, w, h, x+u, y+v, k->bnd_const) * k->kernel[k_offset]; + } + } + return (float)(sum * kscale); +} diff --git a/3rdparty/bgfx/3rdparty/iqa/source/decimate.c b/3rdparty/bgfx/3rdparty/iqa/source/decimate.c new file mode 100644 index 00000000000..91c6a9be3ed --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/source/decimate.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "decimate.h" +#include <stdlib.h> + +int _iqa_decimate(float *img, int w, int h, int factor, const struct _kernel *k, float *result, int *rw, int *rh) +{ + int x,y; + int sw = w/factor + (w&1); + int sh = h/factor + (h&1); + int dst_offset; + float *dst=img; + + if (result) + dst = result; + + /* Downsample */ + for (y=0; y<sh; ++y) { + dst_offset = y*sw; + for (x=0; x<sw; ++x,++dst_offset) { + dst[dst_offset] = _iqa_filter_pixel(img, w, h, x*factor, y*factor, k, 1.0f); + } + } + + if (rw) *rw = sw; + if (rh) *rh = sh; + return 0; +} diff --git a/3rdparty/bgfx/3rdparty/iqa/source/math_utils.c b/3rdparty/bgfx/3rdparty/iqa/source/math_utils.c new file mode 100644 index 00000000000..83f923d7673 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/source/math_utils.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "math_utils.h" +#include <math.h> + +int _round(float a) +{ + int sign_a = a > 0.0f ? 1 : -1; + return a-(int)a >= 0.5 ? (int)a + sign_a : (int)a; +} + +int _max(int x, int y) +{ + return x >= y ? x : y; +} + +int _min(int x, int y) +{ + return x <= y ? x : y; +} + +int _cmp_float(float a, float b, int digits) +{ + /* Round */ + int sign_a = a > 0.0f ? 1 : -1; + int sign_b = b > 0.0f ? 1 : -1; + double scale = pow(10.0, (double)digits); + double ax = a * scale; + double bx = b * scale; + int ai = ax-(int)ax >= 0.5 ? (int)ax + sign_a : (int)ax; + int bi = bx-(int)bx >= 0.5 ? (int)bx + sign_b : (int)bx; + + /* Compare */ + return ai == bi ? 0 : 1; +} + +int _matrix_cmp(const float *a, const float *b, int w, int h, int digits) +{ + int offset; + int result=0; + int len=w*h; + for (offset=0; offset<len; ++offset) { + if (_cmp_float(a[offset], b[offset], digits)) { + result = 1; + break; + } + } + + return result; +} + diff --git a/3rdparty/bgfx/3rdparty/iqa/source/ms_ssim.c b/3rdparty/bgfx/3rdparty/iqa/source/ms_ssim.c new file mode 100644 index 00000000000..91812a07722 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/source/ms_ssim.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "iqa.h" +#include "ssim.h" +#include "decimate.h" +#include <math.h> +#include <stdlib.h> +#include <string.h> + +/* Default number of scales */ +#define SCALES 5 + +/* Low-pass filter for down-sampling (9/7 biorthogonal wavelet filter) */ +#define LPF_LEN 9 +static const float g_lpf[LPF_LEN][LPF_LEN] = { + { 0.000714f,-0.000450f,-0.002090f, 0.007132f, 0.016114f, 0.007132f,-0.002090f,-0.000450f, 0.000714f}, + {-0.000450f, 0.000283f, 0.001316f,-0.004490f,-0.010146f,-0.004490f, 0.001316f, 0.000283f,-0.000450f}, + {-0.002090f, 0.001316f, 0.006115f,-0.020867f,-0.047149f,-0.020867f, 0.006115f, 0.001316f,-0.002090f}, + { 0.007132f,-0.004490f,-0.020867f, 0.071207f, 0.160885f, 0.071207f,-0.020867f,-0.004490f, 0.007132f}, + { 0.016114f,-0.010146f,-0.047149f, 0.160885f, 0.363505f, 0.160885f,-0.047149f,-0.010146f, 0.016114f}, + { 0.007132f,-0.004490f,-0.020867f, 0.071207f, 0.160885f, 0.071207f,-0.020867f,-0.004490f, 0.007132f}, + {-0.002090f, 0.001316f, 0.006115f,-0.020867f,-0.047149f,-0.020867f, 0.006115f, 0.001316f,-0.002090f}, + {-0.000450f, 0.000283f, 0.001316f,-0.004490f,-0.010146f,-0.004490f, 0.001316f, 0.000283f,-0.000450f}, + { 0.000714f,-0.000450f,-0.002090f, 0.007132f, 0.016114f, 0.007132f,-0.002090f,-0.000450f, 0.000714f}, +}; + +/* Alpha, beta, and gamma values for each scale */ +static float g_alphas[] = { 0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.1333f }; +static float g_betas[] = { 0.0448f, 0.2856f, 0.3001f, 0.2363f, 0.1333f }; +static float g_gammas[] = { 0.0448f, 0.2856f, 0.3001f, 0.2363f, 0.1333f }; + + +struct _context { + double l; /* Luminance */ + double c; /* Contrast */ + double s; /* Structure */ + float alpha; + float beta; + float gamma; +}; + +/* Called for each pixel */ +int _ms_ssim_map(const struct _ssim_int *si, void *ctx) +{ + struct _context *ms_ctx = (struct _context*)ctx; + ms_ctx->l += si->l; + ms_ctx->c += si->c; + ms_ctx->s += si->s; + return 0; +} + +/* Called to calculate the final result */ +float _ms_ssim_reduce(int w, int h, void *ctx) +{ + double size = (double)(w*h); + struct _context *ms_ctx = (struct _context*)ctx; + ms_ctx->l = pow(ms_ctx->l / size, (double)ms_ctx->alpha); + ms_ctx->c = pow(ms_ctx->c / size, (double)ms_ctx->beta); + ms_ctx->s = pow(fabs(ms_ctx->s / size), (double)ms_ctx->gamma); + return (float)(ms_ctx->l * ms_ctx->c * ms_ctx->s); +} + +/* Releases the scaled buffers */ +void _free_buffers(float **buf, int scales) +{ + int idx; + for (idx=0; idx<scales; ++idx) + free(buf[idx]); +} + +/* Allocates the scaled buffers. If error, all buffers are free'd */ +int _alloc_buffers(float **buf, int w, int h, int scales) +{ + int idx; + int cur_w = w; + int cur_h = h; + for (idx=0; idx<scales; ++idx) { + buf[idx] = (float*)malloc(cur_w*cur_h*sizeof(float)); + if (!buf[idx]) { + _free_buffers(buf, idx); + return 1; + } + cur_w = cur_w/2 + (cur_w&1); + cur_h = cur_h/2 + (cur_h&1); + } + return 0; +} + +/* + * MS_SSIM(X,Y) = Lm(x,y)^aM * MULT[j=1->M]( Cj(x,y)^bj * Sj(x,y)^gj ) + * where, + * L = mean + * C = variance + * S = cross-correlation + * + * b1=g1=0.0448, b2=g2=0.2856, b3=g3=0.3001, b4=g4=0.2363, a5=b5=g5=0.1333 + */ +float iqa_ms_ssim(const unsigned char *ref, const unsigned char *cmp, int w, int h, + int stride, const struct iqa_ms_ssim_args *args) +{ + int wang=0; + int scales=SCALES; + int gauss=1; + const float *alphas=g_alphas, *betas=g_betas, *gammas=g_gammas; + int idx,x,y,cur_w,cur_h; + int offset,src_offset; + float **ref_imgs, **cmp_imgs; /* Array of pointers to scaled images */ + float msssim; + struct _kernel lpf, window; + struct iqa_ssim_args s_args; + struct _map_reduce mr; + struct _context ms_ctx; + + if (args) { + wang = args->wang; + gauss = args->gaussian; + scales = args->scales; + if (args->alphas) + alphas = args->alphas; + if (args->betas) + betas = args->betas; + if (args->gammas) + gammas = args->gammas; + } + + /* Make sure we won't scale below 1x1 */ + cur_w = w; + cur_h = h; + for (idx=0; idx<scales; ++idx) { + if ( gauss ? cur_w<GAUSSIAN_LEN || cur_h<GAUSSIAN_LEN : cur_w<LPF_LEN || cur_h<LPF_LEN ) + return INFINITY; + cur_w /= 2; + cur_h /= 2; + } + + window.kernel = (float*)g_square_window; + window.w = window.h = SQUARE_LEN; + window.normalized = 1; + window.bnd_opt = KBND_SYMMETRIC; + if (gauss) { + window.kernel = (float*)g_gaussian_window; + window.w = window.h = GAUSSIAN_LEN; + } + + mr.map = _ms_ssim_map; + mr.reduce = _ms_ssim_reduce; + + /* Allocate the scaled image buffers */ + ref_imgs = (float**)malloc(scales*sizeof(float*)); + cmp_imgs = (float**)malloc(scales*sizeof(float*)); + if (!ref_imgs || !cmp_imgs) { + if (ref_imgs) free(ref_imgs); + if (cmp_imgs) free(cmp_imgs); + return INFINITY; + } + if (_alloc_buffers(ref_imgs, w, h, scales)) { + free(ref_imgs); + free(cmp_imgs); + return INFINITY; + } + if (_alloc_buffers(cmp_imgs, w, h, scales)) { + _free_buffers(ref_imgs, scales); + free(ref_imgs); + free(cmp_imgs); + return INFINITY; + } + + /* Copy original images into first scale buffer, forcing stride = width. */ + for (y=0; y<h; ++y) { + src_offset = y*stride; + offset = y*w; + for (x=0; x<w; ++x, ++offset, ++src_offset) { + ref_imgs[0][offset] = (float)ref[src_offset]; + cmp_imgs[0][offset] = (float)cmp[src_offset]; + } + } + + /* Create scaled versions of the images */ + cur_w=w; + cur_h=h; + lpf.kernel = (float*)g_lpf; + lpf.w = lpf.h = LPF_LEN; + lpf.normalized = 1; + lpf.bnd_opt = KBND_SYMMETRIC; + for (idx=1; idx<scales; ++idx) { + if (_iqa_decimate(ref_imgs[idx-1], cur_w, cur_h, 2, &lpf, ref_imgs[idx], 0, 0) || + _iqa_decimate(cmp_imgs[idx-1], cur_w, cur_h, 2, &lpf, cmp_imgs[idx], &cur_w, &cur_h)) + { + _free_buffers(ref_imgs, scales); + _free_buffers(cmp_imgs, scales); + free(ref_imgs); + free(cmp_imgs); + return INFINITY; + } + } + + cur_w=w; + cur_h=h; + msssim = 1.0; + for (idx=0; idx<scales; ++idx) { + + ms_ctx.l = 0; + ms_ctx.c = 0; + ms_ctx.s = 0; + ms_ctx.alpha = alphas[idx]; + ms_ctx.beta = betas[idx]; + ms_ctx.gamma = gammas[idx]; + + if (!wang) { + /* MS-SSIM* (Rouse/Hemami) */ + s_args.alpha = 1.0f; + s_args.beta = 1.0f; + s_args.gamma = 1.0f; + s_args.K1 = 0.0f; /* Force stabilization constants to 0 */ + s_args.K2 = 0.0f; + s_args.L = 255; + s_args.f = 1; /* Don't resize */ + mr.context = &ms_ctx; + msssim *= _iqa_ssim(ref_imgs[idx], cmp_imgs[idx], cur_w, cur_h, &window, &mr, &s_args); + } + else { + /* MS-SSIM (Wang) */ + s_args.alpha = 1.0f; + s_args.beta = 1.0f; + s_args.gamma = 1.0f; + s_args.K1 = 0.01f; + s_args.K2 = 0.03f; + s_args.L = 255; + s_args.f = 1; /* Don't resize */ + mr.context = &ms_ctx; + msssim *= _iqa_ssim(ref_imgs[idx], cmp_imgs[idx], cur_w, cur_h, &window, &mr, &s_args); + } + + if (msssim == INFINITY) + break; + cur_w = cur_w/2 + (cur_w&1); + cur_h = cur_h/2 + (cur_h&1); + } + + _free_buffers(ref_imgs, scales); + _free_buffers(cmp_imgs, scales); + free(ref_imgs); + free(cmp_imgs); + + return msssim; +} diff --git a/3rdparty/bgfx/3rdparty/iqa/source/mse.c b/3rdparty/bgfx/3rdparty/iqa/source/mse.c new file mode 100644 index 00000000000..da0ce772e45 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/source/mse.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "iqa.h" + +/* MSE(a,b) = 1/N * SUM((a-b)^2) */ +float iqa_mse(const unsigned char *ref, const unsigned char *cmp, int w, int h, int stride) +{ + int error, offset; + unsigned long long sum=0; + int ww,hh; + for (hh=0; hh<h; ++hh) { + offset = hh*stride; + for (ww=0; ww<w; ++ww, ++offset) { + error = ref[offset] - cmp[offset]; + sum += error * error; + } + } + return (float)( (double)sum / (double)(w*h) ); +} diff --git a/3rdparty/bgfx/3rdparty/iqa/source/psnr.c b/3rdparty/bgfx/3rdparty/iqa/source/psnr.c new file mode 100644 index 00000000000..45670716505 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/source/psnr.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "iqa.h" +#include <math.h> + +/* PSNR(a,b) = 10*log10(L^2 / MSE(a,b)), where L=2^b - 1 (8bit = 255) */ +float iqa_psnr(const unsigned char *ref, const unsigned char *cmp, int w, int h, int stride) +{ + const int L_sqd = 255 * 255; + return (float)( 10.0 * log10( L_sqd / iqa_mse(ref,cmp,w,h,stride) ) ); +} diff --git a/3rdparty/bgfx/3rdparty/iqa/source/ssim.c b/3rdparty/bgfx/3rdparty/iqa/source/ssim.c new file mode 100644 index 00000000000..d1acccb40fb --- /dev/null +++ b/3rdparty/bgfx/3rdparty/iqa/source/ssim.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2011, Tom Distler (http://tdistler.com) + * All rights reserved. + * + * The BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the tdistler.com nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "iqa.h" +#include "convolve.h" +#include "decimate.h" +#include "math_utils.h" +#include "ssim.h" +#include <stdlib.h> +#include <math.h> + + +/* Forward declarations. */ +IQA_INLINE static double _calc_luminance(float, float, float, float); +IQA_INLINE static double _calc_contrast(double, float, float, float, float); +IQA_INLINE static double _calc_structure(float, double, float, float, float, float); +static int _ssim_map(const struct _ssim_int *, void *); +static float _ssim_reduce(int, int, void *); + +/* + * SSIM(x,y)=(2*ux*uy + C1)*(2sxy + C2) / (ux^2 + uy^2 + C1)*(sx^2 + sy^2 + C2) + * where, + * ux = SUM(w*x) + * sx = (SUM(w*(x-ux)^2)^0.5 + * sxy = SUM(w*(x-ux)*(y-uy)) + * + * Returns mean SSIM. MSSIM(X,Y) = 1/M * SUM(SSIM(x,y)) + */ +float iqa_ssim(const unsigned char *ref, const unsigned char *cmp, int w, int h, int stride, + int gaussian, const struct iqa_ssim_args *args) +{ + int scale; + int x,y,src_offset,offset; + float *ref_f,*cmp_f; + struct _kernel low_pass; + struct _kernel window; + float result; + double ssim_sum=0.0; + struct _map_reduce mr; + + /* Initialize algorithm parameters */ + scale = _max( 1, _round( (float)_min(w,h) / 256.0f ) ); + if (args) { + if(args->f) + scale = args->f; + mr.map = _ssim_map; + mr.reduce = _ssim_reduce; + mr.context = (void*)&ssim_sum; + } + window.kernel = (float*)g_square_window; + window.w = window.h = SQUARE_LEN; + window.normalized = 1; + window.bnd_opt = KBND_SYMMETRIC; + if (gaussian) { + window.kernel = (float*)g_gaussian_window; + window.w = window.h = GAUSSIAN_LEN; + } + + /* Convert image values to floats. Forcing stride = width. */ + ref_f = (float*)malloc(w*h*sizeof(float)); + cmp_f = (float*)malloc(w*h*sizeof(float)); + if (!ref_f || !cmp_f) { + if (ref_f) free(ref_f); + if (cmp_f) free(cmp_f); + return INFINITY; + } + for (y=0; y<h; ++y) { + src_offset = y*stride; + offset = y*w; + for (x=0; x<w; ++x, ++offset, ++src_offset) { + ref_f[offset] = (float)ref[src_offset]; + cmp_f[offset] = (float)cmp[src_offset]; + } + } + + /* Scale the images down if required */ + if (scale > 1) { + /* Generate simple low-pass filter */ + low_pass.kernel = (float*)malloc(scale*scale*sizeof(float)); + if (!low_pass.kernel) { + free(ref_f); + free(cmp_f); + return INFINITY; + } + low_pass.w = low_pass.h = scale; + low_pass.normalized = 0; + low_pass.bnd_opt = KBND_SYMMETRIC; + for (offset=0; offset<scale*scale; ++offset) + low_pass.kernel[offset] = 1.0f/(scale*scale); + + /* Resample */ + if (_iqa_decimate(ref_f, w, h, scale, &low_pass, 0, 0, 0) || + _iqa_decimate(cmp_f, w, h, scale, &low_pass, 0, &w, &h)) { /* Update w/h */ + free(ref_f); + free(cmp_f); + free(low_pass.kernel); + return INFINITY; + } + free(low_pass.kernel); + } + + result = _iqa_ssim(ref_f, cmp_f, w, h, &window, &mr, args); + + free(ref_f); + free(cmp_f); + + return result; +} + + +/* _iqa_ssim */ +float _iqa_ssim(float *ref, float *cmp, int w, int h, const struct _kernel *k, const struct _map_reduce *mr, const struct iqa_ssim_args *args) +{ + float alpha=1.0f, beta=1.0f, gamma=1.0f; + int L=255; + float K1=0.01f, K2=0.03f; + float C1,C2,C3; + int x,y,offset; + float *ref_mu,*cmp_mu,*ref_sigma_sqd,*cmp_sigma_sqd,*sigma_both; + double ssim_sum, numerator, denominator; + double luminance_comp, contrast_comp, structure_comp, sigma_root; + struct _ssim_int sint; + + /* Initialize algorithm parameters */ + if (args) { + if (!mr) + return INFINITY; + alpha = args->alpha; + beta = args->beta; + gamma = args->gamma; + L = args->L; + K1 = args->K1; + K2 = args->K2; + } + C1 = (K1*L)*(K1*L); + C2 = (K2*L)*(K2*L); + C3 = C2 / 2.0f; + + ref_mu = (float*)malloc(w*h*sizeof(float)); + cmp_mu = (float*)malloc(w*h*sizeof(float)); + ref_sigma_sqd = (float*)malloc(w*h*sizeof(float)); + cmp_sigma_sqd = (float*)malloc(w*h*sizeof(float)); + sigma_both = (float*)malloc(w*h*sizeof(float)); + if (!ref_mu || !cmp_mu || !ref_sigma_sqd || !cmp_sigma_sqd || !sigma_both) { + if (ref_mu) free(ref_mu); + if (cmp_mu) free(cmp_mu); + if (ref_sigma_sqd) free(ref_sigma_sqd); + if (cmp_sigma_sqd) free(cmp_sigma_sqd); + if (sigma_both) free(sigma_both); + return INFINITY; + } + + /* Calculate mean */ + _iqa_convolve(ref, w, h, k, ref_mu, 0, 0); + _iqa_convolve(cmp, w, h, k, cmp_mu, 0, 0); + + for (y=0; y<h; ++y) { + offset = y*w; + for (x=0; x<w; ++x, ++offset) { + ref_sigma_sqd[offset] = ref[offset] * ref[offset]; + cmp_sigma_sqd[offset] = cmp[offset] * cmp[offset]; + sigma_both[offset] = ref[offset] * cmp[offset]; + } + } + + /* Calculate sigma */ + _iqa_convolve(ref_sigma_sqd, w, h, k, 0, 0, 0); + _iqa_convolve(cmp_sigma_sqd, w, h, k, 0, 0, 0); + _iqa_convolve(sigma_both, w, h, k, 0, &w, &h); /* Update the width and height */ + + /* The convolution results are smaller by the kernel width and height */ + for (y=0; y<h; ++y) { + offset = y*w; + for (x=0; x<w; ++x, ++offset) { + ref_sigma_sqd[offset] -= ref_mu[offset] * ref_mu[offset]; + cmp_sigma_sqd[offset] -= cmp_mu[offset] * cmp_mu[offset]; + sigma_both[offset] -= ref_mu[offset] * cmp_mu[offset]; + } + } + + ssim_sum = 0.0; + for (y=0; y<h; ++y) { + offset = y*w; + for (x=0; x<w; ++x, ++offset) { + + if (!args) { + /* The default case */ + numerator = (2.0 * ref_mu[offset] * cmp_mu[offset] + C1) * (2.0 * sigma_both[offset] + C2); + denominator = (ref_mu[offset]*ref_mu[offset] + cmp_mu[offset]*cmp_mu[offset] + C1) * + (ref_sigma_sqd[offset] + cmp_sigma_sqd[offset] + C2); + ssim_sum += numerator / denominator; + } + else { + /* User tweaked alpha, beta, or gamma */ + + /* passing a negative number to sqrt() cause a domain error */ + if (ref_sigma_sqd[offset] < 0.0f) + ref_sigma_sqd[offset] = 0.0f; + if (cmp_sigma_sqd[offset] < 0.0f) + cmp_sigma_sqd[offset] = 0.0f; + sigma_root = sqrt(ref_sigma_sqd[offset] * cmp_sigma_sqd[offset]); + + luminance_comp = _calc_luminance(ref_mu[offset], cmp_mu[offset], C1, alpha); + contrast_comp = _calc_contrast(sigma_root, ref_sigma_sqd[offset], cmp_sigma_sqd[offset], C2, beta); + structure_comp = _calc_structure(sigma_both[offset], sigma_root, ref_sigma_sqd[offset], cmp_sigma_sqd[offset], C3, gamma); + + sint.l = luminance_comp; + sint.c = contrast_comp; + sint.s = structure_comp; + + if (mr->map(&sint, mr->context)) + return INFINITY; + } + } + } + + free(ref_mu); + free(cmp_mu); + free(ref_sigma_sqd); + free(cmp_sigma_sqd); + free(sigma_both); + + if (!args) + return (float)(ssim_sum / (double)(w*h)); + return mr->reduce(w, h, mr->context); +} + + +/* _ssim_map */ +int _ssim_map(const struct _ssim_int *si, void *ctx) +{ + double *ssim_sum = (double*)ctx; + *ssim_sum += si->l * si->c * si->s; + return 0; +} + +/* _ssim_reduce */ +float _ssim_reduce(int w, int h, void *ctx) +{ + double *ssim_sum = (double*)ctx; + return (float)(*ssim_sum / (double)(w*h)); +} + + +/* _calc_luminance */ +IQA_INLINE static double _calc_luminance(float mu1, float mu2, float C1, float alpha) +{ + double result; + float sign; + /* For MS-SSIM* */ + if (C1 == 0 && mu1*mu1 == 0 && mu2*mu2 == 0) + return 1.0; + result = (2.0 * mu1 * mu2 + C1) / (mu1*mu1 + mu2*mu2 + C1); + if (alpha == 1.0f) + return result; + sign = result < 0.0 ? -1.0f : 1.0f; + return sign * pow(fabs(result),(double)alpha); +} + +/* _calc_contrast */ +IQA_INLINE static double _calc_contrast(double sigma_comb_12, float sigma1_sqd, float sigma2_sqd, float C2, float beta) +{ + double result; + float sign; + /* For MS-SSIM* */ + if (C2 == 0 && sigma1_sqd + sigma2_sqd == 0) + return 1.0; + result = (2.0 * sigma_comb_12 + C2) / (sigma1_sqd + sigma2_sqd + C2); + if (beta == 1.0f) + return result; + sign = result < 0.0 ? -1.0f : 1.0f; + return sign * pow(fabs(result),(double)beta); +} + +/* _calc_structure */ +IQA_INLINE static double _calc_structure(float sigma_12, double sigma_comb_12, float sigma1, float sigma2, float C3, float gamma) +{ + double result; + float sign; + /* For MS-SSIM* */ + if (C3 == 0 && sigma_comb_12 == 0) { + if (sigma1 == 0 && sigma2 == 0) + return 1.0; + else if (sigma1 == 0 || sigma2 == 0) + return 0.0; + } + result = (sigma_12 + C3) / (sigma_comb_12 + C3); + if (gamma == 1.0f) + return result; + sign = result < 0.0 ? -1.0f : 1.0f; + return sign * pow(fabs(result),(double)gamma); +}
\ No newline at end of file diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp index 2c33a0ca187..b09e71cba59 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. @@ -2341,9 +2341,9 @@ static void AddDrawListToRenderList(ImVector<ImDrawList*>& out_render_list, ImDr // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices) // If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly. - IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); // Sanity check. Bug or mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. - IM_ASSERT((unsigned long long int)draw_list->_VtxCurrentIdx <= ((unsigned long long int)1L << (sizeof(ImDrawIdx)*8))); // Too many vertices in same ImDrawList. See comment above. - + IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); // Sanity check. Bug or mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. + IM_ASSERT((int64_t)draw_list->_VtxCurrentIdx <= ((int64_t)1L << (sizeof(ImDrawIdx)*8))); // Too many vertices in same ImDrawList. See comment above. + out_render_list.push_back(draw_list); GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size; @@ -7101,9 +7101,9 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* ob static bool is_separator(unsigned int c) { return ImCharIsSpace(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; } -static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; } static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } #ifdef __APPLE__ // FIXME: Move setting to IO structure +static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; } static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } #else static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h index c8d223db39d..0c41e7ae9f8 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include <stddef.h> // ptrdiff_t, NULL #include <string.h> // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.48 WIP" +#define IMGUI_VERSION "1.49 WIP" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API @@ -315,7 +315,7 @@ namespace ImGui IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose IMGUI_API void TreePush(const void* ptr_id = NULL); // " IMGUI_API void TreePop(); - IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. + IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node/collapsing header to be opened. // Widgets: Selectable / Lists IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height @@ -892,6 +892,7 @@ struct ImGuiTextFilter int CountGrep; ImGuiTextFilter(const char* default_filter = ""); + ~ImGuiTextFilter() {} void Clear() { InputBuf[0] = 0; Build(); } bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build bool PassFilter(const char* text, const char* text_end = NULL) const; @@ -1155,7 +1156,7 @@ struct ImDrawList // Stateful path API, add points then finish with PathFill() or PathStroke() inline void PathClear() { _Path.resize(0); } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } - inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || _Path[_Path.Size-1].x != pos.x || _Path[_Path.Size-1].y != pos.y) _Path.push_back(pos); } + inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } inline void PathFill(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); } IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp index ad6e7aa6ff0..2bc386b50a7 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (demo code) // Don't remove this file from your project! It is useful reference code that you can execute. @@ -2295,12 +2295,12 @@ static void ShowExampleAppPropertyEditor(bool* p_opened) { ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. - bool opened = ImGui::TreeNode("Object", "%s_%u", prefix, uid); + bool is_opened = ImGui::TreeNode("Object", "%s_%u", prefix, uid); ImGui::NextColumn(); ImGui::AlignFirstTextHeightToWidgets(); ImGui::Text("my sailor is rich"); ImGui::NextColumn(); - if (opened) + if (is_opened) { static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; for (int i = 0; i < 8; i++) diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp index 38a110292cf..091e2dca085 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (drawing and font code) // Contains implementation for diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h index 0f654a541a7..e886ff1bbb2 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! diff --git a/3rdparty/bgfx/3rdparty/openvr/openvr_capi.h b/3rdparty/bgfx/3rdparty/openvr/openvr_capi.h new file mode 100644 index 00000000000..230cd3b4513 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/openvr/openvr_capi.h @@ -0,0 +1,1416 @@ +//======= Copyright 1996-2016, Valve Corporation, All rights reserved. ======== +// +// Purpose: Header for flatted SteamAPI. Use this for binding to other languages. +// This file is auto-generated, do not edit it. +// +//============================================================================= + +#ifndef __OPENVR_API_FLAT_H__ +#define __OPENVR_API_FLAT_H__ +#if defined( _WIN32 ) || defined( __clang__ ) +#pragma once +#endif + +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else +#define EXTERN_C +#endif + +#if defined( _WIN32 ) +# define OPENVR_FNTABLE_CALLTYPE __stdcall +#else +# define OPENVR_FNTABLE_CALLTYPE +#endif // + +// OPENVR API export macro +#if defined( _WIN32 ) && !defined( _X360 ) + #if defined( OPENVR_API_EXPORTS ) + #define S_API EXTERN_C __declspec( dllexport ) + #elif defined( OPENVR_API_NODLL ) + #define S_API EXTERN_C + #else + #define S_API extern "C" __declspec( dllimport ) + #endif // OPENVR_API_EXPORTS +#elif defined( GNUC ) + #if defined( OPENVR_API_EXPORTS ) + #define S_API EXTERN_C __attribute__ ((visibility("default"))) + #else + #define S_API EXTERN_C + #endif // OPENVR_API_EXPORTS +#else // !WIN32 + #if defined( OPENVR_API_EXPORTS ) + #define S_API EXTERN_C + #else + #define S_API EXTERN_C + #endif // OPENVR_API_EXPORTS +#endif + +#include <stdint.h> + +// OpenVR Constants + +static const unsigned int k_unTrackingStringSize = 32; +static const unsigned int k_unMaxDriverDebugResponseSize = 32768; +static const unsigned int k_unTrackedDeviceIndex_Hmd = 0; +static const unsigned int k_unMaxTrackedDeviceCount = 16; +static const unsigned int k_unTrackedDeviceIndexInvalid = 4294967295; +static const unsigned int k_unMaxPropertyStringSize = 32768; +static const unsigned int k_unControllerStateAxisCount = 5; +static const unsigned long k_ulOverlayHandleInvalid = 0; +static const char * IVRSystem_Version = "IVRSystem_012"; +static const char * IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +static const unsigned int k_unMaxApplicationKeyLength = 128; +static const char * IVRApplications_Version = "IVRApplications_005"; +static const char * IVRChaperone_Version = "IVRChaperone_003"; +static const char * IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char * IVRCompositor_Version = "IVRCompositor_013"; +static const unsigned int k_unVROverlayMaxKeyLength = 128; +static const unsigned int k_unVROverlayMaxNameLength = 128; +static const unsigned int k_unMaxOverlayCount = 32; +static const char * IVROverlay_Version = "IVROverlay_011"; +static const char * k_pch_Controller_Component_GDC2015 = "gdc2015"; +static const char * k_pch_Controller_Component_Base = "base"; +static const char * k_pch_Controller_Component_Tip = "tip"; +static const char * k_pch_Controller_Component_HandGrip = "handgrip"; +static const char * k_pch_Controller_Component_Status = "status"; +static const char * IVRRenderModels_Version = "IVRRenderModels_005"; +static const unsigned int k_unNotificationTextMaxSize = 256; +static const char * IVRNotifications_Version = "IVRNotifications_002"; +static const unsigned int k_unMaxSettingsKeyLength = 128; +static const char * k_pch_SteamVR_Section = "steamvr"; +static const char * k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char * k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char * k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char * k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char * k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char * k_pch_SteamVR_EnableDistortion_Bool = "enableDistortion"; +static const char * k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char * k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char * k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char * k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char * k_pch_SteamVR_IPD_Float = "ipd"; +static const char * k_pch_SteamVR_Background_String = "background"; +static const char * k_pch_SteamVR_GridColor_String = "gridColor"; +static const char * k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char * k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char * k_pch_SteamVR_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char * k_pch_SteamVR_StandbyAppRunningTimeout_Float = "standbyAppRunningTimeout"; +static const char * k_pch_SteamVR_StandbyNoAppTimeout_Float = "standbyNoAppTimeout"; +static const char * k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char * k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char * k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char * k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char * k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char * k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char * k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char * k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char * k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char * k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char * k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char * k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char * k_pch_Lighthouse_LighthouseName_String = "lighthousename"; +static const char * k_pch_Lighthouse_MaxIncidenceAngleDegrees_Float = "maxincidenceangledegrees"; +static const char * k_pch_Lighthouse_UseLighthouseDirect_Bool = "uselighthousedirect"; +static const char * k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +static const char * k_pch_Lighthouse_OriginOffsetX_Float = "originoffsetx"; +static const char * k_pch_Lighthouse_OriginOffsetY_Float = "originoffsety"; +static const char * k_pch_Lighthouse_OriginOffsetZ_Float = "originoffsetz"; +static const char * k_pch_Lighthouse_HeadingOffset_Float = "headingoffset"; +static const char * k_pch_Null_Section = "driver_null"; +static const char * k_pch_Null_EnableNullDriver_Bool = "enable"; +static const char * k_pch_Null_SerialNumber_String = "serialNumber"; +static const char * k_pch_Null_ModelNumber_String = "modelNumber"; +static const char * k_pch_Null_WindowX_Int32 = "windowX"; +static const char * k_pch_Null_WindowY_Int32 = "windowY"; +static const char * k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char * k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char * k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char * k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char * k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char * k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +static const char * k_pch_UserInterface_Section = "userinterface"; +static const char * k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char * k_pch_Notifications_Section = "notifications"; +static const char * k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +static const char * k_pch_Keyboard_Section = "keyboard"; +static const char * k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char * k_pch_Perf_Section = "perfcheck"; +static const char * k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char * k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char * k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char * k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char * k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char * k_pch_Perf_TestData_Float = "perfTestData"; +static const char * k_pch_Camera_Section = "camera"; +static const char * IVRSettings_Version = "IVRSettings_001"; +static const char * k_pch_audio_Section = "audio"; +static const char * k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char * k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char * k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char * k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char * k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; + +// OpenVR Enums + +typedef enum EVREye +{ + EVREye_Eye_Left = 0, + EVREye_Eye_Right = 1, +} EVREye; + +typedef enum EGraphicsAPIConvention +{ + EGraphicsAPIConvention_API_DirectX = 0, + EGraphicsAPIConvention_API_OpenGL = 1, +} EGraphicsAPIConvention; + +typedef enum EColorSpace +{ + EColorSpace_ColorSpace_Auto = 0, + EColorSpace_ColorSpace_Gamma = 1, + EColorSpace_ColorSpace_Linear = 2, +} EColorSpace; + +typedef enum ETrackingResult +{ + ETrackingResult_TrackingResult_Uninitialized = 1, + ETrackingResult_TrackingResult_Calibrating_InProgress = 100, + ETrackingResult_TrackingResult_Calibrating_OutOfRange = 101, + ETrackingResult_TrackingResult_Running_OK = 200, + ETrackingResult_TrackingResult_Running_OutOfRange = 201, +} ETrackingResult; + +typedef enum ETrackedDeviceClass +{ + ETrackedDeviceClass_TrackedDeviceClass_Invalid = 0, + ETrackedDeviceClass_TrackedDeviceClass_HMD = 1, + ETrackedDeviceClass_TrackedDeviceClass_Controller = 2, + ETrackedDeviceClass_TrackedDeviceClass_TrackingReference = 4, + ETrackedDeviceClass_TrackedDeviceClass_Other = 1000, +} ETrackedDeviceClass; + +typedef enum ETrackedControllerRole +{ + ETrackedControllerRole_TrackedControllerRole_Invalid = 0, + ETrackedControllerRole_TrackedControllerRole_LeftHand = 1, + ETrackedControllerRole_TrackedControllerRole_RightHand = 2, +} ETrackedControllerRole; + +typedef enum ETrackingUniverseOrigin +{ + ETrackingUniverseOrigin_TrackingUniverseSeated = 0, + ETrackingUniverseOrigin_TrackingUniverseStanding = 1, + ETrackingUniverseOrigin_TrackingUniverseRawAndUncalibrated = 2, +} ETrackingUniverseOrigin; + +typedef enum ETrackedDeviceProperty +{ + ETrackedDeviceProperty_Prop_TrackingSystemName_String = 1000, + ETrackedDeviceProperty_Prop_ModelNumber_String = 1001, + ETrackedDeviceProperty_Prop_SerialNumber_String = 1002, + ETrackedDeviceProperty_Prop_RenderModelName_String = 1003, + ETrackedDeviceProperty_Prop_WillDriftInYaw_Bool = 1004, + ETrackedDeviceProperty_Prop_ManufacturerName_String = 1005, + ETrackedDeviceProperty_Prop_TrackingFirmwareVersion_String = 1006, + ETrackedDeviceProperty_Prop_HardwareRevision_String = 1007, + ETrackedDeviceProperty_Prop_AllWirelessDongleDescriptions_String = 1008, + ETrackedDeviceProperty_Prop_ConnectedWirelessDongle_String = 1009, + ETrackedDeviceProperty_Prop_DeviceIsWireless_Bool = 1010, + ETrackedDeviceProperty_Prop_DeviceIsCharging_Bool = 1011, + ETrackedDeviceProperty_Prop_DeviceBatteryPercentage_Float = 1012, + ETrackedDeviceProperty_Prop_StatusDisplayTransform_Matrix34 = 1013, + ETrackedDeviceProperty_Prop_Firmware_UpdateAvailable_Bool = 1014, + ETrackedDeviceProperty_Prop_Firmware_ManualUpdate_Bool = 1015, + ETrackedDeviceProperty_Prop_Firmware_ManualUpdateURL_String = 1016, + ETrackedDeviceProperty_Prop_HardwareRevision_Uint64 = 1017, + ETrackedDeviceProperty_Prop_FirmwareVersion_Uint64 = 1018, + ETrackedDeviceProperty_Prop_FPGAVersion_Uint64 = 1019, + ETrackedDeviceProperty_Prop_VRCVersion_Uint64 = 1020, + ETrackedDeviceProperty_Prop_RadioVersion_Uint64 = 1021, + ETrackedDeviceProperty_Prop_DongleVersion_Uint64 = 1022, + ETrackedDeviceProperty_Prop_BlockServerShutdown_Bool = 1023, + ETrackedDeviceProperty_Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + ETrackedDeviceProperty_Prop_ContainsProximitySensor_Bool = 1025, + ETrackedDeviceProperty_Prop_DeviceProvidesBatteryStatus_Bool = 1026, + ETrackedDeviceProperty_Prop_DeviceCanPowerOff_Bool = 1027, + ETrackedDeviceProperty_Prop_Firmware_ProgrammingTarget_String = 1028, + ETrackedDeviceProperty_Prop_DeviceClass_Int32 = 1029, + ETrackedDeviceProperty_Prop_HasCamera_Bool = 1030, + ETrackedDeviceProperty_Prop_ReportsTimeSinceVSync_Bool = 2000, + ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float = 2001, + ETrackedDeviceProperty_Prop_DisplayFrequency_Float = 2002, + ETrackedDeviceProperty_Prop_UserIpdMeters_Float = 2003, + ETrackedDeviceProperty_Prop_CurrentUniverseId_Uint64 = 2004, + ETrackedDeviceProperty_Prop_PreviousUniverseId_Uint64 = 2005, + ETrackedDeviceProperty_Prop_DisplayFirmwareVersion_Uint64 = 2006, + ETrackedDeviceProperty_Prop_IsOnDesktop_Bool = 2007, + ETrackedDeviceProperty_Prop_DisplayMCType_Int32 = 2008, + ETrackedDeviceProperty_Prop_DisplayMCOffset_Float = 2009, + ETrackedDeviceProperty_Prop_DisplayMCScale_Float = 2010, + ETrackedDeviceProperty_Prop_EdidVendorID_Int32 = 2011, + ETrackedDeviceProperty_Prop_DisplayMCImageLeft_String = 2012, + ETrackedDeviceProperty_Prop_DisplayMCImageRight_String = 2013, + ETrackedDeviceProperty_Prop_DisplayGCBlackClamp_Float = 2014, + ETrackedDeviceProperty_Prop_EdidProductID_Int32 = 2015, + ETrackedDeviceProperty_Prop_CameraToHeadTransform_Matrix34 = 2016, + ETrackedDeviceProperty_Prop_DisplayGCType_Int32 = 2017, + ETrackedDeviceProperty_Prop_DisplayGCOffset_Float = 2018, + ETrackedDeviceProperty_Prop_DisplayGCScale_Float = 2019, + ETrackedDeviceProperty_Prop_DisplayGCPrescale_Float = 2020, + ETrackedDeviceProperty_Prop_DisplayGCImage_String = 2021, + ETrackedDeviceProperty_Prop_LensCenterLeftU_Float = 2022, + ETrackedDeviceProperty_Prop_LensCenterLeftV_Float = 2023, + ETrackedDeviceProperty_Prop_LensCenterRightU_Float = 2024, + ETrackedDeviceProperty_Prop_LensCenterRightV_Float = 2025, + ETrackedDeviceProperty_Prop_UserHeadToEyeDepthMeters_Float = 2026, + ETrackedDeviceProperty_Prop_CameraFirmwareVersion_Uint64 = 2027, + ETrackedDeviceProperty_Prop_CameraFirmwareDescription_String = 2028, + ETrackedDeviceProperty_Prop_DisplayFPGAVersion_Uint64 = 2029, + ETrackedDeviceProperty_Prop_DisplayBootloaderVersion_Uint64 = 2030, + ETrackedDeviceProperty_Prop_DisplayHardwareVersion_Uint64 = 2031, + ETrackedDeviceProperty_Prop_AudioFirmwareVersion_Uint64 = 2032, + ETrackedDeviceProperty_Prop_CameraCompatibilityMode_Int32 = 2033, + ETrackedDeviceProperty_Prop_AttachedDeviceId_String = 3000, + ETrackedDeviceProperty_Prop_SupportedButtons_Uint64 = 3001, + ETrackedDeviceProperty_Prop_Axis0Type_Int32 = 3002, + ETrackedDeviceProperty_Prop_Axis1Type_Int32 = 3003, + ETrackedDeviceProperty_Prop_Axis2Type_Int32 = 3004, + ETrackedDeviceProperty_Prop_Axis3Type_Int32 = 3005, + ETrackedDeviceProperty_Prop_Axis4Type_Int32 = 3006, + ETrackedDeviceProperty_Prop_FieldOfViewLeftDegrees_Float = 4000, + ETrackedDeviceProperty_Prop_FieldOfViewRightDegrees_Float = 4001, + ETrackedDeviceProperty_Prop_FieldOfViewTopDegrees_Float = 4002, + ETrackedDeviceProperty_Prop_FieldOfViewBottomDegrees_Float = 4003, + ETrackedDeviceProperty_Prop_TrackingRangeMinimumMeters_Float = 4004, + ETrackedDeviceProperty_Prop_TrackingRangeMaximumMeters_Float = 4005, + ETrackedDeviceProperty_Prop_ModeLabel_String = 4006, + ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_Start = 10000, + ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_End = 10999, +} ETrackedDeviceProperty; + +typedef enum ETrackedPropertyError +{ + ETrackedPropertyError_TrackedProp_Success = 0, + ETrackedPropertyError_TrackedProp_WrongDataType = 1, + ETrackedPropertyError_TrackedProp_WrongDeviceClass = 2, + ETrackedPropertyError_TrackedProp_BufferTooSmall = 3, + ETrackedPropertyError_TrackedProp_UnknownProperty = 4, + ETrackedPropertyError_TrackedProp_InvalidDevice = 5, + ETrackedPropertyError_TrackedProp_CouldNotContactServer = 6, + ETrackedPropertyError_TrackedProp_ValueNotProvidedByDevice = 7, + ETrackedPropertyError_TrackedProp_StringExceedsMaximumLength = 8, + ETrackedPropertyError_TrackedProp_NotYetAvailable = 9, +} ETrackedPropertyError; + +typedef enum EVRSubmitFlags +{ + EVRSubmitFlags_Submit_Default = 0, + EVRSubmitFlags_Submit_LensDistortionAlreadyApplied = 1, + EVRSubmitFlags_Submit_GlRenderBuffer = 2, +} EVRSubmitFlags; + +typedef enum EVRState +{ + EVRState_VRState_Undefined = -1, + EVRState_VRState_Off = 0, + EVRState_VRState_Searching = 1, + EVRState_VRState_Searching_Alert = 2, + EVRState_VRState_Ready = 3, + EVRState_VRState_Ready_Alert = 4, + EVRState_VRState_NotReady = 5, +} EVRState; + +typedef enum EVREventType +{ + EVREventType_VREvent_None = 0, + EVREventType_VREvent_TrackedDeviceActivated = 100, + EVREventType_VREvent_TrackedDeviceDeactivated = 101, + EVREventType_VREvent_TrackedDeviceUpdated = 102, + EVREventType_VREvent_TrackedDeviceUserInteractionStarted = 103, + EVREventType_VREvent_TrackedDeviceUserInteractionEnded = 104, + EVREventType_VREvent_IpdChanged = 105, + EVREventType_VREvent_EnterStandbyMode = 106, + EVREventType_VREvent_LeaveStandbyMode = 107, + EVREventType_VREvent_TrackedDeviceRoleChanged = 108, + EVREventType_VREvent_ButtonPress = 200, + EVREventType_VREvent_ButtonUnpress = 201, + EVREventType_VREvent_ButtonTouch = 202, + EVREventType_VREvent_ButtonUntouch = 203, + EVREventType_VREvent_MouseMove = 300, + EVREventType_VREvent_MouseButtonDown = 301, + EVREventType_VREvent_MouseButtonUp = 302, + EVREventType_VREvent_FocusEnter = 303, + EVREventType_VREvent_FocusLeave = 304, + EVREventType_VREvent_Scroll = 305, + EVREventType_VREvent_TouchPadMove = 306, + EVREventType_VREvent_InputFocusCaptured = 400, + EVREventType_VREvent_InputFocusReleased = 401, + EVREventType_VREvent_SceneFocusLost = 402, + EVREventType_VREvent_SceneFocusGained = 403, + EVREventType_VREvent_SceneApplicationChanged = 404, + EVREventType_VREvent_SceneFocusChanged = 405, + EVREventType_VREvent_HideRenderModels = 410, + EVREventType_VREvent_ShowRenderModels = 411, + EVREventType_VREvent_OverlayShown = 500, + EVREventType_VREvent_OverlayHidden = 501, + EVREventType_VREvent_DashboardActivated = 502, + EVREventType_VREvent_DashboardDeactivated = 503, + EVREventType_VREvent_DashboardThumbSelected = 504, + EVREventType_VREvent_DashboardRequested = 505, + EVREventType_VREvent_ResetDashboard = 506, + EVREventType_VREvent_RenderToast = 507, + EVREventType_VREvent_ImageLoaded = 508, + EVREventType_VREvent_ShowKeyboard = 509, + EVREventType_VREvent_HideKeyboard = 510, + EVREventType_VREvent_OverlayGamepadFocusGained = 511, + EVREventType_VREvent_OverlayGamepadFocusLost = 512, + EVREventType_VREvent_OverlaySharedTextureChanged = 513, + EVREventType_VREvent_Notification_Shown = 600, + EVREventType_VREvent_Notification_Hidden = 601, + EVREventType_VREvent_Notification_BeginInteraction = 602, + EVREventType_VREvent_Notification_Destroyed = 603, + EVREventType_VREvent_Quit = 700, + EVREventType_VREvent_ProcessQuit = 701, + EVREventType_VREvent_QuitAborted_UserPrompt = 702, + EVREventType_VREvent_QuitAcknowledged = 703, + EVREventType_VREvent_ChaperoneDataHasChanged = 800, + EVREventType_VREvent_ChaperoneUniverseHasChanged = 801, + EVREventType_VREvent_ChaperoneTempDataHasChanged = 802, + EVREventType_VREvent_ChaperoneSettingsHaveChanged = 803, + EVREventType_VREvent_SeatedZeroPoseReset = 804, + EVREventType_VREvent_BackgroundSettingHasChanged = 850, + EVREventType_VREvent_CameraSettingsHaveChanged = 851, + EVREventType_VREvent_StatusUpdate = 900, + EVREventType_VREvent_MCImageUpdated = 1000, + EVREventType_VREvent_FirmwareUpdateStarted = 1100, + EVREventType_VREvent_FirmwareUpdateFinished = 1101, + EVREventType_VREvent_KeyboardClosed = 1200, + EVREventType_VREvent_KeyboardCharInput = 1201, + EVREventType_VREvent_KeyboardDone = 1202, + EVREventType_VREvent_ApplicationTransitionStarted = 1300, + EVREventType_VREvent_ApplicationTransitionAborted = 1301, + EVREventType_VREvent_ApplicationTransitionNewAppStarted = 1302, + EVREventType_VREvent_Compositor_MirrorWindowShown = 1400, + EVREventType_VREvent_Compositor_MirrorWindowHidden = 1401, + EVREventType_VREvent_Compositor_ChaperoneBoundsShown = 1410, + EVREventType_VREvent_Compositor_ChaperoneBoundsHidden = 1411, + EVREventType_VREvent_TrackedCamera_StartVideoStream = 1500, + EVREventType_VREvent_TrackedCamera_StopVideoStream = 1501, + EVREventType_VREvent_TrackedCamera_PauseVideoStream = 1502, + EVREventType_VREvent_TrackedCamera_ResumeVideoStream = 1503, + EVREventType_VREvent_PerformanceTest_EnableCapture = 1600, + EVREventType_VREvent_PerformanceTest_DisableCapture = 1601, + EVREventType_VREvent_PerformanceTest_FidelityLevel = 1602, + EVREventType_VREvent_VendorSpecific_Reserved_Start = 10000, + EVREventType_VREvent_VendorSpecific_Reserved_End = 19999, +} EVREventType; + +typedef enum EDeviceActivityLevel +{ + EDeviceActivityLevel_k_EDeviceActivityLevel_Unknown = -1, + EDeviceActivityLevel_k_EDeviceActivityLevel_Idle = 0, + EDeviceActivityLevel_k_EDeviceActivityLevel_UserInteraction = 1, + EDeviceActivityLevel_k_EDeviceActivityLevel_UserInteraction_Timeout = 2, + EDeviceActivityLevel_k_EDeviceActivityLevel_Standby = 3, +} EDeviceActivityLevel; + +typedef enum EVRButtonId +{ + EVRButtonId_k_EButton_System = 0, + EVRButtonId_k_EButton_ApplicationMenu = 1, + EVRButtonId_k_EButton_Grip = 2, + EVRButtonId_k_EButton_DPad_Left = 3, + EVRButtonId_k_EButton_DPad_Up = 4, + EVRButtonId_k_EButton_DPad_Right = 5, + EVRButtonId_k_EButton_DPad_Down = 6, + EVRButtonId_k_EButton_A = 7, + EVRButtonId_k_EButton_Axis0 = 32, + EVRButtonId_k_EButton_Axis1 = 33, + EVRButtonId_k_EButton_Axis2 = 34, + EVRButtonId_k_EButton_Axis3 = 35, + EVRButtonId_k_EButton_Axis4 = 36, + EVRButtonId_k_EButton_SteamVR_Touchpad = 32, + EVRButtonId_k_EButton_SteamVR_Trigger = 33, + EVRButtonId_k_EButton_Dashboard_Back = 2, + EVRButtonId_k_EButton_Max = 64, +} EVRButtonId; + +typedef enum EVRMouseButton +{ + EVRMouseButton_VRMouseButton_Left = 1, + EVRMouseButton_VRMouseButton_Right = 2, + EVRMouseButton_VRMouseButton_Middle = 4, +} EVRMouseButton; + +typedef enum EVRControllerAxisType +{ + EVRControllerAxisType_k_eControllerAxis_None = 0, + EVRControllerAxisType_k_eControllerAxis_TrackPad = 1, + EVRControllerAxisType_k_eControllerAxis_Joystick = 2, + EVRControllerAxisType_k_eControllerAxis_Trigger = 3, +} EVRControllerAxisType; + +typedef enum EVRControllerEventOutputType +{ + EVRControllerEventOutputType_ControllerEventOutput_OSEvents = 0, + EVRControllerEventOutputType_ControllerEventOutput_VREvents = 1, +} EVRControllerEventOutputType; + +typedef enum ECollisionBoundsStyle +{ + ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_BEGINNER = 0, + ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_INTERMEDIATE = 1, + ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_SQUARES = 2, + ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_ADVANCED = 3, + ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_NONE = 4, + ECollisionBoundsStyle_COLLISION_BOUNDS_STYLE_COUNT = 5, +} ECollisionBoundsStyle; + +typedef enum EVROverlayError +{ + EVROverlayError_VROverlayError_None = 0, + EVROverlayError_VROverlayError_UnknownOverlay = 10, + EVROverlayError_VROverlayError_InvalidHandle = 11, + EVROverlayError_VROverlayError_PermissionDenied = 12, + EVROverlayError_VROverlayError_OverlayLimitExceeded = 13, + EVROverlayError_VROverlayError_WrongVisibilityType = 14, + EVROverlayError_VROverlayError_KeyTooLong = 15, + EVROverlayError_VROverlayError_NameTooLong = 16, + EVROverlayError_VROverlayError_KeyInUse = 17, + EVROverlayError_VROverlayError_WrongTransformType = 18, + EVROverlayError_VROverlayError_InvalidTrackedDevice = 19, + EVROverlayError_VROverlayError_InvalidParameter = 20, + EVROverlayError_VROverlayError_ThumbnailCantBeDestroyed = 21, + EVROverlayError_VROverlayError_ArrayTooSmall = 22, + EVROverlayError_VROverlayError_RequestFailed = 23, + EVROverlayError_VROverlayError_InvalidTexture = 24, + EVROverlayError_VROverlayError_UnableToLoadFile = 25, + EVROverlayError_VROVerlayError_KeyboardAlreadyInUse = 26, + EVROverlayError_VROverlayError_NoNeighbor = 27, +} EVROverlayError; + +typedef enum EVRApplicationType +{ + EVRApplicationType_VRApplication_Other = 0, + EVRApplicationType_VRApplication_Scene = 1, + EVRApplicationType_VRApplication_Overlay = 2, + EVRApplicationType_VRApplication_Background = 3, + EVRApplicationType_VRApplication_Utility = 4, +} EVRApplicationType; + +typedef enum EVRFirmwareError +{ + EVRFirmwareError_VRFirmwareError_None = 0, + EVRFirmwareError_VRFirmwareError_Success = 1, + EVRFirmwareError_VRFirmwareError_Fail = 2, +} EVRFirmwareError; + +typedef enum EVRNotificationError +{ + EVRNotificationError_VRNotificationError_OK = 0, + EVRNotificationError_VRNotificationError_InvalidNotificationId = 100, + EVRNotificationError_VRNotificationError_NotificationQueueFull = 101, + EVRNotificationError_VRNotificationError_InvalidOverlayHandle = 102, +} EVRNotificationError; + +typedef enum EVRInitError +{ + EVRInitError_VRInitError_None = 0, + EVRInitError_VRInitError_Unknown = 1, + EVRInitError_VRInitError_Init_InstallationNotFound = 100, + EVRInitError_VRInitError_Init_InstallationCorrupt = 101, + EVRInitError_VRInitError_Init_VRClientDLLNotFound = 102, + EVRInitError_VRInitError_Init_FileNotFound = 103, + EVRInitError_VRInitError_Init_FactoryNotFound = 104, + EVRInitError_VRInitError_Init_InterfaceNotFound = 105, + EVRInitError_VRInitError_Init_InvalidInterface = 106, + EVRInitError_VRInitError_Init_UserConfigDirectoryInvalid = 107, + EVRInitError_VRInitError_Init_HmdNotFound = 108, + EVRInitError_VRInitError_Init_NotInitialized = 109, + EVRInitError_VRInitError_Init_PathRegistryNotFound = 110, + EVRInitError_VRInitError_Init_NoConfigPath = 111, + EVRInitError_VRInitError_Init_NoLogPath = 112, + EVRInitError_VRInitError_Init_PathRegistryNotWritable = 113, + EVRInitError_VRInitError_Init_AppInfoInitFailed = 114, + EVRInitError_VRInitError_Init_Retry = 115, + EVRInitError_VRInitError_Init_InitCanceledByUser = 116, + EVRInitError_VRInitError_Init_AnotherAppLaunching = 117, + EVRInitError_VRInitError_Init_SettingsInitFailed = 118, + EVRInitError_VRInitError_Init_ShuttingDown = 119, + EVRInitError_VRInitError_Init_TooManyObjects = 120, + EVRInitError_VRInitError_Init_NoServerForBackgroundApp = 121, + EVRInitError_VRInitError_Init_NotSupportedWithCompositor = 122, + EVRInitError_VRInitError_Init_NotAvailableToUtilityApps = 123, + EVRInitError_VRInitError_Driver_Failed = 200, + EVRInitError_VRInitError_Driver_Unknown = 201, + EVRInitError_VRInitError_Driver_HmdUnknown = 202, + EVRInitError_VRInitError_Driver_NotLoaded = 203, + EVRInitError_VRInitError_Driver_RuntimeOutOfDate = 204, + EVRInitError_VRInitError_Driver_HmdInUse = 205, + EVRInitError_VRInitError_Driver_NotCalibrated = 206, + EVRInitError_VRInitError_Driver_CalibrationInvalid = 207, + EVRInitError_VRInitError_Driver_HmdDisplayNotFound = 208, + EVRInitError_VRInitError_IPC_ServerInitFailed = 300, + EVRInitError_VRInitError_IPC_ConnectFailed = 301, + EVRInitError_VRInitError_IPC_SharedStateInitFailed = 302, + EVRInitError_VRInitError_IPC_CompositorInitFailed = 303, + EVRInitError_VRInitError_IPC_MutexInitFailed = 304, + EVRInitError_VRInitError_IPC_Failed = 305, + EVRInitError_VRInitError_Compositor_Failed = 400, + EVRInitError_VRInitError_Compositor_D3D11HardwareRequired = 401, + EVRInitError_VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + EVRInitError_VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + EVRInitError_VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + EVRInitError_VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + EVRInitError_VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + EVRInitError_VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + EVRInitError_VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + EVRInitError_VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + EVRInitError_VRInitError_Steam_SteamInstallationNotFound = 2000, +} EVRInitError; + +typedef enum EVRApplicationError +{ + EVRApplicationError_VRApplicationError_None = 0, + EVRApplicationError_VRApplicationError_AppKeyAlreadyExists = 100, + EVRApplicationError_VRApplicationError_NoManifest = 101, + EVRApplicationError_VRApplicationError_NoApplication = 102, + EVRApplicationError_VRApplicationError_InvalidIndex = 103, + EVRApplicationError_VRApplicationError_UnknownApplication = 104, + EVRApplicationError_VRApplicationError_IPCFailed = 105, + EVRApplicationError_VRApplicationError_ApplicationAlreadyRunning = 106, + EVRApplicationError_VRApplicationError_InvalidManifest = 107, + EVRApplicationError_VRApplicationError_InvalidApplication = 108, + EVRApplicationError_VRApplicationError_LaunchFailed = 109, + EVRApplicationError_VRApplicationError_ApplicationAlreadyStarting = 110, + EVRApplicationError_VRApplicationError_LaunchInProgress = 111, + EVRApplicationError_VRApplicationError_OldApplicationQuitting = 112, + EVRApplicationError_VRApplicationError_TransitionAborted = 113, + EVRApplicationError_VRApplicationError_IsTemplate = 114, + EVRApplicationError_VRApplicationError_BufferTooSmall = 200, + EVRApplicationError_VRApplicationError_PropertyNotSet = 201, + EVRApplicationError_VRApplicationError_UnknownProperty = 202, +} EVRApplicationError; + +typedef enum EVRApplicationProperty +{ + EVRApplicationProperty_VRApplicationProperty_Name_String = 0, + EVRApplicationProperty_VRApplicationProperty_LaunchType_String = 11, + EVRApplicationProperty_VRApplicationProperty_WorkingDirectory_String = 12, + EVRApplicationProperty_VRApplicationProperty_BinaryPath_String = 13, + EVRApplicationProperty_VRApplicationProperty_Arguments_String = 14, + EVRApplicationProperty_VRApplicationProperty_URL_String = 15, + EVRApplicationProperty_VRApplicationProperty_Description_String = 50, + EVRApplicationProperty_VRApplicationProperty_NewsURL_String = 51, + EVRApplicationProperty_VRApplicationProperty_ImagePath_String = 52, + EVRApplicationProperty_VRApplicationProperty_Source_String = 53, + EVRApplicationProperty_VRApplicationProperty_IsDashboardOverlay_Bool = 60, + EVRApplicationProperty_VRApplicationProperty_IsTemplate_Bool = 61, + EVRApplicationProperty_VRApplicationProperty_IsInstanced_Bool = 62, + EVRApplicationProperty_VRApplicationProperty_LastLaunchTime_Uint64 = 70, +} EVRApplicationProperty; + +typedef enum EVRApplicationTransitionState +{ + EVRApplicationTransitionState_VRApplicationTransition_None = 0, + EVRApplicationTransitionState_VRApplicationTransition_OldAppQuitSent = 10, + EVRApplicationTransitionState_VRApplicationTransition_WaitingForExternalLaunch = 11, + EVRApplicationTransitionState_VRApplicationTransition_NewAppLaunched = 20, +} EVRApplicationTransitionState; + +typedef enum ChaperoneCalibrationState +{ + ChaperoneCalibrationState_OK = 1, + ChaperoneCalibrationState_Warning = 100, + ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, + ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, + ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, + ChaperoneCalibrationState_Error = 200, + ChaperoneCalibrationState_Error_BaseStationUninitalized = 201, + ChaperoneCalibrationState_Error_BaseStationConflict = 202, + ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, + ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, +} ChaperoneCalibrationState; + +typedef enum EChaperoneConfigFile +{ + EChaperoneConfigFile_Live = 1, + EChaperoneConfigFile_Temp = 2, +} EChaperoneConfigFile; + +typedef enum EChaperoneImportFlags +{ + EChaperoneImportFlags_EChaperoneImport_BoundsOnly = 1, +} EChaperoneImportFlags; + +typedef enum EVRCompositorError +{ + EVRCompositorError_VRCompositorError_None = 0, + EVRCompositorError_VRCompositorError_IncompatibleVersion = 100, + EVRCompositorError_VRCompositorError_DoNotHaveFocus = 101, + EVRCompositorError_VRCompositorError_InvalidTexture = 102, + EVRCompositorError_VRCompositorError_IsNotSceneApplication = 103, + EVRCompositorError_VRCompositorError_TextureIsOnWrongDevice = 104, + EVRCompositorError_VRCompositorError_TextureUsesUnsupportedFormat = 105, + EVRCompositorError_VRCompositorError_SharedTexturesNotSupported = 106, + EVRCompositorError_VRCompositorError_IndexOutOfRange = 107, +} EVRCompositorError; + +typedef enum VROverlayInputMethod +{ + VROverlayInputMethod_None = 0, + VROverlayInputMethod_Mouse = 1, +} VROverlayInputMethod; + +typedef enum VROverlayTransformType +{ + VROverlayTransformType_VROverlayTransform_Absolute = 0, + VROverlayTransformType_VROverlayTransform_TrackedDeviceRelative = 1, + VROverlayTransformType_VROverlayTransform_SystemOverlay = 2, + VROverlayTransformType_VROverlayTransform_TrackedComponent = 3, +} VROverlayTransformType; + +typedef enum VROverlayFlags +{ + VROverlayFlags_None = 0, + VROverlayFlags_Curved = 1, + VROverlayFlags_RGSS4X = 2, + VROverlayFlags_NoDashboardTab = 3, + VROverlayFlags_AcceptsGamepadEvents = 4, + VROverlayFlags_ShowGamepadFocus = 5, + VROverlayFlags_SendVRScrollEvents = 6, + VROverlayFlags_SendVRTouchpadEvents = 7, + VROverlayFlags_ShowTouchPadScrollWheel = 8, +} VROverlayFlags; + +typedef enum EGamepadTextInputMode +{ + EGamepadTextInputMode_k_EGamepadTextInputModeNormal = 0, + EGamepadTextInputMode_k_EGamepadTextInputModePassword = 1, + EGamepadTextInputMode_k_EGamepadTextInputModeSubmit = 2, +} EGamepadTextInputMode; + +typedef enum EGamepadTextInputLineMode +{ + EGamepadTextInputLineMode_k_EGamepadTextInputLineModeSingleLine = 0, + EGamepadTextInputLineMode_k_EGamepadTextInputLineModeMultipleLines = 1, +} EGamepadTextInputLineMode; + +typedef enum EOverlayDirection +{ + EOverlayDirection_OverlayDirection_Up = 0, + EOverlayDirection_OverlayDirection_Down = 1, + EOverlayDirection_OverlayDirection_Left = 2, + EOverlayDirection_OverlayDirection_Right = 3, + EOverlayDirection_OverlayDirection_Count = 4, +} EOverlayDirection; + +typedef enum EVRRenderModelError +{ + EVRRenderModelError_VRRenderModelError_None = 0, + EVRRenderModelError_VRRenderModelError_Loading = 100, + EVRRenderModelError_VRRenderModelError_NotSupported = 200, + EVRRenderModelError_VRRenderModelError_InvalidArg = 300, + EVRRenderModelError_VRRenderModelError_InvalidModel = 301, + EVRRenderModelError_VRRenderModelError_NoShapes = 302, + EVRRenderModelError_VRRenderModelError_MultipleShapes = 303, + EVRRenderModelError_VRRenderModelError_TooManyIndices = 304, + EVRRenderModelError_VRRenderModelError_MultipleTextures = 305, + EVRRenderModelError_VRRenderModelError_InvalidTexture = 400, +} EVRRenderModelError; + +typedef enum EVRComponentProperty +{ + EVRComponentProperty_VRComponentProperty_IsStatic = 1, + EVRComponentProperty_VRComponentProperty_IsVisible = 2, + EVRComponentProperty_VRComponentProperty_IsTouched = 4, + EVRComponentProperty_VRComponentProperty_IsPressed = 8, + EVRComponentProperty_VRComponentProperty_IsScrolled = 16, +} EVRComponentProperty; + +typedef enum EVRNotificationType +{ + EVRNotificationType_Transient = 0, + EVRNotificationType_Persistent = 1, +} EVRNotificationType; + +typedef enum EVRNotificationStyle +{ + EVRNotificationStyle_None = 0, + EVRNotificationStyle_Application = 100, + EVRNotificationStyle_Contact_Disabled = 200, + EVRNotificationStyle_Contact_Enabled = 201, + EVRNotificationStyle_Contact_Active = 202, +} EVRNotificationStyle; + +typedef enum EVRSettingsError +{ + EVRSettingsError_VRSettingsError_None = 0, + EVRSettingsError_VRSettingsError_IPCFailed = 1, + EVRSettingsError_VRSettingsError_WriteFailed = 2, + EVRSettingsError_VRSettingsError_ReadFailed = 3, +} EVRSettingsError; + + +// OpenVR typedefs + +typedef uint32_t TrackedDeviceIndex_t; +typedef uint32_t VRNotificationId; +typedef uint64_t VROverlayHandle_t; +typedef void * glSharedTextureHandle_t; +typedef int32_t glInt_t; +typedef uint32_t glUInt_t; +typedef uint32_t TrackedDeviceIndex_t; +typedef uint64_t VROverlayHandle_t; +typedef uint32_t VRComponentProperties; +typedef int32_t TextureID_t; +typedef uint32_t VRNotificationId; +typedef EVRInitError HmdError; +typedef EVREye Hmd_Eye; +typedef EGraphicsAPIConvention GraphicsAPIConvention; +typedef EColorSpace ColorSpace; +typedef ETrackingResult HmdTrackingResult; +typedef ETrackedDeviceClass TrackedDeviceClass; +typedef ETrackingUniverseOrigin TrackingUniverseOrigin; +typedef ETrackedDeviceProperty TrackedDeviceProperty; +typedef ETrackedPropertyError TrackedPropertyError; +typedef EVRSubmitFlags VRSubmitFlags_t; +typedef EVRState VRState_t; +typedef ECollisionBoundsStyle CollisionBoundsStyle_t; +typedef EVROverlayError VROverlayError; +typedef EVRFirmwareError VRFirmwareError; +typedef EVRCompositorError VRCompositorError; + +// OpenVR Structs + +typedef struct HmdMatrix34_t +{ + float m[3][4]; //float[3][4] +} HmdMatrix34_t; + +typedef struct HmdMatrix44_t +{ + float m[4][4]; //float[4][4] +} HmdMatrix44_t; + +typedef struct HmdVector3_t +{ + float v[3]; //float[3] +} HmdVector3_t; + +typedef struct HmdVector4_t +{ + float v[4]; //float[4] +} HmdVector4_t; + +typedef struct HmdVector3d_t +{ + double v[3]; //double[3] +} HmdVector3d_t; + +typedef struct HmdVector2_t +{ + float v[2]; //float[2] +} HmdVector2_t; + +typedef struct HmdQuaternion_t +{ + double w; + double x; + double y; + double z; +} HmdQuaternion_t; + +typedef struct HmdColor_t +{ + float r; + float g; + float b; + float a; +} HmdColor_t; + +typedef struct HmdQuad_t +{ + struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] +} HmdQuad_t; + +typedef struct HmdRect2_t +{ + struct HmdVector2_t vTopLeft; + struct HmdVector2_t vBottomRight; +} HmdRect2_t; + +typedef struct DistortionCoordinates_t +{ + float rfRed[2]; //float[2] + float rfGreen[2]; //float[2] + float rfBlue[2]; //float[2] +} DistortionCoordinates_t; + +typedef struct Texture_t +{ + void * handle; // void * + enum EGraphicsAPIConvention eType; + enum EColorSpace eColorSpace; +} Texture_t; + +typedef struct TrackedDevicePose_t +{ + struct HmdMatrix34_t mDeviceToAbsoluteTracking; + struct HmdVector3_t vVelocity; + struct HmdVector3_t vAngularVelocity; + enum ETrackingResult eTrackingResult; + bool bPoseIsValid; + bool bDeviceIsConnected; +} TrackedDevicePose_t; + +typedef struct VRTextureBounds_t +{ + float uMin; + float vMin; + float uMax; + float vMax; +} VRTextureBounds_t; + +typedef struct VREvent_Controller_t +{ + uint32_t button; +} VREvent_Controller_t; + +typedef struct VREvent_Mouse_t +{ + float x; + float y; + uint32_t button; +} VREvent_Mouse_t; + +typedef struct VREvent_Scroll_t +{ + float xdelta; + float ydelta; + uint32_t repeatCount; +} VREvent_Scroll_t; + +typedef struct VREvent_TouchPadMove_t +{ + bool bFingerDown; + float flSecondsFingerDown; + float fValueXFirst; + float fValueYFirst; + float fValueXRaw; + float fValueYRaw; +} VREvent_TouchPadMove_t; + +typedef struct VREvent_Notification_t +{ + uint64_t ulUserValue; + uint32_t notificationId; +} VREvent_Notification_t; + +typedef struct VREvent_Process_t +{ + uint32_t pid; + uint32_t oldPid; + bool bForced; +} VREvent_Process_t; + +typedef struct VREvent_Overlay_t +{ + uint64_t overlayHandle; +} VREvent_Overlay_t; + +typedef struct VREvent_Status_t +{ + uint32_t statusState; +} VREvent_Status_t; + +typedef struct VREvent_Keyboard_t +{ + char * cNewInput[8]; //char[8] + uint64_t uUserValue; +} VREvent_Keyboard_t; + +typedef struct VREvent_Ipd_t +{ + float ipdMeters; +} VREvent_Ipd_t; + +typedef struct VREvent_Chaperone_t +{ + uint64_t m_nPreviousUniverse; + uint64_t m_nCurrentUniverse; +} VREvent_Chaperone_t; + +typedef struct VREvent_Reserved_t +{ + uint64_t reserved0; + uint64_t reserved1; +} VREvent_Reserved_t; + +typedef struct VREvent_PerformanceTest_t +{ + uint32_t m_nFidelityLevel; +} VREvent_PerformanceTest_t; + +typedef struct VREvent_SeatedZeroPoseReset_t +{ + bool bResetBySystemMenu; +} VREvent_SeatedZeroPoseReset_t; + +typedef struct HiddenAreaMesh_t +{ + struct HmdVector2_t * pVertexData; // const struct vr::HmdVector2_t * + uint32_t unTriangleCount; +} HiddenAreaMesh_t; + +typedef struct VRControllerAxis_t +{ + float x; + float y; +} VRControllerAxis_t; + +typedef struct VRControllerState_t +{ + uint32_t unPacketNum; + uint64_t ulButtonPressed; + uint64_t ulButtonTouched; + struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] +} VRControllerState_t; + +typedef struct Compositor_OverlaySettings +{ + uint32_t size; + bool curved; + bool antialias; + float scale; + float distance; + float alpha; + float uOffset; + float vOffset; + float uScale; + float vScale; + float gridDivs; + float gridWidth; + float gridScale; + struct HmdMatrix44_t transform; +} Compositor_OverlaySettings; + +typedef struct AppOverrideKeys_t +{ + char * pchKey; // const char * + char * pchValue; // const char * +} AppOverrideKeys_t; + +typedef struct Compositor_FrameTiming +{ + uint32_t m_nSize; + uint32_t m_nFrameIndex; + uint32_t m_nNumFramePresents; + uint32_t m_nNumDroppedFrames; + double m_flSystemTimeInSeconds; + float m_flSceneRenderGpuMs; + float m_flTotalRenderGpuMs; + float m_flCompositorRenderGpuMs; + float m_flCompositorRenderCpuMs; + float m_flCompositorIdleCpuMs; + float m_flClientFrameIntervalMs; + float m_flPresentCallCpuMs; + float m_flWaitForPresentCpuMs; + float m_flSubmitFrameMs; + float m_flWaitGetPosesCalledMs; + float m_flNewPosesReadyMs; + float m_flNewFrameReadyMs; + float m_flCompositorUpdateStartMs; + float m_flCompositorUpdateEndMs; + float m_flCompositorRenderStartMs; + TrackedDevicePose_t m_HmdPose; + int32_t m_nFidelityLevel; +} Compositor_FrameTiming; + +typedef struct VROverlayIntersectionParams_t +{ + struct HmdVector3_t vSource; + struct HmdVector3_t vDirection; + enum ETrackingUniverseOrigin eOrigin; +} VROverlayIntersectionParams_t; + +typedef struct VROverlayIntersectionResults_t +{ + struct HmdVector3_t vPoint; + struct HmdVector3_t vNormal; + struct HmdVector2_t vUVs; + float fDistance; +} VROverlayIntersectionResults_t; + +typedef struct RenderModel_ComponentState_t +{ + struct HmdMatrix34_t mTrackingToComponentRenderModel; + struct HmdMatrix34_t mTrackingToComponentLocal; + VRComponentProperties uProperties; +} RenderModel_ComponentState_t; + +typedef struct RenderModel_Vertex_t +{ + struct HmdVector3_t vPosition; + struct HmdVector3_t vNormal; + float rfTextureCoord[2]; //float[2] +} RenderModel_Vertex_t; + +typedef struct RenderModel_TextureMap_t +{ + uint16_t unWidth; + uint16_t unHeight; + uint8_t * rubTextureMapData; // const uint8_t * +} RenderModel_TextureMap_t; + +typedef struct RenderModel_t +{ + struct RenderModel_Vertex_t * rVertexData; // const struct vr::RenderModel_Vertex_t * + uint32_t unVertexCount; + uint16_t * rIndexData; // const uint16_t * + uint32_t unTriangleCount; + TextureID_t diffuseTextureId; +} RenderModel_t; + +typedef struct RenderModel_ControllerMode_State_t +{ + bool bScrollWheelVisible; +} RenderModel_ControllerMode_State_t; + +typedef struct NotificationBitmap_t +{ + void * bytes; // void * + int32_t width; + int32_t height; + int32_t depth; +} NotificationBitmap_t; + +typedef struct COpenVRContext +{ + intptr_t m_pVRSystem; // class vr::IVRSystem * + intptr_t m_pVRChaperone; // class vr::IVRChaperone * + intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * + intptr_t m_pVRCompositor; // class vr::IVRCompositor * + intptr_t m_pVROverlay; // class vr::IVROverlay * + intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * + intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * + intptr_t m_pVRSettings; // class vr::IVRSettings * + intptr_t m_pVRApplications; // class vr::IVRApplications * +} COpenVRContext; + + +typedef union +{ + VREvent_Reserved_t reserved; + VREvent_Controller_t controller; + VREvent_Mouse_t mouse; + VREvent_Scroll_t scroll; + VREvent_Process_t process; + VREvent_Notification_t notification; + VREvent_Overlay_t overlay; + VREvent_Status_t status; + VREvent_Keyboard_t keyboard; + VREvent_Ipd_t ipd; + VREvent_Chaperone_t chaperone; + VREvent_PerformanceTest_t performanceTest; + VREvent_TouchPadMove_t touchPadMove; + VREvent_SeatedZeroPoseReset_t seatedZeroPoseReset; +} VREvent_Data_t; + +/** An event posted by the server to all running applications */ +struct VREvent_t +{ + uint32_t eventType; // EVREventType enum + TrackedDeviceIndex_t trackedDeviceIndex; + float eventAgeSeconds; + // event data must be the end of the struct as its size is variable + VREvent_Data_t data; +}; + + +// OpenVR Function Pointer Tables + +struct VR_IVRSystem_FnTable +{ + void (OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t * pnWidth, uint32_t * pnHeight); + struct HmdMatrix44_t (OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ, EGraphicsAPIConvention eProjType); + void (OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float * pfLeft, float * pfRight, float * pfTop, float * pfBottom); + struct DistortionCoordinates_t (OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV); + struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); + bool (OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float * pfSecondsSinceLastVsync, uint64_t * pulFrameCounter); + int32_t (OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); + void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex); + bool (OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); + bool (OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); + void (OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t * pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); + void (OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); + struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); + struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t * punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); + EDeviceActivityLevel (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); + void (OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pTrackedDevicePose, struct HmdMatrix34_t * pTransform); + TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); + ETrackedControllerRole (OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); + ETrackedDeviceClass (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); + bool (OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); + bool (OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); + float (OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); + int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); + uint64_t (OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); + struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char * pchValue, uint32_t unBufferSize, ETrackedPropertyError * pError); + char * (OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); + bool (OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t * pEvent, uint32_t uncbVREvent); + bool (OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t * pEvent, uint32_t uncbVREvent, TrackedDevicePose_t * pTrackedDevicePose); + char * (OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); + struct HiddenAreaMesh_t (OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye); + bool (OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState); + bool (OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, struct TrackedDevicePose_t * pTrackedDevicePose); + void (OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); + char * (OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); + char * (OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); + bool (OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); + void (OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); + bool (OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); + uint32_t (OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char * pchRequest, char * pchResponseBuffer, uint32_t unResponseBufferSize); + EVRFirmwareError (OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); + void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); + void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); +}; + +struct VR_IVRExtendedDisplay_FnTable +{ + void (OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t * pnX, int32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); + void (OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t * pnX, uint32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); + void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex, int32_t * pnAdapterOutputIndex); +}; + +struct VR_IVRApplications_FnTable +{ + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char * pchApplicationManifestFullPath, bool bTemporary); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char * pchApplicationManifestFullPath); + bool (OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char * pchAppKey); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char * pchAppKey); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char * pchTemplateAppKey, char * pchNewAppKey, struct AppOverrideKeys_t * pKeys, uint32_t unKeys); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char * pchAppKey); + bool (OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char * pchAppKey); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char * pchAppKey); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char * pchAppKey); + char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char * pchAppKey, EVRApplicationProperty eProperty, char * pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError * peError); + bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); + uint64_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char * pchAppKey, bool bAutoLaunch); + bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char * pchAppKey); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationTransitionState (OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char * pchAppKey); + char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); + bool (OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); + EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char * pchBinaryPath, char * pchArguments, char * pchWorkingDirectory); +}; + +struct VR_IVRChaperone_FnTable +{ + ChaperoneCalibrationState (OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); + bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float * pSizeX, float * pSizeZ); + bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t * rect); + void (OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); + void (OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); + void (OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t * pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t * pOutputCameraColor); + bool (OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); + void (OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); +}; + +struct VR_IVRChaperoneSetup_FnTable +{ + bool (OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); + void (OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); + bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float * pSizeX, float * pSizeZ); + bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t * rect); + bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); + bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); + bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); + bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatStandingZeroPoseToRawTrackingPose); + void (OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); + void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); + void (OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatSeatedZeroPoseToRawTrackingPose); + void (OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatStandingZeroPoseToRawTrackingPose); + void (OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); + bool (OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); + void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t unTagCount); + bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t * punTagCount); + bool (OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); + bool (OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); + bool (OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char * pBuffer, uint32_t * pnBufferLength); + bool (OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char * pBuffer, uint32_t nImportFlags); +}; + +struct VR_IVRCompositor_FnTable +{ + void (OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); + ETrackingUniverseOrigin (OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); + EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pOutputGamePose); + EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t * pTexture, struct VRTextureBounds_t * pBounds, EVRSubmitFlags nSubmitFlags); + void (OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); + void (OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); + bool (OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming * pTiming, uint32_t unFramesAgo); + float (OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); + void (OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); + void (OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); + EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t * pTextures, uint32_t unTextureCount); + void (OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); + void (OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); + void (OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); + void (OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); + bool (OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); + bool (OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); + void (OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); + void (OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); + bool (OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); + void (OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); + bool (OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); + void (OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); +}; + +struct VR_IVROverlay_FnTable +{ + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char * pchOverlayKey, VROverlayHandle_t * pOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char * pchOverlayKey, char * pchOverlayFriendlyName, VROverlayHandle_t * pOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unBufferSize, uint32_t * punWidth, uint32_t * punHeight); + char * (OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool * pbEnabled); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float * pfRed, float * pfGreen, float * pfBlue); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float * pfAlpha); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfWidthInMeters); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfMinDistanceInMeters, float * pfMaxDistanceInMeters); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace * peTextureColorSpace); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType * peTransformType); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin * peTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char * pchComponentName); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punDeviceIndex, char * pchComponentName, uint32_t unComponentNameSize); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); + bool (OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t * pmatTransform); + bool (OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t * pEvent, uint32_t uncbVREvent); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod * peInputMethod); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); + bool (OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t * pParams, struct VROverlayIntersectionResults_t * pResults); + bool (OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); + bool (OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t * pTexture); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char * pchFilePath); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void ** pNativeTextureHandle, void * pNativeTextureRef, uint32_t * pWidth, uint32_t * pHeight, uint32_t * pNativeFormat, EGraphicsAPIConvention * pAPI, EColorSpace * pColorSpace); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void * pNativeTextureHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char * pchOverlayKey, char * pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t * pThumbnailHandle); + bool (OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); + bool (OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t * punProcessId); + void (OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char * pchOverlayToShow); + TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char * pchText, uint32_t cchText); + void (OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); + void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToKeyboardTransform); + void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); +}; + +struct VR_IVRRenderModels_FnTable +{ + EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char * pchRenderModelName, struct RenderModel_t ** ppRenderModel); + void (OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t * pRenderModel); + EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t ** ppTexture); + void (OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t * pTexture); + EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void * pD3D11Device, void ** ppD3D11Texture2D); + EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void * pDstTexture); + void (OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void * pD3D11Texture2D); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char * pchRenderModelName, uint32_t unRenderModelNameLen); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char * pchRenderModelName); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char * pchRenderModelName, uint32_t unComponentIndex, char * pchComponentName, uint32_t unComponentNameLen); + uint64_t (OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char * pchRenderModelName, char * pchComponentName); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char * pchRenderModelName, char * pchComponentName, char * pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); + bool (OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char * pchRenderModelName, char * pchComponentName, VRControllerState_t * pControllerState, struct RenderModel_ControllerMode_State_t * pState, struct RenderModel_ComponentState_t * pComponentState); + bool (OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char * pchRenderModelName, char * pchComponentName); +}; + +struct VR_IVRNotifications_FnTable +{ + EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char * pchText, EVRNotificationStyle style, struct NotificationBitmap_t * pImage, VRNotificationId * pNotificationId); + EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); +}; + +struct VR_IVRSettings_FnTable +{ + char * (OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); + bool (OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError * peError); + bool (OPENVR_FNTABLE_CALLTYPE *GetBool)(char * pchSection, char * pchSettingsKey, bool bDefaultValue, EVRSettingsError * peError); + void (OPENVR_FNTABLE_CALLTYPE *SetBool)(char * pchSection, char * pchSettingsKey, bool bValue, EVRSettingsError * peError); + int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32)(char * pchSection, char * pchSettingsKey, int32_t nDefaultValue, EVRSettingsError * peError); + void (OPENVR_FNTABLE_CALLTYPE *SetInt32)(char * pchSection, char * pchSettingsKey, int32_t nValue, EVRSettingsError * peError); + float (OPENVR_FNTABLE_CALLTYPE *GetFloat)(char * pchSection, char * pchSettingsKey, float flDefaultValue, EVRSettingsError * peError); + void (OPENVR_FNTABLE_CALLTYPE *SetFloat)(char * pchSection, char * pchSettingsKey, float flValue, EVRSettingsError * peError); + void (OPENVR_FNTABLE_CALLTYPE *GetString)(char * pchSection, char * pchSettingsKey, char * pchValue, uint32_t unValueLen, char * pchDefaultValue, EVRSettingsError * peError); + void (OPENVR_FNTABLE_CALLTYPE *SetString)(char * pchSection, char * pchSettingsKey, char * pchValue, EVRSettingsError * peError); + void (OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char * pchSection, EVRSettingsError * peError); + void (OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); +}; + + +#if 0 +// Global entry points +S_API intptr_t VR_InitInternal( EVRInitError *peError, EVRApplicationType eType ); +S_API void VR_ShutdownInternal(); +S_API bool VR_IsHmdPresent(); +S_API intptr_t VR_GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError ); +S_API bool VR_IsRuntimeInstalled(); +S_API const char * VR_GetVRInitErrorAsSymbol( EVRInitError error ); +S_API const char * VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); +#endif + +#endif // __OPENVR_API_FLAT_H__ + + diff --git a/3rdparty/bgfx/examples/common/entry/entry_p.h b/3rdparty/bgfx/examples/common/entry/entry_p.h index f44a421946a..971b880552d 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_p.h +++ b/3rdparty/bgfx/examples/common/entry/entry_p.h @@ -14,7 +14,7 @@ #include <string.h> // memcpy #ifndef ENTRY_CONFIG_USE_NOOP -# define ENTRY_CONFIG_USE_NOOP (BX_PLATFORM_QNX || BX_PLATFORM_XBOXONE) +# define ENTRY_CONFIG_USE_NOOP (BX_PLATFORM_QNX) #endif // ENTRY_CONFIG_USE_NOOP #ifndef ENTRY_CONFIG_USE_SDL diff --git a/3rdparty/bgfx/examples/common/entry/entry_winrt.cpp b/3rdparty/bgfx/examples/common/entry/entry_winrt.cpp index caf4f235ad2..9edbc36e92a 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_winrt.cpp +++ b/3rdparty/bgfx/examples/common/entry/entry_winrt.cpp @@ -5,7 +5,7 @@ #include "entry_p.h" -#if BX_PLATFORM_WINRT +#if BX_PLATFORM_WINRT || BX_PLATFORM_XBOXONE #include <bgfx/bgfxplatform.h> #include <bx/thread.h> @@ -17,7 +17,9 @@ using namespace Windows::UI::Core; using namespace Windows::UI::Input; using namespace Windows::System; using namespace Windows::Foundation; +#if BX_PLATFORM_WINRT using namespace Windows::Graphics::Display; +#endif // BX_PLATFORM_WINRT using namespace Platform; static char* g_emptyArgs[] = { "" }; @@ -36,13 +38,23 @@ public: // IFrameworkView Methods. virtual void Initialize(CoreApplicationView^ applicationView) { - applicationView->Activated += ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated); + applicationView->Activated += ref new + TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated); + + CoreApplication::Suspending += ref new + EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending); + + CoreApplication::Resuming += ref new + EventHandler<Platform::Object^>(this, &App::OnResuming); } virtual void SetWindow(CoreWindow^ window) { - window->VisibilityChanged += ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged); - window->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed); + window->VisibilityChanged += ref new + TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged); + + window->Closed += ref new + TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed); bgfx::winrtSetWindow(reinterpret_cast<IUnknown*>(window) ); } @@ -58,13 +70,15 @@ public: CoreWindow^ window = CoreWindow::GetForCurrentThread(); auto bounds = window->Bounds; - auto dpi = DisplayInformation::GetForCurrentView()->LogicalDpi; +#if BX_PLATFORM_WINRT + auto dpi = DisplayInformation::GetForCurrentView()->LogicalDpi; static const float dipsPerInch = 96.0f; g_eventQueue.postSizeEvent(g_defaultWindow - , lround(floorf(bounds.Width * dpi / dipsPerInch + 0.5f) ) - , lround(floorf(bounds.Height * dpi / dipsPerInch + 0.5f) ) + , lround(bx::ffloor(bounds.Width * dpi / dipsPerInch + 0.5f) ) + , lround(bx::ffloor(bounds.Height * dpi / dipsPerInch + 0.5f) ) ); +#endif // BX_PLATFORM_WINRT while (!m_windowClosed) { @@ -101,6 +115,16 @@ private: m_windowVisible = args->Visible; } + void OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) + { + SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); + BX_UNUSED(deferral); + } + + void OnResuming(Platform::Object^ sender, Platform::Object^ args) + { + } + void OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) { m_windowClosed = true; @@ -189,4 +213,4 @@ int main(Array<String^>^) return 0; } -#endif // BX_PLATFORM_WINRT +#endif // BX_PLATFORM_WINRT || BX_PLATFORM_XBOXONE diff --git a/3rdparty/bgfx/scripts/texturec.lua b/3rdparty/bgfx/scripts/texturec.lua index dac357b6b86..28e9bcc8bd4 100644 --- a/3rdparty/bgfx/scripts/texturec.lua +++ b/3rdparty/bgfx/scripts/texturec.lua @@ -13,6 +13,7 @@ project "texturec" path.join(BGFX_DIR, "src"), path.join(BGFX_DIR, "3rdparty"), path.join(BGFX_DIR, "3rdparty/nvtt"), + path.join(BGFX_DIR, "3rdparty/iqa/include"), } files { @@ -31,6 +32,8 @@ project "texturec" path.join(BGFX_DIR, "3rdparty/pvrtc/**.h"), path.join(BGFX_DIR, "3rdparty/tinyexr/**.cc"), path.join(BGFX_DIR, "3rdparty/tinyexr/**.h"), + path.join(BGFX_DIR, "3rdparty/iqa/include/**.h"), + path.join(BGFX_DIR, "3rdparty/iqa/source/**.c"), path.join(BGFX_DIR, "tools/texturec/**.cpp"), path.join(BGFX_DIR, "tools/texturec/**.h"), } diff --git a/3rdparty/bgfx/src/glcontext_egl.h b/3rdparty/bgfx/src/glcontext_egl.h index 95323fe419a..767879c8349 100644 --- a/3rdparty/bgfx/src/glcontext_egl.h +++ b/3rdparty/bgfx/src/glcontext_egl.h @@ -10,6 +10,10 @@ #include <EGL/egl.h> #include <EGL/eglext.h> +#if defined(Success) +// X11 defines Success +# undef Success +#endif // defined(Success) namespace bgfx { namespace gl { diff --git a/3rdparty/bgfx/src/hmd_openvr.cpp b/3rdparty/bgfx/src/hmd_openvr.cpp new file mode 100644 index 00000000000..8e873032154 --- /dev/null +++ b/3rdparty/bgfx/src/hmd_openvr.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2011-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "hmd_openvr.h" + +BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wunused-variable") +#include <openvr/openvr_capi.h> + +namespace bgfx +{ +#if BX_PLATFORM_WINDOWS +# define VR_CALLTYPE __cdecl +#else +# define VR_CALLTYPE +#endif + + typedef uint32_t (VR_CALLTYPE *PFN_VR_INITINTERNAL)(EVRInitError* peError, EVRApplicationType eType); + typedef void (VR_CALLTYPE *PFN_VR_SHUTDOWNINTERNAL)(); + typedef bool (VR_CALLTYPE *PFN_VR_ISHMDPRESENT)(); + typedef void* (VR_CALLTYPE *PFN_VR_GETGENERICINTERFACE)(const char* pchInterfaceVersion, EVRInitError* peError); + typedef bool (VR_CALLTYPE *PFN_VR_ISRUNTIMEINSTALLED)(); + typedef bool (VR_CALLTYPE *PFN_VR_ISINTERFACEVERSIONVALID)(const char *pchInterfaceVersion); + typedef uint32_t (VR_CALLTYPE *PFN_VR_GETINITTOKEN)(); + typedef const char* (VR_CALLTYPE *PFN_VR_GETVRINITERRORASSYMBOL)(EVRInitError error); + typedef const char* (VR_CALLTYPE *PFN_VR_GETVRINITERRORASENGLISHDESCRIPTION)(EVRInitError error); + + PFN_VR_INITINTERNAL VR_InitInternal; + PFN_VR_SHUTDOWNINTERNAL VR_ShutdownInternal; + PFN_VR_ISHMDPRESENT VR_IsHmdPresent; + PFN_VR_GETGENERICINTERFACE VR_GetGenericInterface; + PFN_VR_ISRUNTIMEINSTALLED VR_IsRuntimeInstalled; + PFN_VR_ISINTERFACEVERSIONVALID VR_IsInterfaceVersionValid; + PFN_VR_GETINITTOKEN VR_GetInitToken; + PFN_VR_GETVRINITERRORASSYMBOL VR_GetVRInitErrorAsSymbol; + PFN_VR_GETVRINITERRORASENGLISHDESCRIPTION VR_GetVRInitErrorAsEnglishDescription; + + void* loadOpenVR() + { + void* openvrdll = bx::dlopen( +#if BX_PLATFORM_LINUX + "libopenvr_api.so" +#elif BX_PLATFORM_OSX + "libopenvr_api.dylib" +#else + "openvr_api.dll" +#endif // BX_PLATFORM_* + ); + if (NULL != openvrdll) + { + VR_InitInternal = (PFN_VR_INITINTERNAL )bx::dlsym(openvrdll, "VR_InitInternal"); + VR_ShutdownInternal = (PFN_VR_SHUTDOWNINTERNAL )bx::dlsym(openvrdll, "VR_ShutdownInternal"); + VR_IsHmdPresent = (PFN_VR_ISHMDPRESENT )bx::dlsym(openvrdll, "VR_IsHmdPresent"); + VR_GetGenericInterface = (PFN_VR_GETGENERICINTERFACE )bx::dlsym(openvrdll, "VR_GetGenericInterface"); + VR_IsRuntimeInstalled = (PFN_VR_ISRUNTIMEINSTALLED )bx::dlsym(openvrdll, "VR_IsRuntimeInstalled"); + VR_IsInterfaceVersionValid = (PFN_VR_ISINTERFACEVERSIONVALID)bx::dlsym(openvrdll, "VR_IsInterfaceVersionValid"); + VR_GetInitToken = (PFN_VR_GETINITTOKEN )bx::dlsym(openvrdll, "VR_GetInitToken"); + VR_GetVRInitErrorAsSymbol = (PFN_VR_GETVRINITERRORASSYMBOL )bx::dlsym(openvrdll, "VR_GetVRInitErrorAsSymbol"); + VR_GetVRInitErrorAsEnglishDescription = (PFN_VR_GETVRINITERRORASENGLISHDESCRIPTION)bx::dlsym(openvrdll, "VR_GetVRInitErrorAsEnglishDescription"); + + if (NULL == VR_InitInternal + && NULL == VR_ShutdownInternal + && NULL == VR_IsHmdPresent + && NULL == VR_GetGenericInterface + && NULL == VR_IsRuntimeInstalled + && NULL == VR_IsInterfaceVersionValid + && NULL == VR_GetInitToken + && NULL == VR_GetVRInitErrorAsSymbol + && NULL == VR_GetVRInitErrorAsEnglishDescription) + { + bx::dlclose(openvrdll); + return NULL; + } + + EVRInitError err; + uint32_t token = VR_InitInternal(&err, EVRApplicationType_VRApplication_Scene); + BX_UNUSED(token); + + BX_TRACE("OpenVR: HMD is %spresent, Runtime is %sinstalled." + , VR_IsHmdPresent() ? "" : "not " + , VR_IsRuntimeInstalled() ? "" : "not " + ); + } + + return openvrdll; + } + + void unloadOpenVR(void* _openvrdll) + { + VR_ShutdownInternal(); + bx::dlclose(_openvrdll); + } + +} // namespace bgfx diff --git a/3rdparty/bgfx/src/hmd_openvr.h b/3rdparty/bgfx/src/hmd_openvr.h new file mode 100644 index 00000000000..262f8c947a1 --- /dev/null +++ b/3rdparty/bgfx/src/hmd_openvr.h @@ -0,0 +1,18 @@ +/* + * Copyright 2011-2016 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#ifndef BGFX_OPENVR_H_HEADER_GUARD +#define BGFX_OPENVR_H_HEADER_GUARD + +#include "bgfx_p.h" + +namespace bgfx +{ + void* loadOpenVR(); + void unloadOpenVR(void*); + +} // namespace bgfx + +#endif // BGFX_OPENVR_H_HEADER_GUARD diff --git a/3rdparty/bgfx/src/hmd_ovr.cpp b/3rdparty/bgfx/src/hmd_ovr.cpp index a3befb6549c..7d3109dbd45 100644 --- a/3rdparty/bgfx/src/hmd_ovr.cpp +++ b/3rdparty/bgfx/src/hmd_ovr.cpp @@ -17,6 +17,8 @@ namespace bgfx #if BGFX_CONFIG_DEBUG # define OVR_CHECK(_call) _OVR_CHECK(_call) +#else +# define OVR_CHECK(_call) _call #endif // BGFX_CONFIG_DEBUG OVR::OVR() @@ -152,6 +154,7 @@ namespace bgfx for (uint32_t ii = 0; ii < 2; ++ii) { + m_eyeBuffers[ii]->postRender(m_hmd); result = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[ii]->m_textureSwapChain); if (!OVR_SUCCESS(result) ) { diff --git a/3rdparty/bgfx/src/hmd_ovr.h b/3rdparty/bgfx/src/hmd_ovr.h index e30aa878f52..675e711c01e 100644 --- a/3rdparty/bgfx/src/hmd_ovr.h +++ b/3rdparty/bgfx/src/hmd_ovr.h @@ -31,10 +31,10 @@ namespace bgfx struct OVRBufferI { virtual ~OVRBufferI() {}; - virtual void create(const ovrSession& _session, int _eyeIdx) = 0; + virtual void create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) = 0; virtual void destroy(const ovrSession& _session) = 0; virtual void render(const ovrSession& _session) = 0; - + virtual void postRender(const ovrSession& _session) = 0; ovrSizei m_eyeTextureSize; ovrTextureSwapChain m_textureSwapChain; }; diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp index 539ab426f71..140f6a344c1 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.cpp +++ b/3rdparty/bgfx/src/renderer_d3d11.cpp @@ -1076,13 +1076,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_RELEASE(device, 2); } + memset(&m_adapterDesc, 0, sizeof(m_adapterDesc) ); hr = adapter->GetDesc(&m_adapterDesc); - if (FAILED(hr) ) - { - BX_TRACE("Unable to create Direct3D11 device."); - DX_RELEASE(adapter, 2); - goto error; - } + BX_WARN(SUCCEEDED(hr), "Adapter GetDesc failed 0x%08x.", hr); g_caps.vendorId = 0 == m_adapterDesc.VendorId ? BGFX_PCI_ID_SOFTWARE_RASTERIZER @@ -1354,140 +1350,168 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (DXGI_FORMAT_UNKNOWN != fmt) { - struct D3D11_FEATURE_DATA_FORMAT_SUPPORT + if (BX_ENABLED(BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) ) { - DXGI_FORMAT InFormat; - UINT OutFormatSupport; - }; + struct D3D11_FEATURE_DATA_FORMAT_SUPPORT + { + DXGI_FORMAT InFormat; + UINT OutFormatSupport; + }; - D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2 - data.InFormat = fmt; - hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); - if (SUCCEEDED(hr) ) - { - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_TEXTURE2D - | D3D11_FORMAT_SUPPORT_TEXTURE3D - | D3D11_FORMAT_SUPPORT_TEXTURECUBE - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_2D - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2 + data.InFormat = fmt; + hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); + if (SUCCEEDED(hr) ) + { + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_TEXTURE2D + | D3D11_FORMAT_SUPPORT_TEXTURE3D + | D3D11_FORMAT_SUPPORT_TEXTURECUBE + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_2D + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_TEXTURE3D - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_3D - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_TEXTURE3D + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_3D + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_TEXTURECUBE - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_CUBE - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_TEXTURECUBE + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_CUBE + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_BUFFER - | D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER - | D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_VERTEX - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_BUFFER + | D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER + | D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_VERTEX + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_SHADER_LOAD - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_SHADER_LOAD + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_RENDER_TARGET - | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_RENDER_TARGET + | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_MSAA - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_MSAA + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + } + else + { + BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) ); + } + + if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) ) + { + // clear image flag for additional testing + support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE; + + data.InFormat = s_textureFormat[ii].m_fmt; + hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data, sizeof(data) ); + if (SUCCEEDED(hr) ) + { + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD + | D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + } + } } else { - BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) ); + support |= 0 + | BGFX_CAPS_FORMAT_TEXTURE_2D + | BGFX_CAPS_FORMAT_TEXTURE_3D + | BGFX_CAPS_FORMAT_TEXTURE_CUBE + | BGFX_CAPS_FORMAT_TEXTURE_IMAGE + | BGFX_CAPS_FORMAT_TEXTURE_VERTEX + | BGFX_CAPS_FORMAT_TEXTURE_IMAGE + | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER + | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA + | BGFX_CAPS_FORMAT_TEXTURE_MSAA + ; } + } - if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) ) + if (DXGI_FORMAT_UNKNOWN != fmtSrgb) + { + if (BX_ENABLED(BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) ) { - // clear image flag for additional testing - support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE; + struct D3D11_FEATURE_DATA_FORMAT_SUPPORT + { + DXGI_FORMAT InFormat; + UINT OutFormatSupport; + }; - data.InFormat = s_textureFormat[ii].m_fmt; - hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data, sizeof(data) ); + D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2 + data.InFormat = fmtSrgb; + hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); if (SUCCEEDED(hr) ) { support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD - | D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE + | D3D11_FORMAT_SUPPORT_TEXTURE2D ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB : BGFX_CAPS_FORMAT_TEXTURE_NONE ; - } - } - } - - if (DXGI_FORMAT_UNKNOWN != fmtSrgb) - { - struct D3D11_FEATURE_DATA_FORMAT_SUPPORT - { - DXGI_FORMAT InFormat; - UINT OutFormatSupport; - }; - D3D11_FEATURE_DATA_FORMAT_SUPPORT data; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2 - data.InFormat = fmtSrgb; - hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); - if (SUCCEEDED(hr) ) - { - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_TEXTURE2D - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; - - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_TEXTURE3D - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_TEXTURE3D + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; - support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT_TEXTURECUBE - ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_TEXTURECUBE + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + } + else + { + BX_TRACE("CheckFeatureSupport failed with %x for sRGB format %s.", hr, getName(TextureFormat::Enum(ii) ) ); + } } else { - BX_TRACE("CheckFeatureSupport failed with %x for sRGB format %s.", hr, getName(TextureFormat::Enum(ii) ) ); + support |= 0 + | BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB + | BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB + | BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB + ; } } @@ -2132,7 +2156,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ovrPostReset(); // If OVR doesn't create separate depth stencil view, create default one. - if (NULL == m_backBufferDepthStencil) + if (!m_ovr.isEnabled() && NULL == m_backBufferDepthStencil) { D3D11_TEXTURE2D_DESC dsd; dsd.Width = getBufferWidth(); @@ -3096,13 +3120,15 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { if (m_ovr.postReset() ) { + const uint32_t msaaSamples = 1 << ((m_resolution.m_flags&BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT); + for (uint32_t ii = 0; ii < 2; ++ii) { // eye buffers need to be initialized only once during application lifetime if (NULL == m_ovr.m_eyeBuffers[ii]) { m_ovr.m_eyeBuffers[ii] = &m_ovrBuffers[ii]; - m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii); + m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii, msaaSamples); } } @@ -3566,10 +3592,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } #if BGFX_CONFIG_USE_OVR - void OVRBufferD3D11::create(const ovrSession& _session, int _eyeIdx) + void OVRBufferD3D11::create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) { ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session); m_eyeTextureSize = ovr_GetFovTextureSize(_session, (ovrEyeType)_eyeIdx, hmdDesc.DefaultEyeFov[_eyeIdx], 1.0f); + m_msaaTexture = NULL; + m_msaaRtv = NULL; + m_msaaSv = NULL; ovrTextureSwapChainDesc desc = {}; desc.Type = ovrTexture_2D; @@ -3617,7 +3646,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); dbDesc.MipLevels = 1; dbDesc.ArraySize = 1; dbDesc.Format = DXGI_FORMAT_D32_FLOAT; - dbDesc.SampleDesc.Count = 1; + dbDesc.SampleDesc.Count = _msaaSamples; dbDesc.SampleDesc.Quality = 0; dbDesc.Usage = D3D11_USAGE_DEFAULT; dbDesc.CPUAccessFlags = 0; @@ -3627,29 +3656,74 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_CHECK(device->CreateTexture2D(&dbDesc, NULL, &tex) ); DX_CHECK(device->CreateDepthStencilView(tex, NULL, &m_depthBuffer) ); DX_RELEASE(tex, 0); + + // create MSAA render target + if (_msaaSamples > 1) + { + D3D11_TEXTURE2D_DESC dsDesc; + dsDesc.Width = m_eyeTextureSize.w; + dsDesc.Height = m_eyeTextureSize.h; + dsDesc.MipLevels = 1; + dsDesc.ArraySize = 1; + dsDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dsDesc.SampleDesc.Count = _msaaSamples; + dsDesc.SampleDesc.Quality = 0; + dsDesc.Usage = D3D11_USAGE_DEFAULT; + dsDesc.CPUAccessFlags = 0; + dsDesc.MiscFlags = 0; + dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + + ID3D11Device* device = s_renderD3D11->m_device; + DX_CHECK(device->CreateTexture2D(&dsDesc, NULL, &m_msaaTexture)); + DX_CHECK(device->CreateShaderResourceView(m_msaaTexture, NULL, &m_msaaSv)); + DX_CHECK(device->CreateRenderTargetView(m_msaaTexture, NULL, &m_msaaRtv)); + } } void OVRBufferD3D11::render(const ovrSession& _session) { - // Clear and set up rendertarget - int texIndex = 0; - ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &texIndex); - ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; // Important that alpha=0, if want pixels to be transparent, for manual layers - deviceCtx->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer); - deviceCtx->ClearRenderTargetView(m_eyeRtv[texIndex], black); - deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); - - D3D11_VIEWPORT D3Dvp; - D3Dvp.TopLeftX = 0; - D3Dvp.TopLeftY = 0; - D3Dvp.Width = (FLOAT)m_eyeTextureSize.w; - D3Dvp.Height = (FLOAT)m_eyeTextureSize.h; - D3Dvp.MinDepth = 0; - D3Dvp.MaxDepth = 1; - deviceCtx->RSSetViewports(1, &D3Dvp); + + // render to MSAA target + if (NULL != m_msaaTexture) + { + deviceCtx->OMSetRenderTargets(1, &m_msaaRtv, m_depthBuffer); + deviceCtx->ClearRenderTargetView(m_msaaRtv, black); + deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); + } + else // MSAA disabled? render directly to eye buffer + { + int texIndex = 0; + ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &texIndex); + + deviceCtx->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer); + deviceCtx->ClearRenderTargetView(m_eyeRtv[texIndex], black); + deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); + + D3D11_VIEWPORT D3Dvp; + D3Dvp.TopLeftX = 0; + D3Dvp.TopLeftY = 0; + D3Dvp.Width = (FLOAT)m_eyeTextureSize.w; + D3Dvp.Height = (FLOAT)m_eyeTextureSize.h; + D3Dvp.MinDepth = 0; + D3Dvp.MaxDepth = 1; + deviceCtx->RSSetViewports(1, &D3Dvp); + } + } + + void OVRBufferD3D11::postRender(const ovrSession& _session) + { + if (NULL != m_msaaTexture) + { + ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; + int destIndex = 0; + ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &destIndex); + ID3D11Resource* dstTex = NULL; + ovr_GetTextureSwapChainBufferDX(_session, m_textureSwapChain, destIndex, IID_PPV_ARGS(&dstTex)); + deviceCtx->ResolveSubresource(dstTex, 0, m_msaaTexture, 0, DXGI_FORMAT_R8G8B8A8_UNORM); + dstTex->Release(); + } } void OVRBufferD3D11::destroy(const ovrSession& _session) @@ -3661,6 +3735,24 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ovr_DestroyTextureSwapChain(_session, m_textureSwapChain); m_depthBuffer->Release(); + + if (NULL != m_msaaTexture) + { + m_msaaTexture->Release(); + m_msaaTexture = NULL; + } + + if (NULL != m_msaaSv) + { + m_msaaSv->Release(); + m_msaaSv = NULL; + } + + if (NULL != m_msaaRtv) + { + m_msaaRtv->Release(); + m_msaaRtv = NULL; + } } void OVRMirrorD3D11::create(const ovrSession& _session, int _width, int _height) diff --git a/3rdparty/bgfx/src/renderer_d3d11.h b/3rdparty/bgfx/src/renderer_d3d11.h index f69bbef515d..84dd0c61981 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.h +++ b/3rdparty/bgfx/src/renderer_d3d11.h @@ -33,6 +33,7 @@ BX_PRAGMA_DIAGNOSTIC_POP() #include "renderer_d3d.h" #include "shader_dxbc.h" #include "hmd_ovr.h" +#include "hmd_openvr.h" #include "debug_renderdoc.h" #ifndef D3DCOLOR_ARGB @@ -62,12 +63,16 @@ namespace bgfx { namespace d3d11 #if BGFX_CONFIG_USE_OVR struct OVRBufferD3D11 : public OVRBufferI { - virtual void create(const ovrSession& _session, int _eyeIdx) BX_OVERRIDE; + virtual void create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) BX_OVERRIDE; virtual void destroy(const ovrSession& _session) BX_OVERRIDE; virtual void render(const ovrSession& _session) BX_OVERRIDE; + virtual void postRender(const ovrSession& _session) BX_OVERRIDE; ID3D11RenderTargetView* m_eyeRtv[4]; ID3D11DepthStencilView* m_depthBuffer; + ID3D11Texture2D* m_msaaTexture; + ID3D11ShaderResourceView* m_msaaSv; + ID3D11RenderTargetView* m_msaaRtv; }; struct OVRMirrorD3D11 : public OVRMirrorI diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp index 288f479bd45..10f5a1c3fd9 100644 --- a/3rdparty/bgfx/src/renderer_gl.cpp +++ b/3rdparty/bgfx/src/renderer_gl.cpp @@ -2864,13 +2864,15 @@ namespace bgfx { namespace gl { if (m_ovr.postReset() ) { + const uint32_t msaaSamples = 1 << ((m_resolution.m_flags&BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT); + for (uint32_t ii = 0; ii < 2; ++ii) { // eye buffers need to be initialized only once during application lifetime if (NULL == m_ovr.m_eyeBuffers[ii]) { m_ovr.m_eyeBuffers[ii] = &m_ovrBuffers[ii]; - m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii); + m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii, msaaSamples); } } @@ -3332,8 +3334,15 @@ namespace bgfx { namespace gl } #if BGFX_CONFIG_USE_OVR - void OVRBufferGL::create(const ovrSession& _session, int _eyeIdx) + void OVRBufferGL::create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) { + m_eyeFbo = 0; + m_eyeTexId = 0; + m_depthBuffer = 0; + m_msaaEyeFbo = 0; + m_msaaEyeTexId = 0; + m_msaaDepthBuffer = 0; + ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session); m_eyeTextureSize = ovr_GetFovTextureSize(_session, ovrEyeType(_eyeIdx), hmdDesc.DefaultEyeFov[_eyeIdx], 1.0f); @@ -3375,6 +3384,35 @@ namespace bgfx { namespace gl GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ); GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL) ); + + // create MSAA buffers + if (_msaaSamples > 1) + { + GL_CHECK(glGenFramebuffers(1, &m_msaaEyeFbo) ); + + // create color MSAA texture + GL_CHECK(glGenTextures(1, &m_msaaEyeTexId) ); + GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId) ); + + GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_RGBA, m_eyeTextureSize.w, m_eyeTextureSize.h, false) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) ); + + // create MSAA depth buffer + GL_CHECK(glGenTextures(1, &m_msaaDepthBuffer) ); + GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer) ); + + GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_DEPTH_COMPONENT, m_eyeTextureSize.w, m_eyeTextureSize.h, false) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) ); + GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ); + + GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) ); + } } void OVRBufferGL::render(const ovrSession& _session) @@ -3384,20 +3422,74 @@ namespace bgfx { namespace gl ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &curIndex); ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain, curIndex, &m_eyeTexId); - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo) ); - GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) ); - GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0) ); - + if (0 != m_msaaEyeFbo) + { + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaEyeFbo) ); + GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId, 0) ); + GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer, 0) ); + } + else // MSAA disabled? render directly to eye buffer + { + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo) ); + GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) ); + GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0) ); + } GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h) ); GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ); } + void OVRBufferGL::postRender(const ovrSession& /*_sesion*/) + { + if (0 != m_msaaEyeFbo && 0 != m_eyeTexId) + { + // blit the contents of MSAA FBO to the regular eye buffer "connected" to the HMD + GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_msaaEyeFbo)); + GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId, 0) ); + GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) ); + + BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) + , "glCheckFramebufferStatus failed 0x%08x" + , glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) ); + + GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_eyeFbo)); + GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) ); + GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) ); + + BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) + , "glCheckFramebufferStatus failed 0x%08x" + , glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) ); + + GL_CHECK(glBlitFramebuffer(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h, + 0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h, GL_COLOR_BUFFER_BIT, GL_NEAREST) ); + + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) ); + } + } + void OVRBufferGL::destroy(const ovrSession& _session) { GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo) ); GL_CHECK(glDeleteTextures(1, &m_depthBuffer) ); ovr_DestroyTextureSwapChain(_session, m_textureSwapChain); + + if (0 != m_msaaEyeFbo) + { + GL_CHECK(glDeleteFramebuffers(1, &m_msaaEyeFbo) ); + m_msaaEyeFbo = 0; + } + + if (0 != m_msaaEyeTexId) + { + GL_CHECK(glDeleteTextures(1, &m_msaaEyeTexId)); + m_msaaEyeTexId = 0; + } + + if (0 != m_msaaDepthBuffer) + { + GL_CHECK(glDeleteTextures(1, &m_msaaDepthBuffer)); + m_msaaDepthBuffer = 0; + } } void OVRMirrorGL::create(const ovrSession& _session, int _width, int _height) diff --git a/3rdparty/bgfx/src/renderer_gl.h b/3rdparty/bgfx/src/renderer_gl.h index 015e74147ca..527910e559e 100644 --- a/3rdparty/bgfx/src/renderer_gl.h +++ b/3rdparty/bgfx/src/renderer_gl.h @@ -108,6 +108,7 @@ typedef uint64_t GLuint64; #include "renderer.h" #include "hmd_ovr.h" +#include "hmd_openvr.h" #include "debug_renderdoc.h" #ifndef GL_LUMINANCE @@ -904,13 +905,17 @@ namespace bgfx { namespace gl #if BGFX_CONFIG_USE_OVR struct OVRBufferGL : public OVRBufferI { - virtual void create(const ovrSession& _session, int _eyeIdx) BX_OVERRIDE; + virtual void create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) BX_OVERRIDE; virtual void destroy(const ovrSession& _session) BX_OVERRIDE; virtual void render(const ovrSession& _session) BX_OVERRIDE; + virtual void postRender(const ovrSession& _sesion) BX_OVERRIDE; GLuint m_eyeFbo; GLuint m_eyeTexId; GLuint m_depthBuffer; + GLuint m_msaaEyeFbo; + GLuint m_msaaEyeTexId; + GLuint m_msaaDepthBuffer; }; struct OVRMirrorGL : public OVRMirrorI @@ -1284,8 +1289,8 @@ namespace bgfx { namespace gl void create(const ShaderGL& _vsh, const ShaderGL& _fsh); void destroy(); - void init(); - void bindAttributes(const VertexDecl& _vertexDecl, uint32_t _baseVertex = 0) const; + void init(); + void bindAttributes(const VertexDecl& _vertexDecl, uint32_t _baseVertex = 0) const; void bindInstanceData(uint32_t _stride, uint32_t _baseVertex = 0) const; void add(uint32_t _hash) @@ -1299,8 +1304,8 @@ namespace bgfx { namespace gl GLint m_attributes[Attrib::Count]; // sparse GLint m_instanceData[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT+1]; - GLint m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; - uint8_t m_numSamplers; + GLint m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; + uint8_t m_numSamplers; UniformBuffer* m_constantBuffer; PredefinedUniform m_predefined[PredefinedUniform::Count]; diff --git a/scripts/src/3rdparty.lua b/scripts/src/3rdparty.lua index a404872fde4..cfb6fa14069 100644 --- a/scripts/src/3rdparty.lua +++ b/scripts/src/3rdparty.lua @@ -801,6 +801,7 @@ end MAME_DIR .. "3rdparty/bgfx/src/glcontext_wgl.cpp", MAME_DIR .. "3rdparty/bgfx/src/image.cpp", MAME_DIR .. "3rdparty/bgfx/src/hmd_ovr.cpp", + MAME_DIR .. "3rdparty/bgfx/src/hmd_openvr.cpp", MAME_DIR .. "3rdparty/bgfx/src/renderer_d3d12.cpp", MAME_DIR .. "3rdparty/bgfx/src/renderer_d3d11.cpp", MAME_DIR .. "3rdparty/bgfx/src/renderer_d3d9.cpp", |